diff --git a/specification/ai/Azure.AI.Projects/assistants/client.tsp b/specification/ai/Azure.AI.Projects/assistants/client.tsp new file mode 100644 index 000000000000..a8d182992910 --- /dev/null +++ b/specification/ai/Azure.AI.Projects/assistants/client.tsp @@ -0,0 +1,300 @@ +import "@azure-tools/typespec-client-generator-core"; + +using Azure.ClientGenerator.Core; + +namespace Azure.AI.Projects.Assistants { + // Trivial response value containers should treat these containers as internal details and instead surface a shimmed + // operation that exposes the underlying data directly. + @@clientName(AgentDeletionStatus, "InternalAgentDeletionStatus", "csharp"); + @@access(deleteAgent, Access.internal, "csharp"); + @@clientName(deleteAgent, "InternalDeleteAgent", "csharp"); + @@access(deleteThread, Access.internal, "csharp"); + @@clientName(deleteThread, "InternalDeleteThread", "csharp"); + @@access(listAgents, Access.internal, "csharp"); + @@clientName(listAgents, "InternalGetAgents", "csharp"); + @@access(listRunSteps, Access.internal, "csharp"); + @@clientName(listRunSteps, "InternalGetRunSteps", "csharp"); + @@access(listMessages, Access.internal, "csharp"); + @@clientName(listMessages, "InternalGetMessages", "csharp"); + @@access(listRuns, Access.internal, "csharp"); + @@clientName(listRuns, "InternalGetRuns", "csharp"); + @@access(FileListResponse, Access.internal, "csharp"); + @@clientName(FileListResponse, "InternalFileListResponse", "csharp"); + @@access(listFiles, Access.internal, "csharp"); + @@clientName(listFiles, "InternalListFiles", "csharp"); + @@access(FileDeletionStatus, Access.internal, "csharp"); + @@clientName(FileDeletionStatus, "InternalFileDeletionStatus", "csharp"); + @@access(deleteFile, Access.internal, "csharp"); + @@clientName(deleteFile, "InternalDeleteFile", "csharp"); + + // In addition to top-level response value containers, trivial intermediate structure -- levels of single-use model + // hierarchy that don't convey explanatory or functional benefit to consumers of the surface -- should also be + // internalized and merged into the more useful top-level type. + + // FunctionToolDefinition: merge FunctionDefinition structure to recast e.g. toolDefinition.function.name into + // toolDefinition.name + + @@access(FunctionDefinition, Access.internal); + @@clientName(FunctionDefinition, "InternalFunctionDefinition", "csharp"); + @@clientName(FunctionToolDefinition.function, "InternalFunction", "csharp"); + + // Make AzureFunctionDefinition internal in C#. + @@access(AzureFunctionDefinition, Access.internal); + @@clientName(AzureFunctionDefinition, + "InternalAzureFunctionDefinition", + "csharp" + ); + @@clientName(AzureFunctionToolDefinition.azureFunction, + "InternalAzureFunction", + "csharp" + ); + @@access(AzureFunctionBinding, Access.public); + + // SubmitToolOutputsAction: include .tool_calls directly rather than via an intermediate .details. + + @@access(SubmitToolOutputsDetails, Access.internal); + @@clientName(SubmitToolOutputsDetails, + "InternalSubmitToolOutputsDetails", + "csharp" + ); + @@clientName(SubmitToolOutputsAction.submitToolOutputs, + "InternalDetails", + "csharp" + ); + + // RequiredFunctionToolCall, RunStepFunctionToolCall: include name/arguments/output directly + + @@access(RunStepFunctionToolCallDetails, Access.internal); + @@clientName(RunStepFunctionToolCallDetails, + "InternalRunStepFunctionToolCallDetails", + "csharp" + ); + @@clientName(RequiredFunctionToolCall.function, "InternalDetails", "csharp"); + @@access(RequiredFunctionToolCallDetails, Access.internal); + @@clientName(RequiredFunctionToolCallDetails, + "InternalRequiredFunctionToolCallDetails", + "csharp" + ); + @@clientName(RunStepFunctionToolCall.function, "InternalDetails", "csharp"); + + // RunStepCodeInterpreterToolCall: include input/outputs directly + + @@access(RunStepCodeInterpreterToolCallDetails, Access.internal); + @@clientName(RunStepCodeInterpreterToolCallDetails, + "InternalCodeInterpreterToolCallDetails", + "csharp" + ); + @@clientName(RunStepCodeInterpreterToolCall.codeInterpreter, + "InternalDetails", + "csharp" + ); + + // MessageTextContent: text/annotations can also merge + + @@access(MessageTextDetails, Access.internal); + @@clientName(MessageTextDetails, "InternalMessageTextDetails", "csharp"); + @@clientName(MessageTextContent.text, "InternalDetails", "csharp"); + + // MessageTextFileCitationAnnotation: file_id/quote don't need another type + + @@access(MessageTextFileCitationDetails, Access.internal); + @@clientName(MessageTextFileCitationDetails, + "InternalMessageTextFileCitationDetails", + "csharp" + ); + @@clientName(MessageTextFileCitationAnnotation.fileCitation, + "InternalDetails", + "csharp" + ); + + // MessageTextFilePathAnnotation: file_id doesn't need a separate details client type + + @@access(MessageTextFilePathDetails, Access.internal); + @@clientName(MessageTextFilePathDetails, + "InternalMessageTextFilePathDetails", + "csharp" + ); + @@clientName(MessageTextFilePathAnnotation.filePath, + "InternalDetails", + "csharp" + ); + + // MessageImageFileContent: *two* levels of intermediate structure can be squashed to bring file_id to the parent + // type. Per earlier precedent with image generation, even the introduction of more image file representations (e.g. + // base64) are better accomplished via another approach at the client layer. + + @@access(MessageImageFileDetails, Access.internal); + @@clientName(MessageImageFileDetails, + "InternalMessageImageFileDetails", + "csharp" + ); + @@clientName(MessageImageFileContent.imageFile, "InternalDetails", "csharp"); + @@clientName(MessageImageFileDetails.fileId, "InternalDetails", "csharp"); + + // Several of the content item types are not intended to be used as input + + @@usage(MessageTextContent, Usage.output); + @@usage(MessageImageFileContent, Usage.output); + @@usage(MessageTextContent, Usage.output); + @@usage(MessageTextFileCitationAnnotation, Usage.output); + @@usage(MessageTextFilePathAnnotation, Usage.output); + + // Ensure some shared types remain public despite interaction with previously internalized details + + // Ensure generator inclusion of streaming "leaf" types not yet referenced by a route + + @@usage(MessageDeltaTextFileCitationAnnotation, Usage.output); + @@access(MessageDeltaTextFileCitationAnnotation, Access.public); + + @@usage(MessageDeltaTextFileCitationAnnotationObject, Usage.output); + @@access(MessageDeltaTextFileCitationAnnotationObject, Access.public); + + @@usage(MessageDeltaTextFilePathAnnotation, Usage.output); + @@access(MessageDeltaTextFilePathAnnotation, Access.public); + + @@usage(MessageDeltaTextFilePathAnnotationObject, Usage.output); + @@access(MessageDeltaTextFilePathAnnotationObject, Access.public); + + @@usage(MessageDeltaImageFileContent, Usage.output); + @@access(MessageDeltaImageFileContent, Access.public); + + @@usage(MessageDeltaImageFileContentObject, Usage.output); + @@access(MessageDeltaImageFileContentObject, Access.public); + + @@usage(MessageDeltaTextContent, Usage.output); + @@access(MessageDeltaTextContent, Access.public); + + @@usage(MessageDeltaTextContentObject, Usage.output); + @@access(MessageDeltaTextContentObject, Access.public); + + @@usage(RunStepDeltaMessageCreationObject, Usage.output); + @@access(RunStepDeltaMessageCreationObject, Access.public); + + @@usage(RunStepDeltaFunction, Usage.output); + @@access(RunStepDeltaFunction, Access.public); + + @@usage(RunStepDeltaCodeInterpreterLogOutput, Usage.output); + @@access(RunStepDeltaCodeInterpreterLogOutput, Access.public); + + @@usage(RunStepDeltaCodeInterpreterImageOutputObject, Usage.output); + @@access(RunStepDeltaCodeInterpreterImageOutputObject, Access.public); + + @@usage(RunStepDeltaChunk, Usage.output); + @@access(RunStepDeltaChunk, Access.public); + + @@usage(MessageDeltaChunk, Usage.output); + @@access(MessageDeltaChunk, Access.public); + + @@usage(MessageDelta, Usage.output); + @@access(MessageDelta, Access.public); + + @@usage(MessageDeltaContent, Usage.output); + @@access(MessageDeltaContent, Access.public); + + // Stream events : made public to expose documentation and make class casting for strongly typed languages easier + + @@usage(AgentStreamEvent, Usage.output); + @@access(AgentStreamEvent, Access.public); + + @@usage(ThreadStreamEvent, Usage.output); + @@access(ThreadStreamEvent, Access.public); + + @@usage(RunStreamEvent, Usage.output); + @@access(RunStreamEvent, Access.public); + + @@usage(RunStepStreamEvent, Usage.output); + @@access(RunStepStreamEvent, Access.public); + + @@usage(MessageStreamEvent, Usage.output); + @@access(MessageStreamEvent, Access.public); + + @@usage(ErrorEvent, Usage.output); + @@access(ErrorEvent, Access.public); + + @@usage(DoneEvent, Usage.output); + @@access(DoneEvent, Access.public); + + // Tool resources + @@usage(ToolResources, Usage.output); + @@access(ToolResources, Access.public); + + @@usage(CodeInterpreterToolResource, Usage.output); + @@access(CodeInterpreterToolResource, Access.public); + + @@usage(FileSearchToolResource, Usage.output); + @@access(FileSearchToolResource, Access.public); + + // Ensure some shared types remain public despite interaction with previously internalized details + @@access(MessageTextFilePathAnnotation, Access.public); + @@access(MessageTextFileCitationAnnotation, Access.public); + @@access(ListSortOrder, Access.public); + @@access(RequiredToolCall, Access.public); + @@usage(FilePurpose, Usage.input | Usage.output); + @@usage(ListSortOrder, Usage.input | Usage.output); + + // Make getFileContent internal method in Python (override with get_file_content_stream) + @@access(getFileContent, Access.internal, "python"); + + // Additional, language-specific idiomatic renames + + @@clientName(OpenAIFile, "OpenAIFile", "csharp"); + @@clientName(OpenAIFile.bytes, "Size", "csharp"); + @@clientName(FilePurpose, "OpenAIFilePurpose", "csharp"); + @@clientName(ThreadMessage.content, "ContentItems", "csharp"); + @@clientName(MessageTextDetails.value, "Text", "csharp"); + @@clientName(CreateRunOptions.`model`, "OverrideModelName", "csharp"); + @@clientName(CreateRunOptions.instructions, "OverrideInstructions", "csharp"); + @@clientName(CreateRunOptions.tools, "OverrideTools", "csharp"); + @@clientName(CreateAndRunThreadOptions.`model`, + "OverrideModelName", + "csharp" + ); + @@clientName(CreateAndRunThreadOptions.instructions, + "OverrideInstructions", + "csharp" + ); + @@clientName(CreateAndRunThreadOptions.tools, "OverrideTools", "csharp"); + + // Override until final decision made on assistants vs agents naming + @@clientName(ThreadMessage.assistantId, "agentId", "python"); + @@clientName(GetAgentOptions.assistantId, "agentId", "python"); + @@clientName(UpdateAgentOptions.assistantId, "agentId", "python"); + @@clientName(DeleteAgentOptions.assistantId, "agentId", "python"); + @@clientName(RunStep.assistantId, "agentId", "python"); + @@clientName(ThreadRun.assistantId, "agentId", "python"); + @@clientName(CreateRunOptions.assistantId, "agentId", "python"); + @@clientName(CreateAndRunThreadOptions.assistantId, "agentId", "python"); + // From https://platform.openai.com/docs/agents/how-it-works + // "Note that deleting an AgentFile doesn’t delete the original File object, it simply deletes the association + // between that File and the Agent." + + //@override(Azure.AI.Agents.createAgent, "java") + //op createAgentCustomization(createAgentOptions: CreateAgentOptions): Agent; + + //@@clientName(updateAgent::parameters.body, + // "updateAgentOptions", + // "java" + //); + //@@clientName(createThreadAndRun::parameters.body, + // "createAndRunThreadOptions", + // "java" + //); + //@@clientName(createThread::parameters.body, + // "agentThreadCreationOptions", + // "java" + //); + ///@@clientName(updateThread::parameters.body, + // "updateAgentThreadOptions", + // "java" + //); + //@@clientName(createVectorStore::parameters.body, + // "vectorStoreOptions", + // "java" + //); + //@@clientName(modifyVectorStore::parameters.body, + // "vectorStoreUpdateOptions", + // "java" + //); + //@@clientName(createRun::parameters.body, "createRunOptions", "java"); + //@@clientName(createMessage::parameters.body, "threadMessageOptions", "java"); +} diff --git a/specification/ai/Azure.AI.Projects/assistants/files/routes.tsp b/specification/ai/Azure.AI.Projects/assistants/files/routes.tsp index c79524777a3a..df720e178c29 100644 --- a/specification/ai/Azure.AI.Projects/assistants/files/routes.tsp +++ b/specification/ai/Azure.AI.Projects/assistants/files/routes.tsp @@ -58,10 +58,10 @@ op uploadFile is Azure.Core.Foundations.Operation< @doc("The file data, in bytes.") @clientName("Data", "csharp") file: HttpPart; - + @doc("The intended purpose of the uploaded file. Use `assistants` for Agents and Message files, `vision` for Agents image file inputs, `batch` for Batch API, and `fine-tune` for Fine-tuning.") purpose: HttpPart; - + /* * Spec note: filename is not documented as a distinct option but functionally should be one. The value is encoded * in the multipart Content-Disposition header for the data section and can be provided independently of diff --git a/specification/ai/Azure.AI.Projects/assistants/main.tsp b/specification/ai/Azure.AI.Projects/assistants/main.tsp deleted file mode 100644 index 3b662be82ec5..000000000000 --- a/specification/ai/Azure.AI.Projects/assistants/main.tsp +++ /dev/null @@ -1,2 +0,0 @@ -import "./models.tsp"; -import "./routes.tsp"; diff --git a/specification/ai/Azure.AI.Projects/assistants/messages/models.tsp b/specification/ai/Azure.AI.Projects/assistants/messages/models.tsp index ceb5c1244f0b..f6c7ad9a5e93 100644 --- a/specification/ai/Azure.AI.Projects/assistants/messages/models.tsp +++ b/specification/ai/Azure.AI.Projects/assistants/messages/models.tsp @@ -151,7 +151,7 @@ model MessageTextDetails { annotations: MessageTextAnnotation[]; } -// Annotations, used by text content: "file_citation" | "file_path" +// Annotations, used by text content: "file_citation" | "file_path" | "url_citation" @discriminator("type") @doc("An abstract representation of an annotation to text thread message content.") @@ -164,6 +164,35 @@ model MessageTextAnnotation { text: string; } +// URL citation annotation + details + +@doc("A citation within the message that points to a specific URL associated with the message. Generated when the agent uses tools such as 'bing_grounding' to search the Internet.") +model MessageTextUrlCitationAnnotation extends MessageTextAnnotation { + @doc("The object type, which is always 'url_citation'.") + type: "url_citation"; + + @encodedName("application/json", "url_citation") + @doc("The details of the URL citation.") + urlCitation: MessageTextUrlCitationDetails; + + @encodedName("application/json", "start_index") + @doc("The first text index associated with this text annotation.") + startIndex?: int32; + + @encodedName("application/json", "end_index") + @doc("The last text index associated with this text annotation.") + endIndex?: int32; +} + +@doc("A representation of a URL citation, as used in text thread message content.") +model MessageTextUrlCitationDetails { + @doc("The URL associated with this citation.") + url: string; + + @doc("The title of the URL.") + title?: string; +} + // File citation annotation + details @doc("A citation within the message that points to a specific quote from a specific File associated with the agent or the message. Generated when the agent uses the 'file_search' tool to search files.") @@ -355,6 +384,33 @@ model MessageDeltaTextAnnotation { type: string; } +@doc("A citation within the message that points to a specific URL associated with the message. Generated when the agent uses tools such as 'bing_grounding' to search the Internet.") +model MessageDeltaTextUrlCitationAnnotation extends MessageDeltaTextAnnotation { + @doc("The object type, which is always 'url_citation'.") + type: "url_citation"; + + @encodedName("application/json", "url_citation") + @doc("The details of the URL citation.") + urlCitation: MessageDeltaTextUrlCitationDetails; + + @encodedName("application/json", "start_index") + @doc("The first text index associated with this text annotation.") + startIndex?: int32; + + @encodedName("application/json", "end_index") + @doc("The last text index associated with this text annotation.") + endIndex?: int32; +} + +@doc("A representation of a URL citation, as used in text thread message content.") +model MessageDeltaTextUrlCitationDetails { + @doc("The URL associated with this citation.") + url: string; + + @doc("The title of the URL.") + title?: string; +} + /** Represents a streamed file citation applied to a streaming text content part. */ model MessageDeltaTextFileCitationAnnotation extends MessageDeltaTextAnnotation { @@ -414,12 +470,3 @@ model MessageDeltaTextFilePathAnnotationObject { @encodedName("application/json", "file_id") fileId?: string; } - -/** A representation of the URL used for the text citation. */ -model MessageDeltaTextUrlCitationDetails { - /** The URL where the citation is from. */ - url?: string; - - /** The title of the URL. */ - title?: string; -} diff --git a/specification/ai/Azure.AI.Projects/assistants/models.tsp b/specification/ai/Azure.AI.Projects/assistants/models.tsp index 6d552dad15d9..684b24a3e230 100644 --- a/specification/ai/Azure.AI.Projects/assistants/models.tsp +++ b/specification/ai/Azure.AI.Projects/assistants/models.tsp @@ -202,3 +202,17 @@ model AgentDeletionStatus { @doc("The object type, which is always 'assistant.deleted'.") object: "assistant.deleted"; } + +@doc("The request details to use when retrieving an agent.") +model GetAgentOptions { + @doc("Identifier of the agent.") + @path + assistantId: string; +} + +@doc("The request details to use when deleting an agent.") +model DeleteAgentOptions { + @doc("Identifier of the agent.") + @path + assistantId: string; +} diff --git a/specification/ai/Azure.AI.Projects/assistants/routes.tsp b/specification/ai/Azure.AI.Projects/assistants/routes.tsp index 4929ba11dacd..f7220fec9505 100644 --- a/specification/ai/Azure.AI.Projects/assistants/routes.tsp +++ b/specification/ai/Azure.AI.Projects/assistants/routes.tsp @@ -62,9 +62,10 @@ op listAgents is Azure.Core.Foundations.Operation< @route("/assistants/{assistantId}") op getAgent is Azure.Core.Foundations.Operation< { - @doc("Identifier of the agent.") - @path - assistantId: string; + /** + * The request details to use when retrieving an agent. + */ + ...GetAgentOptions; }, Agent >; @@ -103,9 +104,10 @@ op updateAgent is Azure.Core.Foundations.Operation< @route("/assistants/{assistantId}") op deleteAgent is Azure.Core.Foundations.Operation< { - @doc("Identifier of the agent.") - @path - assistantId: string; + /** + * The request details to use when deleting an agent. + */ + ...DeleteAgentOptions; }, AgentDeletionStatus >; diff --git a/specification/ai/Azure.AI.Projects/assistants/run_steps/models.tsp b/specification/ai/Azure.AI.Projects/assistants/run_steps/models.tsp index 67e24ed7aa1e..bfc57b296e0d 100644 --- a/specification/ai/Azure.AI.Projects/assistants/run_steps/models.tsp +++ b/specification/ai/Azure.AI.Projects/assistants/run_steps/models.tsp @@ -265,7 +265,7 @@ model RunStepDeltaFileSearchToolCall extends RunStepDeltaToolCall { /** Reserved for future use. */ @encodedName("application/json", "file_search") - fileSearch?: Record; + fileSearch?: RunStepFileSearchToolCallResults; } /** Represents a Code Interpreter tool call within a streaming run step's tool call details. */ diff --git a/specification/ai/Azure.AI.Projects/assistants/tools/models.tsp b/specification/ai/Azure.AI.Projects/assistants/tools/models.tsp index efd2b465dcd7..67cf55849788 100644 --- a/specification/ai/Azure.AI.Projects/assistants/tools/models.tsp +++ b/specification/ai/Azure.AI.Projects/assistants/tools/models.tsp @@ -58,11 +58,11 @@ model BingGroundingToolDefinition extends ToolDefinition { @doc("The input definition information for a Microsoft Fabric tool as used to configure an agent.") model MicrosoftFabricToolDefinition extends ToolDefinition { - @doc("The object type, which is always 'fabric_aiskill'.") - type: "fabric_aiskill"; + @doc("The object type, which is always 'fabric_dataagent'.") + type: "fabric_dataagent"; @doc("The list of connections used by the Microsoft Fabric tool.") - fabric_aiskill: ToolConnectionList; + fabric_dataagent: ToolConnectionList; } @doc("The input definition information for a sharepoint tool as used to configure an agent.") @@ -400,11 +400,11 @@ model RunStepSharepointToolCall extends RunStepToolCall { executed Microsoft Fabric operations. """) model RunStepMicrosoftFabricToolCall extends RunStepToolCall { - @doc("The object type, which is always 'fabric_aiskill'.") - type: "fabric_aiskill"; + @doc("The object type, which is always 'fabric_dataagent'.") + type: "fabric_dataagent"; @doc("Reserved for future use.") - @encodedName("application/json", "fabric_aiskill") + @encodedName("application/json", "fabric_dataagent") microsoftFabric: Record; } @@ -548,8 +548,8 @@ union AgentsNamedToolChoiceType { /** Tool type `bing_grounding` */ bingGrounding: "bing_grounding", - /** Tool type `fabric_aiskill` */ - microsoftFabric: "fabric_aiskill", + /** Tool type `fabric_dataagent` */ + microsoftFabric: "fabric_dataagent", /** Tool type `sharepoint_grounding` */ sharepoint: "sharepoint_grounding", @@ -565,7 +565,7 @@ model FunctionName { } /** - * A set of connection resources currently used by either the `bing_grounding`, `fabric_aiskill`, or `sharepoint_grounding` tools. + * A set of connection resources currently used by either the `bing_grounding`, `fabric_dataagent`, or `sharepoint_grounding` tools. */ model ToolConnectionList { /** diff --git a/specification/ai/Azure.AI.Projects/assistants/tools/tool_resources.tsp b/specification/ai/Azure.AI.Projects/assistants/tools/tool_resources.tsp index 6f1ed5176e41..28b9a96064d6 100644 --- a/specification/ai/Azure.AI.Projects/assistants/tools/tool_resources.tsp +++ b/specification/ai/Azure.AI.Projects/assistants/tools/tool_resources.tsp @@ -81,7 +81,7 @@ model AzureAISearchResource { */ @maxItems(1) @encodedName("application/json", "indexes") - indexList?: IndexResource[]; + indexList?: AISearchIndexResource[]; } /** @@ -101,6 +101,30 @@ model IndexResource { indexName: string; } +/** + * A AI Search Index resource. + */ +model AISearchIndexResource { + ...IndexResource; + + /** + * Type of query in an AIIndexResource attached to this agent. + */ + @encodedName("application/json", "query_type") + queryType?: AzureAISearchQueryType; + + /** + * Number of documents to retrieve from search and present to the model. + */ + @encodedName("application/json", "top_k") + topK?: int32; + + /** + * Odata filter string for search resource. + */ + filter?: string; +} + // // Creation request objects // @@ -218,3 +242,23 @@ model UpdateFileSearchToolResourceOptions { @encodedName("application/json", "vector_store_ids") vectorStoreIds?: string[]; } + +/** Available query types for Azure AI Search tool. */ +union AzureAISearchQueryType { + string, + + /** Query type `simple` */ + simple: "simple", + + /** Query type `semantic` */ + semantic: "semantic", + + /** Query type `vector` */ + vector: "vector", + + /** Query type `vector_simple_hybrid` */ + vector_simple_hybrid: "vector_simple_hybrid", + + /** Query type `vector_semantic_hybrid` */ + vector_semantic_hybrid: "vector_semantic_hybrid", +}