@jcheesepkg/nanobot 0.9.0 → 0.9.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/README.md +18 -18
- package/dist/agent/context.d.mts +4 -4
- package/dist/agent/context.d.mts.map +1 -1
- package/dist/agent/context.mjs +27 -28
- package/dist/agent/context.mjs.map +1 -1
- package/dist/agent/loop.d.mts +5 -3
- package/dist/agent/loop.d.mts.map +1 -1
- package/dist/agent/loop.mjs +64 -55
- package/dist/agent/loop.mjs.map +1 -1
- package/dist/agent/memory.d.mts.map +1 -1
- package/dist/agent/memory.mjs +3 -3
- package/dist/agent/memory.mjs.map +1 -1
- package/dist/agent/skills.d.mts.map +1 -1
- package/dist/agent/skills.mjs +4 -4
- package/dist/agent/skills.mjs.map +1 -1
- package/dist/agent/subagent.d.mts.map +1 -1
- package/dist/agent/subagent.mjs +22 -22
- package/dist/agent/subagent.mjs.map +1 -1
- package/dist/agent/tools/base.mjs +2 -2
- package/dist/agent/tools/base.mjs.map +1 -1
- package/dist/agent/tools/cron.d.mts +1 -1
- package/dist/agent/tools/cron.d.mts.map +1 -1
- package/dist/agent/tools/cron.mjs +11 -11
- package/dist/agent/tools/cron.mjs.map +1 -1
- package/dist/agent/tools/filesystem.d.mts +4 -4
- package/dist/agent/tools/filesystem.d.mts.map +1 -1
- package/dist/agent/tools/filesystem.mjs +20 -20
- package/dist/agent/tools/filesystem.mjs.map +1 -1
- package/dist/agent/tools/flex.d.mts +1 -1
- package/dist/agent/tools/flex.d.mts.map +1 -1
- package/dist/agent/tools/flex.mjs +112 -112
- package/dist/agent/tools/flex.mjs.map +1 -1
- package/dist/agent/tools/flex.test.mjs +60 -59
- package/dist/agent/tools/flex.test.mjs.map +1 -1
- package/dist/agent/tools/message.d.mts +1 -1
- package/dist/agent/tools/message.d.mts.map +1 -1
- package/dist/agent/tools/message.mjs +4 -4
- package/dist/agent/tools/message.mjs.map +1 -1
- package/dist/agent/tools/registry.d.mts.map +1 -1
- package/dist/agent/tools/registry.mjs +4 -4
- package/dist/agent/tools/registry.mjs.map +1 -1
- package/dist/agent/tools/shell.d.mts +1 -1
- package/dist/agent/tools/shell.mjs +4 -4
- package/dist/agent/tools/shell.mjs.map +1 -1
- package/dist/agent/tools/spawn.d.mts +1 -1
- package/dist/agent/tools/spawn.d.mts.map +1 -1
- package/dist/agent/tools/spawn.mjs +4 -4
- package/dist/agent/tools/spawn.mjs.map +1 -1
- package/dist/agent/tools/web.d.mts +2 -2
- package/dist/agent/tools/web.d.mts.map +1 -1
- package/dist/agent/tools/web.mjs +36 -36
- package/dist/agent/tools/web.mjs.map +1 -1
- package/dist/bus/events.mjs +1 -1
- package/dist/bus/events.mjs.map +1 -1
- package/dist/bus/queue.d.mts.map +1 -1
- package/dist/bus/queue.mjs.map +1 -1
- package/dist/channels/base.d.mts.map +1 -1
- package/dist/channels/base.mjs +2 -2
- package/dist/channels/base.mjs.map +1 -1
- package/dist/channels/line.d.mts +1 -0
- package/dist/channels/line.d.mts.map +1 -1
- package/dist/channels/line.mjs +65 -65
- package/dist/channels/line.mjs.map +1 -1
- package/dist/channels/line.test.mjs +26 -27
- package/dist/channels/line.test.mjs.map +1 -1
- package/dist/channels/manager.d.mts.map +1 -1
- package/dist/channels/manager.mjs +9 -9
- package/dist/channels/manager.mjs.map +1 -1
- package/dist/channels/telegram.mjs +34 -34
- package/dist/channels/telegram.mjs.map +1 -1
- package/dist/cli/index.mjs +36 -36
- package/dist/cli/index.mjs.map +1 -1
- package/dist/config/loader.d.mts.map +1 -1
- package/dist/config/loader.mjs +1 -1
- package/dist/config/loader.mjs.map +1 -1
- package/dist/config/schema.d.mts +381 -381
- package/dist/config/schema.d.mts.map +1 -1
- package/dist/config/schema.mjs +42 -42
- package/dist/config/schema.mjs.map +1 -1
- package/dist/gateway/server.d.mts.map +1 -1
- package/dist/gateway/server.mjs +48 -54
- package/dist/gateway/server.mjs.map +1 -1
- package/dist/heartbeat/service.d.mts.map +1 -1
- package/dist/heartbeat/service.mjs +8 -8
- package/dist/heartbeat/service.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/node_modules/{@jridgewell → .bun/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell}/sourcemap-codec/dist/sourcemap-codec.mjs +1 -1
- package/dist/node_modules/.bun/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_expect@2.1.9/node_modules/@vitest}/expect/dist/index.mjs +8 -8
- package/dist/node_modules/.bun/@vitest_expect@2.1.9/node_modules/@vitest/expect/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_pretty-format@2.1.9/node_modules/@vitest}/pretty-format/dist/index.mjs +2 -2
- package/dist/node_modules/.bun/@vitest_pretty-format@2.1.9/node_modules/@vitest/pretty-format/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_runner@2.1.9/node_modules/@vitest}/runner/dist/chunk-tasks.mjs +1 -1
- package/dist/node_modules/.bun/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/chunk-tasks.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_runner@2.1.9/node_modules/@vitest}/runner/dist/index.mjs +6 -6
- package/dist/node_modules/.bun/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_snapshot@2.1.9/node_modules/@vitest}/snapshot/dist/index.mjs +5 -5
- package/dist/node_modules/.bun/@vitest_snapshot@2.1.9/node_modules/@vitest/snapshot/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_spy@2.1.9/node_modules/@vitest}/spy/dist/index.mjs +2 -2
- package/dist/node_modules/.bun/@vitest_spy@2.1.9/node_modules/@vitest/spy/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/chunk-_commonjsHelpers.mjs +3 -3
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/diff.mjs +4 -4
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/diff.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/error.mjs +3 -3
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/error.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/helpers.mjs +1 -1
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/helpers.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/index.mjs +3 -3
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/source-map.mjs +1 -1
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/source-map.mjs.map +1 -0
- package/dist/node_modules/{chai → .bun/chai@5.3.3/node_modules/chai}/index.mjs +1 -1
- package/dist/node_modules/.bun/chai@5.3.3/node_modules/chai/index.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/arguments.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/arguments.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/array.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/array.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/bigint.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/bigint.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/class.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/class.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/date.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/date.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/error.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/error.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/function.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/function.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/helpers.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/helpers.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/html.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/html.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/index.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/index.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/map.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/map.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/number.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/number.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/object.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/object.mjs.map +1 -0
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/promise.mjs +6 -0
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/promise.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/regexp.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/regexp.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/set.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/set.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/string.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/string.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/symbol.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/symbol.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/typedarray.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/typedarray.mjs.map +1 -0
- package/dist/node_modules/{magic-string → .bun/magic-string@0.30.21/node_modules/magic-string}/dist/magic-string.es.mjs +2 -2
- package/dist/node_modules/.bun/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.mjs.map +1 -0
- package/dist/node_modules/{@vitest/snapshot → .bun/pathe@1.1.2}/node_modules/pathe/dist/shared/pathe.ff20891b.mjs +1 -1
- package/dist/node_modules/.bun/pathe@1.1.2/node_modules/pathe/dist/shared/pathe.ff20891b.mjs.map +1 -0
- package/dist/node_modules/{tinyrainbow → .bun/tinyrainbow@1.2.0/node_modules/tinyrainbow}/dist/chunk-BVHSVHOK.mjs +1 -1
- package/dist/node_modules/.bun/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.mjs.map +1 -0
- package/dist/node_modules/{tinyrainbow → .bun/tinyrainbow@1.2.0/node_modules/tinyrainbow}/dist/node.mjs +1 -1
- package/dist/node_modules/.bun/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/node.mjs.map +1 -0
- package/dist/node_modules/{tinyspy → .bun/tinyspy@3.0.2/node_modules/tinyspy}/dist/index.mjs +1 -1
- package/dist/node_modules/.bun/tinyspy@3.0.2/node_modules/tinyspy/dist/index.mjs.map +1 -0
- package/dist/node_modules/{vitest → .bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest}/dist/chunks/_commonjsHelpers.BFTU3MAI.mjs +1 -1
- package/dist/node_modules/.bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.mjs.map +1 -0
- package/dist/node_modules/{vitest → .bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest}/dist/chunks/date.W2xKR2qe.mjs +1 -1
- package/dist/node_modules/.bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest/dist/chunks/date.W2xKR2qe.mjs.map +1 -0
- package/dist/node_modules/{vitest → .bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest}/dist/chunks/utils.C8RiOc4B.mjs +2 -2
- package/dist/node_modules/.bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest/dist/chunks/utils.C8RiOc4B.mjs.map +1 -0
- package/dist/node_modules/{vitest → .bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest}/dist/chunks/vi.DgezovHB.mjs +11 -11
- package/dist/node_modules/.bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest/dist/chunks/vi.DgezovHB.mjs.map +1 -0
- package/dist/providers/base.d.mts +2 -2
- package/dist/providers/base.d.mts.map +1 -1
- package/dist/providers/openai-provider.d.mts.map +1 -1
- package/dist/providers/openai-provider.mjs +10 -9
- package/dist/providers/openai-provider.mjs.map +1 -1
- package/dist/providers/registry.d.mts +1 -1
- package/dist/providers/registry.d.mts.map +1 -1
- package/dist/providers/registry.mjs +99 -99
- package/dist/providers/registry.mjs.map +1 -1
- package/dist/session/manager.d.mts +2 -2
- package/dist/session/manager.d.mts.map +1 -1
- package/dist/session/manager.mjs +18 -19
- package/dist/session/manager.mjs.map +1 -1
- package/dist/utils/helpers.d.mts.map +1 -1
- package/dist/utils/helpers.mjs.map +1 -1
- package/package.json +11 -11
- package/skills/cron/SKILL.md +12 -8
- package/skills/daily-summary/SKILL.md +5 -1
- package/skills/english/SKILL.md +72 -14
- package/skills/expense/SKILL.md +15 -11
- package/skills/fortune/SKILL.md +25 -21
- package/skills/habit/SKILL.md +7 -6
- package/skills/hydration/SKILL.md +8 -5
- package/skills/memory/SKILL.md +1 -0
- package/skills/mood/SKILL.md +13 -9
- package/skills/skill-creator/SKILL.md +22 -0
- package/skills/summarize/SKILL.md +1 -0
- package/skills/weather/SKILL.md +11 -9
- package/dist/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map +0 -1
- package/dist/node_modules/@vitest/expect/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/pretty-format/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/runner/dist/chunk-tasks.mjs.map +0 -1
- package/dist/node_modules/@vitest/runner/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/snapshot/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/snapshot/node_modules/pathe/dist/shared/pathe.ff20891b.mjs.map +0 -1
- package/dist/node_modules/@vitest/spy/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/diff.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/error.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/helpers.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/source-map.mjs.map +0 -1
- package/dist/node_modules/chai/index.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/arguments.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/array.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/bigint.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/class.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/date.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/error.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/function.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/helpers.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/html.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/index.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/map.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/number.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/object.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/promise.mjs +0 -6
- package/dist/node_modules/loupe/lib/promise.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/regexp.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/set.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/string.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/symbol.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/typedarray.mjs.map +0 -1
- package/dist/node_modules/magic-string/dist/magic-string.es.mjs.map +0 -1
- package/dist/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.mjs.map +0 -1
- package/dist/node_modules/tinyrainbow/dist/node.mjs.map +0 -1
- package/dist/node_modules/tinyspy/dist/index.mjs.map +0 -1
- package/dist/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.mjs.map +0 -1
- package/dist/node_modules/vitest/dist/chunks/date.W2xKR2qe.mjs.map +0 -1
- package/dist/node_modules/vitest/dist/chunks/utils.C8RiOc4B.mjs.map +0 -1
- package/dist/node_modules/vitest/dist/chunks/vi.DgezovHB.mjs.map +0 -1
- /package/dist/node_modules/{@vitest → .bun/@vitest_runner@2.1.9/node_modules/@vitest}/runner/dist/utils.mjs +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-provider.mjs","names":[],"sources":["../../src/providers/openai-provider.ts"],"sourcesContent":["import OpenAI from \"openai\";\nimport type {\n LLMProvider,\n LLMResponse,\n ToolCallRequest,\n ToolDefinition,\n ChatMessage,\n} from \"./base.js\";\n\n/**\n * LLM provider using the OpenAI SDK.\n *\n * Works with OpenAI, OpenRouter, Anthropic (via proxy), and any\n * OpenAI-compatible API by setting apiBase.\n */\nexport class OpenAIProvider implements LLMProvider {\n private client: OpenAI;\n private defaultModel: string;\n private extraHeaders: Record<string, string>;\n\n constructor(params: {\n apiKey: string;\n apiBase?: string | null;\n defaultModel?: string;\n extraHeaders?: Record<string, string> | null;\n }) {\n this.client = new OpenAI({\n apiKey: params.apiKey,\n baseURL: params.apiBase ?? undefined,\n defaultHeaders: params.extraHeaders ?? undefined,\n });\n this.defaultModel
|
|
1
|
+
{"version":3,"file":"openai-provider.mjs","names":[],"sources":["../../src/providers/openai-provider.ts"],"sourcesContent":["import { OpenAI } from \"openai\";\n\nimport type {\n LLMProvider,\n LLMResponse,\n ToolCallRequest,\n ToolDefinition,\n ChatMessage,\n} from \"./base.js\";\n\n/**\n * LLM provider using the OpenAI SDK.\n *\n * Works with OpenAI, OpenRouter, Anthropic (via proxy), and any\n * OpenAI-compatible API by setting apiBase.\n */\nexport class OpenAIProvider implements LLMProvider {\n private client: OpenAI;\n private defaultModel: string;\n private extraHeaders: Record<string, string>;\n\n constructor(params: {\n apiKey: string;\n apiBase?: string | null;\n defaultModel?: string;\n extraHeaders?: Record<string, string> | null;\n }) {\n this.client = new OpenAI({\n apiKey: params.apiKey,\n baseURL: params.apiBase ?? undefined,\n defaultHeaders: params.extraHeaders ?? undefined,\n });\n this.defaultModel =\n params.defaultModel ?? \"anthropic/claude-sonnet-4-20250514\";\n this.extraHeaders = params.extraHeaders ?? {};\n }\n\n getDefaultModel(): string {\n return this.defaultModel;\n }\n\n async chat(params: {\n messages: ChatMessage[];\n tools?: ToolDefinition[];\n model?: string;\n maxTokens?: number;\n signal?: AbortSignal;\n }): Promise<LLMResponse> {\n const model = params.model ?? this.defaultModel;\n\n const requestParams: OpenAI.ChatCompletionCreateParams = {\n max_tokens: params.maxTokens ?? 8192,\n messages: params.messages as OpenAI.ChatCompletionMessageParam[],\n model,\n };\n\n if (params.tools && params.tools.length > 0) {\n requestParams.tools = params.tools as OpenAI.ChatCompletionTool[];\n }\n\n const response = await this.client.chat.completions.create(\n requestParams,\n params.signal ? { signal: params.signal } : undefined\n );\n\n const choice = response.choices[0];\n if (!choice) {\n return {\n content: null,\n hasToolCalls: false,\n toolCalls: [],\n };\n }\n\n const { message } = choice;\n const toolCalls: ToolCallRequest[] = [];\n\n if (message.tool_calls) {\n for (const tc of message.tool_calls) {\n let args: Record<string, unknown> = {};\n try {\n args = JSON.parse(tc.function.arguments);\n } catch {\n // If JSON parse fails, wrap raw string\n args = { _raw: tc.function.arguments };\n }\n\n toolCalls.push({\n arguments: args,\n id: tc.id,\n name: tc.function.name,\n });\n }\n }\n\n return {\n content: message.content ?? null,\n hasToolCalls: toolCalls.length > 0,\n toolCalls,\n usage: response.usage\n ? {\n promptTokens: response.usage.prompt_tokens,\n completionTokens: response.usage.completion_tokens,\n totalTokens: response.usage.total_tokens,\n }\n : undefined,\n };\n }\n}\n"],"mappings":";;;;;;;;;AAgBA,IAAa,iBAAb,MAAmD;CACjD,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YAAY,QAKT;AACD,OAAK,SAAS,IAAI,OAAO;GACvB,QAAQ,OAAO;GACf,SAAS,OAAO,WAAW;GAC3B,gBAAgB,OAAO,gBAAgB;GACxC,CAAC;AACF,OAAK,eACH,OAAO,gBAAgB;AACzB,OAAK,eAAe,OAAO,gBAAgB,EAAE;;CAG/C,kBAA0B;AACxB,SAAO,KAAK;;CAGd,MAAM,KAAK,QAMc;EACvB,MAAM,QAAQ,OAAO,SAAS,KAAK;EAEnC,MAAM,gBAAmD;GACvD,YAAY,OAAO,aAAa;GAChC,UAAU,OAAO;GACjB;GACD;AAED,MAAI,OAAO,SAAS,OAAO,MAAM,SAAS,EACxC,eAAc,QAAQ,OAAO;EAG/B,MAAM,WAAW,MAAM,KAAK,OAAO,KAAK,YAAY,OAClD,eACA,OAAO,SAAS,EAAE,QAAQ,OAAO,QAAQ,GAAG,OAC7C;EAED,MAAM,SAAS,SAAS,QAAQ;AAChC,MAAI,CAAC,OACH,QAAO;GACL,SAAS;GACT,cAAc;GACd,WAAW,EAAE;GACd;EAGH,MAAM,EAAE,YAAY;EACpB,MAAM,YAA+B,EAAE;AAEvC,MAAI,QAAQ,WACV,MAAK,MAAM,MAAM,QAAQ,YAAY;GACnC,IAAI,OAAgC,EAAE;AACtC,OAAI;AACF,WAAO,KAAK,MAAM,GAAG,SAAS,UAAU;WAClC;AAEN,WAAO,EAAE,MAAM,GAAG,SAAS,WAAW;;AAGxC,aAAU,KAAK;IACb,WAAW;IACX,IAAI,GAAG;IACP,MAAM,GAAG,SAAS;IACnB,CAAC;;AAIN,SAAO;GACL,SAAS,QAAQ,WAAW;GAC5B,cAAc,UAAU,SAAS;GACjC;GACA,OAAO,SAAS,QACZ;IACE,cAAc,SAAS,MAAM;IAC7B,kBAAkB,SAAS,MAAM;IACjC,aAAa,SAAS,MAAM;IAC7B,GACD;GACL"}
|
|
@@ -40,7 +40,7 @@ interface ProviderSpec {
|
|
|
40
40
|
/** Strip "provider/" from model before re-prefixing (for gateways like AiHubMix) */
|
|
41
41
|
readonly stripModelPrefix: boolean;
|
|
42
42
|
/** Per-model param overrides, e.g. { "kimi-k2.5": { temperature: 1.0 } } */
|
|
43
|
-
readonly modelOverrides:
|
|
43
|
+
readonly modelOverrides: readonly (readonly [pattern: string, overrides: Record<string, unknown>])[];
|
|
44
44
|
}
|
|
45
45
|
declare const PROVIDERS: readonly ProviderSpec[];
|
|
46
46
|
/** Match a standard provider by model-name keyword (case-insensitive).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.mts","names":[],"sources":["../../src/providers/registry.ts"],"mappings":";;AAcA;;;;;;;;;;;;UAAiB,YAAA;EA2BN;EAAA,SAzBA,IAAA;EA+BA;EAAA,SA7BA,QAAA;
|
|
1
|
+
{"version":3,"file":"registry.d.mts","names":[],"sources":["../../src/providers/registry.ts"],"mappings":";;AAcA;;;;;;;;;;;;UAAiB,YAAA;EA2BN;EAAA,SAzBA,IAAA;EA+BA;EAAA,SA7BA,QAAA;EA+BP;EAAA,SA7BO,WAAA;EA6BU;;AAQrB;;;EARqB,SAtBV,WAAA;EA8BkC;EAAA,SA5BlC,YAAA;EAiNgB;EAAA,SA9MhB,SAAA;EA8MiB;EAAA,SA5MjB,OAAA;EA+NK;EAAA,SA5NL,iBAAA;;WAEA,mBAAA;EA2NT;EAAA,SAzNS,cAAA;EA2NT;EAAA,SAxNS,gBAAA;EAyNI;EAAA,SAtNJ,cAAA,sBACP,OAAA,UACA,SAAA,EAAW,MAAA;AAAA;AAAA,cAQF,SAAA,WAAoB,YAAA;AAwOjC;;AAAA,iBAnDgB,WAAA,CAAY,KAAA,WAAgB,YAAA;;;;;;;iBAmB5B,WAAA,CACd,YAAA,kBACA,MAAA,kBACA,OAAA,mBACC,YAAA;;iBAsBa,UAAA,CAAW,IAAA,WAAe,YAAA;;;iBAM1B,YAAA,CACd,KAAA,UACA,OAAA,EAAS,YAAA;;iBAwBK,iBAAA,CACd,KAAA,WACC,MAAA"}
|
|
@@ -1,49 +1,54 @@
|
|
|
1
1
|
//#region src/providers/registry.ts
|
|
2
2
|
const PROVIDERS = [
|
|
3
3
|
{
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
defaultApiBase: "https://openrouter.ai/api/v1",
|
|
5
|
+
detectByBaseKeyword: "openrouter",
|
|
6
|
+
detectByKeyPrefix: "sk-or-",
|
|
6
7
|
displayName: "OpenRouter",
|
|
7
|
-
modelPrefix: "",
|
|
8
|
-
skipPrefixes: [],
|
|
9
8
|
isGateway: true,
|
|
10
9
|
isLocal: false,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
keywords: ["openrouter"],
|
|
11
|
+
modelOverrides: [],
|
|
12
|
+
modelPrefix: "",
|
|
13
|
+
name: "openrouter",
|
|
14
|
+
skipPrefixes: [],
|
|
15
|
+
stripModelPrefix: false
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
defaultApiBase: "https://aihubmix.com/v1",
|
|
19
|
+
detectByBaseKeyword: "aihubmix",
|
|
20
|
+
detectByKeyPrefix: "",
|
|
20
21
|
displayName: "AiHubMix",
|
|
21
|
-
modelPrefix: "",
|
|
22
|
-
skipPrefixes: [],
|
|
23
22
|
isGateway: true,
|
|
24
23
|
isLocal: false,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
keywords: ["aihubmix"],
|
|
25
|
+
modelOverrides: [],
|
|
26
|
+
modelPrefix: "",
|
|
27
|
+
name: "aihubmix",
|
|
28
|
+
skipPrefixes: [],
|
|
29
|
+
stripModelPrefix: true
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
defaultApiBase: "",
|
|
33
|
+
detectByBaseKeyword: "",
|
|
34
|
+
detectByKeyPrefix: "",
|
|
34
35
|
displayName: "Anthropic",
|
|
35
|
-
modelPrefix: "",
|
|
36
|
-
skipPrefixes: [],
|
|
37
36
|
isGateway: false,
|
|
38
37
|
isLocal: false,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
keywords: ["anthropic", "claude"],
|
|
39
|
+
modelOverrides: [],
|
|
40
|
+
modelPrefix: "",
|
|
41
|
+
name: "anthropic",
|
|
42
|
+
skipPrefixes: [],
|
|
43
|
+
stripModelPrefix: false
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
|
-
|
|
46
|
+
defaultApiBase: "",
|
|
47
|
+
detectByBaseKeyword: "",
|
|
48
|
+
detectByKeyPrefix: "",
|
|
49
|
+
displayName: "OpenAI",
|
|
50
|
+
isGateway: false,
|
|
51
|
+
isLocal: false,
|
|
47
52
|
keywords: [
|
|
48
53
|
"openai",
|
|
49
54
|
"gpt",
|
|
@@ -51,114 +56,109 @@ const PROVIDERS = [
|
|
|
51
56
|
"o3",
|
|
52
57
|
"o4"
|
|
53
58
|
],
|
|
54
|
-
|
|
59
|
+
modelOverrides: [],
|
|
55
60
|
modelPrefix: "",
|
|
61
|
+
name: "openai",
|
|
56
62
|
skipPrefixes: [],
|
|
57
|
-
|
|
58
|
-
isLocal: false,
|
|
59
|
-
detectByKeyPrefix: "",
|
|
60
|
-
detectByBaseKeyword: "",
|
|
61
|
-
defaultApiBase: "",
|
|
62
|
-
stripModelPrefix: false,
|
|
63
|
-
modelOverrides: []
|
|
63
|
+
stripModelPrefix: false
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
defaultApiBase: "https://api.deepseek.com/v1",
|
|
67
|
+
detectByBaseKeyword: "",
|
|
68
|
+
detectByKeyPrefix: "",
|
|
68
69
|
displayName: "DeepSeek",
|
|
69
|
-
modelPrefix: "deepseek",
|
|
70
|
-
skipPrefixes: ["deepseek/"],
|
|
71
70
|
isGateway: false,
|
|
72
71
|
isLocal: false,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
keywords: ["deepseek"],
|
|
73
|
+
modelOverrides: [],
|
|
74
|
+
modelPrefix: "deepseek",
|
|
75
|
+
name: "deepseek",
|
|
76
|
+
skipPrefixes: ["deepseek/"],
|
|
77
|
+
stripModelPrefix: false
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
defaultApiBase: "",
|
|
81
|
+
detectByBaseKeyword: "",
|
|
82
|
+
detectByKeyPrefix: "",
|
|
82
83
|
displayName: "Gemini",
|
|
83
|
-
modelPrefix: "gemini",
|
|
84
|
-
skipPrefixes: ["gemini/"],
|
|
85
84
|
isGateway: false,
|
|
86
85
|
isLocal: false,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
keywords: ["gemini"],
|
|
87
|
+
modelOverrides: [],
|
|
88
|
+
modelPrefix: "gemini",
|
|
89
|
+
name: "gemini",
|
|
90
|
+
skipPrefixes: ["gemini/"],
|
|
91
|
+
stripModelPrefix: false
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
defaultApiBase: "https://open.bigmodel.cn/api/paas/v4",
|
|
95
|
+
detectByBaseKeyword: "",
|
|
96
|
+
detectByKeyPrefix: "",
|
|
96
97
|
displayName: "Zhipu AI",
|
|
97
|
-
modelPrefix: "",
|
|
98
|
-
skipPrefixes: [],
|
|
99
98
|
isGateway: false,
|
|
100
99
|
isLocal: false,
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
keywords: ["zhipu", "glm"],
|
|
101
|
+
modelOverrides: [],
|
|
102
|
+
modelPrefix: "",
|
|
103
|
+
name: "zhipu",
|
|
104
|
+
skipPrefixes: [],
|
|
105
|
+
stripModelPrefix: false
|
|
106
106
|
},
|
|
107
107
|
{
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
defaultApiBase: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
109
|
+
detectByBaseKeyword: "",
|
|
110
|
+
detectByKeyPrefix: "",
|
|
110
111
|
displayName: "DashScope",
|
|
111
|
-
modelPrefix: "",
|
|
112
|
-
skipPrefixes: [],
|
|
113
112
|
isGateway: false,
|
|
114
113
|
isLocal: false,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
114
|
+
keywords: ["qwen", "dashscope"],
|
|
115
|
+
modelOverrides: [],
|
|
116
|
+
modelPrefix: "",
|
|
117
|
+
name: "dashscope",
|
|
118
|
+
skipPrefixes: [],
|
|
119
|
+
stripModelPrefix: false
|
|
120
120
|
},
|
|
121
121
|
{
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
defaultApiBase: "https://api.moonshot.ai/v1",
|
|
123
|
+
detectByBaseKeyword: "",
|
|
124
|
+
detectByKeyPrefix: "",
|
|
124
125
|
displayName: "Moonshot",
|
|
125
|
-
modelPrefix: "",
|
|
126
|
-
skipPrefixes: [],
|
|
127
126
|
isGateway: false,
|
|
128
127
|
isLocal: false,
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
128
|
+
keywords: ["moonshot", "kimi"],
|
|
129
|
+
modelOverrides: [["kimi-k2.5", { temperature: 1 }]],
|
|
130
|
+
modelPrefix: "",
|
|
131
|
+
name: "moonshot",
|
|
132
|
+
skipPrefixes: [],
|
|
133
|
+
stripModelPrefix: false
|
|
134
134
|
},
|
|
135
135
|
{
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
defaultApiBase: "",
|
|
137
|
+
detectByBaseKeyword: "",
|
|
138
|
+
detectByKeyPrefix: "",
|
|
138
139
|
displayName: "vLLM/Local",
|
|
139
|
-
modelPrefix: "",
|
|
140
|
-
skipPrefixes: [],
|
|
141
140
|
isGateway: false,
|
|
142
141
|
isLocal: true,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
142
|
+
keywords: ["vllm"],
|
|
143
|
+
modelOverrides: [],
|
|
144
|
+
modelPrefix: "",
|
|
145
|
+
name: "vllm",
|
|
146
|
+
skipPrefixes: [],
|
|
147
|
+
stripModelPrefix: false
|
|
148
148
|
},
|
|
149
149
|
{
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
defaultApiBase: "https://api.groq.com/openai/v1",
|
|
151
|
+
detectByBaseKeyword: "",
|
|
152
|
+
detectByKeyPrefix: "",
|
|
152
153
|
displayName: "Groq",
|
|
153
|
-
modelPrefix: "",
|
|
154
|
-
skipPrefixes: [],
|
|
155
154
|
isGateway: false,
|
|
156
155
|
isLocal: false,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
keywords: ["groq"],
|
|
157
|
+
modelOverrides: [],
|
|
158
|
+
modelPrefix: "",
|
|
159
|
+
name: "groq",
|
|
160
|
+
skipPrefixes: [],
|
|
161
|
+
stripModelPrefix: false
|
|
162
162
|
}
|
|
163
163
|
];
|
|
164
164
|
/** Match a standard provider by model-name keyword (case-insensitive).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.mjs","names":[],"sources":["../../src/providers/registry.ts"],"sourcesContent":["/**\n * Provider Registry — single source of truth for LLM provider metadata.\n *\n * Adding a new provider:\n * 1. Add a ProviderSpec to PROVIDERS below.\n * 2. Add a field to ProvidersConfigSchema in config/schema.ts.\n * Done. Config matching, status display, model resolution all derive from here.\n *\n * Order matters — it controls match priority and fallback. Gateways first.\n *\n * Ported from the Python nanobot registry (providers/registry.py).\n * Adapted for the TS port which uses the OpenAI SDK directly (no LiteLLM).\n */\n\nexport interface ProviderSpec {\n /** Config field name, e.g. \"dashscope\" */\n readonly name: string;\n /** Model-name keywords for matching (lowercase) */\n readonly keywords: readonly string[];\n /** Display name for status output */\n readonly displayName: string;\n\n /**\n * Prefix to add to model names for API routing.\n * e.g. \"deepseek\" → model becomes \"deepseek/deepseek-chat\"\n * Empty string means no prefix needed (provider recognizes model natively).\n */\n readonly modelPrefix: string;\n /** Don't add prefix if model already starts with any of these */\n readonly skipPrefixes: readonly string[];\n\n /** Gateway: routes any model (OpenRouter, AiHubMix) */\n readonly isGateway: boolean;\n /** Local deployment (vLLM, Ollama) */\n readonly isLocal: boolean;\n\n /** Match api_key prefix, e.g. \"sk-or-\" for OpenRouter */\n readonly detectByKeyPrefix: string;\n /** Match substring in api_base URL */\n readonly detectByBaseKeyword: string;\n /** Fallback base URL for this provider */\n readonly defaultApiBase: string;\n\n /** Strip \"provider/\" from model before re-prefixing (for gateways like AiHubMix) */\n readonly stripModelPrefix: boolean;\n\n /** Per-model param overrides, e.g. { \"kimi-k2.5\": { temperature: 1.0 } } */\n readonly modelOverrides: ReadonlyArray<\n readonly [pattern: string, overrides: Record<string, unknown>]\n >;\n}\n\n// ---------------------------------------------------------------------------\n// PROVIDERS — the registry. Order = priority.\n// ---------------------------------------------------------------------------\n\nexport const PROVIDERS: readonly ProviderSpec[] = [\n // === Gateways =========================================================\n\n {\n name: \"openrouter\",\n keywords: [\"openrouter\"],\n displayName: \"OpenRouter\",\n modelPrefix: \"\",\n skipPrefixes: [],\n isGateway: true,\n isLocal: false,\n detectByKeyPrefix: \"sk-or-\",\n detectByBaseKeyword: \"openrouter\",\n defaultApiBase: \"https://openrouter.ai/api/v1\",\n stripModelPrefix: false,\n modelOverrides: [],\n },\n\n {\n name: \"aihubmix\",\n keywords: [\"aihubmix\"],\n displayName: \"AiHubMix\",\n modelPrefix: \"\",\n skipPrefixes: [],\n isGateway: true,\n isLocal: false,\n detectByKeyPrefix: \"\",\n detectByBaseKeyword: \"aihubmix\",\n defaultApiBase: \"https://aihubmix.com/v1\",\n stripModelPrefix: true,\n modelOverrides: [],\n },\n\n // === Standard providers ================================================\n\n {\n name: \"anthropic\",\n keywords: [\"anthropic\", \"claude\"],\n displayName: \"Anthropic\",\n modelPrefix: \"\",\n skipPrefixes: [],\n isGateway: false,\n isLocal: false,\n detectByKeyPrefix: \"\",\n detectByBaseKeyword: \"\",\n defaultApiBase: \"\",\n stripModelPrefix: false,\n modelOverrides: [],\n },\n\n {\n name: \"openai\",\n keywords: [\"openai\", \"gpt\", \"o1\", \"o3\", \"o4\"],\n displayName: \"OpenAI\",\n modelPrefix: \"\",\n skipPrefixes: [],\n isGateway: false,\n isLocal: false,\n detectByKeyPrefix: \"\",\n detectByBaseKeyword: \"\",\n defaultApiBase: \"\",\n stripModelPrefix: false,\n modelOverrides: [],\n },\n\n {\n name: \"deepseek\",\n keywords: [\"deepseek\"],\n displayName: \"DeepSeek\",\n modelPrefix: \"deepseek\",\n skipPrefixes: [\"deepseek/\"],\n isGateway: false,\n isLocal: false,\n detectByKeyPrefix: \"\",\n detectByBaseKeyword: \"\",\n defaultApiBase: \"https://api.deepseek.com/v1\",\n stripModelPrefix: false,\n modelOverrides: [],\n },\n\n {\n name: \"gemini\",\n keywords: [\"gemini\"],\n displayName: \"Gemini\",\n modelPrefix: \"gemini\",\n skipPrefixes: [\"gemini/\"],\n isGateway: false,\n isLocal: false,\n detectByKeyPrefix: \"\",\n detectByBaseKeyword: \"\",\n defaultApiBase: \"\",\n stripModelPrefix: false,\n modelOverrides: [],\n },\n\n {\n name: \"zhipu\",\n keywords: [\"zhipu\", \"glm\"],\n displayName: \"Zhipu AI\",\n modelPrefix: \"\",\n skipPrefixes: [],\n isGateway: false,\n isLocal: false,\n detectByKeyPrefix: \"\",\n detectByBaseKeyword: \"\",\n defaultApiBase: \"https://open.bigmodel.cn/api/paas/v4\",\n stripModelPrefix: false,\n modelOverrides: [],\n },\n\n {\n name: \"dashscope\",\n keywords: [\"qwen\", \"dashscope\"],\n displayName: \"DashScope\",\n modelPrefix: \"\",\n skipPrefixes: [],\n isGateway: false,\n isLocal: false,\n detectByKeyPrefix: \"\",\n detectByBaseKeyword: \"\",\n defaultApiBase: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n stripModelPrefix: false,\n modelOverrides: [],\n },\n\n {\n name: \"moonshot\",\n keywords: [\"moonshot\", \"kimi\"],\n displayName: \"Moonshot\",\n modelPrefix: \"\",\n skipPrefixes: [],\n isGateway: false,\n isLocal: false,\n detectByKeyPrefix: \"\",\n detectByBaseKeyword: \"\",\n defaultApiBase: \"https://api.moonshot.ai/v1\",\n stripModelPrefix: false,\n modelOverrides: [[\"kimi-k2.5\", { temperature: 1.0 }]],\n },\n\n // === Local deployment ==================================================\n\n {\n name: \"vllm\",\n keywords: [\"vllm\"],\n displayName: \"vLLM/Local\",\n modelPrefix: \"\",\n skipPrefixes: [],\n isGateway: false,\n isLocal: true,\n detectByKeyPrefix: \"\",\n detectByBaseKeyword: \"\",\n defaultApiBase: \"\",\n stripModelPrefix: false,\n modelOverrides: [],\n },\n\n // === Auxiliary ==========================================================\n\n {\n name: \"groq\",\n keywords: [\"groq\"],\n displayName: \"Groq\",\n modelPrefix: \"\",\n skipPrefixes: [],\n isGateway: false,\n isLocal: false,\n detectByKeyPrefix: \"\",\n detectByBaseKeyword: \"\",\n defaultApiBase: \"https://api.groq.com/openai/v1\",\n stripModelPrefix: false,\n modelOverrides: [],\n },\n];\n\n// ---------------------------------------------------------------------------\n// Lookup helpers\n// ---------------------------------------------------------------------------\n\n/** Match a standard provider by model-name keyword (case-insensitive).\n * Skips gateways/local — those are matched by api_key/api_base instead. */\nexport function findByModel(model: string): ProviderSpec | null {\n const lower = model.toLowerCase();\n for (const spec of PROVIDERS) {\n if (spec.isGateway || spec.isLocal) continue;\n if (spec.keywords.some((kw) => lower.includes(kw))) {\n return spec;\n }\n }\n return null;\n}\n\n/** Detect gateway/local provider.\n *\n * Priority:\n * 1. providerName — if it maps to a gateway/local spec, use it directly.\n * 2. apiKey prefix — e.g. \"sk-or-\" → OpenRouter.\n * 3. apiBase keyword — e.g. \"aihubmix\" in URL → AiHubMix. */\nexport function findGateway(\n providerName?: string | null,\n apiKey?: string | null,\n apiBase?: string | null,\n): ProviderSpec | null {\n if (providerName) {\n const spec = findByName(providerName);\n if (spec && (spec.isGateway || spec.isLocal)) return spec;\n }\n for (const spec of PROVIDERS) {\n if (spec.detectByKeyPrefix && apiKey?.startsWith(spec.detectByKeyPrefix)) {\n return spec;\n }\n if (spec.detectByBaseKeyword && apiBase?.includes(spec.detectByBaseKeyword)) {\n return spec;\n }\n }\n return null;\n}\n\n/** Find a provider spec by config field name, e.g. \"dashscope\". */\nexport function findByName(name: string): ProviderSpec | null {\n return PROVIDERS.find((s) => s.name === name) ?? null;\n}\n\n/** Resolve model name: strip gateway prefix if needed, apply provider prefix.\n * Returns the model string the OpenAI SDK should send. */\nexport function resolveModel(\n model: string,\n gateway: ProviderSpec | null,\n): string {\n if (gateway) {\n if (gateway.stripModelPrefix) {\n model = model.split(\"/\").pop() ?? model;\n }\n const prefix = gateway.modelPrefix;\n if (prefix && !model.startsWith(`${prefix}/`)) {\n return `${prefix}/${model}`;\n }\n return model;\n }\n\n const spec = findByModel(model);\n if (spec?.modelPrefix) {\n if (!spec.skipPrefixes.some((p) => model.startsWith(p))) {\n return `${spec.modelPrefix}/${model}`;\n }\n }\n return model;\n}\n\n/** Get model-specific parameter overrides (e.g. temperature for kimi-k2.5). */\nexport function getModelOverrides(\n model: string,\n): Record<string, unknown> | null {\n const lower = model.toLowerCase();\n const spec = findByModel(model);\n if (!spec) return null;\n for (const [pattern, overrides] of spec.modelOverrides) {\n if (lower.includes(pattern)) return { ...overrides };\n }\n return null;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"registry.mjs","names":[],"sources":["../../src/providers/registry.ts"],"sourcesContent":["/**\n * Provider Registry — single source of truth for LLM provider metadata.\n *\n * Adding a new provider:\n * 1. Add a ProviderSpec to PROVIDERS below.\n * 2. Add a field to ProvidersConfigSchema in config/schema.ts.\n * Done. Config matching, status display, model resolution all derive from here.\n *\n * Order matters — it controls match priority and fallback. Gateways first.\n *\n * Ported from the Python nanobot registry (providers/registry.py).\n * Adapted for the TS port which uses the OpenAI SDK directly (no LiteLLM).\n */\n\nexport interface ProviderSpec {\n /** Config field name, e.g. \"dashscope\" */\n readonly name: string;\n /** Model-name keywords for matching (lowercase) */\n readonly keywords: readonly string[];\n /** Display name for status output */\n readonly displayName: string;\n\n /**\n * Prefix to add to model names for API routing.\n * e.g. \"deepseek\" → model becomes \"deepseek/deepseek-chat\"\n * Empty string means no prefix needed (provider recognizes model natively).\n */\n readonly modelPrefix: string;\n /** Don't add prefix if model already starts with any of these */\n readonly skipPrefixes: readonly string[];\n\n /** Gateway: routes any model (OpenRouter, AiHubMix) */\n readonly isGateway: boolean;\n /** Local deployment (vLLM, Ollama) */\n readonly isLocal: boolean;\n\n /** Match api_key prefix, e.g. \"sk-or-\" for OpenRouter */\n readonly detectByKeyPrefix: string;\n /** Match substring in api_base URL */\n readonly detectByBaseKeyword: string;\n /** Fallback base URL for this provider */\n readonly defaultApiBase: string;\n\n /** Strip \"provider/\" from model before re-prefixing (for gateways like AiHubMix) */\n readonly stripModelPrefix: boolean;\n\n /** Per-model param overrides, e.g. { \"kimi-k2.5\": { temperature: 1.0 } } */\n readonly modelOverrides: readonly (readonly [\n pattern: string,\n overrides: Record<string, unknown>,\n ])[];\n}\n\n// ---------------------------------------------------------------------------\n// PROVIDERS — the registry. Order = priority.\n// ---------------------------------------------------------------------------\n\nexport const PROVIDERS: readonly ProviderSpec[] = [\n // === Gateways =========================================================\n\n {\n defaultApiBase: \"https://openrouter.ai/api/v1\",\n detectByBaseKeyword: \"openrouter\",\n detectByKeyPrefix: \"sk-or-\",\n displayName: \"OpenRouter\",\n isGateway: true,\n isLocal: false,\n keywords: [\"openrouter\"],\n modelOverrides: [],\n modelPrefix: \"\",\n name: \"openrouter\",\n skipPrefixes: [],\n stripModelPrefix: false,\n },\n\n {\n defaultApiBase: \"https://aihubmix.com/v1\",\n detectByBaseKeyword: \"aihubmix\",\n detectByKeyPrefix: \"\",\n displayName: \"AiHubMix\",\n isGateway: true,\n isLocal: false,\n keywords: [\"aihubmix\"],\n modelOverrides: [],\n modelPrefix: \"\",\n name: \"aihubmix\",\n skipPrefixes: [],\n stripModelPrefix: true,\n },\n\n // === Standard providers ================================================\n\n {\n defaultApiBase: \"\",\n detectByBaseKeyword: \"\",\n detectByKeyPrefix: \"\",\n displayName: \"Anthropic\",\n isGateway: false,\n isLocal: false,\n keywords: [\"anthropic\", \"claude\"],\n modelOverrides: [],\n modelPrefix: \"\",\n name: \"anthropic\",\n skipPrefixes: [],\n stripModelPrefix: false,\n },\n\n {\n defaultApiBase: \"\",\n detectByBaseKeyword: \"\",\n detectByKeyPrefix: \"\",\n displayName: \"OpenAI\",\n isGateway: false,\n isLocal: false,\n keywords: [\"openai\", \"gpt\", \"o1\", \"o3\", \"o4\"],\n modelOverrides: [],\n modelPrefix: \"\",\n name: \"openai\",\n skipPrefixes: [],\n stripModelPrefix: false,\n },\n\n {\n defaultApiBase: \"https://api.deepseek.com/v1\",\n detectByBaseKeyword: \"\",\n detectByKeyPrefix: \"\",\n displayName: \"DeepSeek\",\n isGateway: false,\n isLocal: false,\n keywords: [\"deepseek\"],\n modelOverrides: [],\n modelPrefix: \"deepseek\",\n name: \"deepseek\",\n skipPrefixes: [\"deepseek/\"],\n stripModelPrefix: false,\n },\n\n {\n defaultApiBase: \"\",\n detectByBaseKeyword: \"\",\n detectByKeyPrefix: \"\",\n displayName: \"Gemini\",\n isGateway: false,\n isLocal: false,\n keywords: [\"gemini\"],\n modelOverrides: [],\n modelPrefix: \"gemini\",\n name: \"gemini\",\n skipPrefixes: [\"gemini/\"],\n stripModelPrefix: false,\n },\n\n {\n defaultApiBase: \"https://open.bigmodel.cn/api/paas/v4\",\n detectByBaseKeyword: \"\",\n detectByKeyPrefix: \"\",\n displayName: \"Zhipu AI\",\n isGateway: false,\n isLocal: false,\n keywords: [\"zhipu\", \"glm\"],\n modelOverrides: [],\n modelPrefix: \"\",\n name: \"zhipu\",\n skipPrefixes: [],\n stripModelPrefix: false,\n },\n\n {\n defaultApiBase: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n detectByBaseKeyword: \"\",\n detectByKeyPrefix: \"\",\n displayName: \"DashScope\",\n isGateway: false,\n isLocal: false,\n keywords: [\"qwen\", \"dashscope\"],\n modelOverrides: [],\n modelPrefix: \"\",\n name: \"dashscope\",\n skipPrefixes: [],\n stripModelPrefix: false,\n },\n\n {\n defaultApiBase: \"https://api.moonshot.ai/v1\",\n detectByBaseKeyword: \"\",\n detectByKeyPrefix: \"\",\n displayName: \"Moonshot\",\n isGateway: false,\n isLocal: false,\n keywords: [\"moonshot\", \"kimi\"],\n modelOverrides: [[\"kimi-k2.5\", { temperature: 1 }]],\n modelPrefix: \"\",\n name: \"moonshot\",\n skipPrefixes: [],\n stripModelPrefix: false,\n },\n\n // === Local deployment ==================================================\n\n {\n defaultApiBase: \"\",\n detectByBaseKeyword: \"\",\n detectByKeyPrefix: \"\",\n displayName: \"vLLM/Local\",\n isGateway: false,\n isLocal: true,\n keywords: [\"vllm\"],\n modelOverrides: [],\n modelPrefix: \"\",\n name: \"vllm\",\n skipPrefixes: [],\n stripModelPrefix: false,\n },\n\n // === Auxiliary ==========================================================\n\n {\n defaultApiBase: \"https://api.groq.com/openai/v1\",\n detectByBaseKeyword: \"\",\n detectByKeyPrefix: \"\",\n displayName: \"Groq\",\n isGateway: false,\n isLocal: false,\n keywords: [\"groq\"],\n modelOverrides: [],\n modelPrefix: \"\",\n name: \"groq\",\n skipPrefixes: [],\n stripModelPrefix: false,\n },\n];\n\n// ---------------------------------------------------------------------------\n// Lookup helpers\n// ---------------------------------------------------------------------------\n\n/** Match a standard provider by model-name keyword (case-insensitive).\n * Skips gateways/local — those are matched by api_key/api_base instead. */\nexport function findByModel(model: string): ProviderSpec | null {\n const lower = model.toLowerCase();\n for (const spec of PROVIDERS) {\n if (spec.isGateway || spec.isLocal) {\n continue;\n }\n if (spec.keywords.some((kw) => lower.includes(kw))) {\n return spec;\n }\n }\n return null;\n}\n\n/** Detect gateway/local provider.\n *\n * Priority:\n * 1. providerName — if it maps to a gateway/local spec, use it directly.\n * 2. apiKey prefix — e.g. \"sk-or-\" → OpenRouter.\n * 3. apiBase keyword — e.g. \"aihubmix\" in URL → AiHubMix. */\nexport function findGateway(\n providerName?: string | null,\n apiKey?: string | null,\n apiBase?: string | null\n): ProviderSpec | null {\n if (providerName) {\n const spec = findByName(providerName);\n if (spec && (spec.isGateway || spec.isLocal)) {\n return spec;\n }\n }\n for (const spec of PROVIDERS) {\n if (spec.detectByKeyPrefix && apiKey?.startsWith(spec.detectByKeyPrefix)) {\n return spec;\n }\n if (\n spec.detectByBaseKeyword &&\n apiBase?.includes(spec.detectByBaseKeyword)\n ) {\n return spec;\n }\n }\n return null;\n}\n\n/** Find a provider spec by config field name, e.g. \"dashscope\". */\nexport function findByName(name: string): ProviderSpec | null {\n return PROVIDERS.find((s) => s.name === name) ?? null;\n}\n\n/** Resolve model name: strip gateway prefix if needed, apply provider prefix.\n * Returns the model string the OpenAI SDK should send. */\nexport function resolveModel(\n model: string,\n gateway: ProviderSpec | null\n): string {\n if (gateway) {\n if (gateway.stripModelPrefix) {\n model = model.split(\"/\").pop() ?? model;\n }\n const prefix = gateway.modelPrefix;\n if (prefix && !model.startsWith(`${prefix}/`)) {\n return `${prefix}/${model}`;\n }\n return model;\n }\n\n const spec = findByModel(model);\n if (spec?.modelPrefix) {\n // oxlint-disable-next-line unicorn/no-lonely-if\n if (!spec.skipPrefixes.some((p) => model.startsWith(p))) {\n return `${spec.modelPrefix}/${model}`;\n }\n }\n return model;\n}\n\n/** Get model-specific parameter overrides (e.g. temperature for kimi-k2.5). */\nexport function getModelOverrides(\n model: string\n): Record<string, unknown> | null {\n const lower = model.toLowerCase();\n const spec = findByModel(model);\n if (!spec) {\n return null;\n }\n for (const [pattern, overrides] of spec.modelOverrides) {\n if (lower.includes(pattern)) {\n return { ...overrides };\n }\n }\n return null;\n}\n"],"mappings":"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"}
|
|
@@ -49,12 +49,12 @@ declare class SessionManager {
|
|
|
49
49
|
/** Delete a session. */
|
|
50
50
|
delete(key: string): boolean;
|
|
51
51
|
/** List all sessions. */
|
|
52
|
-
listSessions():
|
|
52
|
+
listSessions(): {
|
|
53
53
|
key: string;
|
|
54
54
|
createdAt?: string;
|
|
55
55
|
updatedAt?: string;
|
|
56
56
|
path: string;
|
|
57
|
-
}
|
|
57
|
+
}[];
|
|
58
58
|
}
|
|
59
59
|
//#endregion
|
|
60
60
|
export { Session, SessionManager, SessionMessage };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.mts","names":[],"sources":["../../src/session/manager.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"manager.d.mts","names":[],"sources":["../../src/session/manager.ts"],"mappings":";;;;UAeiB,cAAA;EACf,IAAA;EACA,OAAA;EACA,SAAA;EAAA,CACC,GAAA;AAAA;;cAIU,OAAA;EACX,GAAA;EALY;EAOZ,OAAA,EAAS,WAAA;EACT,SAAA,EAAW,IAAA;EACX,SAAA,EAAW,IAAA;EACX,QAAA,EAAU,MAAA;EAHD;EAKT,SAAA;cAEY,MAAA;IACV,GAAA;IACA,OAAA,GAAU,WAAA;IACV,SAAA,GAAY,IAAA;IACZ,SAAA,GAAY,IAAA;IACZ,QAAA,GAAW,MAAA;IACX,SAAA;EAAA;EAuBwC;EAZ1C,eAAA,CAAgB,QAAA,EAAU,WAAA,IAAe,SAAA;EA1BzC;EAsCA,UAAA,CAAW,WAAA,YAAoB,WAAA;EApCtB;EAgDT,WAAA,CAAY,SAAA;EA/CD;EAsDX,KAAA,CAAA;AAAA;;cAOW,cAAA;EAAA,QACH,WAAA;EAAA,QACA,KAAA;cAEI,UAAA;EAAA,QAIJ,cAAA;EA7DI;EAmEZ,WAAA,CAAY,GAAA,WAAc,OAAA;EAAA,QAiBlB,IAAA;EAlFN;EAgIF,IAAA,CAAK,OAAA,EAAS,OAAA;EA/HZ;EAqJF,MAAA,CAAO,GAAA;EApJL;EA+JF,YAAA,CAAA;IACE,GAAA;IACA,SAAA;IACA,SAAA;IACA,IAAA;EAAA;AAAA"}
|
package/dist/session/manager.mjs
CHANGED
|
@@ -35,7 +35,7 @@ var Session = class {
|
|
|
35
35
|
getHistory(maxMessages = 200) {
|
|
36
36
|
if (this.history.length <= maxMessages) return this.history;
|
|
37
37
|
let start = this.history.length - maxMessages;
|
|
38
|
-
while (start < this.history.length && this.history[start].role !== "user") start
|
|
38
|
+
while (start < this.history.length && this.history[start].role !== "user") start += 1;
|
|
39
39
|
return this.history.slice(start);
|
|
40
40
|
}
|
|
41
41
|
/** Trim history to keep only the last N messages. */
|
|
@@ -56,7 +56,7 @@ var SessionManager = class {
|
|
|
56
56
|
this.sessionsDir = ensureDir(join(homedir(), ".nanobot", "sessions"));
|
|
57
57
|
}
|
|
58
58
|
getSessionPath(key) {
|
|
59
|
-
const safeKey = safeFilename(key.
|
|
59
|
+
const safeKey = safeFilename(key.replaceAll(":", "_"));
|
|
60
60
|
return join(this.sessionsDir, `${safeKey}.jsonl`);
|
|
61
61
|
}
|
|
62
62
|
/** Get an existing session or create a new one. */
|
|
@@ -76,7 +76,7 @@ var SessionManager = class {
|
|
|
76
76
|
const path = this.getSessionPath(key);
|
|
77
77
|
if (!existsSync(path)) return null;
|
|
78
78
|
try {
|
|
79
|
-
const lines = readFileSync(path, "
|
|
79
|
+
const lines = readFileSync(path, "utf8").split("\n").filter((l) => l.trim());
|
|
80
80
|
const history = [];
|
|
81
81
|
let metadata = {};
|
|
82
82
|
let createdAt;
|
|
@@ -89,32 +89,31 @@ var SessionManager = class {
|
|
|
89
89
|
isRichFormat = data._format === "rich";
|
|
90
90
|
} else if (isRichFormat) history.push(data);
|
|
91
91
|
else history.push({
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
content: data.content ?? "",
|
|
93
|
+
role: data.role
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
return new Session({
|
|
97
|
-
key,
|
|
98
|
-
history,
|
|
99
97
|
createdAt: createdAt ?? /* @__PURE__ */ new Date(),
|
|
98
|
+
history,
|
|
99
|
+
key,
|
|
100
100
|
metadata
|
|
101
101
|
});
|
|
102
|
-
} catch (
|
|
103
|
-
console.warn(`Failed to load session ${key}:`,
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.warn(`Failed to load session ${key}:`, error);
|
|
104
104
|
return null;
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
/** Save a session to disk. */
|
|
108
108
|
save(session) {
|
|
109
109
|
const path = this.getSessionPath(session.key);
|
|
110
|
-
const lines = [
|
|
111
|
-
lines.push(JSON.stringify({
|
|
112
|
-
_type: "metadata",
|
|
110
|
+
const lines = [JSON.stringify({
|
|
113
111
|
_format: "rich",
|
|
112
|
+
_type: "metadata",
|
|
114
113
|
created_at: session.createdAt.toISOString(),
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
})
|
|
114
|
+
metadata: session.metadata,
|
|
115
|
+
updated_at: session.updatedAt.toISOString()
|
|
116
|
+
})];
|
|
118
117
|
for (const msg of session.history) lines.push(JSON.stringify(msg));
|
|
119
118
|
writeFileSync(path, lines.join("\n") + "\n");
|
|
120
119
|
this.cache.set(session.key, session);
|
|
@@ -137,14 +136,14 @@ var SessionManager = class {
|
|
|
137
136
|
if (!file.endsWith(".jsonl")) continue;
|
|
138
137
|
const filePath = join(this.sessionsDir, file);
|
|
139
138
|
try {
|
|
140
|
-
const firstLine = readFileSync(filePath, "
|
|
139
|
+
const firstLine = readFileSync(filePath, "utf8").split("\n")[0]?.trim();
|
|
141
140
|
if (firstLine) {
|
|
142
141
|
const data = JSON.parse(firstLine);
|
|
143
142
|
if (data._type === "metadata") results.push({
|
|
144
|
-
key: file.replace(".jsonl", "").replace(/_/g, ":"),
|
|
145
143
|
createdAt: data.created_at,
|
|
146
|
-
|
|
147
|
-
path: filePath
|
|
144
|
+
key: file.replace(".jsonl", "").replaceAll("_", ":"),
|
|
145
|
+
path: filePath,
|
|
146
|
+
updatedAt: data.updated_at
|
|
148
147
|
});
|
|
149
148
|
}
|
|
150
149
|
} catch {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.mjs","names":[],"sources":["../../src/session/manager.ts"],"sourcesContent":["import {\n readFileSync,\n writeFileSync,\n existsSync,\n readdirSync,\n unlinkSync,\n} from \"node:fs\";\nimport {
|
|
1
|
+
{"version":3,"file":"manager.mjs","names":[],"sources":["../../src/session/manager.ts"],"sourcesContent":["import {\n readFileSync,\n writeFileSync,\n existsSync,\n readdirSync,\n unlinkSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport type { ChatMessage } from \"../providers/base.js\";\n\nimport { ensureDir, safeFilename } from \"../utils/helpers.js\";\n\n/** A conversation message (legacy simple format, kept for JSONL compat). */\nexport interface SessionMessage {\n role: string;\n content: string;\n timestamp: string;\n [key: string]: unknown;\n}\n\n/** A conversation session. */\nexport class Session {\n key: string;\n /** Rich message history preserving tool_calls, tool results, etc. */\n history: ChatMessage[];\n createdAt: Date;\n updatedAt: Date;\n metadata: Record<string, unknown>;\n /** Tools used in the last turn (for memory consolidation). */\n toolsUsed: string[];\n\n constructor(params: {\n key: string;\n history?: ChatMessage[];\n createdAt?: Date;\n updatedAt?: Date;\n metadata?: Record<string, unknown>;\n toolsUsed?: string[];\n }) {\n this.key = params.key;\n this.history = params.history ?? [];\n this.createdAt = params.createdAt ?? new Date();\n this.updatedAt = params.updatedAt ?? new Date();\n this.metadata = params.metadata ?? {};\n this.toolsUsed = params.toolsUsed ?? [];\n }\n\n /** Append full ChatMessage entries from an agent loop turn (excluding system prompt). */\n addTurnMessages(messages: ChatMessage[], toolsUsed?: string[]): void {\n for (const msg of messages) {\n if (msg.role === \"system\") {\n continue;\n }\n this.history.push(msg);\n }\n this.toolsUsed = toolsUsed ?? [];\n this.updatedAt = new Date();\n }\n\n /** Get the full rich history for replaying into the LLM. */\n getHistory(maxMessages = 200): ChatMessage[] {\n if (this.history.length <= maxMessages) {\n return this.history;\n }\n let start = this.history.length - maxMessages;\n while (start < this.history.length && this.history[start].role !== \"user\") {\n start += 1;\n }\n return this.history.slice(start);\n }\n\n /** Trim history to keep only the last N messages. */\n trimHistory(keepCount: number): void {\n if (this.history.length > keepCount) {\n this.history = this.history.slice(-keepCount);\n }\n }\n\n /** Clear all messages. */\n clear(): void {\n this.history = [];\n this.updatedAt = new Date();\n }\n}\n\n/** Manages conversation sessions stored as JSONL files. */\nexport class SessionManager {\n private sessionsDir: string;\n private cache = new Map<string, Session>();\n\n constructor(_workspace: string) {\n this.sessionsDir = ensureDir(join(homedir(), \".nanobot\", \"sessions\"));\n }\n\n private getSessionPath(key: string): string {\n const safeKey = safeFilename(key.replaceAll(\":\", \"_\"));\n return join(this.sessionsDir, `${safeKey}.jsonl`);\n }\n\n /** Get an existing session or create a new one. */\n getOrCreate(key: string): Session {\n const cached = this.cache.get(key);\n if (cached) {\n return cached;\n }\n\n const loaded = this.load(key);\n if (loaded) {\n this.cache.set(key, loaded);\n return loaded;\n }\n\n const session = new Session({ key });\n this.cache.set(key, session);\n return session;\n }\n\n private load(key: string): Session | null {\n const path = this.getSessionPath(key);\n if (!existsSync(path)) {\n return null;\n }\n\n try {\n const raw = readFileSync(path, \"utf8\");\n const lines = raw.split(\"\\n\").filter((l) => l.trim());\n const history: ChatMessage[] = [];\n let metadata: Record<string, unknown> = {};\n let createdAt: Date | undefined;\n let isRichFormat = false;\n\n for (const line of lines) {\n const data = JSON.parse(line);\n if (data._type === \"metadata\") {\n metadata = data.metadata ?? {};\n createdAt = data.created_at ? new Date(data.created_at) : undefined;\n isRichFormat = data._format === \"rich\";\n } else if (isRichFormat) {\n // Rich format: data is a full ChatMessage\n history.push(data as ChatMessage);\n } else {\n // Legacy format: simple {role, content, timestamp} entries.\n // Convert to ChatMessage, skipping the timestamp field.\n history.push({\n content: data.content ?? \"\",\n role: data.role as ChatMessage[\"role\"],\n });\n }\n }\n\n return new Session({\n createdAt: createdAt ?? new Date(),\n history,\n key,\n metadata,\n });\n } catch (error) {\n console.warn(`Failed to load session ${key}:`, error);\n return null;\n }\n }\n\n /** Save a session to disk. */\n save(session: Session): void {\n const path = this.getSessionPath(session.key);\n const lines: string[] = [\n JSON.stringify({\n _format: \"rich\",\n _type: \"metadata\",\n created_at: session.createdAt.toISOString(),\n metadata: session.metadata,\n updated_at: session.updatedAt.toISOString(),\n }),\n ];\n\n // Message lines — full ChatMessage objects\n for (const msg of session.history) {\n lines.push(JSON.stringify(msg));\n }\n\n writeFileSync(path, lines.join(\"\\n\") + \"\\n\");\n this.cache.set(session.key, session);\n }\n\n /** Delete a session. */\n delete(key: string): boolean {\n this.cache.delete(key);\n const path = this.getSessionPath(key);\n if (existsSync(path)) {\n unlinkSync(path);\n return true;\n }\n return false;\n }\n\n /** List all sessions. */\n listSessions(): {\n key: string;\n createdAt?: string;\n updatedAt?: string;\n path: string;\n }[] {\n const results: {\n key: string;\n createdAt?: string;\n updatedAt?: string;\n path: string;\n }[] = [];\n\n if (!existsSync(this.sessionsDir)) {\n return results;\n }\n\n for (const file of readdirSync(this.sessionsDir)) {\n if (!file.endsWith(\".jsonl\")) {\n continue;\n }\n const filePath = join(this.sessionsDir, file);\n try {\n const raw = readFileSync(filePath, \"utf8\");\n const firstLine = raw.split(\"\\n\")[0]?.trim();\n if (firstLine) {\n const data = JSON.parse(firstLine);\n if (data._type === \"metadata\") {\n results.push({\n createdAt: data.created_at,\n key: file.replace(\".jsonl\", \"\").replaceAll(\"_\", \":\"),\n path: filePath,\n updatedAt: data.updated_at,\n });\n }\n }\n } catch {\n // skip invalid files\n }\n }\n\n return results.sort((a, b) =>\n (b.updatedAt ?? \"\").localeCompare(a.updatedAt ?? \"\")\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.mts","names":[],"sources":["../../src/utils/helpers.ts"],"mappings":";;iBAKgB,SAAA,CAAU,OAAA;;iBAQV,WAAA,CAAA;;iBAKA,gBAAA,CAAiB,SAAA;AALjC;AAAA,iBAagB,eAAA,CAAA;;iBAKA,aAAA,CAAc,SAAA;;iBAMd,SAAA,CAAA;;iBAKA,cAAA,CACd,CAAA,UACA,MAAA,WACA,MAAA;;
|
|
1
|
+
{"version":3,"file":"helpers.d.mts","names":[],"sources":["../../src/utils/helpers.ts"],"mappings":";;iBAKgB,SAAA,CAAU,OAAA;;iBAQV,WAAA,CAAA;;iBAKA,gBAAA,CAAiB,SAAA;AALjC;AAAA,iBAagB,eAAA,CAAA;;iBAKA,aAAA,CAAc,SAAA;;iBAMd,SAAA,CAAA;;iBAKA,cAAA,CACd,CAAA,UACA,MAAA,WACA,MAAA;;iBASc,YAAA,CAAa,IAAA;AA5B7B;AAAA,iBAsCgB,eAAA,CAAgB,GAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.mjs","names":[],"sources":["../../src/utils/helpers.ts"],"sourcesContent":["import { mkdirSync, existsSync } from \"node:fs\";\nimport {
|
|
1
|
+
{"version":3,"file":"helpers.mjs","names":[],"sources":["../../src/utils/helpers.ts"],"sourcesContent":["import { mkdirSync, existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n/** Ensure a directory exists, creating it if necessary. */\nexport function ensureDir(dirPath: string): string {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n return dirPath;\n}\n\n/** Get the nanobot data directory (~/.nanobot). */\nexport function getDataPath(): string {\n return ensureDir(join(homedir(), \".nanobot\"));\n}\n\n/** Get the workspace path. Defaults to ~/.nanobot/workspace. */\nexport function getWorkspacePath(workspace?: string): string {\n const resolved = workspace\n ? workspace.replace(/^~/, homedir())\n : join(homedir(), \".nanobot\", \"workspace\");\n return ensureDir(resolved);\n}\n\n/** Get the sessions storage directory. */\nexport function getSessionsPath(): string {\n return ensureDir(join(getDataPath(), \"sessions\"));\n}\n\n/** Get the skills directory within the workspace. */\nexport function getSkillsPath(workspace?: string): string {\n const ws = workspace ?? getWorkspacePath();\n return ensureDir(join(ws, \"skills\"));\n}\n\n/** Get current timestamp in ISO format. */\nexport function timestamp(): string {\n return new Date().toISOString();\n}\n\n/** Truncate a string to max length, adding suffix if truncated. */\nexport function truncateString(\n s: string,\n maxLen = 100,\n suffix = \"...\"\n): string {\n if (s.length <= maxLen) {\n return s;\n }\n return s.slice(0, maxLen - suffix.length) + suffix;\n}\n\n/** Convert a string to a safe filename. */\nexport function safeFilename(name: string): string {\n const unsafe = '<>:\"/\\\\|?*';\n let result = name;\n for (const char of unsafe) {\n result = result.replaceAll(char, \"_\");\n }\n return result.trim();\n}\n\n/** Parse a session key into channel and chat_id. */\nexport function parseSessionKey(key: string): [string, string] {\n const idx = key.indexOf(\":\");\n if (idx === -1) {\n throw new Error(`Invalid session key: ${key}`);\n }\n return [key.slice(0, idx), key.slice(idx + 1)];\n}\n"],"mappings":";;;;;;AAKA,SAAgB,UAAU,SAAyB;AACjD,KAAI,CAAC,WAAW,QAAQ,CACtB,WAAU,SAAS,EAAE,WAAW,MAAM,CAAC;AAEzC,QAAO;;;AAIT,SAAgB,cAAsB;AACpC,QAAO,UAAU,KAAK,SAAS,EAAE,WAAW,CAAC;;;AAI/C,SAAgB,iBAAiB,WAA4B;AAI3D,QAAO,UAHU,YACb,UAAU,QAAQ,MAAM,SAAS,CAAC,GAClC,KAAK,SAAS,EAAE,YAAY,YAAY,CAClB;;;AAI5B,SAAgB,kBAA0B;AACxC,QAAO,UAAU,KAAK,aAAa,EAAE,WAAW,CAAC;;;AAInD,SAAgB,cAAc,WAA4B;AAExD,QAAO,UAAU,KADN,aAAa,kBAAkB,EAChB,SAAS,CAAC;;;AAItC,SAAgB,YAAoB;AAClC,yBAAO,IAAI,MAAM,EAAC,aAAa;;;AAIjC,SAAgB,eACd,GACA,SAAS,KACT,SAAS,OACD;AACR,KAAI,EAAE,UAAU,OACd,QAAO;AAET,QAAO,EAAE,MAAM,GAAG,SAAS,OAAO,OAAO,GAAG;;;AAI9C,SAAgB,aAAa,MAAsB;CACjD,MAAM,SAAS;CACf,IAAI,SAAS;AACb,MAAK,MAAM,QAAQ,OACjB,UAAS,OAAO,WAAW,MAAM,IAAI;AAEvC,QAAO,OAAO,MAAM;;;AAItB,SAAgB,gBAAgB,KAA+B;CAC7D,MAAM,MAAM,IAAI,QAAQ,IAAI;AAC5B,KAAI,QAAQ,GACV,OAAM,IAAI,MAAM,wBAAwB,MAAM;AAEhD,QAAO,CAAC,IAAI,MAAM,GAAG,IAAI,EAAE,IAAI,MAAM,MAAM,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jcheesepkg/nanobot",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Lightweight AI assistant - TypeScript port",
|
|
5
|
-
"
|
|
6
|
-
"main": "dist/index.mjs",
|
|
7
|
-
"types": "dist/index.d.mts",
|
|
5
|
+
"license": "MIT",
|
|
8
6
|
"bin": {
|
|
9
7
|
"nanobot": "dist/cli/index.mjs"
|
|
10
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"skills",
|
|
12
|
+
"workspace"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "dist/index.mjs",
|
|
16
|
+
"types": "dist/index.d.mts",
|
|
11
17
|
"exports": {
|
|
12
18
|
".": {
|
|
13
19
|
"types": "./dist/index.d.mts",
|
|
@@ -40,11 +46,5 @@
|
|
|
40
46
|
},
|
|
41
47
|
"engines": {
|
|
42
48
|
"node": ">=18.0.0"
|
|
43
|
-
}
|
|
44
|
-
"files": [
|
|
45
|
-
"dist",
|
|
46
|
-
"skills",
|
|
47
|
-
"workspace"
|
|
48
|
-
],
|
|
49
|
-
"license": "MIT"
|
|
49
|
+
}
|
|
50
50
|
}
|