@astralyn/pi 1.5.0 → 1.5.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/bundle/chunks/{chunk-IRUUTK4W.js → chunk-3YGNXVKM.js} +1 -1
  3. package/dist/bundle/chunks/{chunk-THAJ4BZF.js → chunk-HLVMLRZJ.js} +3 -3
  4. package/dist/bundle/chunks/{chunk-R3YHAMWH.js → chunk-M3D4ADUT.js} +17 -17
  5. package/dist/bundle/chunks/{execute-ACWDKC3C.js → execute-SSRW6NGS.js} +1 -1
  6. package/dist/bundle/chunks/{virtual-modules-T2KLVAFL.js → virtual-modules-NFDW2JKH.js} +1 -1
  7. package/dist/bundle/cli.js +1 -1
  8. package/dist/bundle/index.js +1 -1
  9. package/dist/bundle/rpc-entry.js +1 -1
  10. package/dist/core/tasks/activity.d.ts +14 -0
  11. package/dist/core/tasks/activity.d.ts.map +1 -0
  12. package/dist/core/tasks/activity.js +58 -0
  13. package/dist/core/tasks/activity.js.map +1 -0
  14. package/dist/core/tasks/execution.d.ts.map +1 -1
  15. package/dist/core/tasks/execution.js +2 -2
  16. package/dist/core/tasks/execution.js.map +1 -1
  17. package/dist/core/tasks/output.d.ts +4 -1
  18. package/dist/core/tasks/output.d.ts.map +1 -1
  19. package/dist/core/tasks/output.js +33 -0
  20. package/dist/core/tasks/output.js.map +1 -1
  21. package/dist/core/tasks/types.d.ts +19 -2
  22. package/dist/core/tasks/types.d.ts.map +1 -1
  23. package/dist/core/tasks/types.js.map +1 -1
  24. package/dist/extensions/agent/activity-lines.d.ts +1 -5
  25. package/dist/extensions/agent/activity-lines.d.ts.map +1 -1
  26. package/dist/extensions/agent/activity-lines.js +5 -69
  27. package/dist/extensions/agent/activity-lines.js.map +1 -1
  28. package/dist/extensions/agent/activity.d.ts +0 -19
  29. package/dist/extensions/agent/activity.d.ts.map +1 -1
  30. package/dist/extensions/agent/activity.js +0 -63
  31. package/dist/extensions/agent/activity.js.map +1 -1
  32. package/dist/extensions/agent/progress.d.ts.map +1 -1
  33. package/dist/extensions/agent/progress.js +9 -2
  34. package/dist/extensions/agent/progress.js.map +1 -1
  35. package/dist/extensions/agent/types.d.ts +3 -11
  36. package/dist/extensions/agent/types.d.ts.map +1 -1
  37. package/dist/extensions/agent/types.js.map +1 -1
  38. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
  39. package/dist/extensions/tasks/ui/inspector.js +3 -1
  40. package/dist/extensions/tasks/ui/inspector.js.map +1 -1
  41. package/dist/extensions/tasks/ui/views.d.ts +2 -1
  42. package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
  43. package/dist/extensions/tasks/ui/views.js +13 -8
  44. package/dist/extensions/tasks/ui/views.js.map +1 -1
  45. package/dist/index.d.ts +1 -1
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js.map +1 -1
  48. package/dist/modes/interactive/components/task-activity-list.d.ts +5 -0
  49. package/dist/modes/interactive/components/task-activity-list.d.ts.map +1 -0
  50. package/dist/modes/interactive/components/task-activity-list.js +68 -0
  51. package/dist/modes/interactive/components/task-activity-list.js.map +1 -0
  52. package/docs/bundled/extensions/agent.md +1 -1
  53. package/docs/extensions.md +2 -0
  54. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
