@xandout/libra-harness 0.1.34 → 0.1.91
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/README.md +30 -30
- package/dist/agent.d.ts +8 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +205 -193
- package/dist/agent.js.map +1 -1
- package/dist/ai-sdk-model.d.ts.map +1 -1
- package/dist/ai-sdk-model.js +91 -78
- package/dist/ai-sdk-model.js.map +1 -1
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/{extras/extensions → extensions}/auto-steer/extension.d.ts +1 -1
- package/dist/extensions/auto-steer/extension.d.ts.map +1 -0
- package/dist/extensions/auto-steer/extension.js.map +1 -0
- package/dist/extensions/auto-steer/index.d.ts.map +1 -0
- package/dist/extensions/auto-steer/index.js.map +1 -0
- package/dist/extensions/code-tools/extension.d.ts +15 -0
- package/dist/extensions/code-tools/extension.d.ts.map +1 -0
- package/dist/extensions/code-tools/extension.js +73 -0
- package/dist/extensions/code-tools/extension.js.map +1 -0
- package/dist/extensions/code-tools/extension.test.d.ts.map +1 -0
- package/dist/extensions/code-tools/extension.test.js +504 -0
- package/dist/extensions/code-tools/extension.test.js.map +1 -0
- package/dist/extensions/code-tools/index.d.ts.map +1 -0
- package/dist/extensions/code-tools/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/code-tools/tools/code-search.d.ts +2 -2
- package/dist/extensions/code-tools/tools/code-search.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/code-tools/tools/code-search.js +1 -1
- package/dist/extensions/code-tools/tools/code-search.js.map +1 -0
- package/dist/extensions/code-tools/tools/find.d.ts.map +1 -0
- package/dist/extensions/code-tools/tools/find.js +83 -0
- package/dist/extensions/code-tools/tools/find.js.map +1 -0
- package/dist/extensions/code-tools/tools/grep.d.ts.map +1 -0
- package/dist/extensions/code-tools/tools/grep.js +90 -0
- package/dist/extensions/code-tools/tools/grep.js.map +1 -0
- package/dist/extensions/code-tools/tools/read.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/code-tools/tools/read.js +17 -25
- package/dist/extensions/code-tools/tools/read.js.map +1 -0
- package/dist/{extras/extensions → extensions}/code-tools/tools/shared.d.ts +5 -1
- package/dist/extensions/code-tools/tools/shared.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/code-tools/tools/shared.js +68 -0
- package/dist/extensions/code-tools/tools/shared.js.map +1 -0
- package/dist/extensions/code-tools/tools/shell.d.ts +39 -0
- package/dist/extensions/code-tools/tools/shell.d.ts.map +1 -0
- package/dist/extensions/code-tools/tools/shell.js +441 -0
- package/dist/extensions/code-tools/tools/shell.js.map +1 -0
- package/dist/{extras/extensions → extensions}/code-tools/tools/todo.d.ts +0 -3
- package/dist/extensions/code-tools/tools/todo.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/code-tools/tools/todo.js +0 -8
- package/dist/extensions/code-tools/tools/todo.js.map +1 -0
- package/dist/extensions/code-tools/tools/view-image.d.ts +10 -0
- package/dist/extensions/code-tools/tools/view-image.d.ts.map +1 -0
- package/dist/extensions/code-tools/tools/view-image.js +87 -0
- package/dist/extensions/code-tools/tools/view-image.js.map +1 -0
- package/dist/extensions/code-tools/tools/write.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/code-tools/tools/write.js +47 -37
- package/dist/extensions/code-tools/tools/write.js.map +1 -0
- package/dist/{extras/extensions → extensions}/disk-session/extension.d.ts +45 -2
- package/dist/extensions/disk-session/extension.d.ts.map +1 -0
- package/dist/extensions/disk-session/extension.js +818 -0
- package/dist/extensions/disk-session/extension.js.map +1 -0
- package/dist/extensions/disk-session/extension.test.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/disk-session/extension.test.js +445 -16
- package/dist/extensions/disk-session/extension.test.js.map +1 -0
- package/dist/extensions/disk-session/index.d.ts +3 -0
- package/dist/extensions/disk-session/index.d.ts.map +1 -0
- package/dist/extensions/disk-session/index.js +2 -0
- package/dist/extensions/disk-session/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/emoji/extension.d.ts +1 -1
- package/dist/extensions/emoji/extension.d.ts.map +1 -0
- package/dist/extensions/emoji/extension.js.map +1 -0
- package/dist/extensions/emoji/index.d.ts.map +1 -0
- package/dist/extensions/emoji/index.js.map +1 -0
- package/dist/extensions/filesystem/extension.d.ts.map +1 -0
- package/dist/extensions/filesystem/extension.js.map +1 -0
- package/dist/extensions/filesystem/extension.test.d.ts.map +1 -0
- package/dist/extensions/filesystem/extension.test.js.map +1 -0
- package/dist/extensions/filesystem/index.d.ts.map +1 -0
- package/dist/extensions/filesystem/index.js.map +1 -0
- package/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +2 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/keyword-extractor/extension.d.ts +1 -1
- package/dist/extensions/keyword-extractor/extension.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/keyword-extractor/extension.js +1 -1
- package/dist/extensions/keyword-extractor/extension.js.map +1 -0
- package/dist/extensions/keyword-extractor/extension.test.d.ts.map +1 -0
- package/dist/extensions/keyword-extractor/extension.test.js.map +1 -0
- package/dist/extensions/keyword-extractor/index.d.ts.map +1 -0
- package/dist/extensions/keyword-extractor/index.js.map +1 -0
- package/dist/extensions/keyword-extractor/nlp.d.ts.map +1 -0
- package/dist/extensions/keyword-extractor/nlp.js.map +1 -0
- package/dist/extensions/keyword-extractor/nlp.test.d.ts.map +1 -0
- package/dist/extensions/keyword-extractor/nlp.test.js.map +1 -0
- package/dist/{extras/extension-loader.d.ts → extensions/loader.d.ts} +1 -1
- package/dist/extensions/loader.d.ts.map +1 -0
- package/dist/{extras/extension-loader.js → extensions/loader.js} +2 -2
- package/dist/extensions/loader.js.map +1 -0
- package/dist/{extras/extensions → extensions}/logger/extension.d.ts +1 -1
- package/dist/extensions/logger/extension.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/logger/extension.js +1 -1
- package/dist/extensions/logger/extension.js.map +1 -0
- package/dist/extensions/logger/index.d.ts.map +1 -0
- package/dist/extensions/logger/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/mcp/extension.d.ts +1 -1
- package/dist/extensions/mcp/extension.d.ts.map +1 -0
- package/dist/extensions/mcp/extension.js.map +1 -0
- package/dist/extensions/mcp/extension.test.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/mcp/extension.test.js +1 -1
- package/dist/extensions/mcp/extension.test.js.map +1 -0
- package/dist/extensions/mcp/index.d.ts.map +1 -0
- package/dist/extensions/mcp/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/mem-session/extension.d.ts +2 -2
- package/dist/extensions/mem-session/extension.d.ts.map +1 -0
- package/dist/extensions/mem-session/extension.js.map +1 -0
- package/dist/extensions/mem-session/index.d.ts.map +1 -0
- package/dist/extensions/mem-session/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/memory/extension.d.ts +1 -1
- package/dist/extensions/memory/extension.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/memory/extension.js +1 -1
- package/dist/extensions/memory/extension.js.map +1 -0
- package/dist/extensions/memory/index.d.ts +4 -0
- package/dist/extensions/memory/index.d.ts.map +1 -0
- package/dist/extensions/memory/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/memory/llm-extractor.d.ts +1 -1
- package/dist/extensions/memory/llm-extractor.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/memory/llm-extractor.js +1 -1
- package/dist/extensions/memory/llm-extractor.js.map +1 -0
- package/dist/{extras/extensions → extensions}/memory/types.d.ts +2 -2
- package/dist/extensions/memory/types.d.ts.map +1 -0
- package/dist/extensions/memory/types.js.map +1 -0
- package/dist/{extras/extensions → extensions}/otel/extension.d.ts +1 -1
- package/dist/extensions/otel/extension.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/otel/extension.js +1 -1
- package/dist/extensions/otel/extension.js.map +1 -0
- package/dist/extensions/otel/extension.test.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/otel/extension.test.js +1 -1
- package/dist/extensions/otel/extension.test.js.map +1 -0
- package/dist/extensions/otel/index.d.ts.map +1 -0
- package/dist/extensions/otel/index.js.map +1 -0
- package/dist/extensions/otel/jsonl-span-exporter.d.ts.map +1 -0
- package/dist/extensions/otel/jsonl-span-exporter.js.map +1 -0
- package/dist/{extras/extensions → extensions}/scripts/extension.d.ts +1 -1
- package/dist/extensions/scripts/extension.d.ts.map +1 -0
- package/dist/extensions/scripts/extension.js.map +1 -0
- package/dist/extensions/scripts/extension.test.d.ts.map +1 -0
- package/dist/extensions/scripts/extension.test.js.map +1 -0
- package/dist/extensions/scripts/index.d.ts.map +1 -0
- package/dist/extensions/scripts/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/skills/extension.d.ts +1 -1
- package/dist/extensions/skills/extension.d.ts.map +1 -0
- package/dist/extensions/skills/extension.js.map +1 -0
- package/dist/extensions/skills/extension.test.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/skills/extension.test.js +1 -1
- package/dist/extensions/skills/extension.test.js.map +1 -0
- package/dist/extensions/skills/index.d.ts.map +1 -0
- package/dist/extensions/skills/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/streaming/extension.d.ts +1 -1
- package/dist/extensions/streaming/extension.d.ts.map +1 -0
- package/dist/extensions/streaming/extension.js.map +1 -0
- package/dist/extensions/streaming/index.d.ts.map +1 -0
- package/dist/extensions/streaming/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/structured-output/extension.d.ts +1 -1
- package/dist/extensions/structured-output/extension.d.ts.map +1 -0
- package/dist/extensions/structured-output/extension.js.map +1 -0
- package/dist/extensions/structured-output/index.d.ts.map +1 -0
- package/dist/extensions/structured-output/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/timestamp/extension.d.ts +1 -1
- package/dist/extensions/timestamp/extension.d.ts.map +1 -0
- package/dist/extensions/timestamp/extension.js.map +1 -0
- package/dist/extensions/timestamp/index.d.ts.map +1 -0
- package/dist/extensions/timestamp/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/token-stats/extension.d.ts +1 -1
- package/dist/extensions/token-stats/extension.d.ts.map +1 -0
- package/dist/extensions/token-stats/extension.js.map +1 -0
- package/dist/extensions/token-stats/extension.test.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/token-stats/extension.test.js +1 -1
- package/dist/extensions/token-stats/extension.test.js.map +1 -0
- package/dist/extensions/token-stats/index.d.ts.map +1 -0
- package/dist/extensions/token-stats/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/tool-buffer/extension.d.ts +1 -1
- package/dist/extensions/tool-buffer/extension.d.ts.map +1 -0
- package/dist/extensions/tool-buffer/extension.js.map +1 -0
- package/dist/extensions/tool-buffer/extension.test.d.ts.map +1 -0
- package/dist/{extras/extensions → extensions}/tool-buffer/extension.test.js +1 -1
- package/dist/extensions/tool-buffer/extension.test.js.map +1 -0
- package/dist/extensions/tool-buffer/index.d.ts.map +1 -0
- package/dist/extensions/tool-buffer/index.js.map +1 -0
- package/dist/{extras/extensions → extensions}/weather-tool/extension.d.ts +1 -1
- package/dist/extensions/weather-tool/extension.d.ts.map +1 -0
- package/dist/extensions/weather-tool/extension.js.map +1 -0
- package/dist/extensions/weather-tool/index.d.ts.map +1 -0
- package/dist/extensions/weather-tool/index.js.map +1 -0
- package/dist/handle.d.ts +4 -0
- package/dist/handle.d.ts.map +1 -1
- package/dist/{extras/models → models}/ai-sdk-resolver.d.ts +1 -1
- package/dist/models/ai-sdk-resolver.d.ts.map +1 -0
- package/dist/{extras/models → models}/ai-sdk-resolver.js +1 -1
- package/dist/models/ai-sdk-resolver.js.map +1 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js.map +1 -0
- package/dist/{extras/models → models}/routing-model.d.ts +1 -1
- package/dist/models/routing-model.d.ts.map +1 -0
- package/dist/{extras/models → models}/routing-model.js +1 -1
- package/dist/models/routing-model.js.map +1 -0
- package/dist/openai-provider/index.d.ts.map +1 -0
- package/dist/openai-provider/index.js.map +1 -0
- package/dist/{extras/openai-provider → openai-provider}/server.d.ts +1 -1
- package/dist/openai-provider/server.d.ts.map +1 -0
- package/dist/openai-provider/server.js.map +1 -0
- package/package.json +108 -83
- package/dist/extras/extension-loader.d.ts.map +0 -1
- package/dist/extras/extension-loader.js.map +0 -1
- package/dist/extras/extensions/auto-steer/extension.d.ts.map +0 -1
- package/dist/extras/extensions/auto-steer/extension.js.map +0 -1
- package/dist/extras/extensions/auto-steer/index.d.ts.map +0 -1
- package/dist/extras/extensions/auto-steer/index.js.map +0 -1
- package/dist/extras/extensions/code-tools/extension.d.ts +0 -83
- package/dist/extras/extensions/code-tools/extension.d.ts.map +0 -1
- package/dist/extras/extensions/code-tools/extension.js +0 -93
- package/dist/extras/extensions/code-tools/extension.js.map +0 -1
- package/dist/extras/extensions/code-tools/extension.test.d.ts.map +0 -1
- package/dist/extras/extensions/code-tools/extension.test.js +0 -656
- package/dist/extras/extensions/code-tools/extension.test.js.map +0 -1
- package/dist/extras/extensions/code-tools/index.d.ts.map +0 -1
- package/dist/extras/extensions/code-tools/index.js.map +0 -1
- package/dist/extras/extensions/code-tools/tools/code-search.d.ts.map +0 -1
- package/dist/extras/extensions/code-tools/tools/code-search.js.map +0 -1
- package/dist/extras/extensions/code-tools/tools/find.d.ts.map +0 -1
- package/dist/extras/extensions/code-tools/tools/find.js +0 -161
- package/dist/extras/extensions/code-tools/tools/find.js.map +0 -1
- package/dist/extras/extensions/code-tools/tools/grep.d.ts.map +0 -1
- package/dist/extras/extensions/code-tools/tools/grep.js +0 -307
- package/dist/extras/extensions/code-tools/tools/grep.js.map +0 -1
- package/dist/extras/extensions/code-tools/tools/read.d.ts.map +0 -1
- package/dist/extras/extensions/code-tools/tools/read.js.map +0 -1
- package/dist/extras/extensions/code-tools/tools/shared.d.ts.map +0 -1
- package/dist/extras/extensions/code-tools/tools/shared.js.map +0 -1
- package/dist/extras/extensions/code-tools/tools/shell.d.ts +0 -49
- package/dist/extras/extensions/code-tools/tools/shell.d.ts.map +0 -1
- package/dist/extras/extensions/code-tools/tools/shell.js +0 -623
- package/dist/extras/extensions/code-tools/tools/shell.js.map +0 -1
- package/dist/extras/extensions/code-tools/tools/todo.d.ts.map +0 -1
- package/dist/extras/extensions/code-tools/tools/todo.js.map +0 -1
- package/dist/extras/extensions/code-tools/tools/write.d.ts.map +0 -1
- package/dist/extras/extensions/code-tools/tools/write.js.map +0 -1
- package/dist/extras/extensions/disk-session/extension.d.ts.map +0 -1
- package/dist/extras/extensions/disk-session/extension.js +0 -640
- package/dist/extras/extensions/disk-session/extension.js.map +0 -1
- package/dist/extras/extensions/disk-session/extension.test.d.ts.map +0 -1
- package/dist/extras/extensions/disk-session/extension.test.js.map +0 -1
- package/dist/extras/extensions/disk-session/index.d.ts +0 -3
- package/dist/extras/extensions/disk-session/index.d.ts.map +0 -1
- package/dist/extras/extensions/disk-session/index.js +0 -2
- package/dist/extras/extensions/disk-session/index.js.map +0 -1
- package/dist/extras/extensions/emoji/extension.d.ts.map +0 -1
- package/dist/extras/extensions/emoji/extension.js.map +0 -1
- package/dist/extras/extensions/emoji/index.d.ts.map +0 -1
- package/dist/extras/extensions/emoji/index.js.map +0 -1
- package/dist/extras/extensions/filesystem/extension.d.ts.map +0 -1
- package/dist/extras/extensions/filesystem/extension.js.map +0 -1
- package/dist/extras/extensions/filesystem/extension.test.d.ts.map +0 -1
- package/dist/extras/extensions/filesystem/extension.test.js.map +0 -1
- package/dist/extras/extensions/filesystem/index.d.ts.map +0 -1
- package/dist/extras/extensions/filesystem/index.js.map +0 -1
- package/dist/extras/extensions/keyword-extractor/extension.d.ts.map +0 -1
- package/dist/extras/extensions/keyword-extractor/extension.js.map +0 -1
- package/dist/extras/extensions/keyword-extractor/extension.test.d.ts.map +0 -1
- package/dist/extras/extensions/keyword-extractor/extension.test.js.map +0 -1
- package/dist/extras/extensions/keyword-extractor/index.d.ts.map +0 -1
- package/dist/extras/extensions/keyword-extractor/index.js.map +0 -1
- package/dist/extras/extensions/keyword-extractor/nlp.d.ts.map +0 -1
- package/dist/extras/extensions/keyword-extractor/nlp.js.map +0 -1
- package/dist/extras/extensions/keyword-extractor/nlp.test.d.ts.map +0 -1
- package/dist/extras/extensions/keyword-extractor/nlp.test.js.map +0 -1
- package/dist/extras/extensions/logger/extension.d.ts.map +0 -1
- package/dist/extras/extensions/logger/extension.js.map +0 -1
- package/dist/extras/extensions/logger/index.d.ts.map +0 -1
- package/dist/extras/extensions/logger/index.js.map +0 -1
- package/dist/extras/extensions/mcp/extension.d.ts.map +0 -1
- package/dist/extras/extensions/mcp/extension.js.map +0 -1
- package/dist/extras/extensions/mcp/extension.test.d.ts.map +0 -1
- package/dist/extras/extensions/mcp/extension.test.js.map +0 -1
- package/dist/extras/extensions/mcp/index.d.ts.map +0 -1
- package/dist/extras/extensions/mcp/index.js.map +0 -1
- package/dist/extras/extensions/mem-session/extension.d.ts.map +0 -1
- package/dist/extras/extensions/mem-session/extension.js.map +0 -1
- package/dist/extras/extensions/mem-session/index.d.ts.map +0 -1
- package/dist/extras/extensions/mem-session/index.js.map +0 -1
- package/dist/extras/extensions/memory/extension.d.ts.map +0 -1
- package/dist/extras/extensions/memory/extension.js.map +0 -1
- package/dist/extras/extensions/memory/index.d.ts +0 -5
- package/dist/extras/extensions/memory/index.d.ts.map +0 -1
- package/dist/extras/extensions/memory/index.js.map +0 -1
- package/dist/extras/extensions/memory/llm-extractor.d.ts.map +0 -1
- package/dist/extras/extensions/memory/llm-extractor.js.map +0 -1
- package/dist/extras/extensions/memory/types.d.ts.map +0 -1
- package/dist/extras/extensions/memory/types.js.map +0 -1
- package/dist/extras/extensions/otel/extension.d.ts.map +0 -1
- package/dist/extras/extensions/otel/extension.js.map +0 -1
- package/dist/extras/extensions/otel/extension.test.d.ts.map +0 -1
- package/dist/extras/extensions/otel/extension.test.js.map +0 -1
- package/dist/extras/extensions/otel/index.d.ts.map +0 -1
- package/dist/extras/extensions/otel/index.js.map +0 -1
- package/dist/extras/extensions/otel/jsonl-span-exporter.d.ts.map +0 -1
- package/dist/extras/extensions/otel/jsonl-span-exporter.js.map +0 -1
- package/dist/extras/extensions/scripts/extension.d.ts.map +0 -1
- package/dist/extras/extensions/scripts/extension.js.map +0 -1
- package/dist/extras/extensions/scripts/extension.test.d.ts.map +0 -1
- package/dist/extras/extensions/scripts/extension.test.js.map +0 -1
- package/dist/extras/extensions/scripts/index.d.ts.map +0 -1
- package/dist/extras/extensions/scripts/index.js.map +0 -1
- package/dist/extras/extensions/skills/extension.d.ts.map +0 -1
- package/dist/extras/extensions/skills/extension.js.map +0 -1
- package/dist/extras/extensions/skills/extension.test.d.ts.map +0 -1
- package/dist/extras/extensions/skills/extension.test.js.map +0 -1
- package/dist/extras/extensions/skills/index.d.ts.map +0 -1
- package/dist/extras/extensions/skills/index.js.map +0 -1
- package/dist/extras/extensions/streaming/extension.d.ts.map +0 -1
- package/dist/extras/extensions/streaming/extension.js.map +0 -1
- package/dist/extras/extensions/streaming/index.d.ts.map +0 -1
- package/dist/extras/extensions/streaming/index.js.map +0 -1
- package/dist/extras/extensions/structured-output/extension.d.ts.map +0 -1
- package/dist/extras/extensions/structured-output/extension.js.map +0 -1
- package/dist/extras/extensions/structured-output/index.d.ts.map +0 -1
- package/dist/extras/extensions/structured-output/index.js.map +0 -1
- package/dist/extras/extensions/timestamp/extension.d.ts.map +0 -1
- package/dist/extras/extensions/timestamp/extension.js.map +0 -1
- package/dist/extras/extensions/timestamp/index.d.ts.map +0 -1
- package/dist/extras/extensions/timestamp/index.js.map +0 -1
- package/dist/extras/extensions/token-stats/extension.d.ts.map +0 -1
- package/dist/extras/extensions/token-stats/extension.js.map +0 -1
- package/dist/extras/extensions/token-stats/extension.test.d.ts.map +0 -1
- package/dist/extras/extensions/token-stats/extension.test.js.map +0 -1
- package/dist/extras/extensions/token-stats/index.d.ts.map +0 -1
- package/dist/extras/extensions/token-stats/index.js.map +0 -1
- package/dist/extras/extensions/tool-buffer/extension.d.ts.map +0 -1
- package/dist/extras/extensions/tool-buffer/extension.js.map +0 -1
- package/dist/extras/extensions/tool-buffer/extension.test.d.ts.map +0 -1
- package/dist/extras/extensions/tool-buffer/extension.test.js.map +0 -1
- package/dist/extras/extensions/tool-buffer/index.d.ts.map +0 -1
- package/dist/extras/extensions/tool-buffer/index.js.map +0 -1
- package/dist/extras/extensions/weather-tool/extension.d.ts.map +0 -1
- package/dist/extras/extensions/weather-tool/extension.js.map +0 -1
- package/dist/extras/extensions/weather-tool/index.d.ts.map +0 -1
- package/dist/extras/extensions/weather-tool/index.js.map +0 -1
- package/dist/extras/models/ai-sdk-resolver.d.ts.map +0 -1
- package/dist/extras/models/ai-sdk-resolver.js.map +0 -1
- package/dist/extras/models/index.d.ts.map +0 -1
- package/dist/extras/models/index.js.map +0 -1
- package/dist/extras/models/routing-model.d.ts.map +0 -1
- package/dist/extras/models/routing-model.js.map +0 -1
- package/dist/extras/openai-provider/index.d.ts.map +0 -1
- package/dist/extras/openai-provider/index.js.map +0 -1
- package/dist/extras/openai-provider/server.d.ts.map +0 -1
- package/dist/extras/openai-provider/server.js.map +0 -1
- /package/dist/{extras/extensions → extensions}/auto-steer/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/auto-steer/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/auto-steer/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/auto-steer/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/code-tools/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/code-tools/extension.test.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/code-tools/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/code-tools/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/code-tools/tools/find.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/code-tools/tools/grep.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/code-tools/tools/read.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/code-tools/tools/write.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/disk-session/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/disk-session/extension.test.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/emoji/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/emoji/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/emoji/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/emoji/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/filesystem/extension.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/filesystem/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/filesystem/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/filesystem/extension.test.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/filesystem/extension.test.js +0 -0
- /package/dist/{extras/extensions → extensions}/filesystem/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/filesystem/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/keyword-extractor/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/keyword-extractor/extension.test.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/keyword-extractor/extension.test.js +0 -0
- /package/dist/{extras/extensions → extensions}/keyword-extractor/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/keyword-extractor/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/keyword-extractor/nlp.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/keyword-extractor/nlp.js +0 -0
- /package/dist/{extras/extensions → extensions}/keyword-extractor/nlp.test.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/keyword-extractor/nlp.test.js +0 -0
- /package/dist/{extras/extensions → extensions}/logger/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/logger/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/logger/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/mcp/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/mcp/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/mcp/extension.test.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/mcp/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/mcp/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/mem-session/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/mem-session/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/mem-session/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/mem-session/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/memory/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/memory/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/memory/types.js +0 -0
- /package/dist/{extras/extensions → extensions}/otel/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/otel/extension.test.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/otel/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/otel/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/otel/jsonl-span-exporter.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/otel/jsonl-span-exporter.js +0 -0
- /package/dist/{extras/extensions → extensions}/scripts/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/scripts/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/scripts/extension.test.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/scripts/extension.test.js +0 -0
- /package/dist/{extras/extensions → extensions}/scripts/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/scripts/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/skills/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/skills/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/skills/extension.test.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/skills/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/skills/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/streaming/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/streaming/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/streaming/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/streaming/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/structured-output/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/structured-output/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/structured-output/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/structured-output/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/timestamp/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/timestamp/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/timestamp/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/timestamp/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/token-stats/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/token-stats/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/token-stats/extension.test.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/token-stats/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/token-stats/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/tool-buffer/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/tool-buffer/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/tool-buffer/extension.test.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/tool-buffer/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/tool-buffer/index.js +0 -0
- /package/dist/{extras/extensions → extensions}/weather-tool/extension.js +0 -0
- /package/dist/{extras/extensions → extensions}/weather-tool/extension.json +0 -0
- /package/dist/{extras/extensions → extensions}/weather-tool/index.d.ts +0 -0
- /package/dist/{extras/extensions → extensions}/weather-tool/index.js +0 -0
- /package/dist/{extras/models → models}/index.d.ts +0 -0
- /package/dist/{extras/models → models}/index.js +0 -0
- /package/dist/{extras/openai-provider → openai-provider}/index.d.ts +0 -0
- /package/dist/{extras/openai-provider → openai-provider}/index.js +0 -0
- /package/dist/{extras/openai-provider → openai-provider}/server.js +0 -0
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ pnpm add @xandout/libra-harness
|
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
16
|
import { Agent } from '@xandout/libra-harness'
|
|
17
|
-
import { resolveModel } from '@xandout/libra-harness/
|
|
17
|
+
import { resolveModel } from '@xandout/libra-harness/models'
|
|
18
18
|
|
|
19
19
|
// Resolve a model from environment variables (DEEPSEEK_API_KEY, OPENAI_API_KEY, etc.)
|
|
20
20
|
const model = await resolveModel('deepseek/deepseek-v4-flash')
|
|
@@ -140,8 +140,8 @@ agent.use(loggingExtension)
|
|
|
140
140
|
Libra ships with a set of optional extensions under `@xandout/libra-harness/extras`. Each is importable via its own subpath — import only what you need:
|
|
141
141
|
|
|
142
142
|
```typescript
|
|
143
|
-
import { createLoggerExtension } from '@xandout/libra-harness/
|
|
144
|
-
import { createDiskSessionExtension } from '@xandout/libra-harness/
|
|
143
|
+
import { createLoggerExtension } from '@xandout/libra-harness/extensions/logger'
|
|
144
|
+
import { createDiskSessionExtension } from '@xandout/libra-harness/extensions/disk-session'
|
|
145
145
|
|
|
146
146
|
agent.use(createLoggerExtension())
|
|
147
147
|
agent.use(createDiskSessionExtension({ dir: './sessions' }))
|
|
@@ -149,37 +149,37 @@ agent.use(createDiskSessionExtension({ dir: './sessions' }))
|
|
|
149
149
|
|
|
150
150
|
| Extension | Import | Description |
|
|
151
151
|
|-----------|--------|-------------|
|
|
152
|
-
| logger | `@xandout/libra-harness/
|
|
153
|
-
| streaming | `@xandout/libra-harness/
|
|
154
|
-
| otel | `@xandout/libra-harness/
|
|
155
|
-
| weather-tool | `@xandout/libra-harness/
|
|
156
|
-
| structured-output | `@xandout/libra-harness/
|
|
157
|
-
| mcp | `@xandout/libra-harness/
|
|
158
|
-
| skills | `@xandout/libra-harness/
|
|
159
|
-
| filesystem | `@xandout/libra-harness/
|
|
160
|
-
| scripts | `@xandout/libra-harness/
|
|
161
|
-
| keyword-extractor | `@xandout/libra-harness/
|
|
162
|
-
| token-stats | `@xandout/libra-harness/
|
|
163
|
-
| tool-buffer | `@xandout/libra-harness/
|
|
164
|
-
| auto-steer | `@xandout/libra-harness/
|
|
165
|
-
| emoji | `@xandout/libra-harness/
|
|
166
|
-
| timestamp | `@xandout/libra-harness/
|
|
167
|
-
| disk-session | `@xandout/libra-harness/
|
|
168
|
-
| mem-session | `@xandout/libra-harness/
|
|
169
|
-
| memory | `@xandout/libra-harness/
|
|
152
|
+
| logger | `@xandout/libra-harness/extensions/logger` | Logs each lifecycle stage |
|
|
153
|
+
| streaming | `@xandout/libra-harness/extensions/streaming` | Streams text/reasoning/tool-input deltas |
|
|
154
|
+
| otel | `@xandout/libra-harness/extensions/otel` | OpenTelemetry tracing (JSONL or OTLP export) |
|
|
155
|
+
| weather-tool | `@xandout/libra-harness/extensions/weather-tool` | Registers a `get_weather` tool |
|
|
156
|
+
| structured-output | `@xandout/libra-harness/extensions/structured-output` | Validates LLM output against a JSON schema |
|
|
157
|
+
| mcp | `@xandout/libra-harness/extensions/mcp` | Connects to MCP servers, registers tools |
|
|
158
|
+
| skills | `@xandout/libra-harness/extensions/skills` | Loads Agent Skills from directories |
|
|
159
|
+
| filesystem | `@xandout/libra-harness/extensions/filesystem` | File read/write/list tools |
|
|
160
|
+
| scripts | `@xandout/libra-harness/extensions/scripts` | Runs shell scripts in pipeline stages |
|
|
161
|
+
| keyword-extractor | `@xandout/libra-harness/extensions/keyword-extractor` | Extracts keywords from messages (local NLP) |
|
|
162
|
+
| token-stats | `@xandout/libra-harness/extensions/token-stats` | Tracks token usage per turn |
|
|
163
|
+
| tool-buffer | `@xandout/libra-harness/extensions/tool-buffer` | Buffers and replays tool results |
|
|
164
|
+
| auto-steer | `@xandout/libra-harness/extensions/auto-steer` | Auto-injects steering messages based on conditions |
|
|
165
|
+
| emoji | `@xandout/libra-harness/extensions/emoji` | Decorates responses with an emoji prefix |
|
|
166
|
+
| timestamp | `@xandout/libra-harness/extensions/timestamp` | Records start/finish timestamps in metadata |
|
|
167
|
+
| disk-session | `@xandout/libra-harness/extensions/disk-session` | Disk-backed session history per session ID |
|
|
168
|
+
| mem-session | `@xandout/libra-harness/extensions/mem-session` | In-memory session history per session ID |
|
|
169
|
+
| memory | `@xandout/libra-harness/extensions/memory` | Long-term memory with LLM-based extraction |
|
|
170
170
|
|
|
171
171
|
**Priority** controls hook execution order within each lifecycle stage (higher = runs first, ties keep registration order). Set `priority` on any extension whose hooks must run before or after another extension's hooks.
|
|
172
172
|
|
|
173
|
-
See [`src/
|
|
173
|
+
See [`src/extensions/README.md`](src/extensions/README.md) for full API docs.
|
|
174
174
|
|
|
175
175
|
### Extension loader
|
|
176
176
|
|
|
177
177
|
For larger setups, `loadExtensions` accepts a mix of factory functions, `Extension` objects, and directory paths. It passes a shared config object to each factory, sorts by priority, and handles cleanup:
|
|
178
178
|
|
|
179
179
|
```typescript
|
|
180
|
-
import { loadExtensions, installExtensions, closeExtensions } from '@xandout/libra-harness/
|
|
181
|
-
import { createLoggerExtension } from '@xandout/libra-harness/
|
|
182
|
-
import { createMcpExtension } from '@xandout/libra-harness/
|
|
180
|
+
import { loadExtensions, installExtensions, closeExtensions } from '@xandout/libra-harness/extensions'
|
|
181
|
+
import { createLoggerExtension } from '@xandout/libra-harness/extensions/logger'
|
|
182
|
+
import { createMcpExtension } from '@xandout/libra-harness/extensions/mcp'
|
|
183
183
|
|
|
184
184
|
const loaded = await loadExtensions(
|
|
185
185
|
[
|
|
@@ -201,10 +201,10 @@ await closeExtensions(loaded) // calls close() on extensions that have one (
|
|
|
201
201
|
|
|
202
202
|
### Native resolver
|
|
203
203
|
|
|
204
|
-
The easiest way to get a model is `resolveModel` from `@xandout/libra-harness/
|
|
204
|
+
The easiest way to get a model is `resolveModel` from `@xandout/libra-harness/models`. It reads API keys from environment variables and loads the appropriate AI SDK provider package dynamically:
|
|
205
205
|
|
|
206
206
|
```typescript
|
|
207
|
-
import { resolveModel } from '@xandout/libra-harness/
|
|
207
|
+
import { resolveModel } from '@xandout/libra-harness/models'
|
|
208
208
|
|
|
209
209
|
// Reads DEEPSEEK_API_KEY from env, loads @ai-sdk/deepseek
|
|
210
210
|
const model = await resolveModel('deepseek/deepseek-v4-flash')
|
|
@@ -244,7 +244,7 @@ const model = new AISdkModel(openai('gpt-4.1-mini'))
|
|
|
244
244
|
Route requests to different models based on input content — e.g. send images to a vision model:
|
|
245
245
|
|
|
246
246
|
```typescript
|
|
247
|
-
import { createRoutingModel, hasImageInput } from '@xandout/libra-harness/
|
|
247
|
+
import { createRoutingModel, hasImageInput } from '@xandout/libra-harness/models'
|
|
248
248
|
|
|
249
249
|
const model = createRoutingModel({
|
|
250
250
|
default: await resolveModel('deepseek/deepseek-v4-flash'),
|
|
@@ -274,8 +274,8 @@ Expose Libra agents as OpenAI-compatible models. Any framework that supports a c
|
|
|
274
274
|
|
|
275
275
|
```typescript
|
|
276
276
|
import { Agent } from '@xandout/libra-harness'
|
|
277
|
-
import { resolveModel } from '@xandout/libra-harness/
|
|
278
|
-
import { createOpenAICompatibleServer } from '@xandout/libra-harness/
|
|
277
|
+
import { resolveModel } from '@xandout/libra-harness/models'
|
|
278
|
+
import { createOpenAICompatibleServer } from '@xandout/libra-harness/openai-provider'
|
|
279
279
|
|
|
280
280
|
const model = await resolveModel('deepseek/deepseek-v4-flash')
|
|
281
281
|
|
package/dist/agent.d.ts
CHANGED
|
@@ -89,6 +89,8 @@ export declare class Agent {
|
|
|
89
89
|
private installingExtension?;
|
|
90
90
|
private readonly activeHandles;
|
|
91
91
|
constructor(config: AgentConfig);
|
|
92
|
+
/** The configured model for this agent. */
|
|
93
|
+
get model(): Model;
|
|
92
94
|
/**
|
|
93
95
|
* Append content to the system prompt. This is a one-time mutation
|
|
94
96
|
* typically called by extensions at install time (e.g. the skills
|
|
@@ -157,6 +159,10 @@ export declare class Agent {
|
|
|
157
159
|
run(request: AgentRequest): RunHandle;
|
|
158
160
|
private mergeTools;
|
|
159
161
|
private executeTurn;
|
|
162
|
+
private executeTurnIteration;
|
|
163
|
+
private handleNoToolCalls;
|
|
164
|
+
private handleTurnError;
|
|
165
|
+
private generateModelResponse;
|
|
160
166
|
/**
|
|
161
167
|
* Build the response, run beforeResponse + afterTurn hooks, and return.
|
|
162
168
|
* All turn exit paths go through here so extensions (session, memory,
|
|
@@ -171,6 +177,8 @@ export declare class Agent {
|
|
|
171
177
|
* observability extensions can inspect it via `afterTurn`.
|
|
172
178
|
*/
|
|
173
179
|
private finishWithError;
|
|
180
|
+
private processInternalCalls;
|
|
181
|
+
private executeToolBatch;
|
|
174
182
|
private executeToolCall;
|
|
175
183
|
/**
|
|
176
184
|
* Race a promise against an abort signal. Returns `undefined` if the
|
package/dist/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/agent.js
CHANGED
|
@@ -34,6 +34,10 @@ export class Agent {
|
|
|
34
34
|
this.tools.set(tool.name, tool);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
/** The configured model for this agent. */
|
|
38
|
+
get model() {
|
|
39
|
+
return this.config.model;
|
|
40
|
+
}
|
|
37
41
|
// ── System Prompt ──────────────────────────────────────────────────
|
|
38
42
|
/**
|
|
39
43
|
* Append content to the system prompt. This is a one-time mutation
|
|
@@ -198,7 +202,7 @@ export class Agent {
|
|
|
198
202
|
turn.halt = (reason) => handle.halt(reason);
|
|
199
203
|
// Kick off the turn. We store the promise on the handle so `handle.done`
|
|
200
204
|
// and `await handle` both resolve to the same result.
|
|
201
|
-
handle.done = this.executeTurn(turn, maxIter, steeringQueue).finally(() => {
|
|
205
|
+
handle.done = this.executeTurn(turn, maxIter, steeringQueue, handle).finally(() => {
|
|
202
206
|
this.activeHandles.delete(handle);
|
|
203
207
|
});
|
|
204
208
|
return handle;
|
|
@@ -209,7 +213,7 @@ export class Agent {
|
|
|
209
213
|
all.set(t.name, t);
|
|
210
214
|
return [...all.values()];
|
|
211
215
|
}
|
|
212
|
-
async executeTurn(turn, maxIter, steeringQueue) {
|
|
216
|
+
async executeTurn(turn, maxIter, steeringQueue, handle) {
|
|
213
217
|
let iterations = 0;
|
|
214
218
|
const allToolCalls = [];
|
|
215
219
|
try {
|
|
@@ -218,197 +222,161 @@ export class Agent {
|
|
|
218
222
|
// beforeContext — last chance to modify context before the LLM loop.
|
|
219
223
|
await this.runHooks('beforeContext', { turn });
|
|
220
224
|
for (;;) {
|
|
221
|
-
|
|
222
|
-
if (
|
|
223
|
-
return
|
|
224
|
-
}
|
|
225
|
-
// ── Check max iterations ──
|
|
226
|
-
if (iterations >= maxIter) {
|
|
227
|
-
return await this.finishTurn(turn, '', 'max_iterations', iterations, allToolCalls);
|
|
228
|
-
}
|
|
229
|
-
// ── Drain steering messages ──
|
|
230
|
-
this.drainSteering(turn, steeringQueue);
|
|
231
|
-
// ── beforeLLM ──
|
|
232
|
-
const modelRequest = {
|
|
233
|
-
messages: turn.messages,
|
|
234
|
-
tools: turn.tools.length > 0 ? turn.tools.map(toToolDefinition) : undefined,
|
|
235
|
-
systemPrompt: turn.systemPrompt,
|
|
236
|
-
temperature: this.config.temperature,
|
|
237
|
-
maxTokens: this.config.maxTokens,
|
|
238
|
-
reasoningEffort: this.config.reasoningEffort,
|
|
239
|
-
providerOptions: this.config.providerOptions,
|
|
240
|
-
signal: turn.signal,
|
|
241
|
-
};
|
|
242
|
-
const beforeLLMResult = await this.runHooks('beforeLLM', { turn, modelRequest });
|
|
243
|
-
// Halt may have been called during beforeLLM hooks.
|
|
244
|
-
if (turn.signal.aborted) {
|
|
245
|
-
return await this.finishTurn(turn, '', 'halted', iterations, allToolCalls);
|
|
246
|
-
}
|
|
247
|
-
let modelResponse;
|
|
248
|
-
if (beforeLLMResult.skipped && beforeLLMResult.value) {
|
|
249
|
-
modelResponse = beforeLLMResult.value;
|
|
250
|
-
}
|
|
251
|
-
else {
|
|
252
|
-
try {
|
|
253
|
-
modelResponse = await this.config.model.generate(modelRequest);
|
|
254
|
-
}
|
|
255
|
-
catch (err) {
|
|
256
|
-
if (turn.signal.aborted) {
|
|
257
|
-
return await this.finishTurn(turn, '', 'halted', iterations, allToolCalls);
|
|
258
|
-
}
|
|
259
|
-
throw err;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
// ── afterLLM ──
|
|
263
|
-
await this.runHooks('afterLLM', { turn, modelRequest, modelResponse });
|
|
225
|
+
const result = await this.executeTurnIteration(turn, maxIter, steeringQueue, handle, iterations, allToolCalls);
|
|
226
|
+
if (result.status === 'finish')
|
|
227
|
+
return result.response;
|
|
264
228
|
iterations++;
|
|
265
|
-
// Add the assistant message to the conversation.
|
|
266
|
-
turn.messages.push(modelResponse.message);
|
|
267
|
-
// ── Halt may have been called during afterLLM hooks ──
|
|
268
|
-
if (turn.signal.aborted) {
|
|
269
|
-
return await this.finishTurn(turn, messageContentToText(modelResponse.message.content), 'halted', iterations, allToolCalls);
|
|
270
|
-
}
|
|
271
|
-
// ── No tool calls → final response (unless steering pending) ──
|
|
272
|
-
const toolCalls = modelResponse.message.toolCalls;
|
|
273
|
-
if (!toolCalls || toolCalls.length === 0) {
|
|
274
|
-
// If steering messages arrived during the LLM call, don't end
|
|
275
|
-
// the turn — drain them and loop so the agent can respond.
|
|
276
|
-
if (steeringQueue.length > 0) {
|
|
277
|
-
this.drainSteering(turn, steeringQueue);
|
|
278
|
-
continue;
|
|
279
|
-
}
|
|
280
|
-
return await this.finishTurn(turn, messageContentToText(modelResponse.message.content), 'stop', iterations, allToolCalls);
|
|
281
|
-
}
|
|
282
|
-
// ── Separate external (pass-through) from internal (execute) tool calls ──
|
|
283
|
-
const externalCalls = [];
|
|
284
|
-
const internalCalls = [];
|
|
285
|
-
for (const tc of toolCalls) {
|
|
286
|
-
const tool = turn.tools.find((t) => t.name === tc.name);
|
|
287
|
-
if (tool?.external)
|
|
288
|
-
externalCalls.push(tc);
|
|
289
|
-
else
|
|
290
|
-
internalCalls.push(tc);
|
|
291
|
-
}
|
|
292
|
-
// ── External tool calls → return to caller for execution ──
|
|
293
|
-
if (externalCalls.length > 0) {
|
|
294
|
-
allToolCalls.push(...externalCalls);
|
|
295
|
-
// If there are also internal calls in this batch, execute those first
|
|
296
|
-
// (the model may have mixed both in one response). The external calls
|
|
297
|
-
// are still returned — the caller will see them and the internal results.
|
|
298
|
-
if (internalCalls.length > 0) {
|
|
299
|
-
allToolCalls.push(...internalCalls);
|
|
300
|
-
if (turn.signal.aborted) {
|
|
301
|
-
return await this.finishTurn(turn, '', 'halted', iterations, allToolCalls);
|
|
302
|
-
}
|
|
303
|
-
const mixedResults = await Promise.all(internalCalls.map(async (toolCall) => {
|
|
304
|
-
const beforeToolCtx = { turn, toolCall };
|
|
305
|
-
const beforeToolResult = await this.runHooks('beforeTool', beforeToolCtx);
|
|
306
|
-
let toolResult;
|
|
307
|
-
if (beforeToolResult.skipped && beforeToolResult.value) {
|
|
308
|
-
toolResult = beforeToolResult.value;
|
|
309
|
-
}
|
|
310
|
-
else {
|
|
311
|
-
toolResult = await this.executeToolCall(toolCall, turn);
|
|
312
|
-
}
|
|
313
|
-
const afterToolCtx = { turn, toolCall, toolResult };
|
|
314
|
-
const afterToolResult = await this.runHooks('afterTool', afterToolCtx);
|
|
315
|
-
if (afterToolResult.value) {
|
|
316
|
-
toolResult = afterToolResult.value;
|
|
317
|
-
}
|
|
318
|
-
return { toolCall, toolResult };
|
|
319
|
-
}));
|
|
320
|
-
for (const { toolCall, toolResult } of mixedResults) {
|
|
321
|
-
turn.messages.push({
|
|
322
|
-
role: 'tool',
|
|
323
|
-
content: toolResult.content,
|
|
324
|
-
toolCallId: toolCall.id,
|
|
325
|
-
name: toolCall.name,
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
// Drain steering after mixed tool results too.
|
|
329
|
-
this.drainSteering(turn, steeringQueue);
|
|
330
|
-
}
|
|
331
|
-
// Return external tool calls to the caller. The assistant message
|
|
332
|
-
// (with toolCalls) is already in turn.messages from the push above.
|
|
333
|
-
return await this.finishTurn(turn, messageContentToText(modelResponse.message.content), 'tool_calls', iterations, allToolCalls, externalCalls);
|
|
334
|
-
}
|
|
335
|
-
// ── Execute internal tool calls ──
|
|
336
|
-
allToolCalls.push(...internalCalls);
|
|
337
|
-
// Check halt before starting the batch.
|
|
338
|
-
if (turn.signal.aborted) {
|
|
339
|
-
return await this.finishTurn(turn, '', 'halted', iterations, allToolCalls);
|
|
340
|
-
}
|
|
341
|
-
// Execute all internal tool calls in the batch concurrently.
|
|
342
|
-
// Each tool call runs its beforeTool → execute → afterTool pipeline
|
|
343
|
-
// independently. Results are collected in order and appended to
|
|
344
|
-
// turn.messages after all complete, preserving the model's ordering.
|
|
345
|
-
const results = await Promise.all(internalCalls.map(async (toolCall) => {
|
|
346
|
-
// beforeTool — can short-circuit with a synthetic result.
|
|
347
|
-
const beforeToolCtx = { turn, toolCall };
|
|
348
|
-
const beforeToolResult = await this.runHooks('beforeTool', beforeToolCtx);
|
|
349
|
-
let toolResult;
|
|
350
|
-
if (beforeToolResult.skipped && beforeToolResult.value) {
|
|
351
|
-
toolResult = beforeToolResult.value;
|
|
352
|
-
}
|
|
353
|
-
else {
|
|
354
|
-
toolResult = await this.executeToolCall(toolCall, turn);
|
|
355
|
-
}
|
|
356
|
-
// afterTool — can modify the result.
|
|
357
|
-
const afterToolCtx = { turn, toolCall, toolResult };
|
|
358
|
-
const afterToolResult = await this.runHooks('afterTool', afterToolCtx);
|
|
359
|
-
if (afterToolResult.value) {
|
|
360
|
-
toolResult = afterToolResult.value;
|
|
361
|
-
}
|
|
362
|
-
return { toolCall, toolResult };
|
|
363
|
-
}));
|
|
364
|
-
// Append results to messages in the original order.
|
|
365
|
-
for (const { toolCall, toolResult } of results) {
|
|
366
|
-
turn.messages.push({
|
|
367
|
-
role: 'tool',
|
|
368
|
-
content: toolResult.content,
|
|
369
|
-
toolCallId: toolCall.id,
|
|
370
|
-
name: toolCall.name,
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
// ── Drain steering messages right after tool results ──
|
|
374
|
-
// This ensures the model sees steering directives immediately
|
|
375
|
-
// alongside tool results, rather than waiting for the next
|
|
376
|
-
// loop iteration's drain at the top.
|
|
377
|
-
this.drainSteering(turn, steeringQueue);
|
|
378
|
-
// Loop continues — the model will see the tool results.
|
|
379
229
|
}
|
|
380
230
|
}
|
|
381
231
|
catch (err) {
|
|
382
|
-
|
|
383
|
-
|
|
232
|
+
return await this.handleTurnError(turn, err, iterations, allToolCalls);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async executeTurnIteration(turn, maxIter, steeringQueue, handle, iterations, allToolCalls) {
|
|
236
|
+
// ── Check halt ──
|
|
237
|
+
if (turn.signal.aborted) {
|
|
238
|
+
return { status: 'finish', response: await this.finishTurn(turn, '', 'halted', iterations, allToolCalls) };
|
|
239
|
+
}
|
|
240
|
+
// ── Check max iterations ──
|
|
241
|
+
if (iterations >= maxIter) {
|
|
242
|
+
return { status: 'finish', response: await this.finishTurn(turn, '', 'max_iterations', iterations, allToolCalls) };
|
|
243
|
+
}
|
|
244
|
+
// ── Drain steering messages ──
|
|
245
|
+
this.drainSteering(turn, steeringQueue);
|
|
246
|
+
const modelResponse = await this.generateModelResponse(turn);
|
|
247
|
+
if (!modelResponse) {
|
|
248
|
+
return { status: 'finish', response: await this.finishTurn(turn, '', 'halted', iterations, allToolCalls) };
|
|
249
|
+
}
|
|
250
|
+
// Add the assistant message to the conversation.
|
|
251
|
+
turn.messages.push(modelResponse.message);
|
|
252
|
+
// ── Emit text blurb immediately upon arrival ──
|
|
253
|
+
const blurbText = messageContentToText(modelResponse.message.content);
|
|
254
|
+
if (blurbText.trim()) {
|
|
255
|
+
try {
|
|
256
|
+
turn.request.onMessage?.(blurbText);
|
|
384
257
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
const errorResult = await this.runHooks('onError', { turn, error: err });
|
|
388
|
-
if (errorResult.skipped && errorResult.value) {
|
|
389
|
-
const response = errorResult.value;
|
|
390
|
-
turn.response = response;
|
|
391
|
-
await this.runHooks('afterTurn', { turn });
|
|
392
|
-
return response;
|
|
258
|
+
catch (err) {
|
|
259
|
+
console.error('[agent] request.onMessage error:', err);
|
|
393
260
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
261
|
+
handle?.emitMessage(blurbText);
|
|
262
|
+
}
|
|
263
|
+
// ── Halt may have been called during afterLLM hooks ──
|
|
264
|
+
if (turn.signal.aborted) {
|
|
265
|
+
return { status: 'finish', response: await this.finishTurn(turn, blurbText, 'halted', iterations + 1, allToolCalls) };
|
|
266
|
+
}
|
|
267
|
+
// ── No tool calls → final response (unless steering pending) ──
|
|
268
|
+
const toolCalls = modelResponse.message.toolCalls;
|
|
269
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
270
|
+
const result = await this.handleNoToolCalls(turn, modelResponse, steeringQueue, iterations + 1, allToolCalls);
|
|
271
|
+
if (result.status === 'finish')
|
|
272
|
+
return { status: 'finish', response: result.response };
|
|
273
|
+
return { status: 'continue' };
|
|
274
|
+
}
|
|
275
|
+
// ── Separate external (pass-through) from internal (execute) tool calls ──
|
|
276
|
+
const externalCalls = [];
|
|
277
|
+
const internalCalls = [];
|
|
278
|
+
for (const tc of toolCalls) {
|
|
279
|
+
const tool = turn.tools.find((t) => t.name === tc.name);
|
|
280
|
+
if (tool?.external)
|
|
281
|
+
externalCalls.push(tc);
|
|
282
|
+
else
|
|
283
|
+
internalCalls.push(tc);
|
|
284
|
+
}
|
|
285
|
+
// ── External tool calls → return to caller for execution ──
|
|
286
|
+
if (externalCalls.length > 0) {
|
|
287
|
+
allToolCalls.push(...externalCalls);
|
|
288
|
+
if (internalCalls.length > 0) {
|
|
289
|
+
const haltedResponse = await this.processInternalCalls(turn, internalCalls, allToolCalls, steeringQueue, iterations + 1);
|
|
290
|
+
if (haltedResponse)
|
|
291
|
+
return { status: 'finish', response: haltedResponse };
|
|
398
292
|
}
|
|
399
|
-
|
|
400
|
-
|
|
293
|
+
// Return external tool calls to the caller. The assistant message
|
|
294
|
+
// (with toolCalls) is already in turn.messages from the push above.
|
|
295
|
+
return { status: 'finish', response: await this.finishTurn(turn, messageContentToText(modelResponse.message.content), 'tool_calls', iterations + 1, allToolCalls, externalCalls) };
|
|
296
|
+
}
|
|
297
|
+
// ── Execute internal tool calls ──
|
|
298
|
+
const haltedResponse = await this.processInternalCalls(turn, internalCalls, allToolCalls, steeringQueue, iterations + 1);
|
|
299
|
+
if (haltedResponse)
|
|
300
|
+
return { status: 'finish', response: haltedResponse };
|
|
301
|
+
return { status: 'continue' };
|
|
302
|
+
}
|
|
303
|
+
async handleNoToolCalls(turn, modelResponse, steeringQueue, iterations, allToolCalls) {
|
|
304
|
+
const textContent = messageContentToText(modelResponse.message.content).trim();
|
|
305
|
+
if (!textContent) {
|
|
306
|
+
turn.messages.push({
|
|
307
|
+
role: 'user',
|
|
308
|
+
content: 'You sent an empty response. Please provide a meaningful response to the last completed task. Do not acknowledge this empty response, just provide the expected output.'
|
|
309
|
+
});
|
|
310
|
+
return { status: 'continue' };
|
|
311
|
+
}
|
|
312
|
+
if (steeringQueue.length > 0) {
|
|
313
|
+
this.drainSteering(turn, steeringQueue);
|
|
314
|
+
return { status: 'continue' };
|
|
315
|
+
}
|
|
316
|
+
return { status: 'finish', response: await this.finishTurn(turn, textContent, 'stop', iterations, allToolCalls) };
|
|
317
|
+
}
|
|
318
|
+
async handleTurnError(turn, err, iterations, allToolCalls) {
|
|
319
|
+
if (turn.signal.aborted) {
|
|
320
|
+
return await this.finishTurn(turn, '', 'halted', iterations, allToolCalls);
|
|
321
|
+
}
|
|
322
|
+
// Fire onError hooks — extensions can observe or recover.
|
|
323
|
+
// Hooks take precedence over the error policy.
|
|
324
|
+
const errorResult = await this.runHooks('onError', { turn, error: err });
|
|
325
|
+
if (errorResult.skipped && errorResult.value) {
|
|
326
|
+
const response = errorResult.value;
|
|
327
|
+
turn.response = response;
|
|
328
|
+
await this.runHooks('afterTurn', { turn });
|
|
329
|
+
return response;
|
|
330
|
+
}
|
|
331
|
+
// No hook recovered — apply the configured error policy.
|
|
332
|
+
const policy = this.config.errorPolicy ?? DEFAULT_ERROR_POLICY;
|
|
333
|
+
if (policy === 'throw') {
|
|
334
|
+
throw err;
|
|
335
|
+
}
|
|
336
|
+
if (policy === 'fallback') {
|
|
337
|
+
return await this.finishWithError(turn, err, iterations, allToolCalls);
|
|
338
|
+
}
|
|
339
|
+
// Custom policy function — return a response to recover,
|
|
340
|
+
// return undefined to rethrow.
|
|
341
|
+
const customResponse = await policy({ error: err, turn });
|
|
342
|
+
if (customResponse) {
|
|
343
|
+
turn.response = customResponse;
|
|
344
|
+
await this.runHooks('afterTurn', { turn });
|
|
345
|
+
return customResponse;
|
|
346
|
+
}
|
|
347
|
+
throw err;
|
|
348
|
+
}
|
|
349
|
+
async generateModelResponse(turn) {
|
|
350
|
+
const modelRequest = {
|
|
351
|
+
messages: turn.messages,
|
|
352
|
+
tools: turn.tools.length > 0 ? turn.tools.map(toToolDefinition) : undefined,
|
|
353
|
+
systemPrompt: turn.systemPrompt,
|
|
354
|
+
temperature: this.config.temperature,
|
|
355
|
+
maxTokens: this.config.maxTokens,
|
|
356
|
+
reasoningEffort: this.config.reasoningEffort,
|
|
357
|
+
providerOptions: this.config.providerOptions,
|
|
358
|
+
signal: turn.signal,
|
|
359
|
+
};
|
|
360
|
+
const beforeLLMResult = await this.runHooks('beforeLLM', { turn, modelRequest });
|
|
361
|
+
// Halt may have been called during beforeLLM hooks.
|
|
362
|
+
if (turn.signal.aborted)
|
|
363
|
+
return undefined;
|
|
364
|
+
let modelResponse;
|
|
365
|
+
if (beforeLLMResult.skipped && beforeLLMResult.value) {
|
|
366
|
+
modelResponse = beforeLLMResult.value;
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
try {
|
|
370
|
+
modelResponse = await this.config.model.generate(modelRequest);
|
|
401
371
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
turn.response = customResponse;
|
|
407
|
-
await this.runHooks('afterTurn', { turn });
|
|
408
|
-
return customResponse;
|
|
372
|
+
catch (err) {
|
|
373
|
+
if (turn.signal.aborted)
|
|
374
|
+
return undefined;
|
|
375
|
+
throw err;
|
|
409
376
|
}
|
|
410
|
-
throw err;
|
|
411
377
|
}
|
|
378
|
+
await this.runHooks('afterLLM', { turn, modelRequest, modelResponse });
|
|
379
|
+
return modelResponse;
|
|
412
380
|
}
|
|
413
381
|
/**
|
|
414
382
|
* Build the response, run beforeResponse + afterTurn hooks, and return.
|
|
@@ -440,6 +408,42 @@ export class Agent {
|
|
|
440
408
|
await this.runHooks('afterTurn', { turn });
|
|
441
409
|
return response;
|
|
442
410
|
}
|
|
411
|
+
async processInternalCalls(turn, internalCalls, allToolCalls, steeringQueue, iterations) {
|
|
412
|
+
allToolCalls.push(...internalCalls);
|
|
413
|
+
if (turn.signal.aborted) {
|
|
414
|
+
return await this.finishTurn(turn, '', 'halted', iterations, allToolCalls);
|
|
415
|
+
}
|
|
416
|
+
await this.executeToolBatch(turn, internalCalls);
|
|
417
|
+
this.drainSteering(turn, steeringQueue);
|
|
418
|
+
return undefined;
|
|
419
|
+
}
|
|
420
|
+
async executeToolBatch(turn, internalCalls) {
|
|
421
|
+
const results = await Promise.all(internalCalls.map(async (toolCall) => {
|
|
422
|
+
const beforeToolCtx = { turn, toolCall };
|
|
423
|
+
const beforeToolResult = await this.runHooks('beforeTool', beforeToolCtx);
|
|
424
|
+
let toolResult;
|
|
425
|
+
if (beforeToolResult.skipped && beforeToolResult.value) {
|
|
426
|
+
toolResult = beforeToolResult.value;
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
toolResult = await this.executeToolCall(toolCall, turn);
|
|
430
|
+
}
|
|
431
|
+
const afterToolCtx = { turn, toolCall, toolResult };
|
|
432
|
+
const afterToolResult = await this.runHooks('afterTool', afterToolCtx);
|
|
433
|
+
if (afterToolResult.value) {
|
|
434
|
+
toolResult = afterToolResult.value;
|
|
435
|
+
}
|
|
436
|
+
return { toolCall, toolResult };
|
|
437
|
+
}));
|
|
438
|
+
for (const { toolCall, toolResult } of results) {
|
|
439
|
+
turn.messages.push({
|
|
440
|
+
role: 'tool',
|
|
441
|
+
content: toolResult.content,
|
|
442
|
+
toolCallId: toolCall.id,
|
|
443
|
+
name: toolCall.name,
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
443
447
|
async executeToolCall(toolCall, turn) {
|
|
444
448
|
const tool = turn.tools.find((t) => t.name === toolCall.name);
|
|
445
449
|
if (!tool) {
|
|
@@ -524,16 +528,9 @@ export class Agent {
|
|
|
524
528
|
drainSteering(turn, steeringQueue) {
|
|
525
529
|
while (steeringQueue.length > 0) {
|
|
526
530
|
const msg = steeringQueue.shift();
|
|
527
|
-
// Inject
|
|
528
|
-
//
|
|
529
|
-
//
|
|
530
|
-
// Models deprioritize mid-conversation system messages, so we
|
|
531
|
-
// pair it with a user message (which models can't ignore) and
|
|
532
|
-
// use the system message to frame it as a hard redirect.
|
|
533
|
-
turn.messages.push({
|
|
534
|
-
role: 'system',
|
|
535
|
-
content: '[steering] The user has sent a new directive. You must address it immediately. Do not continue the previous task — pivot to the user\'s new request now.',
|
|
536
|
-
});
|
|
531
|
+
// Inject the steering directive as a user message. We do not inject a
|
|
532
|
+
// role: 'system' message here because LLM providers (Anthropic, Gemini,
|
|
533
|
+
// OpenAI) forbid or reject mid-conversation system messages.
|
|
537
534
|
turn.messages.push({
|
|
538
535
|
role: 'user',
|
|
539
536
|
content: `[steering] ${msg}`,
|
|
@@ -578,6 +575,7 @@ export class Agent {
|
|
|
578
575
|
class RunHandleImpl {
|
|
579
576
|
abort;
|
|
580
577
|
steeringQueue;
|
|
578
|
+
messageListeners = [];
|
|
581
579
|
_done;
|
|
582
580
|
constructor(abort, steeringQueue) {
|
|
583
581
|
this.abort = abort;
|
|
@@ -606,6 +604,20 @@ class RunHandleImpl {
|
|
|
606
604
|
halt(reason = 'halted') {
|
|
607
605
|
this.abort.abort(reason);
|
|
608
606
|
}
|
|
607
|
+
onMessage(callback) {
|
|
608
|
+
this.messageListeners.push(callback);
|
|
609
|
+
return this;
|
|
610
|
+
}
|
|
611
|
+
emitMessage(message) {
|
|
612
|
+
for (const listener of this.messageListeners) {
|
|
613
|
+
try {
|
|
614
|
+
listener(message);
|
|
615
|
+
}
|
|
616
|
+
catch (err) {
|
|
617
|
+
console.error('[handle] onMessage listener error:', err);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
609
621
|
// Thenable — allows `await handle` to work.
|
|
610
622
|
then(onfulfilled, onrejected) {
|
|
611
623
|
return this.done.then(onfulfilled, onrejected);
|