@pencil-agent/nano-pencil 2.0.0-beta.8 → 2.0.0-beta.9

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 (49) hide show
  1. package/dist/build-meta.json +3 -3
  2. package/dist/core/extensions-host/loader.js +1 -1
  3. package/dist/core/extensions-host/runner.d.ts +1 -0
  4. package/dist/core/extensions-host/runner.js +2 -2
  5. package/dist/core/extensions-host/types.d.ts +14 -16
  6. package/dist/core/lib/ai/src/types.d.ts +12 -2
  7. package/dist/core/persona/persona-manager.js +5 -2
  8. package/dist/core/runtime/agent-session.js +3 -3
  9. package/dist/core/runtime/extension-core-bindings.d.ts +1 -0
  10. package/dist/core/runtime/extension-core-bindings.js +2 -2
  11. package/dist/extensions/builtin/goal/goal-controller.d.ts +39 -10
  12. package/dist/extensions/builtin/goal/goal-controller.js +1 -1
  13. package/dist/extensions/builtin/goal/goal-format.js +1 -1
  14. package/dist/extensions/builtin/goal/goal-prompts.d.ts +2 -0
  15. package/dist/extensions/builtin/goal/goal-prompts.js +5 -4
  16. package/dist/extensions/builtin/goal/goal-store.js +1 -1
  17. package/dist/extensions/builtin/goal/index.d.ts +1 -1
  18. package/dist/extensions/builtin/goal/index.js +10 -7
  19. package/dist/extensions/builtin/link-world/index.js +6 -6
  20. package/dist/extensions/builtin/plan/index.js +1 -1
  21. package/dist/extensions/builtin/task/task-store.d.ts +4 -0
  22. package/dist/extensions/builtin/task/task-store.js +1 -1
  23. package/dist/modes/interactive/components/footer.js +1 -1
  24. package/dist/modes/interactive/components/task-status-panel.d.ts +36 -0
  25. package/dist/modes/interactive/components/task-status-panel.js +1 -0
  26. package/dist/modes/interactive/controllers/stream-render-controller.d.ts +7 -0
  27. package/dist/modes/interactive/controllers/stream-render-controller.js +2 -2
  28. package/dist/modes/interactive/interactive-mode.js +40 -40
  29. package/dist/modes/interactive/state/interactive-state.d.ts +2 -0
  30. package/dist/modes/interactive/state/interactive-state.js +1 -1
  31. package/dist/node_modules/@pencil-agent/ai/dist/models.generated.js +1 -1
  32. package/dist/node_modules/@pencil-agent/ai/dist/providers/anthropic.js +2 -2
  33. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-completions.js +5 -5
  34. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses.js +1 -1
  35. package/dist/node_modules/@pencil-agent/ai/dist/stream.js +1 -1
  36. package/dist/packages/protocol/src/commands.d.ts +33 -0
  37. package/dist/packages/{extension-sdk → protocol}/src/index.d.ts +5 -4
  38. package/dist/packages/protocol/src/index.js +1 -0
  39. package/dist/packages/{extension-sdk → protocol}/src/lifecycle.d.ts +12 -14
  40. package/dist/packages/{extension-sdk → protocol}/src/tools.d.ts +1 -1
  41. package/dist/packages/protocol/src/tools.js +0 -0
  42. package/docs/nanoPencil-/345/255/246/344/271/240/350/256/241/345/210/222.md +170 -0
  43. package/docs/scan-report.md +3820 -0
  44. package/docs//351/230/277/351/207/214/345/267/264/345/267/264/350/264/242/346/212/245/345/210/206/346/236/220/344/271/246.md +261 -0
  45. package/package.json +4 -4
  46. package/dist/packages/extension-sdk/src/index.js +0 -1
  47. /package/dist/extensions/builtin/link-world/{network-routing.md → network-routing/network-routing.md} +0 -0
  48. /package/dist/packages/{extension-sdk/src/lifecycle.js → protocol/src/commands.js} +0 -0
  49. /package/dist/packages/{extension-sdk/src/tools.js → protocol/src/lifecycle.js} +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "2.0.0-beta.8",
3
- "commitHash": "7b427f1",
2
+ "version": "2.0.0-beta.9",
3
+ "commitHash": "2617f4e",
4
4
  "branch": "main",
5
- "builtAt": "2026-06-11T18:43:07.597Z"
5
+ "builtAt": "2026-06-12T16:40:47.199Z"
6
6
  }
