From 5745e7e9115f333c3dce6aa6a666668ac894a0f0 Mon Sep 17 00:00:00 2001 From: Xi Yan Date: Fri, 31 Jan 2025 12:27:42 -0800 Subject: [PATCH 1/2] Sync updates from stainless branch: yanxi0830/dev --- src/index.ts | 7 +- src/resources/agents/agents.ts | 4 +- src/resources/agents/index.ts | 2 +- src/resources/agents/turn.ts | 69 +++++++++--- src/resources/batch-inference.ts | 17 +-- src/resources/index.ts | 3 +- src/resources/inference.ts | 136 ++++++++---------------- src/resources/shared.ts | 78 ++++++++++++++ tests/api-resources/agents/turn.test.ts | 6 +- tests/api-resources/inference.test.ts | 12 +-- 10 files changed, 192 insertions(+), 142 deletions(-) diff --git a/src/index.ts b/src/index.ts index 72d8e1f..8a8a7ee 100644 --- a/src/index.ts +++ b/src/index.ts @@ -33,17 +33,16 @@ import { ListEvalTasksResponse, } from './resources/eval-tasks'; import { + ChatCompletionResponseStreamChunk, CompletionResponse, EmbeddingsResponse, Inference, InferenceChatCompletionParams, InferenceChatCompletionParamsNonStreaming, InferenceChatCompletionParamsStreaming, - InferenceChatCompletionResponse, InferenceCompletionParams, InferenceCompletionParamsNonStreaming, InferenceCompletionParamsStreaming, - InferenceCompletionResponse, InferenceEmbeddingsParams, TokenLogProbs, } from './resources/inference'; @@ -407,11 +406,10 @@ export declare namespace LlamaStackClient { export { Inference as Inference, + type ChatCompletionResponseStreamChunk as ChatCompletionResponseStreamChunk, type CompletionResponse as CompletionResponse, type EmbeddingsResponse as EmbeddingsResponse, type TokenLogProbs as TokenLogProbs, - type InferenceChatCompletionResponse as InferenceChatCompletionResponse, - type InferenceCompletionResponse as InferenceCompletionResponse, type InferenceChatCompletionParams as InferenceChatCompletionParams, type InferenceChatCompletionParamsNonStreaming as InferenceChatCompletionParamsNonStreaming, type InferenceChatCompletionParamsStreaming as InferenceChatCompletionParamsStreaming, @@ -538,6 +536,7 @@ export declare namespace LlamaStackClient { export type AgentConfig = API.AgentConfig; export type BatchCompletion = API.BatchCompletion; + export type ChatCompletionResponse = API.ChatCompletionResponse; export type CompletionMessage = API.CompletionMessage; export type ContentDelta = API.ContentDelta; export type Document = API.Document; diff --git a/src/resources/agents/agents.ts b/src/resources/agents/agents.ts index ce2ad08..633f3c9 100644 --- a/src/resources/agents/agents.ts +++ b/src/resources/agents/agents.ts @@ -15,11 +15,11 @@ import * as StepsAPI from './steps'; import { StepRetrieveResponse, Steps } from './steps'; import * as TurnAPI from './turn'; import { + AgentTurnResponseStreamChunk, Turn, TurnCreateParams, TurnCreateParamsNonStreaming, TurnCreateParamsStreaming, - TurnCreateResponse, TurnResource, TurnResponseEvent, TurnResponseEventPayload, @@ -145,10 +145,10 @@ export declare namespace Agents { export { TurnResource as TurnResource, + type AgentTurnResponseStreamChunk as AgentTurnResponseStreamChunk, type Turn as Turn, type TurnResponseEvent as TurnResponseEvent, type TurnResponseEventPayload as TurnResponseEventPayload, - type TurnCreateResponse as TurnCreateResponse, type TurnCreateParams as TurnCreateParams, type TurnCreateParamsNonStreaming as TurnCreateParamsNonStreaming, type TurnCreateParamsStreaming as TurnCreateParamsStreaming, diff --git a/src/resources/agents/index.ts b/src/resources/agents/index.ts index e02c3b6..c6053b9 100644 --- a/src/resources/agents/index.ts +++ b/src/resources/agents/index.ts @@ -20,10 +20,10 @@ export { export { Steps, type StepRetrieveResponse } from './steps'; export { TurnResource, + type AgentTurnResponseStreamChunk, type Turn, type TurnResponseEvent, type TurnResponseEventPayload, - type TurnCreateResponse, type TurnCreateParams, type TurnCreateParamsNonStreaming, type TurnCreateParamsStreaming, diff --git a/src/resources/agents/turn.ts b/src/resources/agents/turn.ts index 6f63d18..6b13388 100644 --- a/src/resources/agents/turn.ts +++ b/src/resources/agents/turn.ts @@ -14,31 +14,30 @@ export class TurnResource extends APIResource { sessionId: string, body: TurnCreateParamsNonStreaming, options?: Core.RequestOptions, - ): APIPromise; + ): APIPromise; create( agentId: string, sessionId: string, body: TurnCreateParamsStreaming, options?: Core.RequestOptions, - ): APIPromise>; + ): APIPromise>; create( agentId: string, sessionId: string, body: TurnCreateParamsBase, options?: Core.RequestOptions, - ): APIPromise | TurnCreateResponse>; + ): APIPromise | Turn>; create( agentId: string, sessionId: string, body: TurnCreateParams, options?: Core.RequestOptions, - ): APIPromise | APIPromise> { + ): APIPromise | APIPromise> { return this._client.post(`/v1/agents/${agentId}/session/${sessionId}/turn`, { body, ...options, - headers: { Accept: 'text/event-stream', ...options?.headers }, stream: body.stream ?? false, - }) as APIPromise | APIPromise>; + }) as APIPromise | APIPromise>; } retrieve( @@ -51,6 +50,10 @@ export class TurnResource extends APIResource { } } +export interface AgentTurnResponseStreamChunk { + event: TurnResponseEvent; +} + export interface Turn { input_messages: Array; @@ -88,22 +91,44 @@ export namespace Turn { export namespace OutputAttachment { export interface ImageContentItem { + /** + * Image as a base64 encoded string or an URL + */ image: ImageContentItem.Image; + /** + * Discriminator type of the content item. Always "image" + */ type: 'image'; } export namespace ImageContentItem { + /** + * Image as a base64 encoded string or an URL + */ export interface Image { + /** + * base64 encoded image data as string + */ data?: string; + /** + * A URL of the image or data URL in the format of data:image/{type};base64,{data}. + * Note that URL could have length limits. + */ url?: Shared.URL; } } export interface TextContentItem { + /** + * Text content + */ text: string; + /** + * Discriminator type of the content item. Always "text" + */ type: 'text'; } } @@ -168,14 +193,6 @@ export namespace TurnResponseEventPayload { } } -export type TurnCreateResponse = Turn | TurnCreateResponse.AgentTurnResponseStreamChunk; - -export namespace TurnCreateResponse { - export interface AgentTurnResponseStreamChunk { - event: TurnAPI.TurnResponseEvent; - } -} - export type TurnCreateParams = TurnCreateParamsNonStreaming | TurnCreateParamsStreaming; export interface TurnCreateParamsBase { @@ -202,22 +219,44 @@ export namespace TurnCreateParams { export namespace Document { export interface ImageContentItem { + /** + * Image as a base64 encoded string or an URL + */ image: ImageContentItem.Image; + /** + * Discriminator type of the content item. Always "image" + */ type: 'image'; } export namespace ImageContentItem { + /** + * Image as a base64 encoded string or an URL + */ export interface Image { + /** + * base64 encoded image data as string + */ data?: string; + /** + * A URL of the image or data URL in the format of data:image/{type};base64,{data}. + * Note that URL could have length limits. + */ url?: Shared.URL; } } export interface TextContentItem { + /** + * Text content + */ text: string; + /** + * Discriminator type of the content item. Always "text" + */ type: 'text'; } } @@ -242,10 +281,10 @@ export interface TurnCreateParamsStreaming extends TurnCreateParamsBase { export declare namespace TurnResource { export { + type AgentTurnResponseStreamChunk as AgentTurnResponseStreamChunk, type Turn as Turn, type TurnResponseEvent as TurnResponseEvent, type TurnResponseEventPayload as TurnResponseEventPayload, - type TurnCreateResponse as TurnCreateResponse, type TurnCreateParams as TurnCreateParams, type TurnCreateParamsNonStreaming as TurnCreateParamsNonStreaming, type TurnCreateParamsStreaming as TurnCreateParamsStreaming, diff --git a/src/resources/batch-inference.ts b/src/resources/batch-inference.ts index 46b89d2..9f99274 100644 --- a/src/resources/batch-inference.ts +++ b/src/resources/batch-inference.ts @@ -2,7 +2,6 @@ import { APIResource } from '../resource'; import * as Core from '../core'; -import * as InferenceAPI from './inference'; import * as Shared from './shared'; export class BatchInference extends APIResource { @@ -22,21 +21,7 @@ export class BatchInference extends APIResource { } export interface BatchInferenceChatCompletionResponse { - batch: Array; -} - -export namespace BatchInferenceChatCompletionResponse { - export interface Batch { - /** - * The complete response message - */ - completion_message: Shared.CompletionMessage; - - /** - * Optional log probabilities for generated tokens - */ - logprobs?: Array; - } + batch: Array; } export interface BatchInferenceChatCompletionParams { diff --git a/src/resources/index.ts b/src/resources/index.ts index 77e90a5..b809d8c 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -48,11 +48,10 @@ export { } from './eval-tasks'; export { Inference, + type ChatCompletionResponseStreamChunk, type CompletionResponse, type EmbeddingsResponse, type TokenLogProbs, - type InferenceChatCompletionResponse, - type InferenceCompletionResponse, type InferenceChatCompletionParams, type InferenceChatCompletionParamsNonStreaming, type InferenceChatCompletionParamsStreaming, diff --git a/src/resources/inference.ts b/src/resources/inference.ts index a281f90..7dc59c7 100644 --- a/src/resources/inference.ts +++ b/src/resources/inference.ts @@ -14,25 +14,24 @@ export class Inference extends APIResource { chatCompletion( body: InferenceChatCompletionParamsNonStreaming, options?: Core.RequestOptions, - ): APIPromise; + ): APIPromise; chatCompletion( body: InferenceChatCompletionParamsStreaming, options?: Core.RequestOptions, - ): APIPromise>; + ): APIPromise>; chatCompletion( body: InferenceChatCompletionParamsBase, options?: Core.RequestOptions, - ): APIPromise | InferenceChatCompletionResponse>; + ): APIPromise | Shared.ChatCompletionResponse>; chatCompletion( body: InferenceChatCompletionParams, options?: Core.RequestOptions, - ): APIPromise | APIPromise> { + ): APIPromise | APIPromise> { return this._client.post('/v1/inference/chat-completion', { body, ...options, - headers: { Accept: 'text/event-stream', ...options?.headers }, stream: body.stream ?? false, - }) as APIPromise | APIPromise>; + }) as APIPromise | APIPromise>; } /** @@ -41,25 +40,24 @@ export class Inference extends APIResource { completion( body: InferenceCompletionParamsNonStreaming, options?: Core.RequestOptions, - ): APIPromise; + ): APIPromise; completion( body: InferenceCompletionParamsStreaming, options?: Core.RequestOptions, - ): APIPromise>; + ): APIPromise>; completion( body: InferenceCompletionParamsBase, options?: Core.RequestOptions, - ): APIPromise | InferenceCompletionResponse>; + ): APIPromise | CompletionResponse>; completion( body: InferenceCompletionParams, options?: Core.RequestOptions, - ): APIPromise | APIPromise> { + ): APIPromise | APIPromise> { return this._client.post('/v1/inference/completion', { body, ...options, - headers: { Accept: 'text/event-stream', ...options?.headers }, stream: body.stream ?? false, - }) as APIPromise | APIPromise>; + }) as APIPromise | APIPromise>; } /** @@ -73,6 +71,41 @@ export class Inference extends APIResource { } } +export interface ChatCompletionResponseStreamChunk { + /** + * The event containing the new content + */ + event: ChatCompletionResponseStreamChunk.Event; +} + +export namespace ChatCompletionResponseStreamChunk { + /** + * The event containing the new content + */ + export interface Event { + /** + * Content generated since last event. This can be one or more tokens, or a tool + * call. + */ + delta: Shared.ContentDelta; + + /** + * Type of the event + */ + event_type: 'start' | 'complete' | 'progress'; + + /** + * Optional log probabilities for generated tokens + */ + logprobs?: Array; + + /** + * Optional reason why generation stopped, if complete + */ + stop_reason?: 'end_of_turn' | 'end_of_message' | 'out_of_tokens'; + } +} + export interface CompletionResponse { /** * The generated completion text @@ -106,82 +139,6 @@ export interface TokenLogProbs { logprobs_by_token: Record; } -export type InferenceChatCompletionResponse = - | InferenceChatCompletionResponse.ChatCompletionResponse - | InferenceChatCompletionResponse.ChatCompletionResponseStreamChunk; - -export namespace InferenceChatCompletionResponse { - export interface ChatCompletionResponse { - /** - * The complete response message - */ - completion_message: Shared.CompletionMessage; - - /** - * Optional log probabilities for generated tokens - */ - logprobs?: Array; - } - - export interface ChatCompletionResponseStreamChunk { - /** - * The event containing the new content - */ - event: ChatCompletionResponseStreamChunk.Event; - } - - export namespace ChatCompletionResponseStreamChunk { - /** - * The event containing the new content - */ - export interface Event { - /** - * Content generated since last event. This can be one or more tokens, or a tool - * call. - */ - delta: Shared.ContentDelta; - - /** - * Type of the event - */ - event_type: 'start' | 'complete' | 'progress'; - - /** - * Optional log probabilities for generated tokens - */ - logprobs?: Array; - - /** - * Optional reason why generation stopped, if complete - */ - stop_reason?: 'end_of_turn' | 'end_of_message' | 'out_of_tokens'; - } - } -} - -export type InferenceCompletionResponse = - | CompletionResponse - | InferenceCompletionResponse.CompletionResponseStreamChunk; - -export namespace InferenceCompletionResponse { - export interface CompletionResponseStreamChunk { - /** - * New content generated since last chunk. This can be one or more tokens. - */ - delta: string; - - /** - * Optional log probabilities for generated tokens - */ - logprobs?: Array; - - /** - * Optional reason why generation stopped, if complete - */ - stop_reason?: 'end_of_turn' | 'end_of_message' | 'out_of_tokens'; - } -} - export type InferenceChatCompletionParams = | InferenceChatCompletionParamsNonStreaming | InferenceChatCompletionParamsStreaming; @@ -374,11 +331,10 @@ export interface InferenceEmbeddingsParams { export declare namespace Inference { export { + type ChatCompletionResponseStreamChunk as ChatCompletionResponseStreamChunk, type CompletionResponse as CompletionResponse, type EmbeddingsResponse as EmbeddingsResponse, type TokenLogProbs as TokenLogProbs, - type InferenceChatCompletionResponse as InferenceChatCompletionResponse, - type InferenceCompletionResponse as InferenceCompletionResponse, type InferenceChatCompletionParams as InferenceChatCompletionParams, type InferenceChatCompletionParamsNonStreaming as InferenceChatCompletionParamsNonStreaming, type InferenceChatCompletionParamsStreaming as InferenceChatCompletionParamsStreaming, diff --git a/src/resources/shared.ts b/src/resources/shared.ts index 4eea2de..d236d3c 100644 --- a/src/resources/shared.ts +++ b/src/resources/shared.ts @@ -42,6 +42,18 @@ export interface BatchCompletion { batch: Array; } +export interface ChatCompletionResponse { + /** + * The complete response message + */ + completion_message: CompletionMessage; + + /** + * Optional log probabilities for generated tokens + */ + logprobs?: Array; +} + export interface CompletionMessage { /** * The content of the model's response @@ -110,22 +122,44 @@ export interface Document { export namespace Document { export interface ImageContentItem { + /** + * Image as a base64 encoded string or an URL + */ image: ImageContentItem.Image; + /** + * Discriminator type of the content item. Always "image" + */ type: 'image'; } export namespace ImageContentItem { + /** + * Image as a base64 encoded string or an URL + */ export interface Image { + /** + * base64 encoded image data as string + */ data?: string; + /** + * A URL of the image or data URL in the format of data:image/{type};base64,{data}. + * Note that URL could have length limits. + */ url?: Shared.URL; } } export interface TextContentItem { + /** + * Text content + */ text: string; + /** + * Discriminator type of the content item. Always "text" + */ type: 'text'; } } @@ -138,22 +172,44 @@ export type InterleavedContent = export namespace InterleavedContent { export interface ImageContentItem { + /** + * Image as a base64 encoded string or an URL + */ image: ImageContentItem.Image; + /** + * Discriminator type of the content item. Always "image" + */ type: 'image'; } export namespace ImageContentItem { + /** + * Image as a base64 encoded string or an URL + */ export interface Image { + /** + * base64 encoded image data as string + */ data?: string; + /** + * A URL of the image or data URL in the format of data:image/{type};base64,{data}. + * Note that URL could have length limits. + */ url?: Shared.URL; } } export interface TextContentItem { + /** + * Text content + */ text: string; + /** + * Discriminator type of the content item. Always "text" + */ type: 'text'; } } @@ -164,22 +220,44 @@ export type InterleavedContentItem = export namespace InterleavedContentItem { export interface ImageContentItem { + /** + * Image as a base64 encoded string or an URL + */ image: ImageContentItem.Image; + /** + * Discriminator type of the content item. Always "image" + */ type: 'image'; } export namespace ImageContentItem { + /** + * Image as a base64 encoded string or an URL + */ export interface Image { + /** + * base64 encoded image data as string + */ data?: string; + /** + * A URL of the image or data URL in the format of data:image/{type};base64,{data}. + * Note that URL could have length limits. + */ url?: Shared.URL; } } export interface TextContentItem { + /** + * Text content + */ text: string; + /** + * Discriminator type of the content item. Always "text" + */ type: 'text'; } } diff --git a/tests/api-resources/agents/turn.test.ts b/tests/api-resources/agents/turn.test.ts index 6d53271..62394a9 100644 --- a/tests/api-resources/agents/turn.test.ts +++ b/tests/api-resources/agents/turn.test.ts @@ -6,8 +6,7 @@ import { Response } from 'node-fetch'; const client = new LlamaStackClient({ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010' }); describe('resource turn', () => { - // skipped: currently no good way to test endpoints with content type text/event-stream, Prism mock server will fail - test.skip('create: only required params', async () => { + test('create: only required params', async () => { const responsePromise = client.agents.turn.create('agent_id', 'session_id', { messages: [{ content: 'string', role: 'user' }], }); @@ -20,8 +19,7 @@ describe('resource turn', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // skipped: currently no good way to test endpoints with content type text/event-stream, Prism mock server will fail - test.skip('create: required and optional params', async () => { + test('create: required and optional params', async () => { const response = await client.agents.turn.create('agent_id', 'session_id', { messages: [{ content: 'string', role: 'user', context: 'string' }], documents: [{ content: 'string', mime_type: 'mime_type' }], diff --git a/tests/api-resources/inference.test.ts b/tests/api-resources/inference.test.ts index 8b17494..7842628 100644 --- a/tests/api-resources/inference.test.ts +++ b/tests/api-resources/inference.test.ts @@ -6,8 +6,7 @@ import { Response } from 'node-fetch'; const client = new LlamaStackClient({ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010' }); describe('resource inference', () => { - // skipped: currently no good way to test endpoints with content type text/event-stream, Prism mock server will fail - test.skip('chatCompletion: only required params', async () => { + test('chatCompletion: only required params', async () => { const responsePromise = client.inference.chatCompletion({ messages: [{ content: 'string', role: 'user' }], model_id: 'model_id', @@ -21,8 +20,7 @@ describe('resource inference', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // skipped: currently no good way to test endpoints with content type text/event-stream, Prism mock server will fail - test.skip('chatCompletion: required and optional params', async () => { + test('chatCompletion: required and optional params', async () => { const response = await client.inference.chatCompletion({ messages: [{ content: 'string', role: 'user', context: 'string' }], model_id: 'model_id', @@ -44,8 +42,7 @@ describe('resource inference', () => { }); }); - // skipped: currently no good way to test endpoints with content type text/event-stream, Prism mock server will fail - test.skip('completion: only required params', async () => { + test('completion: only required params', async () => { const responsePromise = client.inference.completion({ content: 'string', model_id: 'model_id' }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -56,8 +53,7 @@ describe('resource inference', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // skipped: currently no good way to test endpoints with content type text/event-stream, Prism mock server will fail - test.skip('completion: required and optional params', async () => { + test('completion: required and optional params', async () => { const response = await client.inference.completion({ content: 'string', model_id: 'model_id', From ea4146c20524c905d661b934ff9d6001d11da5d2 Mon Sep 17 00:00:00 2001 From: Xi Yan Date: Fri, 31 Jan 2025 12:33:43 -0800 Subject: [PATCH 2/2] add examples --- examples/agents.ts | 2 +- examples/inference.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/agents.ts b/examples/agents.ts index 171b570..d99d92c 100755 --- a/examples/agents.ts +++ b/examples/agents.ts @@ -2,7 +2,7 @@ import { AgentConfig } from "llama-stack-client/resources/shared"; -const LlamaStackClient = require('llama-stack-client').default; +import LlamaStackClient from 'llama-stack-client'; const client = new LlamaStackClient({ baseURL: 'http://localhost:8321' }); async function main() { diff --git a/examples/inference.ts b/examples/inference.ts index 1ee19ba..6339cba 100755 --- a/examples/inference.ts +++ b/examples/inference.ts @@ -1,6 +1,6 @@ #!/usr/bin/env -S npm run tsn -T -const LlamaStackClient = require('llama-stack-client').default; +import LlamaStackClient from 'llama-stack-client'; const client = new LlamaStackClient({ baseURL: 'http://localhost:8321' }); async function main() { @@ -22,7 +22,9 @@ async function main() { stream: true, }); for await (const chunk of stream) { - process.stdout.write(chunk.event.delta.text || ''); + if (chunk.event.delta.type === 'text') { + process.stdout.write(chunk.event.delta.text || ''); + } } process.stdout.write('\n'); }