2
- import{Bm25Ranker,CODEMODE_DOCS_PATH,CODEMODE_STORE_ENTRY_TYPE,DEFAULT_TOOL_SEARCH_LIMIT,combineUsage,createToolSearchDocument,formatSize,getCodemodeCallableTools,parseCodemodeSource,renderToolSample,toCodemodeDeclaration,toCodemodeIdentifier,writeOutputFile}from"./chunk-THAJ4BZF.js";import"./chunk-6QGV3IWD.js";import{getCodemodeWorkerSpecifier,getQuickJSWasmPath}from"./chunk-PSYLMRL6.js";import"./chunk-JEIV47WR.js";import"./chunk-IC6JXX2J.js";import"./chunk-RAIYJ5FC.js";import"./chunk-6VYRLG5F.js";import"./chunk-H3UF54OB.js";import"./chunk-4L3WN2XY.js";function isWorkerToHostMessage(value){if(typeof value!="object"||value===null)return!1;let type=value.type;return type==="call"||type==="output"||type==="done"||type==="crash"||type==="started"||type==="idle"}var DEFAULT_TIMEOUT_MS=3e5,IDENTIFIER=/^[A-Za-z_$][A-Za-z0-9_$]*$/,RESERVED_GLOBALS=new Set(["tools","ALL_TOOLS","console","text","image","exit","globalThis","store","load"]);function errorMessage(error){return error instanceof Error?error.message:String(error)}function serializeStore(store){let serialized={};for(let[key,value]of Object.entries(store??{})){let json=JSON.stringify(value);json!==void 0&&(serialized[key]=json)}return serialized}var BridgeError=class extends Error{};function parseBridgeJson(json,what){try{return JSON.parse(json)}catch{throw new BridgeError(`${what} is not valid JSON`)}}function parseStoreWrites(json){let entries=parseBridgeJson(json,"store writes");if(!Array.isArray(entries))throw new BridgeError("store writes are not an array");let writes={set:{},delete:[]};for(let entry of entries){if(!Array.isArray(entry)||typeof entry[0]!="string"||(entry.length===2?typeof entry[1]!="string":entry.length!==1))throw new BridgeError("store writes contain a malformed entry");let[key,value]=entry;value===void 0?writes.delete.push(key):writes.set[key]=parseBridgeJson(value,`store value for ${JSON.stringify(key)}`)}return writes}function parseScriptError(json){let parsed=parseBridgeJson(json,"script error");if(typeof parsed!="object"||parsed===null)throw new BridgeError("script error is not an object");let{name,message,stack}=parsed;if(typeof message!="string"||name!==void 0&&typeof name!="string"||stack!==void 0&&typeof stack!="string")throw new BridgeError("script error is malformed");return{kind:"script",name,message,stack}}function checkGlobals(globals){let names=new Set,namespaces=new Set;for(let global of globals){let parts=global.name.split(".");if(parts.length>2||!parts.every(part=>IDENTIFIER.test(part))||RESERVED_GLOBALS.has(parts[0]))throw new Error(`Invalid global name "${global.name}"`);if(names.has(global.name))throw new Error(`Global "${global.name}" is already registered`);parts.length===2&&namespaces.add(parts[0]),names.add(global.name)}for(let name of namespaces)if(names.has(name))throw new Error(`Global "${name}" conflicts with the namespace "${name}"`)}var Execution=class{promise;resolveResult;channel;unsent=[];executors;control;delivered=new Set;signal;timer;output=[];calls=[];pending=new Map;finished=!1;constructor(options){if(this.promise=new Promise(resolve=>{this.resolveResult=resolve}),this.executors=options.executors,this.control=options.control,this.signal=options.signal,Number.isFinite(options.timeoutMs)&&(this.timer=setTimeout(()=>{this.finish({kind:"timeout",message:`Execution timed out after ${options.timeoutMs} ms`})},options.timeoutMs)),options.signal&&(options.signal.aborted?this.onAbort():options.signal.addEventListener("abort",this.onAbort,{once:!0})),this.finished)return;let data={code:options.code,tools:options.tools.map(tool=>({name:tool.name,jsName:tool.jsName??toCodemodeIdentifier(tool.name),description:tool.description??""})),globals:options.globals.map(global=>({name:global.name,spread:global.spread===!0})),memoryLimitBytes:options.memoryLimitBytes,store:options.store,...options.deterministic?{deterministic:options.deterministic}:{}},events={message:message=>this.receive(message),failure:error=>this.finish(error)};new Promise(resolve=>resolve(options.launch(data,events))).then(channel=>{if(this.finished){channel.stop().catch(()=>{});return}this.channel=channel;for(let message of this.unsent.splice(0))channel.post(message)},error=>{this.finish({kind:"sandbox",message:errorMessage(error)})})}deliver(seq,now,id,outcome){if(this.finished)return;if(!Number.isFinite(now))throw new Error(`The clock value of result ${seq} is not a finite number`);if(!Number.isInteger(seq)||seq<1||this.delivered.has(seq))throw new Error(`Result number ${seq} is not a positive integer used once`);let pending=this.pending.get(id);if(pending===void 0)throw new Error(`Call ${id} is not waiting for a result`);if(!outcome.ok&&outcome.properties!==void 0){let{properties:properties2}=outcome;if(typeof properties2!="object"||properties2===null||Array.isArray(properties2))throw new Error(`The properties of result ${seq} are not an object`)}let payload=outcome.ok?outcome.value===void 0?void 0:JSON.stringify(outcome.value):outcome.message,properties=!outcome.ok&&outcome.properties!==void 0?JSON.stringify(outcome.properties):void 0;this.delivered.add(seq),this.pending.delete(id),pending.record&&(pending.record.status=outcome.ok?"ok":"error",pending.record.durationMs=performance.now()-pending.startedAt),this.post({type:"result",id,ok:outcome.ok,payload,seq,now,...properties===void 0?{}:{properties}})}abort(message){return this.finish({kind:"aborted",message}),this.promise}onAbort=()=>{let reason=this.signal?.reason;this.finish({kind:"aborted",message:reason instanceof Error?reason.message:"Execution aborted"})};post(message){this.channel?this.channel.post(message):this.unsent.push(message)}receive(message){try{this.handleMessage(message)}catch(error){this.finish({kind:"sandbox",message:error instanceof BridgeError?`Sandbox bridge broken: ${error.message}. The script may have modified built-ins such as a prototype's toJSON.`:`Sandbox host failed: ${errorMessage(error)}`})}}handleMessage(message){if(!this.finished){if(!isWorkerToHostMessage(message))throw new BridgeError("unknown message from the worker");switch(message.type){case"output":this.output.push(message.item);break;case"call":if(this.pending.has(message.id))throw new BridgeError(`duplicate call id ${message.id}`);this.control?this.forwardCall(message,this.control):this.handleCall(message);break;case"started":this.control?.onStarted?.(message.fingerprint);break;case"idle":this.control?.onIdle?.(message.seq,message.issued);break;case"done":this.handleDone(message);break;case"crash":this.finish({kind:"sandbox",message:message.message});break}}}handleDone(message){if(!message.ok){this.finish(parseScriptError(message.error),void 0,void 0,message.during);return}let value=message.value===void 0?void 0:parseBridgeJson(message.value,"return value");this.finish(void 0,value,parseStoreWrites(message.writes),message.during)}forwardCall(message,control){let{id,name,target}=message,args=message.args===void 0?void 0:parseBridgeJson(message.args,"call arguments"),record=target==="tool"?{name,status:"cancelled",durationMs:0}:void 0;record&&this.calls.push(record),this.pending.set(id,{record,startedAt:performance.now(),controller:new AbortController}),control.onCall({id,target,name,args})}async handleCall(message){let{id,name}=message,isTool=message.target==="tool",record=isTool?{name,status:"cancelled",durationMs:0}:void 0;record&&this.calls.push(record);let pending={record,startedAt:performance.now(),controller:new AbortController};this.pending.set(id,pending);let status,reply;try{let tool=(isTool?this.executors.tools:this.executors.globals).get(name);if(!tool)throw new Error(`Unknown ${isTool?"tool":"global"} "${name}"`);let args=message.args===void 0?void 0:JSON.parse(message.args),value=await tool.execute(args,{signal:pending.controller.signal});reply={type:"result",id,ok:!0,payload:value===void 0?void 0:JSON.stringify(value)},status="ok"}catch(error){reply={type:"result",id,ok:!1,payload:errorMessage(error)},status="error"}this.pending.delete(id)&&(record&&(record.status=status,record.durationMs=performance.now()-pending.startedAt),this.post(reply))}finish(error,value,writes,during){if(this.finished)return;this.finished=!0,clearTimeout(this.timer),this.signal?.removeEventListener("abort",this.onAbort);let now=performance.now();for(let pending of this.pending.values())pending.record&&(pending.record.durationMs=now-pending.startedAt),pending.controller.abort();this.pending.clear(),this.unsent=[];let ended=during===void 0?{}:{during:{seq:during.seq,issued:during.issued}},result=error?{ok:!1,error,output:this.output,calls:this.calls,...ended}:{ok:!0,value,output:this.output,calls:this.calls,storeWrites:writes??{set:{},delete:[]},...ended};if(!this.channel){this.resolveResult(result);return}this.channel.stop().catch(()=>{}).then(()=>this.resolveResult(result))}},CodemodeSandboxBase=class{toolsByName=new Map;globalsByName=new Map;timeoutMs;memoryLimitBytes;launch;running=new Set;closed=!1;constructor(options,launch){this.timeoutMs=options.timeoutMs??DEFAULT_TIMEOUT_MS,this.memoryLimitBytes=options.memoryLimitBytes,this.launch=launch;for(let tool of options.tools??[])this.registerTool(tool);checkGlobals(options.globals??[]);for(let global of options.globals??[])this.globalsByName.set(global.name,global)}registerTool(tool){if(this.toolsByName.has(tool.name))throw new Error(`Tool "${tool.name}" is already registered`);this.toolsByName.set(tool.name,tool)}unregisterTool(name){return this.toolsByName.delete(name)}get tools(){return[...this.toolsByName.values()]}get globals(){return[...this.globalsByName.values()]}execute(code,options={}){if(this.closed)return Promise.reject(new Error("Sandbox is closed"));let tools=new Map(this.toolsByName),execution=new Execution({code,tools:[...tools.values()],globals:[...this.globalsByName.values()],executors:{tools,globals:this.globalsByName},timeoutMs:options.timeoutMs??this.timeoutMs,signal:options.signal,memoryLimitBytes:this.memoryLimitBytes,store:serializeStore(options.store),launch:this.launch});return this.running.add(execution),execution.promise.finally(()=>this.running.delete(execution))}start(code,options){if(this.closed)throw new Error("Sandbox is closed");if(!Number.isFinite(options.startedAt)||options.startedAt<0)throw new Error("startedAt must be a non-negative number of milliseconds since the epoch");if(!Number.isInteger(options.seed)||options.seed<0||options.seed>4294967295)throw new Error("seed must be a 32-bit unsigned integer");let tools=options.tools??[];if(new Set(tools.map(tool=>tool.name)).size!==tools.length)throw new Error("Tool names must be unique");let scriptNames=tools.map(tool=>tool.jsName??toCodemodeIdentifier(tool.name));if(new Set(scriptNames).size!==tools.length)throw new Error("Tool script names must be unique");let globals=options.globals??[];checkGlobals(globals);let execution=new Execution({code,tools,globals,executors:{tools:new Map,globals:new Map},timeoutMs:options.timeoutMs??Number.POSITIVE_INFINITY,signal:options.signal,memoryLimitBytes:this.memoryLimitBytes,store:serializeStore(options.store),deterministic:{startedAt:options.startedAt,seed:options.seed},control:{onStarted:options.onStarted,onCall:options.onCall,onIdle:options.onIdle},launch:this.launch});return this.running.add(execution),{result:execution.promise.finally(()=>this.running.delete(execution)),deliver:(seq,now,id,outcome)=>execution.deliver(seq,now,id,outcome),get finished(){return execution.finished}}}async close(){this.closed=!0,await Promise.all([...this.running].map(execution=>execution.abort("Sandbox closed")))}};import{Worker}from"node:worker_threads";import{readFile}from"node:fs/promises";import{createRequire}from"node:module";var modules=new Map;function loadQuickJSWasm(path){let resolved=path??createRequire(import.meta.url).resolve("quickjs-wasi/quickjs.wasm"),module=modules.get(resolved);if(!module){let{WebAssembly:WebAssembly2}=globalThis;module=readFile(resolved).then(bytes=>WebAssembly2.compile(bytes)).catch(error=>{throw modules.delete(resolved),error}),modules.set(resolved,module)}return module}function defaultWorkerUrl(){return new URL(import.meta.url.endsWith(".ts")?"./worker.ts":"./worker.js",import.meta.url)}function workerLauncher(options){return async(data,events)=>{let module;try{module=await(options.wasm??loadQuickJSWasm())}catch(error){throw new Error(`Failed to load QuickJS: ${errorMessage(error)}`)}let interrupt=new SharedArrayBuffer(4),workerData={...data,wasm:module,interrupt},releaseWorker=options.acquireWorker?.(),worker;try{worker=new Worker(options.workerUrl??defaultWorkerUrl(),{workerData})}catch(error){throw releaseWorker?.(),new Error(`Failed to start worker: ${errorMessage(error)}`)}releaseWorker&&worker.once("exit",releaseWorker),worker.on("message",message=>{typeof message=="object"&&message!==null&&("watch:import"in message||"watch:require"in message)||events.message(message)}),worker.on("error",error=>{events.failure({kind:"sandbox",name:error instanceof Error?error.name:void 0,message:errorMessage(error)})}),worker.on("exit",code=>{events.failure({kind:"sandbox",message:`Worker exited with code ${code} before the script settled`})});let stop=async()=>{Atomics.store(new Int32Array(interrupt),0,1),worker.terminate().catch(()=>{}),worker.unref()};try{options.onWorkerStarted?.(new Promise(resolve=>worker.once("exit",()=>resolve())))}catch(error){throw stop(),error}return{post:message=>worker.postMessage(message),stop}}}var CodemodeSandbox=class extends CodemodeSandboxBase{constructor(options={}){super(options,workerLauncher(options))}};var decoder=new TextDecoder;var MAX_STACK_SIZE=512*1024;var wtf8Decoder=new TextDecoder,wtf8Encoder=new TextEncoder;var IMAGE_HELPER_EXPECTS='image expects a non-empty image URL string, an object with image_url, or an image block { type: "image", data, mimeType }',PRELUDE_SOURCE=`(function (bridge, toolsJson, globalsJson, storeJson) {
2
+ import{Bm25Ranker,CODEMODE_DOCS_PATH,CODEMODE_STORE_ENTRY_TYPE,DEFAULT_TOOL_SEARCH_LIMIT,combineUsage,createToolSearchDocument,formatSize,getCodemodeCallableTools,parseCodemodeSource,renderToolSample,toCodemodeDeclaration,toCodemodeIdentifier,writeOutputFile}from"./chunk-HLVMLRZJ.js";import"./chunk-6QGV3IWD.js";import{getCodemodeWorkerSpecifier,getQuickJSWasmPath}from"./chunk-PSYLMRL6.js";import"./chunk-JEIV47WR.js";import"./chunk-IC6JXX2J.js";import"./chunk-RAIYJ5FC.js";import"./chunk-6VYRLG5F.js";import"./chunk-H3UF54OB.js";import"./chunk-4L3WN2XY.js";function isWorkerToHostMessage(value){if(typeof value!="object"||value===null)return!1;let type=value.type;return type==="call"||type==="output"||type==="done"||type==="crash"||type==="started"||type==="idle"}var DEFAULT_TIMEOUT_MS=3e5,IDENTIFIER=/^[A-Za-z_$][A-Za-z0-9_$]*$/,RESERVED_GLOBALS=new Set(["tools","ALL_TOOLS","console","text","image","exit","globalThis","store","load"]);function errorMessage(error){return error instanceof Error?error.message:String(error)}function serializeStore(store){let serialized={};for(let[key,value]of Object.entries(store??{})){let json=JSON.stringify(value);json!==void 0&&(serialized[key]=json)}return serialized}var BridgeError=class extends Error{};function parseBridgeJson(json,what){try{return JSON.parse(json)}catch{throw new BridgeError(`${what} is not valid JSON`)}}function parseStoreWrites(json){let entries=parseBridgeJson(json,"store writes");if(!Array.isArray(entries))throw new BridgeError("store writes are not an array");let writes={set:{},delete:[]};for(let entry of entries){if(!Array.isArray(entry)||typeof entry[0]!="string"||(entry.length===2?typeof entry[1]!="string":entry.length!==1))throw new BridgeError("store writes contain a malformed entry");let[key,value]=entry;value===void 0?writes.delete.push(key):writes.set[key]=parseBridgeJson(value,`store value for ${JSON.stringify(key)}`)}return writes}function parseScriptError(json){let parsed=parseBridgeJson(json,"script error");if(typeof parsed!="object"||parsed===null)throw new BridgeError("script error is not an object");let{name,message,stack}=parsed;if(typeof message!="string"||name!==void 0&&typeof name!="string"||stack!==void 0&&typeof stack!="string")throw new BridgeError("script error is malformed");return{kind:"script",name,message,stack}}function checkGlobals(globals){let names=new Set,namespaces=new Set;for(let global of globals){let parts=global.name.split(".");if(parts.length>2||!parts.every(part=>IDENTIFIER.test(part))||RESERVED_GLOBALS.has(parts[0]))throw new Error(`Invalid global name "${global.name}"`);if(names.has(global.name))throw new Error(`Global "${global.name}" is already registered`);parts.length===2&&namespaces.add(parts[0]),names.add(global.name)}for(let name of namespaces)if(names.has(name))throw new Error(`Global "${name}" conflicts with the namespace "${name}"`)}var Execution=class{promise;resolveResult;channel;unsent=[];executors;control;delivered=new Set;signal;timer;output=[];calls=[];pending=new Map;finished=!1;constructor(options){if(this.promise=new Promise(resolve=>{this.resolveResult=resolve}),this.executors=options.executors,this.control=options.control,this.signal=options.signal,Number.isFinite(options.timeoutMs)&&(this.timer=setTimeout(()=>{this.finish({kind:"timeout",message:`Execution timed out after ${options.timeoutMs} ms`})},options.timeoutMs)),options.signal&&(options.signal.aborted?this.onAbort():options.signal.addEventListener("abort",this.onAbort,{once:!0})),this.finished)return;let data={code:options.code,tools:options.tools.map(tool=>({name:tool.name,jsName:tool.jsName??toCodemodeIdentifier(tool.name),description:tool.description??""})),globals:options.globals.map(global=>({name:global.name,spread:global.spread===!0})),memoryLimitBytes:options.memoryLimitBytes,store:options.store,...options.deterministic?{deterministic:options.deterministic}:{}},events={message:message=>this.receive(message),failure:error=>this.finish(error)};new Promise(resolve=>resolve(options.launch(data,events))).then(channel=>{if(this.finished){channel.stop().catch(()=>{});return}this.channel=channel;for(let message of this.unsent.splice(0))channel.post(message)},error=>{this.finish({kind:"sandbox",message:errorMessage(error)})})}deliver(seq,now,id,outcome){if(this.finished)return;if(!Number.isFinite(now))throw new Error(`The clock value of result ${seq} is not a finite number`);if(!Number.isInteger(seq)||seq<1||this.delivered.has(seq))throw new Error(`Result number ${seq} is not a positive integer used once`);let pending=this.pending.get(id);if(pending===void 0)throw new Error(`Call ${id} is not waiting for a result`);if(!outcome.ok&&outcome.properties!==void 0){let{properties:properties2}=outcome;if(typeof properties2!="object"||properties2===null||Array.isArray(properties2))throw new Error(`The properties of result ${seq} are not an object`)}let payload=outcome.ok?outcome.value===void 0?void 0:JSON.stringify(outcome.value):outcome.message,properties=!outcome.ok&&outcome.properties!==void 0?JSON.stringify(outcome.properties):void 0;this.delivered.add(seq),this.pending.delete(id),pending.record&&(pending.record.status=outcome.ok?"ok":"error",pending.record.durationMs=performance.now()-pending.startedAt),this.post({type:"result",id,ok:outcome.ok,payload,seq,now,...properties===void 0?{}:{properties}})}abort(message){return this.finish({kind:"aborted",message}),this.promise}onAbort=()=>{let reason=this.signal?.reason;this.finish({kind:"aborted",message:reason instanceof Error?reason.message:"Execution aborted"})};post(message){this.channel?this.channel.post(message):this.unsent.push(message)}receive(message){try{this.handleMessage(message)}catch(error){this.finish({kind:"sandbox",message:error instanceof BridgeError?`Sandbox bridge broken: ${error.message}. The script may have modified built-ins such as a prototype's toJSON.`:`Sandbox host failed: ${errorMessage(error)}`})}}handleMessage(message){if(!this.finished){if(!isWorkerToHostMessage(message))throw new BridgeError("unknown message from the worker");switch(message.type){case"output":this.output.push(message.item);break;case"call":if(this.pending.has(message.id))throw new BridgeError(`duplicate call id ${message.id}`);this.control?this.forwardCall(message,this.control):this.handleCall(message);break;case"started":this.control?.onStarted?.(message.fingerprint);break;case"idle":this.control?.onIdle?.(message.seq,message.issued);break;case"done":this.handleDone(message);break;case"crash":this.finish({kind:"sandbox",message:message.message});break}}}handleDone(message){if(!message.ok){this.finish(parseScriptError(message.error),void 0,void 0,message.during);return}let value=message.value===void 0?void 0:parseBridgeJson(message.value,"return value");this.finish(void 0,value,parseStoreWrites(message.writes),message.during)}forwardCall(message,control){let{id,name,target}=message,args=message.args===void 0?void 0:parseBridgeJson(message.args,"call arguments"),record=target==="tool"?{name,status:"cancelled",durationMs:0}:void 0;record&&this.calls.push(record),this.pending.set(id,{record,startedAt:performance.now(),controller:new AbortController}),control.onCall({id,target,name,args})}async handleCall(message){let{id,name}=message,isTool=message.target==="tool",record=isTool?{name,status:"cancelled",durationMs:0}:void 0;record&&this.calls.push(record);let pending={record,startedAt:performance.now(),controller:new AbortController};this.pending.set(id,pending);let status,reply;try{let tool=(isTool?this.executors.tools:this.executors.globals).get(name);if(!tool)throw new Error(`Unknown ${isTool?"tool":"global"} "${name}"`);let args=message.args===void 0?void 0:JSON.parse(message.args),value=await tool.execute(args,{signal:pending.controller.signal});reply={type:"result",id,ok:!0,payload:value===void 0?void 0:JSON.stringify(value)},status="ok"}catch(error){reply={type:"result",id,ok:!1,payload:errorMessage(error)},status="error"}this.pending.delete(id)&&(record&&(record.status=status,record.durationMs=performance.now()-pending.startedAt),this.post(reply))}finish(error,value,writes,during){if(this.finished)return;this.finished=!0,clearTimeout(this.timer),this.signal?.removeEventListener("abort",this.onAbort);let now=performance.now();for(let pending of this.pending.values())pending.record&&(pending.record.durationMs=now-pending.startedAt),pending.controller.abort();this.pending.clear(),this.unsent=[];let ended=during===void 0?{}:{during:{seq:during.seq,issued:during.issued}},result=error?{ok:!1,error,output:this.output,calls:this.calls,...ended}:{ok:!0,value,output:this.output,calls:this.calls,storeWrites:writes??{set:{},delete:[]},...ended};if(!this.channel){this.resolveResult(result);return}this.channel.stop().catch(()=>{}).then(()=>this.resolveResult(result))}},CodemodeSandboxBase=class{toolsByName=new Map;globalsByName=new Map;timeoutMs;memoryLimitBytes;launch;running=new Set;closed=!1;constructor(options,launch){this.timeoutMs=options.timeoutMs??DEFAULT_TIMEOUT_MS,this.memoryLimitBytes=options.memoryLimitBytes,this.launch=launch;for(let tool of options.tools??[])this.registerTool(tool);checkGlobals(options.globals??[]);for(let global of options.globals??[])this.globalsByName.set(global.name,global)}registerTool(tool){if(this.toolsByName.has(tool.name))throw new Error(`Tool "${tool.name}" is already registered`);this.toolsByName.set(tool.name,tool)}unregisterTool(name){return this.toolsByName.delete(name)}get tools(){return[...this.toolsByName.values()]}get globals(){return[...this.globalsByName.values()]}execute(code,options={}){if(this.closed)return Promise.reject(new Error("Sandbox is closed"));let tools=new Map(this.toolsByName),execution=new Execution({code,tools:[...tools.values()],globals:[...this.globalsByName.values()],executors:{tools,globals:this.globalsByName},timeoutMs:options.timeoutMs??this.timeoutMs,signal:options.signal,memoryLimitBytes:this.memoryLimitBytes,store:serializeStore(options.store),launch:this.launch});return this.running.add(execution),execution.promise.finally(()=>this.running.delete(execution))}start(code,options){if(this.closed)throw new Error("Sandbox is closed");if(!Number.isFinite(options.startedAt)||options.startedAt<0)throw new Error("startedAt must be a non-negative number of milliseconds since the epoch");if(!Number.isInteger(options.seed)||options.seed<0||options.seed>4294967295)throw new Error("seed must be a 32-bit unsigned integer");let tools=options.tools??[];if(new Set(tools.map(tool=>tool.name)).size!==tools.length)throw new Error("Tool names must be unique");let scriptNames=tools.map(tool=>tool.jsName??toCodemodeIdentifier(tool.name));if(new Set(scriptNames).size!==tools.length)throw new Error("Tool script names must be unique");let globals=options.globals??[];checkGlobals(globals);let execution=new Execution({code,tools,globals,executors:{tools:new Map,globals:new Map},timeoutMs:options.timeoutMs??Number.POSITIVE_INFINITY,signal:options.signal,memoryLimitBytes:this.memoryLimitBytes,store:serializeStore(options.store),deterministic:{startedAt:options.startedAt,seed:options.seed},control:{onStarted:options.onStarted,onCall:options.onCall,onIdle:options.onIdle},launch:this.launch});return this.running.add(execution),{result:execution.promise.finally(()=>this.running.delete(execution)),deliver:(seq,now,id,outcome)=>execution.deliver(seq,now,id,outcome),get finished(){return execution.finished}}}async close(){this.closed=!0,await Promise.all([...this.running].map(execution=>execution.abort("Sandbox closed")))}};import{Worker}from"node:worker_threads";import{readFile}from"node:fs/promises";import{createRequire}from"node:module";var modules=new Map;function loadQuickJSWasm(path){let resolved=path??createRequire(import.meta.url).resolve("quickjs-wasi/quickjs.wasm"),module=modules.get(resolved);if(!module){let{WebAssembly:WebAssembly2}=globalThis;module=readFile(resolved).then(bytes=>WebAssembly2.compile(bytes)).catch(error=>{throw modules.delete(resolved),error}),modules.set(resolved,module)}return module}function defaultWorkerUrl(){return new URL(import.meta.url.endsWith(".ts")?"./worker.ts":"./worker.js",import.meta.url)}function workerLauncher(options){return async(data,events)=>{let module;try{module=await(options.wasm??loadQuickJSWasm())}catch(error){throw new Error(`Failed to load QuickJS: ${errorMessage(error)}`)}let interrupt=new SharedArrayBuffer(4),workerData={...data,wasm:module,interrupt},releaseWorker=options.acquireWorker?.(),worker;try{worker=new Worker(options.workerUrl??defaultWorkerUrl(),{workerData})}catch(error){throw releaseWorker?.(),new Error(`Failed to start worker: ${errorMessage(error)}`)}releaseWorker&&worker.once("exit",releaseWorker),worker.on("message",message=>{typeof message=="object"&&message!==null&&("watch:import"in message||"watch:require"in message)||events.message(message)}),worker.on("error",error=>{events.failure({kind:"sandbox",name:error instanceof Error?error.name:void 0,message:errorMessage(error)})}),worker.on("exit",code=>{events.failure({kind:"sandbox",message:`Worker exited with code ${code} before the script settled`})});let stop=async()=>{Atomics.store(new Int32Array(interrupt),0,1),worker.terminate().catch(()=>{}),worker.unref()};try{options.onWorkerStarted?.(new Promise(resolve=>worker.once("exit",()=>resolve())))}catch(error){throw stop(),error}return{post:message=>worker.postMessage(message),stop}}}var CodemodeSandbox=class extends CodemodeSandboxBase{constructor(options={}){super(options,workerLauncher(options))}};var decoder=new TextDecoder;var MAX_STACK_SIZE=512*1024;var wtf8Decoder=new TextDecoder,wtf8Encoder=new TextEncoder;var IMAGE_HELPER_EXPECTS='image expects a non-empty image URL string, an object with image_url, or an image block { type: "image", data, mimeType }',PRELUDE_SOURCE=`(function (bridge, toolsJson, globalsJson, storeJson) {
3
3
  "use strict";
