qlogicagent 1.0.1 → 1.1.1
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.
- package/dist/agent.js +6 -6
- package/dist/cli.js +181 -172
- package/dist/index.js +181 -172
- package/dist/orchestration.js +1 -1
- package/dist/types/agent/tool-loop.d.ts +2 -0
- package/dist/types/agent/types.d.ts +46 -1
- package/dist/types/cli/stdio-server.d.ts +10 -0
- package/dist/types/cli/tool-bootstrap.d.ts +13 -1
- package/dist/types/llm/index.d.ts +1 -1
- package/dist/types/llm/llm-client.d.ts +1 -1
- package/dist/types/llm/media-client.d.ts +3 -4
- package/dist/types/llm/media-transport.d.ts +75 -4
- package/dist/types/llm/provider-def.d.ts +124 -3
- package/dist/types/llm/provider-registry.d.ts +5 -0
- package/dist/types/llm/provider-tool-api.d.ts +44 -0
- package/dist/types/llm/retry.d.ts +37 -0
- package/dist/types/llm/transport.d.ts +157 -2
- package/dist/types/llm/transports/anthropic-messages.d.ts +7 -0
- package/dist/types/llm/transports/minimax-media.d.ts +5 -0
- package/dist/types/llm/transports/openai-chat.d.ts +44 -3
- package/dist/types/llm/transports/realtime-transport.d.ts +183 -0
- package/dist/types/llm/transports/volcengine-grounding.d.ts +58 -0
- package/dist/types/llm/transports/volcengine-media.d.ts +50 -0
- package/dist/types/llm/transports/volcengine-responses.d.ts +60 -0
- package/dist/types/llm/transports/zhipu-media.d.ts +60 -0
- package/dist/types/llm/transports/zhipu-tool-api.d.ts +35 -0
- package/dist/types/orchestration/tool-cascade.d.ts +40 -0
- package/dist/types/orchestration/tool-loop/tool-schema.d.ts +1 -1
- package/dist/types/protocol/methods.d.ts +19 -0
- package/dist/types/skills/memory/memory-extractor.d.ts +1 -1
- package/dist/types/skills/tools/file-management-tool.d.ts +90 -0
- package/dist/types/skills/tools/image-generate-tool.d.ts +13 -1
- package/dist/types/skills/tools/music-generate-tool.d.ts +25 -0
- package/dist/types/skills/tools/stt-tool.d.ts +33 -0
- package/dist/types/skills/tools/three-d-generate-tool.d.ts +45 -0
- package/dist/types/skills/tools/tts-tool.d.ts +12 -0
- package/dist/types/skills/tools/video-edit-tool.d.ts +5 -2
- package/dist/types/skills/tools/video-generate-tool.d.ts +102 -2
- package/dist/types/skills/tools/video-merge-tool.d.ts +1 -1
- package/dist/types/skills/tools/video-upscale-tool.d.ts +1 -1
- package/dist/types/skills/tools/voice-clone-tool.d.ts +40 -0
- package/package.json +1 -1
package/dist/orchestration.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function ce(e,t,n){return{role:"assistant",content:t||null,tool_calls:e,...n&&n.length>0?{thinkingBlocks:n}:{}}}function ue(e,t){let n=t.ok?typeof t.payload=="string"?t.payload:JSON.stringify(t.payload??""):`Error: ${t.error??"Tool execution failed"}`;return{role:"tool",tool_call_id:e,content:n}}var pe=/\b(?:daily|weekly|monthly)(?:\/(?:daily|weekly|monthly))* (?:usage )?limit(?:s)?(?: (?:exhausted|reached|exceeded))?\b/i,h={rateLimit:[/rate[_ ]limit|too many requests|429/,"model_cooldown","exceeded your current quota","resource has been exhausted","quota exceeded","resource_exhausted","usage limit",/\btpm\b/i,"tokens per minute","tokens per day"],overloaded:[/overloaded_error|"type"\s*:\s*"overloaded_error"/i,"overloaded",/service[_ ]unavailable.*(?:overload|capacity|high[_ ]demand)|(?:overload|capacity|high[_ ]demand).*service[_ ]unavailable/i,"high demand"],timeout:["timeout","timed out","service unavailable","deadline exceeded","context deadline exceeded","connection error","network error","network request failed","fetch failed","socket hang up",/\beconn(?:refused|reset|aborted)\b/i,/\benotfound\b/i,/\beai_again\b/i,/without sending (?:any )?chunks?/i,/\bstop reason:\s*(?:abort|error|network_error)\b/i,/\breason:\s*(?:abort|error|network_error)\b/i,/\bunhandled stop reason:\s*(?:abort|error|network_error)\b/i],billing:[/["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|\b(?:got|returned|received)\s+(?:a\s+)?402\b|^\s*402\s+payment/i,"payment required","insufficient credits",/insufficient[_ ]quota/i,"credit balance","plans & billing","insufficient balance"],authPermanent:[/api[_ ]?key[_ ]?(?:revoked|invalid|deactivated|deleted)/i,"invalid_api_key","key has been disabled","key has been revoked","account has been deactivated",/could not (?:authenticate|validate).*(?:api[_ ]?key|credentials)/i,"permission_error","not allowed for this organization"],auth:[/invalid[_ ]?api[_ ]?key/,"incorrect api key","invalid token","authentication","re-authenticate","oauth token refresh failed","unauthorized","forbidden","access denied","insufficient permissions","insufficient permission",/missing scopes?:/i,"expired","token has expired",/\b401\b/,/\b403\b/,"no credentials found","no api key found"],format:["string should match pattern","tool_use.id","tool_use_id","messages.1.content.1.tool_use.id","invalid request format",/tool call id was.*must be/i]},de=/^(?:error[:\s-]+)?billing(?:\s+error)?(?:[:\s-]+|$)|^(?:error[:\s-]+)?(?:credit balance|insufficient credits?|payment required|http\s*402\b)/i,me=/["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|^\s*402\s+payment/i,fe=512,ge=/^(?:http\s*)?(\d{3})(?:\s+([\s\S]+))?$/i;var ye=new Set([500,502,503,504,521,522,523,524,529]),he=["insufficient credits","insufficient quota","credit balance","insufficient balance","plans & billing","add more credits","top up"],Ce=["upgrade your plan","upgrade plan","current plan","subscription"],Te=["daily","weekly","monthly"],be=["try again","retry","temporary","cooldown"],ke=["usage limit","rate limit","organization usage"],_e=["organization","workspace"],Re=["billing period","exceeded","reached","exhausted"],xe=/["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|\b(?:got|returned|received)\s+(?:a\s+)?402\b|^\s*402\s+payment required\b/i,Se=/^(?:error[:\s-]+)?(?:(?:http\s*)?402(?:\s+payment required)?|payment required)(?:[:\s-]+|$)/i;function C(e,t){if(!e)return!1;let n=e.toLowerCase();return t.some(o=>o instanceof RegExp?o.test(n):n.includes(o))}function Ae(e){return C(e,h.format)}function U(e){return C(e,h.rateLimit)}function ve(e){return C(e,h.timeout)}function Me(e){return pe.test(e)}function v(e){let t=e.toLowerCase();return t?e.length>fe?me.test(t):C(t,h.billing)?!0:de.test(e)?t.includes("upgrade")||t.includes("credits")||t.includes("payment")||t.includes("plan"):!1:!1}function Y(e){return C(e,h.authPermanent)}function we(e){return C(e,h.auth)}function W(e){return C(e,h.overloaded)}function y(e,t){return t.some(n=>e.includes(n))}function Ee(e){return y(e,he)||y(e,Ce)&&e.includes("limit")||e.includes("billing hard limit")||e.includes("hard limit reached")||e.includes("maximum allowed")&&e.includes("limit")}function Ie(e){let t=y(e,Te),n=e.includes("spend limit")||e.includes("spending limit"),o=y(e,_e);return y(e,be)&&y(e,ke)||t&&(e.includes("usage limit")||n)||t&&e.includes("limit")&&e.includes("reset")||o&&e.includes("limit")&&(n||y(e,Re))}function Le(e){return e.trim().toLowerCase().replace(Se,"").trim()}function K(e){let t=Le(e);return!t||Ee(t)?"billing":U(t)||Ie(t)?"rate_limit":"billing"}function Oe(e){return xe.test(e)?K(e):null}function J(e){let t=e.match(ge);if(!t)return null;let n=Number(t[1]);return Number.isFinite(n)?{code:n,rest:(t[2]??"").trim()}:null}function Pe(e){if(!e)return!1;let t=e.toLowerCase();return t.includes('"type":"api_error"')&&t.includes("internal server error")}function Fe(e){let t=e.trim();if(!t)return!1;let n=J(t);return n?ye.has(n.code):!1}function V(e,t){return typeof e!="number"||!Number.isFinite(e)?null:e===402?t?K(t):"billing":e===429?"rate_limit":e===401||e===403?t&&Y(t)?"auth_permanent":"auth":e===408?"timeout":e===503?t&&W(t)?"overloaded":"timeout":e===502||e===504?"timeout":e===529?"overloaded":e===400?t&&v(t)?"billing":"format":null}function Ne(e){if(!e)return!1;let t=e.toLowerCase();return!!(t.includes("unknown model")||t.includes("model not found")||t.includes("model_not_found")||t.includes("not_found_error")||t.includes("does not exist")&&t.includes("model")||t.includes("invalid model")&&!t.includes("invalid model reference")||/models\/[^\s]+ is not found/i.test(e)||/\b404\b/.test(e)&&/not[-_ ]?found/i.test(e))}function Be(e){if(!e)return!1;let t=e.toLowerCase();return t.includes("session not found")||t.includes("session does not exist")||t.includes("session expired")||t.includes("session invalid")||t.includes("conversation not found")||t.includes("conversation does not exist")||t.includes("conversation expired")||t.includes("conversation invalid")||t.includes("no such session")||t.includes("invalid session")||t.includes("session id not found")||t.includes("conversation id not found")}function X(e){if(Be(e))return"session_expired";if(Ne(e))return"model_not_found";let t=Oe(e);return t||(Me(e)?v(e)?"billing":"rate_limit":U(e)?"rate_limit":W(e)?"overloaded":Fe(e)?J(e.trim())?.code===529?"overloaded":"timeout":Pe(e)?"timeout":Ae(e)?"format":v(e)?"billing":ve(e)?"timeout":Y(e)?"auth_permanent":we(e)?"auth":null)}var De={timeout:"RETRYABLE_TRANSIENT",overloaded:"RETRYABLE_TRANSIENT",rate_limit:"RETRYABLE_DEGRADED",auth:"NON_RETRYABLE_AUTH",auth_permanent:"NON_RETRYABLE_AUTH",billing:"NON_RETRYABLE_QUOTA",format:"NON_RETRYABLE_CONTENT",model_not_found:"NON_RETRYABLE_CONTENT",session_expired:"NON_RETRYABLE_CONTENT",unknown:"RETRYABLE_TRANSIENT"},je=new Set(["RETRYABLE_TRANSIENT","RETRYABLE_DEGRADED","TOOL_EXECUTION_FAILED"]);function $e(e,t){let n=V(e,t)??(t?X(t):null);return n?De[n]:typeof e=="number"&&e>=400&&e<500?"NON_RETRYABLE_CONTENT":"RETRYABLE_TRANSIENT"}function qe(e){return je.has(e)}function B(e){return typeof e.compressAsync=="function"}var Q=4,M=class{constructor(t){this.estimateTokens=t}estimateTokens;compress(t,n){let o=[],r=[];for(let c of t)c.role==="system"?o.push(c):r.push(c);let a=n;for(let c of o)a-=this.estimateTokens(c);let i;for(let c of r)if(c.role==="user"){i=c;break}if(i&&(a-=this.estimateTokens(i)),a<=0)return{messages:i?[...o,i]:o,droppedCount:r.length-(i?1:0),strategy:"sliding-window"};let s=[],l=0;for(let c=r.length-1;c>=0;c--){let d=r[c];if(d===i)continue;let p=this.estimateTokens(d);if(a-p<0&&l>=Q)break;if(a-p<0&&l<Q){s.unshift(d),l++;continue}a-=p,s.unshift(d),l++}let u=[...o];return i&&!s.includes(i)&&u.push(i),u.push(...s),{messages:u,droppedCount:r.length-(s.length+(i&&!s.includes(i)?1:0)),strategy:"sliding-window"}}},w=class{constructor(t,n){this.recentCount=t;this.summarize=n}recentCount;summarize;compress(t,n){let o=t.filter(l=>l.role==="system"),r=t.filter(l=>l.role!=="system");if(r.length<=this.recentCount)return{messages:t,droppedCount:0,strategy:"summarize-old"};let a=r.slice(0,r.length-this.recentCount),i=r.slice(r.length-this.recentCount),s=this.summarize(a);return{messages:[...o,{role:"system",content:`[Conversation summary]
|
|
1
|
+
function ce(e,t,n,o){return{role:"assistant",content:t||null,tool_calls:e,...n&&n.length>0?{thinkingBlocks:n}:{},...o?{reasoning_content:o}:{}}}function ue(e,t){let n=t.ok?typeof t.payload=="string"?t.payload:JSON.stringify(t.payload??""):`Error: ${t.error??"Tool execution failed"}`;return{role:"tool",tool_call_id:e,content:n}}var pe=/\b(?:daily|weekly|monthly)(?:\/(?:daily|weekly|monthly))* (?:usage )?limit(?:s)?(?: (?:exhausted|reached|exceeded))?\b/i,h={rateLimit:[/rate[_ ]limit|too many requests|429/,"model_cooldown","exceeded your current quota","resource has been exhausted","quota exceeded","resource_exhausted","usage limit",/\btpm\b/i,"tokens per minute","tokens per day"],overloaded:[/overloaded_error|"type"\s*:\s*"overloaded_error"/i,"overloaded",/service[_ ]unavailable.*(?:overload|capacity|high[_ ]demand)|(?:overload|capacity|high[_ ]demand).*service[_ ]unavailable/i,"high demand"],timeout:["timeout","timed out","service unavailable","deadline exceeded","context deadline exceeded","connection error","network error","network request failed","fetch failed","socket hang up",/\beconn(?:refused|reset|aborted)\b/i,/\benotfound\b/i,/\beai_again\b/i,/without sending (?:any )?chunks?/i,/\bstop reason:\s*(?:abort|error|network_error)\b/i,/\breason:\s*(?:abort|error|network_error)\b/i,/\bunhandled stop reason:\s*(?:abort|error|network_error)\b/i],billing:[/["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|\b(?:got|returned|received)\s+(?:a\s+)?402\b|^\s*402\s+payment/i,"payment required","insufficient credits",/insufficient[_ ]quota/i,"credit balance","plans & billing","insufficient balance"],authPermanent:[/api[_ ]?key[_ ]?(?:revoked|invalid|deactivated|deleted)/i,"invalid_api_key","key has been disabled","key has been revoked","account has been deactivated",/could not (?:authenticate|validate).*(?:api[_ ]?key|credentials)/i,"permission_error","not allowed for this organization"],auth:[/invalid[_ ]?api[_ ]?key/,"incorrect api key","invalid token","authentication","re-authenticate","oauth token refresh failed","unauthorized","forbidden","access denied","insufficient permissions","insufficient permission",/missing scopes?:/i,"expired","token has expired",/\b401\b/,/\b403\b/,"no credentials found","no api key found"],format:["string should match pattern","tool_use.id","tool_use_id","messages.1.content.1.tool_use.id","invalid request format",/tool call id was.*must be/i]},de=/^(?:error[:\s-]+)?billing(?:\s+error)?(?:[:\s-]+|$)|^(?:error[:\s-]+)?(?:credit balance|insufficient credits?|payment required|http\s*402\b)/i,me=/["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|^\s*402\s+payment/i,fe=512,ge=/^(?:http\s*)?(\d{3})(?:\s+([\s\S]+))?$/i;var ye=new Set([500,502,503,504,521,522,523,524,529]),he=["insufficient credits","insufficient quota","credit balance","insufficient balance","plans & billing","add more credits","top up"],Ce=["upgrade your plan","upgrade plan","current plan","subscription"],Te=["daily","weekly","monthly"],be=["try again","retry","temporary","cooldown"],ke=["usage limit","rate limit","organization usage"],_e=["organization","workspace"],Re=["billing period","exceeded","reached","exhausted"],xe=/["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|\b(?:got|returned|received)\s+(?:a\s+)?402\b|^\s*402\s+payment required\b/i,Se=/^(?:error[:\s-]+)?(?:(?:http\s*)?402(?:\s+payment required)?|payment required)(?:[:\s-]+|$)/i;function C(e,t){if(!e)return!1;let n=e.toLowerCase();return t.some(o=>o instanceof RegExp?o.test(n):n.includes(o))}function Ae(e){return C(e,h.format)}function U(e){return C(e,h.rateLimit)}function ve(e){return C(e,h.timeout)}function Me(e){return pe.test(e)}function v(e){let t=e.toLowerCase();return t?e.length>fe?me.test(t):C(t,h.billing)?!0:de.test(e)?t.includes("upgrade")||t.includes("credits")||t.includes("payment")||t.includes("plan"):!1:!1}function Y(e){return C(e,h.authPermanent)}function we(e){return C(e,h.auth)}function W(e){return C(e,h.overloaded)}function y(e,t){return t.some(n=>e.includes(n))}function Ee(e){return y(e,he)||y(e,Ce)&&e.includes("limit")||e.includes("billing hard limit")||e.includes("hard limit reached")||e.includes("maximum allowed")&&e.includes("limit")}function Ie(e){let t=y(e,Te),n=e.includes("spend limit")||e.includes("spending limit"),o=y(e,_e);return y(e,be)&&y(e,ke)||t&&(e.includes("usage limit")||n)||t&&e.includes("limit")&&e.includes("reset")||o&&e.includes("limit")&&(n||y(e,Re))}function Le(e){return e.trim().toLowerCase().replace(Se,"").trim()}function K(e){let t=Le(e);return!t||Ee(t)?"billing":U(t)||Ie(t)?"rate_limit":"billing"}function Oe(e){return xe.test(e)?K(e):null}function J(e){let t=e.match(ge);if(!t)return null;let n=Number(t[1]);return Number.isFinite(n)?{code:n,rest:(t[2]??"").trim()}:null}function Pe(e){if(!e)return!1;let t=e.toLowerCase();return t.includes('"type":"api_error"')&&t.includes("internal server error")}function Fe(e){let t=e.trim();if(!t)return!1;let n=J(t);return n?ye.has(n.code):!1}function V(e,t){return typeof e!="number"||!Number.isFinite(e)?null:e===402?t?K(t):"billing":e===429?"rate_limit":e===401||e===403?t&&Y(t)?"auth_permanent":"auth":e===408?"timeout":e===503?t&&W(t)?"overloaded":"timeout":e===502||e===504?"timeout":e===529?"overloaded":e===400?t&&v(t)?"billing":"format":null}function Ne(e){if(!e)return!1;let t=e.toLowerCase();return!!(t.includes("unknown model")||t.includes("model not found")||t.includes("model_not_found")||t.includes("not_found_error")||t.includes("does not exist")&&t.includes("model")||t.includes("invalid model")&&!t.includes("invalid model reference")||/models\/[^\s]+ is not found/i.test(e)||/\b404\b/.test(e)&&/not[-_ ]?found/i.test(e))}function Be(e){if(!e)return!1;let t=e.toLowerCase();return t.includes("session not found")||t.includes("session does not exist")||t.includes("session expired")||t.includes("session invalid")||t.includes("conversation not found")||t.includes("conversation does not exist")||t.includes("conversation expired")||t.includes("conversation invalid")||t.includes("no such session")||t.includes("invalid session")||t.includes("session id not found")||t.includes("conversation id not found")}function X(e){if(Be(e))return"session_expired";if(Ne(e))return"model_not_found";let t=Oe(e);return t||(Me(e)?v(e)?"billing":"rate_limit":U(e)?"rate_limit":W(e)?"overloaded":Fe(e)?J(e.trim())?.code===529?"overloaded":"timeout":Pe(e)?"timeout":Ae(e)?"format":v(e)?"billing":ve(e)?"timeout":Y(e)?"auth_permanent":we(e)?"auth":null)}var De={timeout:"RETRYABLE_TRANSIENT",overloaded:"RETRYABLE_TRANSIENT",rate_limit:"RETRYABLE_DEGRADED",auth:"NON_RETRYABLE_AUTH",auth_permanent:"NON_RETRYABLE_AUTH",billing:"NON_RETRYABLE_QUOTA",format:"NON_RETRYABLE_CONTENT",model_not_found:"NON_RETRYABLE_CONTENT",session_expired:"NON_RETRYABLE_CONTENT",unknown:"RETRYABLE_TRANSIENT"},je=new Set(["RETRYABLE_TRANSIENT","RETRYABLE_DEGRADED","TOOL_EXECUTION_FAILED"]);function $e(e,t){let n=V(e,t)??(t?X(t):null);return n?De[n]:typeof e=="number"&&e>=400&&e<500?"NON_RETRYABLE_CONTENT":"RETRYABLE_TRANSIENT"}function qe(e){return je.has(e)}function B(e){return typeof e.compressAsync=="function"}var Q=4,M=class{constructor(t){this.estimateTokens=t}estimateTokens;compress(t,n){let o=[],r=[];for(let c of t)c.role==="system"?o.push(c):r.push(c);let a=n;for(let c of o)a-=this.estimateTokens(c);let i;for(let c of r)if(c.role==="user"){i=c;break}if(i&&(a-=this.estimateTokens(i)),a<=0)return{messages:i?[...o,i]:o,droppedCount:r.length-(i?1:0),strategy:"sliding-window"};let s=[],l=0;for(let c=r.length-1;c>=0;c--){let d=r[c];if(d===i)continue;let p=this.estimateTokens(d);if(a-p<0&&l>=Q)break;if(a-p<0&&l<Q){s.unshift(d),l++;continue}a-=p,s.unshift(d),l++}let u=[...o];return i&&!s.includes(i)&&u.push(i),u.push(...s),{messages:u,droppedCount:r.length-(s.length+(i&&!s.includes(i)?1:0)),strategy:"sliding-window"}}},w=class{constructor(t,n){this.recentCount=t;this.summarize=n}recentCount;summarize;compress(t,n){let o=t.filter(l=>l.role==="system"),r=t.filter(l=>l.role!=="system");if(r.length<=this.recentCount)return{messages:t,droppedCount:0,strategy:"summarize-old"};let a=r.slice(0,r.length-this.recentCount),i=r.slice(r.length-this.recentCount),s=this.summarize(a);return{messages:[...o,{role:"system",content:`[Conversation summary]
|
|
2
2
|
${s}`},...i],droppedCount:a.length,strategy:"summarize-old"}}},E=class{constructor(t=8e3){this.maxToolResultChars=t}maxToolResultChars;compress(t,n){let o=0;return{messages:t.map(a=>a.role!=="tool"||typeof a.content!="string"||a.content.length<=this.maxToolResultChars?a:(o++,{...a,content:Ge(a.content,this.maxToolResultChars)})),droppedCount:o,strategy:"tool-result-trim"}}};function Ge(e,t){if(e.length<=t)return e;let n=e.slice(0,t);if(e.trimStart().startsWith("{")||e.trimStart().startsWith("[")){let a=Math.max(n.lastIndexOf("},"),n.lastIndexOf("],"),n.lastIndexOf(`}
|
|
3
3
|
`),n.lastIndexOf(`]
|
|
4
4
|
`));if(a>t*.5)return n.slice(0,a+1)+`
|
|
@@ -78,6 +78,8 @@ export interface ToolLoopParams {
|
|
|
78
78
|
}) => Promise<void> | void>;
|
|
79
79
|
/** Max concurrent tool executions (0 = unlimited, CC parity: semantic concurrency control). */
|
|
80
80
|
maxConcurrentTools?: number;
|
|
81
|
+
/** Model requires streaming — disable non-streaming fallback. */
|
|
82
|
+
streamRequired?: boolean;
|
|
81
83
|
signal?: AbortSignal;
|
|
82
84
|
}
|
|
83
85
|
/**
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import type { SkillInstruction } from "../orchestration/index.js";
|
|
15
15
|
import type { HookRegistry } from "../contracts/hooks.js";
|
|
16
|
+
import type { MediaCapability } from "../llm/provider-def.js";
|
|
16
17
|
export type ChatMessageRole = "system" | "user" | "assistant" | "tool";
|
|
17
18
|
/** Thinking block from Anthropic Messages API (DeepSeek, Claude, etc.) */
|
|
18
19
|
export interface ThinkingBlock {
|
|
@@ -30,6 +31,38 @@ export interface ChatMessage {
|
|
|
30
31
|
name?: string;
|
|
31
32
|
/** Anthropic thinking blocks — must be passed back to API in subsequent requests */
|
|
32
33
|
thinkingBlocks?: ThinkingBlock[];
|
|
34
|
+
/**
|
|
35
|
+
* Image URLs for vision-capable models.
|
|
36
|
+
* Transports convert these into the provider's native content block format:
|
|
37
|
+
* - OpenAI-chat: [{type:"text",text:...},{type:"image_url",image_url:{url:...}}]
|
|
38
|
+
* - Anthropic: [{type:"text",text:...},{type:"image",source:{type:"url",url:...}}]
|
|
39
|
+
* Only valid on role="user" messages.
|
|
40
|
+
*/
|
|
41
|
+
imageUrls?: string[];
|
|
42
|
+
/** Image detail level for vision understanding: 'auto' | 'low' | 'high' | 'xhigh' */
|
|
43
|
+
imageDetail?: "auto" | "low" | "high" | "xhigh";
|
|
44
|
+
/** Max image pixels budget for vision understanding (Volcengine image_pixel_limit) */
|
|
45
|
+
imagePixelLimit?: {
|
|
46
|
+
minPixels?: number;
|
|
47
|
+
maxPixels?: number;
|
|
48
|
+
};
|
|
49
|
+
/** Video URLs for video-understanding models. Only valid on role="user" messages. */
|
|
50
|
+
videoUrls?: string[];
|
|
51
|
+
/** Per-video fps for video understanding (0.2-5, default 1) */
|
|
52
|
+
videoFps?: number;
|
|
53
|
+
/** Audio format hint for audio understanding: 'mp3' | 'wav' | 'aac' | 'm4a' */
|
|
54
|
+
audioFormat?: "mp3" | "wav" | "aac" | "m4a";
|
|
55
|
+
/** Audio URLs for audio-understanding models. Only valid on role="user" messages. */
|
|
56
|
+
audioUrls?: string[];
|
|
57
|
+
/**
|
|
58
|
+
* Pre-uploaded file IDs for document/media understanding.
|
|
59
|
+
* Used with Files API — each entry is a { id, mimeType } pair.
|
|
60
|
+
* Only valid on role="user" messages.
|
|
61
|
+
*/
|
|
62
|
+
fileIds?: Array<{
|
|
63
|
+
id: string;
|
|
64
|
+
mimeType?: string;
|
|
65
|
+
}>;
|
|
33
66
|
}
|
|
34
67
|
export interface ToolCallMessage {
|
|
35
68
|
id: string;
|
|
@@ -130,7 +163,7 @@ export interface TurnRequest {
|
|
|
130
163
|
export interface TurnConfig {
|
|
131
164
|
/** LLM provider id, e.g. "deepseek" */
|
|
132
165
|
provider?: string;
|
|
133
|
-
/** Model id, e.g. "deepseek-
|
|
166
|
+
/** Model id, e.g. "deepseek-v4-flash" */
|
|
134
167
|
model?: string;
|
|
135
168
|
/** User API key */
|
|
136
169
|
apiKey?: string;
|
|
@@ -160,6 +193,18 @@ export interface TurnConfig {
|
|
|
160
193
|
summaryModel?: string;
|
|
161
194
|
/** Max concurrent tool executions (0 = unlimited). */
|
|
162
195
|
maxConcurrentTools?: number;
|
|
196
|
+
/** Model requires streaming — disable non-streaming fallback. */
|
|
197
|
+
streamRequired?: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* User-designated provider+model per media category.
|
|
200
|
+
* Each entry maps a media type (image/video/music/tts/3d/...) to
|
|
201
|
+
* the specific provider and model the user chose. No failover —
|
|
202
|
+
* if the designated provider fails, the error propagates directly.
|
|
203
|
+
*/
|
|
204
|
+
mediaProviders?: Partial<Record<MediaCapability, {
|
|
205
|
+
provider: string;
|
|
206
|
+
model: string;
|
|
207
|
+
}>>;
|
|
163
208
|
}
|
|
164
209
|
export type TurnEvent = {
|
|
165
210
|
type: "start";
|
|
@@ -100,6 +100,16 @@ export declare class StdioServer {
|
|
|
100
100
|
* Supports optional category filter.
|
|
101
101
|
*/
|
|
102
102
|
private handleToolsList;
|
|
103
|
+
/**
|
|
104
|
+
* `media.listModels` — List available media generation models.
|
|
105
|
+
* Desktop app uses this to populate the model selector per category.
|
|
106
|
+
*/
|
|
107
|
+
private handleMediaListModels;
|
|
108
|
+
/**
|
|
109
|
+
* `provider.list` — List all available LLM providers grouped by logical family.
|
|
110
|
+
* Returns protocol variants so callers can pick which transport to use.
|
|
111
|
+
*/
|
|
112
|
+
private handleProviderList;
|
|
103
113
|
/**
|
|
104
114
|
* `config.get` — Read current agent runtime configuration.
|
|
105
115
|
* Returns merged user-level + project-level settings.
|
|
@@ -2,12 +2,24 @@ import type { PortableTool } from "../skills/portable-tool.js";
|
|
|
2
2
|
import { type ExecProgress } from "../skills/tools/exec-tool.js";
|
|
3
3
|
import type { AgentLogger } from "../agent/types.js";
|
|
4
4
|
import type { MediaClient } from "../llm/media-client.js";
|
|
5
|
+
import type { MediaCapability } from "../llm/provider-def.js";
|
|
6
|
+
import type { ProviderToolAPI } from "../llm/provider-tool-api.js";
|
|
7
|
+
/**
|
|
8
|
+
* Set the provider's tool API for C-level cascade.
|
|
9
|
+
* When set, web_search tool will try provider-native search first,
|
|
10
|
+
* falling back to SearXNG. Called from stdio-server per session.
|
|
11
|
+
*/
|
|
12
|
+
export declare function setProviderToolAPI(api: ProviderToolAPI | undefined): void;
|
|
5
13
|
/**
|
|
6
14
|
* Set the media client + API keys for generation tools.
|
|
7
15
|
* Tools will call vendor APIs directly through MediaTransport.
|
|
8
16
|
* Keys map: { providerId: apiKey, ... }
|
|
17
|
+
* Providers map: { "image": { provider: "volcengine", model: "doubao-seedream-5-0-260128" }, ... }
|
|
9
18
|
*/
|
|
10
|
-
export declare function setMediaClientConfig(client: MediaClient | undefined, apiKeys?: Record<string, string>, onMediaUsage?: (model: string, billingUnit: string, quantity: number) => void
|
|
19
|
+
export declare function setMediaClientConfig(client: MediaClient | undefined, apiKeys?: Record<string, string>, onMediaUsage?: (model: string, billingUnit: string, quantity: number) => void, providers?: Partial<Record<MediaCapability, {
|
|
20
|
+
provider: string;
|
|
21
|
+
model: string;
|
|
22
|
+
}>>): void;
|
|
11
23
|
export interface BootstrapConfig {
|
|
12
24
|
workdir?: string;
|
|
13
25
|
log?: AgentLogger;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides: ProviderDef + LLMTransport + ProviderRegistry + LLMClient factory
|
|
5
5
|
*/
|
|
6
|
-
export type { ProviderDef, ModelInfo, TransportType, AuthType, MediaCapability } from "./provider-def.js";
|
|
6
|
+
export type { ProviderDef, ModelInfo, TransportType, AuthType, MediaCapability, MediaCapabilities, VideoCapabilities, ImageCapabilities, MusicCapabilities, TtsCapabilities, ThreeDCapabilities, SttCapabilities, EmbeddingCapabilities, VideoUnderstandingCapabilities, ImageUnderstandingCapabilities, VoiceCloneCapabilities, RerankCapabilities, DocumentParsingCapabilities, VideoOperation, ImageOperation, MusicOperation, TtsOperation, ThreeDOperation } from "./provider-def.js";
|
|
7
7
|
export type { LLMTransport, LLMRequest, LLMChunk, AccumulatedToolCall, } from "./transport.js";
|
|
8
8
|
export { accumulateToolCalls } from "./transport.js";
|
|
9
9
|
export type { MediaTransport, MediaRequest, MediaResult, MediaType } from "./media-transport.js";
|
|
@@ -10,7 +10,7 @@ import { ProviderRegistry } from "./provider-registry.js";
|
|
|
10
10
|
export interface LLMClientConfig {
|
|
11
11
|
/** Provider id, e.g. "deepseek" */
|
|
12
12
|
provider: string;
|
|
13
|
-
/** Model id, e.g. "deepseek-
|
|
13
|
+
/** Model id, e.g. "deepseek-v4-flash" */
|
|
14
14
|
model: string;
|
|
15
15
|
/** User API key */
|
|
16
16
|
apiKey: string;
|
|
@@ -25,11 +25,10 @@ export declare class MediaClient {
|
|
|
25
25
|
private transports;
|
|
26
26
|
constructor(config: MediaClientConfig);
|
|
27
27
|
/**
|
|
28
|
-
* Find
|
|
29
|
-
*
|
|
30
|
-
* If preferredProvider is set, search that first.
|
|
28
|
+
* Find a specific model by provider + model id for a given media type.
|
|
29
|
+
* Used by the user-designated model routing (no failover).
|
|
31
30
|
*/
|
|
32
|
-
|
|
31
|
+
resolveModelById(providerId: string, modelId: string, mediaType: MediaCapability): ResolvedMediaModel | undefined;
|
|
33
32
|
/**
|
|
34
33
|
* Get a MediaTransport for a specific provider.
|
|
35
34
|
* Creates and caches the adapter on first access.
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Each provider adapter implements this interface and hides vendor-specific
|
|
10
10
|
* auth, endpoint paths, request shapes, and polling logic.
|
|
11
11
|
*/
|
|
12
|
-
export type MediaType = "image" | "video" | "music" | "tts" | "3d";
|
|
12
|
+
export type MediaType = "image" | "video" | "music" | "tts" | "3d" | "stt" | "embedding" | "video_understanding" | "image_understanding" | "voice_clone" | "rerank" | "document_parsing";
|
|
13
13
|
export interface MediaRequest {
|
|
14
14
|
/** Generation model id, e.g. "doubao-seedream-5-0-260128", "gpt-image-2" */
|
|
15
15
|
model: string;
|
|
@@ -39,12 +39,79 @@ export interface MediaRequest {
|
|
|
39
39
|
channel?: string;
|
|
40
40
|
/** Source video URLs for edit/merge operations */
|
|
41
41
|
sourceVideos?: string[];
|
|
42
|
-
/** Reference images
|
|
42
|
+
/** Reference images (no role / first_frame / last_frame) */
|
|
43
43
|
referenceImages?: string[];
|
|
44
|
+
/** Reference image roles — parallel array with referenceImages. */
|
|
45
|
+
imageRoles?: Array<"first_frame" | "last_frame" | "reference_image">;
|
|
46
|
+
/** Reference video URLs for multimodal reference generation (Seedance 2.0) */
|
|
47
|
+
referenceVideos?: string[];
|
|
48
|
+
/** Reference audio URLs for multimodal reference generation (Seedance 2.0) */
|
|
49
|
+
referenceAudios?: string[];
|
|
50
|
+
/** Generate synchronized audio track (Seedance 2.0 / 1.5 pro) */
|
|
51
|
+
generateAudio?: boolean;
|
|
44
52
|
/** Output resolution for upscale, e.g. "1080p" */
|
|
45
53
|
resolution?: string;
|
|
46
|
-
/** Operation variant: generate (default), edit, merge, upscale */
|
|
47
|
-
operation?: "generate" | "edit" | "merge" | "upscale";
|
|
54
|
+
/** Operation variant: generate (default), edit, merge, upscale, multimodal_reference, extend */
|
|
55
|
+
operation?: "generate" | "edit" | "merge" | "upscale" | "multimodal_reference" | "extend";
|
|
56
|
+
/** Image/video quality, e.g. "auto", "high", "low", "hd" */
|
|
57
|
+
quality?: string;
|
|
58
|
+
/** Seed for reproducible generation */
|
|
59
|
+
seed?: number;
|
|
60
|
+
/** TTS voice, e.g. "alloy", "nova", "shimmer" */
|
|
61
|
+
voice?: string;
|
|
62
|
+
/** TTS speech speed multiplier */
|
|
63
|
+
speed?: number;
|
|
64
|
+
/** Pure instrumental mode (MiniMax music) */
|
|
65
|
+
isInstrumental?: boolean;
|
|
66
|
+
/** Source audio URL for cover/remix (MiniMax music) */
|
|
67
|
+
audioUrl?: string;
|
|
68
|
+
/** Output audio format, e.g. "mp3", "wav", "flac" */
|
|
69
|
+
audioFormat?: string;
|
|
70
|
+
/** Video frames per second */
|
|
71
|
+
fps?: number;
|
|
72
|
+
/** Whether to add AI watermark */
|
|
73
|
+
watermark?: boolean;
|
|
74
|
+
/** img2img guidance/control strength (0-1), e.g. Volcengine */
|
|
75
|
+
guidanceScale?: number;
|
|
76
|
+
/** Auto-generate lyrics when none provided (MiniMax) */
|
|
77
|
+
lyricsOptimizer?: boolean;
|
|
78
|
+
/** 3D output format, e.g. "glb", "obj", "usd", "usdz" */
|
|
79
|
+
outputFormat?: string;
|
|
80
|
+
/** Image background mode (OpenAI gpt-image-2): "transparent", "opaque", "auto" */
|
|
81
|
+
background?: string;
|
|
82
|
+
/** Provider-specific request metadata (e.g. rerank documents, parsing options) */
|
|
83
|
+
metadata?: Record<string, unknown>;
|
|
84
|
+
/** Ask the provider to optimize/enhance the prompt before generation */
|
|
85
|
+
enhancePrompt?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Progress callback for async polling operations (video gen, 3D gen, etc.).
|
|
88
|
+
* Called periodically with estimated progress percentage and status text.
|
|
89
|
+
*/
|
|
90
|
+
onProgress?: (percent: number, status: string) => void;
|
|
91
|
+
/** Enable progressive/streaming image generation (Volcengine Seedream stream:true) */
|
|
92
|
+
streamImage?: boolean;
|
|
93
|
+
/** Lock camera position (Seedance 1.0/1.5, not Seedance 2.0) */
|
|
94
|
+
cameraFixed?: boolean;
|
|
95
|
+
/** Return last frame URL for chaining continuous video segments */
|
|
96
|
+
returnLastFrame?: boolean;
|
|
97
|
+
/** Service tier: 'default' (online) or 'flex' (offline, ~50% cost) — not all models support flex */
|
|
98
|
+
serviceTier?: "default" | "flex";
|
|
99
|
+
/** Task expiration in seconds (for flex/offline scheduling) */
|
|
100
|
+
executionExpiresAfterSeconds?: number;
|
|
101
|
+
/** Draft mode — low-cost preview (Seedance 1.5 pro only) */
|
|
102
|
+
draft?: boolean;
|
|
103
|
+
/** Draft task ID to promote to final video */
|
|
104
|
+
draftTaskId?: string;
|
|
105
|
+
/** Video-level builtin tools, e.g. ["web_search"] (Seedance 2.0) */
|
|
106
|
+
videoTools?: string[];
|
|
107
|
+
/** End-user safety identifier for content moderation */
|
|
108
|
+
safetyIdentifier?: string;
|
|
109
|
+
/** Callback URL for async task status push notifications */
|
|
110
|
+
callbackUrl?: string;
|
|
111
|
+
/** Image detail level control: 'auto' | 'low' | 'high' */
|
|
112
|
+
detail?: "auto" | "low" | "high";
|
|
113
|
+
/** Max image pixels budget (Volcengine image_pixel_limit) */
|
|
114
|
+
imagePixelLimit?: number;
|
|
48
115
|
}
|
|
49
116
|
export interface MediaResult {
|
|
50
117
|
/** URLs of generated media files */
|
|
@@ -61,6 +128,10 @@ export interface MediaResult {
|
|
|
61
128
|
billingQuantity?: number;
|
|
62
129
|
/** Provider-specific metadata */
|
|
63
130
|
metadata?: Record<string, unknown>;
|
|
131
|
+
/** Last frame image URL for chaining continuous video generation */
|
|
132
|
+
lastFrameUrl?: string;
|
|
133
|
+
/** Task ID (for continuing draft→final or querying) */
|
|
134
|
+
taskId?: string;
|
|
64
135
|
}
|
|
65
136
|
export interface MediaTransport {
|
|
66
137
|
/**
|
|
@@ -9,9 +9,116 @@
|
|
|
9
9
|
* Layer 2: model-catalog.ts remote (models.dev)
|
|
10
10
|
* Layer 3: user config (from agent.turn.config)
|
|
11
11
|
*/
|
|
12
|
-
export type TransportType = "openai-chat" | "anthropic-messages";
|
|
12
|
+
export type TransportType = "openai-chat" | "anthropic-messages" | "volcengine-responses";
|
|
13
13
|
export type AuthType = "bearer" | "x-api-key" | "none";
|
|
14
|
-
export type MediaCapability = "image" | "video" | "music" | "tts" | "3d";
|
|
14
|
+
export type MediaCapability = "image" | "video" | "music" | "tts" | "3d" | "stt" | "embedding" | "video_understanding" | "image_understanding" | "voice_clone" | "rerank" | "document_parsing";
|
|
15
|
+
export type VideoOperation = "text2video" | "img2video" | "video2video" | "edit" | "merge" | "upscale";
|
|
16
|
+
export type ImageOperation = "text2image" | "img2img" | "inpainting" | "outpainting";
|
|
17
|
+
export type MusicOperation = "text2music" | "cover";
|
|
18
|
+
export type TtsOperation = "text2speech" | "voice_clone";
|
|
19
|
+
export type ThreeDOperation = "text2_3d" | "img2_3d";
|
|
20
|
+
export interface VideoCapabilities {
|
|
21
|
+
type: "video";
|
|
22
|
+
operations: VideoOperation[];
|
|
23
|
+
maxDurationSeconds?: number;
|
|
24
|
+
resolutions?: string[];
|
|
25
|
+
aspectRatios?: string[];
|
|
26
|
+
fps?: number[];
|
|
27
|
+
}
|
|
28
|
+
export interface ImageCapabilities {
|
|
29
|
+
type: "image";
|
|
30
|
+
operations: ImageOperation[];
|
|
31
|
+
sizes?: string[];
|
|
32
|
+
transparentBackground?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface MusicCapabilities {
|
|
35
|
+
type: "music";
|
|
36
|
+
operations: MusicOperation[];
|
|
37
|
+
maxDurationSeconds?: number;
|
|
38
|
+
formats?: string[];
|
|
39
|
+
}
|
|
40
|
+
export interface TtsCapabilities {
|
|
41
|
+
type: "tts";
|
|
42
|
+
operations?: TtsOperation[];
|
|
43
|
+
voices?: string[];
|
|
44
|
+
maxCharacters?: number;
|
|
45
|
+
formats?: string[];
|
|
46
|
+
}
|
|
47
|
+
export interface ThreeDCapabilities {
|
|
48
|
+
type: "3d";
|
|
49
|
+
operations: ThreeDOperation[];
|
|
50
|
+
outputFormats?: string[];
|
|
51
|
+
}
|
|
52
|
+
export interface SttCapabilities {
|
|
53
|
+
type: "stt";
|
|
54
|
+
languages?: string[];
|
|
55
|
+
maxDurationSeconds?: number;
|
|
56
|
+
formats?: string[];
|
|
57
|
+
}
|
|
58
|
+
export interface EmbeddingCapabilities {
|
|
59
|
+
type: "embedding";
|
|
60
|
+
dimensions?: number;
|
|
61
|
+
maxTokens?: number;
|
|
62
|
+
}
|
|
63
|
+
export interface VideoUnderstandingCapabilities {
|
|
64
|
+
type: "video_understanding";
|
|
65
|
+
maxDurationSeconds?: number;
|
|
66
|
+
formats?: string[];
|
|
67
|
+
}
|
|
68
|
+
export interface ImageUnderstandingCapabilities {
|
|
69
|
+
type: "image_understanding";
|
|
70
|
+
formats?: string[];
|
|
71
|
+
}
|
|
72
|
+
export interface VoiceCloneCapabilities {
|
|
73
|
+
type: "voice_clone";
|
|
74
|
+
maxSampleDurationSeconds?: number;
|
|
75
|
+
maxSampleSizeMB?: number;
|
|
76
|
+
formats?: string[];
|
|
77
|
+
}
|
|
78
|
+
export interface RerankCapabilities {
|
|
79
|
+
type: "rerank";
|
|
80
|
+
maxDocuments?: number;
|
|
81
|
+
maxQueryLength?: number;
|
|
82
|
+
maxDocumentLength?: number;
|
|
83
|
+
}
|
|
84
|
+
export interface DocumentParsingCapabilities {
|
|
85
|
+
type: "document_parsing";
|
|
86
|
+
supportedFormats?: string[];
|
|
87
|
+
maxPageCount?: number;
|
|
88
|
+
maxFileSizeMB?: number;
|
|
89
|
+
}
|
|
90
|
+
export type MediaCapabilities = VideoCapabilities | ImageCapabilities | MusicCapabilities | TtsCapabilities | ThreeDCapabilities | SttCapabilities | EmbeddingCapabilities | VideoUnderstandingCapabilities | ImageUnderstandingCapabilities | VoiceCloneCapabilities | RerankCapabilities | DocumentParsingCapabilities;
|
|
91
|
+
/**
|
|
92
|
+
* Provider-specific quirks — drives conditional logic in transports.
|
|
93
|
+
* CC parity: provider detection via quirks flags instead of hardcoded if/else.
|
|
94
|
+
* altcode parity: provider auto-detect + per-provider parameter translation.
|
|
95
|
+
*/
|
|
96
|
+
export interface ProviderQuirks {
|
|
97
|
+
/** Provider doesn't support thinking content blocks (Qwen) */
|
|
98
|
+
filterThinkingBlocks?: boolean;
|
|
99
|
+
/** Provider doesn't support image content blocks — strip imageUrls before sending (DeepSeek, MiniMax) */
|
|
100
|
+
filterImageBlocks?: boolean;
|
|
101
|
+
/** DeepSeek: budget_tokens ignored, use output_config.effort instead */
|
|
102
|
+
useEffortInsteadOfBudget?: boolean;
|
|
103
|
+
/** Provider supports reasoning_effort param (Kimi K2, OpenAI o-series) */
|
|
104
|
+
supportsReasoningEffort?: boolean;
|
|
105
|
+
/** Provider has built-in web search (Kimi: builtin_function.$web_search, GLM: web_search) */
|
|
106
|
+
builtinWebSearch?: boolean;
|
|
107
|
+
/** Provider has built-in code interpreter */
|
|
108
|
+
builtinCodeInterpreter?: boolean;
|
|
109
|
+
/** Supports thinking.type="enabled"/"disabled" body param (Kimi K2, GLM).
|
|
110
|
+
* Disambiguation: GLM also sets supportsToolStream; Kimi does not. */
|
|
111
|
+
supportsThinkingParam?: boolean;
|
|
112
|
+
/** GLM-only: supports tool_stream=true for incremental tool call streaming */
|
|
113
|
+
supportsToolStream?: boolean;
|
|
114
|
+
/** DeepSeek only maps to "high"|"max"; low/medium→high */
|
|
115
|
+
maxReasoningEffort?: "high" | "max";
|
|
116
|
+
/** Supports prefix completion via /beta endpoint (DeepSeek Beta) */
|
|
117
|
+
supportsPrefixCompletion?: boolean;
|
|
118
|
+
/** MiniMax OpenAI route: inject reasoning_split=true to split thinking into reasoning_details.
|
|
119
|
+
* Streaming uses cumulative string updates (not incremental deltas). */
|
|
120
|
+
supportsReasoningSplit?: boolean;
|
|
121
|
+
}
|
|
15
122
|
export interface ProviderDef {
|
|
16
123
|
/** Unique provider id, e.g. "deepseek", "openai", "anthropic" */
|
|
17
124
|
id: string;
|
|
@@ -21,6 +128,12 @@ export interface ProviderDef {
|
|
|
21
128
|
transport: TransportType;
|
|
22
129
|
/** API base URL, e.g. "https://api.deepseek.com" */
|
|
23
130
|
baseUrl: string;
|
|
131
|
+
/**
|
|
132
|
+
* Logical provider group — links protocol variants of the same vendor.
|
|
133
|
+
* e.g. both "zhipu" (anthropic) and "zhipu-openai" share group "zhipu".
|
|
134
|
+
* Defaults to provider id if unset.
|
|
135
|
+
*/
|
|
136
|
+
group?: string;
|
|
24
137
|
/** Env var names for API key (priority order) */
|
|
25
138
|
apiKeyEnvVars: string[];
|
|
26
139
|
/** Auth header style */
|
|
@@ -37,9 +150,11 @@ export interface ProviderDef {
|
|
|
37
150
|
supportsStreamOptions?: boolean;
|
|
38
151
|
/** Whether to omit temperature when it equals 0 (some providers reject 0) */
|
|
39
152
|
omitZeroTemperature?: boolean;
|
|
153
|
+
/** Provider-specific quirks for transport-level conditional logic */
|
|
154
|
+
quirks?: ProviderQuirks;
|
|
40
155
|
}
|
|
41
156
|
export interface ModelInfo {
|
|
42
|
-
/** Model id, e.g. "deepseek-
|
|
157
|
+
/** Model id, e.g. "deepseek-v4-flash" */
|
|
43
158
|
id: string;
|
|
44
159
|
/** Display name, e.g. "DeepSeek Chat V3" */
|
|
45
160
|
name: string;
|
|
@@ -51,6 +166,10 @@ export interface ModelInfo {
|
|
|
51
166
|
toolCall: boolean;
|
|
52
167
|
/** Has reasoning/thinking mode */
|
|
53
168
|
reasoning: boolean;
|
|
169
|
+
/** Thinking is forced on — cannot be toggled off (e.g. QwQ, DeepSeek-R1) */
|
|
170
|
+
reasoningRequired?: boolean;
|
|
171
|
+
/** Model only supports streaming (non-stream requests will fail) */
|
|
172
|
+
streamRequired?: boolean;
|
|
54
173
|
/** Supports vision (image input) */
|
|
55
174
|
vision: boolean;
|
|
56
175
|
/** Cost per 1M input tokens (USD) */
|
|
@@ -63,4 +182,6 @@ export interface ModelInfo {
|
|
|
63
182
|
costCacheWrite?: number;
|
|
64
183
|
/** Media generation capability — undefined means chat/reasoning model */
|
|
65
184
|
mediaType?: MediaCapability;
|
|
185
|
+
/** Fine-grained media capabilities — operations, formats, limits */
|
|
186
|
+
mediaCapabilities?: MediaCapabilities;
|
|
66
187
|
}
|
|
@@ -41,6 +41,11 @@ export declare class ProviderRegistry {
|
|
|
41
41
|
* Merges: Layer 3 override > Layer 1 builtin > Layer 2 catalog enrichment.
|
|
42
42
|
*/
|
|
43
43
|
listModels(providerId: string): ModelInfo[];
|
|
44
|
+
/**
|
|
45
|
+
* Look up a single model's info by provider + model id.
|
|
46
|
+
* Returns undefined if the model is not found.
|
|
47
|
+
*/
|
|
48
|
+
getModelInfo(providerId: string, modelId: string): ModelInfo | undefined;
|
|
44
49
|
/**
|
|
45
50
|
* Trigger background refresh of the remote model catalog.
|
|
46
51
|
*/
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProviderToolAPI — interface for provider-specific utility endpoints
|
|
3
|
+
* that are neither LLM chat nor media generation.
|
|
4
|
+
*
|
|
5
|
+
* Examples: web search, content reader, tokenizer, moderation, realtime voice.
|
|
6
|
+
* Each provider can expose its own set of tool APIs; the agent's tool cascade
|
|
7
|
+
* mechanism (Q1) routes to these when the provider has a native capability.
|
|
8
|
+
*/
|
|
9
|
+
export interface WebSearchResult {
|
|
10
|
+
title: string;
|
|
11
|
+
url: string;
|
|
12
|
+
snippet: string;
|
|
13
|
+
/** Full page content if available */
|
|
14
|
+
content?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ReaderResult {
|
|
17
|
+
title: string;
|
|
18
|
+
content: string;
|
|
19
|
+
url: string;
|
|
20
|
+
}
|
|
21
|
+
export interface TokenizerResult {
|
|
22
|
+
tokenCount: number;
|
|
23
|
+
model: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ModerationResult {
|
|
26
|
+
flagged: boolean;
|
|
27
|
+
categories: Record<string, boolean>;
|
|
28
|
+
scores?: Record<string, number>;
|
|
29
|
+
}
|
|
30
|
+
export interface ProviderToolAPI {
|
|
31
|
+
/** Which tool APIs this provider supports */
|
|
32
|
+
readonly capabilities: readonly ProviderToolCapability[];
|
|
33
|
+
/** Web search — returns search result list */
|
|
34
|
+
webSearch?(query: string, options?: {
|
|
35
|
+
maxResults?: number;
|
|
36
|
+
}): Promise<WebSearchResult[]>;
|
|
37
|
+
/** URL reader — extracts content from a web page */
|
|
38
|
+
reader?(url: string): Promise<ReaderResult>;
|
|
39
|
+
/** Tokenizer — count tokens for given text/model */
|
|
40
|
+
tokenize?(text: string, model: string): Promise<TokenizerResult>;
|
|
41
|
+
/** Content moderation — check text for policy violations */
|
|
42
|
+
moderate?(text: string): Promise<ModerationResult>;
|
|
43
|
+
}
|
|
44
|
+
export type ProviderToolCapability = "web_search" | "reader" | "tokenizer" | "moderations";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared retry/backoff utilities for LLM transport implementations.
|
|
3
|
+
*
|
|
4
|
+
* Provides common constants and helper functions used by all transports
|
|
5
|
+
* (anthropic-messages, openai-chat, volcengine-responses) to handle
|
|
6
|
+
* transient errors with exponential backoff.
|
|
7
|
+
*/
|
|
8
|
+
/** Default maximum number of retry attempts */
|
|
9
|
+
export declare const DEFAULT_MAX_RETRIES = 3;
|
|
10
|
+
/** Base delay for exponential backoff (doubles each attempt, capped at 30s) */
|
|
11
|
+
export declare const RETRY_BASE_DELAY_MS = 1000;
|
|
12
|
+
/** Maximum backoff delay */
|
|
13
|
+
export declare const RETRY_MAX_DELAY_MS = 30000;
|
|
14
|
+
/** HTTP status codes considered transient (worth retrying) */
|
|
15
|
+
export declare const TRANSIENT_STATUS_CODES: Set<number>;
|
|
16
|
+
/** Default timeout for idle stream detection (no data received) */
|
|
17
|
+
export declare const STREAM_IDLE_TIMEOUT_MS = 90000;
|
|
18
|
+
/**
|
|
19
|
+
* Calculate the delay for a given retry attempt using exponential backoff with jitter.
|
|
20
|
+
* @param attempt 1-based attempt number (1 = first retry)
|
|
21
|
+
* @returns delay in milliseconds
|
|
22
|
+
*/
|
|
23
|
+
export declare function retryDelay(attempt: number): number;
|
|
24
|
+
/**
|
|
25
|
+
* Check if an HTTP status code indicates a transient error worth retrying.
|
|
26
|
+
*/
|
|
27
|
+
export declare function isTransientStatus(status: number | null | undefined): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Sleep with abort signal support. Resolves after `ms` milliseconds
|
|
30
|
+
* or rejects if the signal is aborted.
|
|
31
|
+
*/
|
|
32
|
+
export declare function retrySleep(ms: number, signal?: AbortSignal): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Extract HTTP status from various error shapes.
|
|
35
|
+
* Works with fetch Response errors, Axios errors, and generic errors with status property.
|
|
36
|
+
*/
|
|
37
|
+
export declare function extractHttpStatus(error: unknown): number | null;
|