diff --git a/agentschema-emitter/lib/model/tools/mcp.tsp b/agentschema-emitter/lib/model/tools/mcp.tsp index 9ff07842..d9280207 100644 --- a/agentschema-emitter/lib/model/tools/mcp.tsp +++ b/agentschema-emitter/lib/model/tools/mcp.tsp @@ -31,6 +31,10 @@ model McpTool extends Tool { @doc("List of allowed operations or resources for the MCP tool") @sample(#{ allowedTools: #["operation1", "operation2"] }) allowedTools?: string[]; + + @doc("Custom HTTP headers to include in requests to the MCP server, useful for authentication or routing") + @sample(#{ headers: #{ Authorization: "Bearer token" } }) + headers?: Record; } alias mcpApprovalMode = "always" | "never" | "specify"; diff --git a/agentschema-emitter/package-lock.json b/agentschema-emitter/package-lock.json index 1eb5ec68..1fc0a863 100644 --- a/agentschema-emitter/package-lock.json +++ b/agentschema-emitter/package-lock.json @@ -799,7 +799,6 @@ "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -853,7 +852,6 @@ "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", @@ -1071,7 +1069,6 @@ "integrity": "sha512-FeLb7Q0z6Bh5dDpqtnU2RlWiIWWWF7rujx2xGMta5dcTuIOZ4jbdyz1hVdxk4iM4qadvaSV4ey/qrSuffNoh3w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "~7.27.1", "@inquirer/prompts": "^8.0.1", @@ -1128,7 +1125,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1531,7 +1527,6 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3552,7 +3547,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -3605,7 +3599,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/agentschema-emitter/src/ast.ts b/agentschema-emitter/src/ast.ts index eb092f62..f86b5161 100644 --- a/agentschema-emitter/src/ast.ts +++ b/agentschema-emitter/src/ast.ts @@ -442,7 +442,7 @@ export const resolveModelProperty = (program: Program, property: ModelProperty, prop.isCollection = false; prop.typeName = getModelType(model, rootNamespace, rootAlias); - if (prop.typeName.name === "Record") { + if (prop.typeName.name === "Record" || prop.typeName.name === "Record") { prop.isScalar = true; prop.isDict = true; prop.typeName = { diff --git a/docs/src/content/docs/reference/McpTool.md b/docs/src/content/docs/reference/McpTool.md index 771ef8d7..772a055f 100644 --- a/docs/src/content/docs/reference/McpTool.md +++ b/docs/src/content/docs/reference/McpTool.md @@ -33,6 +33,7 @@ classDiagram +string serverDescription +McpServerApprovalMode approvalMode +string[] allowedTools + +dictionary headers } class McpServerApprovalMode { +string kind @@ -53,6 +54,8 @@ approvalMode: allowedTools: - operation1 - operation2 +headers: + Authorization: Bearer token ``` ## Properties @@ -65,6 +68,7 @@ allowedTools: | serverDescription | string | The description of the MCP tool | | approvalMode | [McpServerApprovalMode](../mcpserverapprovalmode/) | The approval mode for the MCP tool, either 'auto' or 'manual'(Related Types: [McpServerToolAlwaysRequireApprovalMode](../mcpservertoolalwaysrequireapprovalmode/), [McpServerToolNeverRequireApprovalMode](../mcpservertoolneverrequireapprovalmode/), [McpServerToolSpecifyApprovalMode](../mcpservertoolspecifyapprovalmode/)) | | allowedTools | string[] | List of allowed operations or resources for the MCP tool | +| headers | dictionary | Custom HTTP headers to include in requests to the MCP server, useful for authentication or routing | ## Composed Types diff --git a/docs/src/content/docs/reference/README.md b/docs/src/content/docs/reference/README.md index d52403dc..5901b8ce 100644 --- a/docs/src/content/docs/reference/README.md +++ b/docs/src/content/docs/reference/README.md @@ -187,6 +187,7 @@ classDiagram +string serverDescription +McpServerApprovalMode approvalMode +string[] allowedTools + +dictionary headers } class OpenApiTool { diff --git a/docs/src/content/docs/reference/Record.md b/docs/src/content/docs/reference/Record.md new file mode 100644 index 00000000..53456e0d --- /dev/null +++ b/docs/src/content/docs/reference/Record.md @@ -0,0 +1,24 @@ +--- +title: "Record<string>" +description: "Documentation for the Record<string> type." +slug: "reference/record<string>" +--- + + + +## Class Diagram + +```mermaid +--- +title: Record<string> +config: + look: handDrawn + theme: colorful + class: + hideEmptyMembersBox: true +--- +classDiagram + class Record<string> { + + } +``` diff --git a/docs/src/content/docs/reference/Tool.md b/docs/src/content/docs/reference/Tool.md index 289a0a81..57b06e7f 100644 --- a/docs/src/content/docs/reference/Tool.md +++ b/docs/src/content/docs/reference/Tool.md @@ -60,6 +60,7 @@ classDiagram +string serverDescription +McpServerApprovalMode approvalMode +string[] allowedTools + +dictionary headers } Tool <|-- McpTool class OpenApiTool { diff --git a/runtime/csharp/AgentSchema.Tests/McpToolConversionTests.cs b/runtime/csharp/AgentSchema.Tests/McpToolConversionTests.cs index a4b25bc1..97328fbb 100644 --- a/runtime/csharp/AgentSchema.Tests/McpToolConversionTests.cs +++ b/runtime/csharp/AgentSchema.Tests/McpToolConversionTests.cs @@ -22,6 +22,8 @@ public void LoadYamlInput() allowedTools: - operation1 - operation2 +headers: + Authorization: Bearer token """; @@ -50,7 +52,10 @@ public void LoadJsonInput() "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } """; @@ -79,7 +84,10 @@ public void RoundtripJson() "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } """; @@ -111,6 +119,8 @@ public void RoundtripYaml() allowedTools: - operation1 - operation2 +headers: + Authorization: Bearer token """; @@ -144,7 +154,10 @@ public void ToJsonProducesValidJson() "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } """; @@ -170,6 +183,8 @@ public void ToYamlProducesValidYaml() allowedTools: - operation1 - operation2 +headers: + Authorization: Bearer token """; diff --git a/runtime/csharp/AgentSchema/McpTool.cs b/runtime/csharp/AgentSchema/McpTool.cs index 4fbfa079..82e7e728 100644 --- a/runtime/csharp/AgentSchema/McpTool.cs +++ b/runtime/csharp/AgentSchema/McpTool.cs @@ -55,6 +55,11 @@ public McpTool() /// public IList? AllowedTools { get; set; } + /// + /// Custom HTTP headers to include in requests to the MCP server, useful for authentication or routing + /// + public IDictionary? Headers { get; set; } + #region Load Methods @@ -106,6 +111,11 @@ public McpTool() instance.AllowedTools = (allowedToolsValue as IEnumerable)?.Select(x => x?.ToString()!).ToList() ?? []; } + if (data.TryGetValue("headers", out var headersValue) && headersValue is not null) + { + instance.Headers = headersValue.GetDictionary()!; + } + if (context is not null) { instance = context.ProcessOutput(instance); @@ -167,6 +177,11 @@ public McpTool() result["allowedTools"] = obj.AllowedTools; } + if (obj.Headers is not null) + { + result["headers"] = obj.Headers; + } + return result; } diff --git a/runtime/go/agentschema/mcp_tool_test.go b/runtime/go/agentschema/mcp_tool_test.go index f2f6e37b..015de0d0 100644 --- a/runtime/go/agentschema/mcp_tool_test.go +++ b/runtime/go/agentschema/mcp_tool_test.go @@ -27,7 +27,10 @@ func TestMcpToolLoadJSON(t *testing.T) { "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } ` var data map[string]interface{} @@ -64,6 +67,8 @@ approvalMode: allowedTools: - operation1 - operation2 +headers: + Authorization: Bearer token ` var data map[string]interface{} @@ -103,7 +108,10 @@ func TestMcpToolRoundtrip(t *testing.T) { "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } ` var data map[string]interface{} @@ -150,7 +158,10 @@ func TestMcpToolToJSON(t *testing.T) { "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } ` var data map[string]interface{} @@ -190,7 +201,10 @@ func TestMcpToolToYAML(t *testing.T) { "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } ` var data map[string]interface{} diff --git a/runtime/go/agentschema/tool.go b/runtime/go/agentschema/tool.go index 81b7bc7c..5969e526 100644 --- a/runtime/go/agentschema/tool.go +++ b/runtime/go/agentschema/tool.go @@ -574,12 +574,13 @@ func FileSearchToolFromYAML(yamlStr string) (FileSearchTool, error) { // McpTool represents The MCP Server tool. type McpTool struct { - Kind string `json:"kind" yaml:"kind"` - Connection interface{} `json:"connection" yaml:"connection"` - ServerName string `json:"serverName" yaml:"serverName"` - ServerDescription *string `json:"serverDescription,omitempty" yaml:"serverDescription,omitempty"` - ApprovalMode interface{} `json:"approvalMode" yaml:"approvalMode"` - AllowedTools []string `json:"allowedTools,omitempty" yaml:"allowedTools,omitempty"` + Kind string `json:"kind" yaml:"kind"` + Connection interface{} `json:"connection" yaml:"connection"` + ServerName string `json:"serverName" yaml:"serverName"` + ServerDescription *string `json:"serverDescription,omitempty" yaml:"serverDescription,omitempty"` + ApprovalMode interface{} `json:"approvalMode" yaml:"approvalMode"` + AllowedTools []string `json:"allowedTools,omitempty" yaml:"allowedTools,omitempty"` + Headers map[string]interface{} `json:"headers,omitempty" yaml:"headers,omitempty"` } // LoadMcpTool creates a McpTool from a map[string]interface{} @@ -620,6 +621,11 @@ func LoadMcpTool(data interface{}, ctx *LoadContext) (McpTool, error) { } } } + if val, ok := m["headers"]; ok && val != nil { + if m, ok := val.(map[string]interface{}); ok { + result.Headers = m + } + } } return result, nil @@ -654,6 +660,9 @@ func (obj *McpTool) Save(ctx *SaveContext) map[string]interface{} { result["approvalMode"] = obj.ApprovalMode } result["allowedTools"] = obj.AllowedTools + if obj.Headers != nil { + result["headers"] = obj.Headers + } return result } diff --git a/runtime/python/agentschema/src/agentschema/_AgentDefinition.py b/runtime/python/agentschema/src/agentschema/_AgentDefinition.py index 767785b3..1ff3312f 100644 --- a/runtime/python/agentschema/src/agentschema/_AgentDefinition.py +++ b/runtime/python/agentschema/src/agentschema/_AgentDefinition.py @@ -18,13 +18,14 @@ from ._Tool import Tool + @dataclass class AgentDefinition(ABC): """The following is a specification for defining AI agents with structured metadata, inputs, outputs, tools, and templates. It provides a way to create reusable and composable AI agents that can be executed with specific configurations. The specification includes metadata about the agent, model configuration, input parameters, expected outputs, available tools, and template configurations for prompt rendering. - + Attributes ---------- kind : str @@ -63,16 +64,17 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "AgentDefinition": AgentDefinition: The loaded AgentDefinition instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for AgentDefinition: {data}") # load polymorphic AgentDefinition instance instance = AgentDefinition.load_kind(data, context) + if data is not None and "kind" in data: instance.kind = data["kind"] if data is not None and "name" in data: @@ -91,6 +93,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "AgentDefinition": instance = context.process_output(instance) return instance + + @staticmethod def load_kind(data: dict, context: Optional[LoadContext]) -> "AgentDefinition": # load polymorphic AgentDefinition instance @@ -104,13 +108,12 @@ def load_kind(data: dict, context: Optional[LoadContext]) -> "AgentDefinition": return ContainerAgent.load(data, context) else: - raise ValueError( - f"Unknown AgentDefinition discriminator value: {discriminator_value}" - ) + raise ValueError(f"Unknown AgentDefinition discriminator value: {discriminator_value}") else: raise ValueError("Missing AgentDefinition discriminator property: 'kind'") + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the AgentDefinition instance to a dictionary. Args: @@ -122,6 +125,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -175,7 +179,7 @@ class PromptAgent(AgentDefinition): """Prompt based agent definition. Used to create agents that can be executed directly. These agents can leverage tools, input parameters, and templates to generate responses. They are designed to be straightforward and easy to use for various applications. - + Attributes ---------- kind : str @@ -211,10 +215,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "PromptAgent": PromptAgent: The loaded PromptAgent instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for PromptAgent: {data}") @@ -237,6 +241,7 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "PromptAgent": instance = context.process_output(instance) return instance + @staticmethod def load_tools(data: dict | list, context: Optional[LoadContext]) -> list[Tool]: if isinstance(data, dict): @@ -253,15 +258,13 @@ def load_tools(data: dict | list, context: Optional[LoadContext]) -> list[Tool]: return [Tool.load(item, context) for item in data] @staticmethod - def save_tools( - items: list[Tool], context: Optional[SaveContext] - ) -> dict[str, Any] | list[dict[str, Any]]: + def save_tools(items: list[Tool], context: Optional[SaveContext]) -> dict[str, Any] | list[dict[str, Any]]: if context is None: context = SaveContext() - + if context.collection_format == "array": return [item.save(context) for item in items] - + # Object format: use name as key result: dict[str, Any] = {} for item in items: @@ -269,13 +272,9 @@ def save_tools( name = item_data.pop("name", None) if name: # Check if we can use shorthand (only primary property set) - if context.use_shorthand and hasattr(item, "_shorthand_property"): + if context.use_shorthand and hasattr(item, '_shorthand_property'): shorthand_prop = item._shorthand_property - if ( - shorthand_prop - and len(item_data) == 1 - and shorthand_prop in item_data - ): + if shorthand_prop and len(item_data) == 1 and shorthand_prop in item_data: result[name] = item_data[shorthand_prop] continue result[name] = item_data @@ -286,6 +285,7 @@ def save_tools( result["_unnamed"].append(item_data) return result + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the PromptAgent instance to a dictionary. Args: @@ -297,10 +297,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.model is not None: @@ -347,15 +349,15 @@ class Workflow(AgentDefinition): """A workflow agent that can orchestrate multiple steps and actions. This agent type is designed to handle complex workflows that may involve multiple tools, models, and decision points. - + The workflow agent can be configured with a series of steps that define the flow of execution, including conditional logic and parallel processing. This allows for the creation of sophisticated AI-driven processes that can adapt to various scenarios and requirements. - + Note: The detailed structure of the workflow steps and actions is not defined here and would need to be implemented based on specific use cases and requirements. - + Attributes ---------- kind : str @@ -379,10 +381,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Workflow": Workflow: The loaded Workflow instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for Workflow: {data}") @@ -397,6 +399,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Workflow": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the Workflow instance to a dictionary. Args: @@ -408,10 +412,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.trigger is not None: @@ -450,7 +456,7 @@ class ContainerAgent(AgentDefinition): """This represents a container based agent hosted by the provider/publisher. The intent is to represent a container application that the user wants to run in a hosted environment that the provider manages. - + Attributes ---------- kind : str @@ -486,10 +492,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ContainerAgent": ContainerAgent: The loaded ContainerAgent instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for ContainerAgent: {data}") @@ -499,9 +505,7 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ContainerAgent": if data is not None and "kind" in data: instance.kind = data["kind"] if data is not None and "protocols" in data: - instance.protocols = ContainerAgent.load_protocols( - data["protocols"], context - ) + instance.protocols = ContainerAgent.load_protocols(data["protocols"], context) if data is not None and "image" in data: instance.image = data["image"] if data is not None and "dockerfilePath" in data: @@ -509,17 +513,14 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ContainerAgent": if data is not None and "resources" in data: instance.resources = ContainerResources.load(data["resources"], context) if data is not None and "environmentVariables" in data: - instance.environmentVariables = ContainerAgent.load_environmentVariables( - data["environmentVariables"], context - ) + instance.environmentVariables = ContainerAgent.load_environmentVariables(data["environmentVariables"], context) if context is not None: instance = context.process_output(instance) return instance + @staticmethod - def load_protocols( - data: dict | list, context: Optional[LoadContext] - ) -> list[ProtocolVersionRecord]: + def load_protocols(data: dict | list, context: Optional[LoadContext]) -> list[ProtocolVersionRecord]: if isinstance(data, dict): # convert simple named protocols to list of ProtocolVersionRecord result = [] @@ -534,15 +535,13 @@ def load_protocols( return [ProtocolVersionRecord.load(item, context) for item in data] @staticmethod - def save_protocols( - items: list[ProtocolVersionRecord], context: Optional[SaveContext] - ) -> dict[str, Any] | list[dict[str, Any]]: + def save_protocols(items: list[ProtocolVersionRecord], context: Optional[SaveContext]) -> dict[str, Any] | list[dict[str, Any]]: if context is None: context = SaveContext() - + if context.collection_format == "array": return [item.save(context) for item in items] - + # Object format: use name as key result: dict[str, Any] = {} for item in items: @@ -550,13 +549,9 @@ def save_protocols( name = item_data.pop("name", None) if name: # Check if we can use shorthand (only primary property set) - if context.use_shorthand and hasattr(item, "_shorthand_property"): + if context.use_shorthand and hasattr(item, '_shorthand_property'): shorthand_prop = item._shorthand_property - if ( - shorthand_prop - and len(item_data) == 1 - and shorthand_prop in item_data - ): + if shorthand_prop and len(item_data) == 1 and shorthand_prop in item_data: result[name] = item_data[shorthand_prop] continue result[name] = item_data @@ -568,9 +563,7 @@ def save_protocols( return result @staticmethod - def load_environmentVariables( - data: dict | list, context: Optional[LoadContext] - ) -> list[EnvironmentVariable]: + def load_environmentVariables(data: dict | list, context: Optional[LoadContext]) -> list[EnvironmentVariable]: if isinstance(data, dict): # convert simple named environmentVariables to list of EnvironmentVariable result = [] @@ -585,15 +578,13 @@ def load_environmentVariables( return [EnvironmentVariable.load(item, context) for item in data] @staticmethod - def save_environmentVariables( - items: list[EnvironmentVariable], context: Optional[SaveContext] - ) -> dict[str, Any] | list[dict[str, Any]]: + def save_environmentVariables(items: list[EnvironmentVariable], context: Optional[SaveContext]) -> dict[str, Any] | list[dict[str, Any]]: if context is None: context = SaveContext() - + if context.collection_format == "array": return [item.save(context) for item in items] - + # Object format: use name as key result: dict[str, Any] = {} for item in items: @@ -601,13 +592,9 @@ def save_environmentVariables( name = item_data.pop("name", None) if name: # Check if we can use shorthand (only primary property set) - if context.use_shorthand and hasattr(item, "_shorthand_property"): + if context.use_shorthand and hasattr(item, '_shorthand_property'): shorthand_prop = item._shorthand_property - if ( - shorthand_prop - and len(item_data) == 1 - and shorthand_prop in item_data - ): + if shorthand_prop and len(item_data) == 1 and shorthand_prop in item_data: result[name] = item_data[shorthand_prop] continue result[name] = item_data @@ -618,6 +605,7 @@ def save_environmentVariables( result["_unnamed"].append(item_data) return result + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the ContainerAgent instance to a dictionary. Args: @@ -629,10 +617,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.protocols is not None: @@ -644,9 +634,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: if obj.resources is not None: result["resources"] = obj.resources.save(context) if obj.environmentVariables is not None: - result["environmentVariables"] = ContainerAgent.save_environmentVariables( - obj.environmentVariables, context - ) + result["environmentVariables"] = ContainerAgent.save_environmentVariables(obj.environmentVariables, context) return result @@ -674,3 +662,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_AgentManifest.py b/runtime/python/agentschema/src/agentschema/_AgentManifest.py index 005c6cdb..9b87b3b3 100644 --- a/runtime/python/agentschema/src/agentschema/_AgentManifest.py +++ b/runtime/python/agentschema/src/agentschema/_AgentManifest.py @@ -13,21 +13,22 @@ from ._Resource import Resource + @dataclass class AgentManifest: """The following represents a manifest that can be used to create agents dynamically. It includes parameters that can be used to configure the agent's behavior. These parameters include values that can be used as publisher parameters that can be used to describe additional variables that have been tested and are known to work. - + Variables described here are then used to project into a prompt agent that can be executed. Once parameters are provided, these can be referenced in the manifest using the following notation: - + `{{myParameter}}` - + This allows for dynamic configuration of the agent based on the provided parameters. (This notation is used elsewhere, but only the `param` scope is supported here) - + Attributes ---------- name : str @@ -66,10 +67,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "AgentManifest": AgentManifest: The loaded AgentManifest instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for AgentManifest: {data}") @@ -89,17 +90,14 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "AgentManifest": if data is not None and "parameters" in data: instance.parameters = PropertySchema.load(data["parameters"], context) if data is not None and "resources" in data: - instance.resources = AgentManifest.load_resources( - data["resources"], context - ) + instance.resources = AgentManifest.load_resources(data["resources"], context) if context is not None: instance = context.process_output(instance) return instance + @staticmethod - def load_resources( - data: dict | list, context: Optional[LoadContext] - ) -> list[Resource]: + def load_resources(data: dict | list, context: Optional[LoadContext]) -> list[Resource]: if isinstance(data, dict): # convert simple named resources to list of Resource result = [] @@ -114,15 +112,13 @@ def load_resources( return [Resource.load(item, context) for item in data] @staticmethod - def save_resources( - items: list[Resource], context: Optional[SaveContext] - ) -> dict[str, Any] | list[dict[str, Any]]: + def save_resources(items: list[Resource], context: Optional[SaveContext]) -> dict[str, Any] | list[dict[str, Any]]: if context is None: context = SaveContext() - + if context.collection_format == "array": return [item.save(context) for item in items] - + # Object format: use name as key result: dict[str, Any] = {} for item in items: @@ -130,13 +126,9 @@ def save_resources( name = item_data.pop("name", None) if name: # Check if we can use shorthand (only primary property set) - if context.use_shorthand and hasattr(item, "_shorthand_property"): + if context.use_shorthand and hasattr(item, '_shorthand_property'): shorthand_prop = item._shorthand_property - if ( - shorthand_prop - and len(item_data) == 1 - and shorthand_prop in item_data - ): + if shorthand_prop and len(item_data) == 1 and shorthand_prop in item_data: result[name] = item_data[shorthand_prop] continue result[name] = item_data @@ -147,6 +139,7 @@ def save_resources( result["_unnamed"].append(item_data) return result + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the AgentManifest instance to a dictionary. Args: @@ -158,6 +151,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -204,3 +198,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_Binding.py b/runtime/python/agentschema/src/agentschema/_Binding.py index d40f763c..e7ee068d 100644 --- a/runtime/python/agentschema/src/agentschema/_Binding.py +++ b/runtime/python/agentschema/src/agentschema/_Binding.py @@ -10,10 +10,11 @@ from ._context import LoadContext, SaveContext + @dataclass class Binding: """Represents a binding between an input property and a tool parameter. - + Attributes ---------- name : str @@ -37,14 +38,14 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Binding": Binding: The loaded Binding instance. """ - + if context is not None: data = context.process_input(data) - + # handle alternate representations if isinstance(data, str): data = {"input": data} - + if not isinstance(data, dict): raise ValueError(f"Invalid data for Binding: {data}") @@ -59,6 +60,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Binding": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the Binding instance to a dictionary. Args: @@ -70,6 +73,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -106,3 +110,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_Connection.py b/runtime/python/agentschema/src/agentschema/_Connection.py index 8e22e0c0..8d5fa855 100644 --- a/runtime/python/agentschema/src/agentschema/_Connection.py +++ b/runtime/python/agentschema/src/agentschema/_Connection.py @@ -11,12 +11,13 @@ from ._context import LoadContext, SaveContext + @dataclass class Connection(ABC): """Connection configuration for AI agents. `provider`, `kind`, and `endpoint` are required properties here, but this section can accept additional via options. - + Attributes ---------- kind : str @@ -43,16 +44,17 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Connection": Connection: The loaded Connection instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for Connection: {data}") # load polymorphic Connection instance instance = Connection.load_kind(data, context) + if data is not None and "kind" in data: instance.kind = data["kind"] if data is not None and "authenticationMode" in data: @@ -63,6 +65,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Connection": instance = context.process_output(instance) return instance + + @staticmethod def load_kind(data: dict, context: Optional[LoadContext]) -> "Connection": # load polymorphic Connection instance @@ -82,13 +86,12 @@ def load_kind(data: dict, context: Optional[LoadContext]) -> "Connection": return OAuthConnection.load(data, context) else: - raise ValueError( - f"Unknown Connection discriminator value: {discriminator_value}" - ) + raise ValueError(f"Unknown Connection discriminator value: {discriminator_value}") else: raise ValueError("Missing Connection discriminator property: 'kind'") + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the Connection instance to a dictionary. Args: @@ -100,6 +103,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -143,7 +147,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class ReferenceConnection(Connection): """Connection configuration for AI services using named connections. - + Attributes ---------- kind : str @@ -170,10 +174,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ReferenceConnecti ReferenceConnection: The loaded ReferenceConnection instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for ReferenceConnection: {data}") @@ -190,6 +194,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ReferenceConnecti instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the ReferenceConnection instance to a dictionary. Args: @@ -201,10 +207,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.name is not None: @@ -243,7 +251,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class RemoteConnection(Connection): """Connection configuration for AI services using named connections. - + Attributes ---------- kind : str @@ -270,10 +278,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "RemoteConnection" RemoteConnection: The loaded RemoteConnection instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for RemoteConnection: {data}") @@ -290,6 +298,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "RemoteConnection" instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the RemoteConnection instance to a dictionary. Args: @@ -301,10 +311,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.name is not None: @@ -343,7 +355,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class ApiKeyConnection(Connection): """Connection configuration for AI services using API keys. - + Attributes ---------- kind : str @@ -370,10 +382,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ApiKeyConnection" ApiKeyConnection: The loaded ApiKeyConnection instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for ApiKeyConnection: {data}") @@ -390,6 +402,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ApiKeyConnection" instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the ApiKeyConnection instance to a dictionary. Args: @@ -401,10 +415,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.endpoint is not None: @@ -443,7 +459,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class AnonymousConnection(Connection): """ - + Attributes ---------- kind : str @@ -467,10 +483,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "AnonymousConnecti AnonymousConnection: The loaded AnonymousConnection instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for AnonymousConnection: {data}") @@ -485,6 +501,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "AnonymousConnecti instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the AnonymousConnection instance to a dictionary. Args: @@ -496,10 +514,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.endpoint is not None: @@ -538,7 +558,7 @@ class FoundryConnection(Connection): """Connection configuration for Microsoft Foundry projects. Provides project-scoped access to models, tools, and services via Entra ID (DefaultAzureCredential) authentication. - + Attributes ---------- kind : str @@ -568,10 +588,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "FoundryConnection FoundryConnection: The loaded FoundryConnection instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for FoundryConnection: {data}") @@ -590,6 +610,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "FoundryConnection instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the FoundryConnection instance to a dictionary. Args: @@ -601,10 +623,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.endpoint is not None: @@ -647,7 +671,7 @@ class OAuthConnection(Connection): """Connection configuration using OAuth 2.0 client credentials. Useful for tools and services that require OAuth authentication, such as MCP servers, OpenAPI endpoints, or other REST APIs. - + Attributes ---------- kind : str @@ -683,10 +707,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "OAuthConnection": OAuthConnection: The loaded OAuthConnection instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for OAuthConnection: {data}") @@ -709,6 +733,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "OAuthConnection": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the OAuthConnection instance to a dictionary. Args: @@ -720,10 +746,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.endpoint is not None: @@ -763,3 +791,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_ContainerResources.py b/runtime/python/agentschema/src/agentschema/_ContainerResources.py index 6d14daf0..916c0fb8 100644 --- a/runtime/python/agentschema/src/agentschema/_ContainerResources.py +++ b/runtime/python/agentschema/src/agentschema/_ContainerResources.py @@ -10,11 +10,12 @@ from ._context import LoadContext, SaveContext + @dataclass class ContainerResources: """Resource allocation for a containerized agent. Valid CPU and memory pairings depend on the target hosting provider. - + Attributes ---------- cpu : str @@ -38,10 +39,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ContainerResource ContainerResources: The loaded ContainerResources instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for ContainerResources: {data}") @@ -56,6 +57,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ContainerResource instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the ContainerResources instance to a dictionary. Args: @@ -67,6 +70,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -103,3 +107,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_EnvironmentVariable.py b/runtime/python/agentschema/src/agentschema/_EnvironmentVariable.py index bbbf19e7..b645c356 100644 --- a/runtime/python/agentschema/src/agentschema/_EnvironmentVariable.py +++ b/runtime/python/agentschema/src/agentschema/_EnvironmentVariable.py @@ -10,10 +10,11 @@ from ._context import LoadContext, SaveContext + @dataclass class EnvironmentVariable: """Definition for an environment variable used in containerized agents. - + Attributes ---------- name : str @@ -37,10 +38,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "EnvironmentVariab EnvironmentVariable: The loaded EnvironmentVariable instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for EnvironmentVariable: {data}") @@ -55,6 +56,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "EnvironmentVariab instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the EnvironmentVariable instance to a dictionary. Args: @@ -66,6 +69,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -102,3 +106,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_Format.py b/runtime/python/agentschema/src/agentschema/_Format.py index d2c149ed..5edbd294 100644 --- a/runtime/python/agentschema/src/agentschema/_Format.py +++ b/runtime/python/agentschema/src/agentschema/_Format.py @@ -10,10 +10,11 @@ from ._context import LoadContext, SaveContext + @dataclass class Format: """Template format definition - + Attributes ---------- kind : str @@ -40,14 +41,14 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Format": Format: The loaded Format instance. """ - + if context is not None: data = context.process_input(data) - + # handle alternate representations if isinstance(data, str): data = {"kind": data} - + if not isinstance(data, dict): raise ValueError(f"Invalid data for Format: {data}") @@ -64,6 +65,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Format": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the Format instance to a dictionary. Args: @@ -75,6 +78,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -113,3 +117,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_McpServerApprovalMode.py b/runtime/python/agentschema/src/agentschema/_McpServerApprovalMode.py index 87d5f443..7256d65a 100644 --- a/runtime/python/agentschema/src/agentschema/_McpServerApprovalMode.py +++ b/runtime/python/agentschema/src/agentschema/_McpServerApprovalMode.py @@ -11,10 +11,11 @@ from ._context import LoadContext, SaveContext + @dataclass class McpServerApprovalMode(ABC): """The approval mode for MCP server tools. - + Attributes ---------- kind : str @@ -26,9 +27,7 @@ class McpServerApprovalMode(ABC): kind: str = field(default="") @staticmethod - def load( - data: Any, context: Optional[LoadContext] = None - ) -> "McpServerApprovalMode": + def load(data: Any, context: Optional[LoadContext] = None) -> "McpServerApprovalMode": """Load a McpServerApprovalMode instance. Args: data (Any): The data to load the instance from. @@ -37,30 +36,31 @@ def load( McpServerApprovalMode: The loaded McpServerApprovalMode instance. """ - + if context is not None: data = context.process_input(data) - + # handle alternate representations if isinstance(data, str): data = {"kind": data} - + if not isinstance(data, dict): raise ValueError(f"Invalid data for McpServerApprovalMode: {data}") # load polymorphic McpServerApprovalMode instance instance = McpServerApprovalMode.load_kind(data, context) + if data is not None and "kind" in data: instance.kind = data["kind"] if context is not None: instance = context.process_output(instance) return instance + + @staticmethod - def load_kind( - data: dict, context: Optional[LoadContext] - ) -> "McpServerApprovalMode": + def load_kind(data: dict, context: Optional[LoadContext]) -> "McpServerApprovalMode": # load polymorphic McpServerApprovalMode instance if data is not None and "kind" in data: discriminator_value = str(data["kind"]).lower() @@ -72,14 +72,11 @@ def load_kind( return McpServerToolSpecifyApprovalMode.load(data, context) else: - raise ValueError( - f"Unknown McpServerApprovalMode discriminator value: {discriminator_value}" - ) + raise ValueError(f"Unknown McpServerApprovalMode discriminator value: {discriminator_value}") else: - raise ValueError( - "Missing McpServerApprovalMode discriminator property: 'kind'" - ) + raise ValueError("Missing McpServerApprovalMode discriminator property: 'kind'") + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the McpServerApprovalMode instance to a dictionary. @@ -92,6 +89,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -131,7 +129,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class McpServerToolAlwaysRequireApprovalMode(McpServerApprovalMode): """ - + Attributes ---------- kind : str @@ -143,9 +141,7 @@ class McpServerToolAlwaysRequireApprovalMode(McpServerApprovalMode): kind: str = field(default="always") @staticmethod - def load( - data: Any, context: Optional[LoadContext] = None - ) -> "McpServerToolAlwaysRequireApprovalMode": + def load(data: Any, context: Optional[LoadContext] = None) -> "McpServerToolAlwaysRequireApprovalMode": """Load a McpServerToolAlwaysRequireApprovalMode instance. Args: data (Any): The data to load the instance from. @@ -154,14 +150,12 @@ def load( McpServerToolAlwaysRequireApprovalMode: The loaded McpServerToolAlwaysRequireApprovalMode instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): - raise ValueError( - f"Invalid data for McpServerToolAlwaysRequireApprovalMode: {data}" - ) + raise ValueError(f"Invalid data for McpServerToolAlwaysRequireApprovalMode: {data}") # create new instance instance = McpServerToolAlwaysRequireApprovalMode() @@ -172,6 +166,8 @@ def load( instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the McpServerToolAlwaysRequireApprovalMode instance to a dictionary. Args: @@ -183,10 +179,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind @@ -221,7 +219,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class McpServerToolNeverRequireApprovalMode(McpServerApprovalMode): """ - + Attributes ---------- kind : str @@ -233,9 +231,7 @@ class McpServerToolNeverRequireApprovalMode(McpServerApprovalMode): kind: str = field(default="never") @staticmethod - def load( - data: Any, context: Optional[LoadContext] = None - ) -> "McpServerToolNeverRequireApprovalMode": + def load(data: Any, context: Optional[LoadContext] = None) -> "McpServerToolNeverRequireApprovalMode": """Load a McpServerToolNeverRequireApprovalMode instance. Args: data (Any): The data to load the instance from. @@ -244,14 +240,12 @@ def load( McpServerToolNeverRequireApprovalMode: The loaded McpServerToolNeverRequireApprovalMode instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): - raise ValueError( - f"Invalid data for McpServerToolNeverRequireApprovalMode: {data}" - ) + raise ValueError(f"Invalid data for McpServerToolNeverRequireApprovalMode: {data}") # create new instance instance = McpServerToolNeverRequireApprovalMode() @@ -262,6 +256,8 @@ def load( instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the McpServerToolNeverRequireApprovalMode instance to a dictionary. Args: @@ -273,10 +269,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind @@ -311,7 +309,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class McpServerToolSpecifyApprovalMode(McpServerApprovalMode): """ - + Attributes ---------- kind : str @@ -329,9 +327,7 @@ class McpServerToolSpecifyApprovalMode(McpServerApprovalMode): neverRequireApprovalTools: list[str] = field(default_factory=list) @staticmethod - def load( - data: Any, context: Optional[LoadContext] = None - ) -> "McpServerToolSpecifyApprovalMode": + def load(data: Any, context: Optional[LoadContext] = None) -> "McpServerToolSpecifyApprovalMode": """Load a McpServerToolSpecifyApprovalMode instance. Args: data (Any): The data to load the instance from. @@ -340,14 +336,12 @@ def load( McpServerToolSpecifyApprovalMode: The loaded McpServerToolSpecifyApprovalMode instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): - raise ValueError( - f"Invalid data for McpServerToolSpecifyApprovalMode: {data}" - ) + raise ValueError(f"Invalid data for McpServerToolSpecifyApprovalMode: {data}") # create new instance instance = McpServerToolSpecifyApprovalMode() @@ -362,6 +356,8 @@ def load( instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the McpServerToolSpecifyApprovalMode instance to a dictionary. Args: @@ -373,10 +369,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.alwaysRequireApprovalTools is not None: @@ -410,3 +408,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_Model.py b/runtime/python/agentschema/src/agentschema/_Model.py index 87182c2d..a8766c4a 100644 --- a/runtime/python/agentschema/src/agentschema/_Model.py +++ b/runtime/python/agentschema/src/agentschema/_Model.py @@ -12,12 +12,13 @@ from ._ModelOptions import ModelOptions + @dataclass class Model: """Model for defining the structure and behavior of AI agents. This model includes properties for specifying the model's provider, connection details, and various options. It allows for flexible configuration of AI models to suit different use cases and requirements. - + Attributes ---------- id : str @@ -50,14 +51,14 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Model": Model: The loaded Model instance. """ - + if context is not None: data = context.process_input(data) - + # handle alternate representations if isinstance(data, str): data = {"id": data} - + if not isinstance(data, dict): raise ValueError(f"Invalid data for Model: {data}") @@ -78,6 +79,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Model": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the Model instance to a dictionary. Args: @@ -89,6 +92,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -131,3 +135,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_ModelOptions.py b/runtime/python/agentschema/src/agentschema/_ModelOptions.py index c01f3180..49110617 100644 --- a/runtime/python/agentschema/src/agentschema/_ModelOptions.py +++ b/runtime/python/agentschema/src/agentschema/_ModelOptions.py @@ -10,11 +10,12 @@ from ._context import LoadContext, SaveContext + @dataclass class ModelOptions: """Options for configuring the behavior of the AI model. `kind` is a required property here, but this section can accept additional via options. - + Attributes ---------- frequencyPenalty : Optional[float] @@ -62,10 +63,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ModelOptions": ModelOptions: The loaded ModelOptions instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for ModelOptions: {data}") @@ -96,6 +97,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ModelOptions": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the ModelOptions instance to a dictionary. Args: @@ -107,6 +110,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -159,3 +163,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_Parser.py b/runtime/python/agentschema/src/agentschema/_Parser.py index 1dcdd5dd..eaaa9ea0 100644 --- a/runtime/python/agentschema/src/agentschema/_Parser.py +++ b/runtime/python/agentschema/src/agentschema/_Parser.py @@ -10,10 +10,11 @@ from ._context import LoadContext, SaveContext + @dataclass class Parser: """Template parser definition - + Attributes ---------- kind : str @@ -37,14 +38,14 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Parser": Parser: The loaded Parser instance. """ - + if context is not None: data = context.process_input(data) - + # handle alternate representations if isinstance(data, str): data = {"kind": data} - + if not isinstance(data, dict): raise ValueError(f"Invalid data for Parser: {data}") @@ -59,6 +60,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Parser": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the Parser instance to a dictionary. Args: @@ -70,6 +73,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -106,3 +110,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_Property.py b/runtime/python/agentschema/src/agentschema/_Property.py index 5b1cc674..c6fbfea3 100644 --- a/runtime/python/agentschema/src/agentschema/_Property.py +++ b/runtime/python/agentschema/src/agentschema/_Property.py @@ -10,15 +10,16 @@ from ._context import LoadContext, SaveContext + @dataclass class Property: """Represents a single property. - + - This model defines the structure of properties that can be used in prompts, including their type, description, whether they are required, and other attributes. - It allows for the definition of dynamic inputs that can be filled with data and processed to generate prompts for AI models. - + Attributes ---------- name : str @@ -57,26 +58,27 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Property": Property: The loaded Property instance. """ - + if context is not None: data = context.process_input(data) - + # handle alternate representations if isinstance(data, bool): - data = {"kind": "boolean", "example": data} + data = {"kind":"boolean","example": data} if isinstance(data, float): - data = {"kind": "float", "example": data} + data = {"kind":"float","example": data} if isinstance(data, int): - data = {"kind": "integer", "example": data} + data = {"kind":"integer","example": data} if isinstance(data, str): - data = {"kind": "string", "example": data} - + data = {"kind":"string","example": data} + if not isinstance(data, dict): raise ValueError(f"Invalid data for Property: {data}") # load polymorphic Property instance instance = Property.load_kind(data, context) + if data is not None and "name" in data: instance.name = data["name"] if data is not None and "kind" in data: @@ -95,6 +97,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Property": instance = context.process_output(instance) return instance + + @staticmethod def load_kind(data: dict, context: Optional[LoadContext]) -> "Property": # load polymorphic Property instance @@ -110,6 +114,7 @@ def load_kind(data: dict, context: Optional[LoadContext]) -> "Property": # create new instance (stop recursion) return Property() + else: # create new instance @@ -126,6 +131,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -178,11 +184,11 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str class ArrayProperty(Property): """Represents an array property. This extends the base Property model to represent an array of items. - + Attributes ---------- kind : str - + items : Property The type of items contained in the array """ @@ -202,10 +208,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ArrayProperty": ArrayProperty: The loaded ArrayProperty instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for ArrayProperty: {data}") @@ -220,6 +226,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ArrayProperty": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the ArrayProperty instance to a dictionary. Args: @@ -231,10 +239,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.items is not None: @@ -272,11 +282,11 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str class ObjectProperty(Property): """Represents an object property. This extends the base Property model to represent a structured object. - + Attributes ---------- kind : str - + properties : list[Property] The properties contained in the object """ @@ -296,10 +306,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ObjectProperty": ObjectProperty: The loaded ObjectProperty instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for ObjectProperty: {data}") @@ -309,17 +319,14 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ObjectProperty": if data is not None and "kind" in data: instance.kind = data["kind"] if data is not None and "properties" in data: - instance.properties = ObjectProperty.load_properties( - data["properties"], context - ) + instance.properties = ObjectProperty.load_properties(data["properties"], context) if context is not None: instance = context.process_output(instance) return instance + @staticmethod - def load_properties( - data: dict | list, context: Optional[LoadContext] - ) -> list[Property]: + def load_properties(data: dict | list, context: Optional[LoadContext]) -> list[Property]: if isinstance(data, dict): # convert simple named properties to list of Property result = [] @@ -334,15 +341,13 @@ def load_properties( return [Property.load(item, context) for item in data] @staticmethod - def save_properties( - items: list[Property], context: Optional[SaveContext] - ) -> dict[str, Any] | list[dict[str, Any]]: + def save_properties(items: list[Property], context: Optional[SaveContext]) -> dict[str, Any] | list[dict[str, Any]]: if context is None: context = SaveContext() - + if context.collection_format == "array": return [item.save(context) for item in items] - + # Object format: use name as key result: dict[str, Any] = {} for item in items: @@ -350,13 +355,9 @@ def save_properties( name = item_data.pop("name", None) if name: # Check if we can use shorthand (only primary property set) - if context.use_shorthand and hasattr(item, "_shorthand_property"): + if context.use_shorthand and hasattr(item, '_shorthand_property'): shorthand_prop = item._shorthand_property - if ( - shorthand_prop - and len(item_data) == 1 - and shorthand_prop in item_data - ): + if shorthand_prop and len(item_data) == 1 and shorthand_prop in item_data: result[name] = item_data[shorthand_prop] continue result[name] = item_data @@ -367,6 +368,7 @@ def save_properties( result["_unnamed"].append(item_data) return result + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the ObjectProperty instance to a dictionary. Args: @@ -378,16 +380,16 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.properties is not None: - result["properties"] = ObjectProperty.save_properties( - obj.properties, context - ) + result["properties"] = ObjectProperty.save_properties(obj.properties, context) return result @@ -415,3 +417,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_PropertySchema.py b/runtime/python/agentschema/src/agentschema/_PropertySchema.py index 5eecc353..dcf39ea6 100644 --- a/runtime/python/agentschema/src/agentschema/_PropertySchema.py +++ b/runtime/python/agentschema/src/agentschema/_PropertySchema.py @@ -11,11 +11,12 @@ from ._Property import Property + @dataclass class PropertySchema: """Definition for the property schema of a model. This includes the properties and example records. - + Attributes ---------- examples : Optional[dict[str, Any]] @@ -42,10 +43,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "PropertySchema": PropertySchema: The loaded PropertySchema instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for PropertySchema: {data}") @@ -57,17 +58,14 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "PropertySchema": if data is not None and "strict" in data: instance.strict = data["strict"] if data is not None and "properties" in data: - instance.properties = PropertySchema.load_properties( - data["properties"], context - ) + instance.properties = PropertySchema.load_properties(data["properties"], context) if context is not None: instance = context.process_output(instance) return instance + @staticmethod - def load_properties( - data: dict | list, context: Optional[LoadContext] - ) -> list[Property]: + def load_properties(data: dict | list, context: Optional[LoadContext]) -> list[Property]: if isinstance(data, dict): # convert simple named properties to list of Property result = [] @@ -82,15 +80,13 @@ def load_properties( return [Property.load(item, context) for item in data] @staticmethod - def save_properties( - items: list[Property], context: Optional[SaveContext] - ) -> dict[str, Any] | list[dict[str, Any]]: + def save_properties(items: list[Property], context: Optional[SaveContext]) -> dict[str, Any] | list[dict[str, Any]]: if context is None: context = SaveContext() - + if context.collection_format == "array": return [item.save(context) for item in items] - + # Object format: use name as key result: dict[str, Any] = {} for item in items: @@ -98,13 +94,9 @@ def save_properties( name = item_data.pop("name", None) if name: # Check if we can use shorthand (only primary property set) - if context.use_shorthand and hasattr(item, "_shorthand_property"): + if context.use_shorthand and hasattr(item, '_shorthand_property'): shorthand_prop = item._shorthand_property - if ( - shorthand_prop - and len(item_data) == 1 - and shorthand_prop in item_data - ): + if shorthand_prop and len(item_data) == 1 and shorthand_prop in item_data: result[name] = item_data[shorthand_prop] continue result[name] = item_data @@ -115,6 +107,7 @@ def save_properties( result["_unnamed"].append(item_data) return result + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the PropertySchema instance to a dictionary. Args: @@ -126,6 +119,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -134,9 +128,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: if obj.strict is not None: result["strict"] = obj.strict if obj.properties is not None: - result["properties"] = PropertySchema.save_properties( - obj.properties, context - ) + result["properties"] = PropertySchema.save_properties(obj.properties, context) if context is not None: result = context.process_dict(result) @@ -166,3 +158,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_ProtocolVersionRecord.py b/runtime/python/agentschema/src/agentschema/_ProtocolVersionRecord.py index c69d01ab..1d76f7ab 100644 --- a/runtime/python/agentschema/src/agentschema/_ProtocolVersionRecord.py +++ b/runtime/python/agentschema/src/agentschema/_ProtocolVersionRecord.py @@ -10,10 +10,11 @@ from ._context import LoadContext, SaveContext + @dataclass class ProtocolVersionRecord: """ - + Attributes ---------- protocol : str @@ -28,9 +29,7 @@ class ProtocolVersionRecord: version: str = field(default="") @staticmethod - def load( - data: Any, context: Optional[LoadContext] = None - ) -> "ProtocolVersionRecord": + def load(data: Any, context: Optional[LoadContext] = None) -> "ProtocolVersionRecord": """Load a ProtocolVersionRecord instance. Args: data (Any): The data to load the instance from. @@ -39,10 +38,10 @@ def load( ProtocolVersionRecord: The loaded ProtocolVersionRecord instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for ProtocolVersionRecord: {data}") @@ -57,6 +56,8 @@ def load( instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the ProtocolVersionRecord instance to a dictionary. Args: @@ -68,6 +69,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -104,3 +106,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_Resource.py b/runtime/python/agentschema/src/agentschema/_Resource.py index ff65f658..dea2cd6a 100644 --- a/runtime/python/agentschema/src/agentschema/_Resource.py +++ b/runtime/python/agentschema/src/agentschema/_Resource.py @@ -11,12 +11,13 @@ from ._context import LoadContext, SaveContext + @dataclass class Resource(ABC): """Represents a resource required by the agent Resources can include databases, APIs, or other external systems that the agent needs to interact with to perform its tasks - + Attributes ---------- name : str @@ -40,16 +41,17 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Resource": Resource: The loaded Resource instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for Resource: {data}") # load polymorphic Resource instance instance = Resource.load_kind(data, context) + if data is not None and "name" in data: instance.name = data["name"] if data is not None and "kind" in data: @@ -58,6 +60,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Resource": instance = context.process_output(instance) return instance + + @staticmethod def load_kind(data: dict, context: Optional[LoadContext]) -> "Resource": # load polymorphic Resource instance @@ -69,13 +73,12 @@ def load_kind(data: dict, context: Optional[LoadContext]) -> "Resource": return ToolResource.load(data, context) else: - raise ValueError( - f"Unknown Resource discriminator value: {discriminator_value}" - ) + raise ValueError(f"Unknown Resource discriminator value: {discriminator_value}") else: raise ValueError("Missing Resource discriminator property: 'kind'") + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the Resource instance to a dictionary. Args: @@ -87,6 +90,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -128,7 +132,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class ModelResource(Resource): """Represents a model resource required by the agent - + Attributes ---------- kind : str @@ -152,10 +156,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ModelResource": ModelResource: The loaded ModelResource instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for ModelResource: {data}") @@ -170,6 +174,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ModelResource": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the ModelResource instance to a dictionary. Args: @@ -181,10 +187,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.id is not None: @@ -221,7 +229,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class ToolResource(Resource): """Represents a tool resource required by the agent - + Attributes ---------- kind : str @@ -248,10 +256,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ToolResource": ToolResource: The loaded ToolResource instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for ToolResource: {data}") @@ -268,6 +276,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "ToolResource": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the ToolResource instance to a dictionary. Args: @@ -279,10 +289,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.id is not None: @@ -316,3 +328,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_Template.py b/runtime/python/agentschema/src/agentschema/_Template.py index 163dea16..9ab360f6 100644 --- a/runtime/python/agentschema/src/agentschema/_Template.py +++ b/runtime/python/agentschema/src/agentschema/_Template.py @@ -12,17 +12,18 @@ from ._Parser import Parser + @dataclass class Template: """Template model for defining prompt templates. - + This model specifies the rendering engine used for slot filling prompts, the parser used to process the rendered template into API-compatible format, and additional options for the template engine. - + It allows for the creation of reusable templates that can be filled with dynamic data and processed to generate prompts for AI models. - + Attributes ---------- format : Format @@ -46,10 +47,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Template": Template: The loaded Template instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for Template: {data}") @@ -64,6 +65,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Template": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the Template instance to a dictionary. Args: @@ -75,6 +78,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -111,3 +115,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/_Tool.py b/runtime/python/agentschema/src/agentschema/_Tool.py index 802ef16e..45ae86a5 100644 --- a/runtime/python/agentschema/src/agentschema/_Tool.py +++ b/runtime/python/agentschema/src/agentschema/_Tool.py @@ -15,10 +15,11 @@ from ._PropertySchema import PropertySchema + @dataclass class Tool(ABC): """Represents a tool that can be used in prompts. - + Attributes ---------- name : str @@ -48,16 +49,17 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Tool": Tool: The loaded Tool instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for Tool: {data}") # load polymorphic Tool instance instance = Tool.load_kind(data, context) + if data is not None and "name" in data: instance.name = data["name"] if data is not None and "kind" in data: @@ -70,10 +72,9 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "Tool": instance = context.process_output(instance) return instance + @staticmethod - def load_bindings( - data: dict | list, context: Optional[LoadContext] - ) -> list[Binding]: + def load_bindings(data: dict | list, context: Optional[LoadContext]) -> list[Binding]: if isinstance(data, dict): # convert simple named bindings to list of Binding result = [] @@ -88,15 +89,13 @@ def load_bindings( return [Binding.load(item, context) for item in data] @staticmethod - def save_bindings( - items: list[Binding], context: Optional[SaveContext] - ) -> dict[str, Any] | list[dict[str, Any]]: + def save_bindings(items: list[Binding], context: Optional[SaveContext]) -> dict[str, Any] | list[dict[str, Any]]: if context is None: context = SaveContext() - + if context.collection_format == "array": return [item.save(context) for item in items] - + # Object format: use name as key result: dict[str, Any] = {} for item in items: @@ -104,13 +103,9 @@ def save_bindings( name = item_data.pop("name", None) if name: # Check if we can use shorthand (only primary property set) - if context.use_shorthand and hasattr(item, "_shorthand_property"): + if context.use_shorthand and hasattr(item, '_shorthand_property'): shorthand_prop = item._shorthand_property - if ( - shorthand_prop - and len(item_data) == 1 - and shorthand_prop in item_data - ): + if shorthand_prop and len(item_data) == 1 and shorthand_prop in item_data: result[name] = item_data[shorthand_prop] continue result[name] = item_data @@ -121,6 +116,7 @@ def save_bindings( result["_unnamed"].append(item_data) return result + @staticmethod def load_kind(data: dict, context: Optional[LoadContext]) -> "Tool": # load polymorphic Tool instance @@ -148,6 +144,7 @@ def load_kind(data: dict, context: Optional[LoadContext]) -> "Tool": raise ValueError("Missing Tool discriminator property: 'kind'") + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the Tool instance to a dictionary. Args: @@ -159,6 +156,7 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + result: dict[str, Any] = {} @@ -204,7 +202,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class FunctionTool(Tool): """Represents a local function tool. - + Attributes ---------- kind : str @@ -231,10 +229,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "FunctionTool": FunctionTool: The loaded FunctionTool instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for FunctionTool: {data}") @@ -251,6 +249,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "FunctionTool": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the FunctionTool instance to a dictionary. Args: @@ -262,10 +262,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.parameters is not None: @@ -308,7 +310,7 @@ class CustomTool(Tool): It may include features such as authentication, data storage, and long-running processes This tool kind is ideal for tasks that involve complex computations or access to secure resources Server tools can be used to offload heavy processing from client applications - + Attributes ---------- kind : str @@ -335,10 +337,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "CustomTool": CustomTool: The loaded CustomTool instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for CustomTool: {data}") @@ -355,6 +357,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "CustomTool": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the CustomTool instance to a dictionary. Args: @@ -366,10 +370,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.connection is not None: @@ -408,7 +414,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class WebSearchTool(Tool): """The Bing search tool. - + Attributes ---------- kind : str @@ -435,10 +441,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "WebSearchTool": WebSearchTool: The loaded WebSearchTool instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for WebSearchTool: {data}") @@ -455,6 +461,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "WebSearchTool": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the WebSearchTool instance to a dictionary. Args: @@ -466,10 +474,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.connection is not None: @@ -509,7 +519,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str class FileSearchTool(Tool): """A tool for searching files. This tool allows an AI agent to search for files based on a query. - + Attributes ---------- kind : str @@ -548,10 +558,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "FileSearchTool": FileSearchTool: The loaded FileSearchTool instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for FileSearchTool: {data}") @@ -576,6 +586,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "FileSearchTool": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the FileSearchTool instance to a dictionary. Args: @@ -587,10 +599,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.connection is not None: @@ -637,7 +651,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class McpTool(Tool): """The MCP Server tool. - + Attributes ---------- kind : str @@ -652,6 +666,8 @@ class McpTool(Tool): The approval mode for the MCP tool, either 'auto' or 'manual' allowedTools : list[str] List of allowed operations or resources for the MCP tool + headers : Optional[dict[str, Any]] + Custom HTTP headers to include in requests to the MCP server, useful for authentication or routing """ _shorthand_property: ClassVar[Optional[str]] = None @@ -662,6 +678,7 @@ class McpTool(Tool): serverDescription: Optional[str] = None approvalMode: McpServerApprovalMode = field(default_factory=McpServerApprovalMode) allowedTools: list[str] = field(default_factory=list) + headers: Optional[dict[str, Any]] = None @staticmethod def load(data: Any, context: Optional[LoadContext] = None) -> "McpTool": @@ -673,10 +690,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "McpTool": McpTool: The loaded McpTool instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for McpTool: {data}") @@ -692,15 +709,17 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "McpTool": if data is not None and "serverDescription" in data: instance.serverDescription = data["serverDescription"] if data is not None and "approvalMode" in data: - instance.approvalMode = McpServerApprovalMode.load( - data["approvalMode"], context - ) + instance.approvalMode = McpServerApprovalMode.load(data["approvalMode"], context) if data is not None and "allowedTools" in data: instance.allowedTools = data["allowedTools"] + if data is not None and "headers" in data: + instance.headers = data["headers"] if context is not None: instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the McpTool instance to a dictionary. Args: @@ -712,10 +731,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.connection is not None: @@ -728,6 +749,8 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: result["approvalMode"] = obj.approvalMode.save(context) if obj.allowedTools is not None: result["allowedTools"] = obj.allowedTools + if obj.headers is not None: + result["headers"] = obj.headers return result @@ -760,7 +783,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str @dataclass class OpenApiTool(Tool): """ - + Attributes ---------- kind : str @@ -787,10 +810,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "OpenApiTool": OpenApiTool: The loaded OpenApiTool instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for OpenApiTool: {data}") @@ -807,6 +830,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "OpenApiTool": instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the OpenApiTool instance to a dictionary. Args: @@ -818,10 +843,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.connection is not None: @@ -861,7 +888,7 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str class CodeInterpreterTool(Tool): """A tool for interpreting and executing code. This tool allows an AI agent to run code snippets and analyze data files. - + Attributes ---------- kind : str @@ -885,10 +912,10 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "CodeInterpreterTo CodeInterpreterTool: The loaded CodeInterpreterTool instance. """ - + if context is not None: data = context.process_input(data) - + if not isinstance(data, dict): raise ValueError(f"Invalid data for CodeInterpreterTool: {data}") @@ -903,6 +930,8 @@ def load(data: Any, context: Optional[LoadContext] = None) -> "CodeInterpreterTo instance = context.process_output(instance) return instance + + def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: """Save the CodeInterpreterTool instance to a dictionary. Args: @@ -914,10 +943,12 @@ def save(self, context: Optional[SaveContext] = None) -> dict[str, Any]: obj = self if context is not None: obj = context.process_object(obj) + # Start with parent class properties result = super().save(context) + if obj.kind is not None: result["kind"] = obj.kind if obj.fileIds is not None: @@ -949,3 +980,4 @@ def to_json(self, context: Optional[SaveContext] = None, indent: int = 2) -> str if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + diff --git a/runtime/python/agentschema/src/agentschema/__init__.py b/runtime/python/agentschema/src/agentschema/__init__.py index 652ac009..4f84623b 100644 --- a/runtime/python/agentschema/src/agentschema/__init__.py +++ b/runtime/python/agentschema/src/agentschema/__init__.py @@ -1,3 +1,4 @@ + ########################################## # WARNING: This is an auto-generated file. # DO NOT EDIT THIS FILE DIRECTLY @@ -5,17 +6,22 @@ ########################################## from ._context import LoadContext, SaveContext -from ._AgentDefinition import AgentDefinition, PromptAgent, Workflow, ContainerAgent +from ._AgentDefinition import ( + AgentDefinition, + PromptAgent, + Workflow, + ContainerAgent +) from ._Connection import ( - Connection, - ReferenceConnection, - RemoteConnection, - ApiKeyConnection, - AnonymousConnection, - FoundryConnection, - OAuthConnection, + Connection, + ReferenceConnection, + RemoteConnection, + ApiKeyConnection, + AnonymousConnection, + FoundryConnection, + OAuthConnection ) @@ -29,28 +35,32 @@ from ._Tool import ( - Tool, - FunctionTool, - CustomTool, - WebSearchTool, - FileSearchTool, - McpTool, - OpenApiTool, - CodeInterpreterTool, + Tool, + FunctionTool, + CustomTool, + WebSearchTool, + FileSearchTool, + McpTool, + OpenApiTool, + CodeInterpreterTool ) -from ._Property import Property, ArrayProperty, ObjectProperty +from ._Property import ( + Property, + ArrayProperty, + ObjectProperty +) from ._PropertySchema import PropertySchema from ._McpServerApprovalMode import ( - McpServerApprovalMode, - McpServerToolAlwaysRequireApprovalMode, - McpServerToolNeverRequireApprovalMode, - McpServerToolSpecifyApprovalMode, + McpServerApprovalMode, + McpServerToolAlwaysRequireApprovalMode, + McpServerToolNeverRequireApprovalMode, + McpServerToolSpecifyApprovalMode ) @@ -72,11 +82,16 @@ from ._EnvironmentVariable import EnvironmentVariable -from ._Resource import Resource, ModelResource, ToolResource +from ._Resource import ( + Resource, + ModelResource, + ToolResource +) from ._AgentManifest import AgentManifest + __all__ = [ "LoadContext", "SaveContext", diff --git a/runtime/python/agentschema/src/agentschema/_context.py b/runtime/python/agentschema/src/agentschema/_context.py index d8e53e71..c2eb7350 100644 --- a/runtime/python/agentschema/src/agentschema/_context.py +++ b/runtime/python/agentschema/src/agentschema/_context.py @@ -1,3 +1,5 @@ + + # AgentSchema LoadContext import json from dataclasses import dataclass diff --git a/runtime/python/agentschema/tests/test_agent_definition.py b/runtime/python/agentschema/tests/test_agent_definition.py index db99fabb..0d346a7d 100644 --- a/runtime/python/agentschema/tests/test_agent_definition.py +++ b/runtime/python/agentschema/tests/test_agent_definition.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_agentdefinition(): - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -46,21 +47,18 @@ def test_load_json_agentdefinition(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) assert instance is not None assert instance.kind == "prompt" assert instance.name == "basic-prompt" assert instance.displayName == "Basic Prompt Agent" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" + def test_load_yaml_agentdefinition(): - yaml_data = r""" + yaml_data = r''' kind: prompt name: basic-prompt displayName: Basic Prompt Agent @@ -89,22 +87,18 @@ def test_load_yaml_agentdefinition(): kind: string description: The answer to the user's question. - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = AgentDefinition.load(data) assert instance is not None assert instance.kind == "prompt" assert instance.name == "basic-prompt" assert instance.displayName == "Basic Prompt Agent" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_roundtrip_json_agentdefinition(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -145,7 +139,7 @@ def test_roundtrip_json_agentdefinition(): } } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = AgentDefinition.load(original_data) saved_data = instance.save() @@ -154,15 +148,11 @@ def test_roundtrip_json_agentdefinition(): assert reloaded.kind == "prompt" assert reloaded.name == "basic-prompt" assert reloaded.displayName == "Basic Prompt Agent" - assert ( - reloaded.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert reloaded.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_to_json_agentdefinition(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -203,7 +193,7 @@ def test_to_json_agentdefinition(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) json_output = instance.to_json() @@ -211,10 +201,9 @@ def test_to_json_agentdefinition(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_agentdefinition(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -255,7 +244,7 @@ def test_to_yaml_agentdefinition(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) yaml_output = instance.to_yaml() @@ -263,9 +252,8 @@ def test_to_yaml_agentdefinition(): parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) - def test_load_json_agentdefinition_1(): - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -307,21 +295,18 @@ def test_load_json_agentdefinition_1(): ] } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) assert instance is not None assert instance.kind == "prompt" assert instance.name == "basic-prompt" assert instance.displayName == "Basic Prompt Agent" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" + def test_load_yaml_agentdefinition_1(): - yaml_data = r""" + yaml_data = r''' kind: prompt name: basic-prompt displayName: Basic Prompt Agent @@ -350,22 +335,18 @@ def test_load_yaml_agentdefinition_1(): kind: string description: The answer to the user's question. - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = AgentDefinition.load(data) assert instance is not None assert instance.kind == "prompt" assert instance.name == "basic-prompt" assert instance.displayName == "Basic Prompt Agent" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_roundtrip_json_agentdefinition_1(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -407,7 +388,7 @@ def test_roundtrip_json_agentdefinition_1(): ] } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = AgentDefinition.load(original_data) saved_data = instance.save() @@ -416,15 +397,11 @@ def test_roundtrip_json_agentdefinition_1(): assert reloaded.kind == "prompt" assert reloaded.name == "basic-prompt" assert reloaded.displayName == "Basic Prompt Agent" - assert ( - reloaded.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert reloaded.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_to_json_agentdefinition_1(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -466,7 +443,7 @@ def test_to_json_agentdefinition_1(): ] } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) json_output = instance.to_json() @@ -474,10 +451,9 @@ def test_to_json_agentdefinition_1(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_agentdefinition_1(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -519,7 +495,7 @@ def test_to_yaml_agentdefinition_1(): ] } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) yaml_output = instance.to_yaml() @@ -527,9 +503,8 @@ def test_to_yaml_agentdefinition_1(): parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) - def test_load_json_agentdefinition_2(): - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -573,21 +548,18 @@ def test_load_json_agentdefinition_2(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) assert instance is not None assert instance.kind == "prompt" assert instance.name == "basic-prompt" assert instance.displayName == "Basic Prompt Agent" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" + def test_load_yaml_agentdefinition_2(): - yaml_data = r""" + yaml_data = r''' kind: prompt name: basic-prompt displayName: Basic Prompt Agent @@ -616,22 +588,18 @@ def test_load_yaml_agentdefinition_2(): kind: string description: The answer to the user's question. - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = AgentDefinition.load(data) assert instance is not None assert instance.kind == "prompt" assert instance.name == "basic-prompt" assert instance.displayName == "Basic Prompt Agent" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_roundtrip_json_agentdefinition_2(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -675,7 +643,7 @@ def test_roundtrip_json_agentdefinition_2(): } } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = AgentDefinition.load(original_data) saved_data = instance.save() @@ -684,15 +652,11 @@ def test_roundtrip_json_agentdefinition_2(): assert reloaded.kind == "prompt" assert reloaded.name == "basic-prompt" assert reloaded.displayName == "Basic Prompt Agent" - assert ( - reloaded.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert reloaded.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_to_json_agentdefinition_2(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -736,7 +700,7 @@ def test_to_json_agentdefinition_2(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) json_output = instance.to_json() @@ -744,10 +708,9 @@ def test_to_json_agentdefinition_2(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_agentdefinition_2(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -791,7 +754,7 @@ def test_to_yaml_agentdefinition_2(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) yaml_output = instance.to_yaml() @@ -799,9 +762,8 @@ def test_to_yaml_agentdefinition_2(): parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) - def test_load_json_agentdefinition_3(): - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -846,21 +808,18 @@ def test_load_json_agentdefinition_3(): ] } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) assert instance is not None assert instance.kind == "prompt" assert instance.name == "basic-prompt" assert instance.displayName == "Basic Prompt Agent" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" + def test_load_yaml_agentdefinition_3(): - yaml_data = r""" + yaml_data = r''' kind: prompt name: basic-prompt displayName: Basic Prompt Agent @@ -889,22 +848,18 @@ def test_load_yaml_agentdefinition_3(): kind: string description: The answer to the user's question. - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = AgentDefinition.load(data) assert instance is not None assert instance.kind == "prompt" assert instance.name == "basic-prompt" assert instance.displayName == "Basic Prompt Agent" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_roundtrip_json_agentdefinition_3(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -949,7 +904,7 @@ def test_roundtrip_json_agentdefinition_3(): ] } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = AgentDefinition.load(original_data) saved_data = instance.save() @@ -958,15 +913,11 @@ def test_roundtrip_json_agentdefinition_3(): assert reloaded.kind == "prompt" assert reloaded.name == "basic-prompt" assert reloaded.displayName == "Basic Prompt Agent" - assert ( - reloaded.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert reloaded.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_to_json_agentdefinition_3(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -1011,7 +962,7 @@ def test_to_json_agentdefinition_3(): ] } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) json_output = instance.to_json() @@ -1019,10 +970,9 @@ def test_to_json_agentdefinition_3(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_agentdefinition_3(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "name": "basic-prompt", @@ -1067,10 +1017,12 @@ def test_to_yaml_agentdefinition_3(): ] } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentDefinition.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_agent_manifest.py b/runtime/python/agentschema/tests/test_agent_manifest.py index eba823a6..faf08775 100644 --- a/runtime/python/agentschema/tests/test_agent_manifest.py +++ b/runtime/python/agentschema/tests/test_agent_manifest.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_agentmanifest(): - json_data = r""" + json_data = r''' { "name": "basic-prompt", "displayName": "My Basic Prompt", @@ -54,20 +55,17 @@ def test_load_json_agentmanifest(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentManifest.load(data) assert instance is not None assert instance.name == "basic-prompt" assert instance.displayName == "My Basic Prompt" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" + def test_load_yaml_agentmanifest(): - yaml_data = r""" + yaml_data = r''' name: basic-prompt displayName: My Basic Prompt description: A basic prompt that uses the GPT-3 chat API to answer questions @@ -101,21 +99,17 @@ def test_load_yaml_agentmanifest(): options: apiKey: my-api-key - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = AgentManifest.load(data) assert instance is not None assert instance.name == "basic-prompt" assert instance.displayName == "My Basic Prompt" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_roundtrip_json_agentmanifest(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "name": "basic-prompt", "displayName": "My Basic Prompt", @@ -164,7 +158,7 @@ def test_roundtrip_json_agentmanifest(): } } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = AgentManifest.load(original_data) saved_data = instance.save() @@ -172,15 +166,11 @@ def test_roundtrip_json_agentmanifest(): assert reloaded is not None assert reloaded.name == "basic-prompt" assert reloaded.displayName == "My Basic Prompt" - assert ( - reloaded.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert reloaded.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_to_json_agentmanifest(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "name": "basic-prompt", "displayName": "My Basic Prompt", @@ -229,7 +219,7 @@ def test_to_json_agentmanifest(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentManifest.load(data) json_output = instance.to_json() @@ -237,10 +227,9 @@ def test_to_json_agentmanifest(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_agentmanifest(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "name": "basic-prompt", "displayName": "My Basic Prompt", @@ -289,7 +278,7 @@ def test_to_yaml_agentmanifest(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentManifest.load(data) yaml_output = instance.to_yaml() @@ -297,9 +286,8 @@ def test_to_yaml_agentmanifest(): parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) - def test_load_json_agentmanifest_1(): - json_data = r""" + json_data = r''' { "name": "basic-prompt", "displayName": "My Basic Prompt", @@ -350,20 +338,17 @@ def test_load_json_agentmanifest_1(): } ] } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentManifest.load(data) assert instance is not None assert instance.name == "basic-prompt" assert instance.displayName == "My Basic Prompt" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" + def test_load_yaml_agentmanifest_1(): - yaml_data = r""" + yaml_data = r''' name: basic-prompt displayName: My Basic Prompt description: A basic prompt that uses the GPT-3 chat API to answer questions @@ -397,21 +382,17 @@ def test_load_yaml_agentmanifest_1(): options: apiKey: my-api-key - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = AgentManifest.load(data) assert instance is not None assert instance.name == "basic-prompt" assert instance.displayName == "My Basic Prompt" - assert ( - instance.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert instance.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_roundtrip_json_agentmanifest_1(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "name": "basic-prompt", "displayName": "My Basic Prompt", @@ -462,7 +443,7 @@ def test_roundtrip_json_agentmanifest_1(): } ] } - """ + ''' original_data = json.loads(json_data, strict=False) instance = AgentManifest.load(original_data) saved_data = instance.save() @@ -470,15 +451,11 @@ def test_roundtrip_json_agentmanifest_1(): assert reloaded is not None assert reloaded.name == "basic-prompt" assert reloaded.displayName == "My Basic Prompt" - assert ( - reloaded.description - == "A basic prompt that uses the GPT-3 chat API to answer questions" - ) - + assert reloaded.description == "A basic prompt that uses the GPT-3 chat API to answer questions" def test_to_json_agentmanifest_1(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "name": "basic-prompt", "displayName": "My Basic Prompt", @@ -529,7 +506,7 @@ def test_to_json_agentmanifest_1(): } ] } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentManifest.load(data) json_output = instance.to_json() @@ -537,10 +514,9 @@ def test_to_json_agentmanifest_1(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_agentmanifest_1(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "name": "basic-prompt", "displayName": "My Basic Prompt", @@ -591,10 +567,12 @@ def test_to_yaml_agentmanifest_1(): } ] } - """ + ''' data = json.loads(json_data, strict=False) instance = AgentManifest.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_anonymous_connection.py b/runtime/python/agentschema/tests/test_anonymous_connection.py index 602e23f3..bd59cdda 100644 --- a/runtime/python/agentschema/tests/test_anonymous_connection.py +++ b/runtime/python/agentschema/tests/test_anonymous_connection.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,40 +6,39 @@ def test_load_json_anonymousconnection(): - json_data = r""" + json_data = r''' { "kind": "anonymous", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/" } - """ + ''' data = json.loads(json_data, strict=False) instance = AnonymousConnection.load(data) assert instance is not None assert instance.kind == "anonymous" assert instance.endpoint == "https://{your-custom-endpoint}.openai.azure.com/" - + def test_load_yaml_anonymousconnection(): - yaml_data = r""" + yaml_data = r''' kind: anonymous endpoint: "https://{your-custom-endpoint}.openai.azure.com/" - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = AnonymousConnection.load(data) assert instance is not None assert instance.kind == "anonymous" assert instance.endpoint == "https://{your-custom-endpoint}.openai.azure.com/" - def test_roundtrip_json_anonymousconnection(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "anonymous", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = AnonymousConnection.load(original_data) saved_data = instance.save() @@ -47,15 +47,14 @@ def test_roundtrip_json_anonymousconnection(): assert reloaded.kind == "anonymous" assert reloaded.endpoint == "https://{your-custom-endpoint}.openai.azure.com/" - def test_to_json_anonymousconnection(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "anonymous", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/" } - """ + ''' data = json.loads(json_data, strict=False) instance = AnonymousConnection.load(data) json_output = instance.to_json() @@ -63,18 +62,19 @@ def test_to_json_anonymousconnection(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_anonymousconnection(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "anonymous", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/" } - """ + ''' data = json.loads(json_data, strict=False) instance = AnonymousConnection.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_api_key_connection.py b/runtime/python/agentschema/tests/test_api_key_connection.py index a2970e41..d53abef0 100644 --- a/runtime/python/agentschema/tests/test_api_key_connection.py +++ b/runtime/python/agentschema/tests/test_api_key_connection.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,28 +6,28 @@ def test_load_json_apikeyconnection(): - json_data = r""" + json_data = r''' { "kind": "key", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/", "apiKey": "your-api-key" } - """ + ''' data = json.loads(json_data, strict=False) instance = ApiKeyConnection.load(data) assert instance is not None assert instance.kind == "key" assert instance.endpoint == "https://{your-custom-endpoint}.openai.azure.com/" assert instance.apiKey == "your-api-key" - + def test_load_yaml_apikeyconnection(): - yaml_data = r""" + yaml_data = r''' kind: key endpoint: "https://{your-custom-endpoint}.openai.azure.com/" apiKey: your-api-key - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = ApiKeyConnection.load(data) assert instance is not None @@ -34,16 +35,15 @@ def test_load_yaml_apikeyconnection(): assert instance.endpoint == "https://{your-custom-endpoint}.openai.azure.com/" assert instance.apiKey == "your-api-key" - def test_roundtrip_json_apikeyconnection(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "key", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/", "apiKey": "your-api-key" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = ApiKeyConnection.load(original_data) saved_data = instance.save() @@ -53,16 +53,15 @@ def test_roundtrip_json_apikeyconnection(): assert reloaded.endpoint == "https://{your-custom-endpoint}.openai.azure.com/" assert reloaded.apiKey == "your-api-key" - def test_to_json_apikeyconnection(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "key", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/", "apiKey": "your-api-key" } - """ + ''' data = json.loads(json_data, strict=False) instance = ApiKeyConnection.load(data) json_output = instance.to_json() @@ -70,19 +69,20 @@ def test_to_json_apikeyconnection(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_apikeyconnection(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "key", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/", "apiKey": "your-api-key" } - """ + ''' data = json.loads(json_data, strict=False) instance = ApiKeyConnection.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_array_property.py b/runtime/python/agentschema/tests/test_array_property.py index c95f0130..bc5ee725 100644 --- a/runtime/python/agentschema/tests/test_array_property.py +++ b/runtime/python/agentschema/tests/test_array_property.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,54 +6,52 @@ def test_load_json_arrayproperty(): - json_data = r""" + json_data = r''' { "items": { "kind": "string" } } - """ + ''' data = json.loads(json_data, strict=False) instance = ArrayProperty.load(data) assert instance is not None - + def test_load_yaml_arrayproperty(): - yaml_data = r""" + yaml_data = r''' items: kind: string - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = ArrayProperty.load(data) assert instance is not None - def test_roundtrip_json_arrayproperty(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "items": { "kind": "string" } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = ArrayProperty.load(original_data) saved_data = instance.save() reloaded = ArrayProperty.load(saved_data) assert reloaded is not None - def test_to_json_arrayproperty(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "items": { "kind": "string" } } - """ + ''' data = json.loads(json_data, strict=False) instance = ArrayProperty.load(data) json_output = instance.to_json() @@ -60,19 +59,20 @@ def test_to_json_arrayproperty(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_arrayproperty(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "items": { "kind": "string" } } - """ + ''' data = json.loads(json_data, strict=False) instance = ArrayProperty.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_binding.py b/runtime/python/agentschema/tests/test_binding.py index c99e9234..cb3a4f14 100644 --- a/runtime/python/agentschema/tests/test_binding.py +++ b/runtime/python/agentschema/tests/test_binding.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,40 +6,39 @@ def test_load_json_binding(): - json_data = r""" + json_data = r''' { "name": "my-tool", "input": "input-variable" } - """ + ''' data = json.loads(json_data, strict=False) instance = Binding.load(data) assert instance is not None assert instance.name == "my-tool" assert instance.input == "input-variable" - + def test_load_yaml_binding(): - yaml_data = r""" + yaml_data = r''' name: my-tool input: input-variable - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = Binding.load(data) assert instance is not None assert instance.name == "my-tool" assert instance.input == "input-variable" - def test_roundtrip_json_binding(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "name": "my-tool", "input": "input-variable" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = Binding.load(original_data) saved_data = instance.save() @@ -47,15 +47,14 @@ def test_roundtrip_json_binding(): assert reloaded.name == "my-tool" assert reloaded.input == "input-variable" - def test_to_json_binding(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "name": "my-tool", "input": "input-variable" } - """ + ''' data = json.loads(json_data, strict=False) instance = Binding.load(data) json_output = instance.to_json() @@ -63,15 +62,14 @@ def test_to_json_binding(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_binding(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "name": "my-tool", "input": "input-variable" } - """ + ''' data = json.loads(json_data, strict=False) instance = Binding.load(data) yaml_output = instance.to_yaml() @@ -84,3 +82,5 @@ def test_load_binding_from_str(): instance = Binding.load("example") assert instance is not None assert instance.input == "example" + + diff --git a/runtime/python/agentschema/tests/test_code_interpreter_tool.py b/runtime/python/agentschema/tests/test_code_interpreter_tool.py index 0cc1bddd..868a65ca 100644 --- a/runtime/python/agentschema/tests/test_code_interpreter_tool.py +++ b/runtime/python/agentschema/tests/test_code_interpreter_tool.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_codeinterpretertool(): - json_data = r""" + json_data = r''' { "kind": "code_interpreter", "fileIds": [ @@ -13,30 +14,29 @@ def test_load_json_codeinterpretertool(): "file2" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = CodeInterpreterTool.load(data) assert instance is not None assert instance.kind == "code_interpreter" - + def test_load_yaml_codeinterpretertool(): - yaml_data = r""" + yaml_data = r''' kind: code_interpreter fileIds: - file1 - file2 - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = CodeInterpreterTool.load(data) assert instance is not None assert instance.kind == "code_interpreter" - def test_roundtrip_json_codeinterpretertool(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "code_interpreter", "fileIds": [ @@ -44,7 +44,7 @@ def test_roundtrip_json_codeinterpretertool(): "file2" ] } - """ + ''' original_data = json.loads(json_data, strict=False) instance = CodeInterpreterTool.load(original_data) saved_data = instance.save() @@ -52,10 +52,9 @@ def test_roundtrip_json_codeinterpretertool(): assert reloaded is not None assert reloaded.kind == "code_interpreter" - def test_to_json_codeinterpretertool(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "code_interpreter", "fileIds": [ @@ -63,7 +62,7 @@ def test_to_json_codeinterpretertool(): "file2" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = CodeInterpreterTool.load(data) json_output = instance.to_json() @@ -71,10 +70,9 @@ def test_to_json_codeinterpretertool(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_codeinterpretertool(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "code_interpreter", "fileIds": [ @@ -82,10 +80,12 @@ def test_to_yaml_codeinterpretertool(): "file2" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = CodeInterpreterTool.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_connection.py b/runtime/python/agentschema/tests/test_connection.py index 7a28f311..a219d691 100644 --- a/runtime/python/agentschema/tests/test_connection.py +++ b/runtime/python/agentschema/tests/test_connection.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,51 +6,44 @@ def test_load_json_connection(): - json_data = r""" + json_data = r''' { "kind": "reference", "authenticationMode": "system", "usageDescription": "This will allow the agent to respond to an email on your behalf" } - """ + ''' data = json.loads(json_data, strict=False) instance = Connection.load(data) assert instance is not None assert instance.kind == "reference" assert instance.authenticationMode == "system" - assert ( - instance.usageDescription - == "This will allow the agent to respond to an email on your behalf" - ) - + assert instance.usageDescription == "This will allow the agent to respond to an email on your behalf" + def test_load_yaml_connection(): - yaml_data = r""" + yaml_data = r''' kind: reference authenticationMode: system usageDescription: This will allow the agent to respond to an email on your behalf - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = Connection.load(data) assert instance is not None assert instance.kind == "reference" assert instance.authenticationMode == "system" - assert ( - instance.usageDescription - == "This will allow the agent to respond to an email on your behalf" - ) - + assert instance.usageDescription == "This will allow the agent to respond to an email on your behalf" def test_roundtrip_json_connection(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "reference", "authenticationMode": "system", "usageDescription": "This will allow the agent to respond to an email on your behalf" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = Connection.load(original_data) saved_data = instance.save() @@ -57,21 +51,17 @@ def test_roundtrip_json_connection(): assert reloaded is not None assert reloaded.kind == "reference" assert reloaded.authenticationMode == "system" - assert ( - reloaded.usageDescription - == "This will allow the agent to respond to an email on your behalf" - ) - + assert reloaded.usageDescription == "This will allow the agent to respond to an email on your behalf" def test_to_json_connection(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "reference", "authenticationMode": "system", "usageDescription": "This will allow the agent to respond to an email on your behalf" } - """ + ''' data = json.loads(json_data, strict=False) instance = Connection.load(data) json_output = instance.to_json() @@ -79,19 +69,20 @@ def test_to_json_connection(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_connection(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "reference", "authenticationMode": "system", "usageDescription": "This will allow the agent to respond to an email on your behalf" } - """ + ''' data = json.loads(json_data, strict=False) instance = Connection.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_container_agent.py b/runtime/python/agentschema/tests/test_container_agent.py index 5383eb99..20d7206e 100644 --- a/runtime/python/agentschema/tests/test_container_agent.py +++ b/runtime/python/agentschema/tests/test_container_agent.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_containeragent(): - json_data = r""" + json_data = r''' { "kind": "hosted", "protocols": [ @@ -27,17 +28,17 @@ def test_load_json_containeragent(): } ] } - """ + ''' data = json.loads(json_data, strict=False) instance = ContainerAgent.load(data) assert instance is not None assert instance.kind == "hosted" assert instance.image == "myregistry.azurecr.io/my-agent" assert instance.dockerfilePath == "./Dockerfile" - + def test_load_yaml_containeragent(): - yaml_data = r""" + yaml_data = r''' kind: hosted protocols: - protocol: responses @@ -51,7 +52,7 @@ def test_load_yaml_containeragent(): - name: MY_ENV_VAR value: my-value - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = ContainerAgent.load(data) assert instance is not None @@ -59,10 +60,9 @@ def test_load_yaml_containeragent(): assert instance.image == "myregistry.azurecr.io/my-agent" assert instance.dockerfilePath == "./Dockerfile" - def test_roundtrip_json_containeragent(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "hosted", "protocols": [ @@ -84,7 +84,7 @@ def test_roundtrip_json_containeragent(): } ] } - """ + ''' original_data = json.loads(json_data, strict=False) instance = ContainerAgent.load(original_data) saved_data = instance.save() @@ -94,10 +94,9 @@ def test_roundtrip_json_containeragent(): assert reloaded.image == "myregistry.azurecr.io/my-agent" assert reloaded.dockerfilePath == "./Dockerfile" - def test_to_json_containeragent(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "hosted", "protocols": [ @@ -119,7 +118,7 @@ def test_to_json_containeragent(): } ] } - """ + ''' data = json.loads(json_data, strict=False) instance = ContainerAgent.load(data) json_output = instance.to_json() @@ -127,10 +126,9 @@ def test_to_json_containeragent(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_containeragent(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "hosted", "protocols": [ @@ -152,10 +150,12 @@ def test_to_yaml_containeragent(): } ] } - """ + ''' data = json.loads(json_data, strict=False) instance = ContainerAgent.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_container_resources.py b/runtime/python/agentschema/tests/test_container_resources.py index 5e0f37c7..7cc07cc9 100644 --- a/runtime/python/agentschema/tests/test_container_resources.py +++ b/runtime/python/agentschema/tests/test_container_resources.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,40 +6,39 @@ def test_load_json_containerresources(): - json_data = r""" + json_data = r''' { "cpu": "1", "memory": "2Gi" } - """ + ''' data = json.loads(json_data, strict=False) instance = ContainerResources.load(data) assert instance is not None assert instance.cpu == "1" assert instance.memory == "2Gi" - + def test_load_yaml_containerresources(): - yaml_data = r""" + yaml_data = r''' cpu: "1" memory: 2Gi - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = ContainerResources.load(data) assert instance is not None assert instance.cpu == "1" assert instance.memory == "2Gi" - def test_roundtrip_json_containerresources(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "cpu": "1", "memory": "2Gi" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = ContainerResources.load(original_data) saved_data = instance.save() @@ -47,15 +47,14 @@ def test_roundtrip_json_containerresources(): assert reloaded.cpu == "1" assert reloaded.memory == "2Gi" - def test_to_json_containerresources(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "cpu": "1", "memory": "2Gi" } - """ + ''' data = json.loads(json_data, strict=False) instance = ContainerResources.load(data) json_output = instance.to_json() @@ -63,18 +62,19 @@ def test_to_json_containerresources(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_containerresources(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "cpu": "1", "memory": "2Gi" } - """ + ''' data = json.loads(json_data, strict=False) instance = ContainerResources.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_context.py b/runtime/python/agentschema/tests/test_context.py index f1f9fe03..86df1c19 100644 --- a/runtime/python/agentschema/tests/test_context.py +++ b/runtime/python/agentschema/tests/test_context.py @@ -1,3 +1,5 @@ + + # AgentSchema LoadContext from agentschema._context import LoadContext, SaveContext @@ -20,7 +22,6 @@ def test_process_input_without_callback(self) -> None: def test_process_input_with_callback(self) -> None: """Test process_input applies the pre_process callback.""" - def add_field(data: dict) -> dict: return {**data, "added": True} @@ -39,7 +40,6 @@ def test_process_output_without_callback(self) -> None: def test_process_output_with_callback(self) -> None: """Test process_output applies the post_process callback.""" - def wrap_result(result: dict) -> dict: return {"wrapped": result} @@ -50,7 +50,6 @@ def wrap_result(result: dict) -> dict: def test_both_callbacks(self) -> None: """Test using both pre_process and post_process callbacks.""" - def normalize_keys(data: dict) -> dict: return {k.lower(): v for k, v in data.items()} @@ -58,17 +57,16 @@ def add_metadata(result: dict) -> dict: return {**result, "_processed": True} context = LoadContext(pre_process=normalize_keys, post_process=add_metadata) - + input_data = {"Key": "value", "UPPER": "case"} processed_input = context.process_input(input_data) assert processed_input == {"key": "value", "upper": "case"} - + final_result = context.process_output(processed_input) assert final_result == {"key": "value", "upper": "case", "_processed": True} def test_pre_process_can_modify_structure(self) -> None: """Test that pre_process can fundamentally transform data structure.""" - def flatten_nested(data: dict) -> dict: result = {} for key, value in data.items(): @@ -103,7 +101,6 @@ def test_process_object_without_callback(self) -> None: def test_process_object_with_callback(self) -> None: """Test process_object applies the pre_save callback.""" - def add_timestamp(obj: dict) -> dict: return {**obj, "timestamp": "2024-01-01"} @@ -121,7 +118,6 @@ def test_process_dict_without_callback(self) -> None: def test_process_dict_with_callback(self) -> None: """Test process_dict applies the post_save callback.""" - def remove_internal_fields(data: dict) -> dict: return {k: v for k, v in data.items() if not k.startswith("_")} @@ -132,7 +128,6 @@ def remove_internal_fields(data: dict) -> dict: def test_both_callbacks(self) -> None: """Test using both pre_save and post_save callbacks.""" - def mark_for_export(obj: dict) -> dict: return {**obj, "_exporting": True} @@ -140,11 +135,11 @@ def clean_markers(data: dict) -> dict: return {k: v for k, v in data.items() if not k.startswith("_")} context = SaveContext(pre_save=mark_for_export, post_save=clean_markers) - + obj = {"name": "test", "value": 42} processed_obj = context.process_object(obj) assert processed_obj == {"name": "test", "value": 42, "_exporting": True} - + final_dict = context.process_dict(processed_obj) assert final_dict == {"name": "test", "value": 42} @@ -161,7 +156,6 @@ def test_to_yaml(self) -> None: def test_to_json(self) -> None: """Test to_json produces valid JSON string.""" import json - context = SaveContext() data = {"name": "test", "items": ["a", "b"]} result = context.to_json(data) diff --git a/runtime/python/agentschema/tests/test_custom_tool.py b/runtime/python/agentschema/tests/test_custom_tool.py index e12fb9b2..8b8a7a40 100644 --- a/runtime/python/agentschema/tests/test_custom_tool.py +++ b/runtime/python/agentschema/tests/test_custom_tool.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_customtool(): - json_data = r""" + json_data = r''' { "connection": { "kind": "reference" @@ -15,29 +16,28 @@ def test_load_json_customtool(): "retries": 3 } } - """ + ''' data = json.loads(json_data, strict=False) instance = CustomTool.load(data) assert instance is not None - + def test_load_yaml_customtool(): - yaml_data = r""" + yaml_data = r''' connection: kind: reference options: timeout: 30 retries: 3 - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = CustomTool.load(data) assert instance is not None - def test_roundtrip_json_customtool(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "connection": { "kind": "reference" @@ -47,17 +47,16 @@ def test_roundtrip_json_customtool(): "retries": 3 } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = CustomTool.load(original_data) saved_data = instance.save() reloaded = CustomTool.load(saved_data) assert reloaded is not None - def test_to_json_customtool(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "connection": { "kind": "reference" @@ -67,7 +66,7 @@ def test_to_json_customtool(): "retries": 3 } } - """ + ''' data = json.loads(json_data, strict=False) instance = CustomTool.load(data) json_output = instance.to_json() @@ -75,10 +74,9 @@ def test_to_json_customtool(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_customtool(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "connection": { "kind": "reference" @@ -88,10 +86,12 @@ def test_to_yaml_customtool(): "retries": 3 } } - """ + ''' data = json.loads(json_data, strict=False) instance = CustomTool.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_environment_variable.py b/runtime/python/agentschema/tests/test_environment_variable.py index fb119aea..e54d418e 100644 --- a/runtime/python/agentschema/tests/test_environment_variable.py +++ b/runtime/python/agentschema/tests/test_environment_variable.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,40 +6,39 @@ def test_load_json_environmentvariable(): - json_data = r""" + json_data = r''' { "name": "MY_ENV_VAR", "value": "my-value" } - """ + ''' data = json.loads(json_data, strict=False) instance = EnvironmentVariable.load(data) assert instance is not None assert instance.name == "MY_ENV_VAR" assert instance.value == "my-value" - + def test_load_yaml_environmentvariable(): - yaml_data = r""" + yaml_data = r''' name: MY_ENV_VAR value: my-value - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = EnvironmentVariable.load(data) assert instance is not None assert instance.name == "MY_ENV_VAR" assert instance.value == "my-value" - def test_roundtrip_json_environmentvariable(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "name": "MY_ENV_VAR", "value": "my-value" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = EnvironmentVariable.load(original_data) saved_data = instance.save() @@ -47,15 +47,14 @@ def test_roundtrip_json_environmentvariable(): assert reloaded.name == "MY_ENV_VAR" assert reloaded.value == "my-value" - def test_to_json_environmentvariable(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "name": "MY_ENV_VAR", "value": "my-value" } - """ + ''' data = json.loads(json_data, strict=False) instance = EnvironmentVariable.load(data) json_output = instance.to_json() @@ -63,18 +62,19 @@ def test_to_json_environmentvariable(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_environmentvariable(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "name": "MY_ENV_VAR", "value": "my-value" } - """ + ''' data = json.loads(json_data, strict=False) instance = EnvironmentVariable.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_file_search_tool.py b/runtime/python/agentschema/tests/test_file_search_tool.py index 632c6fe8..d566eb22 100644 --- a/runtime/python/agentschema/tests/test_file_search_tool.py +++ b/runtime/python/agentschema/tests/test_file_search_tool.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_filesearchtool(): - json_data = r""" + json_data = r''' { "kind": "file_search", "connection": { @@ -23,7 +24,7 @@ def test_load_json_filesearchtool(): "createdAfter": "2023-01-01" } } - """ + ''' data = json.loads(json_data, strict=False) instance = FileSearchTool.load(data) assert instance is not None @@ -31,10 +32,10 @@ def test_load_json_filesearchtool(): assert instance.maximumResultCount == 10 assert instance.ranker == "auto" assert instance.scoreThreshold == 0.5 - + def test_load_yaml_filesearchtool(): - yaml_data = r""" + yaml_data = r''' kind: file_search connection: kind: reference @@ -48,7 +49,7 @@ def test_load_yaml_filesearchtool(): fileType: pdf createdAfter: 2023-01-01 - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = FileSearchTool.load(data) assert instance is not None @@ -57,10 +58,9 @@ def test_load_yaml_filesearchtool(): assert instance.ranker == "auto" assert instance.scoreThreshold == 0.5 - def test_roundtrip_json_filesearchtool(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "file_search", "connection": { @@ -78,7 +78,7 @@ def test_roundtrip_json_filesearchtool(): "createdAfter": "2023-01-01" } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = FileSearchTool.load(original_data) saved_data = instance.save() @@ -89,10 +89,9 @@ def test_roundtrip_json_filesearchtool(): assert reloaded.ranker == "auto" assert reloaded.scoreThreshold == 0.5 - def test_to_json_filesearchtool(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "file_search", "connection": { @@ -110,7 +109,7 @@ def test_to_json_filesearchtool(): "createdAfter": "2023-01-01" } } - """ + ''' data = json.loads(json_data, strict=False) instance = FileSearchTool.load(data) json_output = instance.to_json() @@ -118,10 +117,9 @@ def test_to_json_filesearchtool(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_filesearchtool(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "file_search", "connection": { @@ -139,10 +137,12 @@ def test_to_yaml_filesearchtool(): "createdAfter": "2023-01-01" } } - """ + ''' data = json.loads(json_data, strict=False) instance = FileSearchTool.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_format.py b/runtime/python/agentschema/tests/test_format.py index 07d74c23..35c29728 100644 --- a/runtime/python/agentschema/tests/test_format.py +++ b/runtime/python/agentschema/tests/test_format.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_format(): - json_data = r""" + json_data = r''' { "kind": "mustache", "strict": true, @@ -13,33 +14,32 @@ def test_load_json_format(): "key": "value" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Format.load(data) assert instance is not None assert instance.kind == "mustache" - + assert instance.strict - + def test_load_yaml_format(): - yaml_data = r""" + yaml_data = r''' kind: mustache strict: true options: key: value - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = Format.load(data) assert instance is not None assert instance.kind == "mustache" assert instance.strict - def test_roundtrip_json_format(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "mustache", "strict": true, @@ -47,7 +47,7 @@ def test_roundtrip_json_format(): "key": "value" } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = Format.load(original_data) saved_data = instance.save() @@ -56,10 +56,9 @@ def test_roundtrip_json_format(): assert reloaded.kind == "mustache" assert reloaded.strict - def test_to_json_format(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "mustache", "strict": true, @@ -67,7 +66,7 @@ def test_to_json_format(): "key": "value" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Format.load(data) json_output = instance.to_json() @@ -75,10 +74,9 @@ def test_to_json_format(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_format(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "mustache", "strict": true, @@ -86,7 +84,7 @@ def test_to_yaml_format(): "key": "value" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Format.load(data) yaml_output = instance.to_yaml() @@ -99,3 +97,5 @@ def test_load_format_from_str(): instance = Format.load("example") assert instance is not None assert instance.kind == "example" + + diff --git a/runtime/python/agentschema/tests/test_foundry_connection.py b/runtime/python/agentschema/tests/test_foundry_connection.py index 969cf135..55df64aa 100644 --- a/runtime/python/agentschema/tests/test_foundry_connection.py +++ b/runtime/python/agentschema/tests/test_foundry_connection.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,80 +6,69 @@ def test_load_json_foundryconnection(): - json_data = r""" + json_data = r''' { "kind": "foundry", "endpoint": "https://myresource.services.ai.azure.com/api/projects/myproject", "name": "my-openai-connection", "connectionType": "model" } - """ + ''' data = json.loads(json_data, strict=False) instance = FoundryConnection.load(data) assert instance is not None assert instance.kind == "foundry" - assert ( - instance.endpoint - == "https://myresource.services.ai.azure.com/api/projects/myproject" - ) + assert instance.endpoint == "https://myresource.services.ai.azure.com/api/projects/myproject" assert instance.name == "my-openai-connection" assert instance.connectionType == "model" - + def test_load_yaml_foundryconnection(): - yaml_data = r""" + yaml_data = r''' kind: foundry endpoint: "https://myresource.services.ai.azure.com/api/projects/myproject" name: my-openai-connection connectionType: model - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = FoundryConnection.load(data) assert instance is not None assert instance.kind == "foundry" - assert ( - instance.endpoint - == "https://myresource.services.ai.azure.com/api/projects/myproject" - ) + assert instance.endpoint == "https://myresource.services.ai.azure.com/api/projects/myproject" assert instance.name == "my-openai-connection" assert instance.connectionType == "model" - def test_roundtrip_json_foundryconnection(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "foundry", "endpoint": "https://myresource.services.ai.azure.com/api/projects/myproject", "name": "my-openai-connection", "connectionType": "model" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = FoundryConnection.load(original_data) saved_data = instance.save() reloaded = FoundryConnection.load(saved_data) assert reloaded is not None assert reloaded.kind == "foundry" - assert ( - reloaded.endpoint - == "https://myresource.services.ai.azure.com/api/projects/myproject" - ) + assert reloaded.endpoint == "https://myresource.services.ai.azure.com/api/projects/myproject" assert reloaded.name == "my-openai-connection" assert reloaded.connectionType == "model" - def test_to_json_foundryconnection(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "foundry", "endpoint": "https://myresource.services.ai.azure.com/api/projects/myproject", "name": "my-openai-connection", "connectionType": "model" } - """ + ''' data = json.loads(json_data, strict=False) instance = FoundryConnection.load(data) json_output = instance.to_json() @@ -86,20 +76,21 @@ def test_to_json_foundryconnection(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_foundryconnection(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "foundry", "endpoint": "https://myresource.services.ai.azure.com/api/projects/myproject", "name": "my-openai-connection", "connectionType": "model" } - """ + ''' data = json.loads(json_data, strict=False) instance = FoundryConnection.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_function_tool.py b/runtime/python/agentschema/tests/test_function_tool.py index bd32fba8..9c9818f5 100644 --- a/runtime/python/agentschema/tests/test_function_tool.py +++ b/runtime/python/agentschema/tests/test_function_tool.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_functiontool(): - json_data = r""" + json_data = r''' { "kind": "function", "parameters": { @@ -26,17 +27,17 @@ def test_load_json_functiontool(): }, "strict": true } - """ + ''' data = json.loads(json_data, strict=False) instance = FunctionTool.load(data) assert instance is not None assert instance.kind == "function" - + assert instance.strict - + def test_load_yaml_functiontool(): - yaml_data = r""" + yaml_data = r''' kind: function parameters: properties: @@ -51,17 +52,16 @@ def test_load_yaml_functiontool(): value: What is the meaning of life? strict: true - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = FunctionTool.load(data) assert instance is not None assert instance.kind == "function" assert instance.strict - def test_roundtrip_json_functiontool(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "function", "parameters": { @@ -82,7 +82,7 @@ def test_roundtrip_json_functiontool(): }, "strict": true } - """ + ''' original_data = json.loads(json_data, strict=False) instance = FunctionTool.load(original_data) saved_data = instance.save() @@ -91,10 +91,9 @@ def test_roundtrip_json_functiontool(): assert reloaded.kind == "function" assert reloaded.strict - def test_to_json_functiontool(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "function", "parameters": { @@ -115,7 +114,7 @@ def test_to_json_functiontool(): }, "strict": true } - """ + ''' data = json.loads(json_data, strict=False) instance = FunctionTool.load(data) json_output = instance.to_json() @@ -123,10 +122,9 @@ def test_to_json_functiontool(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_functiontool(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "function", "parameters": { @@ -147,7 +145,7 @@ def test_to_yaml_functiontool(): }, "strict": true } - """ + ''' data = json.loads(json_data, strict=False) instance = FunctionTool.load(data) yaml_output = instance.to_yaml() @@ -155,9 +153,8 @@ def test_to_yaml_functiontool(): parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) - def test_load_json_functiontool_1(): - json_data = r""" + json_data = r''' { "kind": "function", "parameters": { @@ -181,17 +178,17 @@ def test_load_json_functiontool_1(): }, "strict": true } - """ + ''' data = json.loads(json_data, strict=False) instance = FunctionTool.load(data) assert instance is not None assert instance.kind == "function" - + assert instance.strict - + def test_load_yaml_functiontool_1(): - yaml_data = r""" + yaml_data = r''' kind: function parameters: properties: @@ -206,17 +203,16 @@ def test_load_yaml_functiontool_1(): value: What is the meaning of life? strict: true - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = FunctionTool.load(data) assert instance is not None assert instance.kind == "function" assert instance.strict - def test_roundtrip_json_functiontool_1(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "function", "parameters": { @@ -240,7 +236,7 @@ def test_roundtrip_json_functiontool_1(): }, "strict": true } - """ + ''' original_data = json.loads(json_data, strict=False) instance = FunctionTool.load(original_data) saved_data = instance.save() @@ -249,10 +245,9 @@ def test_roundtrip_json_functiontool_1(): assert reloaded.kind == "function" assert reloaded.strict - def test_to_json_functiontool_1(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "function", "parameters": { @@ -276,7 +271,7 @@ def test_to_json_functiontool_1(): }, "strict": true } - """ + ''' data = json.loads(json_data, strict=False) instance = FunctionTool.load(data) json_output = instance.to_json() @@ -284,10 +279,9 @@ def test_to_json_functiontool_1(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_functiontool_1(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "function", "parameters": { @@ -311,10 +305,12 @@ def test_to_yaml_functiontool_1(): }, "strict": true } - """ + ''' data = json.loads(json_data, strict=False) instance = FunctionTool.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_mcp_server_approval_mode.py b/runtime/python/agentschema/tests/test_mcp_server_approval_mode.py index 88a91d30..81cf7d3b 100644 --- a/runtime/python/agentschema/tests/test_mcp_server_approval_mode.py +++ b/runtime/python/agentschema/tests/test_mcp_server_approval_mode.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,35 +6,34 @@ def test_load_json_mcpserverapprovalmode(): - json_data = r""" + json_data = r''' { "kind": "never" } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerApprovalMode.load(data) assert instance is not None assert instance.kind == "never" - + def test_load_yaml_mcpserverapprovalmode(): - yaml_data = r""" + yaml_data = r''' kind: never - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = McpServerApprovalMode.load(data) assert instance is not None assert instance.kind == "never" - def test_roundtrip_json_mcpserverapprovalmode(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "never" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = McpServerApprovalMode.load(original_data) saved_data = instance.save() @@ -41,14 +41,13 @@ def test_roundtrip_json_mcpserverapprovalmode(): assert reloaded is not None assert reloaded.kind == "never" - def test_to_json_mcpserverapprovalmode(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "never" } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerApprovalMode.load(data) json_output = instance.to_json() @@ -56,14 +55,13 @@ def test_to_json_mcpserverapprovalmode(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_mcpserverapprovalmode(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "never" } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerApprovalMode.load(data) yaml_output = instance.to_yaml() @@ -76,3 +74,5 @@ def test_load_mcpserverapprovalmode_from_str(): instance = McpServerApprovalMode.load("never") assert instance is not None assert instance.kind == "never" + + diff --git a/runtime/python/agentschema/tests/test_mcp_server_tool_always_require_approval_mode.py b/runtime/python/agentschema/tests/test_mcp_server_tool_always_require_approval_mode.py index 590ba693..a1666386 100644 --- a/runtime/python/agentschema/tests/test_mcp_server_tool_always_require_approval_mode.py +++ b/runtime/python/agentschema/tests/test_mcp_server_tool_always_require_approval_mode.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,35 +6,34 @@ def test_load_json_mcpservertoolalwaysrequireapprovalmode(): - json_data = r""" + json_data = r''' { "kind": "always" } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerToolAlwaysRequireApprovalMode.load(data) assert instance is not None assert instance.kind == "always" - + def test_load_yaml_mcpservertoolalwaysrequireapprovalmode(): - yaml_data = r""" + yaml_data = r''' kind: always - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = McpServerToolAlwaysRequireApprovalMode.load(data) assert instance is not None assert instance.kind == "always" - def test_roundtrip_json_mcpservertoolalwaysrequireapprovalmode(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "always" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = McpServerToolAlwaysRequireApprovalMode.load(original_data) saved_data = instance.save() @@ -41,14 +41,13 @@ def test_roundtrip_json_mcpservertoolalwaysrequireapprovalmode(): assert reloaded is not None assert reloaded.kind == "always" - def test_to_json_mcpservertoolalwaysrequireapprovalmode(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "always" } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerToolAlwaysRequireApprovalMode.load(data) json_output = instance.to_json() @@ -56,17 +55,18 @@ def test_to_json_mcpservertoolalwaysrequireapprovalmode(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_mcpservertoolalwaysrequireapprovalmode(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "always" } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerToolAlwaysRequireApprovalMode.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_mcp_server_tool_never_require_approval_mode.py b/runtime/python/agentschema/tests/test_mcp_server_tool_never_require_approval_mode.py index 49e20d69..76e81558 100644 --- a/runtime/python/agentschema/tests/test_mcp_server_tool_never_require_approval_mode.py +++ b/runtime/python/agentschema/tests/test_mcp_server_tool_never_require_approval_mode.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,35 +6,34 @@ def test_load_json_mcpservertoolneverrequireapprovalmode(): - json_data = r""" + json_data = r''' { "kind": "never" } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerToolNeverRequireApprovalMode.load(data) assert instance is not None assert instance.kind == "never" - + def test_load_yaml_mcpservertoolneverrequireapprovalmode(): - yaml_data = r""" + yaml_data = r''' kind: never - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = McpServerToolNeverRequireApprovalMode.load(data) assert instance is not None assert instance.kind == "never" - def test_roundtrip_json_mcpservertoolneverrequireapprovalmode(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "never" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = McpServerToolNeverRequireApprovalMode.load(original_data) saved_data = instance.save() @@ -41,14 +41,13 @@ def test_roundtrip_json_mcpservertoolneverrequireapprovalmode(): assert reloaded is not None assert reloaded.kind == "never" - def test_to_json_mcpservertoolneverrequireapprovalmode(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "never" } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerToolNeverRequireApprovalMode.load(data) json_output = instance.to_json() @@ -56,17 +55,18 @@ def test_to_json_mcpservertoolneverrequireapprovalmode(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_mcpservertoolneverrequireapprovalmode(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "never" } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerToolNeverRequireApprovalMode.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_mcp_server_tool_specify_approval_mode.py b/runtime/python/agentschema/tests/test_mcp_server_tool_specify_approval_mode.py index 329943d4..1dffd310 100644 --- a/runtime/python/agentschema/tests/test_mcp_server_tool_specify_approval_mode.py +++ b/runtime/python/agentschema/tests/test_mcp_server_tool_specify_approval_mode.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_mcpservertoolspecifyapprovalmode(): - json_data = r""" + json_data = r''' { "kind": "specify", "alwaysRequireApprovalTools": [ @@ -15,31 +16,30 @@ def test_load_json_mcpservertoolspecifyapprovalmode(): "operation2" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerToolSpecifyApprovalMode.load(data) assert instance is not None assert instance.kind == "specify" - + def test_load_yaml_mcpservertoolspecifyapprovalmode(): - yaml_data = r""" + yaml_data = r''' kind: specify alwaysRequireApprovalTools: - operation1 neverRequireApprovalTools: - operation2 - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = McpServerToolSpecifyApprovalMode.load(data) assert instance is not None assert instance.kind == "specify" - def test_roundtrip_json_mcpservertoolspecifyapprovalmode(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "specify", "alwaysRequireApprovalTools": [ @@ -49,7 +49,7 @@ def test_roundtrip_json_mcpservertoolspecifyapprovalmode(): "operation2" ] } - """ + ''' original_data = json.loads(json_data, strict=False) instance = McpServerToolSpecifyApprovalMode.load(original_data) saved_data = instance.save() @@ -57,10 +57,9 @@ def test_roundtrip_json_mcpservertoolspecifyapprovalmode(): assert reloaded is not None assert reloaded.kind == "specify" - def test_to_json_mcpservertoolspecifyapprovalmode(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "specify", "alwaysRequireApprovalTools": [ @@ -70,7 +69,7 @@ def test_to_json_mcpservertoolspecifyapprovalmode(): "operation2" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerToolSpecifyApprovalMode.load(data) json_output = instance.to_json() @@ -78,10 +77,9 @@ def test_to_json_mcpservertoolspecifyapprovalmode(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_mcpservertoolspecifyapprovalmode(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "specify", "alwaysRequireApprovalTools": [ @@ -91,10 +89,12 @@ def test_to_yaml_mcpservertoolspecifyapprovalmode(): "operation2" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = McpServerToolSpecifyApprovalMode.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_mcp_tool.py b/runtime/python/agentschema/tests/test_mcp_tool.py index 2b32b719..dd1694a3 100644 --- a/runtime/python/agentschema/tests/test_mcp_tool.py +++ b/runtime/python/agentschema/tests/test_mcp_tool.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_mcptool(): - json_data = r""" + json_data = r''' { "kind": "mcp", "connection": { @@ -19,19 +20,22 @@ def test_load_json_mcptool(): "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } - """ + ''' data = json.loads(json_data, strict=False) instance = McpTool.load(data) assert instance is not None assert instance.kind == "mcp" assert instance.serverName == "My MCP Server" assert instance.serverDescription == "This tool allows access to MCP services." - + def test_load_yaml_mcptool(): - yaml_data = r""" + yaml_data = r''' kind: mcp connection: kind: reference @@ -42,8 +46,10 @@ def test_load_yaml_mcptool(): allowedTools: - operation1 - operation2 + headers: + Authorization: Bearer token - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = McpTool.load(data) assert instance is not None @@ -51,10 +57,9 @@ def test_load_yaml_mcptool(): assert instance.serverName == "My MCP Server" assert instance.serverDescription == "This tool allows access to MCP services." - def test_roundtrip_json_mcptool(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "mcp", "connection": { @@ -68,9 +73,12 @@ def test_roundtrip_json_mcptool(): "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = McpTool.load(original_data) saved_data = instance.save() @@ -80,10 +88,9 @@ def test_roundtrip_json_mcptool(): assert reloaded.serverName == "My MCP Server" assert reloaded.serverDescription == "This tool allows access to MCP services." - def test_to_json_mcptool(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "mcp", "connection": { @@ -97,9 +104,12 @@ def test_to_json_mcptool(): "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } - """ + ''' data = json.loads(json_data, strict=False) instance = McpTool.load(data) json_output = instance.to_json() @@ -107,10 +117,9 @@ def test_to_json_mcptool(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_mcptool(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "mcp", "connection": { @@ -124,12 +133,17 @@ def test_to_yaml_mcptool(): "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } - """ + ''' data = json.loads(json_data, strict=False) instance = McpTool.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_model.py b/runtime/python/agentschema/tests/test_model.py index b8e345b4..905121cc 100644 --- a/runtime/python/agentschema/tests/test_model.py +++ b/runtime/python/agentschema/tests/test_model.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_model(): - json_data = r""" + json_data = r''' { "id": "gpt-35-turbo", "provider": "azure", @@ -21,17 +22,17 @@ def test_load_json_model(): "maxTokens": 1000 } } - """ + ''' data = json.loads(json_data, strict=False) instance = Model.load(data) assert instance is not None assert instance.id == "gpt-35-turbo" assert instance.provider == "azure" assert instance.apiType == "chat" - + def test_load_yaml_model(): - yaml_data = r""" + yaml_data = r''' id: gpt-35-turbo provider: azure apiType: chat @@ -44,7 +45,7 @@ def test_load_yaml_model(): temperature: 0.7 maxTokens: 1000 - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = Model.load(data) assert instance is not None @@ -52,10 +53,9 @@ def test_load_yaml_model(): assert instance.provider == "azure" assert instance.apiType == "chat" - def test_roundtrip_json_model(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "id": "gpt-35-turbo", "provider": "azure", @@ -71,7 +71,7 @@ def test_roundtrip_json_model(): "maxTokens": 1000 } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = Model.load(original_data) saved_data = instance.save() @@ -81,10 +81,9 @@ def test_roundtrip_json_model(): assert reloaded.provider == "azure" assert reloaded.apiType == "chat" - def test_to_json_model(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "id": "gpt-35-turbo", "provider": "azure", @@ -100,7 +99,7 @@ def test_to_json_model(): "maxTokens": 1000 } } - """ + ''' data = json.loads(json_data, strict=False) instance = Model.load(data) json_output = instance.to_json() @@ -108,10 +107,9 @@ def test_to_json_model(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_model(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "id": "gpt-35-turbo", "provider": "azure", @@ -127,7 +125,7 @@ def test_to_yaml_model(): "maxTokens": 1000 } } - """ + ''' data = json.loads(json_data, strict=False) instance = Model.load(data) yaml_output = instance.to_yaml() @@ -140,3 +138,5 @@ def test_load_model_from_str(): instance = Model.load("example") assert instance is not None assert instance.id == "example" + + diff --git a/runtime/python/agentschema/tests/test_model_options.py b/runtime/python/agentschema/tests/test_model_options.py index b467ca23..ae3d5344 100644 --- a/runtime/python/agentschema/tests/test_model_options.py +++ b/runtime/python/agentschema/tests/test_model_options.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_modeloptions(): - json_data = r""" + json_data = r''' { "frequencyPenalty": 0.5, "maxOutputTokens": 2048, @@ -24,7 +25,7 @@ def test_load_json_modeloptions(): "anotherProperty": "anotherValue" } } - """ + ''' data = json.loads(json_data, strict=False) instance = ModelOptions.load(data) assert instance is not None @@ -35,12 +36,12 @@ def test_load_json_modeloptions(): assert instance.temperature == 0.7 assert instance.topK == 40 assert instance.topP == 0.9 - + assert instance.allowMultipleToolCalls - + def test_load_yaml_modeloptions(): - yaml_data = r""" + yaml_data = r''' frequencyPenalty: 0.5 maxOutputTokens: 2048 presencePenalty: 0.3 @@ -56,7 +57,7 @@ def test_load_yaml_modeloptions(): customProperty: value anotherProperty: anotherValue - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = ModelOptions.load(data) assert instance is not None @@ -69,10 +70,9 @@ def test_load_yaml_modeloptions(): assert instance.topP == 0.9 assert instance.allowMultipleToolCalls - def test_roundtrip_json_modeloptions(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "frequencyPenalty": 0.5, "maxOutputTokens": 2048, @@ -91,7 +91,7 @@ def test_roundtrip_json_modeloptions(): "anotherProperty": "anotherValue" } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = ModelOptions.load(original_data) saved_data = instance.save() @@ -106,10 +106,9 @@ def test_roundtrip_json_modeloptions(): assert reloaded.topP == 0.9 assert reloaded.allowMultipleToolCalls - def test_to_json_modeloptions(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "frequencyPenalty": 0.5, "maxOutputTokens": 2048, @@ -128,7 +127,7 @@ def test_to_json_modeloptions(): "anotherProperty": "anotherValue" } } - """ + ''' data = json.loads(json_data, strict=False) instance = ModelOptions.load(data) json_output = instance.to_json() @@ -136,10 +135,9 @@ def test_to_json_modeloptions(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_modeloptions(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "frequencyPenalty": 0.5, "maxOutputTokens": 2048, @@ -158,10 +156,12 @@ def test_to_yaml_modeloptions(): "anotherProperty": "anotherValue" } } - """ + ''' data = json.loads(json_data, strict=False) instance = ModelOptions.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_model_resource.py b/runtime/python/agentschema/tests/test_model_resource.py index 7051256d..effabbda 100644 --- a/runtime/python/agentschema/tests/test_model_resource.py +++ b/runtime/python/agentschema/tests/test_model_resource.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,40 +6,39 @@ def test_load_json_modelresource(): - json_data = r""" + json_data = r''' { "kind": "model", "id": "gpt-4o" } - """ + ''' data = json.loads(json_data, strict=False) instance = ModelResource.load(data) assert instance is not None assert instance.kind == "model" assert instance.id == "gpt-4o" - + def test_load_yaml_modelresource(): - yaml_data = r""" + yaml_data = r''' kind: model id: gpt-4o - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = ModelResource.load(data) assert instance is not None assert instance.kind == "model" assert instance.id == "gpt-4o" - def test_roundtrip_json_modelresource(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "model", "id": "gpt-4o" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = ModelResource.load(original_data) saved_data = instance.save() @@ -47,15 +47,14 @@ def test_roundtrip_json_modelresource(): assert reloaded.kind == "model" assert reloaded.id == "gpt-4o" - def test_to_json_modelresource(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "model", "id": "gpt-4o" } - """ + ''' data = json.loads(json_data, strict=False) instance = ModelResource.load(data) json_output = instance.to_json() @@ -63,18 +62,19 @@ def test_to_json_modelresource(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_modelresource(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "model", "id": "gpt-4o" } - """ + ''' data = json.loads(json_data, strict=False) instance = ModelResource.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_o_auth_connection.py b/runtime/python/agentschema/tests/test_o_auth_connection.py index b4d956f1..ff43139e 100644 --- a/runtime/python/agentschema/tests/test_o_auth_connection.py +++ b/runtime/python/agentschema/tests/test_o_auth_connection.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_oauthconnection(): - json_data = r""" + json_data = r''' { "kind": "oauth", "endpoint": "https://api.example.com", @@ -16,7 +17,7 @@ def test_load_json_oauthconnection(): "https://cognitiveservices.azure.com/.default" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = OAuthConnection.load(data) assert instance is not None @@ -24,14 +25,11 @@ def test_load_json_oauthconnection(): assert instance.endpoint == "https://api.example.com" assert instance.clientId == "your-client-id" assert instance.clientSecret == "your-client-secret" - assert ( - instance.tokenUrl - == "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token" - ) - + assert instance.tokenUrl == "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token" + def test_load_yaml_oauthconnection(): - yaml_data = r""" + yaml_data = r''' kind: oauth endpoint: "https://api.example.com" clientId: your-client-id @@ -40,7 +38,7 @@ def test_load_yaml_oauthconnection(): scopes: - "https://cognitiveservices.azure.com/.default" - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = OAuthConnection.load(data) assert instance is not None @@ -48,15 +46,11 @@ def test_load_yaml_oauthconnection(): assert instance.endpoint == "https://api.example.com" assert instance.clientId == "your-client-id" assert instance.clientSecret == "your-client-secret" - assert ( - instance.tokenUrl - == "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token" - ) - + assert instance.tokenUrl == "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token" def test_roundtrip_json_oauthconnection(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "oauth", "endpoint": "https://api.example.com", @@ -67,7 +61,7 @@ def test_roundtrip_json_oauthconnection(): "https://cognitiveservices.azure.com/.default" ] } - """ + ''' original_data = json.loads(json_data, strict=False) instance = OAuthConnection.load(original_data) saved_data = instance.save() @@ -77,15 +71,11 @@ def test_roundtrip_json_oauthconnection(): assert reloaded.endpoint == "https://api.example.com" assert reloaded.clientId == "your-client-id" assert reloaded.clientSecret == "your-client-secret" - assert ( - reloaded.tokenUrl - == "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token" - ) - + assert reloaded.tokenUrl == "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token" def test_to_json_oauthconnection(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "oauth", "endpoint": "https://api.example.com", @@ -96,7 +86,7 @@ def test_to_json_oauthconnection(): "https://cognitiveservices.azure.com/.default" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = OAuthConnection.load(data) json_output = instance.to_json() @@ -104,10 +94,9 @@ def test_to_json_oauthconnection(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_oauthconnection(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "oauth", "endpoint": "https://api.example.com", @@ -118,10 +107,12 @@ def test_to_yaml_oauthconnection(): "https://cognitiveservices.azure.com/.default" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = OAuthConnection.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_object_property.py b/runtime/python/agentschema/tests/test_object_property.py index 362d47fd..62fd7941 100644 --- a/runtime/python/agentschema/tests/test_object_property.py +++ b/runtime/python/agentschema/tests/test_object_property.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_objectproperty(): - json_data = r""" + json_data = r''' { "properties": { "property1": { @@ -16,29 +17,28 @@ def test_load_json_objectproperty(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = ObjectProperty.load(data) assert instance is not None - + def test_load_yaml_objectproperty(): - yaml_data = r""" + yaml_data = r''' properties: property1: kind: string property2: kind: number - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = ObjectProperty.load(data) assert instance is not None - def test_roundtrip_json_objectproperty(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "properties": { "property1": { @@ -49,17 +49,16 @@ def test_roundtrip_json_objectproperty(): } } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = ObjectProperty.load(original_data) saved_data = instance.save() reloaded = ObjectProperty.load(saved_data) assert reloaded is not None - def test_to_json_objectproperty(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "properties": { "property1": { @@ -70,7 +69,7 @@ def test_to_json_objectproperty(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = ObjectProperty.load(data) json_output = instance.to_json() @@ -78,10 +77,9 @@ def test_to_json_objectproperty(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_objectproperty(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "properties": { "property1": { @@ -92,10 +90,12 @@ def test_to_yaml_objectproperty(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = ObjectProperty.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_open_api_tool.py b/runtime/python/agentschema/tests/test_open_api_tool.py index 4d087ece..a1d4b535 100644 --- a/runtime/python/agentschema/tests/test_open_api_tool.py +++ b/runtime/python/agentschema/tests/test_open_api_tool.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_openapitool(): - json_data = r""" + json_data = r''' { "kind": "openapi", "connection": { @@ -13,32 +14,31 @@ def test_load_json_openapitool(): }, "specification": "full_sepcification_here" } - """ + ''' data = json.loads(json_data, strict=False) instance = OpenApiTool.load(data) assert instance is not None assert instance.kind == "openapi" assert instance.specification == "full_sepcification_here" - + def test_load_yaml_openapitool(): - yaml_data = r""" + yaml_data = r''' kind: openapi connection: kind: reference specification: full_sepcification_here - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = OpenApiTool.load(data) assert instance is not None assert instance.kind == "openapi" assert instance.specification == "full_sepcification_here" - def test_roundtrip_json_openapitool(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "openapi", "connection": { @@ -46,7 +46,7 @@ def test_roundtrip_json_openapitool(): }, "specification": "full_sepcification_here" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = OpenApiTool.load(original_data) saved_data = instance.save() @@ -55,10 +55,9 @@ def test_roundtrip_json_openapitool(): assert reloaded.kind == "openapi" assert reloaded.specification == "full_sepcification_here" - def test_to_json_openapitool(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "openapi", "connection": { @@ -66,7 +65,7 @@ def test_to_json_openapitool(): }, "specification": "full_sepcification_here" } - """ + ''' data = json.loads(json_data, strict=False) instance = OpenApiTool.load(data) json_output = instance.to_json() @@ -74,10 +73,9 @@ def test_to_json_openapitool(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_openapitool(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "openapi", "connection": { @@ -85,10 +83,12 @@ def test_to_yaml_openapitool(): }, "specification": "full_sepcification_here" } - """ + ''' data = json.loads(json_data, strict=False) instance = OpenApiTool.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_parser.py b/runtime/python/agentschema/tests/test_parser.py index 6e999b38..29d0e3f5 100644 --- a/runtime/python/agentschema/tests/test_parser.py +++ b/runtime/python/agentschema/tests/test_parser.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,43 +6,42 @@ def test_load_json_parser(): - json_data = r""" + json_data = r''' { "kind": "prompty", "options": { "key": "value" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Parser.load(data) assert instance is not None assert instance.kind == "prompty" - + def test_load_yaml_parser(): - yaml_data = r""" + yaml_data = r''' kind: prompty options: key: value - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = Parser.load(data) assert instance is not None assert instance.kind == "prompty" - def test_roundtrip_json_parser(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "prompty", "options": { "key": "value" } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = Parser.load(original_data) saved_data = instance.save() @@ -49,17 +49,16 @@ def test_roundtrip_json_parser(): assert reloaded is not None assert reloaded.kind == "prompty" - def test_to_json_parser(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "prompty", "options": { "key": "value" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Parser.load(data) json_output = instance.to_json() @@ -67,17 +66,16 @@ def test_to_json_parser(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_parser(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "prompty", "options": { "key": "value" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Parser.load(data) yaml_output = instance.to_yaml() @@ -90,3 +88,5 @@ def test_load_parser_from_str(): instance = Parser.load("example") assert instance is not None assert instance.kind == "example" + + diff --git a/runtime/python/agentschema/tests/test_prompt_agent.py b/runtime/python/agentschema/tests/test_prompt_agent.py index 5ec2654d..f74ba671 100644 --- a/runtime/python/agentschema/tests/test_prompt_agent.py +++ b/runtime/python/agentschema/tests/test_prompt_agent.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_promptagent(): - json_data = r""" + json_data = r''' { "kind": "prompt", "model": { @@ -39,7 +40,7 @@ def test_load_json_promptagent(): }, "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } - """ + ''' data = json.loads(json_data, strict=False) instance = PromptAgent.load(data) assert instance is not None @@ -55,10 +56,10 @@ def test_load_json_promptagent(): their questions. Use their name to address them in your responses. user: {{question}}""" - + def test_load_yaml_promptagent(): - yaml_data = r""" + yaml_data = r''' kind: prompt model: id: gpt-35-turbo @@ -101,7 +102,7 @@ def test_load_yaml_promptagent(): {{question}}" - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = PromptAgent.load(data) assert instance is not None @@ -118,10 +119,9 @@ def test_load_yaml_promptagent(): user: {{question}}""" - def test_roundtrip_json_promptagent(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "model": { @@ -155,7 +155,7 @@ def test_roundtrip_json_promptagent(): }, "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = PromptAgent.load(original_data) saved_data = instance.save() @@ -174,10 +174,9 @@ def test_roundtrip_json_promptagent(): user: {{question}}""" - def test_to_json_promptagent(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "model": { @@ -211,7 +210,7 @@ def test_to_json_promptagent(): }, "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } - """ + ''' data = json.loads(json_data, strict=False) instance = PromptAgent.load(data) json_output = instance.to_json() @@ -219,10 +218,9 @@ def test_to_json_promptagent(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_promptagent(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "model": { @@ -256,7 +254,7 @@ def test_to_yaml_promptagent(): }, "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } - """ + ''' data = json.loads(json_data, strict=False) instance = PromptAgent.load(data) yaml_output = instance.to_yaml() @@ -264,9 +262,8 @@ def test_to_yaml_promptagent(): parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) - def test_load_json_promptagent_1(): - json_data = r""" + json_data = r''' { "kind": "prompt", "model": { @@ -299,7 +296,7 @@ def test_load_json_promptagent_1(): }, "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } - """ + ''' data = json.loads(json_data, strict=False) instance = PromptAgent.load(data) assert instance is not None @@ -315,10 +312,10 @@ def test_load_json_promptagent_1(): their questions. Use their name to address them in your responses. user: {{question}}""" - + def test_load_yaml_promptagent_1(): - yaml_data = r""" + yaml_data = r''' kind: prompt model: id: gpt-35-turbo @@ -361,7 +358,7 @@ def test_load_yaml_promptagent_1(): {{question}}" - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = PromptAgent.load(data) assert instance is not None @@ -378,10 +375,9 @@ def test_load_yaml_promptagent_1(): user: {{question}}""" - def test_roundtrip_json_promptagent_1(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "model": { @@ -414,7 +410,7 @@ def test_roundtrip_json_promptagent_1(): }, "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = PromptAgent.load(original_data) saved_data = instance.save() @@ -433,10 +429,9 @@ def test_roundtrip_json_promptagent_1(): user: {{question}}""" - def test_to_json_promptagent_1(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "model": { @@ -469,7 +464,7 @@ def test_to_json_promptagent_1(): }, "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } - """ + ''' data = json.loads(json_data, strict=False) instance = PromptAgent.load(data) json_output = instance.to_json() @@ -477,10 +472,9 @@ def test_to_json_promptagent_1(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_promptagent_1(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "prompt", "model": { @@ -513,10 +507,12 @@ def test_to_yaml_promptagent_1(): }, "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } - """ + ''' data = json.loads(json_data, strict=False) instance = PromptAgent.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_property.py b/runtime/python/agentschema/tests/test_property.py index 7588fbc0..9677dd6c 100644 --- a/runtime/python/agentschema/tests/test_property.py +++ b/runtime/python/agentschema/tests/test_property.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_property(): - json_data = r""" + json_data = r''' { "name": "my-input", "kind": "string", @@ -19,21 +20,21 @@ def test_load_json_property(): "value3" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = Property.load(data) assert instance is not None assert instance.name == "my-input" assert instance.kind == "string" assert instance.description == "A description of the input property" - + assert instance.required assert instance.default == "default value" assert instance.example == "example value" - + def test_load_yaml_property(): - yaml_data = r""" + yaml_data = r''' name: my-input kind: string description: A description of the input property @@ -45,7 +46,7 @@ def test_load_yaml_property(): - value2 - value3 - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = Property.load(data) assert instance is not None @@ -56,10 +57,9 @@ def test_load_yaml_property(): assert instance.default == "default value" assert instance.example == "example value" - def test_roundtrip_json_property(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "name": "my-input", "kind": "string", @@ -73,7 +73,7 @@ def test_roundtrip_json_property(): "value3" ] } - """ + ''' original_data = json.loads(json_data, strict=False) instance = Property.load(original_data) saved_data = instance.save() @@ -86,10 +86,9 @@ def test_roundtrip_json_property(): assert reloaded.default == "default value" assert reloaded.example == "example value" - def test_to_json_property(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "name": "my-input", "kind": "string", @@ -103,7 +102,7 @@ def test_to_json_property(): "value3" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = Property.load(data) json_output = instance.to_json() @@ -111,10 +110,9 @@ def test_to_json_property(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_property(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "name": "my-input", "kind": "string", @@ -128,7 +126,7 @@ def test_to_yaml_property(): "value3" ] } - """ + ''' data = json.loads(json_data, strict=False) instance = Property.load(data) yaml_output = instance.to_yaml() @@ -142,24 +140,20 @@ def test_load_property_from_bool(): assert instance is not None assert instance.kind == "boolean" assert not instance.example - - def test_load_property_from_float(): instance = Property.load(3.14) assert instance is not None assert instance.kind == "float" assert instance.example == 3.14 - - def test_load_property_from_integer(): instance = Property.load(4) assert instance is not None assert instance.kind == "integer" assert instance.example == 4 - - def test_load_property_from_str(): instance = Property.load("example") assert instance is not None assert instance.kind == "string" assert instance.example == "example" + + diff --git a/runtime/python/agentschema/tests/test_property_schema.py b/runtime/python/agentschema/tests/test_property_schema.py index 373edb9d..a9d38f5b 100644 --- a/runtime/python/agentschema/tests/test_property_schema.py +++ b/runtime/python/agentschema/tests/test_property_schema.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_propertyschema(): - json_data = r""" + json_data = r''' { "examples": [ { @@ -28,16 +29,16 @@ def test_load_json_propertyschema(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = PropertySchema.load(data) assert instance is not None - + assert instance.strict - + def test_load_yaml_propertyschema(): - yaml_data = r""" + yaml_data = r''' examples: - key: value strict: true @@ -52,16 +53,15 @@ def test_load_yaml_propertyschema(): kind: string sample: What is the meaning of life? - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = PropertySchema.load(data) assert instance is not None assert instance.strict - def test_roundtrip_json_propertyschema(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "examples": [ { @@ -84,7 +84,7 @@ def test_roundtrip_json_propertyschema(): } } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = PropertySchema.load(original_data) saved_data = instance.save() @@ -92,10 +92,9 @@ def test_roundtrip_json_propertyschema(): assert reloaded is not None assert reloaded.strict - def test_to_json_propertyschema(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "examples": [ { @@ -118,7 +117,7 @@ def test_to_json_propertyschema(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = PropertySchema.load(data) json_output = instance.to_json() @@ -126,10 +125,9 @@ def test_to_json_propertyschema(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_propertyschema(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "examples": [ { @@ -152,10 +150,12 @@ def test_to_yaml_propertyschema(): } } } - """ + ''' data = json.loads(json_data, strict=False) instance = PropertySchema.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_protocol_version_record.py b/runtime/python/agentschema/tests/test_protocol_version_record.py index 5649994e..46dd1940 100644 --- a/runtime/python/agentschema/tests/test_protocol_version_record.py +++ b/runtime/python/agentschema/tests/test_protocol_version_record.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,40 +6,39 @@ def test_load_json_protocolversionrecord(): - json_data = r""" + json_data = r''' { "protocol": "responses", "version": "v0.1.1" } - """ + ''' data = json.loads(json_data, strict=False) instance = ProtocolVersionRecord.load(data) assert instance is not None assert instance.protocol == "responses" assert instance.version == "v0.1.1" - + def test_load_yaml_protocolversionrecord(): - yaml_data = r""" + yaml_data = r''' protocol: responses version: v0.1.1 - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = ProtocolVersionRecord.load(data) assert instance is not None assert instance.protocol == "responses" assert instance.version == "v0.1.1" - def test_roundtrip_json_protocolversionrecord(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "protocol": "responses", "version": "v0.1.1" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = ProtocolVersionRecord.load(original_data) saved_data = instance.save() @@ -47,15 +47,14 @@ def test_roundtrip_json_protocolversionrecord(): assert reloaded.protocol == "responses" assert reloaded.version == "v0.1.1" - def test_to_json_protocolversionrecord(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "protocol": "responses", "version": "v0.1.1" } - """ + ''' data = json.loads(json_data, strict=False) instance = ProtocolVersionRecord.load(data) json_output = instance.to_json() @@ -63,18 +62,19 @@ def test_to_json_protocolversionrecord(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_protocolversionrecord(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "protocol": "responses", "version": "v0.1.1" } - """ + ''' data = json.loads(json_data, strict=False) instance = ProtocolVersionRecord.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_reference_connection.py b/runtime/python/agentschema/tests/test_reference_connection.py index e35883fd..a21345ee 100644 --- a/runtime/python/agentschema/tests/test_reference_connection.py +++ b/runtime/python/agentschema/tests/test_reference_connection.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,28 +6,28 @@ def test_load_json_referenceconnection(): - json_data = r""" + json_data = r''' { "kind": "reference", "name": "my-reference-connection", "target": "my-target-resource" } - """ + ''' data = json.loads(json_data, strict=False) instance = ReferenceConnection.load(data) assert instance is not None assert instance.kind == "reference" assert instance.name == "my-reference-connection" assert instance.target == "my-target-resource" - + def test_load_yaml_referenceconnection(): - yaml_data = r""" + yaml_data = r''' kind: reference name: my-reference-connection target: my-target-resource - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = ReferenceConnection.load(data) assert instance is not None @@ -34,16 +35,15 @@ def test_load_yaml_referenceconnection(): assert instance.name == "my-reference-connection" assert instance.target == "my-target-resource" - def test_roundtrip_json_referenceconnection(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "reference", "name": "my-reference-connection", "target": "my-target-resource" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = ReferenceConnection.load(original_data) saved_data = instance.save() @@ -53,16 +53,15 @@ def test_roundtrip_json_referenceconnection(): assert reloaded.name == "my-reference-connection" assert reloaded.target == "my-target-resource" - def test_to_json_referenceconnection(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "reference", "name": "my-reference-connection", "target": "my-target-resource" } - """ + ''' data = json.loads(json_data, strict=False) instance = ReferenceConnection.load(data) json_output = instance.to_json() @@ -70,19 +69,20 @@ def test_to_json_referenceconnection(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_referenceconnection(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "reference", "name": "my-reference-connection", "target": "my-target-resource" } - """ + ''' data = json.loads(json_data, strict=False) instance = ReferenceConnection.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_remote_connection.py b/runtime/python/agentschema/tests/test_remote_connection.py index 98089f4b..c6f8315c 100644 --- a/runtime/python/agentschema/tests/test_remote_connection.py +++ b/runtime/python/agentschema/tests/test_remote_connection.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,28 +6,28 @@ def test_load_json_remoteconnection(): - json_data = r""" + json_data = r''' { "kind": "remote", "name": "my-reference-connection", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/" } - """ + ''' data = json.loads(json_data, strict=False) instance = RemoteConnection.load(data) assert instance is not None assert instance.kind == "remote" assert instance.name == "my-reference-connection" assert instance.endpoint == "https://{your-custom-endpoint}.openai.azure.com/" - + def test_load_yaml_remoteconnection(): - yaml_data = r""" + yaml_data = r''' kind: remote name: my-reference-connection endpoint: "https://{your-custom-endpoint}.openai.azure.com/" - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = RemoteConnection.load(data) assert instance is not None @@ -34,16 +35,15 @@ def test_load_yaml_remoteconnection(): assert instance.name == "my-reference-connection" assert instance.endpoint == "https://{your-custom-endpoint}.openai.azure.com/" - def test_roundtrip_json_remoteconnection(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "remote", "name": "my-reference-connection", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = RemoteConnection.load(original_data) saved_data = instance.save() @@ -53,16 +53,15 @@ def test_roundtrip_json_remoteconnection(): assert reloaded.name == "my-reference-connection" assert reloaded.endpoint == "https://{your-custom-endpoint}.openai.azure.com/" - def test_to_json_remoteconnection(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "remote", "name": "my-reference-connection", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/" } - """ + ''' data = json.loads(json_data, strict=False) instance = RemoteConnection.load(data) json_output = instance.to_json() @@ -70,19 +69,20 @@ def test_to_json_remoteconnection(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_remoteconnection(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "remote", "name": "my-reference-connection", "endpoint": "https://{your-custom-endpoint}.openai.azure.com/" } - """ + ''' data = json.loads(json_data, strict=False) instance = RemoteConnection.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_resource.py b/runtime/python/agentschema/tests/test_resource.py index ca478c6f..0e0d7501 100644 --- a/runtime/python/agentschema/tests/test_resource.py +++ b/runtime/python/agentschema/tests/test_resource.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,40 +6,39 @@ def test_load_json_resource(): - json_data = r""" + json_data = r''' { "name": "my-resource", "kind": "model" } - """ + ''' data = json.loads(json_data, strict=False) instance = Resource.load(data) assert instance is not None assert instance.name == "my-resource" assert instance.kind == "model" - + def test_load_yaml_resource(): - yaml_data = r""" + yaml_data = r''' name: my-resource kind: model - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = Resource.load(data) assert instance is not None assert instance.name == "my-resource" assert instance.kind == "model" - def test_roundtrip_json_resource(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "name": "my-resource", "kind": "model" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = Resource.load(original_data) saved_data = instance.save() @@ -47,15 +47,14 @@ def test_roundtrip_json_resource(): assert reloaded.name == "my-resource" assert reloaded.kind == "model" - def test_to_json_resource(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "name": "my-resource", "kind": "model" } - """ + ''' data = json.loads(json_data, strict=False) instance = Resource.load(data) json_output = instance.to_json() @@ -63,18 +62,19 @@ def test_to_json_resource(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_resource(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "name": "my-resource", "kind": "model" } - """ + ''' data = json.loads(json_data, strict=False) instance = Resource.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_template.py b/runtime/python/agentschema/tests/test_template.py index b73782ac..74588129 100644 --- a/runtime/python/agentschema/tests/test_template.py +++ b/runtime/python/agentschema/tests/test_template.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_template(): - json_data = r""" + json_data = r''' { "format": { "kind": "mustache" @@ -14,28 +15,27 @@ def test_load_json_template(): "kind": "mustache" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Template.load(data) assert instance is not None - + def test_load_yaml_template(): - yaml_data = r""" + yaml_data = r''' format: kind: mustache parser: kind: mustache - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = Template.load(data) assert instance is not None - def test_roundtrip_json_template(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "format": { "kind": "mustache" @@ -44,17 +44,16 @@ def test_roundtrip_json_template(): "kind": "mustache" } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = Template.load(original_data) saved_data = instance.save() reloaded = Template.load(saved_data) assert reloaded is not None - def test_to_json_template(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "format": { "kind": "mustache" @@ -63,7 +62,7 @@ def test_to_json_template(): "kind": "mustache" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Template.load(data) json_output = instance.to_json() @@ -71,10 +70,9 @@ def test_to_json_template(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_template(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "format": { "kind": "mustache" @@ -83,10 +81,12 @@ def test_to_yaml_template(): "kind": "mustache" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Template.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_tool.py b/runtime/python/agentschema/tests/test_tool.py index 2bf0dcbf..150b19eb 100644 --- a/runtime/python/agentschema/tests/test_tool.py +++ b/runtime/python/agentschema/tests/test_tool.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_tool(): - json_data = r""" + json_data = r''' { "name": "my-tool", "kind": "function", @@ -14,24 +15,24 @@ def test_load_json_tool(): "input": "value" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Tool.load(data) assert instance is not None assert instance.name == "my-tool" assert instance.kind == "function" assert instance.description == "A description of the tool" - + def test_load_yaml_tool(): - yaml_data = r""" + yaml_data = r''' name: my-tool kind: function description: A description of the tool bindings: input: value - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = Tool.load(data) assert instance is not None @@ -39,10 +40,9 @@ def test_load_yaml_tool(): assert instance.kind == "function" assert instance.description == "A description of the tool" - def test_roundtrip_json_tool(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "name": "my-tool", "kind": "function", @@ -51,7 +51,7 @@ def test_roundtrip_json_tool(): "input": "value" } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = Tool.load(original_data) saved_data = instance.save() @@ -61,10 +61,9 @@ def test_roundtrip_json_tool(): assert reloaded.kind == "function" assert reloaded.description == "A description of the tool" - def test_to_json_tool(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "name": "my-tool", "kind": "function", @@ -73,7 +72,7 @@ def test_to_json_tool(): "input": "value" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Tool.load(data) json_output = instance.to_json() @@ -81,10 +80,9 @@ def test_to_json_tool(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_tool(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "name": "my-tool", "kind": "function", @@ -93,10 +91,12 @@ def test_to_yaml_tool(): "input": "value" } } - """ + ''' data = json.loads(json_data, strict=False) instance = Tool.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_tool_resource.py b/runtime/python/agentschema/tests/test_tool_resource.py index cdcde2be..fb764aa4 100644 --- a/runtime/python/agentschema/tests/test_tool_resource.py +++ b/runtime/python/agentschema/tests/test_tool_resource.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_toolresource(): - json_data = r""" + json_data = r''' { "kind": "tool", "id": "web-search", @@ -13,32 +14,31 @@ def test_load_json_toolresource(): "myToolResourceProperty": "myValue" } } - """ + ''' data = json.loads(json_data, strict=False) instance = ToolResource.load(data) assert instance is not None assert instance.kind == "tool" assert instance.id == "web-search" - + def test_load_yaml_toolresource(): - yaml_data = r""" + yaml_data = r''' kind: tool id: web-search options: myToolResourceProperty: myValue - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = ToolResource.load(data) assert instance is not None assert instance.kind == "tool" assert instance.id == "web-search" - def test_roundtrip_json_toolresource(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "tool", "id": "web-search", @@ -46,7 +46,7 @@ def test_roundtrip_json_toolresource(): "myToolResourceProperty": "myValue" } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = ToolResource.load(original_data) saved_data = instance.save() @@ -55,10 +55,9 @@ def test_roundtrip_json_toolresource(): assert reloaded.kind == "tool" assert reloaded.id == "web-search" - def test_to_json_toolresource(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "tool", "id": "web-search", @@ -66,7 +65,7 @@ def test_to_json_toolresource(): "myToolResourceProperty": "myValue" } } - """ + ''' data = json.loads(json_data, strict=False) instance = ToolResource.load(data) json_output = instance.to_json() @@ -74,10 +73,9 @@ def test_to_json_toolresource(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_toolresource(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "tool", "id": "web-search", @@ -85,10 +83,12 @@ def test_to_yaml_toolresource(): "myToolResourceProperty": "myValue" } } - """ + ''' data = json.loads(json_data, strict=False) instance = ToolResource.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_web_search_tool.py b/runtime/python/agentschema/tests/test_web_search_tool.py index a8b2f7a6..4596d4cf 100644 --- a/runtime/python/agentschema/tests/test_web_search_tool.py +++ b/runtime/python/agentschema/tests/test_web_search_tool.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,7 +6,7 @@ def test_load_json_websearchtool(): - json_data = r""" + json_data = r''' { "kind": "bing_search", "connection": { @@ -19,15 +20,15 @@ def test_load_json_websearchtool(): "freshness": "Day" } } - """ + ''' data = json.loads(json_data, strict=False) instance = WebSearchTool.load(data) assert instance is not None assert instance.kind == "bing_search" - + def test_load_yaml_websearchtool(): - yaml_data = r""" + yaml_data = r''' kind: bing_search connection: kind: reference @@ -38,16 +39,15 @@ def test_load_yaml_websearchtool(): count: 10 freshness: Day - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = WebSearchTool.load(data) assert instance is not None assert instance.kind == "bing_search" - def test_roundtrip_json_websearchtool(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "bing_search", "connection": { @@ -61,7 +61,7 @@ def test_roundtrip_json_websearchtool(): "freshness": "Day" } } - """ + ''' original_data = json.loads(json_data, strict=False) instance = WebSearchTool.load(original_data) saved_data = instance.save() @@ -69,10 +69,9 @@ def test_roundtrip_json_websearchtool(): assert reloaded is not None assert reloaded.kind == "bing_search" - def test_to_json_websearchtool(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "bing_search", "connection": { @@ -86,7 +85,7 @@ def test_to_json_websearchtool(): "freshness": "Day" } } - """ + ''' data = json.loads(json_data, strict=False) instance = WebSearchTool.load(data) json_output = instance.to_json() @@ -94,10 +93,9 @@ def test_to_json_websearchtool(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_websearchtool(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "bing_search", "connection": { @@ -111,10 +109,12 @@ def test_to_yaml_websearchtool(): "freshness": "Day" } } - """ + ''' data = json.loads(json_data, strict=False) instance = WebSearchTool.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/python/agentschema/tests/test_workflow.py b/runtime/python/agentschema/tests/test_workflow.py index 4e150914..b02247eb 100644 --- a/runtime/python/agentschema/tests/test_workflow.py +++ b/runtime/python/agentschema/tests/test_workflow.py @@ -1,3 +1,4 @@ + import json import yaml @@ -5,35 +6,34 @@ def test_load_json_workflow(): - json_data = r""" + json_data = r''' { "kind": "workflow" } - """ + ''' data = json.loads(json_data, strict=False) instance = Workflow.load(data) assert instance is not None assert instance.kind == "workflow" - + def test_load_yaml_workflow(): - yaml_data = r""" + yaml_data = r''' kind: workflow - """ + ''' data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = Workflow.load(data) assert instance is not None assert instance.kind == "workflow" - def test_roundtrip_json_workflow(): """Test that load -> save -> load produces equivalent data.""" - json_data = r""" + json_data = r''' { "kind": "workflow" } - """ + ''' original_data = json.loads(json_data, strict=False) instance = Workflow.load(original_data) saved_data = instance.save() @@ -41,14 +41,13 @@ def test_roundtrip_json_workflow(): assert reloaded is not None assert reloaded.kind == "workflow" - def test_to_json_workflow(): """Test that to_json produces valid JSON.""" - json_data = r""" + json_data = r''' { "kind": "workflow" } - """ + ''' data = json.loads(json_data, strict=False) instance = Workflow.load(data) json_output = instance.to_json() @@ -56,17 +55,18 @@ def test_to_json_workflow(): parsed = json.loads(json_output) assert isinstance(parsed, dict) - def test_to_yaml_workflow(): """Test that to_yaml produces valid YAML.""" - json_data = r""" + json_data = r''' { "kind": "workflow" } - """ + ''' data = json.loads(json_data, strict=False) instance = Workflow.load(data) yaml_output = instance.to_yaml() assert yaml_output is not None parsed = yaml.safe_load(yaml_output) assert isinstance(parsed, dict) + + diff --git a/runtime/rust/agentschema/src/tool.rs b/runtime/rust/agentschema/src/tool.rs index 4b7bc610..d1b71a42 100644 --- a/runtime/rust/agentschema/src/tool.rs +++ b/runtime/rust/agentschema/src/tool.rs @@ -515,6 +515,8 @@ pub struct McpTool { pub approval_mode: serde_json::Value, /// List of allowed operations or resources for the MCP tool pub allowed_tools: Option>, + /// Custom HTTP headers to include in requests to the MCP server, useful for authentication or routing + pub headers: serde_json::Value, } impl McpTool { @@ -568,6 +570,10 @@ impl McpTool { .filter_map(|v| v.as_str().map(|s| s.to_string())) .collect() }), + headers: value + .get("headers") + .cloned() + .unwrap_or(serde_json::Value::Null), } } @@ -604,6 +610,9 @@ impl McpTool { serde_json::to_value(items).unwrap_or(serde_json::Value::Null), ); } + if !self.headers.is_null() { + result.insert("headers".to_string(), self.headers.clone()); + } serde_json::Value::Object(result) } @@ -616,6 +625,11 @@ impl McpTool { pub fn to_yaml(&self) -> Result { serde_yaml::to_string(&self.to_value()) } + /// Returns typed reference to the map if the field is an object. + /// Returns `None` if the field is null or not an object. + pub fn as_headers_dict(&self) -> Option<&serde_json::Map> { + self.headers.as_object() + } } /// OpenApiTool schema type diff --git a/runtime/rust/agentschema/tests/mcp_tool_test.rs b/runtime/rust/agentschema/tests/mcp_tool_test.rs index ad42f569..60d9a88d 100644 --- a/runtime/rust/agentschema/tests/mcp_tool_test.rs +++ b/runtime/rust/agentschema/tests/mcp_tool_test.rs @@ -18,7 +18,10 @@ fn test_mcp_tool_load_json() { "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } "####; let result = McpTool::from_json(json); @@ -53,6 +56,8 @@ approvalMode: allowedTools: - operation1 - operation2 +headers: + Authorization: Bearer token "####; let result = McpTool::from_yaml(yaml); @@ -86,7 +91,10 @@ fn test_mcp_tool_roundtrip() { "allowedTools": [ "operation1", "operation2" - ] + ], + "headers": { + "Authorization": "Bearer token" + } } "####; let result = McpTool::from_json(json); diff --git a/runtime/typescript/agentschema/package-lock.json b/runtime/typescript/agentschema/package-lock.json index 63f651db..0dfbce6c 100644 --- a/runtime/typescript/agentschema/package-lock.json +++ b/runtime/typescript/agentschema/package-lock.json @@ -59,7 +59,6 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -2217,7 +2216,6 @@ "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/types": "8.57.2", @@ -2474,7 +2472,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2769,7 +2766,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -3192,7 +3188,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -3257,7 +3252,6 @@ "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -4104,7 +4098,6 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -5375,7 +5368,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -6332,7 +6324,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6553,7 +6544,6 @@ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "license": "ISC", - "peer": true, "bin": { "yaml": "bin.mjs" }, diff --git a/runtime/typescript/agentschema/src/tool.ts b/runtime/typescript/agentschema/src/tool.ts index fa9b10e2..d09ece47 100644 --- a/runtime/typescript/agentschema/src/tool.ts +++ b/runtime/typescript/agentschema/src/tool.ts @@ -1012,6 +1012,11 @@ export class McpTool extends Tool { */ allowedTools?: string[] = []; + /** + * Custom HTTP headers to include in requests to the MCP server, useful for authentication or routing + */ + headers?: Record | undefined = {}; + /** * Initializes a new instance of McpTool. */ @@ -1033,6 +1038,10 @@ export class McpTool extends Tool { if (init?.allowedTools !== undefined) { this.allowedTools = init.allowedTools; } + + if (init?.headers !== undefined) { + this.headers = init.headers; + } } //#region Load Methods @@ -1080,6 +1089,10 @@ export class McpTool extends Tool { : []; } + if (data["headers"] !== undefined && data["headers"] !== null) { + instance.headers = data["headers"] as Record; + } + if (context) { return context.processOutput(instance) as McpTool; } @@ -1125,6 +1138,10 @@ export class McpTool extends Tool { result["allowedTools"] = obj.allowedTools; } + if (obj.headers !== undefined && obj.headers !== null) { + result["headers"] = obj.headers; + } + return result; } diff --git a/runtime/typescript/agentschema/tests/mcp-tool.test.ts b/runtime/typescript/agentschema/tests/mcp-tool.test.ts index f0b8e6e3..cfbd709f 100644 --- a/runtime/typescript/agentschema/tests/mcp-tool.test.ts +++ b/runtime/typescript/agentschema/tests/mcp-tool.test.ts @@ -18,7 +18,7 @@ describe("McpTool", () => { describe("JSON serialization", () => { it("should load from JSON - example 1", () => { - const json = `{\n "kind": "mcp",\n "connection": {\n "kind": "reference"\n },\n "serverName": "My MCP Server",\n "serverDescription": "This tool allows access to MCP services.",\n "approvalMode": {\n "kind": "always"\n },\n "allowedTools": [\n "operation1",\n "operation2"\n ]\n}`; + const json = `{\n "kind": "mcp",\n "connection": {\n "kind": "reference"\n },\n "serverName": "My MCP Server",\n "serverDescription": "This tool allows access to MCP services.",\n "approvalMode": {\n "kind": "always"\n },\n "allowedTools": [\n "operation1",\n "operation2"\n ],\n "headers": {\n "Authorization": "Bearer token"\n }\n}`; const instance = McpTool.fromJson(json); expect(instance).toBeDefined(); @@ -30,7 +30,7 @@ describe("McpTool", () => { }); it("should round-trip JSON - example 1", () => { - const json = `{\n "kind": "mcp",\n "connection": {\n "kind": "reference"\n },\n "serverName": "My MCP Server",\n "serverDescription": "This tool allows access to MCP services.",\n "approvalMode": {\n "kind": "always"\n },\n "allowedTools": [\n "operation1",\n "operation2"\n ]\n}`; + const json = `{\n "kind": "mcp",\n "connection": {\n "kind": "reference"\n },\n "serverName": "My MCP Server",\n "serverDescription": "This tool allows access to MCP services.",\n "approvalMode": {\n "kind": "always"\n },\n "allowedTools": [\n "operation1",\n "operation2"\n ],\n "headers": {\n "Authorization": "Bearer token"\n }\n}`; const instance = McpTool.fromJson(json); const output = instance.toJson(); const reloaded = McpTool.fromJson(output); @@ -45,7 +45,7 @@ describe("McpTool", () => { describe("YAML serialization", () => { it("should load from YAML - example 1", () => { - const yaml = `kind: mcp\nconnection:\n kind: reference\nserverName: My MCP Server\nserverDescription: This tool allows access to MCP services.\napprovalMode:\n kind: always\nallowedTools:\n - operation1\n - operation2\n`; + const yaml = `kind: mcp\nconnection:\n kind: reference\nserverName: My MCP Server\nserverDescription: This tool allows access to MCP services.\napprovalMode:\n kind: always\nallowedTools:\n - operation1\n - operation2\nheaders:\n Authorization: Bearer token\n`; const instance = McpTool.fromYaml(yaml); expect(instance).toBeDefined(); @@ -57,7 +57,7 @@ describe("McpTool", () => { }); it("should round-trip YAML - example 1", () => { - const yaml = `kind: mcp\nconnection:\n kind: reference\nserverName: My MCP Server\nserverDescription: This tool allows access to MCP services.\napprovalMode:\n kind: always\nallowedTools:\n - operation1\n - operation2\n`; + const yaml = `kind: mcp\nconnection:\n kind: reference\nserverName: My MCP Server\nserverDescription: This tool allows access to MCP services.\napprovalMode:\n kind: always\nallowedTools:\n - operation1\n - operation2\nheaders:\n Authorization: Bearer token\n`; const instance = McpTool.fromYaml(yaml); const output = instance.toYaml(); const reloaded = McpTool.fromYaml(output); diff --git a/schemas/v1.0/McpTool.yaml b/schemas/v1.0/McpTool.yaml index 6ace9ade..e1840035 100644 --- a/schemas/v1.0/McpTool.yaml +++ b/schemas/v1.0/McpTool.yaml @@ -23,6 +23,9 @@ properties: items: type: string description: List of allowed operations or resources for the MCP tool + headers: + $ref: RecordString.yaml + description: Custom HTTP headers to include in requests to the MCP server, useful for authentication or routing required: - kind - connection diff --git a/schemas/v1.0/RecordString.yaml b/schemas/v1.0/RecordString.yaml new file mode 100644 index 00000000..286d8570 --- /dev/null +++ b/schemas/v1.0/RecordString.yaml @@ -0,0 +1,6 @@ +$schema: https://json-schema.org/draft/2020-12/schema +$id: RecordString.yaml +type: object +properties: {} +unevaluatedProperties: + type: string