diff --git a/.gitignore b/.gitignore index 46e455750..46b08ea9c 100644 --- a/.gitignore +++ b/.gitignore @@ -144,6 +144,8 @@ apps/stage-tamagotchi/electron.vite.config.*.mjs docs/ai/context/verifications/ .playwright-mcp/ .vishot/ +.alint/ +.alintcache # Generated from packages/i18n/glossary/terms.yaml at upload time. Never committed, so it # cannot drift from its source. diff --git a/packages/core-agent/src/runtime/llm-service.test.ts b/packages/core-agent/src/runtime/llm-service.test.ts index 78f678441..5c7f2ea39 100644 --- a/packages/core-agent/src/runtime/llm-service.test.ts +++ b/packages/core-agent/src/runtime/llm-service.test.ts @@ -29,7 +29,7 @@ const provider = { function createMockStreamResult( steps: Promise = Promise.resolve([]), - totalUsage: Promise<{ prompt_tokens: number, completion_tokens: number, total_tokens: number } | undefined> = Promise.resolve(undefined), + totalUsage: Promise<{ inputTokens: number, outputTokens: number, totalTokens: number } | undefined> = Promise.resolve(undefined), ) { return { steps, @@ -44,7 +44,7 @@ describe('streamFrom tool error capture', () => { const onUsage = vi.fn() streamTextMock.mockReturnValueOnce(createMockStreamResult( Promise.resolve([]), - Promise.resolve({ prompt_tokens: 12, completion_tokens: 8, total_tokens: 20 }), + Promise.resolve({ inputTokens: 12, outputTokens: 8, totalTokens: 20 }), )) await streamFrom({ @@ -84,7 +84,7 @@ describe('streamFrom tool error capture', () => { const onUsage = vi.fn() streamTextMock.mockReturnValueOnce(createMockStreamResult( Promise.resolve([]), - Promise.resolve({} as { prompt_tokens: number, completion_tokens: number, total_tokens: number }), + Promise.resolve({} as { inputTokens: number, outputTokens: number, totalTokens: number }), )) await streamFrom({ diff --git a/packages/core-agent/src/runtime/llm-service.ts b/packages/core-agent/src/runtime/llm-service.ts index 84c5fe86c..2287d807d 100644 --- a/packages/core-agent/src/runtime/llm-service.ts +++ b/packages/core-agent/src/runtime/llm-service.ts @@ -114,14 +114,14 @@ function createCapturedToolErrorResult(toolName: string, error: unknown): string } function normalizeUsage(usage: Usage | undefined) { - if (!usage || (usage.prompt_tokens == null && usage.completion_tokens == null && usage.total_tokens == null)) { + if (usage?.inputTokens == null || usage.outputTokens == null || usage.totalTokens == null) { return { source: 'unavailable' as const } } return { - inputTokens: usage.prompt_tokens, - outputTokens: usage.completion_tokens, - totalTokens: usage.total_tokens, + inputTokens: usage.inputTokens, + outputTokens: usage.outputTokens, + totalTokens: usage.totalTokens, source: 'reported' as const, } } @@ -241,6 +241,7 @@ export async function streamFrom({ // chat body, so unknown runtime-only fields can be rejected upstream. // AIRI captures tool failures by wrapping local tool executors instead. tools: streamTools, + toolChoice: options?.toolChoice, onEvent, }) diff --git a/packages/core-agent/src/types/llm.ts b/packages/core-agent/src/types/llm.ts index 2f93f8432..01e7be02c 100644 --- a/packages/core-agent/src/types/llm.ts +++ b/packages/core-agent/src/types/llm.ts @@ -1,5 +1,5 @@ import type { ChatProvider } from '@xsai-ext/providers/utils' -import type { CommonContentPart, CompletionToolCall, CompletionToolResult, Message, Tool } from '@xsai/shared-chat' +import type { CommonContentPart, CompletionToolCall, CompletionToolResult, Message, Tool, ToolChoice } from '@xsai/shared-chat' /** Describes whether generation usage came from the provider or a local fallback. */ export type LlmUsageSource = 'reported' | 'estimated' | 'unavailable' @@ -36,6 +36,8 @@ export interface StreamOptions { supportsTools?: boolean waitForTools?: boolean captureToolErrors?: boolean + /** Provider tool-selection directive for one request. */ + toolChoice?: ToolChoice tools?: Tool[] | (() => Promise) /** * Per-model runtime cache of whether the provider accepts content-part arrays diff --git a/packages/stage-pages/src/components/settings-general-fields.vue b/packages/stage-pages/src/components/settings-general-fields.vue index 9f6e70f27..84dd4a278 100644 --- a/packages/stage-pages/src/components/settings-general-fields.vue +++ b/packages/stage-pages/src/components/settings-general-fields.vue @@ -1,7 +1,7 @@