@bastani/atomic 0.9.11-alpha.1 → 0.9.11-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/builtin/cursor/package.json +3 -3
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/mcp/package.json +3 -3
- package/dist/builtin/subagents/package.json +4 -4
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +6 -0
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/src/durable/child-primitive.ts +3 -0
- package/dist/builtin/workflows/src/durable/completed-catalog.ts +182 -33
- package/dist/builtin/workflows/src/durable/completed-inspection.ts +9 -4
- package/dist/builtin/workflows/src/durable/dbos-envelope.ts +31 -8
- package/dist/builtin/workflows/src/durable/resume-runtime.ts +6 -2
- package/dist/builtin/workflows/src/durable/stage-primitive.ts +48 -10
- package/dist/builtin/workflows/src/durable/types.ts +11 -0
- package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +9 -9
- package/dist/builtin/workflows/src/engine/run-durable-topology.ts +89 -0
- package/dist/builtin/workflows/src/engine/run.ts +18 -16
- package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +3 -0
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +3 -0
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +6 -3
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +2 -2
- package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +4 -1
- package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +2 -3
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +7 -1
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +3 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-tree.d.ts.map +1 -1
- package/dist/core/agent-session-tree.js +4 -1
- package/dist/core/agent-session-tree.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +15 -0
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +5 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +7 -8
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction-runner.d.ts +3 -1
- package/dist/core/compaction/compaction-runner.d.ts.map +1 -1
- package/dist/core/compaction/compaction-runner.js +6 -1
- package/dist/core/compaction/compaction-runner.js.map +1 -1
- package/dist/core/compaction/range-planner.d.ts +3 -0
- package/dist/core/compaction/range-planner.d.ts.map +1 -1
- package/dist/core/compaction/range-planner.js +2 -1
- package/dist/core/compaction/range-planner.js.map +1 -1
- package/dist/core/model-registry.js +2 -2
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver-defaults.d.ts.map +1 -1
- package/dist/core/model-resolver-defaults.js +2 -0
- package/dist/core/model-resolver-defaults.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +1 -0
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +6 -4
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +25 -6
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/sdk-exports.d.ts +1 -1
- package/dist/core/sdk-exports.d.ts.map +1 -1
- package/dist/core/sdk-exports.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +4 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager-core.d.ts +1 -0
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +7 -4
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/core/session-manager-validation.d.ts.map +1 -1
- package/dist/core/session-manager-validation.js +3 -16
- package/dist/core/session-manager-validation.js.map +1 -1
- package/dist/core/summarization-retry.d.ts +11 -0
- package/dist/core/summarization-retry.d.ts.map +1 -0
- package/dist/core/summarization-retry.js +21 -0
- package/dist/core/summarization-retry.js.map +1 -0
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-events.js +16 -0
- package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
- package/dist/modes/interactive/components/footer.js +2 -2
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.js +6 -0
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-model-catalog-startup.d.ts +13 -0
- package/dist/modes/interactive/interactive-model-catalog-startup.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-model-catalog-startup.js +24 -0
- package/dist/modes/interactive/interactive-model-catalog-startup.js.map +1 -0
- package/dist/modes/interactive/interactive-model-routing.js +4 -3
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-queueing.js +3 -2
- package/dist/modes/interactive/interactive-queueing.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +4 -7
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-summarization-retry-events.d.ts +8 -0
- package/dist/modes/interactive/interactive-summarization-retry-events.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-summarization-retry-events.js +40 -0
- package/dist/modes/interactive/interactive-summarization-retry-events.js.map +1 -0
- package/dist/modes/rpc/rpc-client-api.d.ts +1 -0
- package/dist/modes/rpc/rpc-client-api.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client-api.js +3 -0
- package/dist/modes/rpc/rpc-client-api.js.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.js +5 -0
- package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +11 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/extensions.md +3 -3
- package/docs/json.md +7 -1
- package/docs/prompt-templates.md +1 -0
- package/docs/providers.md +4 -0
- package/docs/rpc.md +49 -0
- package/docs/sdk.md +3 -0
- package/docs/tui.md +2 -2
- package/docs/workflows.md +6 -6
- package/examples/extensions/README.md +1 -1
- package/examples/extensions/sandbox/package-lock.json +3 -3
- package/npm-shrinkwrap.json +36 -36
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-resolver-defaults.js","sourceRoot":"","sources":["../../src/core/model-resolver-defaults.ts"],"names":[],"mappings":"AAEA,gDAAgD;AAChD,MAAM,CAAC,MAAM,uBAAuB,GAA2B;IAC7D,gBAAgB,EAAE,iCAAiC;IACnD,SAAS,EAAE,iBAAiB;IAC5B,MAAM,EAAE,SAAS;IACjB,wBAAwB,EAAE,SAAS;IACnC,cAAc,EAAE,SAAS;IACzB,QAAQ,EAAE,iBAAiB;IAC3B,MAAM,EAAE,wBAAwB;IAChC,eAAe,EAAE,wBAAwB;IACzC,gBAAgB,EAAE,SAAS;IAC3B,MAAM,EAAE,YAAY;IACpB,UAAU,EAAE,sBAAsB;IAClC,mBAAmB,EAAE,aAAa;IAClC,GAAG,EAAE,0BAA0B;IAC/B,IAAI,EAAE,qBAAqB;IAC3B,QAAQ,EAAE,aAAa;IACvB,UAAU,EAAE,aAAa;IACzB,GAAG,EAAE,SAAS;IACd,OAAO,EAAE,wBAAwB;IACjC,OAAO,EAAE,cAAc;IACvB,YAAY,EAAE,cAAc;IAC5B,UAAU,EAAE,WAAW;IACvB,eAAe,EAAE,WAAW;IAC5B,WAAW,EAAE,sBAAsB;IACnC,SAAS,EAAE,qCAAqC;IAChD,QAAQ,EAAE,sBAAsB;IAChC,QAAQ,EAAE,WAAW;IACrB,aAAa,EAAE,WAAW;IAC1B,aAAa,EAAE,iBAAiB;IAChC,uBAAuB,EAAE,0BAA0B;IACnD,uBAAuB,EAAE,qCAAqC;IAC9D,MAAM,EAAE,eAAe;IACvB,sBAAsB,EAAE,eAAe;IACvC,uBAAuB,EAAE,eAAe;IACxC,uBAAuB,EAAE,eAAe;CACzC,CAAC;AAEF,MAAM,UAAU,2BAA2B,CAAC,eAA6B;IACvE,KAAK,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC;QAC5E,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;QACzF,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;AAC5B,CAAC","sourcesContent":["import type { Api, Model } from \"@earendil-works/pi-ai/compat\";\n\n/** Default model IDs for each known provider */\nexport const defaultModelPerProvider: Record<string, string> = {\n \"amazon-bedrock\": \"us.anthropic.claude-opus-4-6-v1\",\n anthropic: \"claude-opus-4-8\",\n openai: \"gpt-5.5\",\n \"azure-openai-responses\": \"gpt-5.4\",\n \"openai-codex\": \"gpt-5.5\",\n deepseek: \"deepseek-v4-pro\",\n google: \"gemini-3.1-pro-preview\",\n \"google-vertex\": \"gemini-3.1-pro-preview\",\n \"github-copilot\": \"gpt-5.4\",\n cursor: \"composer-2\",\n openrouter: \"moonshotai/kimi-k2.6\",\n \"vercel-ai-gateway\": \"zai/glm-5.1\",\n xai: \"grok-4.20-0309-reasoning\",\n groq: \"openai/gpt-oss-120b\",\n cerebras: \"zai-glm-4.7\",\n \"ant-ling\": \"Ring-2.6-1T\",\n zai: \"glm-5.1\",\n mistral: \"devstral-medium-latest\",\n minimax: \"MiniMax-M2.7\",\n \"minimax-cn\": \"MiniMax-M2.7\",\n moonshotai: \"kimi-k2.6\",\n \"moonshotai-cn\": \"kimi-k2.6\",\n huggingface: \"moonshotai/Kimi-K2.6\",\n fireworks: \"accounts/fireworks/models/kimi-k2p6\",\n together: \"moonshotai/Kimi-K2.6\",\n opencode: \"kimi-k2.6\",\n \"opencode-go\": \"kimi-k2.6\",\n \"kimi-coding\": \"kimi-for-coding\",\n \"cloudflare-workers-ai\": \"@cf/moonshotai/kimi-k2.6\",\n \"cloudflare-ai-gateway\": \"workers-ai/@cf/moonshotai/kimi-k2.6\",\n xiaomi: \"mimo-v2.5-pro\",\n \"xiaomi-token-plan-cn\": \"mimo-v2.5-pro\",\n \"xiaomi-token-plan-ams\": \"mimo-v2.5-pro\",\n \"xiaomi-token-plan-sgp\": \"mimo-v2.5-pro\",\n};\n\nexport function findPreferredAvailableModel(availableModels: Model<Api>[]): Model<Api> | undefined {\n for (const [provider, defaultId] of Object.entries(defaultModelPerProvider)) {\n const match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n if (match) {\n return match;\n }\n }\n\n return availableModels[0];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"model-resolver-defaults.js","sourceRoot":"","sources":["../../src/core/model-resolver-defaults.ts"],"names":[],"mappings":"AAEA,gDAAgD;AAChD,MAAM,CAAC,MAAM,uBAAuB,GAA2B;IAC7D,gBAAgB,EAAE,iCAAiC;IACnD,SAAS,EAAE,iBAAiB;IAC5B,MAAM,EAAE,SAAS;IACjB,wBAAwB,EAAE,SAAS;IACnC,cAAc,EAAE,SAAS;IACzB,QAAQ,EAAE,iBAAiB;IAC3B,MAAM,EAAE,wBAAwB;IAChC,eAAe,EAAE,wBAAwB;IACzC,gBAAgB,EAAE,SAAS;IAC3B,MAAM,EAAE,YAAY;IACpB,UAAU,EAAE,sBAAsB;IAClC,mBAAmB,EAAE,aAAa;IAClC,GAAG,EAAE,0BAA0B;IAC/B,IAAI,EAAE,qBAAqB;IAC3B,QAAQ,EAAE,aAAa;IACvB,UAAU,EAAE,aAAa;IACzB,GAAG,EAAE,SAAS;IACd,OAAO,EAAE,wBAAwB;IACjC,OAAO,EAAE,cAAc;IACvB,YAAY,EAAE,cAAc;IAC5B,UAAU,EAAE,WAAW;IACvB,eAAe,EAAE,WAAW;IAC5B,WAAW,EAAE,sBAAsB;IACnC,SAAS,EAAE,qCAAqC;IAChD,QAAQ,EAAE,sBAAsB;IAChC,QAAQ,EAAE,WAAW;IACrB,aAAa,EAAE,WAAW;IAC1B,aAAa,EAAE,iBAAiB;IAChC,uBAAuB,EAAE,0BAA0B;IACnD,uBAAuB,EAAE,qCAAqC;IAC9D,iBAAiB,EAAE,aAAa;IAChC,oBAAoB,EAAE,aAAa;IACnC,MAAM,EAAE,eAAe;IACvB,sBAAsB,EAAE,eAAe;IACvC,uBAAuB,EAAE,eAAe;IACxC,uBAAuB,EAAE,eAAe;CACzC,CAAC;AAEF,MAAM,UAAU,2BAA2B,CAAC,eAA6B;IACvE,KAAK,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC;QAC5E,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;QACzF,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;AAC5B,CAAC","sourcesContent":["import type { Api, Model } from \"@earendil-works/pi-ai/compat\";\n\n/** Default model IDs for each known provider */\nexport const defaultModelPerProvider: Record<string, string> = {\n \"amazon-bedrock\": \"us.anthropic.claude-opus-4-6-v1\",\n anthropic: \"claude-opus-4-8\",\n openai: \"gpt-5.5\",\n \"azure-openai-responses\": \"gpt-5.4\",\n \"openai-codex\": \"gpt-5.5\",\n deepseek: \"deepseek-v4-pro\",\n google: \"gemini-3.1-pro-preview\",\n \"google-vertex\": \"gemini-3.1-pro-preview\",\n \"github-copilot\": \"gpt-5.4\",\n cursor: \"composer-2\",\n openrouter: \"moonshotai/kimi-k2.6\",\n \"vercel-ai-gateway\": \"zai/glm-5.1\",\n xai: \"grok-4.20-0309-reasoning\",\n groq: \"openai/gpt-oss-120b\",\n cerebras: \"zai-glm-4.7\",\n \"ant-ling\": \"Ring-2.6-1T\",\n zai: \"glm-5.1\",\n mistral: \"devstral-medium-latest\",\n minimax: \"MiniMax-M2.7\",\n \"minimax-cn\": \"MiniMax-M2.7\",\n moonshotai: \"kimi-k2.6\",\n \"moonshotai-cn\": \"kimi-k2.6\",\n huggingface: \"moonshotai/Kimi-K2.6\",\n fireworks: \"accounts/fireworks/models/kimi-k2p6\",\n together: \"moonshotai/Kimi-K2.6\",\n opencode: \"kimi-k2.6\",\n \"opencode-go\": \"kimi-k2.6\",\n \"kimi-coding\": \"kimi-for-coding\",\n \"cloudflare-workers-ai\": \"@cf/moonshotai/kimi-k2.6\",\n \"cloudflare-ai-gateway\": \"workers-ai/@cf/moonshotai/kimi-k2.6\",\n \"qwen-token-plan\": \"qwen3.7-max\",\n \"qwen-token-plan-cn\": \"qwen3.7-max\",\n xiaomi: \"mimo-v2.5-pro\",\n \"xiaomi-token-plan-cn\": \"mimo-v2.5-pro\",\n \"xiaomi-token-plan-ams\": \"mimo-v2.5-pro\",\n \"xiaomi-token-plan-sgp\": \"mimo-v2.5-pro\",\n};\n\nexport function findPreferredAvailableModel(availableModels: Model<Api>[]): Model<Api> | undefined {\n for (const [provider, defaultId] of Object.entries(defaultModelPerProvider)) {\n const match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n if (match) {\n return match;\n }\n }\n\n return availableModels[0];\n}\n"]}
|
|
@@ -23,6 +23,7 @@ export declare function parseCommandArgs(argsString: string): string[];
|
|
|
23
23
|
* - ${@:N} for args from Nth onwards (bash-style slicing)
|
|
24
24
|
* - ${@:N:L} for L args starting from Nth
|
|
25
25
|
* - ${N:-default} for positional args with a default value when missing/empty
|
|
26
|
+
* - ${@:-default} and ${ARGUMENTS:-default} for all args with a default when empty
|
|
26
27
|
*
|
|
27
28
|
* Note: Replacement happens on the template string only. Argument and default
|
|
28
29
|
* values containing patterns like $1, $@, or $ARGUMENTS are NOT recursively substituted.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-templates.d.ts","sourceRoot":"","sources":["../../src/core/prompt-templates.ts"],"names":[],"mappings":"AAKA,OAAO,EAA6B,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CA+B7D;AAED
|
|
1
|
+
{"version":3,"file":"prompt-templates.d.ts","sourceRoot":"","sources":["../../src/core/prompt-templates.ts"],"names":[],"mappings":"AAKA,OAAO,EAA6B,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CA+B7D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAoCtE;AA2ED,MAAM,WAAW,0BAA0B;IAC1C,qDAAqD;IACrD,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,0CAA0C;IAC1C,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,cAAc,EAAE,CAqEzF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,MAAM,CActF"}
|
|
@@ -48,6 +48,7 @@ export function parseCommandArgs(argsString) {
|
|
|
48
48
|
* - ${@:N} for args from Nth onwards (bash-style slicing)
|
|
49
49
|
* - ${@:N:L} for L args starting from Nth
|
|
50
50
|
* - ${N:-default} for positional args with a default value when missing/empty
|
|
51
|
+
* - ${@:-default} and ${ARGUMENTS:-default} for all args with a default when empty
|
|
51
52
|
*
|
|
52
53
|
* Note: Replacement happens on the template string only. Argument and default
|
|
53
54
|
* values containing patterns like $1, $@, or $ARGUMENTS are NOT recursively substituted.
|
|
@@ -58,10 +59,11 @@ export function substituteArgs(content, args) {
|
|
|
58
59
|
// backtracking (ReDoS) when scanning template content, which is read from
|
|
59
60
|
// disk. This is an Atomic hardening divergence from upstream; 1024 characters
|
|
60
61
|
// far exceeds any realistic slash-command default value.
|
|
61
|
-
return content.replace(/\$\{(\d
|
|
62
|
-
if (
|
|
63
|
-
const
|
|
64
|
-
|
|
62
|
+
return content.replace(/\$\{(\d+|ARGUMENTS|@):-([^}]{0,1024})\}|\$\{@:(\d+)(?::(\d+))?\}|\$(ARGUMENTS|@|\d+)/g, (_match, defaultTarget, defaultValue, sliceStart, sliceLength, simple) => {
|
|
63
|
+
if (defaultTarget) {
|
|
64
|
+
const value = defaultTarget === "@" || defaultTarget === "ARGUMENTS"
|
|
65
|
+
? allArgs
|
|
66
|
+
: args[parseInt(defaultTarget, 10) - 1];
|
|
65
67
|
return value ? value : defaultValue;
|
|
66
68
|
}
|
|
67
69
|
if (sliceStart) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-templates.js","sourceRoot":"","sources":["../../src/core/prompt-templates.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from \"fs\";\nimport { basename, dirname, join, resolve, sep } from \"path\";\nimport { CONFIG_DIR_NAME } from \"../config.ts\";\nimport { parseFrontmatter } from \"../utils/frontmatter.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { createSyntheticSourceInfo, type SourceInfo } from \"./source-info.ts\";\n\n/**\n * Represents a prompt template loaded from a markdown file\n */\nexport interface PromptTemplate {\n\tname: string;\n\tdescription: string;\n\targumentHint?: string;\n\tcontent: string;\n\tsourceInfo: SourceInfo;\n\tfilePath: string; // Absolute path to the template file\n}\n\n/**\n * Parse command arguments respecting quoted strings (bash-style)\n * Returns array of arguments\n */\nexport function parseCommandArgs(argsString: string): string[] {\n\tconst args: string[] = [];\n\tlet current = \"\";\n\tlet inQuote: string | null = null;\n\n\tfor (let i = 0; i < argsString.length; i++) {\n\t\tconst char = argsString[i];\n\n\t\tif (inQuote) {\n\t\t\tif (char === inQuote) {\n\t\t\t\tinQuote = null;\n\t\t\t} else {\n\t\t\t\tcurrent += char;\n\t\t\t}\n\t\t} else if (char === '\"' || char === \"'\") {\n\t\t\tinQuote = char;\n\t\t} else if (char === \" \" || char === \"\\t\") {\n\t\t\tif (current) {\n\t\t\t\targs.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t} else {\n\t\t\tcurrent += char;\n\t\t}\n\t}\n\n\tif (current) {\n\t\targs.push(current);\n\t}\n\n\treturn args;\n}\n\n/**\n * Substitute argument placeholders in template content\n * Supports:\n * - $1, $2, ... for positional args\n * - $@ and $ARGUMENTS for all args\n * - ${@:N} for args from Nth onwards (bash-style slicing)\n * - ${@:N:L} for L args starting from Nth\n * - ${N:-default} for positional args with a default value when missing/empty\n *\n * Note: Replacement happens on the template string only. Argument and default\n * values containing patterns like $1, $@, or $ARGUMENTS are NOT recursively substituted.\n */\nexport function substituteArgs(content: string, args: string[]): string {\n\tconst allArgs = args.join(\" \");\n\n\t// The default-value group is length-bounded to avoid polynomial-time regex\n\t// backtracking (ReDoS) when scanning template content, which is read from\n\t// disk. This is an Atomic hardening divergence from upstream; 1024 characters\n\t// far exceeds any realistic slash-command default value.\n\treturn content.replace(\n\t\t/\\$\\{(\\d+):-([^}]{0,1024})\\}|\\$\\{@:(\\d+)(?::(\\d+))?\\}|\\$(ARGUMENTS|@|\\d+)/g,\n\t\t(_match, defaultNum, defaultValue, sliceStart, sliceLength, simple) => {\n\t\t\tif (defaultNum) {\n\t\t\t\tconst index = parseInt(defaultNum, 10) - 1;\n\t\t\t\tconst value = args[index];\n\t\t\t\treturn value ? value : defaultValue;\n\t\t\t}\n\n\t\t\tif (sliceStart) {\n\t\t\t\tlet start = parseInt(sliceStart, 10) - 1;\n\t\t\t\tif (start < 0) start = 0;\n\n\t\t\t\tif (sliceLength) {\n\t\t\t\t\tconst length = parseInt(sliceLength, 10);\n\t\t\t\t\treturn args.slice(start, start + length).join(\" \");\n\t\t\t\t}\n\t\t\t\treturn args.slice(start).join(\" \");\n\t\t\t}\n\n\t\t\tif (simple === \"ARGUMENTS\" || simple === \"@\") {\n\t\t\t\treturn allArgs;\n\t\t\t}\n\n\t\t\tconst index = parseInt(simple, 10) - 1;\n\t\t\treturn args[index] ?? \"\";\n\t\t},\n\t);\n}\n\nfunction loadTemplateFromFile(filePath: string, sourceInfo: SourceInfo): PromptTemplate | null {\n\ttry {\n\t\tconst rawContent = readFileSync(filePath, \"utf-8\");\n\t\tconst { frontmatter, body } = parseFrontmatter<Record<string, string>>(rawContent);\n\n\t\tconst name = basename(filePath).replace(/\\.md$/, \"\");\n\n\t\t// Get description from frontmatter or first non-empty line\n\t\tlet description = frontmatter.description || \"\";\n\t\tif (!description) {\n\t\t\tconst firstLine = body.split(\"\\n\").find((line) => line.trim());\n\t\t\tif (firstLine) {\n\t\t\t\t// Truncate if too long\n\t\t\t\tdescription = firstLine.slice(0, 60);\n\t\t\t\tif (firstLine.length > 60) description += \"...\";\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tname,\n\t\t\tdescription,\n\t\t\t...(frontmatter[\"argument-hint\"] && { argumentHint: frontmatter[\"argument-hint\"] }),\n\t\t\tcontent: body,\n\t\t\tsourceInfo,\n\t\t\tfilePath,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Scan a directory for .md files (non-recursive) and load them as prompt templates.\n */\nfunction loadTemplatesFromDir(dir: string, getSourceInfo: (filePath: string) => SourceInfo): PromptTemplate[] {\n\tconst templates: PromptTemplate[] = [];\n\n\tif (!existsSync(dir)) {\n\t\treturn templates;\n\t}\n\n\ttry {\n\t\tconst entries = readdirSync(dir, { withFileTypes: true });\n\n\t\tfor (const entry of entries) {\n\t\t\tconst fullPath = join(dir, entry.name);\n\n\t\t\t// For symlinks, check if they point to a file\n\t\t\tlet isFile = entry.isFile();\n\t\t\tif (entry.isSymbolicLink()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst stats = statSync(fullPath);\n\t\t\t\t\tisFile = stats.isFile();\n\t\t\t\t} catch {\n\t\t\t\t\t// Broken symlink, skip it\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isFile && entry.name.endsWith(\".md\")) {\n\t\t\t\tconst template = loadTemplateFromFile(fullPath, getSourceInfo(fullPath));\n\t\t\t\tif (template) {\n\t\t\t\t\ttemplates.push(template);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {\n\t\treturn templates;\n\t}\n\n\treturn templates;\n}\n\nexport interface LoadPromptTemplatesOptions {\n\t/** Working directory for project-local templates. */\n\tcwd: string;\n\t/** Agent config directory for global templates. */\n\tagentDir: string;\n\t/** Explicit prompt template paths (files or directories). */\n\tpromptPaths?: string[];\n\t/** Include default prompt directories. */\n\tincludeDefaults?: boolean;\n}\n\n/**\n * Load all prompt templates from:\n * 1. Global: agentDir/prompts/\n * 2. Project: cwd/{CONFIG_DIR_NAME}/prompts/\n * 3. Explicit prompt paths\n */\nexport function loadPromptTemplates(options: LoadPromptTemplatesOptions): PromptTemplate[] {\n\tconst resolvedCwd = resolvePath(options.cwd);\n\tconst resolvedAgentDir = resolvePath(options.agentDir);\n\tconst promptPaths = options.promptPaths ?? [];\n\tconst includeDefaults = options.includeDefaults ?? true;\n\n\tconst templates: PromptTemplate[] = [];\n\n\tconst globalPromptsDir = join(resolvedAgentDir, \"prompts\");\n\tconst projectPromptsDir = resolve(resolvedCwd, CONFIG_DIR_NAME, \"prompts\");\n\n\tconst isUnderPath = (target: string, root: string): boolean => {\n\t\tconst normalizedRoot = resolve(root);\n\t\tif (target === normalizedRoot) {\n\t\t\treturn true;\n\t\t}\n\t\tconst prefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\treturn target.startsWith(prefix);\n\t};\n\n\tconst getSourceInfo = (resolvedPath: string): SourceInfo => {\n\t\tif (isUnderPath(resolvedPath, globalPromptsDir)) {\n\t\t\treturn createSyntheticSourceInfo(resolvedPath, {\n\t\t\t\tsource: \"local\",\n\t\t\t\tscope: \"user\",\n\t\t\t\tbaseDir: globalPromptsDir,\n\t\t\t});\n\t\t}\n\t\tif (isUnderPath(resolvedPath, projectPromptsDir)) {\n\t\t\treturn createSyntheticSourceInfo(resolvedPath, {\n\t\t\t\tsource: \"local\",\n\t\t\t\tscope: \"project\",\n\t\t\t\tbaseDir: projectPromptsDir,\n\t\t\t});\n\t\t}\n\t\treturn createSyntheticSourceInfo(resolvedPath, {\n\t\t\tsource: \"local\",\n\t\t\tbaseDir: statSync(resolvedPath).isDirectory() ? resolvedPath : dirname(resolvedPath),\n\t\t});\n\t};\n\n\tif (includeDefaults) {\n\t\ttemplates.push(...loadTemplatesFromDir(globalPromptsDir, getSourceInfo));\n\t\ttemplates.push(...loadTemplatesFromDir(projectPromptsDir, getSourceInfo));\n\t}\n\n\t// 3. Load explicit prompt paths\n\tfor (const rawPath of promptPaths) {\n\t\tconst resolvedPath = resolvePath(rawPath, resolvedCwd, { trim: true });\n\t\tif (!existsSync(resolvedPath)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\ttry {\n\t\t\tconst stats = statSync(resolvedPath);\n\t\t\tif (stats.isDirectory()) {\n\t\t\t\ttemplates.push(...loadTemplatesFromDir(resolvedPath, getSourceInfo));\n\t\t\t} else if (stats.isFile() && resolvedPath.endsWith(\".md\")) {\n\t\t\t\tconst template = loadTemplateFromFile(resolvedPath, getSourceInfo(resolvedPath));\n\t\t\t\tif (template) {\n\t\t\t\t\ttemplates.push(template);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore read failures\n\t\t}\n\t}\n\n\treturn templates;\n}\n\n/**\n * Expand a prompt template if it matches a template name.\n * Returns the expanded content or the original text if not a template.\n */\nexport function expandPromptTemplate(text: string, templates: PromptTemplate[]): string {\n\tif (!text.startsWith(\"/\")) return text;\n\n\tconst spaceIndex = text.indexOf(\" \");\n\tconst templateName = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);\n\tconst argsString = spaceIndex === -1 ? \"\" : text.slice(spaceIndex + 1);\n\n\tconst template = templates.find((t) => t.name === templateName);\n\tif (template) {\n\t\tconst args = parseCommandArgs(argsString);\n\t\treturn substituteArgs(template.content, args);\n\t}\n\n\treturn text;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"prompt-templates.js","sourceRoot":"","sources":["../../src/core/prompt-templates.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from \"fs\";\nimport { basename, dirname, join, resolve, sep } from \"path\";\nimport { CONFIG_DIR_NAME } from \"../config.ts\";\nimport { parseFrontmatter } from \"../utils/frontmatter.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { createSyntheticSourceInfo, type SourceInfo } from \"./source-info.ts\";\n\n/**\n * Represents a prompt template loaded from a markdown file\n */\nexport interface PromptTemplate {\n\tname: string;\n\tdescription: string;\n\targumentHint?: string;\n\tcontent: string;\n\tsourceInfo: SourceInfo;\n\tfilePath: string; // Absolute path to the template file\n}\n\n/**\n * Parse command arguments respecting quoted strings (bash-style)\n * Returns array of arguments\n */\nexport function parseCommandArgs(argsString: string): string[] {\n\tconst args: string[] = [];\n\tlet current = \"\";\n\tlet inQuote: string | null = null;\n\n\tfor (let i = 0; i < argsString.length; i++) {\n\t\tconst char = argsString[i];\n\n\t\tif (inQuote) {\n\t\t\tif (char === inQuote) {\n\t\t\t\tinQuote = null;\n\t\t\t} else {\n\t\t\t\tcurrent += char;\n\t\t\t}\n\t\t} else if (char === '\"' || char === \"'\") {\n\t\t\tinQuote = char;\n\t\t} else if (char === \" \" || char === \"\\t\") {\n\t\t\tif (current) {\n\t\t\t\targs.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t} else {\n\t\t\tcurrent += char;\n\t\t}\n\t}\n\n\tif (current) {\n\t\targs.push(current);\n\t}\n\n\treturn args;\n}\n\n/**\n * Substitute argument placeholders in template content\n * Supports:\n * - $1, $2, ... for positional args\n * - $@ and $ARGUMENTS for all args\n * - ${@:N} for args from Nth onwards (bash-style slicing)\n * - ${@:N:L} for L args starting from Nth\n * - ${N:-default} for positional args with a default value when missing/empty\n * - ${@:-default} and ${ARGUMENTS:-default} for all args with a default when empty\n *\n * Note: Replacement happens on the template string only. Argument and default\n * values containing patterns like $1, $@, or $ARGUMENTS are NOT recursively substituted.\n */\nexport function substituteArgs(content: string, args: string[]): string {\n\tconst allArgs = args.join(\" \");\n\n\t// The default-value group is length-bounded to avoid polynomial-time regex\n\t// backtracking (ReDoS) when scanning template content, which is read from\n\t// disk. This is an Atomic hardening divergence from upstream; 1024 characters\n\t// far exceeds any realistic slash-command default value.\n\treturn content.replace(\n\t\t/\\$\\{(\\d+|ARGUMENTS|@):-([^}]{0,1024})\\}|\\$\\{@:(\\d+)(?::(\\d+))?\\}|\\$(ARGUMENTS|@|\\d+)/g,\n\t\t(_match, defaultTarget, defaultValue, sliceStart, sliceLength, simple) => {\n\t\t\tif (defaultTarget) {\n\t\t\t\tconst value = defaultTarget === \"@\" || defaultTarget === \"ARGUMENTS\"\n\t\t\t\t\t? allArgs\n\t\t\t\t\t: args[parseInt(defaultTarget, 10) - 1];\n\t\t\t\treturn value ? value : defaultValue;\n\t\t\t}\n\n\t\t\tif (sliceStart) {\n\t\t\t\tlet start = parseInt(sliceStart, 10) - 1;\n\t\t\t\tif (start < 0) start = 0;\n\n\t\t\t\tif (sliceLength) {\n\t\t\t\t\tconst length = parseInt(sliceLength, 10);\n\t\t\t\t\treturn args.slice(start, start + length).join(\" \");\n\t\t\t\t}\n\t\t\t\treturn args.slice(start).join(\" \");\n\t\t\t}\n\n\t\t\tif (simple === \"ARGUMENTS\" || simple === \"@\") {\n\t\t\t\treturn allArgs;\n\t\t\t}\n\n\t\t\tconst index = parseInt(simple, 10) - 1;\n\t\t\treturn args[index] ?? \"\";\n\t\t},\n\t);\n}\n\nfunction loadTemplateFromFile(filePath: string, sourceInfo: SourceInfo): PromptTemplate | null {\n\ttry {\n\t\tconst rawContent = readFileSync(filePath, \"utf-8\");\n\t\tconst { frontmatter, body } = parseFrontmatter<Record<string, string>>(rawContent);\n\n\t\tconst name = basename(filePath).replace(/\\.md$/, \"\");\n\n\t\t// Get description from frontmatter or first non-empty line\n\t\tlet description = frontmatter.description || \"\";\n\t\tif (!description) {\n\t\t\tconst firstLine = body.split(\"\\n\").find((line) => line.trim());\n\t\t\tif (firstLine) {\n\t\t\t\t// Truncate if too long\n\t\t\t\tdescription = firstLine.slice(0, 60);\n\t\t\t\tif (firstLine.length > 60) description += \"...\";\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tname,\n\t\t\tdescription,\n\t\t\t...(frontmatter[\"argument-hint\"] && { argumentHint: frontmatter[\"argument-hint\"] }),\n\t\t\tcontent: body,\n\t\t\tsourceInfo,\n\t\t\tfilePath,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Scan a directory for .md files (non-recursive) and load them as prompt templates.\n */\nfunction loadTemplatesFromDir(dir: string, getSourceInfo: (filePath: string) => SourceInfo): PromptTemplate[] {\n\tconst templates: PromptTemplate[] = [];\n\n\tif (!existsSync(dir)) {\n\t\treturn templates;\n\t}\n\n\ttry {\n\t\tconst entries = readdirSync(dir, { withFileTypes: true });\n\n\t\tfor (const entry of entries) {\n\t\t\tconst fullPath = join(dir, entry.name);\n\n\t\t\t// For symlinks, check if they point to a file\n\t\t\tlet isFile = entry.isFile();\n\t\t\tif (entry.isSymbolicLink()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst stats = statSync(fullPath);\n\t\t\t\t\tisFile = stats.isFile();\n\t\t\t\t} catch {\n\t\t\t\t\t// Broken symlink, skip it\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isFile && entry.name.endsWith(\".md\")) {\n\t\t\t\tconst template = loadTemplateFromFile(fullPath, getSourceInfo(fullPath));\n\t\t\t\tif (template) {\n\t\t\t\t\ttemplates.push(template);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {\n\t\treturn templates;\n\t}\n\n\treturn templates;\n}\n\nexport interface LoadPromptTemplatesOptions {\n\t/** Working directory for project-local templates. */\n\tcwd: string;\n\t/** Agent config directory for global templates. */\n\tagentDir: string;\n\t/** Explicit prompt template paths (files or directories). */\n\tpromptPaths?: string[];\n\t/** Include default prompt directories. */\n\tincludeDefaults?: boolean;\n}\n\n/**\n * Load all prompt templates from:\n * 1. Global: agentDir/prompts/\n * 2. Project: cwd/{CONFIG_DIR_NAME}/prompts/\n * 3. Explicit prompt paths\n */\nexport function loadPromptTemplates(options: LoadPromptTemplatesOptions): PromptTemplate[] {\n\tconst resolvedCwd = resolvePath(options.cwd);\n\tconst resolvedAgentDir = resolvePath(options.agentDir);\n\tconst promptPaths = options.promptPaths ?? [];\n\tconst includeDefaults = options.includeDefaults ?? true;\n\n\tconst templates: PromptTemplate[] = [];\n\n\tconst globalPromptsDir = join(resolvedAgentDir, \"prompts\");\n\tconst projectPromptsDir = resolve(resolvedCwd, CONFIG_DIR_NAME, \"prompts\");\n\n\tconst isUnderPath = (target: string, root: string): boolean => {\n\t\tconst normalizedRoot = resolve(root);\n\t\tif (target === normalizedRoot) {\n\t\t\treturn true;\n\t\t}\n\t\tconst prefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\treturn target.startsWith(prefix);\n\t};\n\n\tconst getSourceInfo = (resolvedPath: string): SourceInfo => {\n\t\tif (isUnderPath(resolvedPath, globalPromptsDir)) {\n\t\t\treturn createSyntheticSourceInfo(resolvedPath, {\n\t\t\t\tsource: \"local\",\n\t\t\t\tscope: \"user\",\n\t\t\t\tbaseDir: globalPromptsDir,\n\t\t\t});\n\t\t}\n\t\tif (isUnderPath(resolvedPath, projectPromptsDir)) {\n\t\t\treturn createSyntheticSourceInfo(resolvedPath, {\n\t\t\t\tsource: \"local\",\n\t\t\t\tscope: \"project\",\n\t\t\t\tbaseDir: projectPromptsDir,\n\t\t\t});\n\t\t}\n\t\treturn createSyntheticSourceInfo(resolvedPath, {\n\t\t\tsource: \"local\",\n\t\t\tbaseDir: statSync(resolvedPath).isDirectory() ? resolvedPath : dirname(resolvedPath),\n\t\t});\n\t};\n\n\tif (includeDefaults) {\n\t\ttemplates.push(...loadTemplatesFromDir(globalPromptsDir, getSourceInfo));\n\t\ttemplates.push(...loadTemplatesFromDir(projectPromptsDir, getSourceInfo));\n\t}\n\n\t// 3. Load explicit prompt paths\n\tfor (const rawPath of promptPaths) {\n\t\tconst resolvedPath = resolvePath(rawPath, resolvedCwd, { trim: true });\n\t\tif (!existsSync(resolvedPath)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\ttry {\n\t\t\tconst stats = statSync(resolvedPath);\n\t\t\tif (stats.isDirectory()) {\n\t\t\t\ttemplates.push(...loadTemplatesFromDir(resolvedPath, getSourceInfo));\n\t\t\t} else if (stats.isFile() && resolvedPath.endsWith(\".md\")) {\n\t\t\t\tconst template = loadTemplateFromFile(resolvedPath, getSourceInfo(resolvedPath));\n\t\t\t\tif (template) {\n\t\t\t\t\ttemplates.push(template);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore read failures\n\t\t}\n\t}\n\n\treturn templates;\n}\n\n/**\n * Expand a prompt template if it matches a template name.\n * Returns the expanded content or the original text if not a template.\n */\nexport function expandPromptTemplate(text: string, templates: PromptTemplate[]): string {\n\tif (!text.startsWith(\"/\")) return text;\n\n\tconst spaceIndex = text.indexOf(\" \");\n\tconst templateName = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);\n\tconst argsString = spaceIndex === -1 ? \"\" : text.slice(spaceIndex + 1);\n\n\tconst template = templates.find((t) => t.name === templateName);\n\tif (template) {\n\t\tconst args = parseCommandArgs(argsString);\n\t\treturn substituteArgs(template.content, args);\n\t}\n\n\treturn text;\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Provider } from "@earendil-works/pi-ai";
|
|
2
2
|
export declare const REMOTE_CATALOG_REFRESH_INTERVAL_MS: number;
|
|
3
3
|
/** Add a persisted pi.dev catalog overlay to a static built-in provider. */
|
|
4
|
-
export declare function withRemoteCatalog(provider: Provider, catalogBaseUrl?: string): Provider;
|
|
4
|
+
export declare function withRemoteCatalog(provider: Provider, catalogBaseUrl?: string, localCatalogUrl?: URL): Provider;
|
|
5
5
|
//# sourceMappingURL=remote-catalog-provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-catalog-provider.d.ts","sourceRoot":"","sources":["../../src/core/remote-catalog-provider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"remote-catalog-provider.d.ts","sourceRoot":"","sources":["../../src/core/remote-catalog-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgC,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAKpF,eAAO,MAAM,kCAAkC,QAAqB,CAAC;AAuDrE,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAChC,QAAQ,EAAE,QAAQ,EAClB,cAAc,GAAE,MAAiC,EACjD,eAAe,CAAC,EAAE,GAAG,GACnB,QAAQ,CAoGV"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { stat } from "node:fs/promises";
|
|
1
2
|
import { VERSION } from "../config.js";
|
|
2
3
|
import { getPiUserAgent } from "../utils/pi-user-agent.js";
|
|
3
4
|
const DEFAULT_CATALOG_BASE_URL = "https://pi.dev";
|
|
@@ -23,6 +24,14 @@ function parseCatalog(providerId, value) {
|
|
|
23
24
|
.filter((entry) => typeof entry === "object" && entry !== null && "id" in entry)
|
|
24
25
|
.map((model) => ({ ...model, provider: providerId }));
|
|
25
26
|
}
|
|
27
|
+
function remoteModels(entry, localLastModified) {
|
|
28
|
+
if (!entry)
|
|
29
|
+
return [];
|
|
30
|
+
if (localLastModified !== undefined && (entry.lastModified === undefined || entry.lastModified <= localLastModified)) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
return entry.models;
|
|
34
|
+
}
|
|
26
35
|
function settleOnAbort(operation, signal, canSettle) {
|
|
27
36
|
if (!signal)
|
|
28
37
|
return operation;
|
|
@@ -38,7 +47,7 @@ function settleOnAbort(operation, signal, canSettle) {
|
|
|
38
47
|
});
|
|
39
48
|
}
|
|
40
49
|
/** Add a persisted pi.dev catalog overlay to a static built-in provider. */
|
|
41
|
-
export function withRemoteCatalog(provider, catalogBaseUrl = DEFAULT_CATALOG_BASE_URL) {
|
|
50
|
+
export function withRemoteCatalog(provider, catalogBaseUrl = DEFAULT_CATALOG_BASE_URL, localCatalogUrl) {
|
|
42
51
|
let dynamicModels = [];
|
|
43
52
|
let inflightRefresh;
|
|
44
53
|
let refreshEpoch = 0;
|
|
@@ -82,15 +91,18 @@ export function withRemoteCatalog(provider, catalogBaseUrl = DEFAULT_CATALOG_BAS
|
|
|
82
91
|
}
|
|
83
92
|
};
|
|
84
93
|
const operation = (async () => {
|
|
94
|
+
const localLastModified = localCatalogUrl
|
|
95
|
+
? await stat(localCatalogUrl).then((value) => value.mtimeMs, () => undefined)
|
|
96
|
+
: undefined;
|
|
85
97
|
const stored = await context.store.read();
|
|
86
98
|
if (!isCurrent())
|
|
87
99
|
return;
|
|
88
|
-
|
|
89
|
-
dynamicModels = stored.models.filter((model) => model.provider === provider.id);
|
|
100
|
+
dynamicModels = remoteModels(stored, localLastModified).filter((model) => model.provider === provider.id);
|
|
90
101
|
if (!context.allowNetwork)
|
|
91
102
|
return;
|
|
92
103
|
if (!context.force &&
|
|
93
104
|
stored?.checkedAt !== undefined &&
|
|
105
|
+
stored.lastModified !== undefined &&
|
|
94
106
|
Date.now() - stored.checkedAt < REMOTE_CATALOG_REFRESH_INTERVAL_MS)
|
|
95
107
|
return;
|
|
96
108
|
const url = new URL(`/api/models/providers/${encodeURIComponent(provider.id)}`, catalogBaseUrl);
|
|
@@ -102,19 +114,26 @@ export function withRemoteCatalog(provider, catalogBaseUrl = DEFAULT_CATALOG_BAS
|
|
|
102
114
|
return;
|
|
103
115
|
const checkedAt = Date.now();
|
|
104
116
|
if (response.status === 404 || response.status === 501) {
|
|
105
|
-
await persist({ models:
|
|
117
|
+
await persist({ ...(stored ?? { models: [] }), checkedAt, lastModified: 0 });
|
|
106
118
|
return;
|
|
107
119
|
}
|
|
108
120
|
if (!response.ok) {
|
|
121
|
+
await persist({ ...(stored ?? { models: [] }), checkedAt });
|
|
109
122
|
throw new Error(`Model catalog request failed for ${provider.id}: ${response.status}`);
|
|
110
123
|
}
|
|
111
124
|
const body = await response.json();
|
|
112
125
|
if (!isCurrent())
|
|
113
126
|
return;
|
|
114
127
|
const refreshed = parseCatalog(provider.id, body);
|
|
115
|
-
|
|
128
|
+
const lastModified = Date.parse(response.headers.get("last-modified") ?? "");
|
|
129
|
+
const entry = {
|
|
130
|
+
models: refreshed,
|
|
131
|
+
checkedAt,
|
|
132
|
+
lastModified: Number.isNaN(lastModified) ? 0 : lastModified,
|
|
133
|
+
};
|
|
134
|
+
await persist(entry);
|
|
116
135
|
if (isCurrent())
|
|
117
|
-
dynamicModels =
|
|
136
|
+
dynamicModels = remoteModels(entry, localLastModified);
|
|
118
137
|
})();
|
|
119
138
|
const refresh = settleOnAbort(operation, context.signal, () => !persistenceInProgress);
|
|
120
139
|
const published = refresh.finally(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-catalog-provider.js","sourceRoot":"","sources":["../../src/core/remote-catalog-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model, Provider } from \"@earendil-works/pi-ai\";\nimport { VERSION } from \"../config.ts\";\nimport { getPiUserAgent } from \"../utils/pi-user-agent.ts\";\n\nconst DEFAULT_CATALOG_BASE_URL = \"https://pi.dev\";\nexport const REMOTE_CATALOG_REFRESH_INTERVAL_MS = 4 * 60 * 60 * 1000;\n\nfunction mergeModels(baseline: readonly Model<Api>[], dynamic: readonly Model<Api>[]): Model<Api>[] {\n\tconst merged = [...baseline];\n\tfor (const model of dynamic) {\n\t\tconst index = merged.findIndex((entry) => entry.id === model.id);\n\t\tif (index >= 0) merged[index] = model;\n\t\telse merged.push(model);\n\t}\n\treturn merged;\n}\n\nfunction parseCatalog(providerId: string, value: object): Model<Api>[] {\n\tconst entries = Array.isArray(value)\n\t\t? value\n\t\t: \"models\" in value && Array.isArray(value.models)\n\t\t\t? value.models\n\t\t\t: Object.values(value);\n\treturn entries\n\t\t.filter((entry): entry is Model<Api> => typeof entry === \"object\" && entry !== null && \"id\" in entry)\n\t\t.map((model) => ({ ...model, provider: providerId }));\n}\n\nfunction settleOnAbort(\n\toperation: Promise<void>,\n\tsignal: AbortSignal | undefined,\n\tcanSettle: () => boolean,\n): Promise<void> {\n\tif (!signal) return operation;\n\tif (signal.aborted && canSettle()) return Promise.resolve();\n\treturn new Promise<void>((resolve, reject) => {\n\t\tconst abort = () => {\n\t\t\tif (canSettle()) resolve();\n\t\t};\n\t\tsignal.addEventListener(\"abort\", abort, { once: true });\n\t\toperation.then(resolve, reject).finally(() => signal.removeEventListener(\"abort\", abort));\n\t});\n}\n\ntype RefreshContext = Parameters<NonNullable<Provider[\"refreshModels\"]>>[0];\n\ninterface InflightRefresh {\n\tpromise: Promise<void>;\n\tallowNetwork: boolean;\n\tforce: boolean;\n\tsignal?: AbortSignal;\n}\n/** Add a persisted pi.dev catalog overlay to a static built-in provider. */\nexport function withRemoteCatalog(provider: Provider, catalogBaseUrl: string = DEFAULT_CATALOG_BASE_URL): Provider {\n\tlet dynamicModels: readonly Model<Api>[] = [];\n\tlet inflightRefresh: InflightRefresh | undefined;\n\tlet refreshEpoch = 0;\n\tlet persistenceInProgress = false;\n\n\tconst refreshModels = (context: RefreshContext): Promise<void> => {\n\t\tif (inflightRefresh) {\n\t\t\tconst requiresEscalation = (context.allowNetwork && !inflightRefresh.allowNetwork)\n\t\t\t\t|| (context.force === true && !inflightRefresh.force)\n\t\t\t\t|| (inflightRefresh.signal?.aborted === true && context.signal?.aborted !== true);\n\t\t\tif (requiresEscalation) {\n\t\t\t\tconst startEscalation = () => {\n\t\t\t\t\tif (context.signal?.aborted) return;\n\t\t\t\t\treturn refreshModels(context);\n\t\t\t\t};\n\t\t\t\tconst escalation = inflightRefresh.promise.then(startEscalation, startEscalation);\n\t\t\t\treturn settleOnAbort(escalation, context.signal, () => !persistenceInProgress);\n\t\t\t}\n\t\t\tconst owner = inflightRefresh;\n\t\t\tconst retryAfterAbortedOwner = () => {\n\t\t\t\tif (owner.signal?.aborted && !context.signal?.aborted) return refreshModels(context);\n\t\t\t};\n\t\t\tconst joined = owner.promise.then(retryAfterAbortedOwner, (error) => {\n\t\t\t\tconst retry = retryAfterAbortedOwner();\n\t\t\t\tif (retry) return retry;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t\treturn settleOnAbort(joined, context.signal, () => !persistenceInProgress);\n\t\t}\n\t\tconst epoch = ++refreshEpoch;\n\t\tconst isCurrent = () => epoch === refreshEpoch && !context.signal?.aborted;\n\t\tconst persist = async (entry: Parameters<typeof context.store.write>[0]) => {\n\t\t\tpersistenceInProgress = true;\n\t\t\ttry {\n\t\t\t\tawait context.store.write(entry);\n\t\t\t} finally {\n\t\t\t\tpersistenceInProgress = false;\n\t\t\t}\n\t\t};\n\t\tconst operation = (async () => {\n\t\t\tconst stored = await context.store.read();\n\t\t\tif (!isCurrent()) return;\n\t\t\tif (stored) dynamicModels = stored.models.filter((model) => model.provider === provider.id);\n\t\t\tif (!context.allowNetwork) return;\n\t\t\tif (\n\t\t\t\t!context.force &&\n\t\t\t\tstored?.checkedAt !== undefined &&\n\t\t\t\tDate.now() - stored.checkedAt < REMOTE_CATALOG_REFRESH_INTERVAL_MS\n\t\t\t) return;\n\n\t\t\tconst url = new URL(`/api/models/providers/${encodeURIComponent(provider.id)}`, catalogBaseUrl);\n\t\t\tconst response = await fetch(url, {\n\t\t\t\theaders: { accept: \"application/json\", \"User-Agent\": getPiUserAgent(VERSION) },\n\t\t\t\tsignal: context.signal,\n\t\t\t});\n\t\t\tif (!isCurrent()) return;\n\t\t\tconst checkedAt = Date.now();\n\t\t\tif (response.status === 404 || response.status === 501) {\n\t\t\t\tawait persist({ models: dynamicModels, checkedAt });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Model catalog request failed for ${provider.id}: ${response.status}`);\n\t\t\t}\n\t\t\tconst body: object = await response.json();\n\t\t\tif (!isCurrent()) return;\n\t\t\tconst refreshed = parseCatalog(provider.id, body);\n\t\t\tawait persist({ models: refreshed, checkedAt });\n\t\t\tif (isCurrent()) dynamicModels = refreshed;\n\t\t})();\n\t\tconst refresh = settleOnAbort(operation, context.signal, () => !persistenceInProgress);\n\t\tconst published = refresh.finally(() => {\n\t\t\tif (inflightRefresh?.promise === published) inflightRefresh = undefined;\n\t\t});\n\t\tinflightRefresh = {\n\t\t\tpromise: published,\n\t\t\tallowNetwork: context.allowNetwork,\n\t\t\tforce: context.force === true,\n\t\t\tsignal: context.signal,\n\t\t};\n\t\treturn published;\n\t};\n\n\treturn {\n\t\t...provider,\n\t\tgetModels: () => mergeModels(provider.getModels(), dynamicModels),\n\t\trefreshModels,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remote-catalog-provider.js","sourceRoot":"","sources":["../../src/core/remote-catalog-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { stat } from \"node:fs/promises\";\nimport type { Api, Model, ModelsStoreEntry, Provider } from \"@earendil-works/pi-ai\";\nimport { VERSION } from \"../config.ts\";\nimport { getPiUserAgent } from \"../utils/pi-user-agent.ts\";\n\nconst DEFAULT_CATALOG_BASE_URL = \"https://pi.dev\";\nexport const REMOTE_CATALOG_REFRESH_INTERVAL_MS = 4 * 60 * 60 * 1000;\n\nfunction mergeModels(baseline: readonly Model<Api>[], dynamic: readonly Model<Api>[]): Model<Api>[] {\n\tconst merged = [...baseline];\n\tfor (const model of dynamic) {\n\t\tconst index = merged.findIndex((entry) => entry.id === model.id);\n\t\tif (index >= 0) merged[index] = model;\n\t\telse merged.push(model);\n\t}\n\treturn merged;\n}\n\nfunction parseCatalog(providerId: string, value: object): Model<Api>[] {\n\tconst entries = Array.isArray(value)\n\t\t? value\n\t\t: \"models\" in value && Array.isArray(value.models)\n\t\t\t? value.models\n\t\t\t: Object.values(value);\n\treturn entries\n\t\t.filter((entry): entry is Model<Api> => typeof entry === \"object\" && entry !== null && \"id\" in entry)\n\t\t.map((model) => ({ ...model, provider: providerId }));\n}\n\nfunction remoteModels(entry: ModelsStoreEntry | undefined, localLastModified: number | undefined): readonly Model<Api>[] {\n\tif (!entry) return [];\n\tif (localLastModified !== undefined && (entry.lastModified === undefined || entry.lastModified <= localLastModified)) {\n\t\treturn [];\n\t}\n\treturn entry.models;\n}\n\nfunction settleOnAbort(\n\toperation: Promise<void>,\n\tsignal: AbortSignal | undefined,\n\tcanSettle: () => boolean,\n): Promise<void> {\n\tif (!signal) return operation;\n\tif (signal.aborted && canSettle()) return Promise.resolve();\n\treturn new Promise<void>((resolve, reject) => {\n\t\tconst abort = () => {\n\t\t\tif (canSettle()) resolve();\n\t\t};\n\t\tsignal.addEventListener(\"abort\", abort, { once: true });\n\t\toperation.then(resolve, reject).finally(() => signal.removeEventListener(\"abort\", abort));\n\t});\n}\n\ntype RefreshContext = Parameters<NonNullable<Provider[\"refreshModels\"]>>[0];\n\ninterface InflightRefresh {\n\tpromise: Promise<void>;\n\tallowNetwork: boolean;\n\tforce: boolean;\n\tsignal?: AbortSignal;\n}\n/** Add a persisted pi.dev catalog overlay to a static built-in provider. */\nexport function withRemoteCatalog(\n\tprovider: Provider,\n\tcatalogBaseUrl: string = DEFAULT_CATALOG_BASE_URL,\n\tlocalCatalogUrl?: URL,\n): Provider {\n\tlet dynamicModels: readonly Model<Api>[] = [];\n\tlet inflightRefresh: InflightRefresh | undefined;\n\tlet refreshEpoch = 0;\n\tlet persistenceInProgress = false;\n\n\tconst refreshModels = (context: RefreshContext): Promise<void> => {\n\t\tif (inflightRefresh) {\n\t\t\tconst requiresEscalation = (context.allowNetwork && !inflightRefresh.allowNetwork)\n\t\t\t\t|| (context.force === true && !inflightRefresh.force)\n\t\t\t\t|| (inflightRefresh.signal?.aborted === true && context.signal?.aborted !== true);\n\t\t\tif (requiresEscalation) {\n\t\t\t\tconst startEscalation = () => {\n\t\t\t\t\tif (context.signal?.aborted) return;\n\t\t\t\t\treturn refreshModels(context);\n\t\t\t\t};\n\t\t\t\tconst escalation = inflightRefresh.promise.then(startEscalation, startEscalation);\n\t\t\t\treturn settleOnAbort(escalation, context.signal, () => !persistenceInProgress);\n\t\t\t}\n\t\t\tconst owner = inflightRefresh;\n\t\t\tconst retryAfterAbortedOwner = () => {\n\t\t\t\tif (owner.signal?.aborted && !context.signal?.aborted) return refreshModels(context);\n\t\t\t};\n\t\t\tconst joined = owner.promise.then(retryAfterAbortedOwner, (error) => {\n\t\t\t\tconst retry = retryAfterAbortedOwner();\n\t\t\t\tif (retry) return retry;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t\treturn settleOnAbort(joined, context.signal, () => !persistenceInProgress);\n\t\t}\n\t\tconst epoch = ++refreshEpoch;\n\t\tconst isCurrent = () => epoch === refreshEpoch && !context.signal?.aborted;\n\t\tconst persist = async (entry: Parameters<typeof context.store.write>[0]) => {\n\t\t\tpersistenceInProgress = true;\n\t\t\ttry {\n\t\t\t\tawait context.store.write(entry);\n\t\t\t} finally {\n\t\t\t\tpersistenceInProgress = false;\n\t\t\t}\n\t\t};\n\t\tconst operation = (async () => {\n\t\t\tconst localLastModified = localCatalogUrl\n\t\t\t\t? await stat(localCatalogUrl).then((value) => value.mtimeMs, () => undefined)\n\t\t\t\t: undefined;\n\t\t\tconst stored = await context.store.read();\n\t\t\tif (!isCurrent()) return;\n\t\t\tdynamicModels = remoteModels(stored, localLastModified).filter((model) => model.provider === provider.id);\n\t\t\tif (!context.allowNetwork) return;\n\t\t\tif (\n\t\t\t\t!context.force &&\n\t\t\t\tstored?.checkedAt !== undefined &&\n\t\t\t\tstored.lastModified !== undefined &&\n\t\t\t\tDate.now() - stored.checkedAt < REMOTE_CATALOG_REFRESH_INTERVAL_MS\n\t\t\t) return;\n\n\t\t\tconst url = new URL(`/api/models/providers/${encodeURIComponent(provider.id)}`, catalogBaseUrl);\n\t\t\tconst response = await fetch(url, {\n\t\t\t\theaders: { accept: \"application/json\", \"User-Agent\": getPiUserAgent(VERSION) },\n\t\t\t\tsignal: context.signal,\n\t\t\t});\n\t\t\tif (!isCurrent()) return;\n\t\t\tconst checkedAt = Date.now();\n\t\t\tif (response.status === 404 || response.status === 501) {\n\t\t\t\tawait persist({ ...(stored ?? { models: [] }), checkedAt, lastModified: 0 });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!response.ok) {\n\t\t\t\tawait persist({ ...(stored ?? { models: [] }), checkedAt });\n\t\t\t\tthrow new Error(`Model catalog request failed for ${provider.id}: ${response.status}`);\n\t\t\t}\n\t\t\tconst body: object = await response.json();\n\t\t\tif (!isCurrent()) return;\n\t\t\tconst refreshed = parseCatalog(provider.id, body);\n\t\t\tconst lastModified = Date.parse(response.headers.get(\"last-modified\") ?? \"\");\n\t\t\tconst entry = {\n\t\t\t\tmodels: refreshed,\n\t\t\t\tcheckedAt,\n\t\t\t\tlastModified: Number.isNaN(lastModified) ? 0 : lastModified,\n\t\t\t};\n\t\t\tawait persist(entry);\n\t\t\tif (isCurrent()) dynamicModels = remoteModels(entry, localLastModified);\n\t\t})();\n\t\tconst refresh = settleOnAbort(operation, context.signal, () => !persistenceInProgress);\n\t\tconst published = refresh.finally(() => {\n\t\t\tif (inflightRefresh?.promise === published) inflightRefresh = undefined;\n\t\t});\n\t\tinflightRefresh = {\n\t\t\tpromise: published,\n\t\t\tallowNetwork: context.allowNetwork,\n\t\t\tforce: context.force === true,\n\t\t\tsignal: context.signal,\n\t\t};\n\t\treturn published;\n\t};\n\n\treturn {\n\t\t...provider,\n\t\tgetModels: () => mergeModels(provider.getModels(), dynamicModels),\n\t\trefreshModels,\n\t};\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "./agent-session-runtime.ts";
|
|
2
|
-
export type { ExtensionAPI, ExtensionCommandContext, ExtensionContext, ExtensionFactory, SlashCommandInfo, SlashCommandSource, ToolDefinition, } from "./extensions/index.ts";
|
|
2
|
+
export type { ExtensionAPI, ExtensionCommandContext, ExtensionContext, ExtensionFactory, MessageEndEvent, MessageStartEvent, MessageUpdateEvent, SlashCommandInfo, SlashCommandSource, ToolDefinition, ToolExecutionEndEvent, ToolExecutionStartEvent, ToolExecutionUpdateEvent, } from "./extensions/index.ts";
|
|
3
3
|
export type { PromptTemplate } from "./prompt-templates.ts";
|
|
4
4
|
export type { Skill } from "./skills.ts";
|
|
5
5
|
export type { JsonObject, JsonPrimitive, JsonValue, StructuredOutputCapture, StructuredOutputFileCapture, StructuredOutputToolOptions, Tool, } from "./tools/index.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-exports.d.ts","sourceRoot":"","sources":["../../src/core/sdk-exports.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,YAAY,EACV,YAAY,EACZ,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,
|
|
1
|
+
{"version":3,"file":"sdk-exports.d.ts","sourceRoot":"","sources":["../../src/core/sdk-exports.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,YAAY,EACV,YAAY,EACZ,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EACV,UAAU,EACV,aAAa,EACb,SAAS,EACT,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,IAAI,GACL,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAE3B,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,6BAA6B,EAC7B,0BAA0B,GAC3B,MAAM,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-exports.js","sourceRoot":"","sources":["../../src/core/sdk-exports.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"sdk-exports.js","sourceRoot":"","sources":["../../src/core/sdk-exports.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AA4B3C,OAAO,EACL,qBAAqB,EACrB,2BAA2B;AAC3B,kCAAkC;AAClC,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,6BAA6B,EAC7B,0BAA0B,GAC3B,MAAM,kBAAkB,CAAC","sourcesContent":["export * from \"./agent-session-runtime.ts\";\nexport type {\n ExtensionAPI,\n ExtensionCommandContext,\n ExtensionContext,\n ExtensionFactory,\n MessageEndEvent,\n MessageStartEvent,\n MessageUpdateEvent,\n SlashCommandInfo,\n SlashCommandSource,\n ToolDefinition,\n ToolExecutionEndEvent,\n ToolExecutionStartEvent,\n ToolExecutionUpdateEvent,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type {\n JsonObject,\n JsonPrimitive,\n JsonValue,\n StructuredOutputCapture,\n StructuredOutputFileCapture,\n StructuredOutputToolOptions,\n Tool,\n} from \"./tools/index.ts\";\n\nexport {\n withFileMutationQueue,\n STRUCTURED_OUTPUT_TOOL_NAME,\n // Tool factories (for custom cwd)\n createCodingTools,\n createReadOnlyTools,\n createReadTool,\n createBashTool,\n createEditTool,\n createWriteTool,\n createFindTool,\n createSearchTool,\n createLsTool,\n createStructuredOutputCapture,\n createStructuredOutputTool,\n} from \"./tools/index.ts\";\n\n"]}
|
package/dist/core/sdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1F,YAAY,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1F,cAAc,kBAAkB,CAAC;AA2BjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,wBAAwB,CAAC,CAuYnC"}
|
package/dist/core/sdk.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
-
import { Agent, } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import { Agent, setDefaultStreamFn } from "@earendil-works/pi-agent-core";
|
|
3
3
|
import { clampThinkingLevel, streamSimple, } from "@earendil-works/pi-ai/compat";
|
|
4
4
|
import { getAgentDir } from "../config.js";
|
|
5
5
|
import { resolvePath } from "../utils/paths.js";
|
|
@@ -25,6 +25,9 @@ import { scrubPreCompactionAssistantUsage } from "./provider-context-usage.js";
|
|
|
25
25
|
import { time } from "./timings.js";
|
|
26
26
|
import { defaultToolNames } from "./tools/index.js";
|
|
27
27
|
export * from "./sdk-exports.js";
|
|
28
|
+
// Preserve the pre-0.81 fallback for extensions that construct Agent instances
|
|
29
|
+
// or invoke low-level agent loops without supplying streamFn.
|
|
30
|
+
setDefaultStreamFn(streamSimple);
|
|
28
31
|
// Helper Functions
|
|
29
32
|
function getDefaultAgentDir() {
|
|
30
33
|
return getAgentDir();
|
package/dist/core/sdk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport {\n Agent,\n type AgentMessage,\n type ThinkingLevel,\n} from \"@earendil-works/pi-agent-core\";\nimport {\n clampThinkingLevel,\n type Api,\n type Message,\n type Model,\n streamSimple,\n} from \"@earendil-works/pi-ai/compat\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport {\n shouldApplyCodexFastMode,\n streamWithCodexFastMode,\n withCodexFastModePayload,\n withCodexFastModeStreamOptions,\n} from \"./codex-fast-mode.ts\";\nimport { restoreAnthropicReplayThinkingBlocks } from \"./anthropic-thinking-guard.ts\";\nimport { sanitizeCopilotGeminiPayload } from \"./copilot-gemini-payload-sanitizer.ts\";\nimport { restoreCopilotGeminiReasoningOpaque } from \"./copilot-gemini-reasoning.ts\";\nimport { normalizeCopilotGeminiReplayToolArguments } from \"./copilot-gemini-tool-arguments.ts\";\nimport { getModelDefaultContextWindow, getSupportedContextWindows, selectContextWindow } from \"./context-window.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport type {\n ExtensionRunner,\n} from \"./extensions/index.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel, resolveRestoredModelReference } from \"./model-resolver.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { mergeProviderAttributionHeaders } from \"./provider-attribution.ts\";\nimport { sanitizeOpenAIResponsesPayload } from \"./openai-responses-payload-sanitizer.ts\";\nimport { scrubPreCompactionAssistantUsage } from \"./provider-context-usage.ts\";\nimport { time } from \"./timings.ts\";\nimport { defaultToolNames } from \"./tools/index.ts\";\n\nimport type { CreateAgentSessionOptions, CreateAgentSessionResult } from \"./sdk-types.ts\";\nexport type { CreateAgentSessionOptions, CreateAgentSessionResult } from \"./sdk-types.ts\";\n\nexport * from \"./sdk-exports.ts\";\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n return getAgentDir();\n}\n\ntype ContextWindowRequestSource = \"explicit\" | \"incoming-model\" | \"session\" | \"model-settings\" | \"global-settings\";\n\nconst COPILOT_CONTEXT_WINDOW_SELECTION_OPTIONS = { allowCopilotLongContextFallback: true } as const;\n\nfunction getAlreadyAppliedContextWindow(model: Model<Api>): number | undefined {\n const defaultContextWindow = getModelDefaultContextWindow(model);\n if (model.contextWindow === defaultContextWindow) {\n return undefined;\n }\n\n return getSupportedContextWindows(model).includes(model.contextWindow)\n ? model.contextWindow\n : undefined;\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@earendil-works/pi-ai/compat';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(\n options: CreateAgentSessionOptions = {},\n): Promise<CreateAgentSessionResult> {\n const cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n const agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n let resourceLoader = options.resourceLoader;\n\n // Use provided or create AuthStorage and ModelRegistry. When a modelRegistry\n // is supplied (e.g. a workflow stage reusing one registry across model\n // fallback candidates), do NOT also build a fresh AuthStorage: its\n // constructor eagerly calls reload(), which acquires the auth.json file lock\n // and, under contention, can fail and leave an empty credential set. Reusing\n // the supplied registry's already-loaded auth avoids that race (issue #1431).\n const authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n const modelsPath = options.agentDir\n ? join(agentDir, \"models.json\")\n : undefined;\n const modelRegistry =\n options.modelRegistry ??\n ModelRegistry.create(options.authStorage ?? AuthStorage.create(authPath), modelsPath);\n // Restore persisted provider-owned catalogs before any synchronous model reads.\n await modelRegistry.refresh({ allowNetwork: false });\n\n const settingsManager =\n options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n const sessionManager =\n options.sessionManager ??\n SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\n // Mark workflow-created sessions as internal so they are excluded from the\n // standard `/resume` history while remaining resumable via `/workflow resume`.\n // Only stamped when the orchestration context identifies a workflow stage;\n // reattaching to an already-marked session preserves its existing marker.\n if (options.orchestrationContext?.kind === \"workflow-stage\") {\n const ctx = options.orchestrationContext;\n sessionManager.markSessionInternal({\n runId: ctx.workflowRunId,\n stageId: ctx.workflowStageId,\n stageName: ctx.workflowStageName,\n });\n }\n\n if (!resourceLoader) {\n resourceLoader = new DefaultResourceLoader({\n cwd,\n agentDir,\n settingsManager,\n });\n await resourceLoader.reload();\n time(\"resourceLoader.reload\");\n }\n\n // Check if session has existing data to restore\n const existingSession = sessionManager.buildSessionContext();\n const hasExistingSession = existingSession.messages.length > 0;\n const hasThinkingEntry = sessionManager\n .getBranch()\n .some((entry) => entry.type === \"thinking_level_change\");\n\n let model = options.model;\n let modelFallbackMessage: string | undefined;\n\n // If session has data, try to restore model from it\n if (!model && hasExistingSession && existingSession.model) {\n const restoredModel = await resolveRestoredModelReference(\n existingSession.model.provider,\n existingSession.model.modelId,\n modelRegistry,\n );\n if (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n model = restoredModel;\n }\n if (!model) {\n modelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n }\n }\n\n // If still no model, use findInitialModel (checks settings default, then provider defaults)\n if (!model) {\n const result = await findInitialModel({\n scopedModels: [],\n isContinuing: hasExistingSession,\n defaultProvider: settingsManager.getDefaultProvider(),\n defaultModelId: settingsManager.getDefaultModel(),\n defaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n modelRegistry,\n });\n model = result.model;\n if (!model) {\n modelFallbackMessage = formatNoModelsAvailableMessage();\n } else if (modelFallbackMessage) {\n modelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n }\n }\n\n let thinkingLevel = options.thinkingLevel;\n\n // If session has data, restore thinking level from it\n if (thinkingLevel === undefined && hasExistingSession) {\n thinkingLevel = hasThinkingEntry\n ? (existingSession.thinkingLevel as ThinkingLevel)\n : (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n }\n\n // Fall back to settings default\n if (thinkingLevel === undefined) {\n thinkingLevel =\n settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n }\n\n // Clamp to model capabilities\n if (!model) {\n thinkingLevel = \"off\";\n } else {\n thinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n }\n\n let selectedContextWindow: number | undefined;\n let contextWindowWarning: string | undefined;\n let contextWindowError: string | undefined;\n const explicitContextWindowSelection = options.contextWindow !== undefined;\n const incomingModelContextWindow =\n model && options.model ? getAlreadyAppliedContextWindow(model) : undefined;\n const sessionContextWindow = hasExistingSession ? existingSession.contextWindow : undefined;\n const modelSettingsContextWindow = model ? settingsManager.getDefaultContextWindowForModel(model.provider, model.id) : undefined;\n const globalSettingsContextWindow = settingsManager.getDefaultContextWindow();\n const contextWindowRequest:\n | { contextWindow: number; source: ContextWindowRequestSource }\n | undefined =\n options.contextWindow !== undefined\n ? { contextWindow: options.contextWindow, source: \"explicit\" }\n : incomingModelContextWindow !== undefined\n ? { contextWindow: incomingModelContextWindow, source: \"incoming-model\" }\n : sessionContextWindow !== undefined\n ? { contextWindow: sessionContextWindow, source: \"session\" }\n : modelSettingsContextWindow !== undefined\n ? { contextWindow: modelSettingsContextWindow, source: \"model-settings\" }\n : globalSettingsContextWindow !== undefined\n ? { contextWindow: globalSettingsContextWindow, source: \"global-settings\" }\n : undefined;\n if (model && contextWindowRequest !== undefined) {\n const selected = selectContextWindow(\n model,\n contextWindowRequest.contextWindow,\n COPILOT_CONTEXT_WINDOW_SELECTION_OPTIONS,\n );\n if (\"error\" in selected) {\n if (options.contextWindowStrict) {\n contextWindowError = selected.error;\n } else if (contextWindowRequest.source !== \"global-settings\") {\n contextWindowWarning = selected.error;\n }\n } else {\n model = selected.model;\n selectedContextWindow = selected.contextWindow;\n }\n }\n\n const allowedToolNames =\n options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n const initialActiveToolNames: string[] = options.tools\n ? [...options.tools]\n : options.noTools\n ? []\n : [...defaultToolNames];\n\n let agent: Agent;\n\n let lastConvertedLlmMessages: Message[] | undefined;\n\n // Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n const convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n const converted = convertToLlm(messages);\n // Check setting dynamically so mid-session changes take effect\n if (!settingsManager.getBlockImages()) {\n lastConvertedLlmMessages = converted;\n return converted;\n }\n // Filter out ImageContent from all messages, replacing with text placeholder\n const filtered = converted.map((msg) => {\n if (msg.role === \"user\" || msg.role === \"toolResult\") {\n const content = msg.content;\n if (Array.isArray(content)) {\n const hasImages = content.some((c) => c.type === \"image\");\n if (hasImages) {\n const filteredContent = content\n .map((c) =>\n c.type === \"image\"\n ? {\n type: \"text\" as const,\n text: \"Image reading is disabled.\",\n }\n : c,\n )\n .filter(\n (c, i, arr) =>\n // Dedupe consecutive \"Image reading is disabled.\" texts\n !(\n c.type === \"text\" &&\n c.text === \"Image reading is disabled.\" &&\n i > 0 &&\n arr[i - 1].type === \"text\" &&\n (arr[i - 1] as { type: \"text\"; text: string }).text ===\n \"Image reading is disabled.\"\n ),\n );\n return { ...msg, content: filteredContent };\n }\n }\n }\n return msg;\n });\n lastConvertedLlmMessages = filtered;\n return filtered;\n };\n\n const extensionRunnerRef: { current?: ExtensionRunner } = {};\n const isCodexFastModeEnabled = (requestModel: Model<Api>): boolean =>\n shouldApplyCodexFastMode(\n requestModel,\n settingsManager.getCodexFastModeSettings(),\n options.orchestrationContext,\n );\n\n agent = new Agent({\n initialState: {\n systemPrompt: \"\",\n model,\n thinkingLevel,\n tools: [],\n },\n convertToLlm: convertToLlmWithBlockImages,\n streamFn: async (model, context, streamOptions) => {\n const auth = await modelRegistry.getApiKeyAndHeaders(model);\n if (!auth.ok) {\n throw new Error(auth.error);\n }\n const requestModel = auth.baseUrl !== undefined && auth.baseUrl !== model.baseUrl\n ? { ...model, baseUrl: auth.baseUrl }\n : model;\n const providerRetrySettings = settingsManager.getProviderRetrySettings();\n const httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n // SDKs treat timeout=0 as 0ms (immediate timeout), not \"no timeout\".\n // Use max int32 to effectively disable the timeout.\n const effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n const timeoutMs = streamOptions?.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs;\n const websocketConnectTimeoutMs =\n streamOptions?.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs();\n const attributionHeaders = mergeProviderAttributionHeaders(\n model,\n settingsManager,\n streamOptions?.sessionId,\n auth.headers,\n streamOptions?.headers,\n );\n const fastModeEnabled = isCodexFastModeEnabled(model);\n const codexFastModeStreamOptions = withCodexFastModeStreamOptions(\n {\n ...streamOptions,\n apiKey: auth.apiKey,\n timeoutMs,\n websocketConnectTimeoutMs,\n maxRetries: streamOptions?.maxRetries ?? providerRetrySettings.maxRetries,\n maxRetryDelayMs:\n streamOptions?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n headers: attributionHeaders,\n },\n fastModeEnabled,\n );\n if (modelRegistry.hasRegisteredStreamSimpleForApi(requestModel.api)) {\n return streamSimple(requestModel, context, codexFastModeStreamOptions);\n }\n return streamWithCodexFastMode(requestModel, context, codexFastModeStreamOptions);\n },\n onPayload: async (payload, model) => {\n const fastModeEnabled = isCodexFastModeEnabled(model);\n const guardedPayload = withCodexFastModePayload(payload, fastModeEnabled);\n const sourceMessages = lastConvertedLlmMessages;\n const replayGuardedPayload = sourceMessages\n ? restoreAnthropicReplayThinkingBlocks(guardedPayload, sourceMessages, model)\n : guardedPayload;\n const runner = extensionRunnerRef.current;\n let finalPayload: unknown;\n if (!runner?.hasHandlers(\"before_provider_request\")) {\n finalPayload = replayGuardedPayload;\n } else {\n const extensionPayload = await runner.emitBeforeProviderRequest(\n replayGuardedPayload,\n );\n finalPayload = sourceMessages\n ? restoreAnthropicReplayThinkingBlocks(extensionPayload, sourceMessages, model)\n : extensionPayload;\n }\n // GitHub Copilot Gemini models are served through CAPI, which translates\n // the OpenAI request into Google GenAI and rejects tool schemas whose\n // `anyOf`/`oneOf` wraps a complex object (HTTP 400 invalid request body).\n // Sanitize tool JSON Schemas into Gemini's supported subset. No-op for\n // every other provider/model, and runs last so it also covers tools\n // injected by `before_provider_request` extensions.\n const schemaSanitized = sanitizeCopilotGeminiPayload(finalPayload, model);\n // Reconstruct flattened tool-call arguments on replayed assistant\n // messages (for example `edits[0].newText` -> `edits: [{ newText }]`).\n // CAPI parses replayed arguments straight into Gemini's FunctionCall,\n // and a flattened/malformed prior call ends the next turn with\n // `finish_reason: \"error\"`. No-op for well-formed args / other models.\n const replayArgsNormalized = normalizeCopilotGeminiReplayToolArguments(schemaSanitized, model);\n // CAPI carries Gemini thought signatures in a `reasoning_opaque` field it\n // reads back off the assistant message on replay. Convert the\n // `reasoning_details` the client re-emits (captured inbound by the SSE\n // interceptor) into that field so multi-turn tool use keeps its thought\n // signature instead of dying on an empty completion. No-op otherwise.\n const reasoningRestored = restoreCopilotGeminiReasoningOpaque(replayArgsNormalized, model);\n return sanitizeOpenAIResponsesPayload(reasoningRestored, model);\n },\n onResponse: async (response, _model) => {\n const runner = extensionRunnerRef.current;\n if (!runner?.hasHandlers(\"after_provider_response\")) {\n return;\n }\n await runner.emit({\n type: \"after_provider_response\",\n status: response.status,\n headers: response.headers,\n });\n },\n sessionId: sessionManager.getSessionId(),\n transformContext: async (messages) => {\n const runner = extensionRunnerRef.current;\n const transformed = runner ? await runner.emitContext(messages) : messages;\n return scrubPreCompactionAssistantUsage(transformed, sessionManager.getBranch());\n },\n steeringMode: settingsManager.getSteeringMode(),\n followUpMode: settingsManager.getFollowUpMode(),\n transport: settingsManager.getTransport(),\n thinkingBudgets: settingsManager.getThinkingBudgets(),\n maxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n });\n\n // Restore messages if session has existing data\n if (hasExistingSession) {\n agent.state.messages = existingSession.messages;\n const transcriptContextWindow = model\n ? (existingSession.contextWindow ?? getModelDefaultContextWindow(model))\n : undefined;\n if (\n selectedContextWindow !== undefined &&\n (explicitContextWindowSelection || selectedContextWindow !== transcriptContextWindow)\n ) {\n sessionManager.appendContextWindowChange(selectedContextWindow);\n }\n if (!hasThinkingEntry) {\n sessionManager.appendThinkingLevelChange(thinkingLevel);\n }\n } else {\n // Save initial model and thinking level for new sessions so they can be restored on resume\n if (model) {\n sessionManager.appendModelChange(model.provider, model.id);\n if (\n selectedContextWindow !== undefined &&\n (explicitContextWindowSelection || selectedContextWindow !== getModelDefaultContextWindow(model))\n ) {\n sessionManager.appendContextWindowChange(selectedContextWindow);\n }\n }\n sessionManager.appendThinkingLevelChange(thinkingLevel);\n }\n\n const session = new AgentSession({\n agent,\n sessionManager,\n settingsManager,\n cwd,\n scopedModels: options.scopedModels,\n fallbackModels: options.fallbackModels ?? settingsManager.getFallbackModels(),\n resourceLoader,\n customTools: options.customTools,\n modelRegistry,\n initialActiveToolNames,\n allowedToolNames,\n excludedToolNames: options.excludedTools,\n extensionRunnerRef,\n sessionStartEvent: options.sessionStartEvent,\n orchestrationContext: options.orchestrationContext,\n });\n const extensionsResult = resourceLoader.getExtensions();\n\n return {\n session,\n extensionsResult,\n modelFallbackMessage,\n contextWindowWarning,\n contextWindowError,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { Agent, type AgentMessage, setDefaultStreamFn, type ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport {\n clampThinkingLevel,\n type Api,\n type Message,\n type Model,\n streamSimple,\n} from \"@earendil-works/pi-ai/compat\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport {\n shouldApplyCodexFastMode,\n streamWithCodexFastMode,\n withCodexFastModePayload,\n withCodexFastModeStreamOptions,\n} from \"./codex-fast-mode.ts\";\nimport { restoreAnthropicReplayThinkingBlocks } from \"./anthropic-thinking-guard.ts\";\nimport { sanitizeCopilotGeminiPayload } from \"./copilot-gemini-payload-sanitizer.ts\";\nimport { restoreCopilotGeminiReasoningOpaque } from \"./copilot-gemini-reasoning.ts\";\nimport { normalizeCopilotGeminiReplayToolArguments } from \"./copilot-gemini-tool-arguments.ts\";\nimport { getModelDefaultContextWindow, getSupportedContextWindows, selectContextWindow } from \"./context-window.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport type {\n ExtensionRunner,\n} from \"./extensions/index.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel, resolveRestoredModelReference } from \"./model-resolver.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { mergeProviderAttributionHeaders } from \"./provider-attribution.ts\";\nimport { sanitizeOpenAIResponsesPayload } from \"./openai-responses-payload-sanitizer.ts\";\nimport { scrubPreCompactionAssistantUsage } from \"./provider-context-usage.ts\";\nimport { time } from \"./timings.ts\";\nimport { defaultToolNames } from \"./tools/index.ts\";\n\nimport type { CreateAgentSessionOptions, CreateAgentSessionResult } from \"./sdk-types.ts\";\nexport type { CreateAgentSessionOptions, CreateAgentSessionResult } from \"./sdk-types.ts\";\n\nexport * from \"./sdk-exports.ts\";\n\n// Preserve the pre-0.81 fallback for extensions that construct Agent instances\n// or invoke low-level agent loops without supplying streamFn.\nsetDefaultStreamFn(streamSimple);\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n return getAgentDir();\n}\n\ntype ContextWindowRequestSource = \"explicit\" | \"incoming-model\" | \"session\" | \"model-settings\" | \"global-settings\";\n\nconst COPILOT_CONTEXT_WINDOW_SELECTION_OPTIONS = { allowCopilotLongContextFallback: true } as const;\n\nfunction getAlreadyAppliedContextWindow(model: Model<Api>): number | undefined {\n const defaultContextWindow = getModelDefaultContextWindow(model);\n if (model.contextWindow === defaultContextWindow) {\n return undefined;\n }\n\n return getSupportedContextWindows(model).includes(model.contextWindow)\n ? model.contextWindow\n : undefined;\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@earendil-works/pi-ai/compat';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(\n options: CreateAgentSessionOptions = {},\n): Promise<CreateAgentSessionResult> {\n const cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n const agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n let resourceLoader = options.resourceLoader;\n\n // Use provided or create AuthStorage and ModelRegistry. When a modelRegistry\n // is supplied (e.g. a workflow stage reusing one registry across model\n // fallback candidates), do NOT also build a fresh AuthStorage: its\n // constructor eagerly calls reload(), which acquires the auth.json file lock\n // and, under contention, can fail and leave an empty credential set. Reusing\n // the supplied registry's already-loaded auth avoids that race (issue #1431).\n const authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n const modelsPath = options.agentDir\n ? join(agentDir, \"models.json\")\n : undefined;\n const modelRegistry =\n options.modelRegistry ??\n ModelRegistry.create(options.authStorage ?? AuthStorage.create(authPath), modelsPath);\n // Restore persisted provider-owned catalogs before any synchronous model reads.\n await modelRegistry.refresh({ allowNetwork: false });\n\n const settingsManager =\n options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n const sessionManager =\n options.sessionManager ??\n SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\n // Mark workflow-created sessions as internal so they are excluded from the\n // standard `/resume` history while remaining resumable via `/workflow resume`.\n // Only stamped when the orchestration context identifies a workflow stage;\n // reattaching to an already-marked session preserves its existing marker.\n if (options.orchestrationContext?.kind === \"workflow-stage\") {\n const ctx = options.orchestrationContext;\n sessionManager.markSessionInternal({\n runId: ctx.workflowRunId,\n stageId: ctx.workflowStageId,\n stageName: ctx.workflowStageName,\n });\n }\n\n if (!resourceLoader) {\n resourceLoader = new DefaultResourceLoader({\n cwd,\n agentDir,\n settingsManager,\n });\n await resourceLoader.reload();\n time(\"resourceLoader.reload\");\n }\n\n // Check if session has existing data to restore\n const existingSession = sessionManager.buildSessionContext();\n const hasExistingSession = existingSession.messages.length > 0;\n const hasThinkingEntry = sessionManager\n .getBranch()\n .some((entry) => entry.type === \"thinking_level_change\");\n\n let model = options.model;\n let modelFallbackMessage: string | undefined;\n\n // If session has data, try to restore model from it\n if (!model && hasExistingSession && existingSession.model) {\n const restoredModel = await resolveRestoredModelReference(\n existingSession.model.provider,\n existingSession.model.modelId,\n modelRegistry,\n );\n if (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n model = restoredModel;\n }\n if (!model) {\n modelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n }\n }\n\n // If still no model, use findInitialModel (checks settings default, then provider defaults)\n if (!model) {\n const result = await findInitialModel({\n scopedModels: [],\n isContinuing: hasExistingSession,\n defaultProvider: settingsManager.getDefaultProvider(),\n defaultModelId: settingsManager.getDefaultModel(),\n defaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n modelRegistry,\n });\n model = result.model;\n if (!model) {\n modelFallbackMessage = formatNoModelsAvailableMessage();\n } else if (modelFallbackMessage) {\n modelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n }\n }\n\n let thinkingLevel = options.thinkingLevel;\n\n // If session has data, restore thinking level from it\n if (thinkingLevel === undefined && hasExistingSession) {\n thinkingLevel = hasThinkingEntry\n ? (existingSession.thinkingLevel as ThinkingLevel)\n : (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n }\n\n // Fall back to settings default\n if (thinkingLevel === undefined) {\n thinkingLevel =\n settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n }\n\n // Clamp to model capabilities\n if (!model) {\n thinkingLevel = \"off\";\n } else {\n thinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n }\n\n let selectedContextWindow: number | undefined;\n let contextWindowWarning: string | undefined;\n let contextWindowError: string | undefined;\n const explicitContextWindowSelection = options.contextWindow !== undefined;\n const incomingModelContextWindow =\n model && options.model ? getAlreadyAppliedContextWindow(model) : undefined;\n const sessionContextWindow = hasExistingSession ? existingSession.contextWindow : undefined;\n const modelSettingsContextWindow = model ? settingsManager.getDefaultContextWindowForModel(model.provider, model.id) : undefined;\n const globalSettingsContextWindow = settingsManager.getDefaultContextWindow();\n const contextWindowRequest:\n | { contextWindow: number; source: ContextWindowRequestSource }\n | undefined =\n options.contextWindow !== undefined\n ? { contextWindow: options.contextWindow, source: \"explicit\" }\n : incomingModelContextWindow !== undefined\n ? { contextWindow: incomingModelContextWindow, source: \"incoming-model\" }\n : sessionContextWindow !== undefined\n ? { contextWindow: sessionContextWindow, source: \"session\" }\n : modelSettingsContextWindow !== undefined\n ? { contextWindow: modelSettingsContextWindow, source: \"model-settings\" }\n : globalSettingsContextWindow !== undefined\n ? { contextWindow: globalSettingsContextWindow, source: \"global-settings\" }\n : undefined;\n if (model && contextWindowRequest !== undefined) {\n const selected = selectContextWindow(\n model,\n contextWindowRequest.contextWindow,\n COPILOT_CONTEXT_WINDOW_SELECTION_OPTIONS,\n );\n if (\"error\" in selected) {\n if (options.contextWindowStrict) {\n contextWindowError = selected.error;\n } else if (contextWindowRequest.source !== \"global-settings\") {\n contextWindowWarning = selected.error;\n }\n } else {\n model = selected.model;\n selectedContextWindow = selected.contextWindow;\n }\n }\n\n const allowedToolNames =\n options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n const initialActiveToolNames: string[] = options.tools\n ? [...options.tools]\n : options.noTools\n ? []\n : [...defaultToolNames];\n\n let agent: Agent;\n\n let lastConvertedLlmMessages: Message[] | undefined;\n\n // Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n const convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n const converted = convertToLlm(messages);\n // Check setting dynamically so mid-session changes take effect\n if (!settingsManager.getBlockImages()) {\n lastConvertedLlmMessages = converted;\n return converted;\n }\n // Filter out ImageContent from all messages, replacing with text placeholder\n const filtered = converted.map((msg) => {\n if (msg.role === \"user\" || msg.role === \"toolResult\") {\n const content = msg.content;\n if (Array.isArray(content)) {\n const hasImages = content.some((c) => c.type === \"image\");\n if (hasImages) {\n const filteredContent = content\n .map((c) =>\n c.type === \"image\"\n ? {\n type: \"text\" as const,\n text: \"Image reading is disabled.\",\n }\n : c,\n )\n .filter(\n (c, i, arr) =>\n // Dedupe consecutive \"Image reading is disabled.\" texts\n !(\n c.type === \"text\" &&\n c.text === \"Image reading is disabled.\" &&\n i > 0 &&\n arr[i - 1].type === \"text\" &&\n (arr[i - 1] as { type: \"text\"; text: string }).text ===\n \"Image reading is disabled.\"\n ),\n );\n return { ...msg, content: filteredContent };\n }\n }\n }\n return msg;\n });\n lastConvertedLlmMessages = filtered;\n return filtered;\n };\n\n const extensionRunnerRef: { current?: ExtensionRunner } = {};\n const isCodexFastModeEnabled = (requestModel: Model<Api>): boolean =>\n shouldApplyCodexFastMode(\n requestModel,\n settingsManager.getCodexFastModeSettings(),\n options.orchestrationContext,\n );\n\n agent = new Agent({\n initialState: {\n systemPrompt: \"\",\n model,\n thinkingLevel,\n tools: [],\n },\n convertToLlm: convertToLlmWithBlockImages,\n streamFn: async (model, context, streamOptions) => {\n const auth = await modelRegistry.getApiKeyAndHeaders(model);\n if (!auth.ok) {\n throw new Error(auth.error);\n }\n const requestModel = auth.baseUrl !== undefined && auth.baseUrl !== model.baseUrl\n ? { ...model, baseUrl: auth.baseUrl }\n : model;\n const providerRetrySettings = settingsManager.getProviderRetrySettings();\n const httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n // SDKs treat timeout=0 as 0ms (immediate timeout), not \"no timeout\".\n // Use max int32 to effectively disable the timeout.\n const effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n const timeoutMs = streamOptions?.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs;\n const websocketConnectTimeoutMs =\n streamOptions?.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs();\n const attributionHeaders = mergeProviderAttributionHeaders(\n model,\n settingsManager,\n streamOptions?.sessionId,\n auth.headers,\n streamOptions?.headers,\n );\n const fastModeEnabled = isCodexFastModeEnabled(model);\n const codexFastModeStreamOptions = withCodexFastModeStreamOptions(\n {\n ...streamOptions,\n apiKey: auth.apiKey,\n timeoutMs,\n websocketConnectTimeoutMs,\n maxRetries: streamOptions?.maxRetries ?? providerRetrySettings.maxRetries,\n maxRetryDelayMs:\n streamOptions?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n headers: attributionHeaders,\n },\n fastModeEnabled,\n );\n if (modelRegistry.hasRegisteredStreamSimpleForApi(requestModel.api)) {\n return streamSimple(requestModel, context, codexFastModeStreamOptions);\n }\n return streamWithCodexFastMode(requestModel, context, codexFastModeStreamOptions);\n },\n onPayload: async (payload, model) => {\n const fastModeEnabled = isCodexFastModeEnabled(model);\n const guardedPayload = withCodexFastModePayload(payload, fastModeEnabled);\n const sourceMessages = lastConvertedLlmMessages;\n const replayGuardedPayload = sourceMessages\n ? restoreAnthropicReplayThinkingBlocks(guardedPayload, sourceMessages, model)\n : guardedPayload;\n const runner = extensionRunnerRef.current;\n let finalPayload: unknown;\n if (!runner?.hasHandlers(\"before_provider_request\")) {\n finalPayload = replayGuardedPayload;\n } else {\n const extensionPayload = await runner.emitBeforeProviderRequest(\n replayGuardedPayload,\n );\n finalPayload = sourceMessages\n ? restoreAnthropicReplayThinkingBlocks(extensionPayload, sourceMessages, model)\n : extensionPayload;\n }\n // GitHub Copilot Gemini models are served through CAPI, which translates\n // the OpenAI request into Google GenAI and rejects tool schemas whose\n // `anyOf`/`oneOf` wraps a complex object (HTTP 400 invalid request body).\n // Sanitize tool JSON Schemas into Gemini's supported subset. No-op for\n // every other provider/model, and runs last so it also covers tools\n // injected by `before_provider_request` extensions.\n const schemaSanitized = sanitizeCopilotGeminiPayload(finalPayload, model);\n // Reconstruct flattened tool-call arguments on replayed assistant\n // messages (for example `edits[0].newText` -> `edits: [{ newText }]`).\n // CAPI parses replayed arguments straight into Gemini's FunctionCall,\n // and a flattened/malformed prior call ends the next turn with\n // `finish_reason: \"error\"`. No-op for well-formed args / other models.\n const replayArgsNormalized = normalizeCopilotGeminiReplayToolArguments(schemaSanitized, model);\n // CAPI carries Gemini thought signatures in a `reasoning_opaque` field it\n // reads back off the assistant message on replay. Convert the\n // `reasoning_details` the client re-emits (captured inbound by the SSE\n // interceptor) into that field so multi-turn tool use keeps its thought\n // signature instead of dying on an empty completion. No-op otherwise.\n const reasoningRestored = restoreCopilotGeminiReasoningOpaque(replayArgsNormalized, model);\n return sanitizeOpenAIResponsesPayload(reasoningRestored, model);\n },\n onResponse: async (response, _model) => {\n const runner = extensionRunnerRef.current;\n if (!runner?.hasHandlers(\"after_provider_response\")) {\n return;\n }\n await runner.emit({\n type: \"after_provider_response\",\n status: response.status,\n headers: response.headers,\n });\n },\n sessionId: sessionManager.getSessionId(),\n transformContext: async (messages) => {\n const runner = extensionRunnerRef.current;\n const transformed = runner ? await runner.emitContext(messages) : messages;\n return scrubPreCompactionAssistantUsage(transformed, sessionManager.getBranch());\n },\n steeringMode: settingsManager.getSteeringMode(),\n followUpMode: settingsManager.getFollowUpMode(),\n transport: settingsManager.getTransport(),\n thinkingBudgets: settingsManager.getThinkingBudgets(),\n maxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n });\n\n // Restore messages if session has existing data\n if (hasExistingSession) {\n agent.state.messages = existingSession.messages;\n const transcriptContextWindow = model\n ? (existingSession.contextWindow ?? getModelDefaultContextWindow(model))\n : undefined;\n if (\n selectedContextWindow !== undefined &&\n (explicitContextWindowSelection || selectedContextWindow !== transcriptContextWindow)\n ) {\n sessionManager.appendContextWindowChange(selectedContextWindow);\n }\n if (!hasThinkingEntry) {\n sessionManager.appendThinkingLevelChange(thinkingLevel);\n }\n } else {\n // Save initial model and thinking level for new sessions so they can be restored on resume\n if (model) {\n sessionManager.appendModelChange(model.provider, model.id);\n if (\n selectedContextWindow !== undefined &&\n (explicitContextWindowSelection || selectedContextWindow !== getModelDefaultContextWindow(model))\n ) {\n sessionManager.appendContextWindowChange(selectedContextWindow);\n }\n }\n sessionManager.appendThinkingLevelChange(thinkingLevel);\n }\n\n const session = new AgentSession({\n agent,\n sessionManager,\n settingsManager,\n cwd,\n scopedModels: options.scopedModels,\n fallbackModels: options.fallbackModels ?? settingsManager.getFallbackModels(),\n resourceLoader,\n customTools: options.customTools,\n modelRegistry,\n initialActiveToolNames,\n allowedToolNames,\n excludedToolNames: options.excludedTools,\n extensionRunnerRef,\n sessionStartEvent: options.sessionStartEvent,\n orchestrationContext: options.orchestrationContext,\n });\n const extensionsResult = resourceLoader.getExtensions();\n\n return {\n session,\n extensionsResult,\n modelFallbackMessage,\n contextWindowWarning,\n contextWindowError,\n };\n}\n"]}
|
|
@@ -18,6 +18,7 @@ export declare class SessionManager {
|
|
|
18
18
|
private constructor();
|
|
19
19
|
/** Switch to a different session file (used for resume and branching) */
|
|
20
20
|
setSessionFile(sessionFile: string): void;
|
|
21
|
+
private _setSessionFile;
|
|
21
22
|
newSession(options?: NewSessionOptions): string | undefined;
|
|
22
23
|
/** Mark the session as workflow-owned, repairing malformed markers while preserving valid ownership. */
|
|
23
24
|
markSessionInternal(workflow?: SessionWorkflowMetadata): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-manager-core.d.ts","sourceRoot":"","sources":["../../src/core/session-manager-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAIvF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAuCzE,OAAO,KAAK,EAGX,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,eAAe,EACf,uBAAuB,EACvB,MAAM,4BAA4B,CAAC;AAGpC,qfAAqf;AACrf,qBAAa,cAAc;IAC1B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,WAAW,CAAmB;IACtC,OAAO,CAAC,IAAI,CAAwC;IACpD,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,mBAAmB,CAAkC;IAC7D,OAAO,CAAC,MAAM,CAAuB;IAErC,OAAO,
|
|
1
|
+
{"version":3,"file":"session-manager-core.d.ts","sourceRoot":"","sources":["../../src/core/session-manager-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAIvF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAuCzE,OAAO,KAAK,EAGX,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,eAAe,EACf,uBAAuB,EACvB,MAAM,4BAA4B,CAAC;AAGpC,qfAAqf;AACrf,qBAAa,cAAc;IAC1B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,WAAW,CAAmB;IACtC,OAAO,CAAC,IAAI,CAAwC;IACpD,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,mBAAmB,CAAkC;IAC7D,OAAO,CAAC,MAAM,CAAuB;IAErC,OAAO,eAoBN;IAED,yEAAyE;IACzE,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAExC;IAED,OAAO,CAAC,eAAe;IAkCvB,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAyB1D;IAED,wGAAwG;IACxG,mBAAmB,CAAC,QAAQ,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAQ5D;IAED,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,YAAY;IAKpB,WAAW,IAAI,OAAO,CAErB;IAED,MAAM,IAAI,MAAM,CAEf;IAED,aAAa,IAAI,MAAM,CAEtB;IAED,qBAAqB,IAAI,OAAO,CAE/B;IAED,YAAY,IAAI,MAAM,CAErB;IAED,cAAc,IAAI,MAAM,GAAG,SAAS,CAEnC;IAED,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAelC;IAED,OAAO,CAAC,YAAY;IAOpB,sFAAsF;IACtF,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,GAAG,oBAAoB,GAAG,MAAM,CAI7E;IAED,oGAAoG;IACpG,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAIvD;IAED,oGAAoG;IACpG,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAIvD;IAED,2FAA2F;IAC3F,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAI3D;IACD,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,GAAG,MAAM,CAKzI;IAED,qGAAqG;IACrG,mBAAmB,CAAC,KAAK,SAAY,GAAG,MAAM,GAAG,SAAS,CAGzD;IAED,4GAA4G;IAC5G,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAI5D;IAED,0EAA0E;IAC1E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAItC;IAED,+EAA+E;IAC/E,cAAc,IAAI,MAAM,GAAG,SAAS,CAEnC;IAED,uGAAuG;IACvG,wBAAwB,CAAC,CAAC,GAAG,OAAO,EACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,EAChD,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,CAAC,EACX,kBAAkB,CAAC,EAAE,OAAO,GAC1B,MAAM,CAIR;IAED,SAAS,IAAI,MAAM,GAAG,IAAI,CAEzB;IAED,YAAY,IAAI,YAAY,GAAG,SAAS,CAEvC;IAED,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAE7C;IAED,2CAA2C;IAC3C,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAQ5C;IAED,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;IAED,wCAAwC;IACxC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAcrE;IAED,oEAAoE;IACpE,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAEzC;IAED,6DAA6D;IAC7D,mBAAmB,IAAI,cAAc,CAEpC;IAED,0BAA0B;IAC1B,SAAS,IAAI,aAAa,GAAG,IAAI,CAGhC;IAED,yEAAyE;IACzE,UAAU,IAAI,YAAY,EAAE,CAE3B;IAED,4FAA4F;IAC5F,OAAO,IAAI,eAAe,EAAE,CAE3B;IAED,gDAAgD;IAChD,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAKjC;IAED,2DAA2D;IAC3D,SAAS,IAAI,IAAI,CAEhB;IAED,+DAA+D;IAC/D,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAQ7G;IAED,0FAA0F;IAC1F,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAuBxD;IAED,4BAA4B;IAC5B,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,cAAc,CAG3F;IAED,oCAAoC;IACpC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,cAAc,CAOnF;IAED,0GAA0G;IAC1G,MAAM,CAAC,cAAc,CACpB,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACrC,cAAc,CAShB;IAED,wDAAwD;IACxD,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAE,MAAsB,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,cAAc,CAExF;IAED,8EAA8E;IAC9E,MAAM,CAAC,QAAQ,CACd,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,iBAAiB,GACzB,cAAc,CAGhB;IAED,+GAA+G;IAC/G,OAAa,IAAI,CAChB,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,mBAAmB,EAChC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACrC,OAAO,CAAC,WAAW,EAAE,CAAC,CAExB;IAED,sHAAsH;IACtH,OAAa,OAAO,CAAC,UAAU,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/E,OAAa,OAAO,CACnB,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,mBAAmB,EAChC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACrC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;CAQ1B"}
|
|
@@ -12,7 +12,7 @@ import { appendSessionEntries, appendSessionEntry, ensureDirectory, findMostRece
|
|
|
12
12
|
import { assertValidSessionId, createSessionId } from "./session-manager-validation.js";
|
|
13
13
|
/** Manages conversation sessions as append-only trees stored in JSONL files. Each session entry has an id and parentId forming a tree structure. The "leaf" pointer tracks the current position. Appending creates a child of the current leaf. Branching moves the leaf to an earlier entry, allowing new branches without modifying history. Use buildSessionContext() to get the resolved message list for the LLM, which applies context-deletion filtering and follows the path from root to current leaf. */
|
|
14
14
|
export class SessionManager {
|
|
15
|
-
constructor(cwd, sessionDir, sessionFile, persist, newSessionOptions) {
|
|
15
|
+
constructor(cwd, sessionDir, sessionFile, persist, newSessionOptions, preloadedFileEntries) {
|
|
16
16
|
this.sessionId = "";
|
|
17
17
|
this.flushed = false;
|
|
18
18
|
this.fileEntries = [];
|
|
@@ -27,7 +27,7 @@ export class SessionManager {
|
|
|
27
27
|
ensureDirectory(this.sessionDir);
|
|
28
28
|
}
|
|
29
29
|
if (sessionFile) {
|
|
30
|
-
this.
|
|
30
|
+
this._setSessionFile(sessionFile, preloadedFileEntries);
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
33
|
this.newSession(newSessionOptions);
|
|
@@ -35,9 +35,12 @@ export class SessionManager {
|
|
|
35
35
|
}
|
|
36
36
|
/** Switch to a different session file (used for resume and branching) */
|
|
37
37
|
setSessionFile(sessionFile) {
|
|
38
|
+
this._setSessionFile(sessionFile);
|
|
39
|
+
}
|
|
40
|
+
_setSessionFile(sessionFile, preloadedFileEntries) {
|
|
38
41
|
this.sessionFile = resolvePath(sessionFile);
|
|
39
42
|
if (existsSync(this.sessionFile)) {
|
|
40
|
-
this.fileEntries = loadEntriesFromFile(this.sessionFile);
|
|
43
|
+
this.fileEntries = preloadedFileEntries ?? loadEntriesFromFile(this.sessionFile);
|
|
41
44
|
// If file was empty, initialize it with a valid session header. If it was non-empty but did not parse as a pi session, fail without modifying it.
|
|
42
45
|
if (this.fileEntries.length === 0) {
|
|
43
46
|
const explicitPath = this.sessionFile;
|
|
@@ -326,7 +329,7 @@ export class SessionManager {
|
|
|
326
329
|
const header = entries.find((entry) => entry.type === "session");
|
|
327
330
|
const cwd = cwdOverride ?? header?.cwd ?? process.cwd();
|
|
328
331
|
const dir = sessionDir ? normalizePath(sessionDir) : resolve(resolvedPath, "..");
|
|
329
|
-
return new SessionManager(cwd, dir, resolvedPath, true);
|
|
332
|
+
return new SessionManager(cwd, dir, resolvedPath, true, undefined, entries);
|
|
330
333
|
}
|
|
331
334
|
/** Continue the most recent session (skips internal workflow sessions unless `includeInternal: true`). */
|
|
332
335
|
static continueRecent(cwd, sessionDir, options) {
|