@roll-agent/core 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{defineCommand as e}from"citty";import{loadConfig as t}from"../../config/loader.js";import{getAgentEnv as o}from"../../config/helpers.js";import{createProviderModel as s}from"../../llm/providers.js";import{McpClientManager as r}from"../../mcp/client-manager.js";import{AgentStore as n}from"../../registry/store.js";import{resolveTransportWithDevSpawnSpec as i}from"../../registry/dev-spawn.js";import{routeWithLLM as a}from"../../router/llm-router.js";import{extractToolInput as l}from"../../tool-runtime/argument-extractor.js";import{formatValidationIssuesMessage as c}from"../../tool-runtime/messages.js";import{preflightToolCall as m}from"../../tool-runtime/preflight.js";import{log as u}from"../utils/output.js";const d=.5;function f(e){if(!Array.isArray(e))return[];const t=[];for(const o of e)"object"==typeof o&&null!==o&&"type"in o&&"text"===o.type&&"text"in o&&"string"==typeof o.text&&t.push(o.text);return t}function g(e){return"object"==typeof e&&null!==e&&"isError"in e&&!0===e.isError}function p(e){console.log(JSON.stringify(e,null,2))}function y(e){const t=f("object"==typeof e.result&&null!==e.result&&"content"in e.result?e.result.content:void 0);for(const e of t)console.log(e)}export default e({meta:{description:"LLM 智能路由,自动选择 Agent 和 tool"},args:{message:{type:"positional",description:"自然语言消息",required:!0},json:{type:"boolean",description:"JSON 格式输出",default:!1}},async run({args:e}){const{config:j}=t(),x=new n(j.agents.dataDir).list();if(0===x.length)return u.error("暂无已注册的 Agent。可使用 `roll agent add <path>`、`roll agent install <package>` 或 `roll agent add --remote <endpoint>`。"),void(process.exitCode=1);const $=t=>{if(e.json)p(t);else if("success"===t.status)y(t)},v=j.llm.defaultProvider,N=j.ask.llmModel??j.llm.defaultModel,k=j.llm.providers[v];if(!k)return u.error(`LLM provider "${v}" 未配置。请检查 roll.config.yaml`),void(process.exitCode=1);const w=s(v,N,k.apiKey,k.baseUrl);let h;u.info(`分析意图: "${e.message}"`);try{h=await a(e.message,x,w)}catch(e){const t={status:"failed",stage:"route",message:`LLM 路由失败: ${e instanceof Error?e.message:String(e)}`};return u.error(t.message),$(t),void(process.exitCode=1)}u.info(`路由决策: ${h.agentName}.${h.toolName} (置信度: ${String(h.confidence)})`);const A=j.ask.confirmThreshold??d;if(h.confidence<A){const e={status:"needs_confirmation",decision:h,message:`置信度 ${String(h.confidence)} 低于阈值 ${String(A)},跳过执行。 可使用 \`roll run ${h.agentName} ${h.toolName}\` 手动调用。`};return u.warn(e.message),$(e),void(process.exitCode=1)}const C=x.find(e=>e.skill.name===h.agentName);if(!C){const e={status:"failed",stage:"route",decision:h,message:`Agent "${h.agentName}" 未找到(LLM 返回了无效的 Agent 名称)`};return u.error(e.message),$(e),void(process.exitCode=1)}const L=s(v,j.llm.defaultModel,k.apiKey,k.baseUrl),M=new r;let S="connect";try{u.info(`连接 Agent "${C.skill.name}"...`);const t=o(j,C.skill.name),s=i(C),r=await M.connect(C.skill.name,s,C.installPath,{samplingModel:L,...t?{env:t}:{}}),{tools:n}=await r.listTools(),a=n.find(e=>e.name===h.toolName);if(!a){const e={status:"failed",stage:"route",decision:h,message:`Tool "${h.toolName}" 不存在于 Agent "${C.skill.name}" 中`};return u.error(e.message),$(e),void(process.exitCode=1)}S="execute";const d=await l(e.message,a,w),p={...h,input:d},y=m(a,p.input);if(!y.ok){const e={status:"needs_input",decision:p,validationIssues:y.issues,message:c(C.skill.name,h.toolName,y.issues)};return u.warn(e.message),$(e),void(process.exitCode=1)}u.info(`调用 ${C.skill.name}.${h.toolName}(${JSON.stringify(p.input)})`);const x=await r.callTool({name:h.toolName,arguments:p.input});if(g(x)){const e={status:"failed",stage:"execute",decision:p,message:f(x.content).join("\n")||"Tool 调用失败"};return u.error(e.message),$(e),void(process.exitCode=1)}$({status:"success",decision:p,result:x}),u.success("调用完成")}catch(e){const t={status:"failed",stage:S,decision:h,message:e instanceof Error?e.message:String(e)};u.error(t.message),$(t),process.exitCode=1}finally{await M.disconnectAll()}}});
1
+ import{defineCommand as e}from"citty";import{loadConfig as t}from"../../config/loader.js";import{getAgentEnv as o}from"../../config/helpers.js";import{createProviderModel as s,resolveLLMCall as r}from"../../llm/providers.js";import{McpClientManager as n}from"../../mcp/client-manager.js";import{AgentStore as i}from"../../registry/store.js";import{resolveTransportWithDevSpawnSpec as a}from"../../registry/dev-spawn.js";import{routeWithLLM as l}from"../../router/llm-router.js";import{extractToolInput as c}from"../../tool-runtime/argument-extractor.js";import{formatValidationIssuesMessage as m}from"../../tool-runtime/messages.js";import{preflightToolCall as u}from"../../tool-runtime/preflight.js";import{log as d}from"../utils/output.js";const f=.5;function g(e){if(!Array.isArray(e))return[];const t=[];for(const o of e)"object"==typeof o&&null!==o&&"type"in o&&"text"===o.type&&"text"in o&&"string"==typeof o.text&&t.push(o.text);return t}function p(e){return"object"==typeof e&&null!==e&&"isError"in e&&!0===e.isError}function y(e){console.log(JSON.stringify(e,null,2))}function j(e){const t=g("object"==typeof e.result&&null!==e.result&&"content"in e.result?e.result.content:void 0);for(const e of t)console.log(e)}export default e({meta:{description:"LLM 智能路由,自动选择 Agent 和 tool"},args:{message:{type:"positional",description:"自然语言消息",required:!0},json:{type:"boolean",description:"JSON 格式输出",default:!1}},async run({args:e}){const{config:v}=t(),x=new i(v.agents.dataDir).list();if(0===x.length)return d.error("暂无已注册的 Agent。可使用 `roll agent add <path>`、`roll agent install <package>` 或 `roll agent add --remote <endpoint>`。"),void(process.exitCode=1);const $=t=>{if(e.json)y(t);else if("success"===t.status)j(t)},N=v.llm.defaultProvider,k=v.ask.llmModel??v.llm.defaultModel,w=v.llm.providers[N];if(!w)return d.error(`LLM provider "${N}" 未配置。请检查 roll.config.yaml`),void(process.exitCode=1);const{model:h,providerOptions:A}=r(N,k,w.apiKey,"structured-output",w.baseUrl);let C;d.info(`分析意图: "${e.message}"`);try{C=await l(e.message,x,h,A)}catch(e){const t={status:"failed",stage:"route",message:`LLM 路由失败: ${e instanceof Error?e.message:String(e)}`};return d.error(t.message),$(t),void(process.exitCode=1)}d.info(`路由决策: ${C.agentName}.${C.toolName} (置信度: ${String(C.confidence)})`);const L=v.ask.confirmThreshold??f;if(C.confidence<L){const e={status:"needs_confirmation",decision:C,message:`置信度 ${String(C.confidence)} 低于阈值 ${String(L)},跳过执行。 可使用 \`roll run ${C.agentName} ${C.toolName}\` 手动调用。`};return d.warn(e.message),$(e),void(process.exitCode=1)}const M=x.find(e=>e.skill.name===C.agentName);if(!M){const e={status:"failed",stage:"route",decision:C,message:`Agent "${C.agentName}" 未找到(LLM 返回了无效的 Agent 名称)`};return d.error(e.message),$(e),void(process.exitCode=1)}const S=s(N,v.llm.defaultModel,w.apiKey,w.baseUrl),b=new n;let T="connect";try{d.info(`连接 Agent "${M.skill.name}"...`);const t=o(v,M.skill.name),s=a(M),r=await b.connect(M.skill.name,s,M.installPath,{samplingModel:S,...t?{env:t}:{}}),{tools:n}=await r.listTools(),i=n.find(e=>e.name===C.toolName);if(!i){const e={status:"failed",stage:"route",decision:C,message:`Tool "${C.toolName}" 不存在于 Agent "${M.skill.name}" 中`};return d.error(e.message),$(e),void(process.exitCode=1)}T="execute";const l=await c(e.message,i,h,A),f={...C,input:l},y=u(i,f.input);if(!y.ok){const e={status:"needs_input",decision:f,validationIssues:y.issues,message:m(M.skill.name,C.toolName,y.issues)};return d.warn(e.message),$(e),void(process.exitCode=1)}d.info(`调用 ${M.skill.name}.${C.toolName}(${JSON.stringify(f.input)})`);const j=await r.callTool({name:C.toolName,arguments:f.input});if(p(j)){const e={status:"failed",stage:"execute",decision:f,message:g(j.content).join("\n")||"Tool 调用失败"};return d.error(e.message),$(e),void(process.exitCode=1)}$({status:"success",decision:f,result:j}),d.success("调用完成")}catch(e){const t={status:"failed",stage:T,decision:C,message:e instanceof Error?e.message:String(e)};d.error(t.message),$(t),process.exitCode=1}finally{await b.disconnectAll()}}});
@@ -1,7 +1,21 @@
1
- import type { LanguageModelV3 } from "@ai-sdk/provider";
1
+ import type { LanguageModelV3, SharedV3ProviderOptions } from "@ai-sdk/provider";
2
2
  /**
3
3
  * 根据 provider 名称创建 AI SDK LanguageModel 实例。
4
4
  *
5
5
  * 支持: anthropic, openai, deepseek, qwen
6
6
  */
