@roll-agent/core 0.6.1 → 0.6.3
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/cli/commands/run.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFileSync as
|
|
1
|
+
import{readFileSync as t}from"node:fs";import{defineCommand as o}from"citty";import{loadConfig as r}from"../../config/loader.js";import{getAgentEnv as e,getMissingAgentEnvRuntimeIssues as n,inspectAgentEnvRequirements as i}from"../../config/helpers.js";import{AgentStore as s}from"../../registry/store.js";import{McpClientManager as l}from"../../mcp/client-manager.js";import{resolveTransportWithDevSpawnSpec as a}from"../../registry/dev-spawn.js";import{createProviderModel as c}from"../../llm/providers.js";import{formatValidationIssuesMessage as f}from"../../tool-runtime/messages.js";import{preflightToolCall as p}from"../../tool-runtime/preflight.js";import{formatMissingToolMessage as u,normalizeListedTools as m}from"../utils/agent-tools.js";import{extractTextContent as g,formatToolResultForJsonOutput as d,isToolErrorResult as h}from"../utils/tool-results.js";import{log as j,redactToolArgsForLog as v}from"../utils/output.js";import{shouldSkipRuntimeReadinessForTool as y}from"../../config/runtime-env.js";export default o({meta:{description:"声明式调用 Agent 的指定 tool"},args:{agent:{type:"positional",description:"Agent 名称",required:!0},tool:{type:"positional",description:"Tool 名称",required:!0},json:{type:"boolean",description:"JSON 格式输出",default:!1},verbose:{type:"boolean",alias:"v",description:"输出调试日志",default:!1},"input-json":{type:"string",description:"以 JSON 字符串提供完整 tool 输入对象"},"input-file":{type:"string",description:"从 JSON 文件读取完整 tool 输入对象"}},async run({args:t,rawArgs:o}){const{config:w}=r(),S=new s(w.agents.dataDir).findByName(t.agent);if(!S)return j.error(`Agent "${t.agent}" 未注册。使用 \`roll agent list\` 查看已注册 Agent。`),void(process.exitCode=1);let N;try{N=resolveToolArgs(o)}catch(t){return j.error(t instanceof Error?t.message:String(t)),void(process.exitCode=1)}const $=new l;try{const o=w.llm.defaultProvider,r=w.llm.providers[o],s=r?c(o,w.llm.defaultModel,r.apiKey,r.baseUrl):void 0;j.info(`连接 Agent "${S.skill.name}"...`);const l=e(w,S.skill.name),A=a(S),b=await $.connect(S.skill.name,A,S.installPath,{...s?{samplingModel:s}:{},...l?{env:l}:{}}),x=m((await b.listTools()).tools),E=x.find(o=>o.name===t.tool);if(!E)return j.error(u(S.skill.name,t.tool,x)),void(process.exitCode=1);const k=i(S.skill.name,S.skill.env,w.agents.env),J=y(E.name)?[]:n(k),O=p(E,N,{runtimeIssues:J});if(!O.ok)return j.error(f(S.skill.name,t.tool,O.issues,O.runtimeIssues)),void(process.exitCode=1);j.info(`调用 ${S.skill.name}.${t.tool}`),j.debug(`调用参数: ${JSON.stringify(v(N))}`);const T=await b.callTool({name:t.tool,arguments:N});if(t.json)console.log(JSON.stringify(d(T),null,2));else for(const t of g(T.content))console.log(t);if(h(T))return j.error("tool 返回 isError=true"),void(process.exitCode=1);j.success("调用完成")}catch(t){const o=t instanceof Error?t.message:String(t),r=t instanceof Error&&t.cause?`\n cause: ${String(t.cause)}`:"";j.error(`${o}${r}`),process.exitCode=1}finally{await $.disconnectAll()}}});const w=new Set(["json","verbose","v","help","h","version"]),S=new Set(["config","input-json","input-file"]);function N(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function $(t,o){let r;try{r=JSON.parse(t)}catch(t){throw new Error(`${o} 不是合法 JSON: ${t instanceof Error?t.message:String(t)}`)}if(!N(r))throw new Error(`${o} 必须是 JSON object`);return r}function A(t,o){let r=0;for(;r<t.length&&!t[r]?.startsWith("--");)r++;for(;r<t.length;){if(t[r]!==`--${o}`){r++;continue}const e=t[r+1];if(!e||e.startsWith("--"))throw new Error(`选项 --${o} 需要提供值`);return e}}export function parseExplicitToolInput(o){const r=A(o,"input-json"),e=A(o,"input-file"),n=b(o);if([r,e,n].filter(t=>void 0!==t).length>1)throw new Error("不能同时使用 positional JSON、--input-json 和 --input-file");if(r)return $(r,"--input-json");if(e){return $(t(e,"utf-8"),`输入文件 ${e}`)}return n?$(n,"positional JSON input"):void 0}function b(t){const o=[];for(const r of t){if(r.startsWith("--"))break;o.push(r)}const r=o.slice(2);if(0!==r.length){if(1===r.length&&r[0]?.trim().startsWith("{"))return r[0];throw new Error("roll run 只接受 agent/tool 两个位置参数;tool 输入请使用 --key value、--input-json、--input-file,或第三个位置参数 JSON object")}}export function resolveToolArgs(t){return{...parseExplicitToolInput(t)??{},...parseToolArgs(t)}}export function parseToolArgs(t){const o={};let r=0;for(;r<t.length&&!t[r]?.startsWith("--");)r++;for(;r<t.length;){const e=t[r];if(!e?.startsWith("--")){r++;continue}const n=e.slice(2),i=t[r+1];if(w.has(n))r++;else if(S.has(n))r+=i&&!i.startsWith("--")?2:1;else if(!i||i.startsWith("--"))o[n]=!0,r++;else{const t=Number(i);o[n]=Number.isNaN(t)?i:t,r+=2}}return o}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{describeValueType as e,getAdditionalPropertiesSetting as t,getSchemaDescription as n,getSchemaEnum as r,getSchemaItems as s,
|
|
1
|
+
import{describeValueType as e,getAdditionalPropertiesSetting as t,getSchemaDescription as n,getSchemaEnum as r,getSchemaItems as s,getSchemaMinItems as i,getSchemaProperties as u,getSchemaRequired as o,getSchemaType as c,isNaturallyExtractableSchema as a,isJsonSchemaObject as p,isPlainObject as l}from"./schema.js";function g(e,t){const r=n(t),s=t&&!a(t);return{path:e,code:s?"requires_explicit_input":"missing_required",message:s?`${e} 无法从自然语言可靠提取,需要显式提供`:`${e} 为必填字段`,...r?{description:r}:{}}}function f(e,t){if(t&&p(t)){const n=h({inputSchema:t},{},e);if(n.length>0)return n}return[g(e,t)]}function m(t,u,o){const a=[],g=n(t),f=r(t),d=c(t);if(f&&!f.some(e=>Object.is(e,u)))return a.push({path:o,code:"invalid_enum",message:`${o} 必须是以下值之一:${f.map(e=>JSON.stringify(e)).join("、")}`,...g?{description:g}:{},expected:f.map(e=>JSON.stringify(e)).join(" | "),actual:JSON.stringify(u)}),a;if(!d)return a;const $=e(u),y=()=>{a.push({path:o,code:"invalid_type",message:`${o} 应为 ${d},当前是 ${$}`,...g?{description:g}:{},expected:d,actual:$})};switch(d){case"string":return"string"!=typeof u&&y(),a;case"number":return("number"!=typeof u||Number.isNaN(u))&&y(),a;case"integer":return"number"==typeof u&&Number.isInteger(u)||y(),a;case"boolean":return"boolean"!=typeof u&&y(),a;case"null":return null!==u&&y(),a;case"array":if(!Array.isArray(u))return y(),a;{const e=i(t);void 0!==e&&u.length<e&&a.push({path:o,code:"too_small",message:`${o} 至少需要 ${String(e)} 个元素,当前是 ${String(u.length)} 个`,...g?{description:g}:{},expected:`minItems: ${String(e)}`,actual:`length: ${String(u.length)}`});const n=s(t);return n?(a.push(...u.flatMap((e,t)=>m(n,e,`${o}[${String(t)}]`))),a):a}case"object":return l(u)?p(t)?h({inputSchema:t},u,o):a:(y(),a);default:return a}}function h(e,n,r=""){const s=o(e),i=u(e.inputSchema),c=[];for(const e of s){const t=n[e];if(null!=t)continue;const s=i[e],u=r?`${r}.${e}`:e;c.push(...f(u,s))}for(const[s,u]of Object.entries(n)){const n=r?`${r}.${s}`:s,o=i[s];o?c.push(...m(o,u,n)):!1===t(e.inputSchema)&&c.push({path:n,code:"unexpected_property",message:`${n} 不是允许的参数`})}return c}export function getInputValidationIssues(e,t){return h(e,t)}export function preflightToolCall(e,t,n={}){const r=getInputValidationIssues(e,t),s=n.runtimeIssues??[];return 0===r.length&&0===s.length?{ok:!0}:{ok:!1,issues:r,runtimeIssues:s}}
|
|
@@ -5,6 +5,7 @@ export declare function getSchemaDescription(schema: object | undefined): string
|
|
|
5
5
|
export declare function getSchemaType(schema: object | undefined): string | undefined;
|
|
6
6
|
export declare function getSchemaEnum(schema: object | undefined): ReadonlyArray<unknown> | undefined;
|
|
7
7
|
export declare function getSchemaItems(schema: object | undefined): object | undefined;
|
|
8
|
+
export declare function getSchemaMinItems(schema: object | undefined): number | undefined;
|
|
8
9
|
export declare function getSchemaProperties(schema: Pick<AgentTool, "inputSchema">["inputSchema"] | object | undefined): Readonly<Record<string, object>>;
|
|
9
10
|
export declare function isNaturallyExtractableSchema(schema: object | undefined): boolean;
|
|
10
11
|
export declare function getSchemaRequired(tool: Pick<AgentTool, "inputSchema">): ReadonlyArray<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}export function isJsonSchemaObject(e){return"type"in e&&"object"===e.type}export function getSchemaDescription(e){return e&&"description"in e&&"string"==typeof e.description?e.description:void 0}export function getSchemaType(e){return e&&"type"in e&&"string"==typeof e.type?e.type:void 0}export function getSchemaEnum(e){return e&&"enum"in e&&Array.isArray(e.enum)?e.enum:void 0}export function getSchemaItems(e){return e&&"items"in e&&"object"==typeof e.items&&null!==e.items?e.items:void 0}export function getSchemaProperties(e){if(!(e&&"properties"in e&&e.properties&&isPlainObject(e.properties)))return{};const t=Object.entries(e.properties).filter(e=>{const[,t]=e;return"object"==typeof t&&null!==t});return Object.fromEntries(t)}export function isNaturallyExtractableSchema(e){return!!e&&("object"!==getSchemaType(e)||Object.keys(getSchemaProperties(e)).length>0)}export function getSchemaRequired(e){return e.inputSchema.required??[]}export function getAdditionalPropertiesSetting(e){return e&&"additionalProperties"in e&&"boolean"==typeof e.additionalProperties?e.additionalProperties:void 0}export function describeValueType(e){return null===e?"null":Array.isArray(e)?"array":typeof e}
|
|
1
|
+
export function isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}export function isJsonSchemaObject(e){return"type"in e&&"object"===e.type}export function getSchemaDescription(e){return e&&"description"in e&&"string"==typeof e.description?e.description:void 0}export function getSchemaType(e){return e&&"type"in e&&"string"==typeof e.type?e.type:void 0}export function getSchemaEnum(e){return e&&"enum"in e&&Array.isArray(e.enum)?e.enum:void 0}export function getSchemaItems(e){return e&&"items"in e&&"object"==typeof e.items&&null!==e.items?e.items:void 0}export function getSchemaMinItems(e){return e&&"minItems"in e&&"number"==typeof e.minItems?e.minItems:void 0}export function getSchemaProperties(e){if(!(e&&"properties"in e&&e.properties&&isPlainObject(e.properties)))return{};const t=Object.entries(e.properties).filter(e=>{const[,t]=e;return"object"==typeof t&&null!==t});return Object.fromEntries(t)}export function isNaturallyExtractableSchema(e){return!!e&&("object"!==getSchemaType(e)||Object.keys(getSchemaProperties(e)).length>0)}export function getSchemaRequired(e){return e.inputSchema.required??[]}export function getAdditionalPropertiesSetting(e){return e&&"additionalProperties"in e&&"boolean"==typeof e.additionalProperties?e.additionalProperties:void 0}export function describeValueType(e){return null===e?"null":Array.isArray(e)?"array":typeof e}
|
package/dist/types/ask.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export declare const ASK_RESULT_STATUSES: readonly ["success", "needs_input", "n
|
|
|
3
3
|
export type AskResultStatus = (typeof ASK_RESULT_STATUSES)[number];
|
|
4
4
|
export declare const ASK_FAILURE_STAGES: readonly ["route", "connect", "execute"];
|
|
5
5
|
export type AskFailureStage = (typeof ASK_FAILURE_STAGES)[number];
|
|
6
|
-
export declare const ASK_VALIDATION_ISSUE_CODES: readonly ["missing_required", "requires_explicit_input", "invalid_type", "invalid_enum", "unexpected_property"];
|
|
6
|
+
export declare const ASK_VALIDATION_ISSUE_CODES: readonly ["missing_required", "requires_explicit_input", "invalid_type", "invalid_enum", "too_small", "unexpected_property"];
|
|
7
7
|
export type AskValidationIssueCode = (typeof ASK_VALIDATION_ISSUE_CODES)[number];
|
|
8
8
|
export declare const ASK_RUNTIME_ISSUE_CATEGORIES: readonly ["env"];
|
|
9
9
|
export type AskRuntimeIssueCategory = (typeof ASK_RUNTIME_ISSUE_CATEGORIES)[number];
|
package/dist/types/ask.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const ASK_RESULT_STATUSES=["success","needs_input","needs_confirmation","failed"];export const ASK_FAILURE_STAGES=["route","connect","execute"];export const ASK_VALIDATION_ISSUE_CODES=["missing_required","requires_explicit_input","invalid_type","invalid_enum","unexpected_property"];export const ASK_RUNTIME_ISSUE_CATEGORIES=["env"];export const ASK_RUNTIME_ISSUE_CODES=["missing_required_env"];
|
|
1
|
+
export const ASK_RESULT_STATUSES=["success","needs_input","needs_confirmation","failed"];export const ASK_FAILURE_STAGES=["route","connect","execute"];export const ASK_VALIDATION_ISSUE_CODES=["missing_required","requires_explicit_input","invalid_type","invalid_enum","too_small","unexpected_property"];export const ASK_RUNTIME_ISSUE_CATEGORIES=["env"];export const ASK_RUNTIME_ISSUE_CODES=["missing_required_env"];
|