diff --git a/agentschema-emitter/lib/model/container.tsp b/agentschema-emitter/lib/model/container.tsp index 85fedba..d334ff1 100644 --- a/agentschema-emitter/lib/model/container.tsp +++ b/agentschema-emitter/lib/model/container.tsp @@ -66,7 +66,7 @@ model ContainerAgent extends AgentDefinition { @doc("Container image path (e.g., '/')") @sample(#{ image: "myregistry.azurecr.io/my-agent" }) - image: string; + image?: string; @doc("Path to a Dockerfile for deployment. Can be relative to the working directory or an absolute path.") @sample(#{ dockerfilePath: "./Dockerfile" }) diff --git a/runtime/csharp/AgentSchema/ContainerAgent.cs b/runtime/csharp/AgentSchema/ContainerAgent.cs index 9ca219b..a746817 100644 --- a/runtime/csharp/AgentSchema/ContainerAgent.cs +++ b/runtime/csharp/AgentSchema/ContainerAgent.cs @@ -40,7 +40,7 @@ public ContainerAgent() /// /// Container image path (e.g., '/') /// - public string Image { get; set; } = string.Empty; + public string? Image { get; set; } /// /// Path to a Dockerfile for deployment. Can be relative to the working directory or an absolute path. diff --git a/runtime/go/agentschema/agent_definition.go b/runtime/go/agentschema/agent_definition.go index 9851de6..7ab3c8c 100644 --- a/runtime/go/agentschema/agent_definition.go +++ b/runtime/go/agentschema/agent_definition.go @@ -378,7 +378,7 @@ func WorkflowFromYAML(yamlStr string) (Workflow, error) { type ContainerAgent struct { Kind string `json:"kind" yaml:"kind"` Protocols []ProtocolVersionRecord `json:"protocols" yaml:"protocols"` - Image string `json:"image" yaml:"image"` + Image *string `json:"image,omitempty" yaml:"image,omitempty"` DockerfilePath *string `json:"dockerfilePath,omitempty" yaml:"dockerfilePath,omitempty"` Resources ContainerResources `json:"resources" yaml:"resources"` EnvironmentVariables []EnvironmentVariable `json:"environmentVariables,omitempty" yaml:"environmentVariables,omitempty"` @@ -405,7 +405,8 @@ func LoadContainerAgent(data interface{}, ctx *LoadContext) (ContainerAgent, err } } if val, ok := m["image"]; ok && val != nil { - result.Image = val.(string) + v := val.(string) + result.Image = &v } if val, ok := m["dockerfilePath"]; ok && val != nil { v := val.(string) @@ -444,7 +445,9 @@ func (obj *ContainerAgent) Save(ctx *SaveContext) map[string]interface{} { } result["protocols"] = arr } - result["image"] = obj.Image + if obj.Image != nil { + result["image"] = *obj.Image + } if obj.DockerfilePath != nil { result["dockerfilePath"] = *obj.DockerfilePath } diff --git a/runtime/go/agentschema/container_agent_test.go b/runtime/go/agentschema/container_agent_test.go index ee950cd..d4c841d 100644 --- a/runtime/go/agentschema/container_agent_test.go +++ b/runtime/go/agentschema/container_agent_test.go @@ -49,7 +49,7 @@ func TestContainerAgentLoadJSON(t *testing.T) { if instance.Kind != "hosted" { t.Errorf(`Expected Kind to be "hosted", got %v`, instance.Kind) } - if instance.Image != "myregistry.azurecr.io/my-agent" { + if instance.Image == nil || *instance.Image != "myregistry.azurecr.io/my-agent" { t.Errorf(`Expected Image to be "myregistry.azurecr.io/my-agent", got %v`, instance.Image) } if instance.DockerfilePath == nil || *instance.DockerfilePath != "./Dockerfile" { @@ -87,7 +87,7 @@ environmentVariables: if instance.Kind != "hosted" { t.Errorf(`Expected Kind to be "hosted", got %v`, instance.Kind) } - if instance.Image != "myregistry.azurecr.io/my-agent" { + if instance.Image == nil || *instance.Image != "myregistry.azurecr.io/my-agent" { t.Errorf(`Expected Image to be "myregistry.azurecr.io/my-agent", got %v`, instance.Image) } if instance.DockerfilePath == nil || *instance.DockerfilePath != "./Dockerfile" { @@ -140,7 +140,7 @@ func TestContainerAgentRoundtrip(t *testing.T) { if reloaded.Kind != "hosted" { t.Errorf(`Expected Kind to be "hosted", got %v`, reloaded.Kind) } - if reloaded.Image != "myregistry.azurecr.io/my-agent" { + if reloaded.Image == nil || *reloaded.Image != "myregistry.azurecr.io/my-agent" { t.Errorf(`Expected Image to be "myregistry.azurecr.io/my-agent", got %v`, reloaded.Image) } if reloaded.DockerfilePath == nil || *reloaded.DockerfilePath != "./Dockerfile" { diff --git a/runtime/python/agentschema/src/agentschema/_AgentDefinition.py b/runtime/python/agentschema/src/agentschema/_AgentDefinition.py index fbb4756..767785b 100644 --- a/runtime/python/agentschema/src/agentschema/_AgentDefinition.py +++ b/runtime/python/agentschema/src/agentschema/_AgentDefinition.py @@ -457,7 +457,7 @@ class ContainerAgent(AgentDefinition): Type of agent, e.g., 'hosted' protocols : list[ProtocolVersionRecord] Protocol used by the containerized agent - image : str + image : Optional[str] Container image path (e.g., '/') dockerfilePath : Optional[str] Path to a Dockerfile for deployment. Can be relative to the working directory or an absolute path. @@ -471,7 +471,7 @@ class ContainerAgent(AgentDefinition): kind: str = field(default="hosted") protocols: list[ProtocolVersionRecord] = field(default_factory=list) - image: str = field(default="") + image: Optional[str] = None dockerfilePath: Optional[str] = None resources: ContainerResources = field(default_factory=ContainerResources) environmentVariables: list[EnvironmentVariable] = field(default_factory=list) diff --git a/runtime/rust/agentschema/src/agent_definition.rs b/runtime/rust/agentschema/src/agent_definition.rs index f09f937..9770c9d 100644 --- a/runtime/rust/agentschema/src/agent_definition.rs +++ b/runtime/rust/agentschema/src/agent_definition.rs @@ -373,7 +373,7 @@ pub struct ContainerAgent { /// Protocol used by the containerized agent pub protocols: serde_json::Value, /// Container image path (e.g., '/') - pub image: String, + pub image: Option, /// Path to a Dockerfile for deployment. Can be relative to the working directory or an absolute path. pub dockerfile_path: Option, /// Resource allocation for the container @@ -415,8 +415,7 @@ impl ContainerAgent { image: value .get("image") .and_then(|v| v.as_str()) - .unwrap_or_default() - .to_string(), + .map(|s| s.to_string()), dockerfile_path: value .get("dockerfilePath") .and_then(|v| v.as_str()) @@ -445,11 +444,8 @@ impl ContainerAgent { if !self.protocols.is_null() { result.insert("protocols".to_string(), self.protocols.clone()); } - if !self.image.is_empty() { - result.insert( - "image".to_string(), - serde_json::Value::String(self.image.clone()), - ); + if let Some(ref val) = self.image { + result.insert("image".to_string(), serde_json::Value::String(val.clone())); } if let Some(ref val) = self.dockerfile_path { result.insert( diff --git a/runtime/rust/agentschema/tests/container_agent_test.rs b/runtime/rust/agentschema/tests/container_agent_test.rs index 7011dce..fc63610 100644 --- a/runtime/rust/agentschema/tests/container_agent_test.rs +++ b/runtime/rust/agentschema/tests/container_agent_test.rs @@ -35,7 +35,11 @@ fn test_container_agent_load_json() { ); let instance = result.unwrap(); assert_eq!(instance.kind, "hosted"); - assert_eq!(instance.image, "myregistry.azurecr.io/my-agent"); + assert!(instance.image.is_some(), "Expected image to be Some"); + assert_eq!( + instance.image.as_ref().unwrap(), + &"myregistry.azurecr.io/my-agent" + ); assert!( instance.dockerfile_path.is_some(), "Expected dockerfile_path to be Some" @@ -68,7 +72,7 @@ environmentVariables: ); let instance = result.unwrap(); assert_eq!(instance.kind, "hosted"); - assert_eq!(instance.image, "myregistry.azurecr.io/my-agent"); + assert!(instance.image.is_some(), "Expected image to be Some"); assert!( instance.dockerfile_path.is_some(), "Expected dockerfile_path to be Some" diff --git a/runtime/typescript/agentschema/src/agent-definition.ts b/runtime/typescript/agentschema/src/agent-definition.ts index 4e80caf..23e6675 100644 --- a/runtime/typescript/agentschema/src/agent-definition.ts +++ b/runtime/typescript/agentschema/src/agent-definition.ts @@ -722,7 +722,7 @@ export class ContainerAgent extends AgentDefinition { /** * Container image path (e.g., '/') */ - image: string = ""; + image?: string | undefined; /** * Path to a Dockerfile for deployment. Can be relative to the working directory or an absolute path. @@ -749,7 +749,9 @@ export class ContainerAgent extends AgentDefinition { this.protocols = init?.protocols ?? []; - this.image = init?.image ?? ""; + if (init?.image !== undefined) { + this.image = init.image; + } if (init?.dockerfilePath !== undefined) { this.dockerfilePath = init.dockerfilePath; diff --git a/schemas/v1.0/ContainerAgent.yaml b/schemas/v1.0/ContainerAgent.yaml index a2757eb..965c94f 100644 --- a/schemas/v1.0/ContainerAgent.yaml +++ b/schemas/v1.0/ContainerAgent.yaml @@ -41,7 +41,6 @@ properties: required: - kind - protocols - - image - resources allOf: - $ref: AgentDefinition.yaml