7
7
  export declare function createProviderModel(providerName: string, modelName: string, apiKey: string, baseURL?: string): LanguageModelV3;
8
+ /** generateText 调用目的 */
9
+ export type LLMCallPurpose = "structured-output" | "text" | "sampling";
10
+ /** resolveLLMCall 的返回值 */
11
+ export interface ResolvedLLMCall {
12
+ readonly model: LanguageModelV3;
13
+ readonly providerOptions?: SharedV3ProviderOptions;
14
+ }
15
+ /**
16
+ * 按 provider + 调用目的解析 generateText 的完整调用上下文。
17
+ *
18
+ * structured-output 场景下,对 qwen provider 自动注入 enableThinking: false,
19
+ * 因为阿里云 thinking mode 不支持 structured output。
20
+ */
21
+ export declare function resolveLLMCall(providerName: string, modelName: string, apiKey: string, purpose: LLMCallPurpose, baseURL?: string): ResolvedLLMCall;
@@ -1 +1 @@
1
- import{createAlibaba as e}from"@ai-sdk/alibaba";import{createAnthropic as a}from"@ai-sdk/anthropic";import{createOpenAI as i}from"@ai-sdk/openai";import{createDeepSeek as o}from"@ai-sdk/deepseek";const p="https://dashscope.aliyuncs.com/compatible-mode/v1",r={anthropic:(e,{apiKey:i,baseURL:o})=>a({apiKey:i,...o?{baseURL:o}:{}})(e),openai:(e,{apiKey:a,baseURL:o})=>i({apiKey:a,...o?{baseURL:o}:{}})(e),deepseek:(e,{apiKey:a,baseURL:i})=>o({apiKey:a,...i?{baseURL:i}:{}})(e),qwen:(a,{apiKey:i,baseURL:o})=>e({apiKey:i,baseURL:o??p})(a)};export function createProviderModel(e,a,i,o){const p=r[e];if(!p){const a=Object.keys(r).join(", ");throw new Error(`Unknown LLM provider "${e}". Supported: ${a}`)}return p(a,{apiKey:i,baseURL:o})}
1
+ import{createAlibaba as e}from"@ai-sdk/alibaba";import{createAnthropic as o}from"@ai-sdk/anthropic";import{createOpenAI as a}from"@ai-sdk/openai";import{createDeepSeek as i}from"@ai-sdk/deepseek";const r="https://dashscope.aliyuncs.com/compatible-mode/v1",p={anthropic:(e,{apiKey:a,baseURL:i})=>o({apiKey:a,...i?{baseURL:i}:{}})(e),openai:(e,{apiKey:o,baseURL:i})=>a({apiKey:o,...i?{baseURL:i}:{}})(e),deepseek:(e,{apiKey:o,baseURL:a})=>i({apiKey:o,...a?{baseURL:a}:{}})(e),qwen:(o,{apiKey:a,baseURL:i})=>e({apiKey:a,baseURL:i??r})(o)};export function createProviderModel(e,o,a,i){const r=p[e];if(!r){const o=Object.keys(p).join(", ");throw new Error(`Unknown LLM provider "${e}". Supported: ${o}`)}return r(o,{apiKey:a,baseURL:i})}export function resolveLLMCall(e,o,a,i,r){const p=createProviderModel(e,o,a,r);return"structured-output"===i&&"qwen"===e?{model:p,providerOptions:{alibaba:{enableThinking:!1}}}:{model:p}}
@@ -1,11 +1,11 @@
1
- import type { LanguageModelV3 } from "@ai-sdk/provider";
1
+ import type { LanguageModelV3, SharedV3ProviderOptions } from "@ai-sdk/provider";
2
2
  import type { RegisteredAgent } from "../types/agent.ts";
