From ad28c90c862aafc9b3819d363eaaf79fc04ddc0d Mon Sep 17 00:00:00 2001 From: Ganesh Bheemarasetty Date: Mon, 4 Nov 2024 15:01:41 -0800 Subject: [PATCH 1/4] first version of streaming api --- sdk/ai/ai-projects/package.json | 6 + sdk/ai/ai-projects/review/ai-projects.api.md | 132 +++++++++++++++-- sdk/ai/ai-projects/src/agents/index.ts | 28 ++-- sdk/ai/ai-projects/src/agents/inputOutputs.ts | 11 ++ sdk/ai/ai-projects/src/agents/streaming.ts | 134 ++++++++++++++++++ sdk/ai/ai-projects/src/index.ts | 2 + .../test/public/agents/streaming.spec.ts | 59 ++++++++ 7 files changed, 354 insertions(+), 18 deletions(-) create mode 100644 sdk/ai/ai-projects/src/agents/inputOutputs.ts create mode 100644 sdk/ai/ai-projects/src/agents/streaming.ts create mode 100644 sdk/ai/ai-projects/test/public/agents/streaming.spec.ts diff --git a/sdk/ai/ai-projects/package.json b/sdk/ai/ai-projects/package.json index 57efe48f1d10..da361791a415 100644 --- a/sdk/ai/ai-projects/package.json +++ b/sdk/ai/ai-projects/package.json @@ -58,6 +58,8 @@ "@azure-rest/core-client": "^2.1.0", "@azure/core-auth": "^1.6.0", "@azure/core-rest-pipeline": "^1.5.0", + "@azure/core-util": "^1.9.0", + "@azure/core-sse": "^2.1.3", "@azure/logger": "^1.0.0", "tslib": "^2.6.2", "@azure/core-paging": "^1.5.0" @@ -110,18 +112,22 @@ "./package.json": "./package.json", ".": { "browser": { + "source": "./src/index.ts", "types": "./dist/browser/index.d.ts", "default": "./dist/browser/index.js" }, "react-native": { + "source": "./src/index.ts", "types": "./dist/react-native/index.d.ts", "default": "./dist/react-native/index.js" }, "import": { + "source": "./src/index.ts", "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" }, "require": { + "source": "./src/index.ts", "types": "./dist/commonjs/index.d.ts", "default": "./dist/commonjs/index.js" } diff --git a/sdk/ai/ai-projects/review/ai-projects.api.md b/sdk/ai/ai-projects/review/ai-projects.api.md index fba90fab7c1f..9f613596dda7 100644 --- a/sdk/ai/ai-projects/review/ai-projects.api.md +++ b/sdk/ai/ai-projects/review/ai-projects.api.md @@ -9,25 +9,50 @@ import { Pipeline } from '@azure/core-rest-pipeline'; import { RequestParameters } from '@azure-rest/core-client'; import { TokenCredential } from '@azure/core-auth'; +// @public +export interface AgentDeletionStatusOutput { + deleted: boolean; + id: string; + object: "assistant.deleted"; +} + +// @public +export interface AgentOutput { + created_at: number; + description: string | null; + id: string; + instructions: string | null; + metadata: Record | null; + model: string; + name: string | null; + object: "assistant"; + // Warning: (ae-forgotten-export) The symbol "AgentsApiResponseFormatOptionOutput" needs to be exported by the entry point index.d.ts + response_format?: AgentsApiResponseFormatOptionOutput | null; + temperature: number | null; + // Warning: (ae-forgotten-export) The symbol "ToolResourcesOutput" needs to be exported by the entry point index.d.ts + tool_resources: ToolResourcesOutput | null; + // Warning: (ae-forgotten-export) The symbol "ToolDefinitionOutput" needs to be exported by the entry point index.d.ts + tools: Array; + top_p: number | null; +} + // @public (undocumented) export interface AgentsOperations { // Warning: (ae-forgotten-export) The symbol "AgentsCancelRunParameters" needs to be exported by the entry point index.d.ts cancelRun: (threadId: string, runId: string, options?: AgentsCancelRunParameters) => Promise; - // Warning: (ae-forgotten-export) The symbol "CreateAgentOptions" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "AgentOutput" needs to be exported by the entry point index.d.ts createAgent: (options: CreateAgentOptions) => Promise; - // Warning: (ae-forgotten-export) The symbol "AgentsCreateMessageParameters" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "ThreadMessageOptions" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "ThreadMessageOutput" needs to be exported by the entry point index.d.ts - createMessage: (threadId: string, options: AgentsCreateMessageParameters) => Promise; + createMessage: (threadId: string, options: ThreadMessageOptions) => Promise; // Warning: (ae-forgotten-export) The symbol "AgentsCreateRunParameters" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "ThreadRunOutput" needs to be exported by the entry point index.d.ts createRun: (threadId: string, options: AgentsCreateRunParameters) => Promise; - // Warning: (ae-forgotten-export) The symbol "AgentsCreateThreadParameters" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "AgentThreadOutput" needs to be exported by the entry point index.d.ts - createThread: (options: AgentsCreateThreadParameters) => Promise; + createRunStreaming: (threadId: string, options: CreateRunOptions) => AsyncIterable; + // Warning: (ae-forgotten-export) The symbol "AgentThreadCreationOptions" needs to be exported by the entry point index.d.ts + createThread: (options?: AgentThreadCreationOptions) => Promise; // Warning: (ae-forgotten-export) The symbol "AgentsCreateThreadAndRunParameters" needs to be exported by the entry point index.d.ts createThreadAndRun: (options: AgentsCreateThreadAndRunParameters) => Promise; - // Warning: (ae-forgotten-export) The symbol "AgentDeletionStatusOutput" needs to be exported by the entry point index.d.ts + createThreadAndRunStreaming: (options: CreateAndRunThreadOptions) => AsyncIterable; deleteAgent: (assistantId: string) => Promise; // Warning: (ae-forgotten-export) The symbol "AgentsDeleteFileParameters" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "FileDeletionStatusOutput" needs to be exported by the entry point index.d.ts @@ -58,7 +83,6 @@ export interface AgentsOperations { listRuns: (threadId: string, options?: AgentsListRunsParameters) => Promise; // Warning: (ae-forgotten-export) The symbol "AgentsSubmitToolOutputsToRunParameters" needs to be exported by the entry point index.d.ts submitToolOutputsToRun: (threadId: string, runId: string, options: AgentsSubmitToolOutputsToRunParameters) => Promise; - // Warning: (ae-forgotten-export) The symbol "UpdateAgentOptions" needs to be exported by the entry point index.d.ts updateAgent: (assistantId: string, options: UpdateAgentOptions) => Promise; // Warning: (ae-forgotten-export) The symbol "AgentsUpdateMessageParameters" needs to be exported by the entry point index.d.ts updateMessage: (threadId: string, messageId: string, options: AgentsUpdateMessageParameters) => Promise; @@ -71,6 +95,23 @@ export interface AgentsOperations { uploadFile: (options: AgentsUploadFileParameters) => Promise; } +// @public (undocumented) +export interface AgentStreamEventMessage { + // (undocumented) + data: any; + // (undocumented) + eventType: string; +} + +// @public +export interface AgentThreadOutput { + created_at: number; + id: string; + metadata: Record | null; + object: "thread"; + tool_resources: ToolResourcesOutput | null; +} + // @public (undocumented) export class AIProjectsClient { // Warning: (ae-forgotten-export) The symbol "AIProjectsClientOptions" needs to be exported by the entry point index.d.ts @@ -81,6 +122,79 @@ export class AIProjectsClient { readonly pipeline: Pipeline; } +// @public +export interface CreateAgentOptions { + description?: string | null; + instructions?: string | null; + metadata?: Record | null; + model: string; + name?: string | null; + // Warning: (ae-forgotten-export) The symbol "AgentsApiResponseFormatOption" needs to be exported by the entry point index.d.ts + response_format?: AgentsApiResponseFormatOption | null; + temperature?: number | null; + // Warning: (ae-forgotten-export) The symbol "ToolResources" needs to be exported by the entry point index.d.ts + tool_resources?: ToolResources | null; + // Warning: (ae-forgotten-export) The symbol "ToolDefinition" needs to be exported by the entry point index.d.ts + tools?: Array; + top_p?: number | null; +} + +// @public +export interface CreateAndRunThreadOptions { + assistant_id: string; + instructions?: string | null; + max_completion_tokens?: number | null; + max_prompt_tokens?: number | null; + metadata?: Record | null; + model?: string | null; + response_format?: AgentsApiResponseFormatOption | null; + stream?: boolean; + temperature?: number | null; + thread?: AgentThreadCreationOptions; + // Warning: (ae-forgotten-export) The symbol "AgentsApiToolChoiceOption" needs to be exported by the entry point index.d.ts + tool_choice?: AgentsApiToolChoiceOption | null; + // Warning: (ae-forgotten-export) The symbol "UpdateToolResourcesOptions" needs to be exported by the entry point index.d.ts + tool_resources?: UpdateToolResourcesOptions | null; + tools?: Array | null; + top_p?: number | null; + // Warning: (ae-forgotten-export) The symbol "TruncationObject" needs to be exported by the entry point index.d.ts + truncation_strategy?: TruncationObject | null; +} + +// @public +export interface CreateRunOptions { + additional_instructions?: string | null; + // Warning: (ae-forgotten-export) The symbol "ThreadMessage" needs to be exported by the entry point index.d.ts + additional_messages?: Array | null; + assistant_id: string; + instructions?: string | null; + max_completion_tokens?: number | null; + max_prompt_tokens?: number | null; + metadata?: Record | null; + model?: string | null; + response_format?: AgentsApiResponseFormatOption | null; + stream?: boolean; + temperature?: number | null; + tool_choice?: AgentsApiToolChoiceOption | null; + tools?: Array | null; + top_p?: number | null; + truncation_strategy?: TruncationObject | null; +} + +// @public +export interface UpdateAgentOptions { + description?: string | null; + instructions?: string | null; + metadata?: Record | null; + model?: string; + name?: string | null; + response_format?: AgentsApiResponseFormatOption | null; + temperature?: number | null; + tool_resources?: ToolResources; + tools?: Array; + top_p?: number | null; +} + // (No @packageDocumentation comment for this package) ``` diff --git a/sdk/ai/ai-projects/src/agents/index.ts b/sdk/ai/ai-projects/src/agents/index.ts index 97e090cb8b91..ef3b239c7346 100644 --- a/sdk/ai/ai-projects/src/agents/index.ts +++ b/sdk/ai/ai-projects/src/agents/index.ts @@ -4,13 +4,14 @@ import { Client } from "@azure-rest/core-client"; import { AgentDeletionStatusOutput, AgentOutput, AgentThreadOutput, FileContentResponseOutput, FileDeletionStatusOutput, FileListResponseOutput, OpenAIFileOutput, OpenAIPageableListOfAgentOutput, OpenAIPageableListOfThreadRunOutput, ThreadDeletionStatusOutput, ThreadMessageOutput, ThreadRunOutput } from "../generated/src/outputModels.js"; -import { AgentsCancelRunParameters, AgentsCreateMessageParameters, AgentsCreateRunParameters, AgentsCreateThreadAndRunParameters, AgentsCreateThreadParameters, AgentsDeleteFileParameters, AgentsDeleteThreadParameters, AgentsGetFileContentParameters, AgentsGetFileParameters, AgentsGetRunParameters, AgentsGetThreadParameters, AgentsListAgentsQueryParamProperties, AgentsListFilesParameters, AgentsListMessagesParameters, AgentsListRunsParameters, AgentsSubmitToolOutputsToRunParameters, AgentsUpdateMessageParameters, AgentsUpdateRunParameters, AgentsUpdateThreadParameters, AgentsUploadFileParameters } from "../generated/src/parameters.js"; +import { AgentsCancelRunParameters, AgentsCreateRunParameters, AgentsCreateThreadAndRunParameters, AgentsDeleteFileParameters, AgentsDeleteThreadParameters, AgentsGetFileContentParameters, AgentsGetFileParameters, AgentsGetRunParameters, AgentsGetThreadParameters, AgentsListAgentsQueryParamProperties, AgentsListFilesParameters, AgentsListMessagesParameters, AgentsListRunsParameters, AgentsSubmitToolOutputsToRunParameters, AgentsUpdateMessageParameters, AgentsUpdateRunParameters, AgentsUpdateThreadParameters, AgentsUploadFileParameters } from "../generated/src/parameters.js"; import { createAgent, deleteAgent, getAgent, listAgents, updateAgent } from "./assistants.js"; import { deleteFile, getFile, getFileContent, listFiles, uploadFile } from "./files.js"; import { createThread, deleteThread, getThread, updateThread } from "./threads.js"; import { cancelRun, createRun, createThreadAndRun, getRun, listRuns, submitToolOutputsToRun, updateRun } from "./runs.js"; import { createMessage, listMessages, updateMessage } from "./messages.js"; -import { CreateAgentOptions, UpdateAgentOptions } from "../generated/src/models.js"; +import { AgentThreadCreationOptions, CreateAgentOptions, CreateAndRunThreadOptions, CreateRunOptions, ThreadMessageOptions, UpdateAgentOptions } from "../generated/src/models.js"; +import { AgentStreamEventMessage, createRunStreaming, createThreadAndRunStreaming } from "./streaming.js"; export interface AgentsOperations { /** Creates a new agent. */ @@ -37,7 +38,7 @@ export interface AgentsOperations { /** Creates a new thread. Threads contain messages and can be run by agents. */ createThread: ( - options: AgentsCreateThreadParameters, + options?: AgentThreadCreationOptions, ) => Promise; /** Gets information about an existing thread. */ getThread: ( @@ -94,10 +95,16 @@ export interface AgentsOperations { options: AgentsCreateThreadAndRunParameters, ) => Promise; + /** create a new thread and immediately start a run of that thread and stream */ + createRunStreaming: (threadId: string, options: CreateRunOptions) => AsyncIterable; + + /** create a new thread and immediately start a run of that thread and stream */ + createThreadAndRunStreaming: (options: CreateAndRunThreadOptions) => AsyncIterable; + /** Creates a new message on a specified thread. */ createMessage: ( threadId: string, - options: AgentsCreateMessageParameters, + options: ThreadMessageOptions, ) => Promise; /** Gets a list of messages that exist on a thread. */ listMessages: ( @@ -152,8 +159,8 @@ function getAgents(context: Client) : AgentsOperations { assistantId: string ) => deleteAgent(context, assistantId), - createThread: (options: AgentsCreateThreadParameters) => - createThread(context, options), + createThread: (options?: AgentThreadCreationOptions) => + createThread(context, {body: options || {}}), getThread: (threadId: string, options?: AgentsGetThreadParameters) => getThread(context, threadId, options), updateThread: (threadId: string, options: AgentsUpdateThreadParameters) => @@ -175,9 +182,12 @@ function getAgents(context: Client) : AgentsOperations { cancelRun(context, threadId, runId, options), createThreadAndRun: (options: AgentsCreateThreadAndRunParameters) => createThreadAndRun(context, options), - - createMessage: (threadId: string, options: AgentsCreateMessageParameters) => - createMessage(context, threadId, options), + createRunStreaming: (threadId: string, options: CreateRunOptions) => + createRunStreaming(context, threadId, {body: options}), + createThreadAndRunStreaming: (options: CreateAndRunThreadOptions) => + createThreadAndRunStreaming(context, {body: options}), + createMessage: (threadId: string, options: ThreadMessageOptions) => + createMessage(context, threadId, { body: options }), listMessages: (threadId: string, options?: AgentsListMessagesParameters) => listMessages(context, threadId, options), updateMessage: (threadId: string, messageId: string, options: AgentsUpdateMessageParameters) => diff --git a/sdk/ai/ai-projects/src/agents/inputOutputs.ts b/sdk/ai/ai-projects/src/agents/inputOutputs.ts new file mode 100644 index 000000000000..20e54695690b --- /dev/null +++ b/sdk/ai/ai-projects/src/agents/inputOutputs.ts @@ -0,0 +1,11 @@ + +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { CreateAgentOptions, CreateAndRunThreadOptions, CreateRunOptions, UpdateAgentOptions } from "../generated/src/models.js" +import { AgentDeletionStatusOutput, AgentOutput, AgentThreadOutput } from "../generated/src/outputModels.js" +import { AgentStreamEventMessage } from "./streaming.js" + +export{CreateAgentOptions, CreateRunOptions, CreateAndRunThreadOptions, UpdateAgentOptions, AgentStreamEventMessage} + +export{AgentThreadOutput, AgentOutput, AgentDeletionStatusOutput} diff --git a/sdk/ai/ai-projects/src/agents/streaming.ts b/sdk/ai/ai-projects/src/agents/streaming.ts new file mode 100644 index 000000000000..96d7eec55c32 --- /dev/null +++ b/sdk/ai/ai-projects/src/agents/streaming.ts @@ -0,0 +1,134 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { Client, createRestError } from "@azure-rest/core-client"; +import { ProjectsClient } from "../generated/src/clientDefinitions.js"; +import { AgentsCreateRunParameters, AgentsCreateThreadAndRunBodyParam } from "../generated/src/index.js"; + +const expectedStatuses = ["200"]; + +export interface AgentStreamEventMessage { + data: any; + eventType: string; +} +// export interface AgentStreamMessage { +// data: string | ThreadMessageOutput | ThreadRunOutput | RunStepOutput | {}; +// eventType: string; +// } + +// export enum AgentStreamEventType { +// ThreadRunCreated = "thread.run.created", +// ThreadRunQueued = "thread.run.queued", +// ThreadRunInProgress = "thread.run.in_progress", +// ThreadRunStepCreated = "thread.run.step.created", +// ThreadRunStepInProgress = "thread.run.step.in_progress", +// ThreadMessageCreated = "thread.message.created", +// ThreadMessageInProgress = "thread.message.in_progress", +// ThreadMessageDelta = "thread.message.delta", +// ThreadMessageCompleted = "thread.message.completed", +// ThreadRunStepCompleted = "thread.run.step.completed", +// ThreadRunCompleted = "thread.run.completed", + +// } +export async function* createRunStreaming( + context: Client, + threadId: string, + options: AgentsCreateRunParameters, +): AsyncIterable { + options.body.stream = true; + const result = await (context as ProjectsClient) + .path("/threads/{threadId}/runs", threadId) + .post(options) + .asBrowserStream(); + + if (!expectedStatuses.includes(result.status)) { + throw createRestError(result); + } + if (!result.body) { + throw new Error("No body in response"); + } + + let buffer = ""; + const decoder = new TextDecoder("utf-8"); + for await (const chunk of result.body) { + buffer += decoder.decode(chunk, { stream: true }); + if (buffer.includes("\n")) { + const lines = buffer.split("\n\n"); + for (let i = 0; i < lines.length - 1; i++) { + const streamData = parseLine(lines[i]); + if (streamData) { + yield streamData; + } + } + buffer = lines[lines.length - 1]; + } + } +} + +export async function* createThreadAndRunStreaming( + context: Client, + options: AgentsCreateThreadAndRunBodyParam, +): AsyncIterable { + options.body.stream = true; + const result = await (context as ProjectsClient) + .path("/threads/runs") + .post(options) + .asBrowserStream(); + + if (!expectedStatuses.includes(result.status)) { + throw createRestError(result); + } + if (!result.body) { + throw new Error("No body in response"); + } + + let buffer = ""; + const decoder = new TextDecoder("utf-8"); + for await (const chunk of result.body) { + buffer += decoder.decode(chunk, { stream: true }); + if (buffer.includes("\n")) { + const lines = buffer.split("\n\n"); + for (let i = 0; i < lines.length - 1; i++) { + const streamData = parseLine(lines[i]); + if (streamData) { + yield streamData; + } + } + buffer = lines[lines.length - 1]; + } + } +} + +function parseLine(line: string): AgentStreamEventMessage | undefined { + const streamData: AgentStreamEventMessage = { data: {}, eventType: "" }; + const trimmedLine = line.trim(); + + if (trimmedLine.length > 0) { + trimmedLine.split("\n").forEach((l) => { + const trimmedL = l.trim(); + const colIndex = trimmedL.indexOf(":"); + + if (colIndex !== -1) { + const fieldName = trimmedL.substring(0, colIndex).trim(); + const fieldValue = trimmedL.substring(colIndex + 1).trim(); + + switch (fieldName) { + case "data": + try { + streamData.data = JSON.parse(fieldValue); + } catch { + streamData.data = fieldValue; + } + break; + case "event": + if (fieldValue !== "done") { + streamData.eventType = fieldValue; + } + break; + } + } + }); + } + + return streamData.eventType ? streamData : undefined; +} diff --git a/sdk/ai/ai-projects/src/index.ts b/sdk/ai/ai-projects/src/index.ts index 3e12d597e814..9304b661725f 100644 --- a/sdk/ai/ai-projects/src/index.ts +++ b/sdk/ai/ai-projects/src/index.ts @@ -5,4 +5,6 @@ import { AIProjectsClient } from "./aiProjectsClient.js"; export {AgentsOperations } from "./agents/index.js"; +export * from "./agents/inputOutputs.js"; + export { AIProjectsClient }; diff --git a/sdk/ai/ai-projects/test/public/agents/streaming.spec.ts b/sdk/ai/ai-projects/test/public/agents/streaming.spec.ts new file mode 100644 index 000000000000..7b1e999e3bef --- /dev/null +++ b/sdk/ai/ai-projects/test/public/agents/streaming.spec.ts @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { Recorder, VitestTestContext } from "@azure-tools/test-recorder"; +import { AgentsOperations, AIProjectsClient } from "../../../src/index.js"; +import { createRecorder, createProjectsClient } from "../utils/createClient.js"; +import { assert, beforeEach, afterEach, it, describe } from "vitest"; + +describe("Agents - streaming", () => { + let recorder: Recorder; + let projectsClient: AIProjectsClient; + let agents: AgentsOperations; + + beforeEach(async function (context: VitestTestContext) { + recorder = await createRecorder(context); + projectsClient = createProjectsClient(recorder); + agents = projectsClient.agents; + }); + + afterEach(async function () { + await recorder.stop(); + }); + + it("should run streaming", async function () { + const agent = await agents.createAgent({ + model: "gpt-4-1106-preview", + name: "My Friendly Test Assistant", + instructions: "You are helpful agent", + }); + const thread = await agents.createThread(); + await agents.createMessage(thread.id, { role: "user", content: "Hello, tell me a joke" }); + const stream = agents.createRunStreaming(thread.id, { assistant_id: agent.id }); + let buffer = ""; + for await (const data of stream) { + buffer += data; + } + assert.isNotNull(buffer); + assert.isNotNull(stream); + }); + + // eslint-disable-next-line no-only-tests/no-only-tests + it("should create thread and run streaming", async function () { + const agent = await agents.createAgent({ + model: "gpt-4-1106-preview", + name: "My Friendly Test Assistant", + instructions: "You are helpful agent", + }); + const stream = agents.createThreadAndRunStreaming({ + assistant_id: agent.id, + thread: { messages: [{ role: "user", content: "Hello, tell me a joke" }] }, + }); + let buffer = ""; + for await (const data of stream) { + buffer += data; + } + assert.isNotNull(buffer); + assert.isNotNull(stream); + }); +}); From e562c7fa959454e34ace23479768a7d40b210efc Mon Sep 17 00:00:00 2001 From: Ganesh Bheemarasetty Date: Mon, 4 Nov 2024 15:08:53 -0800 Subject: [PATCH 2/4] remove sse dependency --- sdk/ai/ai-projects/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/ai/ai-projects/package.json b/sdk/ai/ai-projects/package.json index da361791a415..32904608f0c9 100644 --- a/sdk/ai/ai-projects/package.json +++ b/sdk/ai/ai-projects/package.json @@ -59,7 +59,6 @@ "@azure/core-auth": "^1.6.0", "@azure/core-rest-pipeline": "^1.5.0", "@azure/core-util": "^1.9.0", - "@azure/core-sse": "^2.1.3", "@azure/logger": "^1.0.0", "tslib": "^2.6.2", "@azure/core-paging": "^1.5.0" From a65c8a37886be114ed63f42deb50a873848b9197 Mon Sep 17 00:00:00 2001 From: Ganesh Bheemarasetty Date: Fri, 8 Nov 2024 08:36:40 -0800 Subject: [PATCH 3/4] Streaming implementation, tests and samples --- sdk/ai/ai-projects/package.json | 7 +- sdk/ai/ai-projects/review/ai-projects.api.md | 1669 ++++++++++++++++- .../samples-dev/agents/streaming.ts | 65 + sdk/ai/ai-projects/src/agents/index.ts | 390 ++-- sdk/ai/ai-projects/src/agents/inputOutputs.ts | 9 +- sdk/ai/ai-projects/src/agents/streaming.ts | 141 +- .../ai-projects/src/agents/streamingModels.ts | 411 ++++ sdk/ai/ai-projects/src/aiProjectsClient.ts | 6 +- sdk/ai/ai-projects/src/index.ts | 6 +- .../test/public/agents/streaming.spec.ts | 51 +- sdk/ai/ai-projects/tsconfig.json | 3 +- 11 files changed, 2392 insertions(+), 366 deletions(-) create mode 100644 sdk/ai/ai-projects/samples-dev/agents/streaming.ts create mode 100644 sdk/ai/ai-projects/src/agents/streamingModels.ts diff --git a/sdk/ai/ai-projects/package.json b/sdk/ai/ai-projects/package.json index 32904608f0c9..51a08a1516c4 100644 --- a/sdk/ai/ai-projects/package.json +++ b/sdk/ai/ai-projects/package.json @@ -59,9 +59,10 @@ "@azure/core-auth": "^1.6.0", "@azure/core-rest-pipeline": "^1.5.0", "@azure/core-util": "^1.9.0", - "@azure/logger": "^1.0.0", + "@azure/logger": "^1.1.4", "tslib": "^2.6.2", - "@azure/core-paging": "^1.5.0" + "@azure/core-paging": "^1.5.0", + "@azure/core-sse": "^2.1.3" }, "devDependencies": { "@azure/dev-tool": "^1.0.0", @@ -92,7 +93,7 @@ "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", "build:samples": "echo skipped", "check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.{ts,cts,mts}\" \"test/**/*.{ts,cts,mts}\" \"*.{js,cjs,mjs,json}\" ", - "execute:samples": "echo skipped", + "execute:samples": "dev-tool samples run samples-dev", "format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.{ts,cts,mts}\" \"test/**/*.{ts,cts,mts}\" \"*.{js,cjs,mjs,json}\" ", "integration-test": "npm run integration-test:node && npm run integration-test:browser", "integration-test:browser": "dev-tool run build-package && dev-tool run build-test && dev-tool run test:vitest --no-test-proxy --browser", diff --git a/sdk/ai/ai-projects/review/ai-projects.api.md b/sdk/ai/ai-projects/review/ai-projects.api.md index e61054fda43a..dfc4cfe8dc25 100644 --- a/sdk/ai/ai-projects/review/ai-projects.api.md +++ b/sdk/ai/ai-projects/review/ai-projects.api.md @@ -5,6 +5,7 @@ ```ts import { ClientOptions } from '@azure-rest/core-client'; +import { Paged } from '@azure/core-paging'; import { Pipeline } from '@azure/core-rest-pipeline'; import { RequestParameters } from '@azure-rest/core-client'; import { TokenCredential } from '@azure/core-auth'; @@ -26,39 +27,83 @@ export interface AgentOutput { model: string; name: string | null; object: "assistant"; - // Warning: (ae-forgotten-export) The symbol "AgentsApiResponseFormatOptionOutput" needs to be exported by the entry point index.d.ts response_format?: AgentsApiResponseFormatOptionOutput | null; temperature: number | null; - // Warning: (ae-forgotten-export) The symbol "ToolResourcesOutput" needs to be exported by the entry point index.d.ts tool_resources: ToolResourcesOutput | null; - // Warning: (ae-forgotten-export) The symbol "ToolDefinitionOutput" needs to be exported by the entry point index.d.ts tools: Array; top_p: number | null; } +// @public +export interface AgentsApiResponseFormat { + type?: ApiResponseFormat; +} + +// @public +export type AgentsApiResponseFormatMode = string; + +// @public +export type AgentsApiResponseFormatModeOutput = string; + +// @public +export type AgentsApiResponseFormatOption = string | AgentsApiResponseFormatMode | AgentsApiResponseFormat; + +// @public +export type AgentsApiResponseFormatOptionOutput = string | AgentsApiResponseFormatModeOutput | AgentsApiResponseFormatOutput; + +// @public +export interface AgentsApiResponseFormatOutput { + type?: ApiResponseFormatOutput; +} + +// @public +export type AgentsApiToolChoiceOption = string | AgentsApiToolChoiceOptionMode | AgentsNamedToolChoice; + +// @public +export type AgentsApiToolChoiceOptionMode = string; + +// @public +export type AgentsApiToolChoiceOptionModeOutput = string; + +// @public +export type AgentsApiToolChoiceOptionOutput = string | AgentsApiToolChoiceOptionModeOutput | AgentsNamedToolChoiceOutput; + +// @public +export interface AgentsNamedToolChoice { + function?: FunctionName; + type: AgentsNamedToolChoiceType; +} + +// @public +export interface AgentsNamedToolChoiceOutput { + function?: FunctionNameOutput; + type: AgentsNamedToolChoiceTypeOutput; +} + +// @public +export type AgentsNamedToolChoiceType = string; + +// @public +export type AgentsNamedToolChoiceTypeOutput = string; + // @public (undocumented) export interface AgentsOperations { // Warning: (ae-forgotten-export) The symbol "CancelRunParameters" needs to be exported by the entry point index.d.ts cancelRun: (threadId: string, runId: string, options?: CancelRunParameters) => Promise; createAgent: (options: CreateAgentOptions) => Promise; - // Warning: (ae-forgotten-export) The symbol "ThreadMessageOptions" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "ThreadMessageOutput" needs to be exported by the entry point index.d.ts + createAgentAlternative: (model: string, options?: Omit) => Promise; createMessage: (threadId: string, options: ThreadMessageOptions) => Promise; // Warning: (ae-forgotten-export) The symbol "CreateRunParameters" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "ThreadRunOutput" needs to be exported by the entry point index.d.ts createRun: (threadId: string, options: CreateRunParameters) => Promise; - createRunStreaming: (threadId: string, options: CreateRunOptions) => AsyncIterable; - // Warning: (ae-forgotten-export) The symbol "AgentThreadCreationOptions" needs to be exported by the entry point index.d.ts + createRunStreaming: (threadId: string, assistantId: string, options?: Omit, requestParams?: RequestParameters) => AsyncIterable; createThread: (options?: AgentThreadCreationOptions) => Promise; // Warning: (ae-forgotten-export) The symbol "CreateThreadAndRunParameters" needs to be exported by the entry point index.d.ts createThreadAndRun: (options: CreateThreadAndRunParameters) => Promise; - createThreadAndRunStreaming: (options: CreateAndRunThreadOptions) => AsyncIterable; + createThreadAndRunStreaming: (assistantId: string, options?: Omit, requestParams?: RequestParameters) => AsyncIterable; deleteAgent: (assistantId: string) => Promise; // Warning: (ae-forgotten-export) The symbol "DeleteFileParameters" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "FileDeletionStatusOutput" needs to be exported by the entry point index.d.ts deleteFile: (fileId: string, options?: DeleteFileParameters) => Promise; // Warning: (ae-forgotten-export) The symbol "DeleteThreadParameters" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "ThreadDeletionStatusOutput" needs to be exported by the entry point index.d.ts deleteThread: (threadId: string, options?: DeleteThreadParameters) => Promise; getAgent: (assistantId: string) => Promise; // Warning: (ae-forgotten-export) The symbol "GetFileParameters" needs to be exported by the entry point index.d.ts @@ -70,15 +115,12 @@ export interface AgentsOperations { // Warning: (ae-forgotten-export) The symbol "GetThreadParameters" needs to be exported by the entry point index.d.ts getThread: (threadId: string, options?: GetThreadParameters) => Promise; // Warning: (ae-forgotten-export) The symbol "ListAgentsQueryParamProperties" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "OpenAIPageableListOfAgentOutput" needs to be exported by the entry point index.d.ts listAgents: (options?: ListAgentsQueryParamProperties) => Promise; // Warning: (ae-forgotten-export) The symbol "ListFilesParameters" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "FileListResponseOutput" needs to be exported by the entry point index.d.ts listFiles: (options?: ListFilesParameters) => Promise; // Warning: (ae-forgotten-export) The symbol "ListMessagesParameters" needs to be exported by the entry point index.d.ts listMessages: (threadId: string, options?: ListMessagesParameters) => Promise; // Warning: (ae-forgotten-export) The symbol "ListRunsParameters" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "OpenAIPageableListOfThreadRunOutput" needs to be exported by the entry point index.d.ts listRuns: (threadId: string, options?: ListRunsParameters) => Promise; // Warning: (ae-forgotten-export) The symbol "SubmitToolOutputsToRunParameters" needs to be exported by the entry point index.d.ts submitToolOutputsToRun: (threadId: string, runId: string, options: SubmitToolOutputsToRunParameters) => Promise; @@ -90,16 +132,25 @@ export interface AgentsOperations { // Warning: (ae-forgotten-export) The symbol "UpdateThreadParameters" needs to be exported by the entry point index.d.ts updateThread: (threadId: string, options: UpdateThreadParameters) => Promise; // Warning: (ae-forgotten-export) The symbol "UploadFileParameters" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "OpenAIFileOutput" needs to be exported by the entry point index.d.ts uploadFile: (options: UploadFileParameters) => Promise; } // @public (undocumented) export interface AgentStreamEventMessage { // (undocumented) - data: any; + data: AgentThreadOutput | ThreadRunOutput | RunStepOutput | ThreadMessageOutput | MessageDeltaChunk | RunStepDeltaChunk | string; // (undocumented) - eventType: string; + event: AgentStreamEventType | string; +} + +// @public (undocumented) +export type AgentStreamEventType = ThreadStreamEvent | RunStreamEvent | RunStepStreamEvent | MessageStreamEvent | ErrorEvent | DoneEvent; + +// @public +export interface AgentThreadCreationOptions { + messages?: Array; + metadata?: Record | null; + tool_resources?: ToolResources | null; } // @public @@ -113,14 +164,106 @@ export interface AgentThreadOutput { // @public (undocumented) export class AIProjectsClient { - // Warning: (ae-forgotten-export) The symbol "AIProjectsClientOptions" needs to be exported by the entry point index.d.ts constructor(endpointParam: string, subscriptionId: string, resourceGroupName: string, projectName: string, credential: TokenCredential, options?: AIProjectsClientOptions); readonly agents: AgentsOperations; - // Warning: (ae-forgotten-export) The symbol "CreateProjectsClient" needs to be exported by the entry point index.d.ts - static fromConnectionString(connectionString: string, credential: TokenCredential, options?: CreateProjectsClient): AIProjectsClient; + static fromConnectionString(connectionString: string, credential: TokenCredential, options?: AIProjectsClientOptions): AIProjectsClient; readonly pipeline: Pipeline; } +// @public (undocumented) +export interface AIProjectsClientOptions extends ProjectsClientOptions { +} + +// @public +export type ApiResponseFormat = string; + +// @public +export type ApiResponseFormatOutput = string; + +// @public +export interface AppInsightsPropertiesOutput { + ConnectionString: string; +} + +// @public +export interface ApplicationInsightsConfiguration extends InputDataParent { + connectionString?: string; + query: string; + resourceId: string; + serviceName: string; +} + +// @public +export interface ApplicationInsightsConfigurationOutput extends InputDataOutputParent { + connectionString?: string; + query: string; + resourceId: string; + serviceName: string; + // (undocumented) + readonly type: "app_insights"; +} + +// @public +export type AuthenticationTypeOutput = "ApiKey" | "AAD" | "SAS"; + +// @public +export interface AzureAISearchResource { + indexes?: Array; +} + +// @public +export interface AzureAISearchResourceOutput { + indexes?: Array; +} + +// @public +export interface AzureAISearchToolDefinition extends ToolDefinitionParent { + type: "azure_ai_search"; +} + +// @public +export interface AzureAISearchToolDefinitionOutput extends ToolDefinitionOutputParent { + type: "azure_ai_search"; +} + +// @public +export interface BingGroundingToolDefinition extends ToolDefinitionParent { + bing_grounding: ToolConnectionList; + type: "bing_grounding"; +} + +// @public +export interface BingGroundingToolDefinitionOutput extends ToolDefinitionOutputParent { + bing_grounding: ToolConnectionListOutput; + type: "bing_grounding"; +} + +// @public +export interface CodeInterpreterToolDefinition extends ToolDefinitionParent { + type: "code_interpreter"; +} + +// @public +export interface CodeInterpreterToolDefinitionOutput extends ToolDefinitionOutputParent { + type: "code_interpreter"; +} + +// @public +export interface CodeInterpreterToolResource { + file_ids?: string[]; +} + +// @public +export interface CodeInterpreterToolResourceOutput { + file_ids?: string[]; +} + +// @public +export type ConnectionType = "AzureOpenAI" | "Serverless" | "AzureBlob" | "AIServices" | "CognitiveSearch"; + +// @public +export type ConnectionTypeOutput = "AzureOpenAI" | "Serverless" | "AzureBlob" | "AIServices" | "CognitiveSearch"; + // @public export interface CreateAgentOptions { description?: string | null; @@ -128,12 +271,9 @@ export interface CreateAgentOptions { metadata?: Record | null; model: string; name?: string | null; - // Warning: (ae-forgotten-export) The symbol "AgentsApiResponseFormatOption" needs to be exported by the entry point index.d.ts response_format?: AgentsApiResponseFormatOption | null; temperature?: number | null; - // Warning: (ae-forgotten-export) The symbol "ToolResources" needs to be exported by the entry point index.d.ts tool_resources?: ToolResources | null; - // Warning: (ae-forgotten-export) The symbol "ToolDefinition" needs to be exported by the entry point index.d.ts tools?: Array; top_p?: number | null; } @@ -150,20 +290,16 @@ export interface CreateAndRunThreadOptions { stream?: boolean; temperature?: number | null; thread?: AgentThreadCreationOptions; - // Warning: (ae-forgotten-export) The symbol "AgentsApiToolChoiceOption" needs to be exported by the entry point index.d.ts tool_choice?: AgentsApiToolChoiceOption | null; - // Warning: (ae-forgotten-export) The symbol "UpdateToolResourcesOptions" needs to be exported by the entry point index.d.ts tool_resources?: UpdateToolResourcesOptions | null; tools?: Array | null; top_p?: number | null; - // Warning: (ae-forgotten-export) The symbol "TruncationObject" needs to be exported by the entry point index.d.ts truncation_strategy?: TruncationObject | null; } // @public export interface CreateRunOptions { additional_instructions?: string | null; - // Warning: (ae-forgotten-export) The symbol "ThreadMessage" needs to be exported by the entry point index.d.ts additional_messages?: Array | null; assistant_id: string; instructions?: string | null; @@ -181,17 +317,1474 @@ export interface CreateRunOptions { } // @public -export interface UpdateAgentOptions { - description?: string | null; - instructions?: string | null; - metadata?: Record | null; - model?: string; - name?: string | null; - response_format?: AgentsApiResponseFormatOption | null; - temperature?: number | null; - tool_resources?: ToolResources; - tools?: Array; - top_p?: number | null; +export interface CredentialsApiKeyAuthOutput { + key: string; +} + +// @public +export interface CredentialsSASAuthOutput { + SAS: string; +} + +// @public +export interface CronTrigger extends TriggerParent { + expression: string; +} + +// @public +export interface CronTriggerOutput extends TriggerOutputParent { + expression: string; + // (undocumented) + readonly type: "Cron"; +} + +// @public +export interface Dataset extends InputDataParent { + id: string; +} + +// @public +export interface DatasetOutput extends InputDataOutputParent { + id: string; + // (undocumented) + readonly type: "dataset"; +} + +// @public +export enum DoneEvent { + Done = "done" +} + +// @public +export enum ErrorEvent { + Error = "error" +} + +// @public +export interface Evaluation { + data: InputData; + description?: string; + displayName?: string; + evaluators: Record; + properties?: Record; + tags?: Record; +} + +// @public +export interface EvaluationOutput { + data: InputDataOutput; + description?: string; + displayName?: string; + evaluators: Record; + readonly id: string; + properties?: Record; + readonly status?: string; + readonly systemData?: SystemDataOutput; + tags?: Record; +} + +// @public +export interface EvaluationSchedule { + data: ApplicationInsightsConfiguration; + description?: string; + evaluators: Record; + properties?: Record; + tags?: Record; + trigger: Trigger; +} + +// @public +export interface EvaluationScheduleOutput { + data: ApplicationInsightsConfigurationOutput; + description?: string; + evaluators: Record; + readonly name: string; + properties?: Record; + readonly provisioningStatus?: string; + readonly systemData?: SystemDataOutput; + tags?: Record; + trigger: TriggerOutput; +} + +// @public +export interface EvaluatorConfiguration { + dataMapping?: Record; + id: string; + initParams?: Record; +} + +// @public +export interface EvaluatorConfigurationOutput { + dataMapping?: Record; + id: string; + initParams?: Record; +} + +// @public +export interface FileDeletionStatusOutput { + deleted: boolean; + id: string; + object: "file"; +} + +// @public +export interface FileListResponseOutput { + data: Array; + object: "list"; +} + +// @public +export type FilePurpose = string; + +// @public +export type FilePurposeOutput = string; + +// @public +export interface FileSearchToolDefinition extends ToolDefinitionParent { + file_search?: FileSearchToolDefinitionDetails; + type: "file_search"; +} + +// @public +export interface FileSearchToolDefinitionDetails { + max_num_results?: number; +} + +// @public +export interface FileSearchToolDefinitionDetailsOutput { + max_num_results?: number; +} + +// @public +export interface FileSearchToolDefinitionOutput extends ToolDefinitionOutputParent { + file_search?: FileSearchToolDefinitionDetailsOutput; + type: "file_search"; +} + +// @public +export interface FileSearchToolResource { + vector_store_ids?: string[]; +} + +// @public +export interface FileSearchToolResourceOutput { + vector_store_ids?: string[]; +} + +// @public +export type FileStateOutput = string; + +// @public +export type Frequency = string; + +// @public +export type FrequencyOutput = string; + +// @public +export interface FunctionDefinition { + description?: string; + name: string; + parameters: unknown; +} + +// @public +export interface FunctionDefinitionOutput { + description?: string; + name: string; + parameters: any; +} + +// @public +export interface FunctionName { + name: string; +} + +// @public +export interface FunctionNameOutput { + name: string; +} + +// @public +export interface FunctionToolDefinition extends ToolDefinitionParent { + function: FunctionDefinition; + type: "function"; +} + +// @public +export interface FunctionToolDefinitionOutput extends ToolDefinitionOutputParent { + function: FunctionDefinitionOutput; + type: "function"; +} + +// @public +export interface GetAppInsightsResponseOutput { + id: string; + name: string; + properties: AppInsightsPropertiesOutput; +} + +// @public +export interface GetConnectionResponseOutput { + id: string; + name: string; + properties: InternalConnectionPropertiesOutput; +} + +// @public +export interface GetWorkspaceResponseOutput { + id: string; + name: string; + properties: WorkspacePropertiesOutput; +} + +// @public +export type IncompleteRunDetailsOutput = string; + +// @public +export interface IndexResource { + index_connection_id: string; + index_name: string; +} + +// @public +export interface IndexResourceOutput { + index_connection_id: string; + index_name: string; +} + +// @public +export type InputData = InputDataParent | ApplicationInsightsConfiguration | Dataset; + +// @public +export type InputDataOutput = InputDataOutputParent | ApplicationInsightsConfigurationOutput | DatasetOutput; + +// @public +export interface InputDataOutputParent { + // (undocumented) + type: string; +} + +// @public +export interface InputDataParent { + // (undocumented) + type: string; +} + +// @public +export interface InternalConnectionPropertiesAADAuthOutput extends InternalConnectionPropertiesOutputParent { + authType: "AAD"; + category: ConnectionTypeOutput; + target: string; +} + +// @public +export interface InternalConnectionPropertiesApiKeyAuthOutput extends InternalConnectionPropertiesOutputParent { + authType: "ApiKey"; + category: ConnectionTypeOutput; + credentials: CredentialsApiKeyAuthOutput; + target: string; +} + +// @public +export type InternalConnectionPropertiesOutput = InternalConnectionPropertiesOutputParent | InternalConnectionPropertiesApiKeyAuthOutput | InternalConnectionPropertiesAADAuthOutput | InternalConnectionPropertiesSASAuthOutput; + +// @public +export interface InternalConnectionPropertiesOutputParent { + // (undocumented) + authType: AuthenticationTypeOutput; +} + +// @public +export interface InternalConnectionPropertiesSASAuthOutput extends InternalConnectionPropertiesOutputParent { + authType: "SAS"; + category: ConnectionTypeOutput; + credentials: CredentialsSASAuthOutput; + target: string; +} + +// @public +export interface ListConnectionsResponseOutput { + value: Array; +} + +// @public +export type ListSortOrder = string; + +// @public +export interface MessageAttachment { + file_id: string; + tools: MessageAttachmentToolDefinition[]; +} + +// @public +export interface MessageAttachmentOutput { + file_id: string; + tools: MessageAttachmentToolDefinitionOutput[]; +} + +// @public +export type MessageAttachmentToolDefinition = CodeInterpreterToolDefinition | FileSearchToolDefinition; + +// @public +export type MessageAttachmentToolDefinitionOutput = CodeInterpreterToolDefinitionOutput | FileSearchToolDefinitionOutput; + +// @public +export type MessageContent = MessageContentParent | MessageTextContent | MessageImageFileContent; + +// @public +export type MessageContentOutput = MessageContentOutputParent | MessageTextContentOutput | MessageImageFileContentOutput; + +// @public +export interface MessageContentOutputParent { + // (undocumented) + type: string; +} + +// @public +export interface MessageContentParent { + // (undocumented) + type: string; +} + +// @public +export interface MessageDelta { + content: MessageDeltaContent[]; + role: MessageRole; +} + +// @public +export interface MessageDeltaChunk { + delta: MessageDelta; + id: string; + object: "thread.message.delta"; +} + +// @public +export interface MessageDeltaContent { + index: number; + type: string; +} + +// @public +export interface MessageDeltaImageFileContent extends MessageDeltaContent { + imageFile?: MessageDeltaImageFileContentObject; + type: "image_file"; +} + +// @public +export interface MessageDeltaImageFileContentObject { + fileId?: string; +} + +// @public +export interface MessageDeltaTextAnnotation { + index: number; + type: string; +} + +// @public +export interface MessageDeltaTextContent extends MessageDeltaContent { + text?: MessageDeltaTextContentObject; + type: "text"; +} + +// @public +export interface MessageDeltaTextContentObject { + annotations?: MessageDeltaTextAnnotation[]; + value?: string; +} + +// @public +export interface MessageDeltaTextFileCitationAnnotation extends MessageDeltaTextAnnotation { + endIndex?: number; + fileCitation?: MessageDeltaTextFileCitationAnnotationObject; + startIndex?: number; + text?: string; + type: "file_citation"; +} + +// @public +export interface MessageDeltaTextFileCitationAnnotationObject { + fileId?: string; + quote?: string; +} + +// @public +export interface MessageDeltaTextFilePathAnnotation extends MessageDeltaTextAnnotation { + endIndex?: number; + filePath?: MessageDeltaTextFilePathAnnotationObject; + startIndex?: number; + text?: string; + type: "file_path"; +} + +// @public +export interface MessageDeltaTextFilePathAnnotationObject { + fileId?: string; +} + +// @public +export interface MessageDeltaTextUrlCitationDetails { + title?: string; + url?: string; +} + +// @public +export interface MessageImageFileContent extends MessageContentParent { + image_file: MessageImageFileDetails; + type: "image_file"; +} + +// @public +export interface MessageImageFileContentOutput extends MessageContentOutputParent { + image_file: MessageImageFileDetailsOutput; + type: "image_file"; +} + +// @public +export interface MessageImageFileDetails { + file_id: string; +} + +// @public +export interface MessageImageFileDetailsOutput { + file_id: string; +} + +// @public +export interface MessageIncompleteDetails { + reason: MessageIncompleteDetailsReason; +} + +// @public +export interface MessageIncompleteDetailsOutput { + reason: MessageIncompleteDetailsReasonOutput; +} + +// @public +export type MessageIncompleteDetailsReason = string; + +// @public +export type MessageIncompleteDetailsReasonOutput = string; + +// @public +export type MessageRole = string; + +// @public +export type MessageRoleOutput = string; + +// @public +export type MessageStatus = string; + +// @public +export type MessageStatusOutput = string; + +// @public +export enum MessageStreamEvent { + ThreadMessageCompleted = "thread.message.completed", + ThreadMessageCreated = "thread.message.created", + ThreadMessageDelta = "thread.message.delta", + ThreadMessageIncomplete = "thread.message.incomplete", + ThreadMessageInProgress = "thread.message.in_progress" +} + +// @public +export type MessageTextAnnotation = MessageTextAnnotationParent | MessageTextFileCitationAnnotation | MessageTextFilePathAnnotation; + +// @public +export type MessageTextAnnotationOutput = MessageTextAnnotationOutputParent | MessageTextFileCitationAnnotationOutput | MessageTextFilePathAnnotationOutput; + +// @public +export interface MessageTextAnnotationOutputParent { + text: string; + // (undocumented) + type: string; +} + +// @public +export interface MessageTextAnnotationParent { + text: string; + // (undocumented) + type: string; +} + +// @public +export interface MessageTextContent extends MessageContentParent { + text: MessageTextDetails; + type: "text"; +} + +// @public +export interface MessageTextContentOutput extends MessageContentOutputParent { + text: MessageTextDetailsOutput; + type: "text"; +} + +// @public +export interface MessageTextDetails { + annotations: Array; + value: string; +} + +// @public +export interface MessageTextDetailsOutput { + annotations: Array; + value: string; +} + +// @public +export interface MessageTextFileCitationAnnotation extends MessageTextAnnotationParent { + end_index?: number; + file_citation: MessageTextFileCitationDetails; + start_index?: number; + type: "file_citation"; +} + +// @public +export interface MessageTextFileCitationAnnotationOutput extends MessageTextAnnotationOutputParent { + end_index?: number; + file_citation: MessageTextFileCitationDetailsOutput; + start_index?: number; + type: "file_citation"; +} + +// @public +export interface MessageTextFileCitationDetails { + file_id: string; + quote: string; +} + +// @public +export interface MessageTextFileCitationDetailsOutput { + file_id: string; + quote: string; +} + +// @public +export interface MessageTextFilePathAnnotation extends MessageTextAnnotationParent { + end_index?: number; + file_path: MessageTextFilePathDetails; + start_index?: number; + type: "file_path"; +} + +// @public +export interface MessageTextFilePathAnnotationOutput extends MessageTextAnnotationOutputParent { + end_index?: number; + file_path: MessageTextFilePathDetailsOutput; + start_index?: number; + type: "file_path"; +} + +// @public +export interface MessageTextFilePathDetails { + file_id: string; +} + +// @public +export interface MessageTextFilePathDetailsOutput { + file_id: string; +} + +// @public +export interface MicrosoftFabricToolDefinition extends ToolDefinitionParent { + microsoft_fabric: ToolConnectionList; + type: "microsoft_fabric"; +} + +// @public +export interface MicrosoftFabricToolDefinitionOutput extends ToolDefinitionOutputParent { + microsoft_fabric: ToolConnectionListOutput; + type: "microsoft_fabric"; +} + +// @public +export interface OpenAIFileOutput { + bytes: number; + created_at: number; + filename: string; + id: string; + object: "file"; + purpose: FilePurposeOutput; + status?: FileStateOutput; + status_details?: string; +} + +// @public +export interface OpenAIPageableListOfAgentOutput { + data: Array; + first_id: string; + has_more: boolean; + last_id: string; + object: "list"; +} + +// @public +export interface OpenAIPageableListOfRunStepOutput { + data: Array; + first_id: string; + has_more: boolean; + last_id: string; + object: "list"; +} + +// @public +export interface OpenAIPageableListOfThreadMessageOutput { + data: Array; + first_id: string; + has_more: boolean; + last_id: string; + object: "list"; +} + +// @public +export interface OpenAIPageableListOfThreadRunOutput { + data: Array; + first_id: string; + has_more: boolean; + last_id: string; + object: "list"; +} + +// @public +export interface OpenAIPageableListOfVectorStoreFileOutput { + data: Array; + first_id: string; + has_more: boolean; + last_id: string; + object: "list"; +} + +// @public +export interface OpenAIPageableListOfVectorStoreOutput { + data: Array; + first_id: string; + has_more: boolean; + last_id: string; + object: "list"; +} + +// @public +export type PagedEvaluationOutput = Paged; + +// @public +export type PagedEvaluationScheduleOutput = Paged; + +// @public +export interface ProjectsClientOptions extends ClientOptions { + apiVersion?: string; +} + +// @public +export interface RecurrenceSchedule { + hours: number[]; + minutes: number[]; + monthDays?: number[]; + weekDays?: WeekDays[]; +} + +// @public +export interface RecurrenceScheduleOutput { + hours: number[]; + minutes: number[]; + monthDays?: number[]; + weekDays?: WeekDaysOutput[]; +} + +// @public +export interface RecurrenceTrigger extends TriggerParent { + frequency: Frequency; + interval: number; + schedule?: RecurrenceSchedule; +} + +// @public +export interface RecurrenceTriggerOutput extends TriggerOutputParent { + frequency: FrequencyOutput; + interval: number; + schedule?: RecurrenceScheduleOutput; + // (undocumented) + readonly type: "Recurrence"; +} + +// @public +export type RequiredActionOutput = RequiredActionOutputParent | SubmitToolOutputsActionOutput; + +// @public +export interface RequiredActionOutputParent { + // (undocumented) + type: string; +} + +// @public +export interface RequiredFunctionToolCallDetailsOutput { + arguments: string; + name: string; +} + +// @public +export interface RequiredFunctionToolCallOutput extends RequiredToolCallOutputParent { + function: RequiredFunctionToolCallDetailsOutput; + type: "function"; +} + +// @public +export type RequiredToolCallOutput = RequiredToolCallOutputParent | RequiredFunctionToolCallOutput; + +// @public +export interface RequiredToolCallOutputParent { + id: string; + // (undocumented) + type: string; +} + +// @public +export interface RunCompletionUsageOutput { + completion_tokens: number; + prompt_tokens: number; + total_tokens: number; +} + +// @public +export interface RunErrorOutput { + code: string; + message: string; +} + +// @public +export type RunStatusOutput = string; + +// @public +export interface RunStepAzureAISearchToolCallOutput extends RunStepToolCallOutputParent { + azure_ai_search: Record; + type: "azure_ai_search"; +} + +// @public +export interface RunStepBingGroundingToolCallOutput extends RunStepToolCallOutputParent { + bing_grounding: Record; + type: "bing_grounding"; +} + +// @public +export interface RunStepCodeInterpreterImageOutputOutput extends RunStepCodeInterpreterToolCallOutputOutputParent { + image: RunStepCodeInterpreterImageReferenceOutput; + type: "image"; +} + +// @public +export interface RunStepCodeInterpreterImageReferenceOutput { + file_id: string; +} + +// @public +export interface RunStepCodeInterpreterLogOutputOutput extends RunStepCodeInterpreterToolCallOutputOutputParent { + logs: string; + type: "logs"; +} + +// @public +export interface RunStepCodeInterpreterToolCallDetailsOutput { + input: string; + outputs: Array; +} + +// @public +export interface RunStepCodeInterpreterToolCallOutput extends RunStepToolCallOutputParent { + code_interpreter: RunStepCodeInterpreterToolCallDetailsOutput; + type: "code_interpreter"; +} + +// @public +export type RunStepCodeInterpreterToolCallOutputOutput = RunStepCodeInterpreterToolCallOutputOutputParent | RunStepCodeInterpreterLogOutputOutput | RunStepCodeInterpreterImageOutputOutput; + +// @public +export interface RunStepCodeInterpreterToolCallOutputOutputParent { + // (undocumented) + type: string; +} + +// @public +export interface RunStepCompletionUsageOutput { + completion_tokens: number; + prompt_tokens: number; + total_tokens: number; +} + +// @public +export interface RunStepDelta { + stepDetails?: RunStepDeltaDetail; +} + +// @public +export interface RunStepDeltaChunk { + delta: RunStepDelta; + id: string; + object: "thread.run.step.delta"; +} + +// @public +export interface RunStepDeltaCodeInterpreterDetailItemObject { + input?: string; + outputs?: RunStepDeltaCodeInterpreterOutput[]; +} + +// @public +export interface RunStepDeltaCodeInterpreterImageOutput extends RunStepDeltaCodeInterpreterOutput { + image?: RunStepDeltaCodeInterpreterImageOutputObject; + type: "image"; +} + +// @public +export interface RunStepDeltaCodeInterpreterImageOutputObject { + fileId?: string; +} + +// @public +export interface RunStepDeltaCodeInterpreterLogOutput extends RunStepDeltaCodeInterpreterOutput { + logs?: string; + type: "logs"; +} + +// @public +export interface RunStepDeltaCodeInterpreterOutput { + index: number; + type: string; +} + +// @public +export interface RunStepDeltaCodeInterpreterToolCall extends RunStepDeltaToolCall { + codeInterpreter?: RunStepDeltaCodeInterpreterDetailItemObject; + type: "code_interpreter"; +} + +// @public +export interface RunStepDeltaDetail { + type: string; +} + +// @public +export interface RunStepDeltaFileSearchToolCall extends RunStepDeltaToolCall { + fileSearch?: Array; + type: "file_search"; +} + +// @public +export interface RunStepDeltaFunction { + arguments?: string; + name?: string; + output?: string | null; +} + +// @public +export interface RunStepDeltaFunctionToolCall extends RunStepDeltaToolCall { + function?: RunStepDeltaFunction; + type: "function"; +} + +// @public +export interface RunStepDeltaMessageCreation extends RunStepDeltaDetail { + messageCreation?: RunStepDeltaMessageCreationObject; + type: "message_creation"; +} + +// @public +export interface RunStepDeltaMessageCreationObject { + messageId?: string; +} + +// @public +export interface RunStepDeltaToolCall { + id: string; + index: number; + type: string; +} + +// @public +export interface RunStepDeltaToolCallObject extends RunStepDeltaDetail { + toolCalls?: RunStepDeltaToolCall[]; + type: "tool_calls"; +} + +// @public +export type RunStepDetailsOutput = RunStepDetailsOutputParent | RunStepMessageCreationDetailsOutput | RunStepToolCallDetailsOutput; + +// @public +export interface RunStepDetailsOutputParent { + // (undocumented) + type: RunStepTypeOutput; +} + +// @public +export type RunStepErrorCodeOutput = string; + +// @public +export interface RunStepErrorOutput { + code: RunStepErrorCodeOutput; + message: string; +} + +// @public +export interface RunStepFileSearchToolCallOutput extends RunStepToolCallOutputParent { + file_search: Record; + type: "file_search"; +} + +// @public +export interface RunStepFunctionToolCallDetailsOutput { + arguments: string; + name: string; + output: string | null; +} + +// @public +export interface RunStepFunctionToolCallOutput extends RunStepToolCallOutputParent { + function: RunStepFunctionToolCallDetailsOutput; + type: "function"; +} + +// @public +export interface RunStepMessageCreationDetailsOutput extends RunStepDetailsOutputParent { + message_creation: RunStepMessageCreationReferenceOutput; + type: "message_creation"; +} + +// @public +export interface RunStepMessageCreationReferenceOutput { + message_id: string; +} + +// @public +export interface RunStepMicrosoftFabricToolCallOutput extends RunStepToolCallOutputParent { + microsoft_fabric: Record; + type: "microsoft_fabric"; +} + +// @public +export interface RunStepOutput { + assistant_id: string; + cancelled_at: number | null; + completed_at: number | null; + created_at: number; + expired_at: number | null; + failed_at: number | null; + id: string; + last_error: RunStepErrorOutput | null; + metadata: Record | null; + object: "thread.run.step"; + run_id: string; + status: RunStepStatusOutput; + step_details: RunStepDetailsOutput; + thread_id: string; + type: RunStepTypeOutput; + usage?: RunStepCompletionUsageOutput | null; +} + +// @public +export interface RunStepSharepointToolCallOutput extends RunStepToolCallOutputParent { + sharepoint_grounding: Record; + type: "sharepoint_grounding"; +} + +// @public +export type RunStepStatusOutput = string; + +// @public +export enum RunStepStreamEvent { + ThreadRunStepCancelled = "thread.run.step.cancelled", + ThreadRunStepCompleted = "thread.run.step.completed", + ThreadRunStepCreated = "thread.run.step.created", + ThreadRunStepDelta = "thread.run.step.delta", + ThreadRunStepExpired = "thread.run.step.expired", + ThreadRunStepFailed = "thread.run.step.failed", + ThreadRunStepInProgress = "thread.run.step.in_progress" +} + +// @public +export interface RunStepToolCallDetailsOutput extends RunStepDetailsOutputParent { + tool_calls: Array; + type: "tool_calls"; +} + +// @public +export type RunStepToolCallOutput = RunStepToolCallOutputParent | RunStepCodeInterpreterToolCallOutput | RunStepFileSearchToolCallOutput | RunStepBingGroundingToolCallOutput | RunStepAzureAISearchToolCallOutput | RunStepSharepointToolCallOutput | RunStepMicrosoftFabricToolCallOutput | RunStepFunctionToolCallOutput; + +// @public +export interface RunStepToolCallOutputParent { + id: string; + // (undocumented) + type: string; +} + +// @public +export type RunStepTypeOutput = string; + +// @public +export enum RunStreamEvent { + ThreadRunCancelled = "thread.run.cancelled", + ThreadRunCancelling = "thread.run.cancelling", + ThreadRunCompleted = "thread.run.completed", + ThreadRunCreated = "thread.run.created", + ThreadRunExpired = "thread.run.expired", + ThreadRunFailed = "thread.run.failed", + ThreadRunInProgress = "thread.run.in_progress", + ThreadRunQueued = "thread.run.queued", + ThreadRunRequiresAction = "thread.run.requires_action" +} + +// @public +export interface SharepointToolDefinition extends ToolDefinitionParent { + sharepoint_grounding: ToolConnectionList; + type: "sharepoint_grounding"; +} + +// @public +export interface SharepointToolDefinitionOutput extends ToolDefinitionOutputParent { + sharepoint_grounding: ToolConnectionListOutput; + type: "sharepoint_grounding"; +} + +// @public +export interface SubmitToolOutputsActionOutput extends RequiredActionOutputParent { + submit_tool_outputs: SubmitToolOutputsDetailsOutput; + type: "submit_tool_outputs"; +} + +// @public +export interface SubmitToolOutputsDetailsOutput { + tool_calls: Array; +} + +// @public +export interface SystemData { +} + +// @public +export interface SystemDataOutput { + readonly createdAt?: string; + readonly createdBy?: string; + readonly createdByType?: string; + readonly lastModifiedAt?: string; +} + +// @public +export interface ThreadDeletionStatusOutput { + deleted: boolean; + id: string; + object: "thread.deleted"; +} + +// @public +export interface ThreadMessage { + assistant_id: string | null; + attachments: Array | null; + completed_at: number | null; + content: Array; + created_at: number; + id: string; + incomplete_at: number | null; + incomplete_details: MessageIncompleteDetails | null; + metadata: Record | null; + object: "thread.message"; + role: MessageRole; + run_id: string | null; + status: MessageStatus; + thread_id: string; +} + +// @public +export interface ThreadMessageOptions { + attachments?: Array | null; + content: string; + metadata?: Record | null; + role: MessageRole; +} + +// @public +export interface ThreadMessageOutput { + assistant_id: string | null; + attachments: Array | null; + completed_at: number | null; + content: Array; + created_at: number; + id: string; + incomplete_at: number | null; + incomplete_details: MessageIncompleteDetailsOutput | null; + metadata: Record | null; + object: "thread.message"; + role: MessageRoleOutput; + run_id: string | null; + status: MessageStatusOutput; + thread_id: string; +} + +// @public +export interface ThreadRunOutput { + assistant_id: string; + cancelled_at: number | null; + completed_at: number | null; + created_at: number; + expires_at: number | null; + failed_at: number | null; + id: string; + incomplete_details: IncompleteRunDetailsOutput | null; + instructions: string; + last_error: RunErrorOutput | null; + max_completion_tokens: number | null; + max_prompt_tokens: number | null; + metadata: Record | null; + model: string; + object: "thread.run"; + parallelToolCalls?: boolean; + required_action?: RequiredActionOutput | null; + response_format: AgentsApiResponseFormatOptionOutput | null; + started_at: number | null; + status: RunStatusOutput; + temperature?: number | null; + thread_id: string; + tool_choice: AgentsApiToolChoiceOptionOutput | null; + tool_resources?: UpdateToolResourcesOptionsOutput | null; + tools: Array; + top_p?: number | null; + truncation_strategy: TruncationObjectOutput | null; + usage: RunCompletionUsageOutput | null; +} + +// @public +export enum ThreadStreamEvent { + ThreadCreated = "thread.created" +} + +// @public +export interface ToolConnection { + connection_id: string; +} + +// @public +export interface ToolConnectionList { + connections?: Array; +} + +// @public +export interface ToolConnectionListOutput { + connections?: Array; +} + +// @public +export interface ToolConnectionOutput { + connection_id: string; +} + +// @public +export type ToolDefinition = ToolDefinitionParent | CodeInterpreterToolDefinition | FileSearchToolDefinition | FunctionToolDefinition | BingGroundingToolDefinition | MicrosoftFabricToolDefinition | SharepointToolDefinition | AzureAISearchToolDefinition; + +// @public +export type ToolDefinitionOutput = ToolDefinitionOutputParent | CodeInterpreterToolDefinitionOutput | FileSearchToolDefinitionOutput | FunctionToolDefinitionOutput | BingGroundingToolDefinitionOutput | MicrosoftFabricToolDefinitionOutput | SharepointToolDefinitionOutput | AzureAISearchToolDefinitionOutput; + +// @public +export interface ToolDefinitionOutputParent { + // (undocumented) + type: string; +} + +// @public +export interface ToolDefinitionParent { + // (undocumented) + type: string; +} + +// @public +export interface ToolOutput { + output?: string; + tool_call_id?: string; +} + +// @public +export interface ToolResources { + azure_ai_search?: AzureAISearchResource; + code_interpreter?: CodeInterpreterToolResource; + file_search?: FileSearchToolResource; +} + +// @public +export interface ToolResourcesOutput { + azure_ai_search?: AzureAISearchResourceOutput; + code_interpreter?: CodeInterpreterToolResourceOutput; + file_search?: FileSearchToolResourceOutput; +} + +// @public +export type Trigger = TriggerParent | RecurrenceTrigger | CronTrigger; + +// @public +export type TriggerOutput = TriggerOutputParent | RecurrenceTriggerOutput | CronTriggerOutput; + +// @public +export interface TriggerOutputParent { + // (undocumented) + type: string; +} + +// @public +export interface TriggerParent { + // (undocumented) + type: string; +} + +// @public +export interface TruncationObject { + last_messages?: number | null; + type: TruncationStrategy; +} + +// @public +export interface TruncationObjectOutput { + last_messages?: number | null; + type: TruncationStrategyOutput; +} + +// @public +export type TruncationStrategy = string; + +// @public +export type TruncationStrategyOutput = string; + +// @public +export interface UpdateAgentOptions { + description?: string | null; + instructions?: string | null; + metadata?: Record | null; + model?: string; + name?: string | null; + response_format?: AgentsApiResponseFormatOption | null; + temperature?: number | null; + tool_resources?: ToolResources; + tools?: Array; + top_p?: number | null; +} + +// @public +export interface UpdateAgentThreadOptions { + metadata?: Record | null; + tool_resources?: ToolResources | null; +} + +// @public +export interface UpdateCodeInterpreterToolResourceOptions { + file_ids?: string[]; +} + +// @public +export interface UpdateCodeInterpreterToolResourceOptionsOutput { + file_ids?: string[]; +} + +// @public +export interface UpdateFileSearchToolResourceOptions { + vector_store_ids?: string[]; +} + +// @public +export interface UpdateFileSearchToolResourceOptionsOutput { + vector_store_ids?: string[]; +} + +// @public +export interface UpdateToolResourcesOptions { + azure_ai_search?: AzureAISearchResource; + code_interpreter?: UpdateCodeInterpreterToolResourceOptions; + file_search?: UpdateFileSearchToolResourceOptions; +} + +// @public +export interface UpdateToolResourcesOptionsOutput { + azure_ai_search?: AzureAISearchResourceOutput; + code_interpreter?: UpdateCodeInterpreterToolResourceOptionsOutput; + file_search?: UpdateFileSearchToolResourceOptionsOutput; +} + +// @public +export interface VectorStoreAutoChunkingStrategyRequest extends VectorStoreChunkingStrategyRequestParent { + type: "auto"; +} + +// @public +export interface VectorStoreAutoChunkingStrategyResponseOutput extends VectorStoreChunkingStrategyResponseOutputParent { + type: "other"; +} + +// @public +export type VectorStoreChunkingStrategyRequest = VectorStoreChunkingStrategyRequestParent | VectorStoreAutoChunkingStrategyRequest | VectorStoreStaticChunkingStrategyRequest; + +// @public +export interface VectorStoreChunkingStrategyRequestParent { + // (undocumented) + type: VectorStoreChunkingStrategyRequestType; +} + +// @public +export type VectorStoreChunkingStrategyRequestType = string; + +// @public +export type VectorStoreChunkingStrategyResponseOutput = VectorStoreChunkingStrategyResponseOutputParent | VectorStoreAutoChunkingStrategyResponseOutput | VectorStoreStaticChunkingStrategyResponseOutput; + +// @public +export interface VectorStoreChunkingStrategyResponseOutputParent { + // (undocumented) + type: VectorStoreChunkingStrategyResponseTypeOutput; +} + +// @public +export type VectorStoreChunkingStrategyResponseTypeOutput = string; + +// @public +export interface VectorStoreDeletionStatusOutput { + deleted: boolean; + id: string; + object: "vector_store.deleted"; +} + +// @public +export interface VectorStoreExpirationPolicy { + anchor: VectorStoreExpirationPolicyAnchor; + days: number; +} + +// @public +export type VectorStoreExpirationPolicyAnchor = string; + +// @public +export type VectorStoreExpirationPolicyAnchorOutput = string; + +// @public +export interface VectorStoreExpirationPolicyOutput { + anchor: VectorStoreExpirationPolicyAnchorOutput; + days: number; +} + +// @public +export interface VectorStoreFileBatchOutput { + created_at: number; + file_counts: VectorStoreFileCountOutput; + id: string; + object: "vector_store.files_batch"; + status: VectorStoreFileBatchStatusOutput; + vector_store_id: string; +} + +// @public +export type VectorStoreFileBatchStatusOutput = string; + +// @public +export interface VectorStoreFileCountOutput { + cancelled: number; + completed: number; + failed: number; + in_progress: number; + total: number; +} + +// @public +export interface VectorStoreFileDeletionStatusOutput { + deleted: boolean; + id: string; + object: "vector_store.file.deleted"; +} + +// @public +export type VectorStoreFileErrorCodeOutput = string; + +// @public +export interface VectorStoreFileErrorOutput { + code: VectorStoreFileErrorCodeOutput; + message: string; +} + +// @public +export interface VectorStoreFileOutput { + chunking_strategy: VectorStoreChunkingStrategyResponseOutput; + created_at: number; + id: string; + last_error: VectorStoreFileErrorOutput | null; + object: "vector_store.file"; + status: VectorStoreFileStatusOutput; + usage_bytes: number; + vector_store_id: string; +} + +// @public +export type VectorStoreFileStatusFilter = string; + +// @public +export type VectorStoreFileStatusOutput = string; + +// @public +export interface VectorStoreOptions { + chunking_strategy?: VectorStoreChunkingStrategyRequest; + expires_after?: VectorStoreExpirationPolicy; + file_ids?: string[]; + metadata?: Record | null; + name?: string; +} + +// @public +export interface VectorStoreOutput { + created_at: number; + expires_after?: VectorStoreExpirationPolicyOutput; + expires_at?: number | null; + file_counts: VectorStoreFileCountOutput; + id: string; + last_active_at: number | null; + metadata: Record | null; + name: string; + object: "vector_store"; + status: VectorStoreStatusOutput; + usage_bytes: number; +} + +// @public +export interface VectorStoreStaticChunkingStrategyOptions { + chunk_overlap_tokens: number; + max_chunk_size_tokens: number; +} + +// @public +export interface VectorStoreStaticChunkingStrategyOptionsOutput { + chunk_overlap_tokens: number; + max_chunk_size_tokens: number; +} + +// @public +export interface VectorStoreStaticChunkingStrategyRequest extends VectorStoreChunkingStrategyRequestParent { + static: VectorStoreStaticChunkingStrategyOptions; + type: "static"; +} + +// @public +export interface VectorStoreStaticChunkingStrategyResponseOutput extends VectorStoreChunkingStrategyResponseOutputParent { + static: VectorStoreStaticChunkingStrategyOptionsOutput; + type: "static"; +} + +// @public +export type VectorStoreStatusOutput = string; + +// @public +export interface VectorStoreUpdateOptions { + expires_after?: VectorStoreExpirationPolicy | null; + metadata?: Record | null; + name?: string | null; +} + +// @public +export type WeekDays = string; + +// @public +export type WeekDaysOutput = string; + +// @public +export interface WorkspacePropertiesOutput { + applicationInsights: string; } // (No @packageDocumentation comment for this package) diff --git a/sdk/ai/ai-projects/samples-dev/agents/streaming.ts b/sdk/ai/ai-projects/samples-dev/agents/streaming.ts new file mode 100644 index 000000000000..4b8e664039bd --- /dev/null +++ b/sdk/ai/ai-projects/samples-dev/agents/streaming.ts @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { AIProjectsClient, DoneEvent, ErrorEvent, MessageDeltaChunk, MessageDeltaContent, MessageDeltaTextContent, MessageStreamEvent, RunStreamEvent, ThreadRunOutput } from "@azure/ai-projects" +import { DefaultAzureCredential } from "@azure/identity"; + +import * as dotenv from "dotenv"; +dotenv.config(); + +const connectionString = process.env["AZURE_AI_PROJECTS_CONNECTION_STRING"] || ">;;;"; + +export async function main(): Promise { + const client = AIProjectsClient.fromConnectionString(connectionString || "", new DefaultAzureCredential()); + + const agent = await client.agents.createAgent({ model: "gpt-4-1106-preview", name: "my-assistant", instructions: "You are helpful agent" }); + + console.log(`Created agent, agent ID : ${agent.id}`); + + const thread = await client.agents.createThread(); + + console.log(`Created thread, thread ID : ${agent.id}`); + + await client.agents.createMessage(thread.id, { role: "user", content: "Hello, tell me a joke" }); + + console.log(`Created message, thread ID : ${agent.id}`); + + const streamEventMessages = client.agents.createRunStreaming(thread.id, agent.id); + + for await (const eventMessage of streamEventMessages) { + switch (eventMessage.event) { + case RunStreamEvent.ThreadRunCreated: + console.log(`ThreadRun status: ${(eventMessage.data as ThreadRunOutput).status}`) + break; + case MessageStreamEvent.ThreadMessageDelta: + { + const messageDelta = eventMessage.data as MessageDeltaChunk; + messageDelta.delta.content.forEach((contentPart) => { + if (contentPart.type === "text") { + const textContent = contentPart as MessageDeltaTextContent + const textValue = textContent.text || "No text" + console.log(`ext delta received:: ${textValue}`) + } + }); + } + break; + + case RunStreamEvent.ThreadRunCompleted: + console.log("Thread Run Completed"); + break; + case ErrorEvent.Error: + console.log(`An error occurred. Data ${eventMessage.data}`); + break; + case DoneEvent.Done: + console.log("Stream completed."); + break; + } + } + + await client.agents.deleteAgent(agent.id) + console.log(`Delete agent, agent ID : ${agent.id}`); +} + +main().catch((err) => { + console.error("The sample encountered an error:", err); +}); diff --git a/sdk/ai/ai-projects/src/agents/index.ts b/sdk/ai/ai-projects/src/agents/index.ts index cab5f80e5bb4..8d367823a83c 100644 --- a/sdk/ai/ai-projects/src/agents/index.ts +++ b/sdk/ai/ai-projects/src/agents/index.ts @@ -2,8 +2,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { Client } from "@azure-rest/core-client"; -import { AgentDeletionStatusOutput, AgentOutput, AgentThreadOutput, FileDeletionStatusOutput, FileListResponseOutput, OpenAIFileOutput, OpenAIPageableListOfAgentOutput, OpenAIPageableListOfThreadRunOutput, ThreadDeletionStatusOutput, ThreadMessageOutput, ThreadRunOutput } from "../generated/src/outputModels.js"; +import { Client, RequestParameters } from "@azure-rest/core-client"; +import { AgentDeletionStatusOutput, AgentOutput, AgentThreadOutput, FileDeletionStatusOutput, FileListResponseOutput, OpenAIFileOutput, OpenAIPageableListOfAgentOutput, OpenAIPageableListOfThreadRunOutput, ThreadDeletionStatusOutput, ThreadMessageOutput, ThreadRunOutput } from "../generated/src/outputModels.js"; import { CancelRunParameters, CreateRunParameters, CreateThreadAndRunParameters, DeleteFileParameters, DeleteThreadParameters, GetFileContentParameters, GetFileParameters, GetRunParameters, GetThreadParameters, ListAgentsQueryParamProperties, ListFilesParameters, ListMessagesParameters, ListRunsParameters, SubmitToolOutputsToRunParameters, UpdateMessageParameters, UpdateRunParameters, UpdateThreadParameters, UploadFileParameters } from "../generated/src/parameters.js"; import { createAgent, deleteAgent, getAgent, listAgents, updateAgent } from "./assistants.js"; import { deleteFile, getFile, getFileContent, listFiles, uploadFile } from "./files.js"; @@ -11,203 +11,213 @@ import { createThread, deleteThread, getThread, updateThread } from "./threads.j import { cancelRun, createRun, createThreadAndRun, getRun, listRuns, submitToolOutputsToRun, updateRun } from "./runs.js"; import { createMessage, listMessages, updateMessage } from "./messages.js"; import { AgentThreadCreationOptions, CreateAgentOptions, CreateAndRunThreadOptions, CreateRunOptions, ThreadMessageOptions, UpdateAgentOptions } from "../generated/src/models.js"; -import { AgentStreamEventMessage, createRunStreaming, createThreadAndRunStreaming } from "./streaming.js"; +import { createRunStreaming, createThreadAndRunStreaming } from "./streaming.js"; +import { AgentStreamEventMessage } from "./streamingModels.js"; export interface AgentsOperations { - /** Creates a new agent. */ - createAgent: ( - options: CreateAgentOptions, - ) => Promise; - /** Gets a list of agents that were previously created. */ - listAgents: ( - options?: ListAgentsQueryParamProperties, - ) => Promise; - /** Retrieves an existing agent. */ - getAgent: ( - assistantId: string - ) => Promise; - /** Modifies an existing agent. */ + /** Creates a new agent. */ + createAgent: ( + options: CreateAgentOptions, + ) => Promise; + + /** Creates a new agent. */ + createAgentAlternative: ( + model: string, + options?: Omit, + ) => Promise; + + /** Gets a list of agents that were previously created. */ + listAgents: ( + options?: ListAgentsQueryParamProperties, + ) => Promise; + /** Retrieves an existing agent. */ + getAgent: ( + assistantId: string + ) => Promise; + /** Modifies an existing agent. */ + updateAgent: ( + assistantId: string, + options: UpdateAgentOptions, + ) => Promise; + /** Deletes an agent. */ + deleteAgent: ( + assistantId: string + ) => Promise; + + /** Creates a new thread. Threads contain messages and can be run by agents. */ + createThread: ( + options?: AgentThreadCreationOptions, + ) => Promise; + /** Gets information about an existing thread. */ + getThread: ( + threadId: string, + options?: GetThreadParameters, + ) => Promise; + /** Modifies an existing thread. */ + updateThread: ( + threadId: string, + options: UpdateThreadParameters, + ) => Promise; + /** Deletes an existing thread. */ + deleteThread: ( + threadId: string, + options?: DeleteThreadParameters, + ) => Promise; + + /** Creates and starts a new run of the specified thread using the specified agent. */ + createRun: ( + threadId: string, + options: CreateRunParameters, + ) => Promise; + /** Gets a list of runs for a specified thread. */ + listRuns: ( + threadId: string, + options?: ListRunsParameters, + ) => Promise; + /** Gets an existing run from an existing thread. */ + getRun: ( + threadId: string, + runId: string, + options?: GetRunParameters, + ) => Promise; + /** Modifies an existing thread run. */ + updateRun: ( + threadId: string, + runId: string, + options: UpdateRunParameters, + ) => Promise; + /** Submits outputs from tools as requested by tool calls in a run. Runs that need submitted tool outputs will have a status of 'requires_action' with a required_action.type of 'submit_tool_outputs'. */ + submitToolOutputsToRun: ( + threadId: string, + runId: string, + options: SubmitToolOutputsToRunParameters, + ) => Promise; + /** Cancels a run of an in progress thread. */ + cancelRun: ( + threadId: string, + runId: string, + options?: CancelRunParameters, + ) => Promise; + /** Creates a new thread and immediately starts a run of that thread. */ + createThreadAndRun: ( + options: CreateThreadAndRunParameters, + ) => Promise; + + /** create a new thread and immediately start a run of that thread and stream */ + createRunStreaming: (threadId: string, assistantId: string, options?: Omit, requestParams?: RequestParameters) => AsyncIterable; + + /** create a new thread and immediately start a run of that thread and stream */ + createThreadAndRunStreaming: (assistantId: string, options?: Omit, requestParams?: RequestParameters) => AsyncIterable; + + /** Creates a new message on a specified thread. */ + createMessage: ( + threadId: string, + options: ThreadMessageOptions, + ) => Promise; + /** Gets a list of messages that exist on a thread. */ + listMessages: ( + threadId: string, + options?: ListMessagesParameters, + ) => Promise; + /** Modifies an existing message on an existing thread. */ + updateMessage: ( + threadId: string, + messageId: string, + options: UpdateMessageParameters, + ) => Promise; + + /** Gets a list of previously uploaded files. */ + listFiles: ( + options?: ListFilesParameters, + ) => Promise; + /** Uploads a file for use by other operations. */ + uploadFile: ( + options: UploadFileParameters, + ) => Promise; + /** Delete a previously uploaded file. */ + deleteFile: ( + fileId: string, + options?: DeleteFileParameters, + ) => Promise; + /** Returns information about a specific file. Does not retrieve file content. */ + getFile: ( + fileId: string, + options?: GetFileParameters, + ) => Promise; + /** Returns the content of a specific file. */ + getFileContent: ( + fileId: string, + options?: GetFileContentParameters, + ) => Promise; +} + +function getAgents(context: Client): AgentsOperations { + return { + createAgentAlternative: (model: string, options?: Omit) => + createAgent(context, { body: { ...options, model } }), + createAgent: (options: CreateAgentOptions) => + createAgent(context, { body: options }), + listAgents: (options?: ListAgentsQueryParamProperties) => + listAgents(context, { queryParameters: options as Record }), + getAgent: (assistantId: string) => + getAgent(context, assistantId), updateAgent: ( assistantId: string, options: UpdateAgentOptions, - ) => Promise; - /** Deletes an agent. */ + ) => updateAgent(context, assistantId, { body: options }), deleteAgent: ( assistantId: string - ) => Promise; - - /** Creates a new thread. Threads contain messages and can be run by agents. */ - createThread: ( - options?: AgentThreadCreationOptions, - ) => Promise; - /** Gets information about an existing thread. */ - getThread: ( - threadId: string, - options?: GetThreadParameters, - ) => Promise; - /** Modifies an existing thread. */ - updateThread: ( - threadId: string, - options: UpdateThreadParameters, - ) => Promise; - /** Deletes an existing thread. */ - deleteThread: ( - threadId: string, - options?: DeleteThreadParameters, - ) => Promise; - - /** Creates and starts a new run of the specified thread using the specified agent. */ - createRun: ( - threadId: string, - options: CreateRunParameters, - ) => Promise; - /** Gets a list of runs for a specified thread. */ - listRuns: ( - threadId: string, - options?: ListRunsParameters, - ) => Promise; - /** Gets an existing run from an existing thread. */ - getRun: ( - threadId: string, - runId: string, - options?: GetRunParameters, - ) => Promise; - /** Modifies an existing thread run. */ - updateRun: ( - threadId: string, - runId: string, - options: UpdateRunParameters, - ) => Promise; - /** Submits outputs from tools as requested by tool calls in a run. Runs that need submitted tool outputs will have a status of 'requires_action' with a required_action.type of 'submit_tool_outputs'. */ - submitToolOutputsToRun: ( - threadId: string, - runId: string, - options: SubmitToolOutputsToRunParameters, - ) => Promise; - /** Cancels a run of an in progress thread. */ - cancelRun: ( - threadId: string, - runId: string, - options?: CancelRunParameters, - ) => Promise; - /** Creates a new thread and immediately starts a run of that thread. */ - createThreadAndRun: ( - options: CreateThreadAndRunParameters, - ) => Promise; - - /** create a new thread and immediately start a run of that thread and stream */ - createRunStreaming: (threadId: string, options: CreateRunOptions) => AsyncIterable; - - /** create a new thread and immediately start a run of that thread and stream */ - createThreadAndRunStreaming: (options: CreateAndRunThreadOptions) => AsyncIterable; - - /** Creates a new message on a specified thread. */ - createMessage: ( - threadId: string, - options: ThreadMessageOptions, - ) => Promise; - /** Gets a list of messages that exist on a thread. */ - listMessages: ( - threadId: string, - options?: ListMessagesParameters, - ) => Promise; - /** Modifies an existing message on an existing thread. */ - updateMessage: ( - threadId: string, - messageId: string, - options: UpdateMessageParameters, - ) => Promise; - - /** Gets a list of previously uploaded files. */ - listFiles: ( - options?: ListFilesParameters, - ) => Promise; - /** Uploads a file for use by other operations. */ - uploadFile: ( - options: UploadFileParameters, - ) => Promise; - /** Delete a previously uploaded file. */ - deleteFile: ( - fileId: string, - options?: DeleteFileParameters, - ) => Promise; - /** Returns information about a specific file. Does not retrieve file content. */ - getFile: ( - fileId: string, - options?: GetFileParameters, - ) => Promise; - /** Returns the content of a specific file. */ - getFileContent: ( - fileId: string, - options?: GetFileContentParameters, - ) => Promise; -} + ) => deleteAgent(context, assistantId), + + createThread: (options?: AgentThreadCreationOptions) => + createThread(context, { body: options || {} }), + getThread: (threadId: string, options?: GetThreadParameters) => + getThread(context, threadId, options), + updateThread: (threadId: string, options: UpdateThreadParameters) => + updateThread(context, threadId, options), + deleteThread: (threadId: string, options?: DeleteThreadParameters) => + deleteThread(context, threadId, options), + + createRun: (threadId: string, options: CreateRunParameters) => + createRun(context, threadId, options), + listRuns: (threadId: string, options?: ListRunsParameters) => + listRuns(context, threadId, options), + getRun: (threadId: string, runId: string, options?: GetRunParameters) => + getRun(context, threadId, runId, options), + updateRun: (threadId: string, runId: string, options: UpdateRunParameters) => + updateRun(context, threadId, runId, options), + submitToolOutputsToRun: (threadId: string, runId: string, options: SubmitToolOutputsToRunParameters) => + submitToolOutputsToRun(context, threadId, runId, options), + cancelRun: (threadId: string, runId: string, options?: CancelRunParameters) => + cancelRun(context, threadId, runId, options), + createThreadAndRun: (options: CreateThreadAndRunParameters) => + createThreadAndRun(context, options), + createRunStreaming: (threadId: string, assistantId: string, options?: Omit, requestParams?: RequestParameters) => + createRunStreaming(context, threadId, {...requestParams, body: { ...options, assistant_id: assistantId } }), + createThreadAndRunStreaming: (assistantId: string, options?: Omit, requestParams?: RequestParameters) => + createThreadAndRunStreaming(context, { ...requestParams, body: { ...options, assistant_id: assistantId } }), + createMessage: (threadId: string, options: ThreadMessageOptions) => + createMessage(context, threadId, { body: options }), + listMessages: (threadId: string, options?: ListMessagesParameters) => + listMessages(context, threadId, options), + updateMessage: (threadId: string, messageId: string, options: UpdateMessageParameters) => + updateMessage(context, threadId, messageId, options), -function getAgents(context: Client) : AgentsOperations { - return { - createAgent: (options: CreateAgentOptions) => - createAgent(context, { body:options }), - listAgents: (options?: ListAgentsQueryParamProperties) => - listAgents(context, { queryParameters : options as Record }), - getAgent: (assistantId: string) => - getAgent(context, assistantId), - updateAgent: ( - assistantId: string, - options: UpdateAgentOptions, - ) => updateAgent(context, assistantId, { body: options }), - deleteAgent: ( - assistantId: string - ) => deleteAgent(context, assistantId), - - createThread: (options?: AgentThreadCreationOptions) => - createThread(context, {body: options || {}}), - getThread: (threadId: string, options?: GetThreadParameters) => - getThread(context, threadId, options), - updateThread: (threadId: string, options: UpdateThreadParameters) => - updateThread(context, threadId, options), - deleteThread: (threadId: string, options?: DeleteThreadParameters) => - deleteThread(context, threadId, options), - - createRun: (threadId: string, options: CreateRunParameters) => - createRun(context, threadId, options), - listRuns: (threadId: string, options?: ListRunsParameters) => - listRuns(context, threadId, options), - getRun: (threadId: string, runId: string, options?: GetRunParameters) => - getRun(context, threadId, runId, options), - updateRun: (threadId: string, runId: string, options: UpdateRunParameters) => - updateRun(context, threadId, runId, options), - submitToolOutputsToRun: (threadId: string, runId: string, options: SubmitToolOutputsToRunParameters) => - submitToolOutputsToRun(context, threadId, runId, options), - cancelRun: (threadId: string, runId: string, options?: CancelRunParameters) => - cancelRun(context, threadId, runId, options), - createThreadAndRun: (options: CreateThreadAndRunParameters) => - createThreadAndRun(context, options), - createRunStreaming: (threadId: string, options: CreateRunOptions) => - createRunStreaming(context, threadId, {body: options}), - createThreadAndRunStreaming: (options: CreateAndRunThreadOptions) => - createThreadAndRunStreaming(context, {body: options}), - createMessage: (threadId: string, options: ThreadMessageOptions) => - createMessage(context, threadId, { body: options }), - listMessages: (threadId: string, options?: ListMessagesParameters) => - listMessages(context, threadId, options), - updateMessage: (threadId: string, messageId: string, options: UpdateMessageParameters) => - updateMessage(context, threadId, messageId, options), - - listFiles: (options?: ListFilesParameters) => - listFiles(context, options), - uploadFile: (options: UploadFileParameters) => - uploadFile(context, options), - deleteFile: (fileId: string, options?: DeleteFileParameters) => - deleteFile(context, fileId, options), - getFile: (fileId: string, options?: GetFileParameters) => - getFile(context, fileId, options), - getFileContent: (fileId: string, options?: GetFileContentParameters) => - getFileContent(context, fileId, options), - }; + listFiles: (options?: ListFilesParameters) => + listFiles(context, options), + uploadFile: (options: UploadFileParameters) => + uploadFile(context, options), + deleteFile: (fileId: string, options?: DeleteFileParameters) => + deleteFile(context, fileId, options), + getFile: (fileId: string, options?: GetFileParameters) => + getFile(context, fileId, options), + getFileContent: (fileId: string, options?: GetFileContentParameters) => + getFileContent(context, fileId, options), + }; } export function getAgentsOperations(context: Client): AgentsOperations { - return { - ...getAgents(context), - }; + return { + ...getAgents(context), + }; } diff --git a/sdk/ai/ai-projects/src/agents/inputOutputs.ts b/sdk/ai/ai-projects/src/agents/inputOutputs.ts index 20e54695690b..0d3b4151af55 100644 --- a/sdk/ai/ai-projects/src/agents/inputOutputs.ts +++ b/sdk/ai/ai-projects/src/agents/inputOutputs.ts @@ -2,10 +2,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { CreateAgentOptions, CreateAndRunThreadOptions, CreateRunOptions, UpdateAgentOptions } from "../generated/src/models.js" -import { AgentDeletionStatusOutput, AgentOutput, AgentThreadOutput } from "../generated/src/outputModels.js" -import { AgentStreamEventMessage } from "./streaming.js" -export{CreateAgentOptions, CreateRunOptions, CreateAndRunThreadOptions, UpdateAgentOptions, AgentStreamEventMessage} - -export{AgentThreadOutput, AgentOutput, AgentDeletionStatusOutput} +export * from "./streamingModels.js" +export * from "../generated/src/models.js" +export * from "../generated/src/outputModels.js" diff --git a/sdk/ai/ai-projects/src/agents/streaming.ts b/sdk/ai/ai-projects/src/agents/streaming.ts index bf607fda46af..292015c97f36 100644 --- a/sdk/ai/ai-projects/src/agents/streaming.ts +++ b/sdk/ai/ai-projects/src/agents/streaming.ts @@ -1,46 +1,16 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { Client, createRestError } from "@azure-rest/core-client"; +import { Client, createRestError, HttpBrowserStreamResponse } from "@azure-rest/core-client"; import { ProjectsClient } from "../generated/src/clientDefinitions.js"; import { CreateRunParameters, CreateThreadAndRunBodyParam } from "../generated/src/index.js"; +import { AgentStreamEventMessage } from "./streamingModels.js"; +import { createSseStream } from "@azure/core-sse"; const expectedStatuses = ["200"]; -export interface AgentStreamEventMessage { - data: any; - eventType: string; -} -// export interface AgentStreamMessage { -// data: string | ThreadMessageOutput | ThreadRunOutput | RunStepOutput | {}; -// eventType: string; -// } - -// export enum AgentStreamEventType { -// ThreadRunCreated = "thread.run.created", -// ThreadRunQueued = "thread.run.queued", -// ThreadRunInProgress = "thread.run.in_progress", -// ThreadRunStepCreated = "thread.run.step.created", -// ThreadRunStepInProgress = "thread.run.step.in_progress", -// ThreadMessageCreated = "thread.message.created", -// ThreadMessageInProgress = "thread.message.in_progress", -// ThreadMessageDelta = "thread.message.delta", -// ThreadMessageCompleted = "thread.message.completed", -// ThreadRunStepCompleted = "thread.run.step.completed", -// ThreadRunCompleted = "thread.run.completed", - -// } -export async function* createRunStreaming( - context: Client, - threadId: string, - options: CreateRunParameters, -): AsyncIterable { - options.body.stream = true; - const result = await (context as ProjectsClient) - .path("/threads/{threadId}/runs", threadId) - .post(options) - .asBrowserStream(); +async function* processStream(result: HttpBrowserStreamResponse): AsyncIterable { if (!expectedStatuses.includes(result.status)) { throw createRestError(result); } @@ -48,87 +18,44 @@ export async function* createRunStreaming( throw new Error("No body in response"); } - let buffer = ""; - const decoder = new TextDecoder("utf-8"); - for await (const chunk of result.body) { - buffer += decoder.decode(chunk, { stream: true }); - if (buffer.includes("\n")) { - const lines = buffer.split("\n\n"); - for (let i = 0; i < lines.length - 1; i++) { - const streamData = parseLine(lines[i]); - if (streamData) { - yield streamData; - } - } - buffer = lines[lines.length - 1]; + const stream = createSseStream(result.body); + for await (const event of stream) { + try{ + yield {data: JSON.parse(event.data), event: event.event} + } + catch{ + yield {data: event.data, event: event.event} } } } -export async function* createThreadAndRunStreaming( +/** Create a run and stream the events */ +export async function* createRunStreaming( context: Client, - options: CreateThreadAndRunBodyParam, -): AsyncIterable { - options.body.stream = true; - const result = await (context as ProjectsClient) - .path("/threads/runs") - .post(options) - .asBrowserStream(); - - if (!expectedStatuses.includes(result.status)) { - throw createRestError(result); - } - if (!result.body) { - throw new Error("No body in response"); - } + threadId: string, + options: CreateRunParameters, +): AsyncIterable { + options.body.stream = true; + const response = await (context as ProjectsClient) + .path("/threads/{threadId}/runs", threadId) + .post(options) + .asBrowserStream(); - let buffer = ""; - const decoder = new TextDecoder("utf-8"); - for await (const chunk of result.body) { - buffer += decoder.decode(chunk, { stream: true }); - if (buffer.includes("\n")) { - const lines = buffer.split("\n\n"); - for (let i = 0; i < lines.length - 1; i++) { - const streamData = parseLine(lines[i]); - if (streamData) { - yield streamData; - } - } - buffer = lines[lines.length - 1]; - } - } + yield* processStream(response); } -function parseLine(line: string): AgentStreamEventMessage | undefined { - const streamData: AgentStreamEventMessage = { data: {}, eventType: "" }; - const trimmedLine = line.trim(); - - if (trimmedLine.length > 0) { - trimmedLine.split("\n").forEach((l) => { - const trimmedL = l.trim(); - const colIndex = trimmedL.indexOf(":"); +/** Create a thread and run and stream the events */ +export async function* createThreadAndRunStreaming( + context: Client, + options: CreateThreadAndRunBodyParam, +): AsyncIterable { + options.body.stream = true; + const response = await (context as ProjectsClient) + .path("/threads/runs") + .post(options) + .asBrowserStream(); - if (colIndex !== -1) { - const fieldName = trimmedL.substring(0, colIndex).trim(); - const fieldValue = trimmedL.substring(colIndex + 1).trim(); + yield* processStream(response); +} - switch (fieldName) { - case "data": - try { - streamData.data = JSON.parse(fieldValue); - } catch { - streamData.data = fieldValue; - } - break; - case "event": - if (fieldValue !== "done") { - streamData.eventType = fieldValue; - } - break; - } - } - }); - } - return streamData.eventType ? streamData : undefined; -} diff --git a/sdk/ai/ai-projects/src/agents/streamingModels.ts b/sdk/ai/ai-projects/src/agents/streamingModels.ts new file mode 100644 index 000000000000..c3877e9ac728 --- /dev/null +++ b/sdk/ai/ai-projects/src/agents/streamingModels.ts @@ -0,0 +1,411 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { MessageRole } from "../generated/src/models.js"; +import { AgentThreadOutput, RunStepOutput, ThreadMessageOutput, ThreadRunOutput } from "../generated/src/outputModels.js"; + +/* +Each event in a server-sent events stream has an `event` and `data` property: + + ``` + event: thread.created + data: {"id": "thread_123", "object": "thread", ...} + ``` + + We emit events whenever a new object is created, transitions to a new state, or is being + streamed in parts (deltas). For example, we emit `thread.run.created` when a new run + is created, `thread.run.completed` when a run completes, and so on. When an Agent chooses + to create a message during a run, we emit a `thread.message.created event`, a + `thread.message.in_progress` event, many `thread.message.delta` events, and finally a + `thread.message.completed` event. + + We may add additional events over time, so we recommend handling unknown events gracefully + in your code.*/ + export interface AgentStreamEventMessage { + data: AgentThreadOutput | ThreadRunOutput | RunStepOutput| ThreadMessageOutput | MessageDeltaChunk | RunStepDeltaChunk | string + event: AgentStreamEventType | string; + } + + + /** Thread operation related streaming events */ + export enum ThreadStreamEvent { + /** Event sent when a new thread is created. The data of this event is of type AgentThread */ + ThreadCreated= "thread.created", + } + + /** Run operation related streaming events */ + export enum RunStreamEvent { + + /** Event sent when a new run is created. The data of this event is of type ThreadRun */ + ThreadRunCreated= "thread.run.created", + + /** Event sent when a run moves to `queued` status. The data of this event is of type ThreadRun */ + ThreadRunQueued= "thread.run.queued", + + /** Event sent when a run moves to `in_progress` status. The data of this event is of type ThreadRun */ + ThreadRunInProgress= "thread.run.in_progress", + + /** Event sent when a run moves to `requires_action` status. The data of this event is of type ThreadRun */ + ThreadRunRequiresAction= "thread.run.requires_action", + + /** Event sent when a run is completed. The data of this event is of type ThreadRun */ + ThreadRunCompleted= "thread.run.completed", + + /** Event sent when a run fails. The data of this event is of type ThreadRun */ + ThreadRunFailed= "thread.run.failed", + + /** Event sent when a run moves to `cancelling` status. The data of this event is of type ThreadRun */ + ThreadRunCancelling= "thread.run.cancelling", + + /** Event sent when a run is cancelled. The data of this event is of type ThreadRun */ + ThreadRunCancelled= "thread.run.cancelled", + + /** Event sent when a run is expired. The data of this event is of type ThreadRun */ + ThreadRunExpired= "thread.run.expired", + } + + /** Run step operation related streaming events */ + export enum RunStepStreamEvent { + + /** Event sent when a new thread run step is created. The data of this event is of type RunStep */ + ThreadRunStepCreated= "thread.run.step.created", + + /** Event sent when a run step moves to `in_progress` status. The data of this event is of type RunStep */ + ThreadRunStepInProgress= "thread.run.step.in_progress", + + /** Event sent when a run step is being streamed. The data of this event is of type RunStepDeltaChunk */ + ThreadRunStepDelta= "thread.run.step.delta", + + /** Event sent when a run step is completed. The data of this event is of type RunStep */ + ThreadRunStepCompleted= "thread.run.step.completed", + + /** Event sent when a run step fails. The data of this event is of type RunStep */ + ThreadRunStepFailed= "thread.run.step.failed", + + /** Event sent when a run step is cancelled. The data of this event is of type RunStep */ + ThreadRunStepCancelled= "thread.run.step.cancelled", + + /** Event sent when a run step is expired. The data of this event is of type RunStep */ + ThreadRunStepExpired= "thread.run.step.expired", + } + + /** Message operation related streaming events */ + export enum MessageStreamEvent { + + /** Event sent when a new message is created. The data of this event is of type ThreadMessage */ + ThreadMessageCreated= "thread.message.created", + + /** Event sent when a message moves to `in_progress` status. The data of this event is of type ThreadMessage */ + ThreadMessageInProgress= "thread.message.in_progress", + + /** Event sent when a message is being streamed. The data of this event is of type MessageDeltaChunk */ + ThreadMessageDelta= "thread.message.delta", + + /** Event sent when a message is completed. The data of this event is of type ThreadMessage */ + ThreadMessageCompleted= "thread.message.completed", + + /** Event sent before a message is completed. The data of this event is of type ThreadMessage */ + ThreadMessageIncomplete= "thread.message.incomplete", + } + + /** Terminal event indicating a server side error while streaming. */ + export enum ErrorEvent { + /** Event sent when an error occurs, such as an internal server error or a timeout. */ + Error= "error", + } + + /** Terminal event indicating the successful end of a stream. */ + export enum DoneEvent { + + /** Event sent when the stream is done. */ + Done= "done", + } + + export type AgentStreamEventType = + | ThreadStreamEvent + | RunStreamEvent + | RunStepStreamEvent + | MessageStreamEvent + | ErrorEvent + | DoneEvent; + + /** Represents a message delta i.e. any changed fields on a message during streaming. */ +export interface MessageDeltaChunk { + /** The identifier of the message, which can be referenced in API endpoints. */ + id: string; + + /** The object type, which is always `thread.message.delta`. */ + object: "thread.message.delta"; + + /** The delta containing the fields that have changed on the Message. */ + delta: MessageDelta; + } + + /** Represents the typed 'delta' payload within a streaming message delta chunk. */ + export interface MessageDelta { + /** The entity that produced the message. */ + role: MessageRole; + + /** The content of the message as an array of text and/or images. */ + content: MessageDeltaContent[]; + } + + /** The abstract base representation of a partial streamed message content payload. */ + export interface MessageDeltaContent { + /** The index of the content part of the message. */ + index: number; + + /** The type of content for this content part. */ + type: string; + } + /** Represents a streamed image file content part within a streaming message delta chunk. */ + export interface MessageDeltaImageFileContent extends MessageDeltaContent { + /** The type of content for this content part, which is always "image_file." */ + type: "image_file"; + + /** The image_file data. */ + imageFile?: MessageDeltaImageFileContentObject; + } + + /** Represents the 'image_file' payload within streaming image file content. */ + export interface MessageDeltaImageFileContentObject { + /** The file ID of the image in the message content. */ + fileId?: string; + } + + /** Represents a streamed text content part within a streaming message delta chunk. */ + export interface MessageDeltaTextContent extends MessageDeltaContent { + /** The type of content for this content part, which is always "text." */ + type: "text"; + + /** The text content details. */ + text?: MessageDeltaTextContentObject; + } + + /** Represents the data of a streamed text content part within a streaming message delta chunk. */ + export interface MessageDeltaTextContentObject { + /** The data that makes up the text. */ + value?: string; + + /** Annotations for the text. */ + annotations?: MessageDeltaTextAnnotation[]; + } + + /** The abstract base representation of a streamed text content part's text annotation. */ + export interface MessageDeltaTextAnnotation { + /** The index of the annotation within a text content part. */ + index: number; + + /** The type of the text content annotation. */ + type: string; + } + + /** Represents a streamed file citation applied to a streaming text content part. */ + export interface MessageDeltaTextFileCitationAnnotation + extends MessageDeltaTextAnnotation { + /** The type of the text content annotation, which is always "file_citation." */ + type: "file_citation"; + + /** The file citation information. */ + fileCitation?: MessageDeltaTextFileCitationAnnotationObject; + + /** The text in the message content that needs to be replaced */ + text?: string; + + /** The start index of this annotation in the content text. */ + startIndex?: number; + + /** The end index of this annotation in the content text. */ + endIndex?: number; + } + + /** Represents the data of a streamed file citation as applied to a streaming text content part. */ + export interface MessageDeltaTextFileCitationAnnotationObject { + /** The ID of the specific file the citation is from. */ + fileId?: string; + + /** The specific quote in the cited file. */ + quote?: string; + } + + /** Represents a streamed file path annotation applied to a streaming text content part. */ + export interface MessageDeltaTextFilePathAnnotation extends MessageDeltaTextAnnotation { + /** The type of the text content annotation, which is always "file_path." */ + type: "file_path"; + + /** The file path information. */ + filePath?: MessageDeltaTextFilePathAnnotationObject; + + /** The start index of this annotation in the content text. */ + startIndex?: number; + + /** The end index of this annotation in the content text. */ + endIndex?: number; + + /** The text in the message content that needs to be replaced */ + text?: string; + } + + /** Represents the data of a streamed file path annotation as applied to a streaming text content part. */ + export interface MessageDeltaTextFilePathAnnotationObject { + /** The file ID for the annotation. */ + fileId?: string; + } + + /** A representation of the URL used for the text citation. */ + export interface MessageDeltaTextUrlCitationDetails { + /** The URL where the citation is from. */ + url?: string; + + /** The title of the URL. */ + title?: string; + } + + + /** Represents a run step delta i.e. any changed fields on a run step during streaming. */ + export interface RunStepDeltaChunk { + /** The identifier of the run step, which can be referenced in API endpoints. */ + id: string; + + /** The object type, which is always `thread.run.step.delta`. */ + object: "thread.run.step.delta"; + + /** The delta containing the fields that have changed on the run step. */ + delta: RunStepDelta; + } + + /** Represents the delta payload in a streaming run step delta chunk. */ + export interface RunStepDelta { + /** The details of the run step. */ + stepDetails?: RunStepDeltaDetail; + } + + /** Represents a single run step detail item in a streaming run step's delta payload. */ + export interface RunStepDeltaDetail { + /** The object type for the run step detail object. */ + type: string; + } + + /** Represents a message creation within a streaming run step delta. */ + export interface RunStepDeltaMessageCreation extends RunStepDeltaDetail { + /** The object type, which is always "message_creation." */ + type: "message_creation"; + + /** The message creation data. */ + messageCreation?: RunStepDeltaMessageCreationObject; + } + + /** Represents the data within a streaming run step message creation response object. */ + export interface RunStepDeltaMessageCreationObject { + /** The ID of the newly-created message. */ + messageId?: string; + } + + /** Represents an invocation of tool calls as part of a streaming run step. */ + export interface RunStepDeltaToolCallObject extends RunStepDeltaDetail { + /** The object type, which is always "tool_calls." */ + type: "tool_calls"; + + /** The collection of tool calls for the tool call detail item. */ + toolCalls?: RunStepDeltaToolCall[]; + } + + /** The abstract base representation of a single tool call within a streaming run step's delta tool call details. */ + export interface RunStepDeltaToolCall { + /** The index of the tool call detail in the run step's tool_calls array. */ + index: number; + + /** The ID of the tool call, used when submitting outputs to the run. */ + id: string; + + /** The type of the tool call detail item in a streaming run step's details. */ + type: string; + } + + /** Represents a function tool call within a streaming run step's tool call details. */ + export interface RunStepDeltaFunctionToolCall extends RunStepDeltaToolCall { + /** The object type, which is always "function." */ + type: "function"; + + /** The function data for the tool call. */ + function?: RunStepDeltaFunction; + } + + /** Represents a file search tool call within a streaming run step's tool call details. */ + export interface RunStepDeltaFileSearchToolCall extends RunStepDeltaToolCall { + /** The object type, which is always "file_search." */ + type: "file_search"; + + /** Reserved for future use. */ + fileSearch?: Array + } + + /** Represents a Code Interpreter tool call within a streaming run step's tool call details. */ + export interface RunStepDeltaCodeInterpreterToolCall extends RunStepDeltaToolCall { + /** The object type, which is always "code_interpreter." */ + type: "code_interpreter"; + + /** The Code Interpreter data for the tool call. */ + codeInterpreter?: RunStepDeltaCodeInterpreterDetailItemObject; + } + + /** Represents the function data in a streaming run step delta's function tool call. */ + export interface RunStepDeltaFunction { + /** The name of the function. */ + name?: string; + + /** The arguments passed to the function as input. */ + arguments?: string; + + /** The output of the function, null if outputs have not yet been submitted. */ + output?: string | null; + } + + /** Represents the Code Interpreter tool call data in a streaming run step's tool calls. */ + export interface RunStepDeltaCodeInterpreterDetailItemObject { + /** The input into the Code Interpreter tool call. */ + input?: string; + + /** + * The outputs from the Code Interpreter tool call. Code Interpreter can output one or more + * items, including text (`logs`) or images (`image`). Each of these are represented by a + * different object type. + */ + outputs?: RunStepDeltaCodeInterpreterOutput[]; + } + + /** The abstract base representation of a streaming run step tool call's Code Interpreter tool output. */ + export interface RunStepDeltaCodeInterpreterOutput { + /** The index of the output in the streaming run step tool call's Code Interpreter outputs array. */ + index: number; + + /** The type of the streaming run step tool call's Code Interpreter output. */ + type: string; + } + + /** Represents a log output as produced by the Code Interpreter tool and as represented in a streaming run step's delta tool calls collection. */ + export interface RunStepDeltaCodeInterpreterLogOutput + extends RunStepDeltaCodeInterpreterOutput { + /** The type of the object, which is always "logs." */ + type: "logs"; + + /** The text output from the Code Interpreter tool call. */ + logs?: string; + } + + /** Represents an image output as produced the Code interpreter tool and as represented in a streaming run step's delta tool calls collection. */ + export interface RunStepDeltaCodeInterpreterImageOutput + extends RunStepDeltaCodeInterpreterOutput { + /** The object type, which is always "image." */ + type: "image"; + + /** The image data for the Code Interpreter tool call output. */ + image?: RunStepDeltaCodeInterpreterImageOutputObject; + } + + /** Represents the data for a streaming run step's Code Interpreter tool call image output. */ + export interface RunStepDeltaCodeInterpreterImageOutputObject { + /** The file ID for the image. */ + fileId?: string; + } + diff --git a/sdk/ai/ai-projects/src/aiProjectsClient.ts b/sdk/ai/ai-projects/src/aiProjectsClient.ts index 815559a7cbd8..10c764bf5ac3 100644 --- a/sdk/ai/ai-projects/src/aiProjectsClient.ts +++ b/sdk/ai/ai-projects/src/aiProjectsClient.ts @@ -9,9 +9,6 @@ import { AgentsOperations, getAgentsOperations } from "./agents/index.js"; export interface AIProjectsClientOptions extends ProjectsClientOptions{ } -export interface CreateProjectsClient extends ProjectsClientOptions{ -} - export class AIProjectsClient { private _client: Client; /** The pipeline used by this client to make requests */ @@ -53,7 +50,8 @@ export class AIProjectsClient { static fromConnectionString( connectionString: string, credential: TokenCredential, - options: CreateProjectsClient = {}, + // eslint-disable-next-line @azure/azure-sdk/ts-naming-options + options: AIProjectsClientOptions = {}, ): AIProjectsClient { const { endpointParam, subscriptionId, resourceGroupName, projectName } = AIProjectsClient.praseConnectionString(connectionString); diff --git a/sdk/ai/ai-projects/src/index.ts b/sdk/ai/ai-projects/src/index.ts index 9304b661725f..c3497d3491cc 100644 --- a/sdk/ai/ai-projects/src/index.ts +++ b/sdk/ai/ai-projects/src/index.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { AIProjectsClient } from "./aiProjectsClient.js"; - +import { AIProjectsClient, AIProjectsClientOptions } from "./aiProjectsClient.js"; +import { ProjectsClientOptions } from "./generated/src/projectsClient.js" export {AgentsOperations } from "./agents/index.js"; export * from "./agents/inputOutputs.js"; -export { AIProjectsClient }; +export { AIProjectsClient, AIProjectsClientOptions, ProjectsClientOptions }; diff --git a/sdk/ai/ai-projects/test/public/agents/streaming.spec.ts b/sdk/ai/ai-projects/test/public/agents/streaming.spec.ts index 7b1e999e3bef..3bb260dd9936 100644 --- a/sdk/ai/ai-projects/test/public/agents/streaming.spec.ts +++ b/sdk/ai/ai-projects/test/public/agents/streaming.spec.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. import { Recorder, VitestTestContext } from "@azure-tools/test-recorder"; -import { AgentsOperations, AIProjectsClient } from "../../../src/index.js"; +import { AgentsOperations, AIProjectsClient, MessageStreamEvent, RunStreamEvent, ThreadRunOutput } from "../../../src/index.js"; import { createRecorder, createProjectsClient } from "../utils/createClient.js"; import { assert, beforeEach, afterEach, it, describe } from "vitest"; @@ -29,13 +29,25 @@ describe("Agents - streaming", () => { }); const thread = await agents.createThread(); await agents.createMessage(thread.id, { role: "user", content: "Hello, tell me a joke" }); - const stream = agents.createRunStreaming(thread.id, { assistant_id: agent.id }); - let buffer = ""; - for await (const data of stream) { - buffer += data; + const streamEventMessages = agents.createRunStreaming(thread.id, agent.id ); + let hasEventMessages = false; + + for await (const eventMessage of streamEventMessages) { + hasEventMessages = true; + switch (eventMessage.event) { + case RunStreamEvent.ThreadRunCreated: + console.log(( eventMessage.data as ThreadRunOutput).assistant_id) + break; + case MessageStreamEvent.ThreadMessageDelta: + console.log("Thread Message Delta"); + break; + case RunStreamEvent.ThreadRunCompleted: + console.log("Thread Run Completed"); + break + } } - assert.isNotNull(buffer); - assert.isNotNull(stream); + assert.isTrue(hasEventMessages); + assert.isNotNull(streamEventMessages); }); // eslint-disable-next-line no-only-tests/no-only-tests @@ -45,15 +57,26 @@ describe("Agents - streaming", () => { name: "My Friendly Test Assistant", instructions: "You are helpful agent", }); - const stream = agents.createThreadAndRunStreaming({ - assistant_id: agent.id, + const streamEventMessages = agents.createThreadAndRunStreaming(agent.id,{ thread: { messages: [{ role: "user", content: "Hello, tell me a joke" }] }, }); - let buffer = ""; - for await (const data of stream) { - buffer += data; + + let hasEventMessages = false + for await (const eventMessage of streamEventMessages) { + hasEventMessages = true; + switch (eventMessage.event) { + case RunStreamEvent.ThreadRunCreated: + console.log("Thread Run Created"); + break; + case MessageStreamEvent.ThreadMessageDelta: + console.log("Thread Message Delta"); + break; + case RunStreamEvent.ThreadRunCompleted: + console.log("Thread Run Completed"); + break + } } - assert.isNotNull(buffer); - assert.isNotNull(stream); + assert.isTrue(hasEventMessages); + assert.isNotNull(streamEventMessages); }); }); diff --git a/sdk/ai/ai-projects/tsconfig.json b/sdk/ai/ai-projects/tsconfig.json index d126ebb8f366..1b604c7d40b8 100644 --- a/sdk/ai/ai-projects/tsconfig.json +++ b/sdk/ai/ai-projects/tsconfig.json @@ -4,7 +4,8 @@ "module": "NodeNext", "moduleResolution": "NodeNext", "rootDir": ".", - "skipLibCheck": true + "skipLibCheck": true, + "paths": { "@azure/ai-projects": ["./src/index"] } }, "include": ["./src/**/*.ts", "./src/**/*.mts", "./src/**/*.cts", "test/**/*.ts", "src/**/*.ts", "samples-dev/**/*.ts"] } From afc73806812e3735c780582b37afdf4f6862d364 Mon Sep 17 00:00:00 2001 From: Ganesh Bheemarasetty Date: Fri, 8 Nov 2024 12:25:12 -0800 Subject: [PATCH 4/4] Update sample text --- sdk/ai/ai-projects/samples-dev/agents/streaming.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/ai/ai-projects/samples-dev/agents/streaming.ts b/sdk/ai/ai-projects/samples-dev/agents/streaming.ts index 4b8e664039bd..1c7b4a776a18 100644 --- a/sdk/ai/ai-projects/samples-dev/agents/streaming.ts +++ b/sdk/ai/ai-projects/samples-dev/agents/streaming.ts @@ -37,8 +37,8 @@ export async function main(): Promise { messageDelta.delta.content.forEach((contentPart) => { if (contentPart.type === "text") { const textContent = contentPart as MessageDeltaTextContent - const textValue = textContent.text || "No text" - console.log(`ext delta received:: ${textValue}`) + const textValue = textContent.text?.value || "No text" + console.log(`Text delta received:: ${textValue}`) } }); }