4
4
 
5
5
  // Freeze every object reachable from the built-in globals, plus the intrinsics that are only
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
2
- import{dist_exports as dist_exports3}from"./chunk-IRUUTK4W.js";import{all_exports,compile_exports,dist_exports as dist_exports2,pi_ai_extension_view_exports,value_exports}from"./chunk-R3YHAMWH.js";import"./chunk-FPALVF3F.js";import"./chunk-KBFO53OG.js";import{build_exports,dist_exports}from"./chunk-THAJ4BZF.js";import"./chunk-6QGV3IWD.js";import{DISTRIBUTION_PACKAGE_NAME}from"./chunk-PSYLMRL6.js";import"./chunk-JEIV47WR.js";import"./chunk-D3ZCGC4T.js";import"./chunk-RZ2V53SP.js";import"./chunk-5FDOJRDS.js";import"./chunk-IC6JXX2J.js";import"./chunk-SR6EWNPW.js";import{models_exports}from"./chunk-RAIYJ5FC.js";import"./chunk-6VYRLG5F.js";import"./chunk-H3UF54OB.js";import"./chunk-4L3WN2XY.js";var oauth_exports={};var VIRTUAL_MODULES={typebox:build_exports,"typebox/compile":compile_exports,"typebox/value":value_exports,"@sinclair/typebox":build_exports,"@sinclair/typebox/compile":compile_exports,"@sinclair/typebox/value":value_exports,"@earendil-works/pi-agent-core":dist_exports2,"@earendil-works/pi-tui":dist_exports,"@earendil-works/pi-ai":pi_ai_extension_view_exports,"@earendil-works/pi-ai/compat":pi_ai_extension_view_exports,"@earendil-works/pi-ai/models":models_exports,"@earendil-works/pi-ai/oauth":oauth_exports,"@earendil-works/pi-ai/providers/all":all_exports,"@earendil-works/pi-coding-agent":dist_exports3,[DISTRIBUTION_PACKAGE_NAME]:dist_exports3,"@mariozechner/pi-agent-core":dist_exports2,"@mariozechner/pi-tui":dist_exports,"@mariozechner/pi-ai":pi_ai_extension_view_exports,"@mariozechner/pi-ai/compat":pi_ai_extension_view_exports,"@mariozechner/pi-ai/models":models_exports,"@mariozechner/pi-ai/oauth":oauth_exports,"@mariozechner/pi-ai/providers/all":all_exports,"@mariozechner/pi-coding-agent":dist_exports3};export{VIRTUAL_MODULES};
2
+ import{dist_exports as dist_exports3}from"./chunk-3YGNXVKM.js";import{all_exports,compile_exports,dist_exports as dist_exports2,pi_ai_extension_view_exports,value_exports}from"./chunk-M3D4ADUT.js";import"./chunk-FPALVF3F.js";import"./chunk-KBFO53OG.js";import{build_exports,dist_exports}from"./chunk-HLVMLRZJ.js";import"./chunk-6QGV3IWD.js";import{DISTRIBUTION_PACKAGE_NAME}from"./chunk-PSYLMRL6.js";import"./chunk-JEIV47WR.js";import"./chunk-D3ZCGC4T.js";import"./chunk-RZ2V53SP.js";import"./chunk-5FDOJRDS.js";import"./chunk-IC6JXX2J.js";import"./chunk-SR6EWNPW.js";import{models_exports}from"./chunk-RAIYJ5FC.js";import"./chunk-6VYRLG5F.js";import"./chunk-H3UF54OB.js";import"./chunk-4L3WN2XY.js";var oauth_exports={};var VIRTUAL_MODULES={typebox:build_exports,"typebox/compile":compile_exports,"typebox/value":value_exports,"@sinclair/typebox":build_exports,"@sinclair/typebox/compile":compile_exports,"@sinclair/typebox/value":value_exports,"@earendil-works/pi-agent-core":dist_exports2,"@earendil-works/pi-tui":dist_exports,"@earendil-works/pi-ai":pi_ai_extension_view_exports,"@earendil-works/pi-ai/compat":pi_ai_extension_view_exports,"@earendil-works/pi-ai/models":models_exports,"@earendil-works/pi-ai/oauth":oauth_exports,"@earendil-works/pi-ai/providers/all":all_exports,"@earendil-works/pi-coding-agent":dist_exports3,[DISTRIBUTION_PACKAGE_NAME]:dist_exports3,"@mariozechner/pi-agent-core":dist_exports2,"@mariozechner/pi-tui":dist_exports,"@mariozechner/pi-ai":pi_ai_extension_view_exports,"@mariozechner/pi-ai/compat":pi_ai_extension_view_exports,"@mariozechner/pi-ai/models":models_exports,"@mariozechner/pi-ai/oauth":oauth_exports,"@mariozechner/pi-ai/providers/all":all_exports,"@mariozechner/pi-coding-agent":dist_exports3};export{VIRTUAL_MODULES};
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
3
- import{configureHttpDispatcher,main}from"./chunks/chunk-R3YHAMWH.js";import"./chunks/chunk-FPALVF3F.js";import"./chunks/chunk-KBFO53OG.js";import"./chunks/chunk-THAJ4BZF.js";import"./chunks/chunk-6QGV3IWD.js";import{APP_NAME}from"./chunks/chunk-PSYLMRL6.js";import"./chunks/chunk-JEIV47WR.js";import"./chunks/chunk-D3ZCGC4T.js";import"./chunks/chunk-RZ2V53SP.js";import"./chunks/chunk-5FDOJRDS.js";import"./chunks/chunk-IC6JXX2J.js";import"./chunks/chunk-SR6EWNPW.js";import"./chunks/chunk-RAIYJ5FC.js";import"./chunks/chunk-6VYRLG5F.js";import"./chunks/chunk-H3UF54OB.js";import"./chunks/chunk-4L3WN2XY.js";function setupCli(){process.title=APP_NAME,process.env.PI_CODING_AGENT="true",process.env.AI_AGENT="pi",process.emitWarning=(()=>{}),configureHttpDispatcher()}setupCli();main(process.argv.slice(2));
3
+ import{configureHttpDispatcher,main}from"./chunks/chunk-M3D4ADUT.js";import"./chunks/chunk-FPALVF3F.js";import"./chunks/chunk-KBFO53OG.js";import"./chunks/chunk-HLVMLRZJ.js";import"./chunks/chunk-6QGV3IWD.js";import{APP_NAME}from"./chunks/chunk-PSYLMRL6.js";import"./chunks/chunk-JEIV47WR.js";import"./chunks/chunk-D3ZCGC4T.js";import"./chunks/chunk-RZ2V53SP.js";import"./chunks/chunk-5FDOJRDS.js";import"./chunks/chunk-IC6JXX2J.js";import"./chunks/chunk-SR6EWNPW.js";import"./chunks/chunk-RAIYJ5FC.js";import"./chunks/chunk-6VYRLG5F.js";import"./chunks/chunk-H3UF54OB.js";import"./chunks/chunk-4L3WN2XY.js";function setupCli(){process.title=APP_NAME,process.env.PI_CODING_AGENT="true",process.env.AI_AGENT="pi",process.emitWarning=(()=>{}),configureHttpDispatcher()}setupCli();main(process.argv.slice(2));
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
2
- import{ShowImagesSelectorComponent,ThemeSelectorComponent}from"./chunks/chunk-IRUUTK4W.js";import{AgentSession,AgentSessionRuntime,ArminComponent,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent,CredentialSynchronizationError,CustomEditor,CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS,DefaultPackageManager,DefaultResourceLoader,DynamicBorder,ExtensionEditorComponent,ExtensionInputComponent,ExtensionRunner,ExtensionSelectorComponent,FooterComponent,InteractiveMode,LoginDialogComponent,ModelRegistry,ModelRuntime,ModelSelectorComponent,OAuthSelectorComponent,RpcClient,SessionManager,SessionSelectorComponent,SettingsManager,SettingsSelectorComponent,SkillInvocationMessageComponent,TaskRuntime,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent,VIRTUAL_MODEL_STATE_ENTRY,buildContextEntries,buildSessionContext,buildSessionProjection,calculateContextTokens,collectEntriesForBranchSummary,compact,convertToLlm,convertToPng,copyToClipboard,createAgentSession,createAgentSessionFromServices,createAgentSessionRuntime,createAgentSessionServices,createBashTool,createBashToolDefinition,createCodemodeExtension,createCodingTools,createEditTool,createEditToolDefinition,createEventBus,createExtensionRuntime,createFindTool,createFindToolDefinition,createGrepTool,createGrepToolDefinition,createLocalBashOperations,createLocalPowerShellOperations,createLsTool,createLsToolDefinition,createMcpExtension,createPowerShellTool,createPowerShellToolDefinition,createReadOnlyTools,createReadTool,createReadToolDefinition,createSyntheticSourceInfo,createToolSearchExtension,createWriteTool,createWriteToolDefinition,defineTool,detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions,estimateTokens,findCutPoint,findTurnStartIndex,formatDimensionNote,formatSkillsForPrompt,generateBranchSummary,generateDiffString,generateSummary,generateSummaryWithUsage,generateUnifiedPatch,getLastAssistantUsage,getLatestCompactionEntry,isBashToolResult,isEditToolResult,isFindToolResult,isGrepToolResult,isLsToolResult,isPowerShellToolResult,isReadToolResult,isToolCallEventType,isWriteToolResult,loadProjectContextFiles,loadSkills,loadSkillsFromDir,main,migrateSessionEntries,parseArgs,parseFrontmatter,parseSessionEntries,parseSkillBlock,prepareBranchEntries,renderDiff,resizeImage,resolveCliModel,resolveModelScopeWithDiagnostics,runPrintMode,runRpcMode,serializeConversation,sessionEntryToContextMessages,shouldCompact,stripFrontmatter,withFileMutationQueue,wrapRegisteredTool,wrapRegisteredTools}from"./chunks/chunk-R3YHAMWH.js";import{ProjectTrustStore,hasTrustRequiringProjectResources}from"./chunks/chunk-FPALVF3F.js";import{readStoredCredential}from"./chunks/chunk-KBFO53OG.js";import{DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,Theme,formatReadLineRange,formatSize,getLanguageFromPath,getMarkdownTheme,getSelectListTheme,getSettingsListTheme,highlightCode,initTheme,keyHint,keyText,rawKeyHint,truncateHead,truncateLine,truncateTail,truncateToVisualLines}from"./chunks/chunk-THAJ4BZF.js";import"./chunks/chunk-6QGV3IWD.js";import{CONFIG_DIR_NAME,VERSION,getAgentDir,getDocsPath,getExamplesPath,getPackageDir,getPowerShellConfig,getReadmePath,getShellConfig}from"./chunks/chunk-PSYLMRL6.js";import"./chunks/chunk-JEIV47WR.js";import"./chunks/chunk-D3ZCGC4T.js";import"./chunks/chunk-RZ2V53SP.js";import"./chunks/chunk-5FDOJRDS.js";import"./chunks/chunk-IC6JXX2J.js";import"./chunks/chunk-SR6EWNPW.js";import"./chunks/chunk-RAIYJ5FC.js";import"./chunks/chunk-6VYRLG5F.js";import"./chunks/chunk-H3UF54OB.js";import"./chunks/chunk-4L3WN2XY.js";export{AgentSession,AgentSessionRuntime,ArminComponent,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CONFIG_DIR_NAME,CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent,CredentialSynchronizationError,CustomEditor,CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS,DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,DefaultPackageManager,DefaultResourceLoader,DynamicBorder,ExtensionEditorComponent,ExtensionInputComponent,ExtensionRunner,ExtensionSelectorComponent,FooterComponent,InteractiveMode,LoginDialogComponent,ModelRegistry,ModelRuntime,ModelSelectorComponent,OAuthSelectorComponent,ProjectTrustStore,RpcClient,SessionManager,SessionSelectorComponent,SettingsManager,SettingsSelectorComponent,ShowImagesSelectorComponent,SkillInvocationMessageComponent,TaskRuntime,Theme,ThemeSelectorComponent,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent,VERSION,VIRTUAL_MODEL_STATE_ENTRY,buildContextEntries,buildSessionContext,buildSessionProjection,calculateContextTokens,collectEntriesForBranchSummary,compact,convertToLlm,convertToPng,copyToClipboard,createAgentSession,createAgentSessionFromServices,createAgentSessionRuntime,createAgentSessionServices,createBashTool,createBashToolDefinition,createCodemodeExtension,createCodingTools,createEditTool,createEditToolDefinition,createEventBus,createExtensionRuntime,createFindTool,createFindToolDefinition,createGrepTool,createGrepToolDefinition,createLocalBashOperations,createLocalPowerShellOperations,createLsTool,createLsToolDefinition,createMcpExtension,createPowerShellTool,createPowerShellToolDefinition,createReadOnlyTools,createReadTool,createReadToolDefinition,createSyntheticSourceInfo,createToolSearchExtension,createWriteTool,createWriteToolDefinition,defineTool,detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions,estimateTokens,findCutPoint,findTurnStartIndex,formatDimensionNote,formatReadLineRange,formatSize,formatSkillsForPrompt,generateBranchSummary,generateDiffString,generateSummary,generateSummaryWithUsage,generateUnifiedPatch,getAgentDir,getDocsPath,getExamplesPath,getLanguageFromPath,getLastAssistantUsage,getLatestCompactionEntry,getMarkdownTheme,getPackageDir,getPowerShellConfig,getReadmePath,getSelectListTheme,getSettingsListTheme,getShellConfig,hasTrustRequiringProjectResources,highlightCode,initTheme,isBashToolResult,isEditToolResult,isFindToolResult,isGrepToolResult,isLsToolResult,isPowerShellToolResult,isReadToolResult,isToolCallEventType,isWriteToolResult,keyHint,keyText,loadProjectContextFiles,loadSkills,loadSkillsFromDir,main,migrateSessionEntries,parseArgs,parseFrontmatter,parseSessionEntries,parseSkillBlock,prepareBranchEntries,rawKeyHint,readStoredCredential,renderDiff,resizeImage,resolveCliModel,resolveModelScopeWithDiagnostics,runPrintMode,runRpcMode,serializeConversation,sessionEntryToContextMessages,shouldCompact,stripFrontmatter,truncateHead,truncateLine,truncateTail,truncateToVisualLines,withFileMutationQueue,wrapRegisteredTool,wrapRegisteredTools};
2
+ import{ShowImagesSelectorComponent,ThemeSelectorComponent}from"./chunks/chunk-3YGNXVKM.js";import{AgentSession,AgentSessionRuntime,ArminComponent,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent,CredentialSynchronizationError,CustomEditor,CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS,DefaultPackageManager,DefaultResourceLoader,DynamicBorder,ExtensionEditorComponent,ExtensionInputComponent,ExtensionRunner,ExtensionSelectorComponent,FooterComponent,InteractiveMode,LoginDialogComponent,ModelRegistry,ModelRuntime,ModelSelectorComponent,OAuthSelectorComponent,RpcClient,SessionManager,SessionSelectorComponent,SettingsManager,SettingsSelectorComponent,SkillInvocationMessageComponent,TaskRuntime,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent,VIRTUAL_MODEL_STATE_ENTRY,buildContextEntries,buildSessionContext,buildSessionProjection,calculateContextTokens,collectEntriesForBranchSummary,compact,convertToLlm,convertToPng,copyToClipboard,createAgentSession,createAgentSessionFromServices,createAgentSessionRuntime,createAgentSessionServices,createBashTool,createBashToolDefinition,createCodemodeExtension,createCodingTools,createEditTool,createEditToolDefinition,createEventBus,createExtensionRuntime,createFindTool,createFindToolDefinition,createGrepTool,createGrepToolDefinition,createLocalBashOperations,createLocalPowerShellOperations,createLsTool,createLsToolDefinition,createMcpExtension,createPowerShellTool,createPowerShellToolDefinition,createReadOnlyTools,createReadTool,createReadToolDefinition,createSyntheticSourceInfo,createToolSearchExtension,createWriteTool,createWriteToolDefinition,defineTool,detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions,estimateTokens,findCutPoint,findTurnStartIndex,formatDimensionNote,formatSkillsForPrompt,generateBranchSummary,generateDiffString,generateSummary,generateSummaryWithUsage,generateUnifiedPatch,getLastAssistantUsage,getLatestCompactionEntry,isBashToolResult,isEditToolResult,isFindToolResult,isGrepToolResult,isLsToolResult,isPowerShellToolResult,isReadToolResult,isToolCallEventType,isWriteToolResult,loadProjectContextFiles,loadSkills,loadSkillsFromDir,main,migrateSessionEntries,parseArgs,parseFrontmatter,parseSessionEntries,parseSkillBlock,prepareBranchEntries,renderDiff,resizeImage,resolveCliModel,resolveModelScopeWithDiagnostics,runPrintMode,runRpcMode,serializeConversation,sessionEntryToContextMessages,shouldCompact,stripFrontmatter,withFileMutationQueue,wrapRegisteredTool,wrapRegisteredTools}from"./chunks/chunk-M3D4ADUT.js";import{ProjectTrustStore,hasTrustRequiringProjectResources}from"./chunks/chunk-FPALVF3F.js";import{readStoredCredential}from"./chunks/chunk-KBFO53OG.js";import{DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,Theme,formatReadLineRange,formatSize,getLanguageFromPath,getMarkdownTheme,getSelectListTheme,getSettingsListTheme,highlightCode,initTheme,keyHint,keyText,rawKeyHint,truncateHead,truncateLine,truncateTail,truncateToVisualLines}from"./chunks/chunk-HLVMLRZJ.js";import"./chunks/chunk-6QGV3IWD.js";import{CONFIG_DIR_NAME,VERSION,getAgentDir,getDocsPath,getExamplesPath,getPackageDir,getPowerShellConfig,getReadmePath,getShellConfig}from"./chunks/chunk-PSYLMRL6.js";import"./chunks/chunk-JEIV47WR.js";import"./chunks/chunk-D3ZCGC4T.js";import"./chunks/chunk-RZ2V53SP.js";import"./chunks/chunk-5FDOJRDS.js";import"./chunks/chunk-IC6JXX2J.js";import"./chunks/chunk-SR6EWNPW.js";import"./chunks/chunk-RAIYJ5FC.js";import"./chunks/chunk-6VYRLG5F.js";import"./chunks/chunk-H3UF54OB.js";import"./chunks/chunk-4L3WN2XY.js";export{AgentSession,AgentSessionRuntime,ArminComponent,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CONFIG_DIR_NAME,CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent,CredentialSynchronizationError,CustomEditor,CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS,DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,DefaultPackageManager,DefaultResourceLoader,DynamicBorder,ExtensionEditorComponent,ExtensionInputComponent,ExtensionRunner,ExtensionSelectorComponent,FooterComponent,InteractiveMode,LoginDialogComponent,ModelRegistry,ModelRuntime,ModelSelectorComponent,OAuthSelectorComponent,ProjectTrustStore,RpcClient,SessionManager,SessionSelectorComponent,SettingsManager,SettingsSelectorComponent,ShowImagesSelectorComponent,SkillInvocationMessageComponent,TaskRuntime,Theme,ThemeSelectorComponent,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent,VERSION,VIRTUAL_MODEL_STATE_ENTRY,buildContextEntries,buildSessionContext,buildSessionProjection,calculateContextTokens,collectEntriesForBranchSummary,compact,convertToLlm,convertToPng,copyToClipboard,createAgentSession,createAgentSessionFromServices,createAgentSessionRuntime,createAgentSessionServices,createBashTool,createBashToolDefinition,createCodemodeExtension,createCodingTools,createEditTool,createEditToolDefinition,createEventBus,createExtensionRuntime,createFindTool,createFindToolDefinition,createGrepTool,createGrepToolDefinition,createLocalBashOperations,createLocalPowerShellOperations,createLsTool,createLsToolDefinition,createMcpExtension,createPowerShellTool,createPowerShellToolDefinition,createReadOnlyTools,createReadTool,createReadToolDefinition,createSyntheticSourceInfo,createToolSearchExtension,createWriteTool,createWriteToolDefinition,defineTool,detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions,estimateTokens,findCutPoint,findTurnStartIndex,formatDimensionNote,formatReadLineRange,formatSize,formatSkillsForPrompt,generateBranchSummary,generateDiffString,generateSummary,generateSummaryWithUsage,generateUnifiedPatch,getAgentDir,getDocsPath,getExamplesPath,getLanguageFromPath,getLastAssistantUsage,getLatestCompactionEntry,getMarkdownTheme,getPackageDir,getPowerShellConfig,getReadmePath,getSelectListTheme,getSettingsListTheme,getShellConfig,hasTrustRequiringProjectResources,highlightCode,initTheme,isBashToolResult,isEditToolResult,isFindToolResult,isGrepToolResult,isLsToolResult,isPowerShellToolResult,isReadToolResult,isToolCallEventType,isWriteToolResult,keyHint,keyText,loadProjectContextFiles,loadSkills,loadSkillsFromDir,main,migrateSessionEntries,parseArgs,parseFrontmatter,parseSessionEntries,parseSkillBlock,prepareBranchEntries,rawKeyHint,readStoredCredential,renderDiff,resizeImage,resolveCliModel,resolveModelScopeWithDiagnostics,runPrintMode,runRpcMode,serializeConversation,sessionEntryToContextMessages,shouldCompact,stripFrontmatter,truncateHead,truncateLine,truncateTail,truncateToVisualLines,withFileMutationQueue,wrapRegisteredTool,wrapRegisteredTools};
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
3
- import{configureHttpDispatcher,main}from"./chunks/chunk-R3YHAMWH.js";import"./chunks/chunk-FPALVF3F.js";import"./chunks/chunk-KBFO53OG.js";import"./chunks/chunk-THAJ4BZF.js";import"./chunks/chunk-6QGV3IWD.js";import{APP_NAME}from"./chunks/chunk-PSYLMRL6.js";import"./chunks/chunk-JEIV47WR.js";import"./chunks/chunk-D3ZCGC4T.js";import"./chunks/chunk-RZ2V53SP.js";import"./chunks/chunk-5FDOJRDS.js";import"./chunks/chunk-IC6JXX2J.js";import"./chunks/chunk-SR6EWNPW.js";import"./chunks/chunk-RAIYJ5FC.js";import"./chunks/chunk-6VYRLG5F.js";import"./chunks/chunk-H3UF54OB.js";import"./chunks/chunk-4L3WN2XY.js";process.title=`${APP_NAME}-rpc`;process.env.PI_CODING_AGENT="true";process.env.AI_AGENT="pi";process.emitWarning=(()=>{});configureHttpDispatcher();main(["--mode","rpc",...process.argv.slice(2)]);
3
+ import{configureHttpDispatcher,main}from"./chunks/chunk-M3D4ADUT.js";import"./chunks/chunk-FPALVF3F.js";import"./chunks/chunk-KBFO53OG.js";import"./chunks/chunk-HLVMLRZJ.js";import"./chunks/chunk-6QGV3IWD.js";import{APP_NAME}from"./chunks/chunk-PSYLMRL6.js";import"./chunks/chunk-JEIV47WR.js";import"./chunks/chunk-D3ZCGC4T.js";import"./chunks/chunk-RZ2V53SP.js";import"./chunks/chunk-5FDOJRDS.js";import"./chunks/chunk-IC6JXX2J.js";import"./chunks/chunk-SR6EWNPW.js";import"./chunks/chunk-RAIYJ5FC.js";import"./chunks/chunk-6VYRLG5F.js";import"./chunks/chunk-H3UF54OB.js";import"./chunks/chunk-4L3WN2XY.js";process.title=`${APP_NAME}-rpc`;process.env.PI_CODING_AGENT="true";process.env.AI_AGENT="pi";process.emitWarning=(()=>{});configureHttpDispatcher();main(["--mode","rpc",...process.argv.slice(2)]);
@@ -0,0 +1,14 @@
1
+ import type { TaskActivity, TaskStatus } from "./types.ts";
2
+ export declare function activityStatusAsTaskStatus(status: TaskActivity["status"]): TaskStatus;
3
+ /** `Nms` under a second, `N.Ns` under a minute, then the shared `1m 5s` form. */
4
+ export declare function formatTaskActivityDuration(ms: number | undefined): string;
5
+ /** The tool-name column never grows enough for one long name to push every target away. */
6
+ export declare function taskActivityNameWidth(activities: readonly TaskActivity[]): number;
7
+ /** The first non-empty line of a failure, clipped to one display line. */
8
+ export declare function taskActivityErrorLine(error: string): string;
9
+ export declare function earlierTaskActivitiesLabel(earlier: number): string;
10
+ /** Portable `glyph name target · duration`, plus a failure line under the target column. */
11
+ export declare function taskActivityText(activity: TaskActivity, nameWidth?: number): string;
12
+ /** The portable display: omitted-call count, then one aligned row per retained activity. */
13
+ export declare function taskActivitiesText(activities: readonly TaskActivity[], earlier?: number): string;
14
+ //# sourceMappingURL=activity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/activity.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAY3D,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,UAAU,CAErF;AAED,iFAAiF;AACjF,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMzE;AAED,2FAA2F;AAC3F,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAEjF;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI3D;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElE;AASD,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,SAAoC,GAAG,MAAM,CAO9G;AAED,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,SAAS,YAAY,EAAE,EAAE,OAAO,SAAI,GAAG,MAAM,CAI3F"}
@@ -0,0 +1,58 @@
1
+ /** Theme-free formatting shared by portable task displays and interactive activity rows. */
2
+ import { formatDuration } from "../../utils/duration.js";
3
+ const NAME_COLUMN_MAX = 8;
4
+ const ERROR_LINE_CHARS = 160;
5
+ const TASK_STATUS = {
6
+ running: "running",
7
+ ok: "completed",
8
+ error: "failed",
9
+ cancelled: "cancelled",
10
+ };
11
+ export function activityStatusAsTaskStatus(status) {
12
+ return TASK_STATUS[status];
13
+ }
14
+ /** `Nms` under a second, `N.Ns` under a minute, then the shared `1m 5s` form. */
15
+ export function formatTaskActivityDuration(ms) {
16
+ if (ms === undefined)
17
+ return "";
18
+ const millis = Math.round(ms);
19
+ if (millis < 1000)
20
+ return `${millis}ms`;
21
+ const tenths = Math.round(ms / 100) / 10;
22
+ return tenths < 60 ? `${tenths.toFixed(1)}s` : formatDuration(ms);
23
+ }
24
+ /** The tool-name column never grows enough for one long name to push every target away. */
25
+ export function taskActivityNameWidth(activities) {
26
+ return Math.min(NAME_COLUMN_MAX, Math.max(0, ...activities.map((activity) => activity.name.length)));
27
+ }
28
+ /** The first non-empty line of a failure, clipped to one display line. */
29
+ export function taskActivityErrorLine(error) {
30
+ const line = (error.split(/\r?\n/u).find((part) => part.trim()) ?? "").replace(/\s+/gu, " ").trim();
31
+ const chars = Array.from(line);
32
+ return chars.length > ERROR_LINE_CHARS ? `${chars.slice(0, ERROR_LINE_CHARS - 1).join("")}…` : line;
33
+ }
34
+ export function earlierTaskActivitiesLabel(earlier) {
35
+ return `… ${earlier} earlier tool ${earlier === 1 ? "call" : "calls"}`;
36
+ }
37
+ const PLAIN_GLYPH = {
38
+ running: "›",
39
+ ok: "✓",
40
+ error: "×",
41
+ cancelled: "○",
42
+ };
43
+ /** Portable `glyph name target · duration`, plus a failure line under the target column. */
44
+ export function taskActivityText(activity, nameWidth = taskActivityNameWidth([activity])) {
45
+ const target = activity.target ?? "";
46
+ const name = target ? activity.name.padEnd(nameWidth) : activity.name;
47
+ const duration = formatTaskActivityDuration(activity.durationMs);
48
+ const line = `${PLAIN_GLYPH[activity.status]} ${name}${target ? ` ${target}` : ""}${duration ? ` · ${duration}` : ""}`;
49
+ const error = activity.error ? taskActivityErrorLine(activity.error) : "";
50
+ return error ? `${line}\n${" ".repeat(3 + nameWidth)}${error}` : line;
51
+ }
52
+ /** The portable display: omitted-call count, then one aligned row per retained activity. */
53
+ export function taskActivitiesText(activities, earlier = 0) {
54
+ const width = taskActivityNameWidth(activities);
55
+ const rows = activities.map((activity) => taskActivityText(activity, width));
56
+ return (earlier > 0 ? [earlierTaskActivitiesLabel(earlier), ...rows] : rows).join("\n");
57
+ }
58
+ //# sourceMappingURL=activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../../src/core/tasks/activity.ts"],"names":[],"mappings":"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","sourcesContent":["/** Theme-free formatting shared by portable task displays and interactive activity rows. */\nimport { formatDuration } from \"../../utils/duration.ts\";\nimport type { TaskActivity, TaskStatus } from \"./types.ts\";\n\nconst NAME_COLUMN_MAX = 8;\nconst ERROR_LINE_CHARS = 160;\n\nconst TASK_STATUS: Record<TaskActivity[\"status\"], TaskStatus> = {\n\trunning: \"running\",\n\tok: \"completed\",\n\terror: \"failed\",\n\tcancelled: \"cancelled\",\n};\n\nexport function activityStatusAsTaskStatus(status: TaskActivity[\"status\"]): TaskStatus {\n\treturn TASK_STATUS[status];\n}\n\n/** `Nms` under a second, `N.Ns` under a minute, then the shared `1m 5s` form. */\nexport function formatTaskActivityDuration(ms: number | undefined): string {\n\tif (ms === undefined) return \"\";\n\tconst millis = Math.round(ms);\n\tif (millis < 1000) return `${millis}ms`;\n\tconst tenths = Math.round(ms / 100) / 10;\n\treturn tenths < 60 ? `${tenths.toFixed(1)}s` : formatDuration(ms);\n}\n\n/** The tool-name column never grows enough for one long name to push every target away. */\nexport function taskActivityNameWidth(activities: readonly TaskActivity[]): number {\n\treturn Math.min(NAME_COLUMN_MAX, Math.max(0, ...activities.map((activity) => activity.name.length)));\n}\n\n/** The first non-empty line of a failure, clipped to one display line. */\nexport function taskActivityErrorLine(error: string): string {\n\tconst line = (error.split(/\\r?\\n/u).find((part) => part.trim()) ?? \"\").replace(/\\s+/gu, \" \").trim();\n\tconst chars = Array.from(line);\n\treturn chars.length > ERROR_LINE_CHARS ? `${chars.slice(0, ERROR_LINE_CHARS - 1).join(\"\")}…` : line;\n}\n\nexport function earlierTaskActivitiesLabel(earlier: number): string {\n\treturn `… ${earlier} earlier tool ${earlier === 1 ? \"call\" : \"calls\"}`;\n}\n\nconst PLAIN_GLYPH: Record<TaskActivity[\"status\"], string> = {\n\trunning: \"›\",\n\tok: \"✓\",\n\terror: \"×\",\n\tcancelled: \"○\",\n};\n\n/** Portable `glyph name target · duration`, plus a failure line under the target column. */\nexport function taskActivityText(activity: TaskActivity, nameWidth = taskActivityNameWidth([activity])): string {\n\tconst target = activity.target ?? \"\";\n\tconst name = target ? activity.name.padEnd(nameWidth) : activity.name;\n\tconst duration = formatTaskActivityDuration(activity.durationMs);\n\tconst line = `${PLAIN_GLYPH[activity.status]} ${name}${target ? ` ${target}` : \"\"}${duration ? ` · ${duration}` : \"\"}`;\n\tconst error = activity.error ? taskActivityErrorLine(activity.error) : \"\";\n\treturn error ? `${line}\\n${\" \".repeat(3 + nameWidth)}${error}` : line;\n}\n\n/** The portable display: omitted-call count, then one aligned row per retained activity. */\nexport function taskActivitiesText(activities: readonly TaskActivity[], earlier = 0): string {\n\tconst width = taskActivityNameWidth(activities);\n\tconst rows = activities.map((activity) => taskActivityText(activity, width));\n\treturn (earlier > 0 ? [earlierTaskActivitiesLabel(earlier), ...rows] : rows).join(\"\\n\");\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/execution.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAU1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAEX,WAAW,EACX,aAAa,EAGb,YAAY,EAGZ,eAAe,EAEf,MAAM,YAAY,CAAC;AAEpB,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,IAAI,IAAI,IAAI,CAAC;IACb,0EAA0E;IAC1E,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI,CAAC;IAC3D,mFAAmF;IACnF,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CAC9C;AAyBD;;;;;;;GAOG;AACH,qBAAa,SAAS,CAAC,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA0B;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuC;IACrE,OAAO,CAAC,aAAa,CAAyC;IAC9D,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,QAAQ,CAAC,CAAuC;IACxD,OAAO,CAAC,mBAAmB,CAAwB;IACnD,OAAO,CAAC,KAAK,CAAC,CAAQ;IACtB,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;IAClD,iDAAiD;IACjD,OAAO,CAAC,OAAO,CAAC,CAA6B;gBAEjC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IAwChF,IAAI,IAAI,IAAI,QAAQ,CAAC,YAAY,CAAC,CAEjC;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,6EAA6E;IAC7E,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,kGAAkG;IAClG,IAAI,mBAAmB,IAAI,OAAO,CAEjC;IAED,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,uGAAuG;IACvG,aAAa,IAAI,IAAI;IAMrB,KAAK,IAAI,IAAI;IAsBb,8FAA8F;IAC9F,eAAe,IAAI,IAAI;IAIvB;;;;OAIG;IACH,MAAM,IAAI,MAAM,IAAI;IAQpB,MAAM,IAAI,OAAO;IAWjB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,MAAM;IAUd;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;OAGG;IACH,OAAO,CAAC,OAAO;IAkBf,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,OAAO;IAiBf,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,MAAM;CAmDd"}
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/execution.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAW1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAEX,WAAW,EACX,aAAa,EAGb,YAAY,EAGZ,eAAe,EAEf,MAAM,YAAY,CAAC;AAEpB,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,IAAI,IAAI,IAAI,CAAC;IACb,0EAA0E;IAC1E,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI,CAAC;IAC3D,mFAAmF;IACnF,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CAC9C;AAyBD;;;;;;;GAOG;AACH,qBAAa,SAAS,CAAC,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA0B;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuC;IACrE,OAAO,CAAC,aAAa,CAAyC;IAC9D,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,QAAQ,CAAC,CAAuC;IACxD,OAAO,CAAC,mBAAmB,CAAwB;IACnD,OAAO,CAAC,KAAK,CAAC,CAAQ;IACtB,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;IAClD,iDAAiD;IACjD,OAAO,CAAC,OAAO,CAAC,CAA6B;gBAEjC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IAwChF,IAAI,IAAI,IAAI,QAAQ,CAAC,YAAY,CAAC,CAEjC;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,6EAA6E;IAC7E,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,kGAAkG;IAClG,IAAI,mBAAmB,IAAI,OAAO,CAEjC;IAED,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,uGAAuG;IACvG,aAAa,IAAI,IAAI;IAMrB,KAAK,IAAI,IAAI;IAsBb,8FAA8F;IAC9F,eAAe,IAAI,IAAI;IAIvB;;;;OAIG;IACH,MAAM,IAAI,MAAM,IAAI;IAQpB,MAAM,IAAI,OAAO;IAWjB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,MAAM;IAUd;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;OAGG;IACH,OAAO,CAAC,OAAO;IAkBf,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,OAAO;IAiBf,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,MAAM;CAmDd"}
@@ -1,4 +1,4 @@
1
- import { boundFacts, boundTaskText, boundText, errorText, resultText, TASK_ERROR_BYTES, TASK_PATH_BYTES, } from "./output.js";
1
+ import { boundFacts, boundTaskDisplay, boundTaskText, boundText, errorText, resultText, TASK_ERROR_BYTES, TASK_PATH_BYTES, } from "./output.js";
2
2
  function prependText(text, result) {
3
3
  return {
4
4
  text: boundText(result?.text ? `${text}\n${result.text}` : text),
@@ -208,7 +208,7 @@ export class Execution {
208
208
  this.record.update((task) => {
209
209
  task.result = resultText(update.result);
210
210
  if (update.display !== undefined)
211
- task.display = boundTaskText(update.display);
211
+ task.display = boundTaskDisplay(update.display);
212
212
  });
213
213
  if (update.usage !== undefined)
214
214
  this.usage = structuredClone(update.usage);
@@ -1 +1 @@
1
- {"version":3,"file":"execution.js","sourceRoot":"","sources":["../../../src/core/tasks/execution.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { Usage } from \"@earendil-works/pi-ai/compat\";\nimport {\n\tboundFacts,\n\tboundTaskText,\n\tboundText,\n\terrorText,\n\tresultText,\n\tTASK_ERROR_BYTES,\n\tTASK_PATH_BYTES,\n} from \"./output.ts\";\nimport type { TaskRecord } from \"./record.ts\";\nimport type {\n\tTaskCompletion,\n\tTaskControl,\n\tTaskExecution,\n\tTaskFact,\n\tTaskMode,\n\tTaskSnapshot,\n\tTaskTerminalStatus,\n\tTaskText,\n\tTaskToolOutcome,\n\tTaskUpdate,\n} from \"./types.ts\";\n\n/** The runtime services one execution needs; it never reaches into the runtime itself. */\nexport interface ExecutionHost {\n\treadonly closed: boolean;\n\temit(): void;\n\t/** Synchronous persistence before terminal observers or notifications. */\n\tsettle(task: TaskSnapshot, usage: Usage | undefined): void;\n\t/** The execution settled and holds no slot, parent listener or caller any more. */\n\treleased(execution: Execution<unknown>): void;\n}\n\nfunction prependText(text: string, result: TaskText | undefined): TaskText {\n\treturn {\n\t\ttext: boundText(result?.text ? `${text}\\n${result.text}` : text),\n\t\ttruncated: result?.truncated ?? false,\n\t};\n}\n\n/** Terminal rows replace launch rows with the same label and append new ones. */\nfunction mergeFacts(base: readonly TaskFact[] = [], terminal: readonly TaskFact[]): TaskFact[] {\n\tconst labels = new Set(terminal.map(([label]) => label));\n\treturn boundFacts([...base.filter(([label]) => !labels.has(label)), ...terminal]);\n}\n\n/** queued: waiting for a lane slot; preflight: `run` started, `accept()` not yet called; settled: terminal. */\ntype Phase = \"queued\" | \"preflight\" | \"accepted\" | \"settled\";\n\n/**\n * Where the launching tool call stands: still waiting for the result (`caller`), asked to be\n * released but held until the executor accepts (`detaching`), or released with a background\n * outcome (`background`). Only `background` is reported as the task's mode.\n */\ntype Placement = \"caller\" | \"detaching\" | \"background\";\n\n/**\n * One live task: its caller, controller, parent link and executor callbacks.\n *\n * A caller may be handed off to the background whenever no executor preflight is in\n * progress: before `run` starts (queued) or after the executor calls `accept()`. A release\n * requested during preflight waits for `accept()`; if the run settles first, the caller is\n * answered inline and the task never becomes background.\n */\nexport class Execution<T> {\n\treadonly record: TaskRecord;\n\treadonly kind: string;\n\treadonly concurrency?: { key: string; limit: number };\n\treadonly caller: Promise<TaskToolOutcome<T>>;\n\treadonly done: Promise<void>;\n\treadonly control: TaskControl<T>;\n\tprivate readonly host: ExecutionHost;\n\tprivate readonly run: TaskExecution<T>[\"run\"];\n\tprivate readonly controller = new AbortController();\n\tprivate readonly modeListeners = new Set<(mode: TaskMode) => void>();\n\tprivate resolveCaller!: (outcome: TaskToolOutcome<T>) => void;\n\tprivate rejectCaller!: (error: unknown) => void;\n\tprivate onUpdate?: (result: AgentToolResult<T>) => void;\n\tprivate releaseParentSignal: () => void = () => {};\n\tprivate usage?: Usage;\n\tprivate phase: Phase = \"queued\";\n\tprivate placement: Placement;\n\tprivate readonly reason: \"submitted\" | \"detached\";\n\t/** The executor's `run` promise once started. */\n\tprivate running?: Promise<TaskCompletion<T>>;\n\n\tconstructor(host: ExecutionHost, record: TaskRecord, execution: TaskExecution<T>) {\n\t\tthis.host = host;\n\t\tthis.record = record;\n\t\tthis.run = execution.run;\n\t\tthis.kind = execution.kind;\n\t\tthis.concurrency = execution.concurrency;\n\t\tthis.placement = execution.background ? \"detaching\" : \"caller\";\n\t\tthis.reason = execution.background ? \"submitted\" : \"detached\";\n\t\tthis.onUpdate = execution.onUpdate;\n\t\tthis.caller = new Promise<TaskToolOutcome<T>>((resolve, reject) => {\n\t\t\tthis.resolveCaller = resolve;\n\t\t\tthis.rejectCaller = reject;\n\t\t});\n\t\tthis.done = record.settlement;\n\t\tconst parent = execution.signal;\n\t\tif (parent) {\n\t\t\t// A caller that is leaving survives the parent's abort unless the executor is mid-preflight.\n\t\t\tconst abort = () => {\n\t\t\t\tif (this.placement === \"caller\" || this.phase === \"preflight\") this.cancel();\n\t\t\t};\n\t\t\tparent.addEventListener(\"abort\", abort, { once: true });\n\t\t\tthis.releaseParentSignal = () => parent.removeEventListener(\"abort\", abort);\n\t\t}\n\t\tconst task = record.task;\n\t\tthis.control = {\n\t\t\tid: task.id,\n\t\t\tsignal: this.controller.signal,\n\t\t\tget mode() {\n\t\t\t\treturn task.mode;\n\t\t\t},\n\t\t\tonModeChange: (listener) => this.onModeChange(listener),\n\t\t\taccept: () => this.accept(),\n\t\t\tpublish: (update) => this.publish(update),\n\t\t\tattachOutput: (path, cleanup) => this.attachOutput(path, cleanup),\n\t\t\tcancel: () => {\n\t\t\t\tthis.cancel();\n\t\t\t},\n\t\t};\n\t}\n\n\tget task(): Readonly<TaskSnapshot> {\n\t\treturn this.record.task;\n\t}\n\n\tget aborted(): boolean {\n\t\treturn this.controller.signal.aborted;\n\t}\n\n\t/** Waiting for a concurrency slot: registered, but `run` has not started. */\n\tget queued(): boolean {\n\t\treturn this.phase === \"queued\";\n\t}\n\n\t/** Holds a background slot: handed off, or asked to be and waiting for the executor to accept. */\n\tget holdsBackgroundSlot(): boolean {\n\t\treturn this.phase !== \"settled\" && this.placement !== \"caller\";\n\t}\n\n\tget detachable(): boolean {\n\t\treturn this.phase !== \"settled\" && this.placement === \"caller\" && !this.aborted;\n\t}\n\n\t/** Stop forwarding to the launching tool call: parent cancellation and progress no longer reach it. */\n\treleaseParent(): void {\n\t\tthis.releaseParentSignal();\n\t\tthis.releaseParentSignal = () => {};\n\t\tthis.onUpdate = undefined;\n\t}\n\n\tstart(): void {\n\t\tif (this.phase !== \"queued\") return;\n\t\tif (this.host.closed) {\n\t\t\tthis.cancel();\n\t\t\treturn;\n\t\t}\n\t\tthis.phase = \"preflight\";\n\t\tthis.record.update((task) => {\n\t\t\ttask.status = \"running\";\n\t\t});\n\t\t// The rejection handler is installed immediately, including for synchronous preflight throws.\n\t\ttry {\n\t\t\tthis.running = Promise.resolve(this.run(this.control));\n\t\t\tvoid this.running.then(\n\t\t\t\t(completion) => this.finish(completion),\n\t\t\t\t(error: unknown) => this.finish(undefined, error),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.finish(undefined, error);\n\t\t}\n\t}\n\n\t/** Queued background work returns at once; started work is released at its own `accept()`. */\n\thandOffIfQueued(): void {\n\t\tif (this.phase === \"queued\" && this.handoff()) this.announceBackground();\n\t}\n\n\t/**\n\t * Ask to move the caller to the background. The placement changes now; the returned\n\t * notification is for the caller of a batch to run after every placement has changed, so no\n\t * listener ever observes a half-moved set.\n\t */\n\tdetach(): () => void {\n\t\tthis.placement = \"detaching\";\n\t\tconst released = this.handoff();\n\t\treturn () => {\n\t\t\tif (released) this.announceBackground();\n\t\t};\n\t}\n\n\tcancel(): boolean {\n\t\tif (this.phase === \"settled\" || this.aborted) return false;\n\t\tthis.record.update((task) => {\n\t\t\ttask.status = \"stopping\";\n\t\t});\n\t\tthis.controller.abort();\n\t\tif (this.phase === \"queued\") this.finish(undefined, new Error(\"Task cancelled before it started.\"));\n\t\tthis.host.emit();\n\t\treturn true;\n\t}\n\n\tprivate onModeChange(listener: (mode: TaskMode) => void): () => void {\n\t\tif (this.phase === \"settled\" || this.host.closed) return () => {};\n\t\tthis.modeListeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.modeListeners.delete(listener);\n\t\t};\n\t}\n\n\tprivate accept(): void {\n\t\tif (this.phase !== \"preflight\" || this.host.closed || this.aborted) return;\n\t\tthis.phase = \"accepted\";\n\t\tif (this.placement === \"detaching\") this.releaseParent();\n\t\t// An already available final result wins over a handoff, so decide only once the\n\t\t// executor's own synchronous code has yielded.\n\t\tqueueMicrotask(() => this.handoffIfRunning());\n\t\tthis.host.emit();\n\t}\n\n\t/**\n\t * Hand off unless `run` has already settled. This observes the `run` promise's own settlement,\n\t * not the phase `finish()` sets: a reaction on an already settled promise is queued at once,\n\t * ahead of the pending-check below whatever the promise's chain depth, so the outcome never\n\t * depends on how many hops `start()` chains before `finish()`.\n\t */\n\tprivate handoffIfRunning(): void {\n\t\tlet settled = false;\n\t\tconst markSettled = () => {\n\t\t\tsettled = true;\n\t\t};\n\t\tthis.running?.then(markSettled, markSettled);\n\t\tvoid Promise.resolve().then(() => {\n\t\t\tif (!settled && this.handoff()) this.announceBackground();\n\t\t});\n\t}\n\n\t/**\n\t * Release the caller with a background outcome if it asked to leave and the executor's\n\t * preflight is over. The task is background exactly from here on.\n\t */\n\tprivate handoff(): boolean {\n\t\tif (\n\t\t\tthis.placement !== \"detaching\" ||\n\t\t\t(this.phase !== \"queued\" && this.phase !== \"accepted\") ||\n\t\t\tthis.host.closed ||\n\t\t\t!this.record.visible ||\n\t\t\tthis.aborted\n\t\t)\n\t\t\treturn false;\n\t\tthis.placement = \"background\";\n\t\tthis.record.update((task) => {\n\t\t\ttask.mode = \"background\";\n\t\t});\n\t\tthis.releaseParent();\n\t\tthis.resolveCaller({ kind: \"background\", task: this.record.snapshot(), reason: this.reason });\n\t\treturn true;\n\t}\n\n\tprivate announceBackground(): void {\n\t\tfor (const listener of [...this.modeListeners]) {\n\t\t\ttry {\n\t\t\t\tlistener(\"background\");\n\t\t\t} catch {\n\t\t\t\t/* Executors own their diagnostics. */\n\t\t\t}\n\t\t}\n\t\tthis.host.emit();\n\t}\n\n\tprivate publish(update: TaskUpdate<T>): void {\n\t\tif (this.phase === \"settled\" || this.host.closed) return;\n\t\tthis.record.update((task) => {\n\t\t\ttask.result = resultText(update.result);\n\t\t\tif (update.display !== undefined) task.display = boundTaskText(update.display);\n\t\t});\n\t\tif (update.usage !== undefined) this.usage = structuredClone(update.usage);\n\t\tif (this.placement === \"caller\") {\n\t\t\ttry {\n\t\t\t\tthis.onUpdate?.(update.result);\n\t\t\t} catch {\n\t\t\t\t/* UI observers cannot stop execution. */\n\t\t\t}\n\t\t}\n\t\tthis.host.emit();\n\t}\n\n\tprivate attachOutput(path: string, cleanup?: () => void | Promise<void>): void {\n\t\tif (this.phase === \"settled\") {\n\t\t\tif (cleanup) throw new Error(\"Task execution has settled\");\n\t\t\treturn;\n\t\t}\n\t\t// Never truncate a real filesystem path into a different path.\n\t\tif (Buffer.byteLength(path) > TASK_PATH_BYTES) throw new Error(\"Task output path is too large\");\n\t\tthis.record.attachOutput(path, cleanup);\n\t\tthis.host.emit();\n\t}\n\n\tprivate finish(completion: TaskCompletion<T> | undefined, error?: unknown): void {\n\t\tconst record = this.record;\n\t\tif (this.phase === \"settled\") return;\n\t\tthis.phase = \"settled\";\n\t\tthis.modeListeners.clear();\n\t\tthis.releaseParent();\n\t\tconst status: TaskTerminalStatus = completion\n\t\t\t? (completion.status ?? (this.aborted ? \"cancelled\" : \"completed\"))\n\t\t\t: this.aborted\n\t\t\t\t? \"cancelled\"\n\t\t\t\t: \"failed\";\n\t\trecord.update((task) => {\n\t\t\ttask.endedAt = Date.now();\n\t\t\ttask.status = status;\n\t\t\t// Progress display is the executor's live view; a terminal snapshot shows only what the completion gives.\n\t\t\ttask.display = completion?.display === undefined ? undefined : boundTaskText(completion.display);\n\t\t\tif (completion) {\n\t\t\t\ttask.result = resultText(completion.result);\n\t\t\t\tif (completion.error !== undefined) task.error = boundText(completion.error, TASK_ERROR_BYTES);\n\t\t\t\tif (completion.facts) task.facts = mergeFacts(task.facts, completion.facts);\n\t\t\t} else {\n\t\t\t\ttask.error = errorText(error);\n\t\t\t\ttask.result = prependText(task.error, task.result);\n\t\t\t}\n\t\t});\n\t\t// The caller sees the executor's own diagnostic; a settlement warning is already in its content.\n\t\tconst diagnostic = record.task.error;\n\t\tlet warning: string | undefined;\n\t\ttry {\n\t\t\tthis.host.settle(record.snapshot(), completion?.usage ?? completion?.result.usage ?? this.usage);\n\t\t} catch (accountingError) {\n\t\t\tconst notice = `Usage settlement failed: ${errorText(accountingError)}`;\n\t\t\twarning = notice;\n\t\t\trecord.update((task) => {\n\t\t\t\ttask.error = boundText([task.error, notice].filter(Boolean).join(\"\\n\"), 2 * TASK_ERROR_BYTES);\n\t\t\t\ttask.result = prependText(notice, task.result);\n\t\t\t});\n\t\t}\n\t\tthis.usage = undefined;\n\t\tif (this.placement !== \"background\") {\n\t\t\tif (!completion) this.rejectCaller(error);\n\t\t\telse {\n\t\t\t\t// The task ledger owns usage; a tool result never carries it a second time.\n\t\t\t\tconst { usage: _usage, ...result } = completion.result;\n\t\t\t\tif (warning) result.content = [{ type: \"text\", text: warning }, ...result.content];\n\t\t\t\tthis.resolveCaller({ kind: \"result\", result, status, error: diagnostic });\n\t\t\t}\n\t\t}\n\t\trecord.settle();\n\t\tthis.host.released(this as Execution<unknown>);\n\t}\n}\n"]}
1
+ {"version":3,"file":"execution.js","sourceRoot":"","sources":["../../../src/core/tasks/execution.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { Usage } from \"@earendil-works/pi-ai/compat\";\nimport {\n\tboundFacts,\n\tboundTaskDisplay,\n\tboundTaskText,\n\tboundText,\n\terrorText,\n\tresultText,\n\tTASK_ERROR_BYTES,\n\tTASK_PATH_BYTES,\n} from \"./output.ts\";\nimport type { TaskRecord } from \"./record.ts\";\nimport type {\n\tTaskCompletion,\n\tTaskControl,\n\tTaskExecution,\n\tTaskFact,\n\tTaskMode,\n\tTaskSnapshot,\n\tTaskTerminalStatus,\n\tTaskText,\n\tTaskToolOutcome,\n\tTaskUpdate,\n} from \"./types.ts\";\n\n/** The runtime services one execution needs; it never reaches into the runtime itself. */\nexport interface ExecutionHost {\n\treadonly closed: boolean;\n\temit(): void;\n\t/** Synchronous persistence before terminal observers or notifications. */\n\tsettle(task: TaskSnapshot, usage: Usage | undefined): void;\n\t/** The execution settled and holds no slot, parent listener or caller any more. */\n\treleased(execution: Execution<unknown>): void;\n}\n\nfunction prependText(text: string, result: TaskText | undefined): TaskText {\n\treturn {\n\t\ttext: boundText(result?.text ? `${text}\\n${result.text}` : text),\n\t\ttruncated: result?.truncated ?? false,\n\t};\n}\n\n/** Terminal rows replace launch rows with the same label and append new ones. */\nfunction mergeFacts(base: readonly TaskFact[] = [], terminal: readonly TaskFact[]): TaskFact[] {\n\tconst labels = new Set(terminal.map(([label]) => label));\n\treturn boundFacts([...base.filter(([label]) => !labels.has(label)), ...terminal]);\n}\n\n/** queued: waiting for a lane slot; preflight: `run` started, `accept()` not yet called; settled: terminal. */\ntype Phase = \"queued\" | \"preflight\" | \"accepted\" | \"settled\";\n\n/**\n * Where the launching tool call stands: still waiting for the result (`caller`), asked to be\n * released but held until the executor accepts (`detaching`), or released with a background\n * outcome (`background`). Only `background` is reported as the task's mode.\n */\ntype Placement = \"caller\" | \"detaching\" | \"background\";\n\n/**\n * One live task: its caller, controller, parent link and executor callbacks.\n *\n * A caller may be handed off to the background whenever no executor preflight is in\n * progress: before `run` starts (queued) or after the executor calls `accept()`. A release\n * requested during preflight waits for `accept()`; if the run settles first, the caller is\n * answered inline and the task never becomes background.\n */\nexport class Execution<T> {\n\treadonly record: TaskRecord;\n\treadonly kind: string;\n\treadonly concurrency?: { key: string; limit: number };\n\treadonly caller: Promise<TaskToolOutcome<T>>;\n\treadonly done: Promise<void>;\n\treadonly control: TaskControl<T>;\n\tprivate readonly host: ExecutionHost;\n\tprivate readonly run: TaskExecution<T>[\"run\"];\n\tprivate readonly controller = new AbortController();\n\tprivate readonly modeListeners = new Set<(mode: TaskMode) => void>();\n\tprivate resolveCaller!: (outcome: TaskToolOutcome<T>) => void;\n\tprivate rejectCaller!: (error: unknown) => void;\n\tprivate onUpdate?: (result: AgentToolResult<T>) => void;\n\tprivate releaseParentSignal: () => void = () => {};\n\tprivate usage?: Usage;\n\tprivate phase: Phase = \"queued\";\n\tprivate placement: Placement;\n\tprivate readonly reason: \"submitted\" | \"detached\";\n\t/** The executor's `run` promise once started. */\n\tprivate running?: Promise<TaskCompletion<T>>;\n\n\tconstructor(host: ExecutionHost, record: TaskRecord, execution: TaskExecution<T>) {\n\t\tthis.host = host;\n\t\tthis.record = record;\n\t\tthis.run = execution.run;\n\t\tthis.kind = execution.kind;\n\t\tthis.concurrency = execution.concurrency;\n\t\tthis.placement = execution.background ? \"detaching\" : \"caller\";\n\t\tthis.reason = execution.background ? \"submitted\" : \"detached\";\n\t\tthis.onUpdate = execution.onUpdate;\n\t\tthis.caller = new Promise<TaskToolOutcome<T>>((resolve, reject) => {\n\t\t\tthis.resolveCaller = resolve;\n\t\t\tthis.rejectCaller = reject;\n\t\t});\n\t\tthis.done = record.settlement;\n\t\tconst parent = execution.signal;\n\t\tif (parent) {\n\t\t\t// A caller that is leaving survives the parent's abort unless the executor is mid-preflight.\n\t\t\tconst abort = () => {\n\t\t\t\tif (this.placement === \"caller\" || this.phase === \"preflight\") this.cancel();\n\t\t\t};\n\t\t\tparent.addEventListener(\"abort\", abort, { once: true });\n\t\t\tthis.releaseParentSignal = () => parent.removeEventListener(\"abort\", abort);\n\t\t}\n\t\tconst task = record.task;\n\t\tthis.control = {\n\t\t\tid: task.id,\n\t\t\tsignal: this.controller.signal,\n\t\t\tget mode() {\n\t\t\t\treturn task.mode;\n\t\t\t},\n\t\t\tonModeChange: (listener) => this.onModeChange(listener),\n\t\t\taccept: () => this.accept(),\n\t\t\tpublish: (update) => this.publish(update),\n\t\t\tattachOutput: (path, cleanup) => this.attachOutput(path, cleanup),\n\t\t\tcancel: () => {\n\t\t\t\tthis.cancel();\n\t\t\t},\n\t\t};\n\t}\n\n\tget task(): Readonly<TaskSnapshot> {\n\t\treturn this.record.task;\n\t}\n\n\tget aborted(): boolean {\n\t\treturn this.controller.signal.aborted;\n\t}\n\n\t/** Waiting for a concurrency slot: registered, but `run` has not started. */\n\tget queued(): boolean {\n\t\treturn this.phase === \"queued\";\n\t}\n\n\t/** Holds a background slot: handed off, or asked to be and waiting for the executor to accept. */\n\tget holdsBackgroundSlot(): boolean {\n\t\treturn this.phase !== \"settled\" && this.placement !== \"caller\";\n\t}\n\n\tget detachable(): boolean {\n\t\treturn this.phase !== \"settled\" && this.placement === \"caller\" && !this.aborted;\n\t}\n\n\t/** Stop forwarding to the launching tool call: parent cancellation and progress no longer reach it. */\n\treleaseParent(): void {\n\t\tthis.releaseParentSignal();\n\t\tthis.releaseParentSignal = () => {};\n\t\tthis.onUpdate = undefined;\n\t}\n\n\tstart(): void {\n\t\tif (this.phase !== \"queued\") return;\n\t\tif (this.host.closed) {\n\t\t\tthis.cancel();\n\t\t\treturn;\n\t\t}\n\t\tthis.phase = \"preflight\";\n\t\tthis.record.update((task) => {\n\t\t\ttask.status = \"running\";\n\t\t});\n\t\t// The rejection handler is installed immediately, including for synchronous preflight throws.\n\t\ttry {\n\t\t\tthis.running = Promise.resolve(this.run(this.control));\n\t\t\tvoid this.running.then(\n\t\t\t\t(completion) => this.finish(completion),\n\t\t\t\t(error: unknown) => this.finish(undefined, error),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.finish(undefined, error);\n\t\t}\n\t}\n\n\t/** Queued background work returns at once; started work is released at its own `accept()`. */\n\thandOffIfQueued(): void {\n\t\tif (this.phase === \"queued\" && this.handoff()) this.announceBackground();\n\t}\n\n\t/**\n\t * Ask to move the caller to the background. The placement changes now; the returned\n\t * notification is for the caller of a batch to run after every placement has changed, so no\n\t * listener ever observes a half-moved set.\n\t */\n\tdetach(): () => void {\n\t\tthis.placement = \"detaching\";\n\t\tconst released = this.handoff();\n\t\treturn () => {\n\t\t\tif (released) this.announceBackground();\n\t\t};\n\t}\n\n\tcancel(): boolean {\n\t\tif (this.phase === \"settled\" || this.aborted) return false;\n\t\tthis.record.update((task) => {\n\t\t\ttask.status = \"stopping\";\n\t\t});\n\t\tthis.controller.abort();\n\t\tif (this.phase === \"queued\") this.finish(undefined, new Error(\"Task cancelled before it started.\"));\n\t\tthis.host.emit();\n\t\treturn true;\n\t}\n\n\tprivate onModeChange(listener: (mode: TaskMode) => void): () => void {\n\t\tif (this.phase === \"settled\" || this.host.closed) return () => {};\n\t\tthis.modeListeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.modeListeners.delete(listener);\n\t\t};\n\t}\n\n\tprivate accept(): void {\n\t\tif (this.phase !== \"preflight\" || this.host.closed || this.aborted) return;\n\t\tthis.phase = \"accepted\";\n\t\tif (this.placement === \"detaching\") this.releaseParent();\n\t\t// An already available final result wins over a handoff, so decide only once the\n\t\t// executor's own synchronous code has yielded.\n\t\tqueueMicrotask(() => this.handoffIfRunning());\n\t\tthis.host.emit();\n\t}\n\n\t/**\n\t * Hand off unless `run` has already settled. This observes the `run` promise's own settlement,\n\t * not the phase `finish()` sets: a reaction on an already settled promise is queued at once,\n\t * ahead of the pending-check below whatever the promise's chain depth, so the outcome never\n\t * depends on how many hops `start()` chains before `finish()`.\n\t */\n\tprivate handoffIfRunning(): void {\n\t\tlet settled = false;\n\t\tconst markSettled = () => {\n\t\t\tsettled = true;\n\t\t};\n\t\tthis.running?.then(markSettled, markSettled);\n\t\tvoid Promise.resolve().then(() => {\n\t\t\tif (!settled && this.handoff()) this.announceBackground();\n\t\t});\n\t}\n\n\t/**\n\t * Release the caller with a background outcome if it asked to leave and the executor's\n\t * preflight is over. The task is background exactly from here on.\n\t */\n\tprivate handoff(): boolean {\n\t\tif (\n\t\t\tthis.placement !== \"detaching\" ||\n\t\t\t(this.phase !== \"queued\" && this.phase !== \"accepted\") ||\n\t\t\tthis.host.closed ||\n\t\t\t!this.record.visible ||\n\t\t\tthis.aborted\n\t\t)\n\t\t\treturn false;\n\t\tthis.placement = \"background\";\n\t\tthis.record.update((task) => {\n\t\t\ttask.mode = \"background\";\n\t\t});\n\t\tthis.releaseParent();\n\t\tthis.resolveCaller({ kind: \"background\", task: this.record.snapshot(), reason: this.reason });\n\t\treturn true;\n\t}\n\n\tprivate announceBackground(): void {\n\t\tfor (const listener of [...this.modeListeners]) {\n\t\t\ttry {\n\t\t\t\tlistener(\"background\");\n\t\t\t} catch {\n\t\t\t\t/* Executors own their diagnostics. */\n\t\t\t}\n\t\t}\n\t\tthis.host.emit();\n\t}\n\n\tprivate publish(update: TaskUpdate<T>): void {\n\t\tif (this.phase === \"settled\" || this.host.closed) return;\n\t\tthis.record.update((task) => {\n\t\t\ttask.result = resultText(update.result);\n\t\t\tif (update.display !== undefined) task.display = boundTaskDisplay(update.display);\n\t\t});\n\t\tif (update.usage !== undefined) this.usage = structuredClone(update.usage);\n\t\tif (this.placement === \"caller\") {\n\t\t\ttry {\n\t\t\t\tthis.onUpdate?.(update.result);\n\t\t\t} catch {\n\t\t\t\t/* UI observers cannot stop execution. */\n\t\t\t}\n\t\t}\n\t\tthis.host.emit();\n\t}\n\n\tprivate attachOutput(path: string, cleanup?: () => void | Promise<void>): void {\n\t\tif (this.phase === \"settled\") {\n\t\t\tif (cleanup) throw new Error(\"Task execution has settled\");\n\t\t\treturn;\n\t\t}\n\t\t// Never truncate a real filesystem path into a different path.\n\t\tif (Buffer.byteLength(path) > TASK_PATH_BYTES) throw new Error(\"Task output path is too large\");\n\t\tthis.record.attachOutput(path, cleanup);\n\t\tthis.host.emit();\n\t}\n\n\tprivate finish(completion: TaskCompletion<T> | undefined, error?: unknown): void {\n\t\tconst record = this.record;\n\t\tif (this.phase === \"settled\") return;\n\t\tthis.phase = \"settled\";\n\t\tthis.modeListeners.clear();\n\t\tthis.releaseParent();\n\t\tconst status: TaskTerminalStatus = completion\n\t\t\t? (completion.status ?? (this.aborted ? \"cancelled\" : \"completed\"))\n\t\t\t: this.aborted\n\t\t\t\t? \"cancelled\"\n\t\t\t\t: \"failed\";\n\t\trecord.update((task) => {\n\t\t\ttask.endedAt = Date.now();\n\t\t\ttask.status = status;\n\t\t\t// Progress display is the executor's live view; a terminal snapshot shows only what the completion gives.\n\t\t\ttask.display = completion?.display === undefined ? undefined : boundTaskText(completion.display);\n\t\t\tif (completion) {\n\t\t\t\ttask.result = resultText(completion.result);\n\t\t\t\tif (completion.error !== undefined) task.error = boundText(completion.error, TASK_ERROR_BYTES);\n\t\t\t\tif (completion.facts) task.facts = mergeFacts(task.facts, completion.facts);\n\t\t\t} else {\n\t\t\t\ttask.error = errorText(error);\n\t\t\t\ttask.result = prependText(task.error, task.result);\n\t\t\t}\n\t\t});\n\t\t// The caller sees the executor's own diagnostic; a settlement warning is already in its content.\n\t\tconst diagnostic = record.task.error;\n\t\tlet warning: string | undefined;\n\t\ttry {\n\t\t\tthis.host.settle(record.snapshot(), completion?.usage ?? completion?.result.usage ?? this.usage);\n\t\t} catch (accountingError) {\n\t\t\tconst notice = `Usage settlement failed: ${errorText(accountingError)}`;\n\t\t\twarning = notice;\n\t\t\trecord.update((task) => {\n\t\t\t\ttask.error = boundText([task.error, notice].filter(Boolean).join(\"\\n\"), 2 * TASK_ERROR_BYTES);\n\t\t\t\ttask.result = prependText(notice, task.result);\n\t\t\t});\n\t\t}\n\t\tthis.usage = undefined;\n\t\tif (this.placement !== \"background\") {\n\t\t\tif (!completion) this.rejectCaller(error);\n\t\t\telse {\n\t\t\t\t// The task ledger owns usage; a tool result never carries it a second time.\n\t\t\t\tconst { usage: _usage, ...result } = completion.result;\n\t\t\t\tif (warning) result.content = [{ type: \"text\", text: warning }, ...result.content];\n\t\t\t\tthis.resolveCaller({ kind: \"result\", result, status, error: diagnostic });\n\t\t\t}\n\t\t}\n\t\trecord.settle();\n\t\tthis.host.released(this as Execution<unknown>);\n\t}\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
2
- import type { TaskFact, TaskInput, TaskRead, TaskReadOptions, TaskText } from "./types.ts";
2
+ import type { TaskDisplay, TaskFact, TaskInput, TaskRead, TaskReadOptions, TaskText } from "./types.ts";
3
3
  export declare const TASK_RESULT_BYTES: number;
4
4
  export declare const TASK_DETAILS_BYTES: number;
5
5
  export declare const TASK_READ_BYTES: number;
@@ -9,6 +9,7 @@ export declare const TASK_TITLE_BYTES = 1024;
9
9
  export declare const TASK_LABEL_BYTES = 256;
10
10
  export declare const TASK_FACTS = 16;
11
11
  export declare const TASK_FACT_BYTES = 1024;
12
+ export declare const TASK_ACTIVITIES = 50;
12
13
  export declare const TASK_ERROR_BYTES = 4096;
13
14
  export declare const TASK_PATH_BYTES = 8192;
14
15
  /** A bounded, printable message for any thrown value. */
@@ -16,6 +17,8 @@ export declare function errorText(error: unknown, fallback?: string): string;
16
17
  export declare function boundReadBytes(bytes: number | undefined): number;
17
18
  export declare function boundText(text: string, bytes?: number): string;
18
19
  export declare function boundTaskText(text: string, bytes?: number): TaskText;
20
+ /** Keep live display structured data bounded and detached; its plain text remains the portable fallback. */
21
+ export declare function boundTaskDisplay(display: string | TaskDisplay): TaskDisplay;
19
22
  export declare function boundInput(input: TaskInput): TaskInput;
20
23
  export declare function boundFacts(facts: readonly TaskFact[]): TaskFact[];
21
24
  /** The end of a bounded text, codepoint aligned: a command's outcome is at its end. */
@@ -1 +1 @@
1
- {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/output.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3F,eAAO,MAAM,iBAAiB,QAAY,CAAC;AAC3C,eAAO,MAAM,kBAAkB,QAAa,CAAC;AAC7C,eAAO,MAAM,eAAe,QAAW,CAAC;AACxC,eAAO,MAAM,gBAAgB,QAAY,CAAC;AAC1C,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC,yDAAyD;AACzD,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAA8C,GAAG,MAAM,CAMxG;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEhE;AAmBD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAoB,GAAG,MAAM,CAMzE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAoB,GAAG,QAAQ,CAG/E;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAQtD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAIjE;AAED,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAI3F;AAED,sGAAsG;AACtG,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,QAAQ,CAgBrE;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAGlH;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC,GAAG,MAAM,CAG5F;AA2BD,kFAAkF;AAClF,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,WAAW,CAAC,CAkBvG;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,WAAW,CAUlF"}
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/output.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE,OAAO,KAAK,EAAgB,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtH,eAAO,MAAM,iBAAiB,QAAY,CAAC;AAC3C,eAAO,MAAM,kBAAkB,QAAa,CAAC;AAC7C,eAAO,MAAM,eAAe,QAAW,CAAC;AACxC,eAAO,MAAM,gBAAgB,QAAY,CAAC;AAC1C,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC,yDAAyD;AACzD,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAA8C,GAAG,MAAM,CAMxG;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEhE;AAmBD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAoB,GAAG,MAAM,CAMzE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAoB,GAAG,QAAQ,CAG/E;AAqBD,4GAA4G;AAC5G,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,CAY3E;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAQtD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAIjE;AAED,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAI3F;AAED,sGAAsG;AACtG,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,QAAQ,CAgBrE;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAGlH;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC,GAAG,MAAM,CAG5F;AA2BD,kFAAkF;AAClF,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,WAAW,CAAC,CAkBvG;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,WAAW,CAUlF"}
@@ -9,6 +9,7 @@ export const TASK_TITLE_BYTES = 1024;
9
9
  export const TASK_LABEL_BYTES = 256;
10
10
  export const TASK_FACTS = 16;
11
11
  export const TASK_FACT_BYTES = 1024;
12
+ export const TASK_ACTIVITIES = 50;
12
13
  export const TASK_ERROR_BYTES = 4096;
13
14
  export const TASK_PATH_BYTES = 8192;
14
15
  /** A bounded, printable message for any thrown value. */
@@ -54,6 +55,38 @@ export function boundTaskText(text, bytes = TASK_RESULT_BYTES) {
54
55
  const bounded = boundText(text, bytes);
55
56
  return { text: bounded, truncated: bounded !== text };
56
57
  }
58
+ function activityTime(value) {
59
+ return value !== undefined && Number.isFinite(value) && value >= 0 ? value : undefined;
60
+ }
61
+ function boundActivity(activity) {
62
+ const target = activity.target === undefined ? undefined : boundText(activity.target, TASK_FACT_BYTES);
63
+ const error = activity.error === undefined ? undefined : boundText(activity.error, TASK_FACT_BYTES);
64
+ const startedAt = activityTime(activity.startedAt);
65
+ const durationMs = activityTime(activity.durationMs);
66
+ return {
67
+ name: boundText(activity.name, TASK_LABEL_BYTES),
68
+ status: activity.status,
69
+ ...(target === undefined ? {} : { target }),
70
+ ...(startedAt === undefined ? {} : { startedAt }),
71
+ ...(durationMs === undefined ? {} : { durationMs }),
72
+ ...(error === undefined ? {} : { error }),
73
+ };
74
+ }
75
+ /** Keep live display structured data bounded and detached; its plain text remains the portable fallback. */
76
+ export function boundTaskDisplay(display) {
77
+ if (typeof display === "string")
78
+ return boundTaskText(display);
79
+ const text = boundTaskText(display.text);
80
+ const activities = display.activities?.slice(-TASK_ACTIVITIES).map(boundActivity);
81
+ const omitted = display.activities ? display.activities.length - (activities?.length ?? 0) : 0;
82
+ const earlierActivities = finiteLimit((display.earlierActivities ?? 0) + omitted, 0, Number.MAX_SAFE_INTEGER);
83
+ return {
84
+ ...text,
85
+ truncated: display.truncated || text.truncated,
86
+ ...(activities ? { activities } : {}),
87
+ ...(display.earlierActivities !== undefined || omitted ? { earlierActivities } : {}),
88
+ };
89
+ }
57
90
  export function boundInput(input) {
58
91
  const text = boundTaskText(input.text, TASK_INPUT_BYTES);
59
92
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/core/tasks/output.ts"],"names":[],"mappings":"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","sourcesContent":["import { open } from \"node:fs/promises\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport { finiteLimit } from \"../../utils/number.ts\";\nimport type { TaskFact, TaskInput, TaskRead, TaskReadOptions, TaskText } from \"./types.ts\";\n\nexport const TASK_RESULT_BYTES = 48 * 1024;\nexport const TASK_DETAILS_BYTES = 120 * 1024;\nexport const TASK_READ_BYTES = 8 * 1024;\nexport const TASK_INPUT_BYTES = 24 * 1024;\n/** Task title budget, independent of notification wording and rendering. */\nexport const TASK_TITLE_BYTES = 1024;\nexport const TASK_LABEL_BYTES = 256;\nexport const TASK_FACTS = 16;\nexport const TASK_FACT_BYTES = 1024;\nexport const TASK_ERROR_BYTES = 4096;\nexport const TASK_PATH_BYTES = 8192;\n\n/** A bounded, printable message for any thrown value. */\nexport function errorText(error: unknown, fallback = \"Task execution failed (unprintable error)\"): string {\n\ttry {\n\t\treturn boundText(error instanceof Error ? error.message : String(error), TASK_ERROR_BYTES);\n\t} catch {\n\t\treturn fallback;\n\t}\n}\n\nexport function boundReadBytes(bytes: number | undefined): number {\n\treturn finiteLimit(bytes, TASK_READ_BYTES, TASK_RESULT_BYTES);\n}\n\n/** Both ends are codepoint aligned, including a head read ending inside a character. */\nfunction alignedSlice(buffer: Buffer, start: number, end: number): Buffer {\n\twhile (start < end && (buffer[start]! & 0xc0) === 0x80) start++;\n\tif (end < buffer.length) {\n\t\twhile (end > start && (buffer[end]! & 0xc0) === 0x80) end--;\n\t}\n\t// A concurrently written file can itself end in an incomplete UTF-8 sequence.\n\tlet lead = end - 1;\n\twhile (lead >= start && (buffer[lead]! & 0xc0) === 0x80) lead--;\n\tif (lead >= start) {\n\t\tconst byte = buffer[lead]!;\n\t\tconst width = byte >= 0xf0 ? 4 : byte >= 0xe0 ? 3 : byte >= 0xc0 ? 2 : 1;\n\t\tif (end - lead < width) end = lead;\n\t}\n\treturn buffer.subarray(start, end);\n}\n\nexport function boundText(text: string, bytes = TASK_RESULT_BYTES): string {\n\t// Avoid allocating a buffer proportional to an unbounded source.\n\tconst limit = finiteLimit(bytes, TASK_RESULT_BYTES, TASK_RESULT_BYTES);\n\tconst prefix = text.slice(0, limit + 1);\n\tconst buffer = Buffer.from(prefix);\n\treturn alignedSlice(buffer, 0, Math.min(limit, buffer.length)).toString(\"utf8\");\n}\n\nexport function boundTaskText(text: string, bytes = TASK_RESULT_BYTES): TaskText {\n\tconst bounded = boundText(text, bytes);\n\treturn { text: bounded, truncated: bounded !== text };\n}\n\nexport function boundInput(input: TaskInput): TaskInput {\n\tconst text = boundTaskText(input.text, TASK_INPUT_BYTES);\n\treturn {\n\t\tlabel: boundText(input.label, TASK_LABEL_BYTES),\n\t\ttext: text.text,\n\t\ttruncated: input.truncated || text.truncated,\n\t\t...(input.language ? { language: boundText(input.language, 64) } : {}),\n\t};\n}\n\nexport function boundFacts(facts: readonly TaskFact[]): TaskFact[] {\n\treturn facts\n\t\t.slice(0, TASK_FACTS)\n\t\t.map(([label, value]): TaskFact => [boundText(label, TASK_LABEL_BYTES), boundText(value, TASK_FACT_BYTES)]);\n}\n\n/** The end of a bounded text, codepoint aligned: a command's outcome is at its end. */\nexport function boundTail(text: string, bytes: number): { text: string; truncated: boolean } {\n\tconst buffer = Buffer.from(text);\n\tif (buffer.length <= bytes) return { text, truncated: false };\n\treturn { text: alignedSlice(buffer, buffer.length - bytes, buffer.length).toString(\"utf8\"), truncated: true };\n}\n\n/** The bounded model-readable text of a result; images and private details never enter task state. */\nexport function resultText(result: AgentToolResult<unknown>): TaskText {\n\tlet remaining = TASK_RESULT_BYTES;\n\tconst parts: string[] = [];\n\tlet truncated = false;\n\tfor (const block of result.content) {\n\t\tif (remaining <= 0) {\n\t\t\ttruncated = true;\n\t\t\tbreak;\n\t\t}\n\t\tconst source = block.type === \"text\" ? block.text : \"[Image omitted from task output]\";\n\t\tconst text = boundText(source, remaining);\n\t\tif (block.type !== \"text\" || text !== source) truncated = true;\n\t\tparts.push(text);\n\t\tremaining -= Math.max(1, Buffer.byteLength(text) + 1);\n\t}\n\treturn { text: boundText(parts.join(\"\\n\")), truncated };\n}\n\nexport interface OutputSlice {\n\ttext: string;\n\ttotalBytes: number;\n\ttruncated: boolean;\n\tfromByte: number;\n\t/** Raw source-byte end, independent of UTF-8 decoding or replacement characters. */\n\tendByte: number;\n}\n\n/** Raw source-byte range; decoding invalid UTF-8 must never move the continuation offset. */\nexport function taskReadRange(slice: Pick<TaskRead, \"text\" | \"fromByte\" | \"endByte\">): { from: number; to: number } {\n\tconst from = slice.fromByte ?? 0;\n\treturn { from, to: slice.endByte ?? from + Buffer.byteLength(slice.text) };\n}\n\nexport function taskReadBytes(slice: Pick<TaskRead, \"text\" | \"fromByte\" | \"endByte\">): number {\n\tconst { from, to } = taskReadRange(slice);\n\treturn to - from;\n}\n\n/**\n * The byte window a read covers in an output of `size` bytes. `floor` is the first byte the\n * caller has not seen yet. A head read continues forward from it; a tail read keeps the newest\n * unread window. Anything before the floor never counts as truncated.\n */\nfunction readWindow(size: number, options: TaskReadOptions): { start: number; length: number; floor: number } {\n\tconst bytes = boundReadBytes(options.bytes);\n\tconst since = finiteLimit(options.sinceBytes, 0, Number.MAX_SAFE_INTEGER);\n\tconst floor = since > size ? 0 : since;\n\tconst start =\n\t\toptions.mode === \"head\" ? (options.sinceBytes !== undefined ? floor : 0) : Math.max(floor, size - bytes);\n\treturn { start, length: Math.min(bytes, size - start), floor };\n}\n\nfunction outputSlice(size: number, slice: Buffer, fromByte: number, earlierTruncated: boolean): OutputSlice {\n\tconst endByte = fromByte + slice.byteLength;\n\treturn {\n\t\ttext: slice.toString(\"utf8\"),\n\t\ttotalBytes: size,\n\t\ttruncated: earlierTruncated || endByte < size,\n\t\tfromByte,\n\t\tendByte,\n\t};\n}\n\n/** Positioned, bounded reads only. The executor owns the path and its cleanup. */\nexport async function readOutputSlice(path: string, options: TaskReadOptions = {}): Promise<OutputSlice> {\n\tconst file = await open(path, \"r\");\n\ttry {\n\t\tconst { size } = await file.stat();\n\t\tconst { start, length, floor } = readWindow(size, options);\n\t\t// One extra byte lets alignment distinguish a complete last codepoint.\n\t\tconst buffer = Buffer.alloc(Math.min(length + 1, size - start));\n\t\tconst { bytesRead } = await file.read(buffer, 0, buffer.length, start);\n\t\tconst slice = alignedSlice(buffer.subarray(0, bytesRead), 0, Math.min(length, bytesRead));\n\t\treturn outputSlice(\n\t\t\tsize,\n\t\t\tslice,\n\t\t\tstart + slice.byteOffset - buffer.byteOffset,\n\t\t\toptions.mode !== \"head\" && start > floor,\n\t\t);\n\t} finally {\n\t\tawait file.close();\n\t}\n}\n\nexport function sliceText(text: string, options: TaskReadOptions = {}): OutputSlice {\n\tconst buffer = Buffer.from(text);\n\tconst { start, length, floor } = readWindow(buffer.length, options);\n\tconst slice = alignedSlice(buffer, start, start + length);\n\treturn outputSlice(\n\t\tbuffer.length,\n\t\tslice,\n\t\tslice.byteOffset - buffer.byteOffset,\n\t\toptions.mode !== \"head\" && start > floor,\n\t);\n}\n"]}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/core/tasks/output.ts"],"names":[],"mappings":"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","sourcesContent":["import { open } from \"node:fs/promises\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport { finiteLimit } from \"../../utils/number.ts\";\nimport type { TaskActivity, TaskDisplay, TaskFact, TaskInput, TaskRead, TaskReadOptions, TaskText } from \"./types.ts\";\n\nexport const TASK_RESULT_BYTES = 48 * 1024;\nexport const TASK_DETAILS_BYTES = 120 * 1024;\nexport const TASK_READ_BYTES = 8 * 1024;\nexport const TASK_INPUT_BYTES = 24 * 1024;\n/** Task title budget, independent of notification wording and rendering. */\nexport const TASK_TITLE_BYTES = 1024;\nexport const TASK_LABEL_BYTES = 256;\nexport const TASK_FACTS = 16;\nexport const TASK_FACT_BYTES = 1024;\nexport const TASK_ACTIVITIES = 50;\nexport const TASK_ERROR_BYTES = 4096;\nexport const TASK_PATH_BYTES = 8192;\n\n/** A bounded, printable message for any thrown value. */\nexport function errorText(error: unknown, fallback = \"Task execution failed (unprintable error)\"): string {\n\ttry {\n\t\treturn boundText(error instanceof Error ? error.message : String(error), TASK_ERROR_BYTES);\n\t} catch {\n\t\treturn fallback;\n\t}\n}\n\nexport function boundReadBytes(bytes: number | undefined): number {\n\treturn finiteLimit(bytes, TASK_READ_BYTES, TASK_RESULT_BYTES);\n}\n\n/** Both ends are codepoint aligned, including a head read ending inside a character. */\nfunction alignedSlice(buffer: Buffer, start: number, end: number): Buffer {\n\twhile (start < end && (buffer[start]! & 0xc0) === 0x80) start++;\n\tif (end < buffer.length) {\n\t\twhile (end > start && (buffer[end]! & 0xc0) === 0x80) end--;\n\t}\n\t// A concurrently written file can itself end in an incomplete UTF-8 sequence.\n\tlet lead = end - 1;\n\twhile (lead >= start && (buffer[lead]! & 0xc0) === 0x80) lead--;\n\tif (lead >= start) {\n\t\tconst byte = buffer[lead]!;\n\t\tconst width = byte >= 0xf0 ? 4 : byte >= 0xe0 ? 3 : byte >= 0xc0 ? 2 : 1;\n\t\tif (end - lead < width) end = lead;\n\t}\n\treturn buffer.subarray(start, end);\n}\n\nexport function boundText(text: string, bytes = TASK_RESULT_BYTES): string {\n\t// Avoid allocating a buffer proportional to an unbounded source.\n\tconst limit = finiteLimit(bytes, TASK_RESULT_BYTES, TASK_RESULT_BYTES);\n\tconst prefix = text.slice(0, limit + 1);\n\tconst buffer = Buffer.from(prefix);\n\treturn alignedSlice(buffer, 0, Math.min(limit, buffer.length)).toString(\"utf8\");\n}\n\nexport function boundTaskText(text: string, bytes = TASK_RESULT_BYTES): TaskText {\n\tconst bounded = boundText(text, bytes);\n\treturn { text: bounded, truncated: bounded !== text };\n}\n\nfunction activityTime(value: number | undefined): number | undefined {\n\treturn value !== undefined && Number.isFinite(value) && value >= 0 ? value : undefined;\n}\n\nfunction boundActivity(activity: TaskActivity): TaskActivity {\n\tconst target = activity.target === undefined ? undefined : boundText(activity.target, TASK_FACT_BYTES);\n\tconst error = activity.error === undefined ? undefined : boundText(activity.error, TASK_FACT_BYTES);\n\tconst startedAt = activityTime(activity.startedAt);\n\tconst durationMs = activityTime(activity.durationMs);\n\treturn {\n\t\tname: boundText(activity.name, TASK_LABEL_BYTES),\n\t\tstatus: activity.status,\n\t\t...(target === undefined ? {} : { target }),\n\t\t...(startedAt === undefined ? {} : { startedAt }),\n\t\t...(durationMs === undefined ? {} : { durationMs }),\n\t\t...(error === undefined ? {} : { error }),\n\t};\n}\n\n/** Keep live display structured data bounded and detached; its plain text remains the portable fallback. */\nexport function boundTaskDisplay(display: string | TaskDisplay): TaskDisplay {\n\tif (typeof display === \"string\") return boundTaskText(display);\n\tconst text = boundTaskText(display.text);\n\tconst activities = display.activities?.slice(-TASK_ACTIVITIES).map(boundActivity);\n\tconst omitted = display.activities ? display.activities.length - (activities?.length ?? 0) : 0;\n\tconst earlierActivities = finiteLimit((display.earlierActivities ?? 0) + omitted, 0, Number.MAX_SAFE_INTEGER);\n\treturn {\n\t\t...text,\n\t\ttruncated: display.truncated || text.truncated,\n\t\t...(activities ? { activities } : {}),\n\t\t...(display.earlierActivities !== undefined || omitted ? { earlierActivities } : {}),\n\t};\n}\n\nexport function boundInput(input: TaskInput): TaskInput {\n\tconst text = boundTaskText(input.text, TASK_INPUT_BYTES);\n\treturn {\n\t\tlabel: boundText(input.label, TASK_LABEL_BYTES),\n\t\ttext: text.text,\n\t\ttruncated: input.truncated || text.truncated,\n\t\t...(input.language ? { language: boundText(input.language, 64) } : {}),\n\t};\n}\n\nexport function boundFacts(facts: readonly TaskFact[]): TaskFact[] {\n\treturn facts\n\t\t.slice(0, TASK_FACTS)\n\t\t.map(([label, value]): TaskFact => [boundText(label, TASK_LABEL_BYTES), boundText(value, TASK_FACT_BYTES)]);\n}\n\n/** The end of a bounded text, codepoint aligned: a command's outcome is at its end. */\nexport function boundTail(text: string, bytes: number): { text: string; truncated: boolean } {\n\tconst buffer = Buffer.from(text);\n\tif (buffer.length <= bytes) return { text, truncated: false };\n\treturn { text: alignedSlice(buffer, buffer.length - bytes, buffer.length).toString(\"utf8\"), truncated: true };\n}\n\n/** The bounded model-readable text of a result; images and private details never enter task state. */\nexport function resultText(result: AgentToolResult<unknown>): TaskText {\n\tlet remaining = TASK_RESULT_BYTES;\n\tconst parts: string[] = [];\n\tlet truncated = false;\n\tfor (const block of result.content) {\n\t\tif (remaining <= 0) {\n\t\t\ttruncated = true;\n\t\t\tbreak;\n\t\t}\n\t\tconst source = block.type === \"text\" ? block.text : \"[Image omitted from task output]\";\n\t\tconst text = boundText(source, remaining);\n\t\tif (block.type !== \"text\" || text !== source) truncated = true;\n\t\tparts.push(text);\n\t\tremaining -= Math.max(1, Buffer.byteLength(text) + 1);\n\t}\n\treturn { text: boundText(parts.join(\"\\n\")), truncated };\n}\n\nexport interface OutputSlice {\n\ttext: string;\n\ttotalBytes: number;\n\ttruncated: boolean;\n\tfromByte: number;\n\t/** Raw source-byte end, independent of UTF-8 decoding or replacement characters. */\n\tendByte: number;\n}\n\n/** Raw source-byte range; decoding invalid UTF-8 must never move the continuation offset. */\nexport function taskReadRange(slice: Pick<TaskRead, \"text\" | \"fromByte\" | \"endByte\">): { from: number; to: number } {\n\tconst from = slice.fromByte ?? 0;\n\treturn { from, to: slice.endByte ?? from + Buffer.byteLength(slice.text) };\n}\n\nexport function taskReadBytes(slice: Pick<TaskRead, \"text\" | \"fromByte\" | \"endByte\">): number {\n\tconst { from, to } = taskReadRange(slice);\n\treturn to - from;\n}\n\n/**\n * The byte window a read covers in an output of `size` bytes. `floor` is the first byte the\n * caller has not seen yet. A head read continues forward from it; a tail read keeps the newest\n * unread window. Anything before the floor never counts as truncated.\n */\nfunction readWindow(size: number, options: TaskReadOptions): { start: number; length: number; floor: number } {\n\tconst bytes = boundReadBytes(options.bytes);\n\tconst since = finiteLimit(options.sinceBytes, 0, Number.MAX_SAFE_INTEGER);\n\tconst floor = since > size ? 0 : since;\n\tconst start =\n\t\toptions.mode === \"head\" ? (options.sinceBytes !== undefined ? floor : 0) : Math.max(floor, size - bytes);\n\treturn { start, length: Math.min(bytes, size - start), floor };\n}\n\nfunction outputSlice(size: number, slice: Buffer, fromByte: number, earlierTruncated: boolean): OutputSlice {\n\tconst endByte = fromByte + slice.byteLength;\n\treturn {\n\t\ttext: slice.toString(\"utf8\"),\n\t\ttotalBytes: size,\n\t\ttruncated: earlierTruncated || endByte < size,\n\t\tfromByte,\n\t\tendByte,\n\t};\n}\n\n/** Positioned, bounded reads only. The executor owns the path and its cleanup. */\nexport async function readOutputSlice(path: string, options: TaskReadOptions = {}): Promise<OutputSlice> {\n\tconst file = await open(path, \"r\");\n\ttry {\n\t\tconst { size } = await file.stat();\n\t\tconst { start, length, floor } = readWindow(size, options);\n\t\t// One extra byte lets alignment distinguish a complete last codepoint.\n\t\tconst buffer = Buffer.alloc(Math.min(length + 1, size - start));\n\t\tconst { bytesRead } = await file.read(buffer, 0, buffer.length, start);\n\t\tconst slice = alignedSlice(buffer.subarray(0, bytesRead), 0, Math.min(length, bytesRead));\n\t\treturn outputSlice(\n\t\t\tsize,\n\t\t\tslice,\n\t\t\tstart + slice.byteOffset - buffer.byteOffset,\n\t\t\toptions.mode !== \"head\" && start > floor,\n\t\t);\n\t} finally {\n\t\tawait file.close();\n\t}\n}\n\nexport function sliceText(text: string, options: TaskReadOptions = {}): OutputSlice {\n\tconst buffer = Buffer.from(text);\n\tconst { start, length, floor } = readWindow(buffer.length, options);\n\tconst slice = alignedSlice(buffer, start, start + length);\n\treturn outputSlice(\n\t\tbuffer.length,\n\t\tslice,\n\t\tslice.byteOffset - buffer.byteOffset,\n\t\toptions.mode !== \"head\" && start > floor,\n\t);\n}\n"]}
@@ -22,6 +22,23 @@ export interface TaskText {
22
22
  text: string;
23
23
  truncated: boolean;
24
24
  }
25
+ /** One live unit of work in a human display; UI derives its marker, elapsed time and layout. */
26
+ export interface TaskActivity {
27
+ name: string;
28
+ target?: string;
29
+ status: "running" | "ok" | "error" | "cancelled";
30
+ startedAt?: number;
31
+ durationMs?: number;
32
+ error?: string;
33
+ }
34
+ /**
35
+ * Human-only output with an optional structured live view. `text` remains the portable fallback;
36
+ * activities let an interactive renderer style and lay out the same content without executor UI callbacks.
37
+ */
38
+ export interface TaskDisplay extends TaskText {
39
+ activities?: TaskActivity[];
40
+ earlierActivities?: number;
41
+ }
25
42
  /** What the task was asked to do, such as a shell command or a delegated briefing. */
26
43
  export interface TaskInput extends TaskText {
27
44
  /** Human label for the input, such as "Command" or "Prompt". */
@@ -55,14 +72,14 @@ export interface TaskSnapshot {
55
72
  * model-facing reads always use `result`. A terminal snapshot has one only if the completion
56
73
  * supplied it: the last progress display does not survive settlement.
57
74
  */
58
- display?: TaskText;
75
+ display?: TaskDisplay;
59
76
  error?: string;
60
77
  }
61
78
  export interface TaskUpdate<T> {
62
79
  /** Model-readable progress; also forwarded to a foreground caller's onUpdate. */
63
80
  result: AgentToolResult<T>;
64
81
  /** The live human-only view while running; replaces the result in /tasks and ends at settlement. */
65
- display?: string;
82
+ display?: string | TaskDisplay;
66
83
  /** Cumulative usage so far, settled once if the execution ends without a final usage. */
67
84
  usage?: Usage;
68
85
  }