3
3
  import type { RouteSelection } from "../types/router.ts";
4
4
  /**
5
5
  * 使用 LLM 从用户自然语言意图中选择最合适的 Agent + Tool。
6
6
  *
7
7
  * 两步走:
8
- * 1. 构建包含所有 Agent 描述的 system prompt
9
- * 2. generateObject LLM 返回结构化的路由决策
8
+ * 1. 优先尝试 structured output
9
+ * 2. 仅当模型未遵循 schema 时,降级为纯文本 JSON fallback
10
10
  */
11
- export declare function routeWithLLM(message: string, agents: ReadonlyArray<RegisteredAgent>, model: LanguageModelV3): Promise<RouteSelection>;
11
+ export declare function routeWithLLM(message: string, agents: ReadonlyArray<RegisteredAgent>, model: LanguageModelV3, structuredOutputProviderOptions?: SharedV3ProviderOptions): Promise<RouteSelection>;
@@ -1 +1 @@
1
- import{generateText as n,Output as e}from"ai";import{z as t}from"zod";import{asConfidence as o}from"../types/router.js";const r=t.object({agentName:t.string().describe("选择的 Agent 名称"),toolName:t.string().describe("选择的 Tool 名称"),confidence:t.number().describe("决策置信度 0-1")});function i(n){return 0===n.length?"当前没有已注册的 Agent。":n.map(n=>{const e=n.skill.name,t=n.skill.description,o=n.skillBody?`\n 能力详情:\n${n.skillBody}`:"";return`Agent: ${e}\n 描述: ${t}\n 状态: ${n.status}${o}`}).join("\n\n")}export async function routeWithLLM(t,c,s){const a=`你是 Roll Agent 的智能路由器。根据用户的自然语言请求,从已注册的 Agent 中选择最合适的 Agent 和 Tool。\n\n已注册的 Agent 列表:\n${i(c)}\n\n规则:\n- 选择与用户意图最匹配的 Agent 和 Tool\n- 这一阶段只负责选择 Agent 和 Tool,不要推测或生成 Tool 参数\n- confidence 字段表示你对这个匹配的把握程度(0-1)\n- 如果没有合适的 Agent 匹配,confidence 应该很低(< 0.3)`,{output:l}=await n({model:s,output:e.object({schema:r}),system:a,prompt:t});if(!l)throw new Error("LLM router: failed to produce structured output");return{agentName:l.agentName,toolName:l.toolName,confidence:o(Math.min(1,Math.max(0,l.confidence)))}}
1
+ import{generateText as t,NoObjectGeneratedError as e,Output as n}from"ai";import{z as o}from"zod";import{asConfidence as r}from"../types/router.js";const c=o.object({agentName:o.string().describe("选择的 Agent 名称"),toolName:o.string().describe("选择的 Tool 名称"),confidence:o.number().describe("决策置信度 0-1")});function i(t){return 0===t.length?"当前没有已注册的 Agent。":t.map(t=>{const e=t.skill.name,n=t.skill.description,o=t.skillBody?`\n 能力详情:\n${t.skillBody}`:"";return`Agent: ${e}\n 描述: ${n}\n 状态: ${t.status}${o}`}).join("\n\n")}function a(t){const e=t.trim(),n=[e],o=e.match(/```(?:json)?\s*([\s\S]*?)```/i);o?.[1]&&n.push(o[1].trim());const r=e.indexOf("{"),i=e.lastIndexOf("}");r>=0&&i>r&&n.push(e.slice(r,i+1));for(const t of n)try{return c.parse(JSON.parse(t))}catch{}throw new Error("LLM router: text fallback did not produce valid route JSON")}function s(t){return[t,"","只输出一个 JSON object。","字段必须是 agentName(string)、toolName(string)、confidence(number 0-1)。","不要输出 Markdown 代码块。","不要解释,不要补充额外文本。"].join("\n")}function u(t){return t instanceof Error?t.message:String(t)}export async function routeWithLLM(o,m,l,d){const f=`你是 Roll Agent 的智能路由器。根据用户的自然语言请求,从已注册的 Agent 中选择最合适的 Agent 和 Tool。以 JSON 格式返回结果。\n\n已注册的 Agent 列表:\n${i(m)}\n\n规则:\n- 选择与用户意图最匹配的 Agent 和 Tool\n- 这一阶段只负责选择 Agent 和 Tool,不要推测或生成 Tool 参数\n- confidence 字段表示你对这个匹配的把握程度(0-1)\n- 如果没有合适的 Agent 匹配,confidence 应该很低(< 0.3)`;try{const{output:e}=await t({model:l,output:n.object({schema:c}),system:f,prompt:o,...d?{providerOptions:d}:{}});if(!e)throw new Error("structured output returned null");return{agentName:e.agentName,toolName:e.toolName,confidence:r(Math.min(1,Math.max(0,e.confidence)))}}catch(n){if(!e.isInstance(n))throw n;try{const e=a((await t({model:l,system:f,prompt:s(o)})).text);return{agentName:e.agentName,toolName:e.toolName,confidence:r(Math.min(1,Math.max(0,e.confidence)))}}catch(t){throw new Error(`LLM router: failed to produce route selection (structured output: ${u(n)}; text fallback: ${u(t)})`,{cause:t})}}}
@@ -1,3 +1,3 @@
1
- import type { LanguageModelV3 } from "@ai-sdk/provider";
1
+ import type { LanguageModelV3, SharedV3ProviderOptions } from "@ai-sdk/provider";
2
2
  import type { AgentTool } from "../types/agent.ts";