@@ -1 +1 @@
1
- var P=Object.defineProperty;var c=(n,t)=>P(n,"name",{value:t,configurable:!0});import*as d from"node:fs";import{createRequire as T}from"node:module";import*as y from"node:os";import*as l from"node:path";import{fileURLToPath as A}from"node:url";import{createJiti as M}from"@mariozechner/jiti";import*as w from"@pencil-agent/agent-core";import*as k from"@pencil-agent/ai";import*as L from"@pencil-agent/tui";import*as F from"@sinclair/typebox";import{CONFIG_DIR_NAME as C,getAgentDir as N,isBunBinary as _}from"../../config.js";import{createEventBus as I}from"../runtime/event-bus.js";import{execCommand as R}from"../platform/exec/exec.js";async function z(){return{"@sinclair/typebox":F,"@pencil-agent/agent-core":w,"@pencil-agent/tui":L,"@pencil-agent/ai":k,"@pencil-agent/nano-pencil":await import("../../index.js")}}c(z,"getVirtualModules");const m=T(import.meta.url);let h=null;function U(){if(h)return h;const n=l.dirname(A(import.meta.url)),t=l.resolve(n,"../..","index.js"),r=m.resolve("@sinclair/typebox").replace(/[\\/]build[\\/]cjs[\\/]index\.js$/,"");return h={"@pencil-agent/nano-pencil":t,"@pencil-agent/agent-core":m.resolve("@pencil-agent/agent-core"),"@pencil-agent/tui":m.resolve("@pencil-agent/tui"),"@pencil-agent/ai":m.resolve("@pencil-agent/ai"),"@sinclair/typebox":r},h}c(U,"getAliases");const D=/[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;function J(n){return n.replace(D," ")}c(J,"normalizeUnicodeSpaces");function V(n){const t=J(n);return t.startsWith("~/")?l.join(y.homedir(),t.slice(2)):t.startsWith("~")?l.join(y.homedir(),t.slice(1)):t}c(V,"expandPath");function v(n,t){const o=V(n);return l.isAbsolute(o)?o:l.resolve(t,o)}c(v,"resolvePath");function W(){const n=c(()=>{throw new Error("Extension runtime not initialized. Action methods cannot be called during extension loading.")},"notInitialized");return{sendMessage:n,sendUserMessage:n,executeCommand:c(()=>Promise.reject(new Error("Extension runtime not initialized")),"executeCommand"),isIdle:n,appendEntry:n,setSessionName:n,getSessionName:n,setLabel:n,getActiveTools:n,getAllTools:n,setActiveTools:n,getCommands:n,setModel:c(()=>Promise.reject(new Error("Extension runtime not initialized")),"setModel"),getThinkingLevel:n,setThinkingLevel:n,flagValues:new Map,pendingProviderRegistrations:[]}}c(W,"createExtensionRuntime");function E(n,t,o,r,i){return{cwd:o,agentDir:r,on(e,s){const u=n.handlers.get(e)??[];u.push(s),n.handlers.set(e,u)},registerTool(e){n.tools.set(e.name,{definition:e,extensionPath:n.path})},registerCommand(e,s){n.commands.set(e,{name:e,...s})},registerShortcut(e,s){n.shortcuts.set(e,{shortcut:e,extensionPath:n.path,...s})},registerFlag(e,s){n.flags.set(e,{name:e,extensionPath:n.path,...s}),s.default!==void 0&&!t.flagValues.has(e)&&t.flagValues.set(e,s.default)},registerMessageRenderer(e,s){n.messageRenderers.set(e,s)},getFlag(e){if(n.flags.has(e))return t.flagValues.get(e)},sendMessage(e,s){t.sendMessage(e,s)},sendUserMessage(e,s){t.sendUserMessage(e,s)},executeCommand(e){return t.executeCommand(e)},isIdle(){return t.isIdle()},appendEntry(e,s){t.appendEntry(e,s)},setSessionName(e){t.setSessionName(e)},getSessionName(){return t.getSessionName()},setLabel(e,s){t.setLabel(e,s)},exec(e,s,u){return R(e,s,u?.cwd??o,u)},getActiveTools(){return t.getActiveTools()},getAllTools(){return t.getAllTools()},setActiveTools(e){t.setActiveTools(e)},getCommands(){return t.getCommands()},setModel(e){return t.setModel(e)},getThinkingLevel(){return t.getThinkingLevel()},setThinkingLevel(e){t.setThinkingLevel(e)},registerProvider(e,s){t.pendingProviderRegistrations.push({name:e,config:s})},events:i}}c(E,"createExtensionAPI");async function B(n){const r=await M(import.meta.url,{moduleCache:!1,..._?{virtualModules:await z(),tryNative:!1}:{alias:U()}}).import(n,{default:!0});return typeof r!="function"?void 0:r}c(B,"loadExtensionModule");function S(n,t){return{path:n,resolvedPath:t,handlers:new Map,tools:new Map,messageRenderers:new Map,commands:new Map,flags:new Map,shortcuts:new Map}}c(S,"createExtension");async function O(n,t,o,r,i){const a=v(n,t);try{const e=await B(a);if(!e)return{extension:null,error:`Extension does not export a valid factory function: ${n}`};const s=S(n,a),u=E(s,i,t,o,r);return await e(u),{extension:s,error:null}}catch(e){return{extension:null,error:`Failed to load extension: ${e instanceof Error?e.message:String(e)}`}}}c(O,"loadExtension");async function ne(n,t,o,r,i,a="<inline>"){const e=S(a,a),s=E(e,i,t,o,r);return await n(s),e}c(ne,"loadExtensionFromFactory");async function $(n,t,o,r){const i=[],a=[],e=r??I(),s=W(),u=await Promise.all(n.map(f=>O(f,t,o,e,s).then(p=>({...p,path:f}))));for(const{extension:f,error:p,path:g}of u){if(p){a.push({path:g,error:p});continue}f&&i.push(f)}return{extensions:i,errors:a,runtime:s}}c($,"loadExtensions");function j(n){try{const t=d.readFileSync(n,"utf-8"),o=JSON.parse(t);return o.nanopencil&&typeof o.nanopencil=="object"?o.nanopencil:null}catch{return null}}c(j,"readPiManifest");function q(n){return n.endsWith(".ts")||n.endsWith(".js")}c(q,"isExtensionFile");function b(n){const t=l.join(n,"package.json");if(d.existsSync(t)){const i=j(t);if(i?.extensions?.length){const a=[];for(const e of i.extensions){const s=l.resolve(n,e);d.existsSync(s)&&a.push(s)}if(a.length>0)return a}}const o=l.join(n,"index.ts"),r=l.join(n,"index.js");return d.existsSync(o)?[o]:d.existsSync(r)?[r]:null}c(b,"resolveExtensionEntries");function x(n){if(!d.existsSync(n))return[];const t=[];try{const o=d.readdirSync(n,{withFileTypes:!0});for(const r of o){const i=l.join(n,r.name);if((r.isFile()||r.isSymbolicLink())&&q(r.name)){t.push(i);continue}if(r.isDirectory()||r.isSymbolicLink()){const a=b(i);a&&t.push(...a)}}}catch{return[]}return t}c(x,"discoverExtensionsInDir");function G(n){const t=[],o=c(i=>{const a=l.join(i,"package.json");if(!d.existsSync(a))return;const e=j(a);if(e?.extensions?.length)for(const s of e.extensions){const u=l.resolve(i,s);d.existsSync(u)&&t.push(u)}},"scanPackage"),r=c(i=>{if(!d.existsSync(i))return;let a;try{a=d.readdirSync(i,{withFileTypes:!0})}catch{return}for(const e of a)if(!(!e.isDirectory()&&!e.isSymbolicLink())&&!(e.name===".bin"||e.name===".cache")&&e.name!=="@pencil-agent"){if(e.name.startsWith("@")){const s=l.join(i,e.name);let u;try{u=d.readdirSync(s,{withFileTypes:!0})}catch{continue}for(const f of u)(f.isDirectory()||f.isSymbolicLink())&&o(l.join(s,f.name));continue}o(l.join(i,e.name))}},"scanNodeModules");for(const i of n)r(l.join(i,"node_modules"));return t}c(G,"discoverNpmExtensions");async function te(n,t,o=N(),r){const i=[],a=new Set,e=c(f=>{for(const p of f){const g=l.resolve(p);a.has(g)||(a.add(g),i.push(p))}},"addPaths"),s=l.join(t,C,"extensions");e(x(s));const u=l.join(o,"extensions");e(x(u));for(const f of n){const p=v(f,t);if(d.existsSync(p)&&d.statSync(p).isDirectory()){const g=b(p);if(g){e(g);continue}e(x(p));continue}e([p])}return e(G([t,o])),$(i,t,o,r)}c(te,"discoverAndLoadExtensions");export{W as createExtensionRuntime,te as discoverAndLoadExtensions,ne as loadExtensionFromFactory,$ as loadExtensions};
1
+ var b=Object.defineProperty;var c=(n,t)=>b(n,"name",{value:t,configurable:!0});import*as d from"node:fs";import{createRequire as j}from"node:module";import*as x from"node:os";import*as l from"node:path";import{fileURLToPath as T}from"node:url";import{createJiti as _}from"@mariozechner/jiti";import*as w from"@pencil-agent/agent-core";import*as M from"@pencil-agent/ai";import*as k from"@pencil-agent/ai/env";import*as F from"@pencil-agent/ai/events";import*as L from"@pencil-agent/ai/json";import*as N from"@pencil-agent/ai/models";import*as C from"@pencil-agent/ai/oauth";import*as U from"@pencil-agent/ai/overflow";import*as I from"@pencil-agent/ai/registry";import*as R from"@pencil-agent/ai/schema";import*as D from"@pencil-agent/ai/stream";import*as B from"@pencil-agent/ai/types";import*as O from"@pencil-agent/tui";import*as z from"@sinclair/typebox";import{CONFIG_DIR_NAME as J,getAgentDir as V,isBunBinary as W}from"../../config.js";import{createEventBus as $}from"../runtime/event-bus.js";import{execCommand as Q}from"../platform/exec/exec.js";const q=["types","schema","events","models","registry","stream","env","overflow","json","oauth"],H={"@pencil-agent/ai/types":B,"@pencil-agent/ai/schema":R,"@pencil-agent/ai/events":F,"@pencil-agent/ai/models":N,"@pencil-agent/ai/registry":I,"@pencil-agent/ai/stream":D,"@pencil-agent/ai/env":k,"@pencil-agent/ai/overflow":U,"@pencil-agent/ai/json":L,"@pencil-agent/ai/oauth":C};async function G(){return{"@sinclair/typebox":z,"@pencil-agent/agent-core":w,"@pencil-agent/tui":O,"@pencil-agent/ai":M,...H,"@pencil-agent/nano-pencil":await import("../../index.js")}}c(G,"getVirtualModules");const g=j(import.meta.url);let h=null;function K(){if(h)return h;const n=l.dirname(T(import.meta.url)),t=l.resolve(n,"../..","index.js"),a=g.resolve("@sinclair/typebox").replace(/[\\/]build[\\/]cjs[\\/]index\.js$/,""),i=Object.fromEntries(q.map(r=>[`@pencil-agent/ai/${r}`,g.resolve(`@pencil-agent/ai/${r}`)]));return h={"@pencil-agent/nano-pencil":t,"@pencil-agent/agent-core":g.resolve("@pencil-agent/agent-core"),"@pencil-agent/tui":g.resolve("@pencil-agent/tui"),...i,"@pencil-agent/ai":g.resolve("@pencil-agent/ai"),"@sinclair/typebox":a},h}c(K,"getAliases");const X=/[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;function Y(n){return n.replace(X," ")}c(Y,"normalizeUnicodeSpaces");function Z(n){const t=Y(n);return t.startsWith("~/")?l.join(x.homedir(),t.slice(2)):t.startsWith("~")?l.join(x.homedir(),t.slice(1)):t}c(Z,"expandPath");function v(n,t){const o=Z(n);return l.isAbsolute(o)?o:l.resolve(t,o)}c(v,"resolvePath");function ee(){const n=c(()=>{throw new Error("Extension runtime not initialized. Action methods cannot be called during extension loading.")},"notInitialized");return{sendMessage:n,sendUserMessage:n,executeCommand:c(()=>Promise.reject(new Error("Extension runtime not initialized")),"executeCommand"),isIdle:n,clearFollowUpQueue:n,appendEntry:n,setSessionName:n,getSessionName:n,setLabel:n,getActiveTools:n,getAllTools:n,setActiveTools:n,getCommands:n,setModel:c(()=>Promise.reject(new Error("Extension runtime not initialized")),"setModel"),getThinkingLevel:n,setThinkingLevel:n,flagValues:new Map,pendingProviderRegistrations:[]}}c(ee,"createExtensionRuntime");function E(n,t,o,a,i){return{cwd:o,agentDir:a,on(e,s){const u=n.handlers.get(e)??[];u.push(s),n.handlers.set(e,u)},registerTool(e){n.tools.set(e.name,{definition:e,extensionPath:n.path})},registerCommand(e,s){n.commands.set(e,{name:e,...s})},registerShortcut(e,s){n.shortcuts.set(e,{shortcut:e,extensionPath:n.path,...s})},registerFlag(e,s){n.flags.set(e,{name:e,extensionPath:n.path,...s}),s.default!==void 0&&!t.flagValues.has(e)&&t.flagValues.set(e,s.default)},registerMessageRenderer(e,s){n.messageRenderers.set(e,s)},getFlag(e){if(n.flags.has(e))return t.flagValues.get(e)},sendMessage(e,s){t.sendMessage(e,s)},sendUserMessage(e,s){t.sendUserMessage(e,s)},executeCommand(e){return t.executeCommand(e)},isIdle(){return t.isIdle()},clearFollowUpQueue(){t.clearFollowUpQueue()},appendEntry(e,s){t.appendEntry(e,s)},setSessionName(e){t.setSessionName(e)},getSessionName(){return t.getSessionName()},setLabel(e,s){t.setLabel(e,s)},exec(e,s,u){return Q(e,s,u?.cwd??o,u)},getActiveTools(){return t.getActiveTools()},getAllTools(){return t.getAllTools()},setActiveTools(e){t.setActiveTools(e)},getCommands(){return t.getCommands()},setModel(e){return t.setModel(e)},getThinkingLevel(){return t.getThinkingLevel()},setThinkingLevel(e){t.setThinkingLevel(e)},registerProvider(e,s){t.pendingProviderRegistrations.push({name:e,config:s})},events:i}}c(E,"createExtensionAPI");async function ne(n){const a=await _(import.meta.url,{moduleCache:!1,...W?{virtualModules:await G(),tryNative:!1}:{alias:K()}}).import(n,{default:!0});return typeof a!="function"?void 0:a}c(ne,"loadExtensionModule");function S(n,t){return{path:n,resolvedPath:t,handlers:new Map,tools:new Map,messageRenderers:new Map,commands:new Map,flags:new Map,shortcuts:new Map}}c(S,"createExtension");async function te(n,t,o,a,i){const r=v(n,t);try{const e=await ne(r);if(!e)return{extension:null,error:`Extension does not export a valid factory function: ${n}`};const s=S(n,r),u=E(s,i,t,o,a);return await e(u),{extension:s,error:null}}catch(e){return{extension:null,error:`Failed to load extension: ${e instanceof Error?e.message:String(e)}`}}}c(te,"loadExtension");async function fe(n,t,o,a,i,r="<inline>"){const e=S(r,r),s=E(e,i,t,o,a);return await n(s),e}c(fe,"loadExtensionFromFactory");async function se(n,t,o,a){const i=[],r=[],e=a??$(),s=ee(),u=await Promise.all(n.map(p=>te(p,t,o,e,s).then(f=>({...f,path:p}))));for(const{extension:p,error:f,path:m}of u){if(f){r.push({path:m,error:f});continue}p&&i.push(p)}return{extensions:i,errors:r,runtime:s}}c(se,"loadExtensions");function A(n){try{const t=d.readFileSync(n,"utf-8"),o=JSON.parse(t);return o.nanopencil&&typeof o.nanopencil=="object"?o.nanopencil:null}catch{return null}}c(A,"readPiManifest");function oe(n){return n.endsWith(".ts")||n.endsWith(".js")}c(oe,"isExtensionFile");function P(n){const t=l.join(n,"package.json");if(d.existsSync(t)){const i=A(t);if(i?.extensions?.length){const r=[];for(const e of i.extensions){const s=l.resolve(n,e);d.existsSync(s)&&r.push(s)}if(r.length>0)return r}}const o=l.join(n,"index.ts"),a=l.join(n,"index.js");return d.existsSync(o)?[o]:d.existsSync(a)?[a]:null}c(P,"resolveExtensionEntries");function y(n){if(!d.existsSync(n))return[];const t=[];try{const o=d.readdirSync(n,{withFileTypes:!0});for(const a of o){const i=l.join(n,a.name);if((a.isFile()||a.isSymbolicLink())&&oe(a.name)){t.push(i);continue}if(a.isDirectory()||a.isSymbolicLink()){const r=P(i);r&&t.push(...r)}}}catch{return[]}return t}c(y,"discoverExtensionsInDir");function ie(n){const t=[],o=c(i=>{const r=l.join(i,"package.json");if(!d.existsSync(r))return;const e=A(r);if(e?.extensions?.length)for(const s of e.extensions){const u=l.resolve(i,s);d.existsSync(u)&&t.push(u)}},"scanPackage"),a=c(i=>{if(!d.existsSync(i))return;let r;try{r=d.readdirSync(i,{withFileTypes:!0})}catch{return}for(const e of r)if(!(!e.isDirectory()&&!e.isSymbolicLink())&&!(e.name===".bin"||e.name===".cache")&&e.name!=="@pencil-agent"){if(e.name.startsWith("@")){const s=l.join(i,e.name);let u;try{u=d.readdirSync(s,{withFileTypes:!0})}catch{continue}for(const p of u)(p.isDirectory()||p.isSymbolicLink())&&o(l.join(s,p.name));continue}o(l.join(i,e.name))}},"scanNodeModules");for(const i of n)a(l.join(i,"node_modules"));return t}c(ie,"discoverNpmExtensions");async function me(n,t,o=V(),a){const i=[],r=new Set,e=c(p=>{for(const f of p){const m=l.resolve(f);r.has(m)||(r.add(m),i.push(f))}},"addPaths"),s=l.join(t,J,"extensions");e(y(s));const u=l.join(o,"extensions");e(y(u));for(const p of n){const f=v(p,t);if(d.existsSync(f)&&d.statSync(f).isDirectory()){const m=P(f);if(m){e(m);continue}e(y(f));continue}e([f])}return e(ie([t,o])),se(i,t,o,a)}c(me,"discoverAndLoadExtensions");export{ee as createExtensionRuntime,me as discoverAndLoadExtensions,fe as loadExtensionFromFactory,se as loadExtensions};
@@ -76,6 +76,7 @@ export declare class ExtensionRunner {
76
76
  private isIdleFn;
77
77
  private waitForIdleFn;
78
78
  private abortFn;
79
+ private clearFollowUpQueueFn;
79
80
  private hasPendingMessagesFn;
80
81
  private getContextUsageFn;
81
82
  private compactFn;
@@ -1,3 +1,3 @@
1
- var k=Object.defineProperty;var s=(f,e)=>k(f,"name",{value:e,configurable:!0});import{theme as E}from"../../modes/interactive/theme/theme.js";import{classifyArgsSignature as v,HOOK_SAMPLE_RATES as C,runWithExtCallerContext as x}from"../platform/telemetry/index.js";const T=["interrupt","clear","exit","suspend","cycleThinkingLevel","cycleModelForward","cycleModelBackward","selectModel","selectProviderThenModel","expandTools","toggleThinking","externalEditor","followUp","submit","selectConfirm","selectCancel","copy","deleteToLineEnd"],P=s(f=>{const e={};for(const[n,t]of Object.entries(f)){const o=n,i=Array.isArray(t)?t:[t],a=T.includes(o);for(const r of i){const c=r.toLowerCase();e[c]={action:o,restrictOverride:a}}}return e},"buildBuiltinKeybindings");async function _(f){return f?.hasHandlers("session_shutdown")?(await f.emit({type:"session_shutdown"}),!0):!1}s(_,"emitSessionShutdownEvent");const p={select:s(async()=>{},"select"),confirm:s(async()=>!1,"confirm"),input:s(async()=>{},"input"),notify:s(()=>{},"notify"),onTerminalInput:s(()=>()=>{},"onTerminalInput"),setStatus:s(()=>{},"setStatus"),setWorkingMessage:s(()=>{},"setWorkingMessage"),setWidget:s(()=>{},"setWidget"),setFooter:s(()=>{},"setFooter"),setHeader:s(()=>{},"setHeader"),setTitle:s(()=>{},"setTitle"),custom:s(async()=>{},"custom"),pasteToEditor:s(()=>{},"pasteToEditor"),setEditorText:s(()=>{},"setEditorText"),getEditorText:s(()=>"","getEditorText"),editor:s(async()=>{},"editor"),openExternalEditor:s(async()=>!1,"openExternalEditor"),setEditorComponent:s(()=>{},"setEditorComponent"),get theme(){return E},getAllThemes:s(()=>[],"getAllThemes"),getTheme:s(()=>{},"getTheme"),setTheme:s(f=>({success:!1,error:"UI not available"}),"setTheme"),getToolsExpanded:s(()=>!1,"getToolsExpanded"),setToolsExpanded:s(()=>{},"setToolsExpanded")};class H{static{s(this,"ExtensionRunner")}extensions;runtime;uiContext;cwd;agentDir;sessionManager;modelRegistry;errorListeners=new Set;getModel=s(()=>{},"getModel");completeSimpleFn=s(async()=>{},"completeSimpleFn");completeSimpleWithUsageFn=s(async()=>{},"completeSimpleWithUsageFn");completeJsonFn;isIdleFn=s(()=>!0,"isIdleFn");waitForIdleFn=s(async()=>{},"waitForIdleFn");abortFn=s(()=>{},"abortFn");hasPendingMessagesFn=s(()=>!1,"hasPendingMessagesFn");getContextUsageFn=s(()=>{},"getContextUsageFn");compactFn=s(()=>{},"compactFn");getSystemPromptFn=s(()=>"","getSystemPromptFn");getSoulManagerFn=s(()=>{},"getSoulManagerFn");getSettingsFn=s(()=>({}),"getSettingsFn");getSkillsFn=s(()=>[],"getSkillsFn");newSessionHandler=s(async()=>({cancelled:!1}),"newSessionHandler");forkHandler=s(async()=>({cancelled:!1}),"forkHandler");navigateTreeHandler=s(async()=>({cancelled:!1}),"navigateTreeHandler");switchSessionHandler=s(async()=>({cancelled:!1}),"switchSessionHandler");reloadHandler=s(async()=>{},"reloadHandler");shutdownHandler=s(()=>{},"shutdownHandler");shortcutDiagnostics=[];commandDiagnostics=[];telemetrySink;_beforeAgentStartTimeoutMs=1500;get beforeAgentStartTimeoutMs(){return this._beforeAgentStartTimeoutMs??1500}beforeAgentStartTimeoutSentinel=Symbol("before_agent_start_timeout");beforeAgentStartTimeoutLastReported=new Map;constructor(e,n,t,o,i,a){this.extensions=e,this.runtime=n,this.uiContext=p,this.cwd=t,this.agentDir=o,this.sessionManager=i,this.modelRegistry=a}async withTimeout(e,n){return new Promise(t=>{const o=setTimeout(()=>t(this.beforeAgentStartTimeoutSentinel),n);Promise.resolve(e).then(i=>{clearTimeout(o),t(i)}).catch(()=>{clearTimeout(o),t(this.beforeAgentStartTimeoutSentinel)})})}reportBeforeAgentStartTimeout(e){const n=Date.now(),t=this.beforeAgentStartTimeoutLastReported.get(e)??0;n-t<6e4||(this.beforeAgentStartTimeoutLastReported.set(e,n),console.warn(`Extension before_agent_start timed out (${this.beforeAgentStartTimeoutMs}ms): ${e}`))}bindCore(e,n){this.runtime.sendMessage=e.sendMessage,this.runtime.sendUserMessage=e.sendUserMessage,this.runtime.executeCommand=e.executeCommand,this.runtime.appendEntry=e.appendEntry,this.runtime.setSessionName=e.setSessionName,this.runtime.getSessionName=e.getSessionName,this.runtime.setLabel=e.setLabel,this.runtime.getActiveTools=e.getActiveTools,this.runtime.getAllTools=e.getAllTools,this.runtime.setActiveTools=e.setActiveTools,this.runtime.getCommands=e.getCommands,this.runtime.setModel=e.setModel,this.runtime.getThinkingLevel=e.getThinkingLevel,this.runtime.setThinkingLevel=e.setThinkingLevel,this.getModel=n.getModel,this.completeSimpleFn=n.completeSimple,this.completeSimpleWithUsageFn=n.completeSimpleWithUsage,this.completeJsonFn=n.completeJson,this.isIdleFn=n.isIdle,this.runtime.isIdle=()=>this.isIdleFn(),this.abortFn=n.abort,this.hasPendingMessagesFn=n.hasPendingMessages,this.shutdownHandler=n.shutdown,this.getContextUsageFn=n.getContextUsage,this.compactFn=n.compact,this.getSystemPromptFn=n.getSystemPrompt,this.getSoulManagerFn=n.getSoulManager,this.getSettingsFn=n.getSettings,this.getSkillsFn=n.getSkills;for(const{name:t,config:o}of this.runtime.pendingProviderRegistrations)this.modelRegistry.registerProvider(t,o);this.runtime.pendingProviderRegistrations=[]}bindCommandContext(e){if(e){this.waitForIdleFn=e.waitForIdle,this.newSessionHandler=e.newSession,this.forkHandler=e.fork,this.navigateTreeHandler=e.navigateTree,this.switchSessionHandler=e.switchSession,this.reloadHandler=e.reload;return}this.waitForIdleFn=async()=>{},this.newSessionHandler=async()=>({cancelled:!1}),this.forkHandler=async()=>({cancelled:!1}),this.navigateTreeHandler=async()=>({cancelled:!1}),this.switchSessionHandler=async()=>({cancelled:!1}),this.reloadHandler=async()=>{}}setUIContext(e){this.uiContext=e??p}getUIContext(){return this.uiContext}hasUI(){return this.uiContext===p?!1:this.uiContext.__nonInteractive!==!0}getExtensionPaths(){return this.extensions.map(e=>e.path)}getAllRegisteredTools(){const e=new Map;for(const n of this.extensions)for(const t of n.tools.values())e.has(t.definition.name)||e.set(t.definition.name,t);return Array.from(e.values())}getToolDefinition(e){for(const n of this.extensions){const t=n.tools.get(e);if(t)return t.definition}}getFlags(){const e=new Map;for(const n of this.extensions)for(const[t,o]of n.flags)e.has(t)||e.set(t,o);return e}setFlagValue(e,n){this.runtime.flagValues.set(e,n)}getFlagValues(){return new Map(this.runtime.flagValues)}getShortcuts(e){this.shortcutDiagnostics=[];const n=P(e),t=new Map,o=s((i,a)=>{this.shortcutDiagnostics.push({type:"warning",message:i,path:a}),this.hasUI()||console.warn(i)},"addDiagnostic");for(const i of this.extensions)for(const[a,r]of i.shortcuts){const c=a.toLowerCase(),l=n[c];if(l?.restrictOverride===!0){o(`Extension shortcut '${a}' from ${r.extensionPath} conflicts with built-in shortcut. Skipping.`,r.extensionPath);continue}l?.restrictOverride===!1&&o(`Extension shortcut conflict: '${a}' is built-in shortcut for ${l.action} and ${r.extensionPath}. Using ${r.extensionPath}.`,r.extensionPath);const h=t.get(c);h&&o(`Extension shortcut conflict: '${a}' registered by both ${h.extensionPath} and ${r.extensionPath}. Using ${r.extensionPath}.`,r.extensionPath),t.set(c,r)}return t}getShortcutDiagnostics(){return this.shortcutDiagnostics}onError(e){return this.errorListeners.add(e),()=>this.errorListeners.delete(e)}emitError(e){for(const n of this.errorListeners)n(e)}setBeforeAgentStartTimeout(e){this._beforeAgentStartTimeoutMs=e}dispose(){this.errorListeners.clear(),this.beforeAgentStartTimeoutLastReported.clear(),this.shortcutDiagnostics=[],this.commandDiagnostics=[];for(const e of this.extensions)e.handlers.clear()}hasHandlers(e){for(const n of this.extensions){const t=n.handlers.get(e);if(t&&t.length>0)return!0}return!1}getMessageRenderer(e){for(const n of this.extensions){const t=n.messageRenderers.get(e);if(t)return t}}getRegisteredCommands(e){this.commandDiagnostics=[];const n=[],t=new Map;for(const o of this.extensions)for(const i of o.commands.values()){if(e?.has(i.name)){const r=`Extension command '${i.name}' from ${o.path} conflicts with built-in commands. Skipping.`;this.commandDiagnostics.push({type:"warning",message:r,path:o.path}),this.hasUI()||console.warn(r);continue}const a=t.get(i.name);if(a){const r=`Extension command '${i.name}' from ${o.path} conflicts with ${a}. Skipping.`;this.commandDiagnostics.push({type:"warning",message:r,path:o.path}),this.hasUI()||console.warn(r);continue}t.set(i.name,o.path),n.push(i)}return n}getCommandDiagnostics(){return this.commandDiagnostics}getRegisteredCommandsWithPaths(){const e=[];for(const n of this.extensions)for(const t of n.commands.values())e.push({command:t,extensionPath:n.path});return e}getCommand(e){for(const n of this.extensions){const t=n.commands.get(e);if(t)return t}}findCommandOwner(e){for(const n of this.extensions)if(n.commands.has(e))return n}deriveExtensionName(e){const t=(e.path||e.resolvedPath||"").replace(/\/+$/,"").split(/[\\/]/);return t[t.length-1]||"unknown"}setTelemetrySink(e){this.telemetrySink=e}writeLlmCallEvent(e){try{this.telemetrySink?.writeLlmCallEvent(e)}catch{}}invokeHookHandler(e,n,t){const o=this.deriveExtensionName(e),i={extensionName:o,callerContext:`hook:${n}`,isUserInitiated:!1};return x(i,async()=>{const a=C[n]??1;if(a<1&&Math.random()>=a)return await t();const r=new Date,c=performance.now();let l=!0,h=null;try{return await t()}catch(u){throw l=!1,h=u instanceof Error?u.constructor.name:"unknown",u}finally{try{this.telemetrySink?.writeHookEvent({extensionName:o,hookName:n,durationMs:Math.round(performance.now()-c),ok:l,errorCode:h,sampleRate:a,recordedAt:r})}catch{}}})}async invokeCommand(e,n,t,o){const i=this.getCommand(e);if(!i)return{found:!1};const a=this.findCommandOwner(e),r=a?this.deriveExtensionName(a):"unknown",c=new Date,l=performance.now();let h="ok",u=null,m;const d=v(n),y={extensionName:r,callerContext:d==="no-args"?`command:/${e}`:`command:/${e} ${d}`,isUserInitiated:!0,sessionId:o?.sessionId??null,runId:o?.runId??null,variant:o?.variant??null};try{await x(y,()=>i.handler(n,t))}catch(g){h="error",u=g instanceof Error?g.constructor.name:"unknown",m=g,this.emitError({extensionPath:`command:${e}`,event:"command",error:g instanceof Error?g.message:String(g)})}const S=Math.round(performance.now()-l),w=new Date;try{this.telemetrySink?.writeCommandEvent({extensionName:r,commandName:e,argsSignature:d,argsLength:n.length,outcome:h,errorCode:u,durationMs:S,startedAt:c,endedAt:w,sessionId:o?.sessionId??null,runId:o?.runId??null,variant:o?.variant??null})}catch{}return{found:!0}}shutdown(){this.shutdownHandler()}createContext(){const e=this.getModel;return{ui:this.uiContext,hasUI:this.hasUI(),cwd:this.cwd,agentDir:this.agentDir,sessionManager:this.sessionManager,modelRegistry:this.modelRegistry,get model(){return e()},completeSimple:s((n,t)=>this.completeSimpleFn(n,t),"completeSimple"),completeSimpleWithUsage:s((n,t)=>this.completeSimpleWithUsageFn(n,t),"completeSimpleWithUsage"),completeJson:this.completeJsonFn?(n,t,o,i)=>this.completeJsonFn(n,t,o,i):void 0,isIdle:s(()=>this.isIdleFn(),"isIdle"),abort:s(()=>this.abortFn(),"abort"),hasPendingMessages:s(()=>this.hasPendingMessagesFn(),"hasPendingMessages"),shutdown:s(()=>this.shutdownHandler(),"shutdown"),getContextUsage:s(()=>this.getContextUsageFn(),"getContextUsage"),compact:s(n=>this.compactFn(n),"compact"),getSystemPrompt:s(()=>this.getSystemPromptFn(),"getSystemPrompt"),getSoulManager:s(()=>this.getSoulManagerFn(),"getSoulManager"),getSettings:s(()=>this.getSettingsFn(),"getSettings"),getSkills:s(()=>this.getSkillsFn(),"getSkills")}}createCommandContext(){return{...this.createContext(),waitForIdle:s(()=>this.waitForIdleFn(),"waitForIdle"),newSession:s(e=>this.newSessionHandler(e),"newSession"),fork:s(e=>this.forkHandler(e),"fork"),navigateTree:s((e,n)=>this.navigateTreeHandler(e,n),"navigateTree"),switchSession:s(e=>this.switchSessionHandler(e),"switchSession"),reload:s(()=>this.reloadHandler(),"reload")}}isSessionBeforeEvent(e){return e.type==="session_before_switch"||e.type==="session_before_fork"||e.type==="session_before_compact"||e.type==="session_before_tree"}async emit(e){const n=this.createContext();let t;for(const o of this.extensions){const i=o.handlers.get(e.type);if(!(!i||i.length===0))for(const a of i)try{const r=await this.invokeHookHandler(o,e.type,()=>a(e,n));if(this.isSessionBeforeEvent(e)&&r&&(t=r,t.cancel))return t}catch(r){const c=r instanceof Error?r.message:String(r),l=r instanceof Error?r.stack:void 0;this.emitError({extensionPath:o.path,event:e.type,error:c,stack:l})}}return t}async emitToolResult(e){const n=this.createContext(),t={...e};let o=!1;for(const i of this.extensions){const a=i.handlers.get("tool_result");if(!(!a||a.length===0))for(const r of a)try{const c=await this.invokeHookHandler(i,"tool_result",()=>r(t,n));if(!c)continue;c.content!==void 0&&(t.content=c.content,o=!0),c.details!==void 0&&(t.details=c.details,o=!0),c.isError!==void 0&&(t.isError=c.isError,o=!0)}catch(c){const l=c instanceof Error?c.message:String(c),h=c instanceof Error?c.stack:void 0;this.emitError({extensionPath:i.path,event:"tool_result",error:l,stack:h})}}if(o)return{content:t.content,details:t.details,isError:t.isError}}async emitToolCall(e){const n=this.createContext();let t;for(const o of this.extensions){const i=o.handlers.get("tool_call");if(!(!i||i.length===0))for(const a of i){const r=await this.invokeHookHandler(o,"tool_call",()=>a(e,n));if(r&&(t=r,t.block))return t}}return t}async emitUserBash(e){const n=this.createContext();for(const t of this.extensions){const o=t.handlers.get("user_bash");if(!(!o||o.length===0))for(const i of o)try{const a=await this.invokeHookHandler(t,"user_bash",()=>i(e,n));if(a)return a}catch(a){const r=a instanceof Error?a.message:String(a),c=a instanceof Error?a.stack:void 0;this.emitError({extensionPath:t.path,event:"user_bash",error:r,stack:c})}}}async emitContext(e){const n=this.createContext();let t=structuredClone(e);for(const o of this.extensions){const i=o.handlers.get("context");if(!(!i||i.length===0))for(const a of i)try{const r={type:"context",messages:t},c=await this.invokeHookHandler(o,"context",()=>a(r,n));c&&c.messages&&(t=c.messages)}catch(r){const c=r instanceof Error?r.message:String(r),l=r instanceof Error?r.stack:void 0;this.emitError({extensionPath:o.path,event:"context",error:c,stack:l})}}return t}async emitBeforeAgentStart(e,n,t){const o=this.createContext(),i=[];let a=t,r=!1;for(const c of this.extensions){const l=c.handlers.get("before_agent_start");if(!(!l||l.length===0))for(const h of l)try{const u={type:"before_agent_start",prompt:e,images:n,systemPrompt:a},m=await this.withTimeout(this.invokeHookHandler(c,"before_agent_start",()=>h(u,o)),this.beforeAgentStartTimeoutMs);if(m===this.beforeAgentStartTimeoutSentinel){this.reportBeforeAgentStartTimeout(c.path);continue}if(m){const d=m;d.message&&i.push(d.message),d.systemPrompt!==void 0&&(a=d.systemPrompt,r=!0),d.appendSystemPrompt!==void 0&&(a=this.appendSystemPrompt(a,d.appendSystemPrompt),r=!0)}}catch(u){const m=u instanceof Error?u.message:String(u),d=u instanceof Error?u.stack:void 0;this.emitError({extensionPath:c.path,event:"before_agent_start",error:m,stack:d})}}if(i.length>0||r)return{messages:i.length>0?i:void 0,systemPrompt:r?a:void 0}}appendSystemPrompt(e,n){const t=n.trim();return t?`${e}
1
+ var k=Object.defineProperty;var s=(f,e)=>k(f,"name",{value:e,configurable:!0});import{theme as E}from"../../modes/interactive/theme/theme.js";import{classifyArgsSignature as F,HOOK_SAMPLE_RATES as v,runWithExtCallerContext as x}from"../platform/telemetry/index.js";const C=["interrupt","clear","exit","suspend","cycleThinkingLevel","cycleModelForward","cycleModelBackward","selectModel","selectProviderThenModel","expandTools","toggleThinking","externalEditor","followUp","submit","selectConfirm","selectCancel","copy","deleteToLineEnd"],T=s(f=>{const e={};for(const[n,t]of Object.entries(f)){const o=n,i=Array.isArray(t)?t:[t],a=C.includes(o);for(const r of i){const l=r.toLowerCase();e[l]={action:o,restrictOverride:a}}}return e},"buildBuiltinKeybindings");async function _(f){return f?.hasHandlers("session_shutdown")?(await f.emit({type:"session_shutdown"}),!0):!1}s(_,"emitSessionShutdownEvent");const p={select:s(async()=>{},"select"),confirm:s(async()=>!1,"confirm"),input:s(async()=>{},"input"),notify:s(()=>{},"notify"),onTerminalInput:s(()=>()=>{},"onTerminalInput"),setStatus:s(()=>{},"setStatus"),setWorkingMessage:s(()=>{},"setWorkingMessage"),setWidget:s(()=>{},"setWidget"),setFooter:s(()=>{},"setFooter"),setHeader:s(()=>{},"setHeader"),setTitle:s(()=>{},"setTitle"),custom:s(async()=>{},"custom"),pasteToEditor:s(()=>{},"pasteToEditor"),setEditorText:s(()=>{},"setEditorText"),getEditorText:s(()=>"","getEditorText"),editor:s(async()=>{},"editor"),openExternalEditor:s(async()=>!1,"openExternalEditor"),setEditorComponent:s(()=>{},"setEditorComponent"),get theme(){return E},getAllThemes:s(()=>[],"getAllThemes"),getTheme:s(()=>{},"getTheme"),setTheme:s(f=>({success:!1,error:"UI not available"}),"setTheme"),getToolsExpanded:s(()=>!1,"getToolsExpanded"),setToolsExpanded:s(()=>{},"setToolsExpanded")};class H{static{s(this,"ExtensionRunner")}extensions;runtime;uiContext;cwd;agentDir;sessionManager;modelRegistry;errorListeners=new Set;getModel=s(()=>{},"getModel");completeSimpleFn=s(async()=>{},"completeSimpleFn");completeSimpleWithUsageFn=s(async()=>{},"completeSimpleWithUsageFn");completeJsonFn;isIdleFn=s(()=>!0,"isIdleFn");waitForIdleFn=s(async()=>{},"waitForIdleFn");abortFn=s(()=>{},"abortFn");clearFollowUpQueueFn=s(()=>{},"clearFollowUpQueueFn");hasPendingMessagesFn=s(()=>!1,"hasPendingMessagesFn");getContextUsageFn=s(()=>{},"getContextUsageFn");compactFn=s(()=>{},"compactFn");getSystemPromptFn=s(()=>"","getSystemPromptFn");getSoulManagerFn=s(()=>{},"getSoulManagerFn");getSettingsFn=s(()=>({}),"getSettingsFn");getSkillsFn=s(()=>[],"getSkillsFn");newSessionHandler=s(async()=>({cancelled:!1}),"newSessionHandler");forkHandler=s(async()=>({cancelled:!1}),"forkHandler");navigateTreeHandler=s(async()=>({cancelled:!1}),"navigateTreeHandler");switchSessionHandler=s(async()=>({cancelled:!1}),"switchSessionHandler");reloadHandler=s(async()=>{},"reloadHandler");shutdownHandler=s(()=>{},"shutdownHandler");shortcutDiagnostics=[];commandDiagnostics=[];telemetrySink;_beforeAgentStartTimeoutMs=1500;get beforeAgentStartTimeoutMs(){return this._beforeAgentStartTimeoutMs??1500}beforeAgentStartTimeoutSentinel=Symbol("before_agent_start_timeout");beforeAgentStartTimeoutLastReported=new Map;constructor(e,n,t,o,i,a){this.extensions=e,this.runtime=n,this.uiContext=p,this.cwd=t,this.agentDir=o,this.sessionManager=i,this.modelRegistry=a}async withTimeout(e,n){return new Promise(t=>{const o=setTimeout(()=>t(this.beforeAgentStartTimeoutSentinel),n);Promise.resolve(e).then(i=>{clearTimeout(o),t(i)}).catch(()=>{clearTimeout(o),t(this.beforeAgentStartTimeoutSentinel)})})}reportBeforeAgentStartTimeout(e){const n=Date.now(),t=this.beforeAgentStartTimeoutLastReported.get(e)??0;n-t<6e4||(this.beforeAgentStartTimeoutLastReported.set(e,n),console.warn(`Extension before_agent_start timed out (${this.beforeAgentStartTimeoutMs}ms): ${e}`))}bindCore(e,n){this.runtime.sendMessage=e.sendMessage,this.runtime.sendUserMessage=e.sendUserMessage,this.runtime.executeCommand=e.executeCommand,this.runtime.appendEntry=e.appendEntry,this.runtime.setSessionName=e.setSessionName,this.runtime.getSessionName=e.getSessionName,this.runtime.setLabel=e.setLabel,this.runtime.getActiveTools=e.getActiveTools,this.runtime.getAllTools=e.getAllTools,this.runtime.setActiveTools=e.setActiveTools,this.runtime.getCommands=e.getCommands,this.runtime.setModel=e.setModel,this.runtime.getThinkingLevel=e.getThinkingLevel,this.runtime.setThinkingLevel=e.setThinkingLevel,this.getModel=n.getModel,this.completeSimpleFn=n.completeSimple,this.completeSimpleWithUsageFn=n.completeSimpleWithUsage,this.completeJsonFn=n.completeJson,this.isIdleFn=n.isIdle,this.runtime.isIdle=()=>this.isIdleFn(),this.abortFn=n.abort,this.clearFollowUpQueueFn=n.clearFollowUpQueue,this.runtime.clearFollowUpQueue=()=>this.clearFollowUpQueueFn(),this.hasPendingMessagesFn=n.hasPendingMessages,this.shutdownHandler=n.shutdown,this.getContextUsageFn=n.getContextUsage,this.compactFn=n.compact,this.getSystemPromptFn=n.getSystemPrompt,this.getSoulManagerFn=n.getSoulManager,this.getSettingsFn=n.getSettings,this.getSkillsFn=n.getSkills;for(const{name:t,config:o}of this.runtime.pendingProviderRegistrations)this.modelRegistry.registerProvider(t,o);this.runtime.pendingProviderRegistrations=[]}bindCommandContext(e){if(e){this.waitForIdleFn=e.waitForIdle,this.newSessionHandler=e.newSession,this.forkHandler=e.fork,this.navigateTreeHandler=e.navigateTree,this.switchSessionHandler=e.switchSession,this.reloadHandler=e.reload;return}this.waitForIdleFn=async()=>{},this.newSessionHandler=async()=>({cancelled:!1}),this.forkHandler=async()=>({cancelled:!1}),this.navigateTreeHandler=async()=>({cancelled:!1}),this.switchSessionHandler=async()=>({cancelled:!1}),this.reloadHandler=async()=>{}}setUIContext(e){this.uiContext=e??p}getUIContext(){return this.uiContext}hasUI(){return this.uiContext===p?!1:this.uiContext.__nonInteractive!==!0}getExtensionPaths(){return this.extensions.map(e=>e.path)}getAllRegisteredTools(){const e=new Map;for(const n of this.extensions)for(const t of n.tools.values())e.has(t.definition.name)||e.set(t.definition.name,t);return Array.from(e.values())}getToolDefinition(e){for(const n of this.extensions){const t=n.tools.get(e);if(t)return t.definition}}getFlags(){const e=new Map;for(const n of this.extensions)for(const[t,o]of n.flags)e.has(t)||e.set(t,o);return e}setFlagValue(e,n){this.runtime.flagValues.set(e,n)}getFlagValues(){return new Map(this.runtime.flagValues)}getShortcuts(e){this.shortcutDiagnostics=[];const n=T(e),t=new Map,o=s((i,a)=>{this.shortcutDiagnostics.push({type:"warning",message:i,path:a}),this.hasUI()||console.warn(i)},"addDiagnostic");for(const i of this.extensions)for(const[a,r]of i.shortcuts){const l=a.toLowerCase(),c=n[l];if(c?.restrictOverride===!0){o(`Extension shortcut '${a}' from ${r.extensionPath} conflicts with built-in shortcut. Skipping.`,r.extensionPath);continue}c?.restrictOverride===!1&&o(`Extension shortcut conflict: '${a}' is built-in shortcut for ${c.action} and ${r.extensionPath}. Using ${r.extensionPath}.`,r.extensionPath);const h=t.get(l);h&&o(`Extension shortcut conflict: '${a}' registered by both ${h.extensionPath} and ${r.extensionPath}. Using ${r.extensionPath}.`,r.extensionPath),t.set(l,r)}return t}getShortcutDiagnostics(){return this.shortcutDiagnostics}onError(e){return this.errorListeners.add(e),()=>this.errorListeners.delete(e)}emitError(e){for(const n of this.errorListeners)n(e)}setBeforeAgentStartTimeout(e){this._beforeAgentStartTimeoutMs=e}dispose(){this.errorListeners.clear(),this.beforeAgentStartTimeoutLastReported.clear(),this.shortcutDiagnostics=[],this.commandDiagnostics=[];for(const e of this.extensions)e.handlers.clear()}hasHandlers(e){for(const n of this.extensions){const t=n.handlers.get(e);if(t&&t.length>0)return!0}return!1}getMessageRenderer(e){for(const n of this.extensions){const t=n.messageRenderers.get(e);if(t)return t}}getRegisteredCommands(e){this.commandDiagnostics=[];const n=[],t=new Map;for(const o of this.extensions)for(const i of o.commands.values()){if(e?.has(i.name)){const r=`Extension command '${i.name}' from ${o.path} conflicts with built-in commands. Skipping.`;this.commandDiagnostics.push({type:"warning",message:r,path:o.path}),this.hasUI()||console.warn(r);continue}const a=t.get(i.name);if(a){const r=`Extension command '${i.name}' from ${o.path} conflicts with ${a}. Skipping.`;this.commandDiagnostics.push({type:"warning",message:r,path:o.path}),this.hasUI()||console.warn(r);continue}t.set(i.name,o.path),n.push(i)}return n}getCommandDiagnostics(){return this.commandDiagnostics}getRegisteredCommandsWithPaths(){const e=[];for(const n of this.extensions)for(const t of n.commands.values())e.push({command:t,extensionPath:n.path});return e}getCommand(e){for(const n of this.extensions){const t=n.commands.get(e);if(t)return t}}findCommandOwner(e){for(const n of this.extensions)if(n.commands.has(e))return n}deriveExtensionName(e){const t=(e.path||e.resolvedPath||"").replace(/\/+$/,"").split(/[\\/]/);return t[t.length-1]||"unknown"}setTelemetrySink(e){this.telemetrySink=e}writeLlmCallEvent(e){try{this.telemetrySink?.writeLlmCallEvent(e)}catch{}}invokeHookHandler(e,n,t){const o=this.deriveExtensionName(e),i={extensionName:o,callerContext:`hook:${n}`,isUserInitiated:!1};return x(i,async()=>{const a=v[n]??1;if(a<1&&Math.random()>=a)return await t();const r=new Date,l=performance.now();let c=!0,h=null;try{return await t()}catch(u){throw c=!1,h=u instanceof Error?u.constructor.name:"unknown",u}finally{try{this.telemetrySink?.writeHookEvent({extensionName:o,hookName:n,durationMs:Math.round(performance.now()-l),ok:c,errorCode:h,sampleRate:a,recordedAt:r})}catch{}}})}async invokeCommand(e,n,t,o){const i=this.getCommand(e);if(!i)return{found:!1};const a=this.findCommandOwner(e),r=a?this.deriveExtensionName(a):"unknown",l=new Date,c=performance.now();let h="ok",u=null,m;const d=F(n),y={extensionName:r,callerContext:d==="no-args"?`command:/${e}`:`command:/${e} ${d}`,isUserInitiated:!0,sessionId:o?.sessionId??null,runId:o?.runId??null,variant:o?.variant??null};try{await x(y,()=>i.handler(n,t))}catch(g){h="error",u=g instanceof Error?g.constructor.name:"unknown",m=g,this.emitError({extensionPath:`command:${e}`,event:"command",error:g instanceof Error?g.message:String(g)})}const S=Math.round(performance.now()-c),w=new Date;try{this.telemetrySink?.writeCommandEvent({extensionName:r,commandName:e,argsSignature:d,argsLength:n.length,outcome:h,errorCode:u,durationMs:S,startedAt:l,endedAt:w,sessionId:o?.sessionId??null,runId:o?.runId??null,variant:o?.variant??null})}catch{}return{found:!0}}shutdown(){this.shutdownHandler()}createContext(){const e=this.getModel;return{ui:this.uiContext,hasUI:this.hasUI(),cwd:this.cwd,agentDir:this.agentDir,sessionManager:this.sessionManager,modelRegistry:this.modelRegistry,get model(){return e()},completeSimple:s((n,t)=>this.completeSimpleFn(n,t),"completeSimple"),completeSimpleWithUsage:s((n,t)=>this.completeSimpleWithUsageFn(n,t),"completeSimpleWithUsage"),completeJson:this.completeJsonFn?(n,t,o,i)=>this.completeJsonFn(n,t,o,i):void 0,isIdle:s(()=>this.isIdleFn(),"isIdle"),abort:s(()=>this.abortFn(),"abort"),clearFollowUpQueue:s(()=>this.clearFollowUpQueueFn(),"clearFollowUpQueue"),hasPendingMessages:s(()=>this.hasPendingMessagesFn(),"hasPendingMessages"),shutdown:s(()=>this.shutdownHandler(),"shutdown"),getContextUsage:s(()=>this.getContextUsageFn(),"getContextUsage"),compact:s(n=>this.compactFn(n),"compact"),getSystemPrompt:s(()=>this.getSystemPromptFn(),"getSystemPrompt"),getSoulManager:s(()=>this.getSoulManagerFn(),"getSoulManager"),getSettings:s(()=>this.getSettingsFn(),"getSettings"),getSkills:s(()=>this.getSkillsFn(),"getSkills")}}createCommandContext(){return{...this.createContext(),waitForIdle:s(()=>this.waitForIdleFn(),"waitForIdle"),newSession:s(e=>this.newSessionHandler(e),"newSession"),fork:s(e=>this.forkHandler(e),"fork"),navigateTree:s((e,n)=>this.navigateTreeHandler(e,n),"navigateTree"),switchSession:s(e=>this.switchSessionHandler(e),"switchSession"),reload:s(()=>this.reloadHandler(),"reload")}}isSessionBeforeEvent(e){return e.type==="session_before_switch"||e.type==="session_before_fork"||e.type==="session_before_compact"||e.type==="session_before_tree"}async emit(e){const n=this.createContext();let t;for(const o of this.extensions){const i=o.handlers.get(e.type);if(!(!i||i.length===0))for(const a of i)try{const r=await this.invokeHookHandler(o,e.type,()=>a(e,n));if(this.isSessionBeforeEvent(e)&&r&&(t=r,t.cancel))return t}catch(r){const l=r instanceof Error?r.message:String(r),c=r instanceof Error?r.stack:void 0;this.emitError({extensionPath:o.path,event:e.type,error:l,stack:c})}}return t}async emitToolResult(e){const n=this.createContext(),t={...e};let o=!1;for(const i of this.extensions){const a=i.handlers.get("tool_result");if(!(!a||a.length===0))for(const r of a)try{const l=await this.invokeHookHandler(i,"tool_result",()=>r(t,n));if(!l)continue;l.content!==void 0&&(t.content=l.content,o=!0),l.details!==void 0&&(t.details=l.details,o=!0),l.isError!==void 0&&(t.isError=l.isError,o=!0)}catch(l){const c=l instanceof Error?l.message:String(l),h=l instanceof Error?l.stack:void 0;this.emitError({extensionPath:i.path,event:"tool_result",error:c,stack:h})}}if(o)return{content:t.content,details:t.details,isError:t.isError}}async emitToolCall(e){const n=this.createContext();let t;for(const o of this.extensions){const i=o.handlers.get("tool_call");if(!(!i||i.length===0))for(const a of i){const r=await this.invokeHookHandler(o,"tool_call",()=>a(e,n));if(r&&(t=r,t.block))return t}}return t}async emitUserBash(e){const n=this.createContext();for(const t of this.extensions){const o=t.handlers.get("user_bash");if(!(!o||o.length===0))for(const i of o)try{const a=await this.invokeHookHandler(t,"user_bash",()=>i(e,n));if(a)return a}catch(a){const r=a instanceof Error?a.message:String(a),l=a instanceof Error?a.stack:void 0;this.emitError({extensionPath:t.path,event:"user_bash",error:r,stack:l})}}}async emitContext(e){const n=this.createContext();let t=structuredClone(e);for(const o of this.extensions){const i=o.handlers.get("context");if(!(!i||i.length===0))for(const a of i)try{const r={type:"context",messages:t},l=await this.invokeHookHandler(o,"context",()=>a(r,n));l&&l.messages&&(t=l.messages)}catch(r){const l=r instanceof Error?r.message:String(r),c=r instanceof Error?r.stack:void 0;this.emitError({extensionPath:o.path,event:"context",error:l,stack:c})}}return t}async emitBeforeAgentStart(e,n,t){const o=this.createContext(),i=[];let a=t,r=!1;for(const l of this.extensions){const c=l.handlers.get("before_agent_start");if(!(!c||c.length===0))for(const h of c)try{const u={type:"before_agent_start",prompt:e,images:n,systemPrompt:a},m=await this.withTimeout(this.invokeHookHandler(l,"before_agent_start",()=>h(u,o)),this.beforeAgentStartTimeoutMs);if(m===this.beforeAgentStartTimeoutSentinel){this.reportBeforeAgentStartTimeout(l.path);continue}if(m){const d=m;d.message&&i.push(d.message),d.systemPrompt!==void 0&&(a=d.systemPrompt,r=!0),d.appendSystemPrompt!==void 0&&(a=this.appendSystemPrompt(a,d.appendSystemPrompt),r=!0)}}catch(u){const m=u instanceof Error?u.message:String(u),d=u instanceof Error?u.stack:void 0;this.emitError({extensionPath:l.path,event:"before_agent_start",error:m,stack:d})}}if(i.length>0||r)return{messages:i.length>0?i:void 0,systemPrompt:r?a:void 0}}appendSystemPrompt(e,n){const t=n.trim();return t?`${e}
2
2
 
3
- ${t}`:e}async emitResourcesDiscover(e,n){const t=this.createContext(),o=[],i=[],a=[];for(const r of this.extensions){const c=r.handlers.get("resources_discover");if(!(!c||c.length===0))for(const l of c)try{const h={type:"resources_discover",cwd:e,reason:n},m=await this.invokeHookHandler(r,"resources_discover",()=>l(h,t));m?.skillPaths?.length&&o.push(...m.skillPaths.map(d=>({path:d,extensionPath:r.path}))),m?.promptPaths?.length&&i.push(...m.promptPaths.map(d=>({path:d,extensionPath:r.path}))),m?.themePaths?.length&&a.push(...m.themePaths.map(d=>({path:d,extensionPath:r.path})))}catch(h){const u=h instanceof Error?h.message:String(h),m=h instanceof Error?h.stack:void 0;this.emitError({extensionPath:r.path,event:"resources_discover",error:u,stack:m})}}return{skillPaths:o,promptPaths:i,themePaths:a}}async emitInput(e,n,t){const o=this.createContext();let i=e,a=n;for(const r of this.extensions)for(const c of r.handlers.get("input")??[])try{const l={type:"input",text:i,images:a,source:t},h=await this.invokeHookHandler(r,"input",()=>c(l,o));if(h?.action==="handled")return h;h?.action==="transform"&&(i=h.text,a=h.images??a)}catch(l){this.emitError({extensionPath:r.path,event:"input",error:l instanceof Error?l.message:String(l),stack:l instanceof Error?l.stack:void 0})}return i!==e||a!==n?{action:"transform",text:i,images:a}:{action:"continue"}}}export{H as ExtensionRunner,_ as emitSessionShutdownEvent};
3
+ ${t}`:e}async emitResourcesDiscover(e,n){const t=this.createContext(),o=[],i=[],a=[];for(const r of this.extensions){const l=r.handlers.get("resources_discover");if(!(!l||l.length===0))for(const c of l)try{const h={type:"resources_discover",cwd:e,reason:n},m=await this.invokeHookHandler(r,"resources_discover",()=>c(h,t));m?.skillPaths?.length&&o.push(...m.skillPaths.map(d=>({path:d,extensionPath:r.path}))),m?.promptPaths?.length&&i.push(...m.promptPaths.map(d=>({path:d,extensionPath:r.path}))),m?.themePaths?.length&&a.push(...m.themePaths.map(d=>({path:d,extensionPath:r.path})))}catch(h){const u=h instanceof Error?h.message:String(h),m=h instanceof Error?h.stack:void 0;this.emitError({extensionPath:r.path,event:"resources_discover",error:u,stack:m})}}return{skillPaths:o,promptPaths:i,themePaths:a}}async emitInput(e,n,t){const o=this.createContext();let i=e,a=n;for(const r of this.extensions)for(const l of r.handlers.get("input")??[])try{const c={type:"input",text:i,images:a,source:t},h=await this.invokeHookHandler(r,"input",()=>l(c,o));if(h?.action==="handled")return h;h?.action==="transform"&&(i=h.text,a=h.images??a)}catch(c){this.emitError({extensionPath:r.path,event:"input",error:c instanceof Error?c.message:String(c),stack:c instanceof Error?c.stack:void 0})}return i!==e||a!==n?{action:"transform",text:i,images:a}:{action:"continue"}}}export{H as ExtensionRunner,_ as emitSessionShutdownEvent};
@@ -10,7 +10,7 @@ import type { AssistantMessageEventStream } from "@pencil-agent/ai/events";
10
10
  import type { OAuthCredentials, OAuthLoginCallbacks } from "@pencil-agent/ai/oauth";
11
11
  import type { AutocompleteItem, Component, EditorComponent, EditorTheme, KeyId, OverlayHandle, OverlayOptions, TUI } from "@pencil-agent/tui";
12
12
  import type { Static, TSchema } from "@sinclair/typebox";
13
- import type { ToolRuntimeDescriptor } from "@pencil-agent/extension-sdk";
13
+ import type { ArgumentCompletionContext as ProtocolArgumentCompletionContext, ExtensionCommand as ProtocolExtensionCommand, ExtensionFlag, ToolRuntimeDescriptor } from "@pencil-agent/protocol";
14
14
  import type { Theme } from "../theme-contract.js";
15
15
  import type { BashResult } from "../platform/exec/bash-executor.js";
16
16
  import type { CompactionPreparation, CompactionResult } from "../session/compaction/index.js";
@@ -222,6 +222,10 @@ export interface ExtensionContext {
222
222
  isIdle(): boolean;
223
223
  /** Abort the current agent operation */
224
224
  abort(): void;
225
+ /** Clear the agent's follow-up message queue. Useful when an extension
226
+ * transitions to a terminal state and wants to prevent stale follow-ups
227
+ * from triggering additional turns. */
228
+ clearFollowUpQueue(): void;
225
229
  /** Whether there are queued messages waiting */
226
230
  hasPendingMessages(): boolean;
227
231
  /** Gracefully shutdown NanoPencil and exit. Available in all contexts. */
@@ -696,14 +700,8 @@ export interface MessageRenderOptions {
696
700
  expanded: boolean;
697
701
  }
698
702
  export type MessageRenderer<T = unknown> = (message: CustomMessage<T>, options: MessageRenderOptions, theme: Theme) => Component | undefined;
699
- export interface ArgumentCompletionContext {
700
- commandName: string;
701
- argumentText: string;
702
- argumentPrefix: string;
703
- tokenIndex: number;
704
- previousTokens: string[];
705
- }
706
- export interface RegisteredCommand {
703
+ export type ArgumentCompletionContext = ProtocolArgumentCompletionContext;
704
+ export interface RegisteredCommand extends ProtocolExtensionCommand<ExtensionCommandContext> {
707
705
  name: string;
708
706
  description?: string;
709
707
  getArgumentCompletions?: (argumentPrefix: string, context?: ArgumentCompletionContext) => AutocompleteItem[] | null;
@@ -785,6 +783,9 @@ export interface ExtensionAPI {
785
783
  executeCommand(text: string): Promise<boolean>;
786
784
  /** Whether the agent is idle (not streaming). For queueing loop tasks use with sendUserMessage. */
787
785
  isIdle(): boolean;
786
+ /** Clear the agent's follow-up message queue. Prevents stale follow-ups
787
+ * from triggering additional turns after a terminal state transition. */
788
+ clearFollowUpQueue(): void;
788
789
  /** Append a custom entry to the session for state persistence (not sent to LLM). */
789
790
  appendEntry<T = unknown>(customType: string, data?: T): void;
790
791
  /** Set the session display name (shown in session selector). */
@@ -927,13 +928,7 @@ export interface RegisteredTool {
927
928
  definition: ToolDefinition;
928
929
  extensionPath: string;
929
930
  }
930
- export interface ExtensionFlag {
931
- name: string;
932
- description?: string;
933
- type: "boolean" | "string";
934
- default?: boolean | string;
935
- extensionPath: string;
936
- }
931
+ export type { ExtensionFlag } from "@pencil-agent/protocol";
937
932
  export interface ExtensionShortcut {
938
933
  shortcut: KeyId;
939
934
  description?: string;
@@ -1010,6 +1005,7 @@ export interface ExtensionContextActions {
1010
1005
  }) => Promise<string | undefined>;
1011
1006
  isIdle: () => boolean;
1012
1007
  abort: () => void;
1008
+ clearFollowUpQueue: () => void;
1013
1009
  hasPendingMessages: () => boolean;
1014
1010
  shutdown: () => void;
1015
1011
  getContextUsage: () => ContextUsage | undefined;
@@ -1054,6 +1050,8 @@ export interface ExtensionCommandContextActions {
1054
1050
  export interface ExtensionRuntime extends ExtensionRuntimeState, ExtensionActions {
1055
1051
  /** Bound in runner.bindCore from ExtensionContextActions.isIdle */
1056
1052
  isIdle: () => boolean;
1053
+ /** Bound in runner.bindCore from ExtensionContextActions.clearFollowUpQueue */
1054
+ clearFollowUpQueue: () => void;
1057
1055
  }
1058
1056
  /** Loaded extension with all registered items. */
1059
1057
  export interface Extension {
@@ -25,14 +25,22 @@ export interface StreamOptions {
25
25
  signal?: AbortSignal;
26
26
  /** Retry configuration for automatic retry on retriable errors */
27
27
  retry?: {
28
- /** Maximum number of retry attempts (default: 3) */
28
+ /** Maximum number of retry attempts (default: 3). Ignored when persistentRetry is true. */
29
29
  maxRetries?: number;
30
30
  /** Base delay in ms for exponential backoff (default: 1000) */
31
31
  baseDelayMs?: number;
32
- /** Maximum delay cap in ms (default: 30000) */
32
+ /** Maximum delay cap in ms (default: 30000, or 300000 for persistentRetry) */
33
33
  maxDelayMs?: number;
34
34
  /** Whether to add jitter to avoid thundering herd (default: true) */
35
35
  jitter?: boolean;
36
+ /**
37
+ * Persistent/unattended retry mode for 429/529 overload errors.
38
+ * When true, retries indefinitely with capped backoff and periodic heartbeat yields.
39
+ * Only applies to overload errors (429, 529); other retriable errors still respect maxRetries.
40
+ */
41
+ persistentRetry?: boolean;
42
+ /** Heartbeat interval in ms during persistent retry to prevent idle timeouts (default: 30000) */
43
+ heartbeatMs?: number;
36
44
  };
37
45
  apiKey?: string;
38
46
  /**
@@ -148,6 +156,8 @@ export interface AssistantMessage {
148
156
  usage: Usage;
149
157
  stopReason: StopReason;
150
158
  errorMessage?: string;
159
+ /** HTTP response headers from the error response, if available. Used for retry-after extraction. */
160
+ errorHeaders?: Record<string, string>;
151
161
  timestamp: number;
152
162
  }
153
163
  export interface ToolResultMessage<TDetails = any> {
@@ -1,2 +1,5 @@
1
- var p=Object.defineProperty;var e=(r,t)=>p(r,"name",{value:t,configurable:!0});import{existsSync as c,readdirSync as D,readFileSync as g,mkdirSync as l,statSync as m,writeFileSync as h}from"node:fs";import{join as o,resolve as d}from"node:path";import{defaultAgentDirContext as S}from"../agent-dir/agent-dir-context.js";const f={default:"pencil"};function P(r){const t=r.trim();return t?t.replace(/[^a-zA-Z0-9_-]/g,"_"):"general"}e(P,"normalizePersonaId");class x{static{e(this,"PersonaManager")}ctx;constructor(t=S()){this.ctx=t}get personasDir(){return o(this.ctx.path,"personas")}get activePersonaStatePath(){return o(this.ctx.path,"persona.json")}ensurePersonasDir(){c(this.personasDir)||l(this.personasDir,{recursive:!0})}getPersonasDir(){return this.personasDir}getActivePersonaId(){try{if(!c(this.activePersonaStatePath))return"vex";const t=g(this.activePersonaStatePath,"utf-8"),n=JSON.parse(t);if(!n?.activePersonaId)return"vex";let i=P(String(n.activePersonaId));return f[i]&&(i=f[i],this.setActivePersonaId(i)),i}catch{return"vex"}}setActivePersonaId(t){if(this.ensurePersonasDir(),!t){try{h(this.activePersonaStatePath,JSON.stringify({},null,2),"utf-8")}catch{}return}const n=P(t),i=this.getPersonaDir(n);c(i)||l(i,{recursive:!0});const u={activePersonaId:n};h(this.activePersonaStatePath,JSON.stringify(u,null,2),"utf-8")}listPersonas(){try{return this.ensurePersonasDir(),D(this.personasDir).map(t=>P(t)).filter(t=>{const n=this.getPersonaDir(t);try{return m(n).isDirectory()}catch{return!1}}).sort((t,n)=>t.localeCompare(n))}catch{return[]}}getPersonaDir(t){const n=P(t);return o(this.personasDir,n)}getPersonaPencilPath(t){return o(this.getPersonaDir(t),"PENCIL.md")}getPersonaSkillsDir(t){return o(this.getPersonaDir(t),"skills")}getPersonaSoulDir(t){return o(this.getPersonaDir(t),"soul")}getPersonaMemoryDir(t){return o(this.getPersonaDir(t),"memory")}getPersonaMcpConfigPath(t){return o(this.getPersonaDir(t),"mcp.json")}getPersonaDescription(t){try{const n=this.getPersonaPencilPath(t);if(!c(n))return"";const i=g(n,"utf-8");for(const u of i.split(`
2
- `)){const a=u.trim();if(!(!a||a.startsWith("#")))return a.length>60?a.slice(0,57)+"...":a}return""}catch{return""}}}const s=new x;function M(){return s.getPersonasDir()}e(M,"getPersonasDir");function C(){return s.getActivePersonaId()}e(C,"getActivePersonaId");function N(r){s.setActivePersonaId(r)}e(N,"setActivePersonaId");function k(){return s.listPersonas()}e(k,"listPersonas");function w(r){return s.getPersonaDir(r)}e(w,"getPersonaDir");function z(r){return s.getPersonaPencilPath(r)}e(z,"getPersonaPencilPath");function E(r){return s.getPersonaSkillsDir(r)}e(E,"getPersonaSkillsDir");function O(r){return s.getPersonaSoulDir(r)}e(O,"getPersonaSoulDir");function j(r){return s.getPersonaMemoryDir(r)}e(j,"getPersonaMemoryDir");function J(r){return s.getPersonaMcpConfigPath(r)}e(J,"getPersonaMcpConfigPath");function _(r){return s.getPersonaDescription(r)}e(_,"getPersonaDescription");function F(r){const t=r.trim();return t&&d(t)}e(F,"toAbsolutePath");export{x as PersonaManager,C as getActivePersonaId,_ as getPersonaDescription,w as getPersonaDir,J as getPersonaMcpConfigPath,j as getPersonaMemoryDir,z as getPersonaPencilPath,E as getPersonaSkillsDir,O as getPersonaSoulDir,M as getPersonasDir,k as listPersonas,N as setActivePersonaId,F as toAbsolutePath};
1
+ var p=Object.defineProperty;var n=(e,t)=>p(e,"name",{value:t,configurable:!0});import{existsSync as a,readdirSync as D,readFileSync as f,mkdirSync as l,statSync as m,writeFileSync as g}from"node:fs";import{join as o,resolve as d}from"node:path";import{defaultAgentDirContext as v}from"../agent-dir/agent-dir-context.js";const h={default:"pencil"};function P(e){const t=e.trim();return t?t.replace(/[^a-zA-Z0-9_-]/g,"_"):"general"}n(P,"normalizePersonaId");class x{static{n(this,"PersonaManager")}ctx;constructor(t=v()){this.ctx=t}get personasDir(){return o(this.ctx.path,"personas")}get activePersonaStatePath(){return o(this.ctx.path,"persona.json")}ensurePersonasDir(){a(this.personasDir)||l(this.personasDir,{recursive:!0});const t=o(this.personasDir,"vex");if(!a(t)){l(t,{recursive:!0});const r=o(t,"PENCIL.md");a(r)||g(r,`# vex
2
+
3
+ Default persona for nanoPencil.
4
+ `,"utf-8")}}getPersonasDir(){return this.personasDir}getActivePersonaId(){try{if(!a(this.activePersonaStatePath))return"vex";const t=f(this.activePersonaStatePath,"utf-8"),r=JSON.parse(t);if(!r?.activePersonaId)return"vex";let i=P(String(r.activePersonaId));return h[i]&&(i=h[i],this.setActivePersonaId(i)),i}catch{return"vex"}}setActivePersonaId(t){if(this.ensurePersonasDir(),!t){try{g(this.activePersonaStatePath,JSON.stringify({},null,2),"utf-8")}catch{}return}const r=P(t),i=this.getPersonaDir(r);a(i)||l(i,{recursive:!0});const u={activePersonaId:r};g(this.activePersonaStatePath,JSON.stringify(u,null,2),"utf-8")}listPersonas(){try{return this.ensurePersonasDir(),D(this.personasDir).map(t=>P(t)).filter(t=>{const r=this.getPersonaDir(t);try{return m(r).isDirectory()}catch{return!1}}).sort((t,r)=>t.localeCompare(r))}catch{return[]}}getPersonaDir(t){const r=P(t);return o(this.personasDir,r)}getPersonaPencilPath(t){return o(this.getPersonaDir(t),"PENCIL.md")}getPersonaSkillsDir(t){return o(this.getPersonaDir(t),"skills")}getPersonaSoulDir(t){return o(this.getPersonaDir(t),"soul")}getPersonaMemoryDir(t){return o(this.getPersonaDir(t),"memory")}getPersonaMcpConfigPath(t){return o(this.getPersonaDir(t),"mcp.json")}getPersonaDescription(t){try{const r=this.getPersonaPencilPath(t);if(!a(r))return"";const i=f(r,"utf-8");for(const u of i.split(`
5
+ `)){const c=u.trim();if(!(!c||c.startsWith("#")))return c.length>60?c.slice(0,57)+"...":c}return""}catch{return""}}}const s=new x;function M(){return s.getPersonasDir()}n(M,"getPersonasDir");function C(){return s.getActivePersonaId()}n(C,"getActivePersonaId");function N(e){s.setActivePersonaId(e)}n(N,"setActivePersonaId");function k(){return s.listPersonas()}n(k,"listPersonas");function E(e){return s.getPersonaDir(e)}n(E,"getPersonaDir");function w(e){return s.getPersonaPencilPath(e)}n(w,"getPersonaPencilPath");function z(e){return s.getPersonaSkillsDir(e)}n(z,"getPersonaSkillsDir");function O(e){return s.getPersonaSoulDir(e)}n(O,"getPersonaSoulDir");function j(e){return s.getPersonaMemoryDir(e)}n(j,"getPersonaMemoryDir");function J(e){return s.getPersonaMcpConfigPath(e)}n(J,"getPersonaMcpConfigPath");function _(e){return s.getPersonaDescription(e)}n(_,"getPersonaDescription");function F(e){const t=e.trim();return t&&d(t)}n(F,"toAbsolutePath");export{x as PersonaManager,C as getActivePersonaId,_ as getPersonaDescription,E as getPersonaDir,J as getPersonaMcpConfigPath,j as getPersonaMemoryDir,w as getPersonaPencilPath,z as getPersonaSkillsDir,O as getPersonaSoulDir,M as getPersonasDir,k as listPersonas,N as setActivePersonaId,F as toAbsolutePath};
@@ -1,5 +1,5 @@
1
- var A=Object.defineProperty;var n=(a,e)=>A(a,"name",{value:e,configurable:!0});import{appendFileSync as E,readFileSync as v}from"node:fs";import{homedir as k}from"node:os";import{basename as L,dirname as P,join as _}from"node:path";import{isContextOverflow as T}from"@pencil-agent/ai/overflow";import{resetApiProviders as I}from"@pencil-agent/ai/registry";import{getDocsPath as C}from"../../config.js";import{stripFrontmatter as F}from"../../utils/frontmatter.js";import{calculateContextTokens as b,collectEntriesForBranchSummary as N,estimateContextTokens as U,shouldCompact as B}from"../session/compaction/index.js";import{ToolOrchestrator as O}from"../tools/orchestrator.js";import{DEFAULT_THINKING_LEVEL as D}from"../platform/config/defaults.js";import{createExtensionTelemetrySink as $}from"../platform/telemetry/index.js";import{ExtensionRunner as j}from"../extensions-host/index.js";import{expandPromptTemplate as f}from"../prompt/prompt-templates.js";import{getLatestCompactionEntry as y}from"../session/session-manager.js";import{t as W}from"../platform/i18n/index.js";import{toSoulContext as S,extractSessionContext as w}from"../soul-integration.js";import{createDefaultRuntimeTools as H}from"./default-tools.js";import{BashRunner as K}from"./bash-runner.js";import{Listeners as V}from"../platform/listeners.js";import{ModelController as q}from"./model-controller.js";import{CompactionController as G}from"./compaction-controller.js";import{SessionLifecycleController as Q}from"./session-lifecycle-controller.js";import{SessionTreeController as X}from"./session-tree-controller.js";import{ToolRuntimeController as z}from"./tool-runtime-controller.js";import{buildRuntimeSystemPrompt as J,getActiveBaseToolNames as Y}from"./prompt-assembly.js";import{exportSessionHtml as Z,getLastAssistantText as ee}from"./export-bridge.js";import{ExtensionEventBridge as te}from"./event-bridge.js";import{bindExtensionCore as se}from"./extension-core-bindings.js";import{buildSessionSlashCommands as ne}from"./slash-command-catalog.js";import{RetryCoordinator as oe}from"./retry-coordinator.js";import{createLogger as ie}from"../platform/utils/logger.js";import{createAgentTool as re,createTaskToolAlias as ae,createSendMessageTool as le,AGENT_TOOL_NAME as x,TASK_TOOL_NAME as he,SEND_MESSAGE_TOOL_NAME as M}from"../sub-agent/index.js";import{CycleModelError as ze}from"./model-controller.js";function qe(a){const e=a.match(/^<skill name="([^"]+)" location="([^"]+)">\n([\s\S]*?)\n<\/skill>(?:\n\n([\s\S]+))?$/);return e?{name:e[1],location:e[2],content:e[3],userMessage:e[4]?.trim()||void 0}:null}n(qe,"parseSkillBlock");function R(a,e){const t=new Set(e.content.filter(o=>o.type==="toolCall").map(o=>o.id));let s=a.length;for(;s>0&&ge(a[s-1],t);)s--;return s>0&&ce(a[s-1],e)&&s--,a.slice(0,s)}n(R,"pruneRecoverableErrorTail");function ge(a,e){return a.role==="toolResult"&&e.has(a.toolCallId)}n(ge,"isRecoverableTailToolResult");function ce(a,e){return a.role==="assistant"&&a.stopReason===e.stopReason&&a.timestamp===e.timestamp&&a.provider===e.provider&&a.model===e.model&&a.api===e.api&&a.errorMessage===e.errorMessage}n(ce,"isSameRecoverableAssistantMessage");function me(a){switch(a.type){case"agent_start":return{type:"sub_agent_start",subAgentId:a.subAgentId,agentType:a.agentType,description:a.description,isAsync:a.isAsync};case"tool_start":return{type:"sub_agent_tool_start",subAgentId:a.subAgentId,toolName:a.toolName};case"tool_end":return{type:"sub_agent_tool_end",subAgentId:a.subAgentId,toolName:a.toolName,isError:a.isError};case"agent_end":return{type:"sub_agent_end",subAgentId:a.subAgentId,success:a.success};default:return}}n(me,"mapSubAgentEvent");class Ge{static{n(this,"AgentSession")}agent;sessionManager;settingsManager;agentCtx;_scopedModels;_unsubscribeAgent;_detachExternalAbort;_listeners=new V;_steeringMessages=[];_followUpMessages=[];_pendingNextTurnMessages=[];_retryCoordinator;_logger;_bashRunner;_extensionRunner=void 0;_slashCommandExecutor=void 0;_extensionEventBridge;_resourceLoader;_theme;_dbg(e){if(process.env.NANOPENCIL_DEBUG_SESSION==="1")try{const t=_(k(),".nanopencil","agent","nanopencil-debug.log");E(t,`[${new Date().toISOString()}] [session] ${e}
2
- `)}catch{}}_customTools;_staticCustomTools;_mcpToolsFactory;_soulManagerFactory;_baseToolRegistry=new Map;_agentTool;_createSessionFactory;_cwd;_extensionRunnerRef;_soulManager;_lastSoulInjection;_initialActiveToolNames;_baseToolsOverride;_extensionUIContext;_extensionCommandContextActions;_extensionShutdownHandler;_extensionErrorListener;_extensionErrorUnsubscriber;_modelRegistry;_agentDir;_baseSystemPrompt="";_modelController;_compactionController;_sessionTreeController;_lifecycleController;_toolOrchestrator;_toolRuntimeController;constructor(e){if(this.agent=e.agent,this.sessionManager=e.sessionManager,this.settingsManager=e.settingsManager,this.agentCtx=e.agentCtx,this._scopedModels=e.scopedModels??[],this._resourceLoader=e.resourceLoader,this._theme=e.theme,this._bashRunner=new K({getCwd:n(()=>this._cwd,"getCwd"),getShellCommandPrefix:n(()=>this.settingsManager.getShellCommandPrefix(),"getShellCommandPrefix"),appendToAgent:n(t=>this.agent.appendMessage(t),"appendToAgent"),appendToSession:n(t=>this.sessionManager.appendMessage(t),"appendToSession"),isStreaming:n(()=>this.isStreaming,"isStreaming")}),this._staticCustomTools=e.customTools??[],this._mcpToolsFactory=e.mcpToolsFactory,this._soulManagerFactory=e.soulManagerFactory,this._customTools=[...this._staticCustomTools,...e.initialMcpTools??[]],this._initialActiveToolNames=e.initialActiveToolNames,this._toolOrchestrator=new O({customTools:this._customTools,initialActiveToolNames:this._initialActiveToolNames,getExtensionTools:n(()=>new Map((this._extensionRunner?.getAllRegisteredTools()??[]).map(t=>[t.definition.name,t.definition])),"getExtensionTools")}),this._toolRuntimeController=new z(this._toolOrchestrator),this._cwd=e.cwd,this._agentDir=e.agentDir,this._modelRegistry=e.modelRegistry,this._extensionRunnerRef=e.extensionRunnerRef,this._soulManager=e.soulManager,this._baseToolsOverride=e.baseToolsOverride,this._createSessionFactory=e.createSession,this._extensionEventBridge=new te({getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner")}),this._modelController=new q({getModel:n(()=>this.model,"getModel"),getThinkingLevel:n(()=>this.thinkingLevel,"getThinkingLevel"),getScopedModels:n(()=>this._scopedModels,"getScopedModels"),setAgentModel:n(t=>this.agent.setModel(t),"setAgentModel"),setAgentThinkingLevel:n(t=>this.agent.setThinkingLevel(t),"setAgentThinkingLevel"),setAgentLoopFramework:n(t=>this.agent.setAgentLoopFramework(t),"setAgentLoopFramework"),setLoopPolicy:n(t=>this.agent.setLoopPolicy(t),"setLoopPolicy"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getApiKeyForProvider:n(t=>this._modelRegistry.getApiKeyForProvider(t),"getApiKeyForProvider"),getAvailableModels:n(()=>this._modelRegistry.getAvailableAsync(),"getAvailableModels"),getAuthCredential:n(t=>this._modelRegistry.authStorage.get(t),"getAuthCredential"),appendModelChange:n((t,s)=>this.sessionManager.appendModelChange(t,s),"appendModelChange"),appendThinkingLevelChange:n(t=>this.sessionManager.appendThinkingLevelChange(t),"appendThinkingLevelChange"),setDefaultModelAndProvider:n((t,s)=>this.settingsManager.setDefaultModelAndProvider(t,s),"setDefaultModelAndProvider"),setDefaultThinkingLevel:n(t=>this.settingsManager.setDefaultThinkingLevel(t),"setDefaultThinkingLevel"),emitModelSelect:n(async({model:t,previousModel:s,source:o})=>{this._extensionRunner&&await this._extensionRunner.emit({type:"model_select",model:t,previousModel:s,source:o})},"emitModelSelect")}),this._compactionController=new G({getModel:n(()=>this.model,"getModel"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),getBranch:n(()=>this.sessionManager.getBranch(),"getBranch"),getEntries:n(()=>this.sessionManager.getEntries(),"getEntries"),getCompactionSettings:n(()=>this.settingsManager.getCompactionSettings(),"getCompactionSettings"),appendCompaction:n((t,s,o,r,i)=>this.sessionManager.appendCompaction(t,s,o,r,i),"appendCompaction"),applyCompactedMessages:n(()=>{const t=this.sessionManager.buildSessionContext();return this.agent.replaceMessages(t.messages),t.messages},"applyCompactedMessages"),logInfo:n((t,s)=>this._logger.info(t,s),"logInfo"),disconnectFromAgent:n(()=>this._disconnectFromAgent(),"disconnectFromAgent"),reconnectToAgent:n(()=>this._reconnectToAgent(),"reconnectToAgent"),abortAgent:n(()=>this.abort(),"abortAgent"),emitAutoCompactionStart:n(t=>this._emit({type:"auto_compaction_start",reason:t}),"emitAutoCompactionStart"),emitAutoCompactionEnd:n(t=>this._emit({type:"auto_compaction_end",...t}),"emitAutoCompactionEnd"),getAutoCompactionEnabled:n(()=>this.settingsManager.getCompactionEnabled(),"getAutoCompactionEnabled"),setAutoCompactionEnabled:n(t=>this.settingsManager.setCompactionEnabled(t),"setAutoCompactionEnabled")}),this._sessionTreeController=new X({getModel:n(()=>this.model,"getModel"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),getLeafId:n(()=>this.sessionManager.getLeafId(),"getLeafId"),getEntry:n(t=>this.sessionManager.getEntry(t),"getEntry"),collectBranchSummaryEntries:n((t,s)=>N(this.sessionManager,t,s),"collectBranchSummaryEntries"),getBranchSummaryReserveTokens:n(()=>this.settingsManager.getBranchSummarySettings().reserveTokens,"getBranchSummaryReserveTokens"),branchWithSummary:n((t,s,o,r)=>this.sessionManager.branchWithSummary(t,s,o,r),"branchWithSummary"),appendLabelChange:n((t,s)=>this.sessionManager.appendLabelChange(t,s),"appendLabelChange"),resetLeaf:n(()=>this.sessionManager.resetLeaf(),"resetLeaf"),branch:n(t=>this.sessionManager.branch(t),"branch"),rebuildAgentMessages:n(()=>{const t=this.sessionManager.buildSessionContext();this.agent.replaceMessages(t.messages)},"rebuildAgentMessages"),extractUserMessageText:n(t=>this._extractUserMessageText(t),"extractUserMessageText")}),this._lifecycleController=new Q({getSessionFile:n(()=>this.sessionManager.getSessionFile(),"getSessionFile"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),disconnectFromAgent:n(()=>this._disconnectFromAgent(),"disconnectFromAgent"),reconnectToAgent:n(()=>this._reconnectToAgent(),"reconnectToAgent"),abortAgent:n(()=>this.abort(),"abortAgent"),resetAgent:n(()=>this.agent.reset(),"resetAgent"),syncAgentSessionId:n(()=>{this.agent.sessionId=this.sessionManager.getSessionId()},"syncAgentSessionId"),clearPendingQueues:n(()=>{this._steeringMessages=[],this._followUpMessages=[],this._pendingNextTurnMessages=[]},"clearPendingQueues"),clearPendingNextTurnMessages:n(()=>{this._pendingNextTurnMessages=[]},"clearPendingNextTurnMessages"),sessionNewSession:n(t=>this.sessionManager.newSession({parentSession:t}),"sessionNewSession"),sessionSetFile:n(t=>this.sessionManager.setSessionFile(t),"sessionSetFile"),sessionCreateBranchedSession:n(t=>this.sessionManager.createBranchedSession(t),"sessionCreateBranchedSession"),getEntry:n(t=>this.sessionManager.getEntry(t),"getEntry"),buildSessionContext:n(()=>this.sessionManager.buildSessionContext(),"buildSessionContext"),replaceAgentMessages:n(t=>this.agent.replaceMessages(t),"replaceAgentMessages"),appendThinkingLevelChange:n(t=>this.sessionManager.appendThinkingLevelChange(t),"appendThinkingLevelChange"),getThinkingLevel:n(()=>this.thinkingLevel,"getThinkingLevel"),getBranch:n(()=>this.sessionManager.getBranch(),"getBranch"),getDefaultThinkingLevel:n(()=>this.settingsManager.getDefaultThinkingLevel()??D,"getDefaultThinkingLevel"),getAvailableModels:n(()=>this._modelRegistry.getAvailable(),"getAvailableModels"),restoreModel:n(t=>this._modelController.restoreModel(t),"restoreModel"),restoreThinkingLevel:n(t=>this._modelController.restoreThinkingLevel(t),"restoreThinkingLevel"),runSetup:n(t=>t(this.sessionManager),"runSetup"),extractUserMessageText:n(t=>this._extractUserMessageText(t),"extractUserMessageText")}),this.agent.setModelErrorRecovery(t=>this._recoverModelErrorInLoop(t)),this._unsubscribeAgent=this.agent.subscribe(this._handleAgentEvent),e.signal){const t=n(()=>{this.abort()},"externalAbortHandler");e.signal.addEventListener("abort",t,{once:!0}),this._detachExternalAbort=()=>{e.signal?.removeEventListener("abort",t)}}this._buildRuntime({activeToolNames:this._initialActiveToolNames,includeAllExtensionTools:!0}),this._retryCoordinator=new oe(this._createRetryHost()),this._logger=ie({sessionId:this.sessionManager.getSessionId(),component:"agent-session"})}get modelRegistry(){return this._modelRegistry}get cwd(){return this._cwd}get agentDir(){return this._agentDir}getSlashCommands(){return ne({promptTemplates:this.promptTemplates,resourceLoader:this._resourceLoader,extensionRunner:this._extensionRunner},W)}async tryExecuteExtensionCommand(e){return this._tryExecuteExtensionCommand(e)}async executeSlashCommand(e){return e.startsWith("/")?this._slashCommandExecutor&&await this._slashCommandExecutor(e)?!0:this._tryExecuteExtensionCommand(e):!1}setSlashCommandExecutor(e){this._slashCommandExecutor=e}_emit(e){this._listeners.emit(e)}_lastAssistantMessage=void 0;_handleAgentEvent=n(async e=>{if(e.type==="message_start"&&e.message.role==="user"){const t=this._getUserMessageText(e.message);if(t){const s=this._steeringMessages.indexOf(t);if(s!==-1)this._steeringMessages.splice(s,1);else{const o=this._followUpMessages.indexOf(t);o!==-1&&this._followUpMessages.splice(o,1)}}}if(e.type==="message_update")this._emit(e),this._extensionEventBridge.emitExtensionEvent(e).catch(t=>{this._logger.error("[extension] message_update event error",{error:t})});else{const t=this._extensionEventBridge.emitExtensionEvent(e);this._emit(e),await t}if(e.type==="message_end"&&(e.message.role==="custom"?this.sessionManager.appendCustomMessageEntry(e.message.customType,e.message.content,e.message.display,e.message.details):(e.message.role==="user"||e.message.role==="assistant"||e.message.role==="toolResult")&&this.sessionManager.appendMessage(e.message),e.message.role==="assistant"&&(this._lastAssistantMessage=e.message,e.message.stopReason!=="error"&&this._retryCoordinator.onSuccess())),e.type==="agent_end"&&this._lastAssistantMessage){const t=this._lastAssistantMessage;if(this._lastAssistantMessage=void 0,this._retryCoordinator.isRetryableError(t)&&await this._retryCoordinator.handleError(t))return;if(await this._checkCompaction(t),this._soulManager){const s=t.stopReason==="error"?"failure":"success",o=this._cwd.split(/[/\\]/).pop()||"unknown",{tags:r,complexity:i,toolUsage:c}=w(this.state.messages,this._cwd),g=S(o,r,i,c),l=r[0]||o;(async()=>{try{await this._soulManager.recordInteraction(g,s,"turn"),await this._soulManager.updateExpertise(l,r,s==="success")}catch(m){this._logger.warn("[soul] recordInteraction/updateExpertise failed",{error:m})}})()}}e.type==="agent_end"&&this._extensionRunner&&this._extensionRunner.emit({type:"agent_end",messages:e.messages}).catch(t=>{this._logger.error("[extension] agent_end event error",{error:t})})},"_handleAgentEvent");_getUserMessageText(e){if(e.role!=="user")return"";const t=e.content;return typeof t=="string"?t:t.filter(o=>o.type==="text").map(o=>o.text).join("")}_findLastAssistantMessage(){const e=this.agent.state.messages;for(let t=e.length-1;t>=0;t--){const s=e[t];if(s.role==="assistant")return s}}subscribe(e){return this._listeners.add(e)}_disconnectFromAgent(){this._unsubscribeAgent&&(this._unsubscribeAgent(),this._unsubscribeAgent=void 0)}_reconnectToAgent(){this._unsubscribeAgent||(this._unsubscribeAgent=this.agent.subscribe(this._handleAgentEvent))}dispose(){this._disconnectFromAgent(),this._extensionRunner?.dispose(),this._listeners.clear(),this._detachExternalAbort&&(this._detachExternalAbort(),this._detachExternalAbort=void 0)}get state(){return this.agent.state}get model(){return this.agent.state.model}get thinkingLevel(){return this.agent.state.thinkingLevel}get agentLoopFramework(){return this.agent.agentLoopFramework}get isStreaming(){return this.agent.state.isStreaming}get systemPrompt(){return this.agent.state.systemPrompt}get soulManager(){return this._soulManager}get retryAttempt(){return this._retryCoordinator.attempt}getActiveToolNames(){return this.agent.state.tools.map(e=>e.name)}getAllTools(){return this._toolOrchestrator.getAllTools()}setActiveToolsByName(e){const{tools:t,validToolNames:s}=this._toolOrchestrator.setActiveToolsByName(e);this.agent.setTools(t),this._baseSystemPrompt=this._rebuildSystemPrompt(s),this.agent.setSystemPrompt(this._baseSystemPrompt)}get isCompacting(){return this._compactionController.isCompacting}get messages(){return this.agent.state.messages}get steeringMode(){return this.agent.getSteeringMode()}get followUpMode(){return this.agent.getFollowUpMode()}get sessionFile(){return this.sessionManager.getSessionFile()}get sessionId(){return this.sessionManager.getSessionId()}get sessionName(){return this.sessionManager.getSessionName()}get scopedModels(){return this._scopedModels}setScopedModels(e){this._scopedModels=e}get promptTemplates(){return this._resourceLoader.getPrompts().prompts}_rebuildSystemPrompt(e,t){return J({cwd:this._cwd,resourceLoader:this._resourceLoader,toolNames:e,baseToolRegistry:this._baseToolRegistry,soulInjection:t?.soulInjection??this._lastSoulInjection})}_getActiveBaseToolNames(){return Y(this.getActiveToolNames(),this._baseToolRegistry)}async _generateSoulInjection(){if(!this._soulManager){this._lastSoulInjection=void 0;return}try{const e=this._cwd.split(/[/\\]/).pop()||"unknown",{tags:t,complexity:s,toolUsage:o}=w(this.state.messages,this._cwd),r=await this._soulManager.generateInjection(S(e,t,s,o));return this._lastSoulInjection=typeof r=="string"&&r.trim().length>0?r:void 0,this._lastSoulInjection}catch(e){return this._emit({type:"sdk:error",source:"soul",error:e}),this._lastSoulInjection}}async prompt(e,t){const s=t?.expandPromptTemplates??!0;if(this._dbg(`prompt: "${e.slice(0,80)}" isStreaming=${this.isStreaming} hasModel=${!!this.model}`),s&&e.startsWith("/")){const u=await this.executeSlashCommand(e);if(this._dbg(`prompt: slash handled=${u}`),u)return}let o=e,r=t?.images;if(this._extensionRunner?.hasHandlers("input")){const u=await this._extensionRunner.emitInput(o,r,t?.source??"interactive");if(u.action==="handled")return;u.action==="transform"&&(o=u.text,r=u.images??r)}let i=o;if(s&&(i=this._expandSkillCommand(i),i=f(i,[...this.promptTemplates])),this.isStreaming){if(!t?.streamingBehavior)throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");t.streamingBehavior==="followUp"?await this._queueFollowUp(i,r):await this._queueSteer(i,r);return}if(this._bashRunner.flushPending(),!this.model)throw new Error(`No model selected.
1
+ var A=Object.defineProperty;var n=(a,e)=>A(a,"name",{value:e,configurable:!0});import{appendFileSync as E,readFileSync as v}from"node:fs";import{homedir as k}from"node:os";import{basename as L,dirname as P,join as _}from"node:path";import{isContextOverflow as T}from"@pencil-agent/ai/overflow";import{resetApiProviders as I}from"@pencil-agent/ai/registry";import{getDocsPath as C}from"../../config.js";import{stripFrontmatter as F}from"../../utils/frontmatter.js";import{calculateContextTokens as b,collectEntriesForBranchSummary as N,estimateContextTokens as U,shouldCompact as B}from"../session/compaction/index.js";import{ToolOrchestrator as O}from"../tools/orchestrator.js";import{DEFAULT_THINKING_LEVEL as D}from"../platform/config/defaults.js";import{createExtensionTelemetrySink as $}from"../platform/telemetry/index.js";import{ExtensionRunner as j}from"../extensions-host/index.js";import{expandPromptTemplate as f}from"../prompt/prompt-templates.js";import{getLatestCompactionEntry as y}from"../session/session-manager.js";import{t as W}from"../platform/i18n/index.js";import{toSoulContext as w,extractSessionContext as S}from"../soul-integration.js";import{createDefaultRuntimeTools as H}from"./default-tools.js";import{BashRunner as K}from"./bash-runner.js";import{Listeners as V}from"../platform/listeners.js";import{ModelController as q}from"./model-controller.js";import{CompactionController as Q}from"./compaction-controller.js";import{SessionLifecycleController as G}from"./session-lifecycle-controller.js";import{SessionTreeController as X}from"./session-tree-controller.js";import{ToolRuntimeController as z}from"./tool-runtime-controller.js";import{buildRuntimeSystemPrompt as J,getActiveBaseToolNames as Y}from"./prompt-assembly.js";import{exportSessionHtml as Z,getLastAssistantText as ee}from"./export-bridge.js";import{ExtensionEventBridge as te}from"./event-bridge.js";import{bindExtensionCore as se}from"./extension-core-bindings.js";import{buildSessionSlashCommands as ne}from"./slash-command-catalog.js";import{RetryCoordinator as oe}from"./retry-coordinator.js";import{createLogger as ie}from"../platform/utils/logger.js";import{createAgentTool as re,createTaskToolAlias as ae,createSendMessageTool as le,AGENT_TOOL_NAME as x,TASK_TOOL_NAME as he,SEND_MESSAGE_TOOL_NAME as M}from"../sub-agent/index.js";import{CycleModelError as ze}from"./model-controller.js";function qe(a){const e=a.match(/^<skill name="([^"]+)" location="([^"]+)">\n([\s\S]*?)\n<\/skill>(?:\n\n([\s\S]+))?$/);return e?{name:e[1],location:e[2],content:e[3],userMessage:e[4]?.trim()||void 0}:null}n(qe,"parseSkillBlock");function R(a,e){const t=new Set(e.content.filter(o=>o.type==="toolCall").map(o=>o.id));let s=a.length;for(;s>0&&ge(a[s-1],t);)s--;return s>0&&ce(a[s-1],e)&&s--,a.slice(0,s)}n(R,"pruneRecoverableErrorTail");function ge(a,e){return a.role==="toolResult"&&e.has(a.toolCallId)}n(ge,"isRecoverableTailToolResult");function ce(a,e){return a.role==="assistant"&&a.stopReason===e.stopReason&&a.timestamp===e.timestamp&&a.provider===e.provider&&a.model===e.model&&a.api===e.api&&a.errorMessage===e.errorMessage}n(ce,"isSameRecoverableAssistantMessage");function me(a){switch(a.type){case"agent_start":return{type:"sub_agent_start",subAgentId:a.subAgentId,agentType:a.agentType,description:a.description,isAsync:a.isAsync};case"tool_start":return{type:"sub_agent_tool_start",subAgentId:a.subAgentId,toolName:a.toolName};case"tool_end":return{type:"sub_agent_tool_end",subAgentId:a.subAgentId,toolName:a.toolName,isError:a.isError};case"agent_end":return{type:"sub_agent_end",subAgentId:a.subAgentId,success:a.success};default:return}}n(me,"mapSubAgentEvent");class Qe{static{n(this,"AgentSession")}agent;sessionManager;settingsManager;agentCtx;_scopedModels;_unsubscribeAgent;_detachExternalAbort;_listeners=new V;_steeringMessages=[];_followUpMessages=[];_pendingNextTurnMessages=[];_retryCoordinator;_logger;_bashRunner;_extensionRunner=void 0;_slashCommandExecutor=void 0;_extensionEventBridge;_resourceLoader;_theme;_dbg(e){if(process.env.NANOPENCIL_DEBUG_SESSION==="1")try{const t=_(k(),".nanopencil","agent","nanopencil-debug.log");E(t,`[${new Date().toISOString()}] [session] ${e}
2
+ `)}catch{}}_customTools;_staticCustomTools;_mcpToolsFactory;_soulManagerFactory;_baseToolRegistry=new Map;_agentTool;_createSessionFactory;_cwd;_extensionRunnerRef;_soulManager;_lastSoulInjection;_initialActiveToolNames;_baseToolsOverride;_extensionUIContext;_extensionCommandContextActions;_extensionShutdownHandler;_extensionErrorListener;_extensionErrorUnsubscriber;_modelRegistry;_agentDir;_baseSystemPrompt="";_modelController;_compactionController;_sessionTreeController;_lifecycleController;_toolOrchestrator;_toolRuntimeController;constructor(e){if(this.agent=e.agent,this.sessionManager=e.sessionManager,this.settingsManager=e.settingsManager,this.agentCtx=e.agentCtx,this._scopedModels=e.scopedModels??[],this._resourceLoader=e.resourceLoader,this._theme=e.theme,this._bashRunner=new K({getCwd:n(()=>this._cwd,"getCwd"),getShellCommandPrefix:n(()=>this.settingsManager.getShellCommandPrefix(),"getShellCommandPrefix"),appendToAgent:n(t=>this.agent.appendMessage(t),"appendToAgent"),appendToSession:n(t=>this.sessionManager.appendMessage(t),"appendToSession"),isStreaming:n(()=>this.isStreaming,"isStreaming")}),this._staticCustomTools=e.customTools??[],this._mcpToolsFactory=e.mcpToolsFactory,this._soulManagerFactory=e.soulManagerFactory,this._customTools=[...this._staticCustomTools,...e.initialMcpTools??[]],this._initialActiveToolNames=e.initialActiveToolNames,this._toolOrchestrator=new O({customTools:this._customTools,initialActiveToolNames:this._initialActiveToolNames,getExtensionTools:n(()=>new Map((this._extensionRunner?.getAllRegisteredTools()??[]).map(t=>[t.definition.name,t.definition])),"getExtensionTools")}),this._toolRuntimeController=new z(this._toolOrchestrator),this._cwd=e.cwd,this._agentDir=e.agentDir,this._modelRegistry=e.modelRegistry,this._extensionRunnerRef=e.extensionRunnerRef,this._soulManager=e.soulManager,this._baseToolsOverride=e.baseToolsOverride,this._createSessionFactory=e.createSession,this._extensionEventBridge=new te({getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner")}),this._modelController=new q({getModel:n(()=>this.model,"getModel"),getThinkingLevel:n(()=>this.thinkingLevel,"getThinkingLevel"),getScopedModels:n(()=>this._scopedModels,"getScopedModels"),setAgentModel:n(t=>this.agent.setModel(t),"setAgentModel"),setAgentThinkingLevel:n(t=>this.agent.setThinkingLevel(t),"setAgentThinkingLevel"),setAgentLoopFramework:n(t=>this.agent.setAgentLoopFramework(t),"setAgentLoopFramework"),setLoopPolicy:n(t=>this.agent.setLoopPolicy(t),"setLoopPolicy"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getApiKeyForProvider:n(t=>this._modelRegistry.getApiKeyForProvider(t),"getApiKeyForProvider"),getAvailableModels:n(()=>this._modelRegistry.getAvailableAsync(),"getAvailableModels"),getAuthCredential:n(t=>this._modelRegistry.authStorage.get(t),"getAuthCredential"),appendModelChange:n((t,s)=>this.sessionManager.appendModelChange(t,s),"appendModelChange"),appendThinkingLevelChange:n(t=>this.sessionManager.appendThinkingLevelChange(t),"appendThinkingLevelChange"),setDefaultModelAndProvider:n((t,s)=>this.settingsManager.setDefaultModelAndProvider(t,s),"setDefaultModelAndProvider"),setDefaultThinkingLevel:n(t=>this.settingsManager.setDefaultThinkingLevel(t),"setDefaultThinkingLevel"),emitModelSelect:n(async({model:t,previousModel:s,source:o})=>{this._extensionRunner&&await this._extensionRunner.emit({type:"model_select",model:t,previousModel:s,source:o})},"emitModelSelect")}),this._compactionController=new Q({getModel:n(()=>this.model,"getModel"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),getBranch:n(()=>this.sessionManager.getBranch(),"getBranch"),getEntries:n(()=>this.sessionManager.getEntries(),"getEntries"),getCompactionSettings:n(()=>this.settingsManager.getCompactionSettings(),"getCompactionSettings"),appendCompaction:n((t,s,o,r,i)=>this.sessionManager.appendCompaction(t,s,o,r,i),"appendCompaction"),applyCompactedMessages:n(()=>{const t=this.sessionManager.buildSessionContext();return this.agent.replaceMessages(t.messages),t.messages},"applyCompactedMessages"),logInfo:n((t,s)=>this._logger.info(t,s),"logInfo"),disconnectFromAgent:n(()=>this._disconnectFromAgent(),"disconnectFromAgent"),reconnectToAgent:n(()=>this._reconnectToAgent(),"reconnectToAgent"),abortAgent:n(()=>this.abort(),"abortAgent"),emitAutoCompactionStart:n(t=>this._emit({type:"auto_compaction_start",reason:t}),"emitAutoCompactionStart"),emitAutoCompactionEnd:n(t=>this._emit({type:"auto_compaction_end",...t}),"emitAutoCompactionEnd"),getAutoCompactionEnabled:n(()=>this.settingsManager.getCompactionEnabled(),"getAutoCompactionEnabled"),setAutoCompactionEnabled:n(t=>this.settingsManager.setCompactionEnabled(t),"setAutoCompactionEnabled")}),this._sessionTreeController=new X({getModel:n(()=>this.model,"getModel"),getApiKey:n(t=>this._modelRegistry.getApiKey(t),"getApiKey"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),getLeafId:n(()=>this.sessionManager.getLeafId(),"getLeafId"),getEntry:n(t=>this.sessionManager.getEntry(t),"getEntry"),collectBranchSummaryEntries:n((t,s)=>N(this.sessionManager,t,s),"collectBranchSummaryEntries"),getBranchSummaryReserveTokens:n(()=>this.settingsManager.getBranchSummarySettings().reserveTokens,"getBranchSummaryReserveTokens"),branchWithSummary:n((t,s,o,r)=>this.sessionManager.branchWithSummary(t,s,o,r),"branchWithSummary"),appendLabelChange:n((t,s)=>this.sessionManager.appendLabelChange(t,s),"appendLabelChange"),resetLeaf:n(()=>this.sessionManager.resetLeaf(),"resetLeaf"),branch:n(t=>this.sessionManager.branch(t),"branch"),rebuildAgentMessages:n(()=>{const t=this.sessionManager.buildSessionContext();this.agent.replaceMessages(t.messages)},"rebuildAgentMessages"),extractUserMessageText:n(t=>this._extractUserMessageText(t),"extractUserMessageText")}),this._lifecycleController=new G({getSessionFile:n(()=>this.sessionManager.getSessionFile(),"getSessionFile"),getExtensionRunner:n(()=>this._extensionRunner,"getExtensionRunner"),disconnectFromAgent:n(()=>this._disconnectFromAgent(),"disconnectFromAgent"),reconnectToAgent:n(()=>this._reconnectToAgent(),"reconnectToAgent"),abortAgent:n(()=>this.abort(),"abortAgent"),resetAgent:n(()=>this.agent.reset(),"resetAgent"),syncAgentSessionId:n(()=>{this.agent.sessionId=this.sessionManager.getSessionId()},"syncAgentSessionId"),clearPendingQueues:n(()=>{this._steeringMessages=[],this._followUpMessages=[],this._pendingNextTurnMessages=[]},"clearPendingQueues"),clearPendingNextTurnMessages:n(()=>{this._pendingNextTurnMessages=[]},"clearPendingNextTurnMessages"),sessionNewSession:n(t=>this.sessionManager.newSession({parentSession:t}),"sessionNewSession"),sessionSetFile:n(t=>this.sessionManager.setSessionFile(t),"sessionSetFile"),sessionCreateBranchedSession:n(t=>this.sessionManager.createBranchedSession(t),"sessionCreateBranchedSession"),getEntry:n(t=>this.sessionManager.getEntry(t),"getEntry"),buildSessionContext:n(()=>this.sessionManager.buildSessionContext(),"buildSessionContext"),replaceAgentMessages:n(t=>this.agent.replaceMessages(t),"replaceAgentMessages"),appendThinkingLevelChange:n(t=>this.sessionManager.appendThinkingLevelChange(t),"appendThinkingLevelChange"),getThinkingLevel:n(()=>this.thinkingLevel,"getThinkingLevel"),getBranch:n(()=>this.sessionManager.getBranch(),"getBranch"),getDefaultThinkingLevel:n(()=>this.settingsManager.getDefaultThinkingLevel()??D,"getDefaultThinkingLevel"),getAvailableModels:n(()=>this._modelRegistry.getAvailable(),"getAvailableModels"),restoreModel:n(t=>this._modelController.restoreModel(t),"restoreModel"),restoreThinkingLevel:n(t=>this._modelController.restoreThinkingLevel(t),"restoreThinkingLevel"),runSetup:n(t=>t(this.sessionManager),"runSetup"),extractUserMessageText:n(t=>this._extractUserMessageText(t),"extractUserMessageText")}),this.agent.setModelErrorRecovery(t=>this._recoverModelErrorInLoop(t)),this._unsubscribeAgent=this.agent.subscribe(this._handleAgentEvent),e.signal){const t=n(()=>{this.abort()},"externalAbortHandler");e.signal.addEventListener("abort",t,{once:!0}),this._detachExternalAbort=()=>{e.signal?.removeEventListener("abort",t)}}this._buildRuntime({activeToolNames:this._initialActiveToolNames,includeAllExtensionTools:!0}),this._retryCoordinator=new oe(this._createRetryHost()),this._logger=ie({sessionId:this.sessionManager.getSessionId(),component:"agent-session"})}get modelRegistry(){return this._modelRegistry}get cwd(){return this._cwd}get agentDir(){return this._agentDir}getSlashCommands(){return ne({promptTemplates:this.promptTemplates,resourceLoader:this._resourceLoader,extensionRunner:this._extensionRunner},W)}async tryExecuteExtensionCommand(e){return this._tryExecuteExtensionCommand(e)}async executeSlashCommand(e){return e.startsWith("/")?this._slashCommandExecutor&&await this._slashCommandExecutor(e)?!0:this._tryExecuteExtensionCommand(e):!1}setSlashCommandExecutor(e){this._slashCommandExecutor=e}_emit(e){this._listeners.emit(e)}_lastAssistantMessage=void 0;_handleAgentEvent=n(async e=>{if(e.type==="message_start"&&e.message.role==="user"){const t=this._getUserMessageText(e.message);if(t){const s=this._steeringMessages.indexOf(t);if(s!==-1)this._steeringMessages.splice(s,1);else{const o=this._followUpMessages.indexOf(t);o!==-1&&this._followUpMessages.splice(o,1)}}}if(e.type==="message_update")this._emit(e),this._extensionEventBridge.emitExtensionEvent(e).catch(t=>{this._logger.error("[extension] message_update event error",{error:t})});else{const t=this._extensionEventBridge.emitExtensionEvent(e);this._emit(e),await t}if(e.type==="message_end"&&(e.message.role==="custom"?this.sessionManager.appendCustomMessageEntry(e.message.customType,e.message.content,e.message.display,e.message.details):(e.message.role==="user"||e.message.role==="assistant"||e.message.role==="toolResult")&&this.sessionManager.appendMessage(e.message),e.message.role==="assistant"&&(this._lastAssistantMessage=e.message,e.message.stopReason!=="error"&&this._retryCoordinator.onSuccess())),e.type==="agent_end"&&this._lastAssistantMessage){const t=this._lastAssistantMessage;if(this._lastAssistantMessage=void 0,this._retryCoordinator.isRetryableError(t)&&await this._retryCoordinator.handleError(t))return;if(await this._checkCompaction(t),this._soulManager){const s=t.stopReason==="error"?"failure":"success",o=this._cwd.split(/[/\\]/).pop()||"unknown",{tags:r,complexity:i,toolUsage:c}=S(this.state.messages,this._cwd),g=w(o,r,i,c),l=r[0]||o;(async()=>{try{await this._soulManager.recordInteraction(g,s,"turn"),await this._soulManager.updateExpertise(l,r,s==="success")}catch(m){this._logger.warn("[soul] recordInteraction/updateExpertise failed",{error:m})}})()}}e.type==="agent_end"&&this._extensionRunner&&this._extensionRunner.emit({type:"agent_end",messages:e.messages}).catch(t=>{this._logger.error("[extension] agent_end event error",{error:t})})},"_handleAgentEvent");_getUserMessageText(e){if(e.role!=="user")return"";const t=e.content;return typeof t=="string"?t:t.filter(o=>o.type==="text").map(o=>o.text).join("")}_findLastAssistantMessage(){const e=this.agent.state.messages;for(let t=e.length-1;t>=0;t--){const s=e[t];if(s.role==="assistant")return s}}subscribe(e){return this._listeners.add(e)}_disconnectFromAgent(){this._unsubscribeAgent&&(this._unsubscribeAgent(),this._unsubscribeAgent=void 0)}_reconnectToAgent(){this._unsubscribeAgent||(this._unsubscribeAgent=this.agent.subscribe(this._handleAgentEvent))}dispose(){this._disconnectFromAgent(),this._extensionRunner?.dispose(),this._listeners.clear(),this._detachExternalAbort&&(this._detachExternalAbort(),this._detachExternalAbort=void 0)}get state(){return this.agent.state}get model(){return this.agent.state.model}get thinkingLevel(){return this.agent.state.thinkingLevel}get agentLoopFramework(){return this.agent.agentLoopFramework}get isStreaming(){return this.agent.state.isStreaming}get systemPrompt(){return this.agent.state.systemPrompt}get soulManager(){return this._soulManager}get retryAttempt(){return this._retryCoordinator.attempt}getActiveToolNames(){return this.agent.state.tools.map(e=>e.name)}getAllTools(){return this._toolOrchestrator.getAllTools()}setActiveToolsByName(e){const{tools:t,validToolNames:s}=this._toolOrchestrator.setActiveToolsByName(e);this.agent.setTools(t),this._baseSystemPrompt=this._rebuildSystemPrompt(s),this.agent.setSystemPrompt(this._baseSystemPrompt)}get isCompacting(){return this._compactionController.isCompacting}get messages(){return this.agent.state.messages}get steeringMode(){return this.agent.getSteeringMode()}get followUpMode(){return this.agent.getFollowUpMode()}get sessionFile(){return this.sessionManager.getSessionFile()}get sessionId(){return this.sessionManager.getSessionId()}get sessionName(){return this.sessionManager.getSessionName()}get scopedModels(){return this._scopedModels}setScopedModels(e){this._scopedModels=e}get promptTemplates(){return this._resourceLoader.getPrompts().prompts}_rebuildSystemPrompt(e,t){return J({cwd:this._cwd,resourceLoader:this._resourceLoader,toolNames:e,baseToolRegistry:this._baseToolRegistry,soulInjection:t?.soulInjection??this._lastSoulInjection})}_getActiveBaseToolNames(){return Y(this.getActiveToolNames(),this._baseToolRegistry)}async _generateSoulInjection(){if(!this._soulManager){this._lastSoulInjection=void 0;return}try{const e=this._cwd.split(/[/\\]/).pop()||"unknown",{tags:t,complexity:s,toolUsage:o}=S(this.state.messages,this._cwd),r=await this._soulManager.generateInjection(w(e,t,s,o));return this._lastSoulInjection=typeof r=="string"&&r.trim().length>0?r:void 0,this._lastSoulInjection}catch(e){return this._emit({type:"sdk:error",source:"soul",error:e}),this._lastSoulInjection}}async prompt(e,t){const s=t?.expandPromptTemplates??!0;if(this._dbg(`prompt: "${e.slice(0,80)}" isStreaming=${this.isStreaming} hasModel=${!!this.model}`),s&&e.startsWith("/")){const u=await this.executeSlashCommand(e);if(this._dbg(`prompt: slash handled=${u}`),u)return}let o=e,r=t?.images;if(this._extensionRunner?.hasHandlers("input")){const u=await this._extensionRunner.emitInput(o,r,t?.source??"interactive");if(u.action==="handled")return;u.action==="transform"&&(o=u.text,r=u.images??r)}let i=o;if(s&&(i=this._expandSkillCommand(i),i=f(i,[...this.promptTemplates])),this.isStreaming){if(!t?.streamingBehavior)throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");t.streamingBehavior==="followUp"?await this._queueFollowUp(i,r):await this._queueSteer(i,r);return}if(this._bashRunner.flushPending(),!this.model)throw new Error(`No model selected.
3
3
 
4
4
  Use /login or set an API key environment variable. See ${_(C(),"providers.md")}
5
5
 
@@ -12,4 +12,4 @@ ${c}
12
12
  </skill>`;return o?`${g}
13
13
 
14
14
  ${o}`:g}catch(i){return this._extensionRunner?.emitError({extensionPath:r.filePath,event:"skill_expansion",error:i instanceof Error?i.message:String(i)}),e}}async steer(e,t){e.startsWith("/")&&this._throwIfExtensionCommand(e);let s=this._expandSkillCommand(e);s=f(s,[...this.promptTemplates]),await this._queueSteer(s,t)}async followUp(e,t){e.startsWith("/")&&this._throwIfExtensionCommand(e);let s=this._expandSkillCommand(e);s=f(s,[...this.promptTemplates]),await this._queueFollowUp(s,t)}async _queueSteer(e,t){this._steeringMessages.push(e);const s=[{type:"text",text:e}];t&&s.push(...t),this.agent.steer({role:"user",content:s,timestamp:Date.now()})}async _queueFollowUp(e,t){this._followUpMessages.push(e);const s=[{type:"text",text:e}];t&&s.push(...t),this.agent.followUp({role:"user",content:s,timestamp:Date.now()})}_throwIfExtensionCommand(e){if(!this._extensionRunner)return;const t=e.indexOf(" "),s=t===-1?e.slice(1):e.slice(1,t);if(this._extensionRunner.getCommand(s))throw new Error(`Extension command "/${s}" cannot be queued. Use prompt() or execute the command when not streaming.`)}async sendCustomMessage(e,t){const s={role:"custom",customType:e.customType,content:e.content,display:e.display,details:e.details,timestamp:Date.now()};t?.deliverAs==="nextTurn"?this._pendingNextTurnMessages.push(s):this.isStreaming?t?.deliverAs==="followUp"?this.agent.followUp(s):this.agent.steer(s):t?.triggerTurn?await this.agent.prompt(s):(this.agent.appendMessage(s),this.sessionManager.appendCustomMessageEntry(e.customType,e.content,e.display,e.details),this._emit({type:"message_start",message:s}),this._emit({type:"message_end",message:s}))}async sendUserMessage(e,t){let s,o;if(typeof e=="string")s=e;else{const r=[];o=[];for(const i of e)i.type==="text"?r.push(i.text):i.type==="image"&&o.push(i);s=r.join(`
15
- `),o.length===0&&(o=void 0)}await this.prompt(s,{expandPromptTemplates:!1,streamingBehavior:t?.deliverAs,images:o,source:"extension"})}clearQueue(){const e=[...this._steeringMessages],t=[...this._followUpMessages];return this._steeringMessages=[],this._followUpMessages=[],this.agent.clearAllQueues(),{steering:e,followUp:t}}get pendingMessageCount(){return this._steeringMessages.length+this._followUpMessages.length}getSteeringMessages(){return this._steeringMessages}getFollowUpMessages(){return this._followUpMessages}get resourceLoader(){return this._resourceLoader}async abort(){this.abortRetry(),this.agent.abort(),await this.agent.waitForIdle(),this._extensionRunner?.emit({type:"agent_abort"})}async newSession(e){return this._lifecycleController.newSession(e)}async setModel(e){await this._modelController.setModel(e)}async cycleModel(e="forward"){return this._modelController.cycleModel(e)}setThinkingLevel(e){this._modelController.setThinkingLevel(e)}setAgentLoopFramework(e){this._modelController.setAgentLoopFramework(e)}setLoopPolicy(e){this._modelController.setLoopPolicy(e)}cycleThinkingLevel(){return this._modelController.cycleThinkingLevel()}getAvailableThinkingLevels(){return this._modelController.getAvailableThinkingLevels()}supportsXhighThinking(){return this._modelController.supportsXhighThinking()}supportsThinking(){return this._modelController.supportsThinking()}setSteeringMode(e){this.agent.setSteeringMode(e),this.settingsManager.setSteeringMode(e)}setFollowUpMode(e){this.agent.setFollowUpMode(e),this.settingsManager.setFollowUpMode(e)}async compact(e){return this._compactionController.compact(e)}abortCompaction(){this._compactionController.abort()}abortBranchSummary(){this._sessionTreeController.abortBranchSummary()}async _checkCompaction(e,t=!0){const s=this.settingsManager.getCompactionSettings();if(!s.enabled||t&&e.stopReason==="aborted")return;const o=this.model?.contextWindow??0,r=this.model&&e.provider===this.model.provider&&e.model===this.model.id,i=y(this.sessionManager.getBranch()),c=i!==null&&e.timestamp<new Date(i.timestamp).getTime();if(r&&!c&&T(e,o)){const l=this.agent.state.messages;l.length>0&&l[l.length-1].role==="assistant"&&this.agent.replaceMessages(l.slice(0,-1)),await this._runAutoCompaction("overflow",!0);return}if(e.stopReason==="error")return;const g=b(e.usage);B(g,o,s)&&await this._runAutoCompaction("threshold",!1)}async _recoverModelErrorInLoop(e){const t=this.settingsManager.getCompactionSettings();if(e.message.role!=="assistant")return{action:"stop"};const s=e.message;if(e.errorSubtype!=="context_overflow"){if(!this._retryCoordinator.isRetryableError(s))return{action:"stop"};if(!await this._retryCoordinator.handleErrorInLoop(s))return{action:"stop"};const h=R(this.agent.state.messages,s);return this.agent.replaceMessages(h),{action:"retry",messages:h,transition:{reason:"model_error_recovery",subtype:e.errorSubtype,attempt:e.attempt}}}if(!t.enabled)return{action:"stop"};const o=this.model?.contextWindow??0;if(!(this.model&&s.provider===this.model.provider&&s.model===this.model.id)||!T(s,o))return{action:"stop"};const i=y(this.sessionManager.getBranch());if(i!==null&&s.timestamp<new Date(i.timestamp).getTime())return{action:"stop"};const g=this.agent.state.messages;this.agent.replaceMessages(R(g,s));const l=await this._runAutoCompaction("overflow",!0,{triggerContinue:!1});return l?{action:"retry",messages:l,transition:{reason:"model_error_recovery",subtype:e.errorSubtype,attempt:e.attempt}}:{action:"stop"}}async _runAutoCompaction(e,t,s){const o=s?.triggerContinue??!0,r=await this._compactionController.runAuto(e,t);if(r!==void 0){if(t&&o){const i=this.agent.state.messages,c=i[i.length-1];c?.role==="assistant"&&c.stopReason==="error"&&this.agent.replaceMessages(i.slice(0,-1)),setTimeout(()=>{this.agent.continue().catch(()=>{})},100)}else!t&&this.agent.hasQueuedMessages()&&setTimeout(()=>{this.agent.continue().catch(()=>{})},100);return r}}setAutoCompactionEnabled(e){this._compactionController.setAutoCompactionEnabled(e)}get autoCompactionEnabled(){return this._compactionController.autoCompactionEnabled}async bindExtensions(e){e.uiContext!==void 0&&(this._extensionUIContext=e.uiContext),e.commandContextActions!==void 0&&(this._extensionCommandContextActions=e.commandContextActions),e.shutdownHandler!==void 0&&(this._extensionShutdownHandler=e.shutdownHandler),e.onError!==void 0&&(this._extensionErrorListener=e.onError),this._extensionRunner&&(this._applyExtensionBindings(this._extensionRunner),await this._extensionRunner.emit({type:"session_start"}),await this.extendResourcesFromExtensions("startup"))}async extendResourcesFromExtensions(e){if(!this._extensionRunner?.hasHandlers("resources_discover"))return;const{skillPaths:t,promptPaths:s,themePaths:o}=await this._extensionRunner.emitResourcesDiscover(this._cwd,e);if(t.length===0&&s.length===0&&o.length===0)return;const r={skillPaths:this.buildExtensionResourcePaths(t),promptPaths:this.buildExtensionResourcePaths(s),themePaths:this.buildExtensionResourcePaths(o)};this._resourceLoader.extendResources(r),this._baseSystemPrompt=this._rebuildSystemPrompt(this.getActiveToolNames()),this.agent.setSystemPrompt(this._baseSystemPrompt)}buildExtensionResourcePaths(e){return e.map(t=>{const s=this.getExtensionSourceLabel(t.extensionPath),o=t.extensionPath.startsWith("<")?void 0:P(t.extensionPath);return{path:t.path,metadata:{source:s,scope:"temporary",origin:"top-level",baseDir:o}}})}getExtensionSourceLabel(e){return e.startsWith("<")?`extension:${e.replace(/[<>]/g,"")}`:`extension:${L(e).replace(/\.(ts|js)$/,"")}`}_applyExtensionBindings(e){e.setUIContext(this._extensionUIContext),e.bindCommandContext(this._extensionCommandContextActions),this._extensionErrorUnsubscriber?.(),this._extensionErrorUnsubscriber=this._extensionErrorListener?e.onError(this._extensionErrorListener):void 0}_bindExtensionCore(e){const t=this;se(e,{promptTemplates:this.promptTemplates,resourceLoader:this._resourceLoader,modelRegistry:this.modelRegistry,sessionManager:this.sessionManager,settingsManager:this.settingsManager,shutdownHandler:this._extensionShutdownHandler,soulManager:this._soulManager,get model(){return t.model},get thinkingLevel(){return t.thinkingLevel},get isStreaming(){return t.isStreaming},get pendingMessageCount(){return t.pendingMessageCount},get systemPrompt(){return t.systemPrompt},sendCustomMessage:n((s,o)=>this.sendCustomMessage(s,o),"sendCustomMessage"),sendUserMessage:n((s,o)=>this.sendUserMessage(s,o),"sendUserMessage"),executeSlashCommand:n(s=>this.executeSlashCommand(s),"executeSlashCommand"),getActiveToolNames:n(()=>this.getActiveToolNames(),"getActiveToolNames"),getAllTools:n(()=>this.getAllTools(),"getAllTools"),setActiveToolsByName:n(s=>this.setActiveToolsByName(s),"setActiveToolsByName"),setModel:n(s=>this.setModel(s),"setModel"),setThinkingLevel:n(s=>this.setThinkingLevel(s),"setThinkingLevel"),abort:n(()=>this.abort(),"abort"),getContextUsage:n(()=>this.getContextUsage(),"getContextUsage"),compact:n(s=>this.compact(s),"compact")})}_buildRuntime(e){const t=this._baseToolsOverride?this._baseToolsOverride:H(this._cwd,this.settingsManager);this._baseToolRegistry=new Map(Object.entries(t).map(([m,h])=>[m,h]));const s=this._resourceLoader.getExtensions();if(e.flagValues)for(const[m,h]of e.flagValues)s.runtime.flagValues.set(m,h);const o=s.extensions.length>0,r=this._customTools.length>0;this._extensionRunner=o||r?new j(s.extensions,s.runtime,this._cwd,this._agentDir,this.sessionManager,this._modelRegistry):void 0,this._extensionRunnerRef&&(this._extensionRunnerRef.current=this._extensionRunner),this._extensionRunner&&(this._bindExtensionCore(this._extensionRunner),this._applyExtensionBindings(this._extensionRunner),this._extensionRunner.setTelemetrySink($({workspaceRoot:this._cwd})));const i=this._toolRuntimeController.build({baseTools:this._baseToolRegistry,baseToolsOverride:this._baseToolsOverride,customTools:this._customTools,activeToolNames:e.activeToolNames,includeAllExtensionTools:e.includeAllExtensionTools,extensionRunner:this._extensionRunner}),c=n(m=>{const h=me(m);h&&this._emit(h)},"onSubAgentEvent");this._agentTool=re({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory,onSubAgentEvent:c}),i.activeTools.push(this._agentTool),this._toolOrchestrator.registerTool(x,this._agentTool);const g=ae({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory,onSubAgentEvent:c});i.activeTools.push(g),this._toolOrchestrator.registerTool(he,g);const l=le({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory});i.activeTools.push(l),this._toolOrchestrator.registerTool(M,l),i.systemPromptToolNames.includes(x)||i.systemPromptToolNames.push(x),i.systemPromptToolNames.includes(M)||i.systemPromptToolNames.push(M),this.agent.setTools(i.activeTools),this._baseSystemPrompt=this._rebuildSystemPrompt(i.systemPromptToolNames),this.agent.setSystemPrompt(this._baseSystemPrompt)}async _refreshMcpTools(){if(!this._mcpToolsFactory)return 0;try{const e=await this._mcpToolsFactory();return this._customTools=[...this._staticCustomTools,...e],e.length}catch(e){this._emit({type:"sdk:error",source:"mcp",error:e});const t=this._customTools.filter(s=>s.name.startsWith("mcp_"));return this._customTools=[...this._staticCustomTools,...t],t.length}}async warmupMcpTools(){if(this._mcpToolsFactory)try{const e=await this._refreshMcpTools();this._buildRuntime({activeToolNames:this.getActiveToolNames(),flagValues:this._extensionRunner?.getFlagValues(),includeAllExtensionTools:!0}),this._emit({type:"sdk:mcp_ready",toolCount:e})}catch(e){this._emit({type:"sdk:error",source:"mcp",error:e})}}async reload(){const e=this._extensionRunner?.getFlagValues();if(await this._extensionRunner?.emit({type:"session_shutdown"}),this.settingsManager.reload(),I(),await this._resourceLoader.reload(),await this._refreshMcpTools(),this._soulManagerFactory)try{this._soulManager=await this._soulManagerFactory(),this._lastSoulInjection=void 0}catch(s){this._emit({type:"sdk:error",source:"soul",error:s})}this._buildRuntime({activeToolNames:this.getActiveToolNames(),flagValues:e,includeAllExtensionTools:!0});const t=this._extensionUIContext||this._extensionCommandContextActions||this._extensionShutdownHandler||this._extensionErrorListener;this._extensionRunner&&t&&(await this._extensionRunner.emit({type:"session_start"}),await this.extendResourcesFromExtensions("reload"))}_createRetryHost(){return{getContextWindow:n(()=>this.model?.contextWindow??0,"getContextWindow"),getRetrySettings:n(()=>this.settingsManager.getRetrySettings(),"getRetrySettings"),removeLastAssistantMessage:n(()=>{const e=this.agent.state.messages;e.length>0&&e[e.length-1].role==="assistant"&&this.agent.replaceMessages(e.slice(0,-1))},"removeLastAssistantMessage"),triggerContinue:n(()=>{setTimeout(()=>{this.agent.continue().catch(()=>{})},0)},"triggerContinue"),emitEvent:n(e=>{this._emit(e)},"emitEvent")}}abortRetry(){this._retryCoordinator.abort()}async waitForRetry(){await this._retryCoordinator.waitForCompletion()}get isRetrying(){return this._retryCoordinator.isActive}get autoRetryEnabled(){return this.settingsManager.getRetryEnabled()}setAutoRetryEnabled(e){this.settingsManager.setRetryEnabled(e)}async executeBash(e,t,s){return this._bashRunner.execute(e,t,s)}recordBashResult(e,t,s){this._bashRunner.recordResult(e,t,s)}abortBash(){this._bashRunner.abort()}get isBashRunning(){return this._bashRunner.isRunning}get hasPendingBashMessages(){return this._bashRunner.hasPending}async switchSession(e){return this._lifecycleController.switchSession(e)}setSessionName(e){this.sessionManager.appendSessionInfo(e)}async fork(e){return this._lifecycleController.fork(e)}async navigateTree(e,t={}){return this._sessionTreeController.navigateTree(e,t)}getUserMessagesForForking(){const e=this.sessionManager.getEntries(),t=[];for(const s of e){if(s.type!=="message"||s.message.role!=="user")continue;const o=this._extractUserMessageText(s.message.content);o&&t.push({entryId:s.id,text:o})}return t}_extractUserMessageText(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(t=>t.type==="text").map(t=>t.text).join(""):""}getSessionStats(){const e=this.state,t=e.messages.filter(h=>h.role==="user").length,s=e.messages.filter(h=>h.role==="assistant").length,o=e.messages.filter(h=>h.role==="toolResult").length;let r=0,i=0,c=0,g=0,l=0,m=0;for(const h of e.messages)if(h.role==="assistant"){const d=h;r+=d.content.filter(u=>u.type==="toolCall").length,i+=d.usage.input,c+=d.usage.output,g+=d.usage.cacheRead,l+=d.usage.cacheWrite,m+=d.usage.cost.total}return{sessionFile:this.sessionFile,sessionId:this.sessionId,userMessages:t,assistantMessages:s,toolCalls:r,toolResults:o,totalMessages:e.messages.length,tokens:{input:i,output:c,cacheRead:g,cacheWrite:l,total:i+c+g+l},cost:m}}getContextUsage(){const e=this.model;if(!e)return;const t=e.contextWindow??0;if(t<=0)return;const s=this.sessionManager.getBranch(),o=y(s);if(o){const c=s.lastIndexOf(o);let g=!1;for(let l=s.length-1;l>c;l--){const m=s[l];if(m.type==="message"&&m.message.role==="assistant"){const h=m.message;if(h.stopReason!=="aborted"&&h.stopReason!=="error"){b(h.usage)>0&&(g=!0);break}}}if(!g)return{tokens:null,contextWindow:t,percent:null}}const r=U(this.messages),i=r.tokens/t*100;return{tokens:r.tokens,contextWindow:t,percent:i}}async exportToHtml(e){return await Z({sessionManager:this.sessionManager,state:this.state,outputPath:e,themeName:this.settingsManager.getTheme(),extensionRunner:this._extensionRunner,theme:this._theme})}getLastAssistantText(){return ee(this.messages)}hasExtensionHandlers(e){return this._extensionRunner?.hasHandlers(e)??!1}get extensionRunner(){return this._extensionRunner}}export{Ge as AgentSession,ze as CycleModelError,qe as parseSkillBlock,R as pruneRecoverableErrorTail};
15
+ `),o.length===0&&(o=void 0)}await this.prompt(s,{expandPromptTemplates:!1,streamingBehavior:t?.deliverAs,images:o,source:"extension"})}clearQueue(){const e=[...this._steeringMessages],t=[...this._followUpMessages];return this._steeringMessages=[],this._followUpMessages=[],this.agent.clearAllQueues(),{steering:e,followUp:t}}get pendingMessageCount(){return this._steeringMessages.length+this._followUpMessages.length}getSteeringMessages(){return this._steeringMessages}getFollowUpMessages(){return this._followUpMessages}get resourceLoader(){return this._resourceLoader}async abort(){this.abortRetry(),this.agent.abort(),await this.agent.waitForIdle(),this._extensionRunner?.emit({type:"agent_abort"})}async newSession(e){return this._lifecycleController.newSession(e)}async setModel(e){await this._modelController.setModel(e)}async cycleModel(e="forward"){return this._modelController.cycleModel(e)}setThinkingLevel(e){this._modelController.setThinkingLevel(e)}setAgentLoopFramework(e){this._modelController.setAgentLoopFramework(e)}setLoopPolicy(e){this._modelController.setLoopPolicy(e)}cycleThinkingLevel(){return this._modelController.cycleThinkingLevel()}getAvailableThinkingLevels(){return this._modelController.getAvailableThinkingLevels()}supportsXhighThinking(){return this._modelController.supportsXhighThinking()}supportsThinking(){return this._modelController.supportsThinking()}setSteeringMode(e){this.agent.setSteeringMode(e),this.settingsManager.setSteeringMode(e)}setFollowUpMode(e){this.agent.setFollowUpMode(e),this.settingsManager.setFollowUpMode(e)}async compact(e){return this._compactionController.compact(e)}abortCompaction(){this._compactionController.abort()}abortBranchSummary(){this._sessionTreeController.abortBranchSummary()}async _checkCompaction(e,t=!0){const s=this.settingsManager.getCompactionSettings();if(!s.enabled||t&&e.stopReason==="aborted")return;const o=this.model?.contextWindow??0,r=this.model&&e.provider===this.model.provider&&e.model===this.model.id,i=y(this.sessionManager.getBranch()),c=i!==null&&e.timestamp<new Date(i.timestamp).getTime();if(r&&!c&&T(e,o)){const l=this.agent.state.messages;l.length>0&&l[l.length-1].role==="assistant"&&this.agent.replaceMessages(l.slice(0,-1)),await this._runAutoCompaction("overflow",!0);return}if(e.stopReason==="error")return;const g=b(e.usage);B(g,o,s)&&await this._runAutoCompaction("threshold",!1)}async _recoverModelErrorInLoop(e){const t=this.settingsManager.getCompactionSettings();if(e.message.role!=="assistant")return{action:"stop"};const s=e.message;if(e.errorSubtype!=="context_overflow"){if(!this._retryCoordinator.isRetryableError(s))return{action:"stop"};if(!await this._retryCoordinator.handleErrorInLoop(s))return{action:"stop"};const h=R(this.agent.state.messages,s);return this.agent.replaceMessages(h),{action:"retry",messages:h,transition:{reason:"model_error_recovery",subtype:e.errorSubtype,attempt:e.attempt}}}if(!t.enabled)return{action:"stop"};const o=this.model?.contextWindow??0;if(!(this.model&&s.provider===this.model.provider&&s.model===this.model.id)||!T(s,o))return{action:"stop"};const i=y(this.sessionManager.getBranch());if(i!==null&&s.timestamp<new Date(i.timestamp).getTime())return{action:"stop"};const g=this.agent.state.messages;this.agent.replaceMessages(R(g,s));const l=await this._runAutoCompaction("overflow",!0,{triggerContinue:!1});return l?{action:"retry",messages:l,transition:{reason:"model_error_recovery",subtype:e.errorSubtype,attempt:e.attempt}}:{action:"stop"}}async _runAutoCompaction(e,t,s){const o=s?.triggerContinue??!0,r=await this._compactionController.runAuto(e,t);if(r!==void 0){if(t&&o){const i=this.agent.state.messages,c=i[i.length-1];c?.role==="assistant"&&c.stopReason==="error"&&this.agent.replaceMessages(i.slice(0,-1)),setTimeout(()=>{this.agent.continue().catch(()=>{})},100)}else!t&&this.agent.hasQueuedMessages()&&setTimeout(()=>{this.agent.continue().catch(()=>{})},100);return r}}setAutoCompactionEnabled(e){this._compactionController.setAutoCompactionEnabled(e)}get autoCompactionEnabled(){return this._compactionController.autoCompactionEnabled}async bindExtensions(e){e.uiContext!==void 0&&(this._extensionUIContext=e.uiContext),e.commandContextActions!==void 0&&(this._extensionCommandContextActions=e.commandContextActions),e.shutdownHandler!==void 0&&(this._extensionShutdownHandler=e.shutdownHandler),e.onError!==void 0&&(this._extensionErrorListener=e.onError),this._extensionRunner&&(this._applyExtensionBindings(this._extensionRunner),await this._extensionRunner.emit({type:"session_start"}),await this.extendResourcesFromExtensions("startup"))}async extendResourcesFromExtensions(e){if(!this._extensionRunner?.hasHandlers("resources_discover"))return;const{skillPaths:t,promptPaths:s,themePaths:o}=await this._extensionRunner.emitResourcesDiscover(this._cwd,e);if(t.length===0&&s.length===0&&o.length===0)return;const r={skillPaths:this.buildExtensionResourcePaths(t),promptPaths:this.buildExtensionResourcePaths(s),themePaths:this.buildExtensionResourcePaths(o)};this._resourceLoader.extendResources(r),this._baseSystemPrompt=this._rebuildSystemPrompt(this.getActiveToolNames()),this.agent.setSystemPrompt(this._baseSystemPrompt)}buildExtensionResourcePaths(e){return e.map(t=>{const s=this.getExtensionSourceLabel(t.extensionPath),o=t.extensionPath.startsWith("<")?void 0:P(t.extensionPath);return{path:t.path,metadata:{source:s,scope:"temporary",origin:"top-level",baseDir:o}}})}getExtensionSourceLabel(e){return e.startsWith("<")?`extension:${e.replace(/[<>]/g,"")}`:`extension:${L(e).replace(/\.(ts|js)$/,"")}`}_applyExtensionBindings(e){e.setUIContext(this._extensionUIContext),e.bindCommandContext(this._extensionCommandContextActions),this._extensionErrorUnsubscriber?.(),this._extensionErrorUnsubscriber=this._extensionErrorListener?e.onError(this._extensionErrorListener):void 0}_bindExtensionCore(e){const t=this;se(e,{promptTemplates:this.promptTemplates,resourceLoader:this._resourceLoader,modelRegistry:this.modelRegistry,sessionManager:this.sessionManager,settingsManager:this.settingsManager,shutdownHandler:this._extensionShutdownHandler,soulManager:this._soulManager,get model(){return t.model},get thinkingLevel(){return t.thinkingLevel},get isStreaming(){return t.isStreaming},get pendingMessageCount(){return t.pendingMessageCount},get systemPrompt(){return t.systemPrompt},sendCustomMessage:n((s,o)=>this.sendCustomMessage(s,o),"sendCustomMessage"),sendUserMessage:n((s,o)=>this.sendUserMessage(s,o),"sendUserMessage"),executeSlashCommand:n(s=>this.executeSlashCommand(s),"executeSlashCommand"),getActiveToolNames:n(()=>this.getActiveToolNames(),"getActiveToolNames"),getAllTools:n(()=>this.getAllTools(),"getAllTools"),setActiveToolsByName:n(s=>this.setActiveToolsByName(s),"setActiveToolsByName"),setModel:n(s=>this.setModel(s),"setModel"),setThinkingLevel:n(s=>this.setThinkingLevel(s),"setThinkingLevel"),abort:n(()=>this.abort(),"abort"),clearFollowUpQueue:n(()=>{this.agent.clearFollowUpQueue(),this._followUpMessages=[]},"clearFollowUpQueue"),getContextUsage:n(()=>this.getContextUsage(),"getContextUsage"),compact:n(s=>this.compact(s),"compact")})}_buildRuntime(e){const t=this._baseToolsOverride?this._baseToolsOverride:H(this._cwd,this.settingsManager);this._baseToolRegistry=new Map(Object.entries(t).map(([m,h])=>[m,h]));const s=this._resourceLoader.getExtensions();if(e.flagValues)for(const[m,h]of e.flagValues)s.runtime.flagValues.set(m,h);const o=s.extensions.length>0,r=this._customTools.length>0;this._extensionRunner=o||r?new j(s.extensions,s.runtime,this._cwd,this._agentDir,this.sessionManager,this._modelRegistry):void 0,this._extensionRunnerRef&&(this._extensionRunnerRef.current=this._extensionRunner),this._extensionRunner&&(this._bindExtensionCore(this._extensionRunner),this._applyExtensionBindings(this._extensionRunner),this._extensionRunner.setTelemetrySink($({workspaceRoot:this._cwd})));const i=this._toolRuntimeController.build({baseTools:this._baseToolRegistry,baseToolsOverride:this._baseToolsOverride,customTools:this._customTools,activeToolNames:e.activeToolNames,includeAllExtensionTools:e.includeAllExtensionTools,extensionRunner:this._extensionRunner}),c=n(m=>{const h=me(m);h&&this._emit(h)},"onSubAgentEvent");this._agentTool=re({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory,onSubAgentEvent:c}),i.activeTools.push(this._agentTool),this._toolOrchestrator.registerTool(x,this._agentTool);const g=ae({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory,onSubAgentEvent:c});i.activeTools.push(g),this._toolOrchestrator.registerTool(he,g);const l=le({parentSession:this,parentPermissionMode:"default",parentModel:this.model,createSession:this._createSessionFactory});i.activeTools.push(l),this._toolOrchestrator.registerTool(M,l),i.systemPromptToolNames.includes(x)||i.systemPromptToolNames.push(x),i.systemPromptToolNames.includes(M)||i.systemPromptToolNames.push(M),this.agent.setTools(i.activeTools),this._baseSystemPrompt=this._rebuildSystemPrompt(i.systemPromptToolNames),this.agent.setSystemPrompt(this._baseSystemPrompt)}async _refreshMcpTools(){if(!this._mcpToolsFactory)return 0;try{const e=await this._mcpToolsFactory();return this._customTools=[...this._staticCustomTools,...e],e.length}catch(e){this._emit({type:"sdk:error",source:"mcp",error:e});const t=this._customTools.filter(s=>s.name.startsWith("mcp_"));return this._customTools=[...this._staticCustomTools,...t],t.length}}async warmupMcpTools(){if(this._mcpToolsFactory)try{const e=await this._refreshMcpTools();this._buildRuntime({activeToolNames:this.getActiveToolNames(),flagValues:this._extensionRunner?.getFlagValues(),includeAllExtensionTools:!0}),this._emit({type:"sdk:mcp_ready",toolCount:e})}catch(e){this._emit({type:"sdk:error",source:"mcp",error:e})}}async reload(){const e=this._extensionRunner?.getFlagValues();if(await this._extensionRunner?.emit({type:"session_shutdown"}),this.settingsManager.reload(),I(),await this._resourceLoader.reload(),await this._refreshMcpTools(),this._soulManagerFactory)try{this._soulManager=await this._soulManagerFactory(),this._lastSoulInjection=void 0}catch(s){this._emit({type:"sdk:error",source:"soul",error:s})}this._buildRuntime({activeToolNames:this.getActiveToolNames(),flagValues:e,includeAllExtensionTools:!0});const t=this._extensionUIContext||this._extensionCommandContextActions||this._extensionShutdownHandler||this._extensionErrorListener;this._extensionRunner&&t&&(await this._extensionRunner.emit({type:"session_start"}),await this.extendResourcesFromExtensions("reload"))}_createRetryHost(){return{getContextWindow:n(()=>this.model?.contextWindow??0,"getContextWindow"),getRetrySettings:n(()=>this.settingsManager.getRetrySettings(),"getRetrySettings"),removeLastAssistantMessage:n(()=>{const e=this.agent.state.messages;e.length>0&&e[e.length-1].role==="assistant"&&this.agent.replaceMessages(e.slice(0,-1))},"removeLastAssistantMessage"),triggerContinue:n(()=>{setTimeout(()=>{this.agent.continue().catch(()=>{})},0)},"triggerContinue"),emitEvent:n(e=>{this._emit(e)},"emitEvent")}}abortRetry(){this._retryCoordinator.abort()}async waitForRetry(){await this._retryCoordinator.waitForCompletion()}get isRetrying(){return this._retryCoordinator.isActive}get autoRetryEnabled(){return this.settingsManager.getRetryEnabled()}setAutoRetryEnabled(e){this.settingsManager.setRetryEnabled(e)}async executeBash(e,t,s){return this._bashRunner.execute(e,t,s)}recordBashResult(e,t,s){this._bashRunner.recordResult(e,t,s)}abortBash(){this._bashRunner.abort()}get isBashRunning(){return this._bashRunner.isRunning}get hasPendingBashMessages(){return this._bashRunner.hasPending}async switchSession(e){return this._lifecycleController.switchSession(e)}setSessionName(e){this.sessionManager.appendSessionInfo(e)}async fork(e){return this._lifecycleController.fork(e)}async navigateTree(e,t={}){return this._sessionTreeController.navigateTree(e,t)}getUserMessagesForForking(){const e=this.sessionManager.getEntries(),t=[];for(const s of e){if(s.type!=="message"||s.message.role!=="user")continue;const o=this._extractUserMessageText(s.message.content);o&&t.push({entryId:s.id,text:o})}return t}_extractUserMessageText(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(t=>t.type==="text").map(t=>t.text).join(""):""}getSessionStats(){const e=this.state,t=e.messages.filter(h=>h.role==="user").length,s=e.messages.filter(h=>h.role==="assistant").length,o=e.messages.filter(h=>h.role==="toolResult").length;let r=0,i=0,c=0,g=0,l=0,m=0;for(const h of e.messages)if(h.role==="assistant"){const d=h;r+=d.content.filter(u=>u.type==="toolCall").length,i+=d.usage.input,c+=d.usage.output,g+=d.usage.cacheRead,l+=d.usage.cacheWrite,m+=d.usage.cost.total}return{sessionFile:this.sessionFile,sessionId:this.sessionId,userMessages:t,assistantMessages:s,toolCalls:r,toolResults:o,totalMessages:e.messages.length,tokens:{input:i,output:c,cacheRead:g,cacheWrite:l,total:i+c+g+l},cost:m}}getContextUsage(){const e=this.model;if(!e)return;const t=e.contextWindow??0;if(t<=0)return;const s=this.sessionManager.getBranch(),o=y(s);if(o){const c=s.lastIndexOf(o);let g=!1;for(let l=s.length-1;l>c;l--){const m=s[l];if(m.type==="message"&&m.message.role==="assistant"){const h=m.message;if(h.stopReason!=="aborted"&&h.stopReason!=="error"){b(h.usage)>0&&(g=!0);break}}}if(!g)return{tokens:null,contextWindow:t,percent:null}}const r=U(this.messages),i=r.tokens/t*100;return{tokens:r.tokens,contextWindow:t,percent:i}}async exportToHtml(e){return await Z({sessionManager:this.sessionManager,state:this.state,outputPath:e,themeName:this.settingsManager.getTheme(),extensionRunner:this._extensionRunner,theme:this._theme})}getLastAssistantText(){return ee(this.messages)}hasExtensionHandlers(e){return this._extensionRunner?.hasHandlers(e)??!1}get extensionRunner(){return this._extensionRunner}}export{Qe as AgentSession,ze as CycleModelError,qe as parseSkillBlock,R as pruneRecoverableErrorTail};
@@ -38,6 +38,7 @@ export interface ExtensionCoreBindingHost {
38
38
  setModel(model: Model<any>): Promise<void>;
39
39
  setThinkingLevel(level: ThinkingLevel): void;
40
40
  abort(): Promise<void> | void;
41
+ clearFollowUpQueue(): void;
41
42
  getContextUsage(): ContextUsage | undefined;
42
43
  compact(customInstructions?: string): Promise<CompactionResult>;
43
44
  }
@@ -1,3 +1,3 @@
1
- var E=Object.defineProperty;var t=(n,e)=>E(n,"name",{value:e,configurable:!0});import{completeSimple as S}from"@pencil-agent/ai/stream";import{getExtCallerContext as T}from"../platform/telemetry/index.js";import{buildExtensionSlashCommands as A}from"./slash-command-catalog.js";function I(n,e){switch(n.api){case"openai-completions":return{type:"function",function:{name:e}};case"anthropic-messages":case"bedrock-converse-stream":return{type:"tool",name:e};case"google-generative-ai":case"google-gemini-cli":case"google-vertex":return"any";default:return"required"}}t(I,"getStructuredToolChoice");function L(n){return n.type==="text"}t(L,"isTextContent");function N(n,e){return n.type==="toolCall"&&"name"in n&&n.name===e}t(N,"isNamedToolCall");function v(n){const e=T();return{extensionName:e?.extensionName??"unknown",callerContext:e?.callerContext??"unknown",isUserInitiated:e?.isUserInitiated??!1,modelId:n.model?.id??null,tokensIn:n.usage?.input??null,tokensOut:n.usage?.output??null,costTotal:n.usage?.cost?.total??null,durationMs:Math.round(performance.now()-n.startPerf),ok:n.ok,errorCode:n.errorCode,startedAt:n.startedAt,endedAt:new Date,sessionId:e?.sessionId??n.host.sessionManager.getSessionId(),runId:e?.runId??null,variant:e?.variant??null}}t(v,"buildLlmCallEvent");async function P(n,e,r,o){return(await M(n,e,r,o))?.text}t(P,"completeTextWithCurrentModel");async function M(n,e,r,o){const a=e.model;if(!a)return;const s=await e.modelRegistry.getApiKey(a);if(!s)return;const c=new Date,d=performance.now();let i=!0,g=null,m,u;try{const l=await S(a,{systemPrompt:r,messages:[{role:"user",content:o,timestamp:Date.now()}]},{maxTokens:1500,temperature:.2,apiKey:s});m=l.usage,u=l.content?.filter(L).map(p=>p.text??"").join("")??""}catch(l){i=!1,g=l instanceof Error?l.constructor.name:"unknown"}if(n.writeLlmCallEvent(v({host:e,model:a,startedAt:c,startPerf:d,ok:i,errorCode:g,usage:m})),!(!i||u===void 0||m===void 0))return{text:u,usage:m}}t(M,"completeTextWithUsage");async function b(n,e,r,o,a,s){const c=e.model;if(!c)return;const d=await e.modelRegistry.getApiKey(c);if(!d)return;const i=s?.toolName||"submit_json",g=new Date,m=performance.now();let u=!0,l=null,p,x;try{const f=a,k={maxTokens:1500,temperature:0,apiKey:d,toolChoice:I(c,i)},w=await S(c,{systemPrompt:`${r}
1
+ var E=Object.defineProperty;var t=(n,e)=>E(n,"name",{value:e,configurable:!0});import{completeSimple as S}from"@pencil-agent/ai/stream";import{getExtCallerContext as T}from"../platform/telemetry/index.js";import{buildExtensionSlashCommands as A}from"./slash-command-catalog.js";function I(n,e){switch(n.api){case"openai-completions":return{type:"function",function:{name:e}};case"anthropic-messages":case"bedrock-converse-stream":return{type:"tool",name:e};case"google-generative-ai":case"google-gemini-cli":case"google-vertex":return"any";default:return"required"}}t(I,"getStructuredToolChoice");function L(n){return n.type==="text"}t(L,"isTextContent");function N(n,e){return n.type==="toolCall"&&"name"in n&&n.name===e}t(N,"isNamedToolCall");function v(n){const e=T();return{extensionName:e?.extensionName??"unknown",callerContext:e?.callerContext??"unknown",isUserInitiated:e?.isUserInitiated??!1,modelId:n.model?.id??null,tokensIn:n.usage?.input??null,tokensOut:n.usage?.output??null,costTotal:n.usage?.cost?.total??null,durationMs:Math.round(performance.now()-n.startPerf),ok:n.ok,errorCode:n.errorCode,startedAt:n.startedAt,endedAt:new Date,sessionId:e?.sessionId??n.host.sessionManager.getSessionId(),runId:e?.runId??null,variant:e?.variant??null}}t(v,"buildLlmCallEvent");async function P(n,e,o,r){return(await M(n,e,o,r))?.text}t(P,"completeTextWithCurrentModel");async function M(n,e,o,r){const a=e.model;if(!a)return;const s=await e.modelRegistry.getApiKey(a);if(!s)return;const c=new Date,d=performance.now();let i=!0,g=null,m,u;try{const l=await S(a,{systemPrompt:o,messages:[{role:"user",content:r,timestamp:Date.now()}]},{maxTokens:1500,temperature:.2,apiKey:s});m=l.usage,u=l.content?.filter(L).map(p=>p.text??"").join("")??""}catch(l){i=!1,g=l instanceof Error?l.constructor.name:"unknown"}if(n.writeLlmCallEvent(v({host:e,model:a,startedAt:c,startPerf:d,ok:i,errorCode:g,usage:m})),!(!i||u===void 0||m===void 0))return{text:u,usage:m}}t(M,"completeTextWithUsage");async function U(n,e,o,r,a,s){const c=e.model;if(!c)return;const d=await e.modelRegistry.getApiKey(c);if(!d)return;const i=s?.toolName||"submit_json",g=new Date,m=performance.now();let u=!0,l=null,p,w;try{const f=a,k={maxTokens:1500,temperature:0,apiKey:d,toolChoice:I(c,i)},x=await S(c,{systemPrompt:`${o}
2
2
 
3
- You must call the ${i} tool exactly once with the final structured JSON payload. Do not answer in prose.`,messages:[{role:"user",content:o,timestamp:Date.now()}],tools:[{name:i,description:"Submit the final structured JSON payload.",parameters:f}]},k);p=w.usage;const y=w.content?.find(C=>N(C,i));if(y){const C=s?.resultKey?y.arguments?.[s.resultKey]:y.arguments;x=JSON.stringify(C)}}catch(f){u=!1,l=f instanceof Error?f.constructor.name:"unknown"}if(n.writeLlmCallEvent(v({host:e,model:c,startedAt:g,startPerf:m,ok:u,errorCode:l,usage:p})),!!u)return x}t(b,"completeJsonWithCurrentModel");function O(n,e){n.bindCore({sendMessage:t((r,o)=>{e.sendCustomMessage(r,o).catch(a=>{n.emitError({extensionPath:"<runtime>",event:"send_message",error:a instanceof Error?a.message:String(a)})})},"sendMessage"),sendUserMessage:t((r,o)=>{e.sendUserMessage(r,o).catch(a=>{n.emitError({extensionPath:"<runtime>",event:"send_user_message",error:a instanceof Error?a.message:String(a)})})},"sendUserMessage"),executeCommand:t(async r=>{try{return await e.executeSlashCommand(r)}catch(o){return n.emitError({extensionPath:"<runtime>",event:"execute_command",error:o instanceof Error?o.message:String(o)}),!1}},"executeCommand"),appendEntry:t((r,o)=>{e.sessionManager.appendCustomEntry(r,o)},"appendEntry"),setSessionName:t(r=>{e.sessionManager.appendSessionInfo(r)},"setSessionName"),getSessionName:t(()=>e.sessionManager.getSessionName(),"getSessionName"),setLabel:t((r,o)=>{e.sessionManager.appendLabelChange(r,o)},"setLabel"),getActiveTools:t(()=>e.getActiveToolNames(),"getActiveTools"),getAllTools:t(()=>e.getAllTools(),"getAllTools"),setActiveTools:t(r=>e.setActiveToolsByName(r),"setActiveTools"),getCommands:t(()=>A({promptTemplates:e.promptTemplates,resourceLoader:e.resourceLoader,extensionRunner:n}),"getCommands"),setModel:t(async r=>await e.modelRegistry.getApiKey(r)?(await e.setModel(r),!0):!1,"setModel"),getThinkingLevel:t(()=>e.thinkingLevel,"getThinkingLevel"),setThinkingLevel:t(r=>e.setThinkingLevel(r),"setThinkingLevel")},{getModel:t(()=>e.model,"getModel"),completeSimple:t((r,o)=>P(n,e,r,o),"completeSimple"),completeSimpleWithUsage:t((r,o)=>M(n,e,r,o),"completeSimpleWithUsage"),completeJson:t((r,o,a,s)=>b(n,e,r,o,a,s),"completeJson"),getSettings:t(()=>e.settingsManager.getSettings(),"getSettings"),isIdle:t(()=>!e.isStreaming,"isIdle"),abort:t(()=>{e.abort()},"abort"),hasPendingMessages:t(()=>e.pendingMessageCount>0,"hasPendingMessages"),shutdown:t(()=>{e.shutdownHandler?.()},"shutdown"),getContextUsage:t(()=>e.getContextUsage(),"getContextUsage"),compact:t(r=>{(async()=>{try{const o=await e.compact(r?.customInstructions);r?.onComplete?.(o)}catch(o){const a=o instanceof Error?o:new Error(String(o));r?.onError?.(a)}})()},"compact"),getSystemPrompt:t(()=>e.systemPrompt,"getSystemPrompt"),getSoulManager:t(()=>e.soulManager,"getSoulManager"),getSkills:t(()=>e.resourceLoader.getSkills().skills,"getSkills")})}t(O,"bindExtensionCore");export{O as bindExtensionCore};
3
+ You must call the ${i} tool exactly once with the final structured JSON payload. Do not answer in prose.`,messages:[{role:"user",content:r,timestamp:Date.now()}],tools:[{name:i,description:"Submit the final structured JSON payload.",parameters:f}]},k);p=x.usage;const y=x.content?.find(C=>N(C,i));if(y){const C=s?.resultKey?y.arguments?.[s.resultKey]:y.arguments;w=JSON.stringify(C)}}catch(f){u=!1,l=f instanceof Error?f.constructor.name:"unknown"}if(n.writeLlmCallEvent(v({host:e,model:c,startedAt:g,startPerf:m,ok:u,errorCode:l,usage:p})),!!u)return w}t(U,"completeJsonWithCurrentModel");function O(n,e){n.bindCore({sendMessage:t((o,r)=>{e.sendCustomMessage(o,r).catch(a=>{n.emitError({extensionPath:"<runtime>",event:"send_message",error:a instanceof Error?a.message:String(a)})})},"sendMessage"),sendUserMessage:t((o,r)=>{e.sendUserMessage(o,r).catch(a=>{n.emitError({extensionPath:"<runtime>",event:"send_user_message",error:a instanceof Error?a.message:String(a)})})},"sendUserMessage"),executeCommand:t(async o=>{try{return await e.executeSlashCommand(o)}catch(r){return n.emitError({extensionPath:"<runtime>",event:"execute_command",error:r instanceof Error?r.message:String(r)}),!1}},"executeCommand"),appendEntry:t((o,r)=>{e.sessionManager.appendCustomEntry(o,r)},"appendEntry"),setSessionName:t(o=>{e.sessionManager.appendSessionInfo(o)},"setSessionName"),getSessionName:t(()=>e.sessionManager.getSessionName(),"getSessionName"),setLabel:t((o,r)=>{e.sessionManager.appendLabelChange(o,r)},"setLabel"),getActiveTools:t(()=>e.getActiveToolNames(),"getActiveTools"),getAllTools:t(()=>e.getAllTools(),"getAllTools"),setActiveTools:t(o=>e.setActiveToolsByName(o),"setActiveTools"),getCommands:t(()=>A({promptTemplates:e.promptTemplates,resourceLoader:e.resourceLoader,extensionRunner:n}),"getCommands"),setModel:t(async o=>await e.modelRegistry.getApiKey(o)?(await e.setModel(o),!0):!1,"setModel"),getThinkingLevel:t(()=>e.thinkingLevel,"getThinkingLevel"),setThinkingLevel:t(o=>e.setThinkingLevel(o),"setThinkingLevel")},{getModel:t(()=>e.model,"getModel"),completeSimple:t((o,r)=>P(n,e,o,r),"completeSimple"),completeSimpleWithUsage:t((o,r)=>M(n,e,o,r),"completeSimpleWithUsage"),completeJson:t((o,r,a,s)=>U(n,e,o,r,a,s),"completeJson"),getSettings:t(()=>e.settingsManager.getSettings(),"getSettings"),isIdle:t(()=>!e.isStreaming,"isIdle"),abort:t(()=>{e.abort()},"abort"),clearFollowUpQueue:t(()=>e.clearFollowUpQueue(),"clearFollowUpQueue"),hasPendingMessages:t(()=>e.pendingMessageCount>0,"hasPendingMessages"),shutdown:t(()=>{e.shutdownHandler?.()},"shutdown"),getContextUsage:t(()=>e.getContextUsage(),"getContextUsage"),compact:t(o=>{(async()=>{try{const r=await e.compact(o?.customInstructions);o?.onComplete?.(r)}catch(r){const a=r instanceof Error?r:new Error(String(r));o?.onError?.(a)}})()},"compact"),getSystemPrompt:t(()=>e.systemPrompt,"getSystemPrompt"),getSoulManager:t(()=>e.soulManager,"getSoulManager"),getSkills:t(()=>e.resourceLoader.getSkills().skills,"getSkills")})}t(O,"bindExtensionCore");export{O as bindExtensionCore};