@leviyuan/lodestar 0.19.12 → 0.19.14

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.
@@ -16,7 +16,6 @@ var inject = ["agents", "llm", "agentDefaultModel", "sessionPersistence", "tools
16
16
  var PROVIDER = process.env.LODESTAR_DSH_PROVIDER ?? "deepseek-official";
17
17
  if (!["deepseek-official", "zai-coding-cn", "zai"].includes(PROVIDER))
18
18
  throw new Error(`Unsupported DSH provider: ${PROVIDER}`);
19
- var DELEGATION_TOOLS = ["subagent", "subagent_fork", "workflow", "ralph", "send_message"];
20
19
  function nativeErrorMessage(error, depth = 0) {
21
20
  if (!(error instanceof Error))
22
21
  return String(error);
@@ -56,8 +55,8 @@ function apply(ctx) {
56
55
  delete process.env.DSH_LODESTAR_AGENT_CONTEXT;
57
56
  ctx.shellEnv.register({
58
57
  name: "lodestar-agent",
59
- variables: { DSH_LODESTAR_AGENT_CONTEXT: { description: "Lodestar delegation context for the current root agent only." } },
60
- resolve: (execution) => delegationContext && execution.agent === root?.agent ? { DSH_LODESTAR_AGENT_CONTEXT: delegationContext } : {}
58
+ variables: { DSH_LODESTAR_AGENT_CONTEXT: { description: "Inherited Lodestar task context for this agent and its native descendants." } },
59
+ resolve: () => delegationContext ? { DSH_LODESTAR_AGENT_CONTEXT: delegationContext } : {}
61
60
  });
62
61
  const settle = () => {
63
62
  if (root?.agent.status === "idle" && turnFailure && lastEnd?.data.turn !== activeTurn) {
@@ -113,7 +112,6 @@ function apply(ctx) {
113
112
  ctx.on("agent/created", ({ agent }) => {
114
113
  if (agent.session.id === rootId)
115
114
  return;
116
- agent.ctx.tools.restrict({ deny: DELEGATION_TOOLS });
117
115
  notify("subagent.started", { sessionId: agent.session.id, parentSessionId: agent.session.header.parentSession });
118
116
  });
119
117
  ctx.on("agent/disposed", ({ agent }) => {
@@ -193,8 +191,6 @@ function apply(ctx) {
193
191
  const resolved = await next();
194
192
  return payload.agent === agent ? { ...resolved, ...turnRoute } : resolved;
195
193
  });
196
- if (!input.allowDelegation)
197
- agentCtx.tools.restrict({ deny: DELEGATION_TOOLS });
198
194
  if (input.allowUserInput === false)
199
195
  agentCtx.tools.restrict({ deny: ["ask_user_question"] });
200
196
  if (input.allowedTools)
@@ -119,7 +119,7 @@ try {
119
119
  `:Yf(C));return}case"run":await Cf(I,A);return;case"follow-up":case"followup":await Ef(I,A);return;case"answer":await gf(I,A);return;case"status":{let C=NC(A[0],"status requires run_id"),g=await LI(I,"GET",`/agents/runs/${encodeURIComponent(C)}`);if(t1(g,A.includes("--json")),g.status==="failed"||g.status==="cancelled")process.exitCode=1;return}case"cancel":{let C=NC(A[0],"cancel requires run_id"),g=await LI(I,"DELETE",`/agents/runs/${encodeURIComponent(C)}`);process.stdout.write(`${JSON.stringify(g)}
120
120
  `);return}default:throw Error(n1())}}async function Cf(A,Q){let B=a1(Q,!0),I=await o1(B),C={identity_ids:B.identityIds,description:B.description,prompt:I,...B.effort?{effort:B.effort}:{},...B.sessionId?{session_id:B.sessionId}:{},...B.workDir?{work_dir:B.workDir}:{},...B.requestId?{request_id:B.requestId}:{},...B.requesterOpenId?{requester_open_id:B.requesterOpenId}:{}},g=await LI(A,"POST","/agents/runs",C);await s1(A,g,B.noWait,B.json)}async function Ef(A,Q){let B=NC(Q.shift(),"follow-up requires run_id"),I=a1(Q,!1),C=await o1(I),g={description:I.description,prompt:C,...I.identityId?{identity_id:I.identityId}:{},...I.effort?{effort:I.effort}:{},...I.workDir?{work_dir:I.workDir}:{},...I.requestId?{request_id:I.requestId}:{},...I.requesterOpenId?{requester_open_id:I.requesterOpenId}:{}},F=await LI(A,"POST",`/agents/runs/${encodeURIComponent(B)}/follow-up`,g);await s1(A,F,I.noWait,I.json)}async function gf(A,Q){if(A.project)throw Error(v1);let B=NC(Q.shift(),"answer requires run_id"),I="",C="",g=!1,F={};for(let J=0;J<Q.length;J++){let N=Q[J],G=()=>NC(Q[++J],`${N} requires a value`);switch(N){case"--identity":case"-i":I=G();break;case"--request":C=G();break;case"--answer":{let M=G(),V=M.indexOf("=");if(V<=0)throw Error("--answer must be question-or-id=value");F[M.slice(0,V)]=M.slice(V+1);break}case"--stdin":g=!0;break;default:throw Error(`unknown answer option: ${N}`)}}if(g){let J=(await e1()).trim(),N;try{N=JSON.parse(J)}catch{throw Error("answer stdin must be a JSON object")}if(!N||typeof N!=="object"||Array.isArray(N))throw Error("answer stdin must be a JSON object");for(let[G,M]of Object.entries(N))F[G]=String(M)}if(!C)throw Error("answer requires --request");if(Object.keys(F).length===0)throw Error("answer requires --answer or --stdin");let Y=await LI(A,"POST",`/agents/runs/${encodeURIComponent(B)}/answer`,{request_id:C,answers:F,...I?{identity_id:I}:{}});await r1(A,String(Y.run_id??B))}function a1(A,Q){let B={identityIds:[],identityId:"",sessionId:"",workDir:"",effort:"",description:"",prompt:"",noWait:!1,readStdin:!1,json:!1},I=[];for(let C=0;C<A.length;C++){let g=A[C],F=()=>NC(A[++C],`${g} requires a value`);switch(g){case"--identity":case"-i":if(Q)B.identityIds.push(F());else B.identityId=F();break;case"--effort":B.effort=F();break;case"--request-id":if(B.requestId)throw Error("--request-id may only be specified once");B.requestId=F();break;case"--requester":if(B.requesterOpenId)throw Error("--requester may only be specified once");B.requesterOpenId=F();break;case"--description":B.description=F();break;case"--workdir":if(B.workDir)throw Error("--workdir may only be specified once");F(),B.workDir=A[C];break;case"--session":if(!Q)throw Error("--session is only supported by run; follow-up accepts a run_id");if(B.sessionId)throw Error("--session may only be specified once");B.sessionId=F();break;case"--prompt":F(),B.prompt=A[C];break;case"--stdin":B.readStdin=!0;break;case"--no-wait":B.noWait=!0;break;case"--json":B.json=!0;break;default:if(g.startsWith("-"))throw Error(`unknown option: ${g}`);I.push(g)}}if(B.identityIds=[...new Set(B.identityIds)],B.sessionId&&B.identityIds.length>1)throw Error("--session accepts at most one --identity");if(Q&&!B.sessionId&&B.identityIds.length===0)throw Error("run requires at least one --identity");if(B.description=f1(B.description),!B.prompt&&I.length)B.prompt=I.join(" ");if(!B.prompt)B.readStdin=!0;return B}async function o1(A){let Q=A.readStdin?await e1():"",B=A.prompt||Q;if(!B.trim())throw Error("agent prompt is empty");return B}async function s1(A,Q,B,I){let C=String(Q.run_id??"");if(!C)throw Error("agent API returned no run_id");if(B){if(process.stdout.write(`${JSON.stringify(Q,null,2)}
121
121
  `),Q.status==="failed"||Q.status==="cancelled")process.exitCode=1;return}await r1(A,C,I)}async function r1(A,Q,B=!1){let I=!1,C=()=>{if(I)return;I=!0,LI(A,"DELETE",`/agents/runs/${encodeURIComponent(Q)}`).then(()=>process.exit(130),(g)=>{process.stderr.write(`lodestar-agent: cancellation failed: ${A8(g)}
122
- `),process.exit(1)})};process.once("SIGINT",C),process.once("SIGTERM",C);try{while(!0){let g=await LI(A,"GET",`/agents/runs/${encodeURIComponent(Q)}`);if(g.status==="needs_input"||g.status==="completed"||g.status==="failed"||g.status==="cancelled"){if(t1(g,B),g.status==="failed"||g.status==="cancelled")process.exitCode=1;return}await new Promise((F)=>setTimeout(F,1000))}}finally{process.off("SIGINT",C),process.off("SIGTERM",C)}}function Ff(A){let Q,B=[],I=new Set(["--identity","-i","--effort","--description","--workdir","--session","--prompt","--request","--answer","--request-id","--requester"]);for(let C=0;C<A.length;C++){let g=A[C];if(g==="--project"){if(Q!==void 0)throw Error("--project may only be specified once");Q=NC(A[++C],"--project requires a project name")}else if(B.push(g),I.has(g)&&C+1<A.length)B.push(A[++C])}return{...Q!==void 0?{project:Q}:{},argv:B}}function Df(A){if(A!==void 0){if(process.env.LODESTAR_AGENT_ROLE==="worker")throw Error("Delegated Agents cannot start project calls");if(["LODESTAR_AGENT_ROLE","LODESTAR_AGENT_URL","LODESTAR_AGENT_CAPABILITY","LODESTAR_AGENT_SESSION","DSH_LODESTAR_AGENT_CONTEXT"].some((I)=>process.env[I]!==void 0))throw Error("Agent task calls must remain session-bound; --project is only for independent services and applications");return{...d1(),project:A}}if(process.env.DSH_LODESTAR_AGENT_CONTEXT!==void 0){let I=JSON.parse(process.env.DSH_LODESTAR_AGENT_CONTEXT);if(typeof I.baseUrl!=="string"||!I.baseUrl||typeof I.capability!=="string"||!I.capability)throw Error("invalid DSH Lodestar delegation context");return{baseUrl:I.baseUrl.replace(/\/+$/,""),capability:I.capability}}let Q=String(process.env.LODESTAR_AGENT_URL??"").replace(/\/+$/,""),B=String(process.env.LODESTAR_AGENT_CAPABILITY??"");if(!Q||!B)throw Error("lodestar-agent must run inside a Lodestar-managed Agent session (missing capability)");return{baseUrl:Q,capability:B}}async function LI(A,Q,B,I){let C=new URL(`${A.baseUrl}${B}`);if(A.project)C.searchParams.set("project",A.project);let g=await y1(C.toString(),{method:Q,headers:{authorization:`Bearer ${A.capability}`,...I?{"content-type":"application/json"}:{}},...I?{body:JSON.stringify(I)}:{}}),F=await g.text(),Y;try{Y=JSON.parse(F)}catch{throw Error(`agent API ${Q} ${B} returned HTTP ${g.status}: ${F||"(empty)"}`)}if(!g.ok)throw Error(Y?.error??`agent API HTTP ${g.status}`);return Y}function Yf(A){let Q=[`catalog ${A.catalog_generation??"MISS"}`];for(let B of A.identities??[])Q.push([B.status==="ready"?"✅":"MISS",B.id,B.display_name,B.model,`default-effort=${B.default_effort}`,B.source_default?"source-default":"",B.reason??""].filter(Boolean).join(" · "));for(let B of A.source_failures??[])Q.push(`MISS · ${B.display} · ${B.reason}`);return`${Q.join(`
122
+ `),process.exit(1)})};process.once("SIGINT",C),process.once("SIGTERM",C);try{while(!0){let g=await LI(A,"GET",`/agents/runs/${encodeURIComponent(Q)}`);if(g.status==="needs_input"||g.status==="completed"||g.status==="failed"||g.status==="cancelled"){if(t1(g,B),g.status==="failed"||g.status==="cancelled")process.exitCode=1;return}await new Promise((F)=>setTimeout(F,1000))}}finally{process.off("SIGINT",C),process.off("SIGTERM",C)}}function Ff(A){let Q,B=[],I=new Set(["--identity","-i","--effort","--description","--workdir","--session","--prompt","--request","--answer","--request-id","--requester"]);for(let C=0;C<A.length;C++){let g=A[C];if(g==="--project"){if(Q!==void 0)throw Error("--project may only be specified once");Q=NC(A[++C],"--project requires a project name")}else if(B.push(g),I.has(g)&&C+1<A.length)B.push(A[++C])}return{...Q!==void 0?{project:Q}:{},argv:B}}function Df(A){if(A!==void 0){if(["LODESTAR_AGENT_ROLE","LODESTAR_AGENT_URL","LODESTAR_AGENT_CAPABILITY","LODESTAR_AGENT_SESSION","DSH_LODESTAR_AGENT_CONTEXT"].some((I)=>process.env[I]!==void 0))throw Error("Agent task calls must remain session-bound; --project is only for independent services and applications");return{...d1(),project:A}}if(process.env.DSH_LODESTAR_AGENT_CONTEXT!==void 0){let I=JSON.parse(process.env.DSH_LODESTAR_AGENT_CONTEXT);if(typeof I.baseUrl!=="string"||!I.baseUrl||typeof I.capability!=="string"||!I.capability)throw Error("invalid DSH Lodestar delegation context");return{baseUrl:I.baseUrl.replace(/\/+$/,""),capability:I.capability}}let Q=String(process.env.LODESTAR_AGENT_URL??"").replace(/\/+$/,""),B=String(process.env.LODESTAR_AGENT_CAPABILITY??"");if(!Q||!B)throw Error("lodestar-agent must run inside a Lodestar-managed Agent session (missing capability)");return{baseUrl:Q,capability:B}}async function LI(A,Q,B,I){let C=new URL(`${A.baseUrl}${B}`);if(A.project)C.searchParams.set("project",A.project);let g=await y1(C.toString(),{method:Q,headers:{authorization:`Bearer ${A.capability}`,...I?{"content-type":"application/json"}:{}},...I?{body:JSON.stringify(I)}:{}}),F=await g.text(),Y;try{Y=JSON.parse(F)}catch{throw Error(`agent API ${Q} ${B} returned HTTP ${g.status}: ${F||"(empty)"}`)}if(!g.ok)throw Error(Y?.error??`agent API HTTP ${g.status}`);return Y}function Yf(A){let Q=[`catalog ${A.catalog_generation??"MISS"}`];for(let B of A.identities??[])Q.push([B.status==="ready"?"✅":"MISS",B.id,B.display_name,B.model,`default-effort=${B.default_effort}`,B.source_default?"source-default":"",B.reason??""].filter(Boolean).join(" · "));for(let B of A.source_failures??[])Q.push(`MISS · ${B.display} · ${B.reason}`);return`${Q.join(`
123
123
  `)}
124
124
  `}function t1(A,Q){process.stdout.write(Q?`${JSON.stringify(A,null,2)}
125
125
  `:Uf(A))}function Uf(A){let Q=`lodestar-agent${A.binding==="project"?` --project ${kE(String(A.project))}`:""}`,B=[`# Lodestar agent ${A.run_id??"MISS"}`,"",`- Status: ${A.status??"MISS"}`,...A.binding==="project"?[`- Project: ${A.project}`]:[],`- Description: ${A.description??"MISS"}`,`- Work directory: ${A.work_dir??"MISS"}`,...A.parent_run_id?[`- Parent: ${A.parent_run_id} (${A.parent_kind??"delegate"})`]:[]];if(A.error)B.push(`- Error: ${A.error}`);for(let I of A.workers??[]){if(B.push("",`## ${I.identity_name??I.identity_id}`,"",`Status: ${I.status}`),I.session_id)B.push(`Session: ${I.session_id}`);if(I.error)B.push("",`Error: ${I.error}`);if(I.pending_input){B.push("",`Input request: ${I.pending_input.request_id}`);for(let C of I.pending_input.questions??[])if(B.push(`- [${C.id}] ${C.question}`),C.options?.length)B.push(` Options: ${C.options.map((g)=>g.label).join(" / ")}`);B.push("","Answer with:",`${Q} answer ${kE(A.run_id)} --identity ${kE(I.identity_id)} --request ${kE(I.pending_input.request_id)} --stdin`)}if(I.output)B.push("",I.output);if(I.session_id&&I.identity_id&&["completed","failed","cancelled"].includes(A.status))B.push("","Continue with:",`${Q} run --session ${kE(I.session_id)} --identity ${kE(I.identity_id)} --description '<brief next step>' --stdin`)}if(A.presentation_errors?.length)B.push("","Presentation errors:",...A.presentation_errors.map((I)=>`- ${I}`));return`${B.join(`