diff --git a/package-lock.json b/package-lock.json index a86653ed..db83d925 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2716,10 +2716,10 @@ }, "packages/agent": { "name": "@mariozechner/pi-agent", - "version": "0.5.12", + "version": "0.5.13", "license": "MIT", "dependencies": { - "@mariozechner/pi-tui": "^0.5.11", + "@mariozechner/pi-tui": "^0.5.12", "@types/glob": "^8.1.0", "chalk": "^5.5.0", "glob": "^11.0.3", @@ -3098,7 +3098,7 @@ }, "packages/ai": { "name": "@mariozechner/pi-ai", - "version": "0.5.12", + "version": "0.5.13", "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "^0.60.0", @@ -3134,10 +3134,10 @@ }, "packages/pods": { "name": "@mariozechner/pi", - "version": "0.5.12", + "version": "0.5.13", "license": "MIT", "dependencies": { - "@mariozechner/pi-agent": "^0.5.11", + "@mariozechner/pi-agent": "^0.5.12", "chalk": "^5.5.0" }, "bin": { @@ -3150,7 +3150,7 @@ }, "packages/tui": { "name": "@mariozechner/pi-tui", - "version": "0.5.12", + "version": "0.5.13", "license": "MIT", "dependencies": { "@types/mime-types": "^2.1.4", diff --git a/packages/agent/package-lock.json b/packages/agent/package-lock.json index 164b02e3..dac489b2 100644 --- a/packages/agent/package-lock.json +++ b/packages/agent/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mariozechner/pi-agent", - "version": "0.5.12", + "version": "0.5.13", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mariozechner/pi-agent", - "version": "0.5.12", + "version": "0.5.13", "license": "MIT", "dependencies": { "@mariozechner/tui": "^0.1.1", diff --git a/packages/agent/package.json b/packages/agent/package.json index 98cf5316..51e31e5a 100644 --- a/packages/agent/package.json +++ b/packages/agent/package.json @@ -1,6 +1,6 @@ { "name": "@mariozechner/pi-agent", - "version": "0.5.12", + "version": "0.5.13", "description": "General-purpose agent with tool calling and session persistence", "type": "module", "bin": { @@ -18,7 +18,7 @@ "prepublishOnly": "npm run clean && npm run build" }, "dependencies": { - "@mariozechner/pi-tui": "^0.5.12", + "@mariozechner/pi-tui": "^0.5.13", "@types/glob": "^8.1.0", "chalk": "^5.5.0", "glob": "^11.0.3", diff --git a/packages/ai/package.json b/packages/ai/package.json index 05ba8527..c00cc282 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "@mariozechner/pi-ai", - "version": "0.5.12", + "version": "0.5.13", "description": "Unified LLM API with automatic model discovery and provider configuration", "type": "module", "main": "./dist/index.js", diff --git a/packages/ai/src/models.generated.ts b/packages/ai/src/models.generated.ts index 0027fbe3..a92a077c 100644 --- a/packages/ai/src/models.generated.ts +++ b/packages/ai/src/models.generated.ts @@ -1598,22 +1598,6 @@ export const PROVIDERS = { contextWindow: 131072, maxTokens: 16384, } satisfies Model, - "meta-llama/llama-3.1-405b-instruct": { - id: "meta-llama/llama-3.1-405b-instruct", - name: "Meta: Llama 3.1 405B Instruct", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - reasoning: false, - input: ["text"], - cost: { - input: 0.7999999999999999, - output: 0.7999999999999999, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 32768, - maxTokens: 16384, - } satisfies Model, "meta-llama/llama-3.1-70b-instruct": { id: "meta-llama/llama-3.1-70b-instruct", name: "Meta: Llama 3.1 70B Instruct", @@ -1630,6 +1614,22 @@ export const PROVIDERS = { contextWindow: 131072, maxTokens: 16384, } satisfies Model, + "meta-llama/llama-3.1-405b-instruct": { + id: "meta-llama/llama-3.1-405b-instruct", + name: "Meta: Llama 3.1 405B Instruct", + provider: "openrouter", + baseUrl: "https://openrouter.ai/api/v1", + reasoning: false, + input: ["text"], + cost: { + input: 0.7999999999999999, + output: 0.7999999999999999, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 32768, + maxTokens: 16384, + } satisfies Model, "mistralai/mistral-nemo": { id: "mistralai/mistral-nemo", name: "Mistral: Mistral Nemo", @@ -1646,6 +1646,22 @@ export const PROVIDERS = { contextWindow: 32000, maxTokens: 4096, } satisfies Model, + "mistralai/mistral-7b-instruct-v0.3": { + id: "mistralai/mistral-7b-instruct-v0.3", + name: "Mistral: Mistral 7B Instruct v0.3", + provider: "openrouter", + baseUrl: "https://openrouter.ai/api/v1", + reasoning: false, + input: ["text"], + cost: { + input: 0.028, + output: 0.054, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 32768, + maxTokens: 16384, + } satisfies Model, "mistralai/mistral-7b-instruct:free": { id: "mistralai/mistral-7b-instruct:free", name: "Mistral: Mistral 7B Instruct (free)", @@ -1678,22 +1694,6 @@ export const PROVIDERS = { contextWindow: 32768, maxTokens: 16384, } satisfies Model, - "mistralai/mistral-7b-instruct-v0.3": { - id: "mistralai/mistral-7b-instruct-v0.3", - name: "Mistral: Mistral 7B Instruct v0.3", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - reasoning: false, - input: ["text"], - cost: { - input: 0.028, - output: 0.054, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 32768, - maxTokens: 16384, - } satisfies Model, "microsoft/phi-3-mini-128k-instruct": { id: "microsoft/phi-3-mini-128k-instruct", name: "Microsoft: Phi-3 Mini 128K Instruct", @@ -1726,22 +1726,6 @@ export const PROVIDERS = { contextWindow: 128000, maxTokens: 4096, } satisfies Model, - "meta-llama/llama-3-8b-instruct": { - id: "meta-llama/llama-3-8b-instruct", - name: "Meta: Llama 3 8B Instruct", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - reasoning: false, - input: ["text"], - cost: { - input: 0.03, - output: 0.06, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 8192, - maxTokens: 16384, - } satisfies Model, "meta-llama/llama-3-70b-instruct": { id: "meta-llama/llama-3-70b-instruct", name: "Meta: Llama 3 70B Instruct", @@ -1758,6 +1742,22 @@ export const PROVIDERS = { contextWindow: 8192, maxTokens: 16384, } satisfies Model, + "meta-llama/llama-3-8b-instruct": { + id: "meta-llama/llama-3-8b-instruct", + name: "Meta: Llama 3 8B Instruct", + provider: "openrouter", + baseUrl: "https://openrouter.ai/api/v1", + reasoning: false, + input: ["text"], + cost: { + input: 0.03, + output: 0.06, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 8192, + maxTokens: 16384, + } satisfies Model, "mistralai/mixtral-8x22b-instruct": { id: "mistralai/mixtral-8x22b-instruct", name: "Mistral: Mixtral 8x22B Instruct", @@ -1854,22 +1854,6 @@ export const PROVIDERS = { contextWindow: 128000, maxTokens: 4096, } satisfies Model, - "mistralai/mistral-small": { - id: "mistralai/mistral-small", - name: "Mistral Small", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - reasoning: false, - input: ["text"], - cost: { - input: 0.19999999999999998, - output: 0.6, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 32768, - maxTokens: 4096, - } satisfies Model, "mistralai/mistral-tiny": { id: "mistralai/mistral-tiny", name: "Mistral Tiny", @@ -1886,6 +1870,22 @@ export const PROVIDERS = { contextWindow: 32768, maxTokens: 4096, } satisfies Model, + "mistralai/mistral-small": { + id: "mistralai/mistral-small", + name: "Mistral Small", + provider: "openrouter", + baseUrl: "https://openrouter.ai/api/v1", + reasoning: false, + input: ["text"], + cost: { + input: 0.19999999999999998, + output: 0.6, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 32768, + maxTokens: 4096, + } satisfies Model, "mistralai/mixtral-8x7b-instruct": { id: "mistralai/mixtral-8x7b-instruct", name: "Mistral: Mixtral 8x7B Instruct", @@ -2473,21 +2473,6 @@ export const PROVIDERS = { contextWindow: 16385, maxTokens: 4096, } satisfies Model, - "gpt-3.5-turbo": { - id: "gpt-3.5-turbo", - name: "OpenAI: GPT-3.5 Turbo", - provider: "openai", - reasoning: false, - input: ["text"], - cost: { - input: 0.5, - output: 1.5, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 16385, - maxTokens: 4096, - } satisfies Model, "gpt-4": { id: "gpt-4", name: "OpenAI: GPT-4", @@ -2518,6 +2503,21 @@ export const PROVIDERS = { contextWindow: 8191, maxTokens: 4096, } satisfies Model, + "gpt-3.5-turbo": { + id: "gpt-3.5-turbo", + name: "OpenAI: GPT-3.5 Turbo", + provider: "openai", + reasoning: false, + input: ["text"], + cost: { + input: 0.5, + output: 1.5, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 16385, + maxTokens: 4096, + } satisfies Model, }, }, anthropic: { @@ -2597,9 +2597,9 @@ export const PROVIDERS = { contextWindow: 200000, maxTokens: 64000, } satisfies Model, - "claude-3-5-haiku-latest": { - id: "claude-3-5-haiku-latest", - name: "Anthropic: Claude 3.5 Haiku", + "claude-3-5-haiku-20241022": { + id: "claude-3-5-haiku-20241022", + name: "Anthropic: Claude 3.5 Haiku (2024-10-22)", provider: "anthropic", reasoning: false, input: ["text", "image"], @@ -2612,9 +2612,9 @@ export const PROVIDERS = { contextWindow: 200000, maxTokens: 8192, } satisfies Model, - "claude-3-5-haiku-20241022": { - id: "claude-3-5-haiku-20241022", - name: "Anthropic: Claude 3.5 Haiku (2024-10-22)", + "claude-3-5-haiku-latest": { + id: "claude-3-5-haiku-latest", + name: "Anthropic: Claude 3.5 Haiku", provider: "anthropic", reasoning: false, input: ["text", "image"], diff --git a/packages/ai/src/providers/openai-responses.ts b/packages/ai/src/providers/openai-responses.ts index 5b27f0ea..79bdd8a2 100644 --- a/packages/ai/src/providers/openai-responses.ts +++ b/packages/ai/src/providers/openai-responses.ts @@ -8,6 +8,7 @@ import type { ResponseInputText, ResponseReasoningItem, } from "openai/resources/responses/responses.js"; +import type { ResponseOutputMessage } from "openai/resources/responses/responses.mjs"; import type { AssistantMessage, Context, @@ -83,6 +84,7 @@ export class OpenAIResponsesLLM implements LLM { }); let content = ""; + let contentSignature = ""; let thinking = ""; const toolCalls: ToolCall[] = []; const reasoningItems: ResponseReasoningItem[] = []; @@ -117,6 +119,7 @@ export class OpenAIResponsesLLM implements LLM { content = event.text; } options?.onText?.("", true); + contentSignature = event.item_id; } // Handle function calls else if (event.type === "response.output_item.done") { @@ -167,6 +170,7 @@ export class OpenAIResponsesLLM implements LLM { return { role: "assistant", content: content || undefined, + contentSignature: contentSignature || undefined, thinking: thinking || undefined, thinkingSignature: JSON.stringify(reasoningItems) || undefined, toolCalls: toolCalls.length > 0 ? toolCalls : undefined, @@ -257,8 +261,10 @@ export class OpenAIResponsesLLM implements LLM { output.push({ type: "message", role: "assistant", - content: [{ type: "input_text", text: msg.content }], - }); + content: [{ type: "output_text", text: msg.content, annotations: [] }], + status: "completed", + id: msg.contentSignature || "msg_" + Math.random().toString(36).substring(2, 15), + } satisfies ResponseOutputMessage); } // Add all output items to input input.push(...output); diff --git a/packages/ai/src/types.ts b/packages/ai/src/types.ts index b4b02f7f..4c75089a 100644 --- a/packages/ai/src/types.ts +++ b/packages/ai/src/types.ts @@ -33,6 +33,9 @@ export interface AssistantMessage { // Leaky abstraction: provider specific, does not translate to other providers thinkingSignature?: string; content?: string; + // Leaky abstraction: provider specific, does not translate to other providers + // e.g. OpenAI responses must include id for assistant responses + contentSignature?: string; toolCalls?: { id: string; name: string; diff --git a/packages/ai/test/providers.test.ts b/packages/ai/test/providers.test.ts index 7885a387..f9c2f2ab 100644 --- a/packages/ai/test/providers.test.ts +++ b/packages/ai/test/providers.test.ts @@ -48,6 +48,18 @@ async function basicTextGeneration(llm: LLM) { expect(response.usage.output).toBeGreaterThan(0); expect(response.error).toBeFalsy(); expect(response.content).toContain("Hello test successful"); + + context.messages.push(response); + context.messages.push({ role: "user", content: "Now say 'Goodbye test successful'" }); + + const secondResponse = await llm.complete(context); + + expect(secondResponse.role).toBe("assistant"); + expect(secondResponse.content).toBeTruthy(); + expect(secondResponse.usage.input).toBeGreaterThan(0); + expect(secondResponse.usage.output).toBeGreaterThan(0); + expect(secondResponse.error).toBeFalsy(); + expect(secondResponse.content).toContain("Goodbye test successful"); } async function handleToolCall(llm: LLM) { diff --git a/packages/pods/package-lock.json b/packages/pods/package-lock.json index b5b21362..dfb135e4 100644 --- a/packages/pods/package-lock.json +++ b/packages/pods/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mariozechner/pi", - "version": "0.5.12", + "version": "0.5.13", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mariozechner/pi", - "version": "0.5.12", + "version": "0.5.13", "license": "MIT", "dependencies": { "@ai-sdk/openai": "^2.0.5", diff --git a/packages/pods/package.json b/packages/pods/package.json index 5b231d62..de42e2d0 100644 --- a/packages/pods/package.json +++ b/packages/pods/package.json @@ -1,6 +1,6 @@ { "name": "@mariozechner/pi", - "version": "0.5.12", + "version": "0.5.13", "description": "CLI tool for managing vLLM deployments on GPU pods", "type": "module", "bin": { @@ -34,7 +34,7 @@ "node": ">=20.0.0" }, "dependencies": { - "@mariozechner/pi-agent": "^0.5.12", + "@mariozechner/pi-agent": "^0.5.13", "chalk": "^5.5.0" }, "devDependencies": {} diff --git a/packages/tui/package-lock.json b/packages/tui/package-lock.json index b73afa67..d499b1ff 100644 --- a/packages/tui/package-lock.json +++ b/packages/tui/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mariozechner/tui", - "version": "0.5.12", + "version": "0.5.13", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mariozechner/tui", - "version": "0.5.12", + "version": "0.5.13", "license": "MIT", "dependencies": { "@types/mime-types": "^2.1.4", diff --git a/packages/tui/package.json b/packages/tui/package.json index ccf7f62b..42614086 100644 --- a/packages/tui/package.json +++ b/packages/tui/package.json @@ -1,6 +1,6 @@ { "name": "@mariozechner/pi-tui", - "version": "0.5.12", + "version": "0.5.13", "description": "Terminal User Interface library with differential rendering for efficient text-based applications", "type": "module", "main": "dist/index.js",