3
- export declare function extractToolInput(message: string, tool: Pick<AgentTool, "name" | "description" | "inputSchema">, model: LanguageModelV3): Promise<Readonly<Record<string, unknown>>>;
3
+ export declare function extractToolInput(message: string, tool: Pick<AgentTool, "name" | "description" | "inputSchema">, model: LanguageModelV3, structuredOutputProviderOptions?: SharedV3ProviderOptions): Promise<Readonly<Record<string, unknown>>>;
@@ -1 +1 @@
1
- import{generateText as t,jsonSchema as o,Output as r}from"ai";import{isPlainObject as n}from"./schema.js";import{createExtractionSchema as e,normalizeExtractedToolInput as c}from"./extraction-schema.js";function a(t,o,r){return["你要为一个工具调用提取参数。","这里只提取能从当前消息中明确得到的字段,不要发明新字段。","如果用户没有提供某个值,不要猜测,也不要填充默认值。","如果用户明确提到了某个名字、品牌、城市、数字或其他实体,并且 schema 中有最匹配的字段,即使该字段是可选的,也应当提取出来。","只有在用户消息里确实没有出现对应值时,才省略该可选字段。","可选字段用省略表达,不要输出 null。","系统会在后续按原始 tool 契约继续校验;这里只输出可提取参数的 JSON object。","",`[Tool] ${o.name}`,o.description?`[Description] ${o.description}`:"","[Extraction Schema]",JSON.stringify(r,null,2),"","[User Message]",t].filter(Boolean).join("\n")}function i(t,o,r){return[a(t,o,r),"","只输出一个 JSON object。","不要输出 Markdown 代码块。","不要解释,不要补充额外文本。"].join("\n")}function s(t){return t instanceof Error?t.message:String(t)}function u(t){const o=t.trim(),r=new Set;o&&r.add(o);const n=o.match(/```(?:json)?\s*([\s\S]*?)```/i),e=n?.[1]?.trim();e&&r.add(e);const c=o.indexOf("{"),a=o.lastIndexOf("}");return c>=0&&a>c&&r.add(o.slice(c,a+1).trim()),[...r]}function m(t){for(const o of u(t))try{const t=JSON.parse(o);if(n(t))return t}catch{}throw new Error("Text fallback did not produce a valid JSON object")}export async function extractToolInput(n,u,f){const l=e(u.inputSchema);try{const{output:e}=await t({model:f,output:r.object({schema:o(l)}),prompt:a(n,u,l)});if(!e)throw new Error(`Failed to extract arguments for tool "${u.name}"`);return c(u.inputSchema,e)}catch(o){try{const o=await t({model:f,prompt:i(n,u,l)});return c(u.inputSchema,m(o.text))}catch(t){throw new Error(`Failed to extract arguments for tool "${u.name}" (structured output: ${s(o)}; text fallback: ${s(t)})`,{cause:t})}}}
1
+ import{generateText as t,jsonSchema as o,Output as r}from"ai";import{isPlainObject as n}from"./schema.js";import{createExtractionSchema as e,normalizeExtractedToolInput as c}from"./extraction-schema.js";function a(t,o,r){return["你要为一个工具调用提取参数。以 JSON 格式返回结果。","这里只提取能从当前消息中明确得到的字段,不要发明新字段。","如果用户没有提供某个值,不要猜测,也不要填充默认值。","如果用户明确提到了某个名字、品牌、城市、数字或其他实体,并且 schema 中有最匹配的字段,即使该字段是可选的,也应当提取出来。","只有在用户消息里确实没有出现对应值时,才省略该可选字段。","可选字段用省略表达,不要输出 null。","系统会在后续按原始 tool 契约继续校验;这里只输出可提取参数的 JSON object。","",`[Tool] ${o.name}`,o.description?`[Description] ${o.description}`:"","[Extraction Schema]",JSON.stringify(r,null,2),"","[User Message]",t].filter(Boolean).join("\n")}function i(t,o,r){return[a(t,o,r),"","只输出一个 JSON object。","不要输出 Markdown 代码块。","不要解释,不要补充额外文本。"].join("\n")}function s(t){return t instanceof Error?t.message:String(t)}function u(t){const o=t.trim(),r=new Set;o&&r.add(o);const n=o.match(/```(?:json)?\s*([\s\S]*?)```/i),e=n?.[1]?.trim();e&&r.add(e);const c=o.indexOf("{"),a=o.lastIndexOf("}");return c>=0&&a>c&&r.add(o.slice(c,a+1).trim()),[...r]}function m(t){for(const o of u(t))try{const t=JSON.parse(o);if(n(t))return t}catch{}throw new Error("Text fallback did not produce a valid JSON object")}export async function extractToolInput(n,u,f,l){const p=e(u.inputSchema);try{const{output:e}=await t({model:f,output:r.object({schema:o(p)}),prompt:a(n,u,p),...l?{providerOptions:l}:{}});if(!e)throw new Error(`Failed to extract arguments for tool "${u.name}"`);return c(u.inputSchema,e)}catch(o){try{const o=await t({model:f,prompt:i(n,u,p)});return c(u.inputSchema,m(o.text))}catch(t){throw new Error(`Failed to extract arguments for tool "${u.name}" (structured output: ${s(o)}; text fallback: ${s(t)})`,{cause:t})}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roll-agent/core",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,13 +30,13 @@
30
30
  "node": ">=22.6.0"
31
31
  },
32
32
  "dependencies": {
33
- "@ai-sdk/alibaba": "^1.0.13",
34
- "@ai-sdk/anthropic": "^3.0.58",
35
- "@ai-sdk/deepseek": "^2.0.24",
36
- "@ai-sdk/openai": "^3.0.41",
33
+ "@ai-sdk/alibaba": "^1.0.17",
34
+ "@ai-sdk/anthropic": "^3.0.68",
35
+ "@ai-sdk/deepseek": "^2.0.29",
36
+ "@ai-sdk/openai": "^3.0.52",
37
37
  "@ai-sdk/provider": "^3.0.8",
38
38
  "@modelcontextprotocol/sdk": "^1.12.0",
39
- "ai": "^6.0.116",
39
+ "ai": "^6.0.154",
40
40
  "chalk": "^5.4.0",
41
41
  "citty": "^0.1.6",
42
42
  "cli-table3": "^0.6.5",