@compass-ai/nova 1.0.74 → 1.0.76
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/dist/cli.js +557 -555
- package/dist/index.js +10 -8
- package/package.json +1 -1
- package/dist/acp/agent.d.ts +0 -318
- package/dist/acp/agent.d.ts.map +0 -1
- package/dist/acp/agent.js +0 -795
- package/dist/acp/agent.js.map +0 -1
- package/dist/acp/backpressure-writer.d.ts +0 -49
- package/dist/acp/backpressure-writer.d.ts.map +0 -1
- package/dist/acp/backpressure-writer.js +0 -153
- package/dist/acp/backpressure-writer.js.map +0 -1
- package/dist/acp/event-adapter.d.ts +0 -242
- package/dist/acp/event-adapter.d.ts.map +0 -1
- package/dist/acp/event-adapter.js +0 -456
- package/dist/acp/event-adapter.js.map +0 -1
- package/dist/acp/index.d.ts +0 -30
- package/dist/acp/index.d.ts.map +0 -1
- package/dist/acp/index.js +0 -36
- package/dist/acp/index.js.map +0 -1
- package/dist/acp/modes.d.ts +0 -56
- package/dist/acp/modes.d.ts.map +0 -1
- package/dist/acp/modes.js +0 -135
- package/dist/acp/modes.js.map +0 -1
- package/dist/acp/session-manager.d.ts +0 -170
- package/dist/acp/session-manager.d.ts.map +0 -1
- package/dist/acp/session-manager.js +0 -381
- package/dist/acp/session-manager.js.map +0 -1
- package/dist/acp/text-coalescer.d.ts +0 -45
- package/dist/acp/text-coalescer.d.ts.map +0 -1
- package/dist/acp/text-coalescer.js +0 -110
- package/dist/acp/text-coalescer.js.map +0 -1
- package/dist/acp/tool-bridge.d.ts +0 -156
- package/dist/acp/tool-bridge.d.ts.map +0 -1
- package/dist/acp/tool-bridge.js +0 -381
- package/dist/acp/tool-bridge.js.map +0 -1
- package/dist/acp/types.d.ts +0 -314
- package/dist/acp/types.d.ts.map +0 -1
- package/dist/acp/types.js +0 -8
- package/dist/acp/types.js.map +0 -1
- package/dist/cli.d.ts +0 -9
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/acp.d.ts +0 -26
- package/dist/commands/acp.d.ts.map +0 -1
- package/dist/commands/acp.js +0 -492
- package/dist/commands/acp.js.map +0 -1
- package/dist/commands/cache.d.ts +0 -33
- package/dist/commands/cache.d.ts.map +0 -1
- package/dist/commands/cache.js +0 -537
- package/dist/commands/cache.js.map +0 -1
- package/dist/commands/config.d.ts +0 -10
- package/dist/commands/config.d.ts.map +0 -1
- package/dist/commands/config.js +0 -367
- package/dist/commands/config.js.map +0 -1
- package/dist/commands/consent.d.ts +0 -21
- package/dist/commands/consent.d.ts.map +0 -1
- package/dist/commands/consent.js +0 -334
- package/dist/commands/consent.js.map +0 -1
- package/dist/commands/data.d.ts +0 -24
- package/dist/commands/data.d.ts.map +0 -1
- package/dist/commands/data.js +0 -586
- package/dist/commands/data.js.map +0 -1
- package/dist/commands/index.d.ts +0 -145
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js +0 -210
- package/dist/commands/index.js.map +0 -1
- package/dist/commands/init.d.ts +0 -106
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -349
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/logs.d.ts +0 -13
- package/dist/commands/logs.d.ts.map +0 -1
- package/dist/commands/logs.js +0 -359
- package/dist/commands/logs.js.map +0 -1
- package/dist/commands/mcp.d.ts +0 -20
- package/dist/commands/mcp.d.ts.map +0 -1
- package/dist/commands/mcp.js +0 -687
- package/dist/commands/mcp.js.map +0 -1
- package/dist/commands/reset.d.ts +0 -20
- package/dist/commands/reset.d.ts.map +0 -1
- package/dist/commands/reset.js +0 -372
- package/dist/commands/reset.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -74
- package/dist/commands/setup.d.ts.map +0 -1
- package/dist/commands/setup.js +0 -863
- package/dist/commands/setup.js.map +0 -1
- package/dist/commands/slash/agents.d.ts +0 -40
- package/dist/commands/slash/agents.d.ts.map +0 -1
- package/dist/commands/slash/agents.js +0 -519
- package/dist/commands/slash/agents.js.map +0 -1
- package/dist/commands/slash/approve.d.ts +0 -46
- package/dist/commands/slash/approve.d.ts.map +0 -1
- package/dist/commands/slash/approve.js +0 -239
- package/dist/commands/slash/approve.js.map +0 -1
- package/dist/commands/slash/attach.d.ts +0 -70
- package/dist/commands/slash/attach.d.ts.map +0 -1
- package/dist/commands/slash/attach.js +0 -333
- package/dist/commands/slash/attach.js.map +0 -1
- package/dist/commands/slash/clear.d.ts +0 -47
- package/dist/commands/slash/clear.d.ts.map +0 -1
- package/dist/commands/slash/clear.js +0 -261
- package/dist/commands/slash/clear.js.map +0 -1
- package/dist/commands/slash/commit.d.ts +0 -40
- package/dist/commands/slash/commit.d.ts.map +0 -1
- package/dist/commands/slash/commit.js +0 -337
- package/dist/commands/slash/commit.js.map +0 -1
- package/dist/commands/slash/compact.d.ts +0 -48
- package/dist/commands/slash/compact.d.ts.map +0 -1
- package/dist/commands/slash/compact.js +0 -288
- package/dist/commands/slash/compact.js.map +0 -1
- package/dist/commands/slash/config.d.ts +0 -20
- package/dist/commands/slash/config.d.ts.map +0 -1
- package/dist/commands/slash/config.js +0 -136
- package/dist/commands/slash/config.js.map +0 -1
- package/dist/commands/slash/context.d.ts +0 -49
- package/dist/commands/slash/context.d.ts.map +0 -1
- package/dist/commands/slash/context.js +0 -430
- package/dist/commands/slash/context.js.map +0 -1
- package/dist/commands/slash/cost.d.ts +0 -34
- package/dist/commands/slash/cost.d.ts.map +0 -1
- package/dist/commands/slash/cost.js +0 -312
- package/dist/commands/slash/cost.js.map +0 -1
- package/dist/commands/slash/custom.d.ts +0 -41
- package/dist/commands/slash/custom.d.ts.map +0 -1
- package/dist/commands/slash/custom.js +0 -126
- package/dist/commands/slash/custom.js.map +0 -1
- package/dist/commands/slash/exit.d.ts +0 -25
- package/dist/commands/slash/exit.d.ts.map +0 -1
- package/dist/commands/slash/exit.js +0 -186
- package/dist/commands/slash/exit.js.map +0 -1
- package/dist/commands/slash/export.d.ts +0 -27
- package/dist/commands/slash/export.d.ts.map +0 -1
- package/dist/commands/slash/export.js +0 -318
- package/dist/commands/slash/export.js.map +0 -1
- package/dist/commands/slash/files.d.ts +0 -47
- package/dist/commands/slash/files.d.ts.map +0 -1
- package/dist/commands/slash/files.js +0 -521
- package/dist/commands/slash/files.js.map +0 -1
- package/dist/commands/slash/help.d.ts +0 -50
- package/dist/commands/slash/help.d.ts.map +0 -1
- package/dist/commands/slash/help.js +0 -282
- package/dist/commands/slash/help.js.map +0 -1
- package/dist/commands/slash/index-cmd.d.ts +0 -41
- package/dist/commands/slash/index-cmd.d.ts.map +0 -1
- package/dist/commands/slash/index-cmd.js +0 -349
- package/dist/commands/slash/index-cmd.js.map +0 -1
- package/dist/commands/slash/index.d.ts +0 -97
- package/dist/commands/slash/index.d.ts.map +0 -1
- package/dist/commands/slash/index.js +0 -251
- package/dist/commands/slash/index.js.map +0 -1
- package/dist/commands/slash/login.d.ts +0 -23
- package/dist/commands/slash/login.d.ts.map +0 -1
- package/dist/commands/slash/login.js +0 -175
- package/dist/commands/slash/login.js.map +0 -1
- package/dist/commands/slash/logout.d.ts +0 -23
- package/dist/commands/slash/logout.d.ts.map +0 -1
- package/dist/commands/slash/logout.js +0 -153
- package/dist/commands/slash/logout.js.map +0 -1
- package/dist/commands/slash/logs.d.ts +0 -29
- package/dist/commands/slash/logs.d.ts.map +0 -1
- package/dist/commands/slash/logs.js +0 -423
- package/dist/commands/slash/logs.js.map +0 -1
- package/dist/commands/slash/mcp.d.ts +0 -29
- package/dist/commands/slash/mcp.d.ts.map +0 -1
- package/dist/commands/slash/mcp.js +0 -1026
- package/dist/commands/slash/mcp.js.map +0 -1
- package/dist/commands/slash/model.d.ts +0 -60
- package/dist/commands/slash/model.d.ts.map +0 -1
- package/dist/commands/slash/model.js +0 -466
- package/dist/commands/slash/model.js.map +0 -1
- package/dist/commands/slash/personality.d.ts +0 -40
- package/dist/commands/slash/personality.d.ts.map +0 -1
- package/dist/commands/slash/personality.js +0 -272
- package/dist/commands/slash/personality.js.map +0 -1
- package/dist/commands/slash/purge.d.ts +0 -42
- package/dist/commands/slash/purge.d.ts.map +0 -1
- package/dist/commands/slash/purge.js +0 -233
- package/dist/commands/slash/purge.js.map +0 -1
- package/dist/commands/slash/reset.d.ts +0 -44
- package/dist/commands/slash/reset.d.ts.map +0 -1
- package/dist/commands/slash/reset.js +0 -326
- package/dist/commands/slash/reset.js.map +0 -1
- package/dist/commands/slash/skills.d.ts +0 -40
- package/dist/commands/slash/skills.d.ts.map +0 -1
- package/dist/commands/slash/skills.js +0 -207
- package/dist/commands/slash/skills.js.map +0 -1
- package/dist/commands/slash/tokens.d.ts +0 -34
- package/dist/commands/slash/tokens.d.ts.map +0 -1
- package/dist/commands/slash/tokens.js +0 -205
- package/dist/commands/slash/tokens.js.map +0 -1
- package/dist/commands/slash/unleash.d.ts +0 -50
- package/dist/commands/slash/unleash.d.ts.map +0 -1
- package/dist/commands/slash/unleash.js +0 -262
- package/dist/commands/slash/unleash.js.map +0 -1
- package/dist/commands/slash/update.d.ts +0 -34
- package/dist/commands/slash/update.d.ts.map +0 -1
- package/dist/commands/slash/update.js +0 -364
- package/dist/commands/slash/update.js.map +0 -1
- package/dist/commands/slash/wrap.d.ts +0 -18
- package/dist/commands/slash/wrap.d.ts.map +0 -1
- package/dist/commands/slash/wrap.js +0 -21
- package/dist/commands/slash/wrap.js.map +0 -1
- package/dist/commands/tokens.d.ts +0 -26
- package/dist/commands/tokens.d.ts.map +0 -1
- package/dist/commands/tokens.js +0 -245
- package/dist/commands/tokens.js.map +0 -1
- package/dist/constants/builtin-agents.d.ts +0 -27
- package/dist/constants/builtin-agents.d.ts.map +0 -1
- package/dist/constants/builtin-agents.js +0 -710
- package/dist/constants/builtin-agents.js.map +0 -1
- package/dist/constants/builtin-skills.d.ts +0 -32
- package/dist/constants/builtin-skills.d.ts.map +0 -1
- package/dist/constants/builtin-skills.js +0 -389
- package/dist/constants/builtin-skills.js.map +0 -1
- package/dist/constants/defaults.d.ts +0 -448
- package/dist/constants/defaults.d.ts.map +0 -1
- package/dist/constants/defaults.js +0 -829
- package/dist/constants/defaults.js.map +0 -1
- package/dist/constants/index.d.ts +0 -27
- package/dist/constants/index.d.ts.map +0 -1
- package/dist/constants/index.js +0 -85
- package/dist/constants/index.js.map +0 -1
- package/dist/constants/install-hints.d.ts +0 -7
- package/dist/constants/install-hints.d.ts.map +0 -1
- package/dist/constants/install-hints.js +0 -123
- package/dist/constants/install-hints.js.map +0 -1
- package/dist/constants/models.d.ts +0 -255
- package/dist/constants/models.d.ts.map +0 -1
- package/dist/constants/models.js +0 -596
- package/dist/constants/models.js.map +0 -1
- package/dist/constants/schedule.d.ts +0 -43
- package/dist/constants/schedule.d.ts.map +0 -1
- package/dist/constants/schedule.js +0 -110
- package/dist/constants/schedule.js.map +0 -1
- package/dist/constants/system-utilities.d.ts +0 -57
- package/dist/constants/system-utilities.d.ts.map +0 -1
- package/dist/constants/system-utilities.js +0 -421
- package/dist/constants/system-utilities.js.map +0 -1
- package/dist/constants/token-limits.d.ts +0 -102
- package/dist/constants/token-limits.d.ts.map +0 -1
- package/dist/constants/token-limits.js +0 -286
- package/dist/constants/token-limits.js.map +0 -1
- package/dist/core/autocomplete.d.ts +0 -132
- package/dist/core/autocomplete.d.ts.map +0 -1
- package/dist/core/autocomplete.js +0 -653
- package/dist/core/autocomplete.js.map +0 -1
- package/dist/core/command-parser.d.ts +0 -301
- package/dist/core/command-parser.d.ts.map +0 -1
- package/dist/core/command-parser.js +0 -526
- package/dist/core/command-parser.js.map +0 -1
- package/dist/core/context-builder.d.ts +0 -264
- package/dist/core/context-builder.d.ts.map +0 -1
- package/dist/core/context-builder.js +0 -1018
- package/dist/core/context-builder.js.map +0 -1
- package/dist/core/event-emitter.d.ts +0 -411
- package/dist/core/event-emitter.d.ts.map +0 -1
- package/dist/core/event-emitter.js +0 -138
- package/dist/core/event-emitter.js.map +0 -1
- package/dist/core/history-manager.d.ts +0 -62
- package/dist/core/history-manager.d.ts.map +0 -1
- package/dist/core/history-manager.js +0 -151
- package/dist/core/history-manager.js.map +0 -1
- package/dist/core/slash-command-handler.d.ts +0 -352
- package/dist/core/slash-command-handler.d.ts.map +0 -1
- package/dist/core/slash-command-handler.js +0 -563
- package/dist/core/slash-command-handler.js.map +0 -1
- package/dist/core/task-processor.d.ts +0 -179
- package/dist/core/task-processor.d.ts.map +0 -1
- package/dist/core/task-processor.js +0 -519
- package/dist/core/task-processor.js.map +0 -1
- package/dist/index.d.ts +0 -90
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/prompts/agent-prompt-generator.d.ts +0 -26
- package/dist/prompts/agent-prompt-generator.d.ts.map +0 -1
- package/dist/prompts/agent-prompt-generator.js +0 -244
- package/dist/prompts/agent-prompt-generator.js.map +0 -1
- package/dist/prompts/commit-message.d.ts +0 -35
- package/dist/prompts/commit-message.d.ts.map +0 -1
- package/dist/prompts/commit-message.js +0 -187
- package/dist/prompts/commit-message.js.map +0 -1
- package/dist/prompts/conversation.d.ts +0 -51
- package/dist/prompts/conversation.d.ts.map +0 -1
- package/dist/prompts/conversation.js +0 -115
- package/dist/prompts/conversation.js.map +0 -1
- package/dist/prompts/index.d.ts +0 -39
- package/dist/prompts/index.d.ts.map +0 -1
- package/dist/prompts/index.js +0 -74
- package/dist/prompts/index.js.map +0 -1
- package/dist/prompts/memory.d.ts +0 -6
- package/dist/prompts/memory.d.ts.map +0 -1
- package/dist/prompts/memory.js +0 -29
- package/dist/prompts/memory.js.map +0 -1
- package/dist/prompts/personality.d.ts +0 -77
- package/dist/prompts/personality.d.ts.map +0 -1
- package/dist/prompts/personality.js +0 -393
- package/dist/prompts/personality.js.map +0 -1
- package/dist/prompts/plan-generator.d.ts +0 -144
- package/dist/prompts/plan-generator.d.ts.map +0 -1
- package/dist/prompts/plan-generator.js +0 -553
- package/dist/prompts/plan-generator.js.map +0 -1
- package/dist/prompts/system.d.ts +0 -95
- package/dist/prompts/system.d.ts.map +0 -1
- package/dist/prompts/system.js +0 -461
- package/dist/prompts/system.js.map +0 -1
- package/dist/prompts/task-processor.d.ts +0 -94
- package/dist/prompts/task-processor.d.ts.map +0 -1
- package/dist/prompts/task-processor.js +0 -554
- package/dist/prompts/task-processor.js.map +0 -1
- package/dist/prompts/unguarded.d.ts +0 -78
- package/dist/prompts/unguarded.d.ts.map +0 -1
- package/dist/prompts/unguarded.js +0 -418
- package/dist/prompts/unguarded.js.map +0 -1
- package/dist/prompts/utils.d.ts +0 -73
- package/dist/prompts/utils.d.ts.map +0 -1
- package/dist/prompts/utils.js +0 -114
- package/dist/prompts/utils.js.map +0 -1
- package/dist/prompts/workflow.d.ts +0 -241
- package/dist/prompts/workflow.d.ts.map +0 -1
- package/dist/prompts/workflow.js +0 -608
- package/dist/prompts/workflow.js.map +0 -1
- package/dist/services/action-logger.d.ts +0 -383
- package/dist/services/action-logger.d.ts.map +0 -1
- package/dist/services/action-logger.js +0 -544
- package/dist/services/action-logger.js.map +0 -1
- package/dist/services/agent-budget-allocator.d.ts +0 -111
- package/dist/services/agent-budget-allocator.d.ts.map +0 -1
- package/dist/services/agent-budget-allocator.js +0 -278
- package/dist/services/agent-budget-allocator.js.map +0 -1
- package/dist/services/agent-manager.d.ts +0 -181
- package/dist/services/agent-manager.d.ts.map +0 -1
- package/dist/services/agent-manager.js +0 -749
- package/dist/services/agent-manager.js.map +0 -1
- package/dist/services/agent-spawner.d.ts +0 -138
- package/dist/services/agent-spawner.d.ts.map +0 -1
- package/dist/services/agent-spawner.js +0 -748
- package/dist/services/agent-spawner.js.map +0 -1
- package/dist/services/agent-state-service.d.ts +0 -145
- package/dist/services/agent-state-service.d.ts.map +0 -1
- package/dist/services/agent-state-service.js +0 -247
- package/dist/services/agent-state-service.js.map +0 -1
- package/dist/services/anthropic-client.d.ts +0 -357
- package/dist/services/anthropic-client.d.ts.map +0 -1
- package/dist/services/anthropic-client.js +0 -1451
- package/dist/services/anthropic-client.js.map +0 -1
- package/dist/services/approval-manager.d.ts +0 -385
- package/dist/services/approval-manager.d.ts.map +0 -1
- package/dist/services/approval-manager.js +0 -1044
- package/dist/services/approval-manager.js.map +0 -1
- package/dist/services/audit-logger.d.ts +0 -245
- package/dist/services/audit-logger.d.ts.map +0 -1
- package/dist/services/audit-logger.js +0 -324
- package/dist/services/audit-logger.js.map +0 -1
- package/dist/services/backup-manager.d.ts +0 -136
- package/dist/services/backup-manager.d.ts.map +0 -1
- package/dist/services/backup-manager.js +0 -260
- package/dist/services/backup-manager.js.map +0 -1
- package/dist/services/cache-service.d.ts +0 -247
- package/dist/services/cache-service.d.ts.map +0 -1
- package/dist/services/cache-service.js +0 -558
- package/dist/services/cache-service.js.map +0 -1
- package/dist/services/chat-archival-service.d.ts +0 -108
- package/dist/services/chat-archival-service.d.ts.map +0 -1
- package/dist/services/chat-archival-service.js +0 -465
- package/dist/services/chat-archival-service.js.map +0 -1
- package/dist/services/codebase-indexer.d.ts +0 -272
- package/dist/services/codebase-indexer.d.ts.map +0 -1
- package/dist/services/codebase-indexer.js +0 -863
- package/dist/services/codebase-indexer.js.map +0 -1
- package/dist/services/compass-auth-service.d.ts +0 -204
- package/dist/services/compass-auth-service.d.ts.map +0 -1
- package/dist/services/compass-auth-service.js +0 -391
- package/dist/services/compass-auth-service.js.map +0 -1
- package/dist/services/complexity-classifier.d.ts +0 -208
- package/dist/services/complexity-classifier.d.ts.map +0 -1
- package/dist/services/complexity-classifier.js +0 -1410
- package/dist/services/complexity-classifier.js.map +0 -1
- package/dist/services/config-manager.d.ts +0 -278
- package/dist/services/config-manager.d.ts.map +0 -1
- package/dist/services/config-manager.js +0 -651
- package/dist/services/config-manager.js.map +0 -1
- package/dist/services/consent-manager.d.ts +0 -239
- package/dist/services/consent-manager.d.ts.map +0 -1
- package/dist/services/consent-manager.js +0 -516
- package/dist/services/consent-manager.js.map +0 -1
- package/dist/services/conversation-compactor.d.ts +0 -223
- package/dist/services/conversation-compactor.d.ts.map +0 -1
- package/dist/services/conversation-compactor.js +0 -750
- package/dist/services/conversation-compactor.js.map +0 -1
- package/dist/services/cost-tracker.d.ts +0 -167
- package/dist/services/cost-tracker.d.ts.map +0 -1
- package/dist/services/cost-tracker.js +0 -199
- package/dist/services/cost-tracker.js.map +0 -1
- package/dist/services/credential-store.d.ts +0 -273
- package/dist/services/credential-store.d.ts.map +0 -1
- package/dist/services/credential-store.js +0 -877
- package/dist/services/credential-store.js.map +0 -1
- package/dist/services/custom-command-service.d.ts +0 -112
- package/dist/services/custom-command-service.d.ts.map +0 -1
- package/dist/services/custom-command-service.js +0 -464
- package/dist/services/custom-command-service.js.map +0 -1
- package/dist/services/default-statusline-renderer.d.ts +0 -60
- package/dist/services/default-statusline-renderer.d.ts.map +0 -1
- package/dist/services/default-statusline-renderer.js +0 -110
- package/dist/services/default-statusline-renderer.js.map +0 -1
- package/dist/services/enhanced-context-gatherer.d.ts +0 -116
- package/dist/services/enhanced-context-gatherer.d.ts.map +0 -1
- package/dist/services/enhanced-context-gatherer.js +0 -605
- package/dist/services/enhanced-context-gatherer.js.map +0 -1
- package/dist/services/file-hash-tracker.d.ts +0 -95
- package/dist/services/file-hash-tracker.d.ts.map +0 -1
- package/dist/services/file-hash-tracker.js +0 -199
- package/dist/services/file-hash-tracker.js.map +0 -1
- package/dist/services/file-service.d.ts +0 -274
- package/dist/services/file-service.d.ts.map +0 -1
- package/dist/services/file-service.js +0 -876
- package/dist/services/file-service.js.map +0 -1
- package/dist/services/git-service.d.ts +0 -536
- package/dist/services/git-service.d.ts.map +0 -1
- package/dist/services/git-service.js +0 -1215
- package/dist/services/git-service.js.map +0 -1
- package/dist/services/hook-service.d.ts +0 -148
- package/dist/services/hook-service.d.ts.map +0 -1
- package/dist/services/hook-service.js +0 -705
- package/dist/services/hook-service.js.map +0 -1
- package/dist/services/ide-state-service.d.ts +0 -114
- package/dist/services/ide-state-service.d.ts.map +0 -1
- package/dist/services/ide-state-service.js +0 -204
- package/dist/services/ide-state-service.js.map +0 -1
- package/dist/services/interactive-clarifier.d.ts +0 -90
- package/dist/services/interactive-clarifier.d.ts.map +0 -1
- package/dist/services/interactive-clarifier.js +0 -446
- package/dist/services/interactive-clarifier.js.map +0 -1
- package/dist/services/iteration-scoper.d.ts +0 -225
- package/dist/services/iteration-scoper.d.ts.map +0 -1
- package/dist/services/iteration-scoper.js +0 -387
- package/dist/services/iteration-scoper.js.map +0 -1
- package/dist/services/llm-plan-generator.d.ts +0 -44
- package/dist/services/llm-plan-generator.d.ts.map +0 -1
- package/dist/services/llm-plan-generator.js +0 -863
- package/dist/services/llm-plan-generator.js.map +0 -1
- package/dist/services/llm-system-prompt-generator.d.ts +0 -85
- package/dist/services/llm-system-prompt-generator.d.ts.map +0 -1
- package/dist/services/llm-system-prompt-generator.js +0 -257
- package/dist/services/llm-system-prompt-generator.js.map +0 -1
- package/dist/services/log-interpreter.d.ts +0 -190
- package/dist/services/log-interpreter.d.ts.map +0 -1
- package/dist/services/log-interpreter.js +0 -520
- package/dist/services/log-interpreter.js.map +0 -1
- package/dist/services/mcp-config-manager.d.ts +0 -141
- package/dist/services/mcp-config-manager.d.ts.map +0 -1
- package/dist/services/mcp-config-manager.js +0 -678
- package/dist/services/mcp-config-manager.js.map +0 -1
- package/dist/services/mcp-oauth-service.d.ts +0 -170
- package/dist/services/mcp-oauth-service.d.ts.map +0 -1
- package/dist/services/mcp-oauth-service.js +0 -892
- package/dist/services/mcp-oauth-service.js.map +0 -1
- package/dist/services/mcp-plugin-support.d.ts +0 -81
- package/dist/services/mcp-plugin-support.d.ts.map +0 -1
- package/dist/services/mcp-plugin-support.js +0 -305
- package/dist/services/mcp-plugin-support.js.map +0 -1
- package/dist/services/mcp-server-manager.d.ts +0 -134
- package/dist/services/mcp-server-manager.d.ts.map +0 -1
- package/dist/services/mcp-server-manager.js +0 -613
- package/dist/services/mcp-server-manager.js.map +0 -1
- package/dist/services/mcp-tool-integration.d.ts +0 -119
- package/dist/services/mcp-tool-integration.d.ts.map +0 -1
- package/dist/services/mcp-tool-integration.js +0 -381
- package/dist/services/mcp-tool-integration.js.map +0 -1
- package/dist/services/mcp-transport.d.ts +0 -105
- package/dist/services/mcp-transport.d.ts.map +0 -1
- package/dist/services/mcp-transport.js +0 -1316
- package/dist/services/mcp-transport.js.map +0 -1
- package/dist/services/memory-service.d.ts +0 -55
- package/dist/services/memory-service.d.ts.map +0 -1
- package/dist/services/memory-service.js +0 -251
- package/dist/services/memory-service.js.map +0 -1
- package/dist/services/model-availability.d.ts +0 -64
- package/dist/services/model-availability.d.ts.map +0 -1
- package/dist/services/model-availability.js +0 -114
- package/dist/services/model-availability.js.map +0 -1
- package/dist/services/plan-generator.d.ts +0 -98
- package/dist/services/plan-generator.d.ts.map +0 -1
- package/dist/services/plan-generator.js +0 -658
- package/dist/services/plan-generator.js.map +0 -1
- package/dist/services/plan-mode-fallback.d.ts +0 -80
- package/dist/services/plan-mode-fallback.d.ts.map +0 -1
- package/dist/services/plan-mode-fallback.js +0 -307
- package/dist/services/plan-mode-fallback.js.map +0 -1
- package/dist/services/plan-mode-handler.d.ts +0 -42
- package/dist/services/plan-mode-handler.d.ts.map +0 -1
- package/dist/services/plan-mode-handler.js +0 -388
- package/dist/services/plan-mode-handler.js.map +0 -1
- package/dist/services/plan-persistence.d.ts +0 -203
- package/dist/services/plan-persistence.d.ts.map +0 -1
- package/dist/services/plan-persistence.js +0 -538
- package/dist/services/plan-persistence.js.map +0 -1
- package/dist/services/prompt-preprocessor.d.ts +0 -73
- package/dist/services/prompt-preprocessor.d.ts.map +0 -1
- package/dist/services/prompt-preprocessor.js +0 -146
- package/dist/services/prompt-preprocessor.js.map +0 -1
- package/dist/services/rating-service.d.ts +0 -84
- package/dist/services/rating-service.d.ts.map +0 -1
- package/dist/services/rating-service.js +0 -171
- package/dist/services/rating-service.js.map +0 -1
- package/dist/services/rating-state-manager.d.ts +0 -131
- package/dist/services/rating-state-manager.d.ts.map +0 -1
- package/dist/services/rating-state-manager.js +0 -270
- package/dist/services/rating-state-manager.js.map +0 -1
- package/dist/services/sdk-runner.d.ts +0 -113
- package/dist/services/sdk-runner.d.ts.map +0 -1
- package/dist/services/sdk-runner.js +0 -1424
- package/dist/services/sdk-runner.js.map +0 -1
- package/dist/services/session-manager.d.ts +0 -528
- package/dist/services/session-manager.d.ts.map +0 -1
- package/dist/services/session-manager.js +0 -1184
- package/dist/services/session-manager.js.map +0 -1
- package/dist/services/shell-executor.d.ts +0 -337
- package/dist/services/shell-executor.d.ts.map +0 -1
- package/dist/services/shell-executor.js +0 -1201
- package/dist/services/shell-executor.js.map +0 -1
- package/dist/services/skill-service.d.ts +0 -149
- package/dist/services/skill-service.d.ts.map +0 -1
- package/dist/services/skill-service.js +0 -594
- package/dist/services/skill-service.js.map +0 -1
- package/dist/services/statusline-executor.d.ts +0 -102
- package/dist/services/statusline-executor.d.ts.map +0 -1
- package/dist/services/statusline-executor.js +0 -305
- package/dist/services/statusline-executor.js.map +0 -1
- package/dist/services/step-tracker.d.ts +0 -356
- package/dist/services/step-tracker.d.ts.map +0 -1
- package/dist/services/step-tracker.js +0 -634
- package/dist/services/step-tracker.js.map +0 -1
- package/dist/services/system-event-logger.d.ts +0 -473
- package/dist/services/system-event-logger.d.ts.map +0 -1
- package/dist/services/system-event-logger.js +0 -790
- package/dist/services/system-event-logger.js.map +0 -1
- package/dist/services/system-utility-detector.d.ts +0 -91
- package/dist/services/system-utility-detector.d.ts.map +0 -1
- package/dist/services/system-utility-detector.js +0 -238
- package/dist/services/system-utility-detector.js.map +0 -1
- package/dist/services/team-context-store.d.ts +0 -100
- package/dist/services/team-context-store.d.ts.map +0 -1
- package/dist/services/team-context-store.js +0 -513
- package/dist/services/team-context-store.js.map +0 -1
- package/dist/services/temp-file-service.d.ts +0 -164
- package/dist/services/temp-file-service.d.ts.map +0 -1
- package/dist/services/temp-file-service.js +0 -303
- package/dist/services/temp-file-service.js.map +0 -1
- package/dist/services/token-limit-enforcer.d.ts +0 -53
- package/dist/services/token-limit-enforcer.d.ts.map +0 -1
- package/dist/services/token-limit-enforcer.js +0 -90
- package/dist/services/token-limit-enforcer.js.map +0 -1
- package/dist/services/token-limit-store.d.ts +0 -105
- package/dist/services/token-limit-store.d.ts.map +0 -1
- package/dist/services/token-limit-store.js +0 -288
- package/dist/services/token-limit-store.js.map +0 -1
- package/dist/services/token-tracker.d.ts +0 -290
- package/dist/services/token-tracker.d.ts.map +0 -1
- package/dist/services/token-tracker.js +0 -751
- package/dist/services/token-tracker.js.map +0 -1
- package/dist/services/tool-registry.d.ts +0 -302
- package/dist/services/tool-registry.d.ts.map +0 -1
- package/dist/services/tool-registry.js +0 -606
- package/dist/services/tool-registry.js.map +0 -1
- package/dist/services/tools-logger.d.ts +0 -152
- package/dist/services/tools-logger.d.ts.map +0 -1
- package/dist/services/tools-logger.js +0 -222
- package/dist/services/tools-logger.js.map +0 -1
- package/dist/services/update-plan-handler.d.ts +0 -56
- package/dist/services/update-plan-handler.d.ts.map +0 -1
- package/dist/services/update-plan-handler.js +0 -372
- package/dist/services/update-plan-handler.js.map +0 -1
- package/dist/services/update-service.d.ts +0 -197
- package/dist/services/update-service.d.ts.map +0 -1
- package/dist/services/update-service.js +0 -749
- package/dist/services/update-service.js.map +0 -1
- package/dist/services/verifier.d.ts +0 -113
- package/dist/services/verifier.d.ts.map +0 -1
- package/dist/services/verifier.js +0 -541
- package/dist/services/verifier.js.map +0 -1
- package/dist/services/workflow-manager.d.ts +0 -277
- package/dist/services/workflow-manager.d.ts.map +0 -1
- package/dist/services/workflow-manager.js +0 -616
- package/dist/services/workflow-manager.js.map +0 -1
- package/dist/services/workflow-orchestrator.d.ts +0 -148
- package/dist/services/workflow-orchestrator.d.ts.map +0 -1
- package/dist/services/workflow-orchestrator.js +0 -617
- package/dist/services/workflow-orchestrator.js.map +0 -1
- package/dist/services/worktree-manager.d.ts +0 -36
- package/dist/services/worktree-manager.d.ts.map +0 -1
- package/dist/services/worktree-manager.js +0 -185
- package/dist/services/worktree-manager.js.map +0 -1
- package/dist/templates/ascii-art.d.ts +0 -136
- package/dist/templates/ascii-art.d.ts.map +0 -1
- package/dist/templates/ascii-art.js +0 -286
- package/dist/templates/ascii-art.js.map +0 -1
- package/dist/templates/help.d.ts +0 -186
- package/dist/templates/help.d.ts.map +0 -1
- package/dist/templates/help.js +0 -588
- package/dist/templates/help.js.map +0 -1
- package/dist/templates/prompts/workflow-prompts.d.ts +0 -9
- package/dist/templates/prompts/workflow-prompts.d.ts.map +0 -1
- package/dist/templates/prompts/workflow-prompts.js +0 -9
- package/dist/templates/prompts/workflow-prompts.js.map +0 -1
- package/dist/tools/agent-tools.d.ts +0 -9
- package/dist/tools/agent-tools.d.ts.map +0 -1
- package/dist/tools/agent-tools.js +0 -349
- package/dist/tools/agent-tools.js.map +0 -1
- package/dist/tools/edit-replacers.d.ts +0 -90
- package/dist/tools/edit-replacers.d.ts.map +0 -1
- package/dist/tools/edit-replacers.js +0 -553
- package/dist/tools/edit-replacers.js.map +0 -1
- package/dist/tools/file-tools.d.ts +0 -13
- package/dist/tools/file-tools.d.ts.map +0 -1
- package/dist/tools/file-tools.js +0 -954
- package/dist/tools/file-tools.js.map +0 -1
- package/dist/tools/git-tools.d.ts +0 -9
- package/dist/tools/git-tools.d.ts.map +0 -1
- package/dist/tools/git-tools.js +0 -261
- package/dist/tools/git-tools.js.map +0 -1
- package/dist/tools/index.d.ts +0 -13
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -70
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/network-tools.d.ts +0 -8
- package/dist/tools/network-tools.d.ts.map +0 -1
- package/dist/tools/network-tools.js +0 -261
- package/dist/tools/network-tools.js.map +0 -1
- package/dist/tools/openai-tools.d.ts +0 -16
- package/dist/tools/openai-tools.d.ts.map +0 -1
- package/dist/tools/openai-tools.js +0 -385
- package/dist/tools/openai-tools.js.map +0 -1
- package/dist/tools/plan-tools.d.ts +0 -9
- package/dist/tools/plan-tools.d.ts.map +0 -1
- package/dist/tools/plan-tools.js +0 -223
- package/dist/tools/plan-tools.js.map +0 -1
- package/dist/tools/schedule-tools.d.ts +0 -9
- package/dist/tools/schedule-tools.d.ts.map +0 -1
- package/dist/tools/schedule-tools.js +0 -405
- package/dist/tools/schedule-tools.js.map +0 -1
- package/dist/tools/search-tools.d.ts +0 -8
- package/dist/tools/search-tools.d.ts.map +0 -1
- package/dist/tools/search-tools.js +0 -357
- package/dist/tools/search-tools.js.map +0 -1
- package/dist/tools/shared-utils.d.ts +0 -91
- package/dist/tools/shared-utils.d.ts.map +0 -1
- package/dist/tools/shared-utils.js +0 -385
- package/dist/tools/shared-utils.js.map +0 -1
- package/dist/tools/shell-tools.d.ts +0 -9
- package/dist/tools/shell-tools.d.ts.map +0 -1
- package/dist/tools/shell-tools.js +0 -409
- package/dist/tools/shell-tools.js.map +0 -1
- package/dist/tools/skill-tools.d.ts +0 -13
- package/dist/tools/skill-tools.d.ts.map +0 -1
- package/dist/tools/skill-tools.js +0 -244
- package/dist/tools/skill-tools.js.map +0 -1
- package/dist/tools/swarm-tools.d.ts +0 -9
- package/dist/tools/swarm-tools.d.ts.map +0 -1
- package/dist/tools/swarm-tools.js +0 -422
- package/dist/tools/swarm-tools.js.map +0 -1
- package/dist/tools/user-tools.d.ts +0 -13
- package/dist/tools/user-tools.d.ts.map +0 -1
- package/dist/tools/user-tools.js +0 -232
- package/dist/tools/user-tools.js.map +0 -1
- package/dist/types/agent-process.d.ts +0 -244
- package/dist/types/agent-process.d.ts.map +0 -1
- package/dist/types/agent-process.js +0 -93
- package/dist/types/agent-process.js.map +0 -1
- package/dist/types/agent.d.ts +0 -358
- package/dist/types/agent.d.ts.map +0 -1
- package/dist/types/agent.js +0 -171
- package/dist/types/agent.js.map +0 -1
- package/dist/types/anthropic.d.ts +0 -438
- package/dist/types/anthropic.d.ts.map +0 -1
- package/dist/types/anthropic.js +0 -9
- package/dist/types/anthropic.js.map +0 -1
- package/dist/types/approval.d.ts +0 -332
- package/dist/types/approval.d.ts.map +0 -1
- package/dist/types/approval.js +0 -44
- package/dist/types/approval.js.map +0 -1
- package/dist/types/autocomplete.d.ts +0 -57
- package/dist/types/autocomplete.d.ts.map +0 -1
- package/dist/types/autocomplete.js +0 -7
- package/dist/types/autocomplete.js.map +0 -1
- package/dist/types/chat-archive.d.ts +0 -161
- package/dist/types/chat-archive.d.ts.map +0 -1
- package/dist/types/chat-archive.js +0 -36
- package/dist/types/chat-archive.js.map +0 -1
- package/dist/types/config.d.ts +0 -268
- package/dist/types/config.d.ts.map +0 -1
- package/dist/types/config.js +0 -188
- package/dist/types/config.js.map +0 -1
- package/dist/types/consent.d.ts +0 -191
- package/dist/types/consent.d.ts.map +0 -1
- package/dist/types/consent.js +0 -119
- package/dist/types/consent.js.map +0 -1
- package/dist/types/custom-command.d.ts +0 -139
- package/dist/types/custom-command.d.ts.map +0 -1
- package/dist/types/custom-command.js +0 -7
- package/dist/types/custom-command.js.map +0 -1
- package/dist/types/git.d.ts +0 -20
- package/dist/types/git.d.ts.map +0 -1
- package/dist/types/git.js +0 -2
- package/dist/types/git.js.map +0 -1
- package/dist/types/hook.d.ts +0 -342
- package/dist/types/hook.d.ts.map +0 -1
- package/dist/types/hook.js +0 -84
- package/dist/types/hook.js.map +0 -1
- package/dist/types/index.d.ts +0 -86
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -71
- package/dist/types/index.js.map +0 -1
- package/dist/types/mcp.d.ts +0 -456
- package/dist/types/mcp.d.ts.map +0 -1
- package/dist/types/mcp.js +0 -94
- package/dist/types/mcp.js.map +0 -1
- package/dist/types/rating.d.ts +0 -110
- package/dist/types/rating.d.ts.map +0 -1
- package/dist/types/rating.js +0 -53
- package/dist/types/rating.js.map +0 -1
- package/dist/types/schedule.d.ts +0 -91
- package/dist/types/schedule.d.ts.map +0 -1
- package/dist/types/schedule.js +0 -8
- package/dist/types/schedule.js.map +0 -1
- package/dist/types/session.d.ts +0 -361
- package/dist/types/session.d.ts.map +0 -1
- package/dist/types/session.js +0 -9
- package/dist/types/session.js.map +0 -1
- package/dist/types/skill.d.ts +0 -258
- package/dist/types/skill.d.ts.map +0 -1
- package/dist/types/skill.js +0 -79
- package/dist/types/skill.js.map +0 -1
- package/dist/types/statusline.d.ts +0 -212
- package/dist/types/statusline.d.ts.map +0 -1
- package/dist/types/statusline.js +0 -8
- package/dist/types/statusline.js.map +0 -1
- package/dist/types/stream.d.ts +0 -61
- package/dist/types/stream.d.ts.map +0 -1
- package/dist/types/stream.js +0 -17
- package/dist/types/stream.js.map +0 -1
- package/dist/types/swarm.d.ts +0 -132
- package/dist/types/swarm.d.ts.map +0 -1
- package/dist/types/swarm.js +0 -21
- package/dist/types/swarm.js.map +0 -1
- package/dist/types/token-limits.d.ts +0 -107
- package/dist/types/token-limits.d.ts.map +0 -1
- package/dist/types/token-limits.js +0 -57
- package/dist/types/token-limits.js.map +0 -1
- package/dist/types/token.d.ts +0 -329
- package/dist/types/token.d.ts.map +0 -1
- package/dist/types/token.js +0 -9
- package/dist/types/token.js.map +0 -1
- package/dist/types/update.d.ts +0 -189
- package/dist/types/update.d.ts.map +0 -1
- package/dist/types/update.js +0 -55
- package/dist/types/update.js.map +0 -1
- package/dist/types/workflow.d.ts +0 -396
- package/dist/types/workflow.d.ts.map +0 -1
- package/dist/types/workflow.js +0 -46
- package/dist/types/workflow.js.map +0 -1
- package/dist/ui/App.d.ts +0 -62
- package/dist/ui/App.d.ts.map +0 -1
- package/dist/ui/App.js +0 -511
- package/dist/ui/App.js.map +0 -1
- package/dist/ui/InteractiveSession.d.ts +0 -34
- package/dist/ui/InteractiveSession.d.ts.map +0 -1
- package/dist/ui/InteractiveSession.js +0 -3611
- package/dist/ui/InteractiveSession.js.map +0 -1
- package/dist/ui/MCPApprovalPrompt.d.ts +0 -27
- package/dist/ui/MCPApprovalPrompt.d.ts.map +0 -1
- package/dist/ui/MCPApprovalPrompt.js +0 -51
- package/dist/ui/MCPApprovalPrompt.js.map +0 -1
- package/dist/ui/SetupWizard.d.ts +0 -26
- package/dist/ui/SetupWizard.d.ts.map +0 -1
- package/dist/ui/SetupWizard.js +0 -396
- package/dist/ui/SetupWizard.js.map +0 -1
- package/dist/ui/components/AgentCreationWizard.d.ts +0 -36
- package/dist/ui/components/AgentCreationWizard.d.ts.map +0 -1
- package/dist/ui/components/AgentCreationWizard.js +0 -619
- package/dist/ui/components/AgentCreationWizard.js.map +0 -1
- package/dist/ui/components/AgentManager.d.ts +0 -41
- package/dist/ui/components/AgentManager.d.ts.map +0 -1
- package/dist/ui/components/AgentManager.js +0 -343
- package/dist/ui/components/AgentManager.js.map +0 -1
- package/dist/ui/components/ApprovalDialog.d.ts +0 -18
- package/dist/ui/components/ApprovalDialog.d.ts.map +0 -1
- package/dist/ui/components/ApprovalDialog.js +0 -439
- package/dist/ui/components/ApprovalDialog.js.map +0 -1
- package/dist/ui/components/AsciiArt.d.ts +0 -54
- package/dist/ui/components/AsciiArt.d.ts.map +0 -1
- package/dist/ui/components/AsciiArt.js +0 -89
- package/dist/ui/components/AsciiArt.js.map +0 -1
- package/dist/ui/components/ClarificationWizard.d.ts +0 -36
- package/dist/ui/components/ClarificationWizard.d.ts.map +0 -1
- package/dist/ui/components/ClarificationWizard.js +0 -407
- package/dist/ui/components/ClarificationWizard.js.map +0 -1
- package/dist/ui/components/CompassSpinner.d.ts +0 -15
- package/dist/ui/components/CompassSpinner.d.ts.map +0 -1
- package/dist/ui/components/CompassSpinner.js +0 -50
- package/dist/ui/components/CompassSpinner.js.map +0 -1
- package/dist/ui/components/ConfirmationSelector.d.ts +0 -45
- package/dist/ui/components/ConfirmationSelector.d.ts.map +0 -1
- package/dist/ui/components/ConfirmationSelector.js +0 -106
- package/dist/ui/components/ConfirmationSelector.js.map +0 -1
- package/dist/ui/components/ContextUsage.d.ts +0 -76
- package/dist/ui/components/ContextUsage.d.ts.map +0 -1
- package/dist/ui/components/ContextUsage.js +0 -188
- package/dist/ui/components/ContextUsage.js.map +0 -1
- package/dist/ui/components/DiffPreview.d.ts +0 -13
- package/dist/ui/components/DiffPreview.d.ts.map +0 -1
- package/dist/ui/components/DiffPreview.js +0 -30
- package/dist/ui/components/DiffPreview.js.map +0 -1
- package/dist/ui/components/ExecutionModeSelector.d.ts +0 -45
- package/dist/ui/components/ExecutionModeSelector.d.ts.map +0 -1
- package/dist/ui/components/ExecutionModeSelector.js +0 -120
- package/dist/ui/components/ExecutionModeSelector.js.map +0 -1
- package/dist/ui/components/FileTree.d.ts +0 -47
- package/dist/ui/components/FileTree.d.ts.map +0 -1
- package/dist/ui/components/FileTree.js +0 -258
- package/dist/ui/components/FileTree.js.map +0 -1
- package/dist/ui/components/HelpMenu.d.ts +0 -49
- package/dist/ui/components/HelpMenu.d.ts.map +0 -1
- package/dist/ui/components/HelpMenu.js +0 -91
- package/dist/ui/components/HelpMenu.js.map +0 -1
- package/dist/ui/components/InterleavedStream.d.ts +0 -42
- package/dist/ui/components/InterleavedStream.d.ts.map +0 -1
- package/dist/ui/components/InterleavedStream.js +0 -1500
- package/dist/ui/components/InterleavedStream.js.map +0 -1
- package/dist/ui/components/ModelSelector.d.ts +0 -81
- package/dist/ui/components/ModelSelector.d.ts.map +0 -1
- package/dist/ui/components/ModelSelector.js +0 -305
- package/dist/ui/components/ModelSelector.js.map +0 -1
- package/dist/ui/components/PlanApprovalDialog.d.ts +0 -21
- package/dist/ui/components/PlanApprovalDialog.d.ts.map +0 -1
- package/dist/ui/components/PlanApprovalDialog.js +0 -189
- package/dist/ui/components/PlanApprovalDialog.js.map +0 -1
- package/dist/ui/components/PlanExecutionTracker.d.ts +0 -53
- package/dist/ui/components/PlanExecutionTracker.d.ts.map +0 -1
- package/dist/ui/components/PlanExecutionTracker.js +0 -113
- package/dist/ui/components/PlanExecutionTracker.js.map +0 -1
- package/dist/ui/components/ProgressIndicator.d.ts +0 -151
- package/dist/ui/components/ProgressIndicator.d.ts.map +0 -1
- package/dist/ui/components/ProgressIndicator.js +0 -171
- package/dist/ui/components/ProgressIndicator.js.map +0 -1
- package/dist/ui/components/Prompt.d.ts +0 -47
- package/dist/ui/components/Prompt.d.ts.map +0 -1
- package/dist/ui/components/Prompt.js +0 -632
- package/dist/ui/components/Prompt.js.map +0 -1
- package/dist/ui/components/RatingPanel.d.ts +0 -45
- package/dist/ui/components/RatingPanel.d.ts.map +0 -1
- package/dist/ui/components/RatingPanel.js +0 -119
- package/dist/ui/components/RatingPanel.js.map +0 -1
- package/dist/ui/components/StatusLine.d.ts +0 -43
- package/dist/ui/components/StatusLine.d.ts.map +0 -1
- package/dist/ui/components/StatusLine.js +0 -44
- package/dist/ui/components/StatusLine.js.map +0 -1
- package/dist/ui/components/StreamingResponse.d.ts +0 -45
- package/dist/ui/components/StreamingResponse.d.ts.map +0 -1
- package/dist/ui/components/StreamingResponse.js +0 -56
- package/dist/ui/components/StreamingResponse.js.map +0 -1
- package/dist/ui/components/TokenUsage.d.ts +0 -89
- package/dist/ui/components/TokenUsage.d.ts.map +0 -1
- package/dist/ui/components/TokenUsage.js +0 -99
- package/dist/ui/components/TokenUsage.js.map +0 -1
- package/dist/ui/components/ToolSummary.d.ts +0 -77
- package/dist/ui/components/ToolSummary.d.ts.map +0 -1
- package/dist/ui/components/ToolSummary.js +0 -162
- package/dist/ui/components/ToolSummary.js.map +0 -1
- package/dist/ui/components/UpdateNotification.d.ts +0 -65
- package/dist/ui/components/UpdateNotification.d.ts.map +0 -1
- package/dist/ui/components/UpdateNotification.js +0 -166
- package/dist/ui/components/UpdateNotification.js.map +0 -1
- package/dist/ui/diff-renderer.d.ts +0 -18
- package/dist/ui/diff-renderer.d.ts.map +0 -1
- package/dist/ui/diff-renderer.js +0 -206
- package/dist/ui/diff-renderer.js.map +0 -1
- package/dist/ui/themes/markdown-theme.d.ts +0 -48
- package/dist/ui/themes/markdown-theme.d.ts.map +0 -1
- package/dist/ui/themes/markdown-theme.js +0 -79
- package/dist/ui/themes/markdown-theme.js.map +0 -1
- package/dist/ui/themes/ui-theme.d.ts +0 -301
- package/dist/ui/themes/ui-theme.d.ts.map +0 -1
- package/dist/ui/themes/ui-theme.js +0 -204
- package/dist/ui/themes/ui-theme.js.map +0 -1
- package/dist/utils/attachment-handler.d.ts +0 -129
- package/dist/utils/attachment-handler.d.ts.map +0 -1
- package/dist/utils/attachment-handler.js +0 -280
- package/dist/utils/attachment-handler.js.map +0 -1
- package/dist/utils/backup-cleanup.d.ts +0 -28
- package/dist/utils/backup-cleanup.d.ts.map +0 -1
- package/dist/utils/backup-cleanup.js +0 -99
- package/dist/utils/backup-cleanup.js.map +0 -1
- package/dist/utils/clipboard-handler.d.ts +0 -82
- package/dist/utils/clipboard-handler.d.ts.map +0 -1
- package/dist/utils/clipboard-handler.js +0 -311
- package/dist/utils/clipboard-handler.js.map +0 -1
- package/dist/utils/cloud-detection.d.ts +0 -14
- package/dist/utils/cloud-detection.d.ts.map +0 -1
- package/dist/utils/cloud-detection.js +0 -92
- package/dist/utils/cloud-detection.js.map +0 -1
- package/dist/utils/command-parser.d.ts +0 -56
- package/dist/utils/command-parser.d.ts.map +0 -1
- package/dist/utils/command-parser.js +0 -206
- package/dist/utils/command-parser.js.map +0 -1
- package/dist/utils/console-capture.d.ts +0 -30
- package/dist/utils/console-capture.d.ts.map +0 -1
- package/dist/utils/console-capture.js +0 -88
- package/dist/utils/console-capture.js.map +0 -1
- package/dist/utils/cron-parser.d.ts +0 -52
- package/dist/utils/cron-parser.d.ts.map +0 -1
- package/dist/utils/cron-parser.js +0 -455
- package/dist/utils/cron-parser.js.map +0 -1
- package/dist/utils/crypto.d.ts +0 -351
- package/dist/utils/crypto.d.ts.map +0 -1
- package/dist/utils/crypto.js +0 -615
- package/dist/utils/crypto.js.map +0 -1
- package/dist/utils/diff.d.ts +0 -311
- package/dist/utils/diff.d.ts.map +0 -1
- package/dist/utils/diff.js +0 -566
- package/dist/utils/diff.js.map +0 -1
- package/dist/utils/editor.d.ts +0 -12
- package/dist/utils/editor.d.ts.map +0 -1
- package/dist/utils/editor.js +0 -30
- package/dist/utils/editor.js.map +0 -1
- package/dist/utils/file-system.d.ts +0 -512
- package/dist/utils/file-system.d.ts.map +0 -1
- package/dist/utils/file-system.js +0 -798
- package/dist/utils/file-system.js.map +0 -1
- package/dist/utils/format.d.ts +0 -318
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/format.js +0 -587
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/ignore-patterns.d.ts +0 -93
- package/dist/utils/ignore-patterns.d.ts.map +0 -1
- package/dist/utils/ignore-patterns.js +0 -710
- package/dist/utils/ignore-patterns.js.map +0 -1
- package/dist/utils/log-cleanup.d.ts +0 -16
- package/dist/utils/log-cleanup.d.ts.map +0 -1
- package/dist/utils/log-cleanup.js +0 -51
- package/dist/utils/log-cleanup.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -305
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -447
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/path.d.ts +0 -406
- package/dist/utils/path.d.ts.map +0 -1
- package/dist/utils/path.js +0 -549
- package/dist/utils/path.js.map +0 -1
- package/dist/utils/schedule-file.d.ts +0 -63
- package/dist/utils/schedule-file.d.ts.map +0 -1
- package/dist/utils/schedule-file.js +0 -244
- package/dist/utils/schedule-file.js.map +0 -1
- package/dist/utils/task-id.d.ts +0 -29
- package/dist/utils/task-id.d.ts.map +0 -1
- package/dist/utils/task-id.js +0 -53
- package/dist/utils/task-id.js.map +0 -1
- package/dist/utils/temp-cleanup.d.ts +0 -46
- package/dist/utils/temp-cleanup.d.ts.map +0 -1
- package/dist/utils/temp-cleanup.js +0 -95
- package/dist/utils/temp-cleanup.js.map +0 -1
- package/dist/utils/terminal-output.d.ts +0 -34
- package/dist/utils/terminal-output.d.ts.map +0 -1
- package/dist/utils/terminal-output.js +0 -40
- package/dist/utils/terminal-output.js.map +0 -1
- package/dist/utils/token-counter.d.ts +0 -224
- package/dist/utils/token-counter.d.ts.map +0 -1
- package/dist/utils/token-counter.js +0 -332
- package/dist/utils/token-counter.js.map +0 -1
- package/dist/utils/tool-mapper.d.ts +0 -70
- package/dist/utils/tool-mapper.d.ts.map +0 -1
- package/dist/utils/tool-mapper.js +0 -234
- package/dist/utils/tool-mapper.js.map +0 -1
|
@@ -1,1451 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Anthropic API client service for Claude interactions
|
|
3
|
-
*
|
|
4
|
-
* This module provides a comprehensive client for interacting with Anthropic's Claude API,
|
|
5
|
-
* supporting streaming responses, model switching, token tracking, and retry logic with
|
|
6
|
-
* exponential backoff.
|
|
7
|
-
*/
|
|
8
|
-
import Anthropic, { AnthropicError } from '@anthropic-ai/sdk';
|
|
9
|
-
import { getCompassAuthService } from './compass-auth-service.js';
|
|
10
|
-
import { getModelConfig, CLAUDE_MODELS, resolveModelId } from '../constants/models.js';
|
|
11
|
-
import { DEFAULT_MODEL, DEFAULT_MAX_TOKENS, DEFAULT_ANTHROPIC_TEMPERATURE } from '../constants/defaults.js';
|
|
12
|
-
import { getCredentialStore } from './credential-store.js';
|
|
13
|
-
import { getTokenTracker } from './token-tracker.js';
|
|
14
|
-
import { getDisabledReason, getAvailableFallbackModel } from './model-availability.js';
|
|
15
|
-
import { getAuditLogger } from './audit-logger.js';
|
|
16
|
-
import { getCostTracker, calculateCost as calculateModelCost } from './cost-tracker.js';
|
|
17
|
-
import { logger } from '../utils/logger.js';
|
|
18
|
-
import { getEventEmitter } from '../core/event-emitter.js';
|
|
19
|
-
import { transformJSONSchema } from '@anthropic-ai/sdk/lib/transform-json-schema.js';
|
|
20
|
-
/**
|
|
21
|
-
* Formats system prompt for Anthropic's prompt caching feature.
|
|
22
|
-
* Caching can reduce costs by up to 90% and latency by 25% for cached content.
|
|
23
|
-
* Note: Minimum cacheable content is 1024 tokens for Claude 3.5 Sonnet and 2048 for other models.
|
|
24
|
-
*
|
|
25
|
-
* @param systemPrompt - The system prompt text
|
|
26
|
-
* @param enableCaching - Whether to enable caching (default: true)
|
|
27
|
-
* @returns Formatted system prompt with cache_control if enabled
|
|
28
|
-
*/
|
|
29
|
-
function formatSystemPromptForCaching(systemPrompt, enableCaching = true) {
|
|
30
|
-
if (!systemPrompt) {
|
|
31
|
-
return undefined;
|
|
32
|
-
}
|
|
33
|
-
// If caching disabled, return as plain string
|
|
34
|
-
if (!enableCaching) {
|
|
35
|
-
return systemPrompt;
|
|
36
|
-
}
|
|
37
|
-
// Format with cache_control for caching
|
|
38
|
-
// The system prompt is typically repeated across calls, making it a good caching candidate
|
|
39
|
-
// Use type assertion for cache_control which may not be in base SDK types but is supported by API
|
|
40
|
-
return [
|
|
41
|
-
{
|
|
42
|
-
type: 'text',
|
|
43
|
-
text: systemPrompt,
|
|
44
|
-
cache_control: { type: 'ephemeral' },
|
|
45
|
-
},
|
|
46
|
-
];
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Default retry configuration with exponential backoff
|
|
50
|
-
*/
|
|
51
|
-
const DEFAULT_RETRY_CONFIG = {
|
|
52
|
-
maxRetries: 4,
|
|
53
|
-
baseDelayMs: 1000,
|
|
54
|
-
maxDelayMs: 16000,
|
|
55
|
-
jitterFactor: 0.1,
|
|
56
|
-
};
|
|
57
|
-
/**
|
|
58
|
-
* AnthropicClient class provides a comprehensive interface for interacting
|
|
59
|
-
* with Anthropic's Claude API. It supports streaming responses, model switching,
|
|
60
|
-
* automatic token tracking, and retry logic with exponential backoff.
|
|
61
|
-
*
|
|
62
|
-
* Features:
|
|
63
|
-
* - Streaming and non-streaming message generation
|
|
64
|
-
* - Automatic model switching with validation
|
|
65
|
-
* - Token usage tracking and cost estimation
|
|
66
|
-
* - Retry logic with exponential backoff and jitter
|
|
67
|
-
* - Event emission for token updates and model changes
|
|
68
|
-
* - Connection testing and validation
|
|
69
|
-
*/
|
|
70
|
-
class AnthropicClient {
|
|
71
|
-
clients = new Map();
|
|
72
|
-
currentModel = DEFAULT_MODEL;
|
|
73
|
-
eventEmitter;
|
|
74
|
-
retryConfig;
|
|
75
|
-
initialized = false;
|
|
76
|
-
apiKey = null;
|
|
77
|
-
providerApiKeys = new Map();
|
|
78
|
-
constructor(retryConfig) {
|
|
79
|
-
this.eventEmitter = getEventEmitter();
|
|
80
|
-
this.retryConfig = { ...DEFAULT_RETRY_CONFIG, ...retryConfig };
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Gets the provider for a given model.
|
|
84
|
-
*/
|
|
85
|
-
getModelProvider(modelId) {
|
|
86
|
-
const resolvedId = resolveModelId(modelId);
|
|
87
|
-
const modelConfig = getModelConfig(resolvedId);
|
|
88
|
-
return (modelConfig?.provider || 'anthropic');
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Gets the API key for a specific provider.
|
|
92
|
-
* Returns cached key if available, otherwise fetches from credential store.
|
|
93
|
-
*/
|
|
94
|
-
async getApiKeyForProvider(provider) {
|
|
95
|
-
// Check cache first
|
|
96
|
-
if (this.providerApiKeys.has(provider)) {
|
|
97
|
-
return this.providerApiKeys.get(provider);
|
|
98
|
-
}
|
|
99
|
-
// Fetch from credential store
|
|
100
|
-
const credentialStore = await getCredentialStore();
|
|
101
|
-
const apiKey = await credentialStore.getProviderApiKey(provider);
|
|
102
|
-
if (apiKey) {
|
|
103
|
-
this.providerApiKeys.set(provider, apiKey);
|
|
104
|
-
}
|
|
105
|
-
return apiKey;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Resolves the base URL for a given model.
|
|
109
|
-
*
|
|
110
|
-
* @param modelId - The model ID to resolve base URL for
|
|
111
|
-
* @returns The base URL for the model
|
|
112
|
-
*/
|
|
113
|
-
resolveBaseUrl(modelId) {
|
|
114
|
-
const resolvedId = resolveModelId(modelId);
|
|
115
|
-
const modelConfig = getModelConfig(resolvedId);
|
|
116
|
-
// Priority: environment variable > model config > default
|
|
117
|
-
return process.env.COMPASS_ANTHROPIC_BASE_URL || modelConfig?.baseUrl || 'https://api.anthropic.com';
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Gets or creates a client for the specified model.
|
|
121
|
-
* Uses provider-specific API keys when available.
|
|
122
|
-
*
|
|
123
|
-
* @param modelId - The model ID to get client for
|
|
124
|
-
* @returns The Anthropic client instance for the model's base URL
|
|
125
|
-
*/
|
|
126
|
-
getClientForModel(modelId) {
|
|
127
|
-
const baseURL = this.resolveBaseUrl(modelId);
|
|
128
|
-
const provider = this.getModelProvider(modelId);
|
|
129
|
-
// Create a unique client key that includes both baseURL and provider
|
|
130
|
-
const clientKey = `${baseURL}:${provider}`;
|
|
131
|
-
// Return existing client if available
|
|
132
|
-
if (this.clients.has(clientKey)) {
|
|
133
|
-
return this.clients.get(clientKey);
|
|
134
|
-
}
|
|
135
|
-
// Get the API key for this provider (try provider-specific first, fall back to default)
|
|
136
|
-
const apiKey = this.providerApiKeys.get(provider) || this.apiKey;
|
|
137
|
-
if (!apiKey) {
|
|
138
|
-
throw new Error(`API key not available for provider '${provider}'. Call initialize() first or configure the API key.`);
|
|
139
|
-
}
|
|
140
|
-
const isOllama = baseURL.includes('ollama') || provider === 'ollama';
|
|
141
|
-
const client = new Anthropic({
|
|
142
|
-
apiKey: apiKey,
|
|
143
|
-
baseURL,
|
|
144
|
-
defaultHeaders: isOllama ? { 'Authorization': 'Bearer ' + apiKey } : {}
|
|
145
|
-
});
|
|
146
|
-
this.clients.set(clientKey, client);
|
|
147
|
-
logger.debug(`Created new client for provider '${provider}' at base URL: ${baseURL}`);
|
|
148
|
-
return client;
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Initializes the client with API keys from credential store.
|
|
152
|
-
* Loads API keys for all configured providers.
|
|
153
|
-
* Must be called before making any API requests.
|
|
154
|
-
*
|
|
155
|
-
* @returns True if initialization was successful, false otherwise
|
|
156
|
-
*/
|
|
157
|
-
async initialize() {
|
|
158
|
-
if (this.initialized && this.apiKey) {
|
|
159
|
-
return true;
|
|
160
|
-
}
|
|
161
|
-
try {
|
|
162
|
-
const credentialStore = await getCredentialStore();
|
|
163
|
-
// Load the default Anthropic API key (backward compatibility)
|
|
164
|
-
const defaultApiKey = await credentialStore.getApiKey();
|
|
165
|
-
if (!defaultApiKey) {
|
|
166
|
-
logger.warn('No default API key found. Please configure your Anthropic API key.');
|
|
167
|
-
return false;
|
|
168
|
-
}
|
|
169
|
-
this.apiKey = defaultApiKey;
|
|
170
|
-
this.providerApiKeys.set('anthropic', defaultApiKey);
|
|
171
|
-
// Load API keys for all other configured providers
|
|
172
|
-
const configuredProviders = await credentialStore.getConfiguredProviders();
|
|
173
|
-
for (const provider of configuredProviders) {
|
|
174
|
-
const providerKey = await credentialStore.getProviderApiKey(provider);
|
|
175
|
-
if (providerKey) {
|
|
176
|
-
this.providerApiKeys.set(provider, providerKey);
|
|
177
|
-
logger.debug(`Loaded API key for provider: ${provider}`);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
// Create client for the default model
|
|
181
|
-
this.getClientForModel(this.currentModel);
|
|
182
|
-
this.initialized = true;
|
|
183
|
-
logger.info(`Initialized with API keys for providers: ${Array.from(this.providerApiKeys.keys()).join(', ')}`);
|
|
184
|
-
return true;
|
|
185
|
-
}
|
|
186
|
-
catch (error) {
|
|
187
|
-
logger.error('Failed to initialize Anthropic client', error);
|
|
188
|
-
return false;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Checks if the client has been initialized with a valid API key.
|
|
193
|
-
*
|
|
194
|
-
* @returns True if the client is ready to make requests
|
|
195
|
-
*/
|
|
196
|
-
isInitialized() {
|
|
197
|
-
return this.initialized && this.apiKey !== null;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Gets the current model configuration.
|
|
201
|
-
*
|
|
202
|
-
* @returns The ModelConfig for the currently selected model
|
|
203
|
-
*/
|
|
204
|
-
getCurrentModel() {
|
|
205
|
-
const config = getModelConfig(this.currentModel);
|
|
206
|
-
if (!config) {
|
|
207
|
-
logger.warn(`Current model ${this.currentModel} not found, falling back to default`);
|
|
208
|
-
return CLAUDE_MODELS[DEFAULT_MODEL];
|
|
209
|
-
}
|
|
210
|
-
return config;
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Gets the current model ID.
|
|
214
|
-
*
|
|
215
|
-
* @returns The model ID string
|
|
216
|
-
*/
|
|
217
|
-
getCurrentModelId() {
|
|
218
|
-
return this.currentModel;
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Switches to a different Claude model.
|
|
222
|
-
* Automatically loads the API key for the new model's provider if needed.
|
|
223
|
-
*
|
|
224
|
-
* @param modelIdOrAlias - The model ID or alias (e.g., 'sonnet', 'opus', 'haiku')
|
|
225
|
-
* @returns True if the switch was successful, false if the model is unknown or API key is missing
|
|
226
|
-
*/
|
|
227
|
-
setModel(modelIdOrAlias) {
|
|
228
|
-
const resolvedId = resolveModelId(modelIdOrAlias);
|
|
229
|
-
const config = getModelConfig(resolvedId);
|
|
230
|
-
if (!config) {
|
|
231
|
-
logger.warn(`Unknown model: ${modelIdOrAlias}`);
|
|
232
|
-
return false;
|
|
233
|
-
}
|
|
234
|
-
const previousModel = this.currentModel;
|
|
235
|
-
const previousProvider = this.getModelProvider(previousModel);
|
|
236
|
-
const newProvider = (config.provider || 'anthropic');
|
|
237
|
-
this.currentModel = config.id;
|
|
238
|
-
if (previousModel !== this.currentModel) {
|
|
239
|
-
// Ensure client exists for the new model's base URL (lazy initialization)
|
|
240
|
-
// Note: The API key for the new provider should already be loaded during initialize()
|
|
241
|
-
// or will be fetched on-demand when getClientForModel is called
|
|
242
|
-
if (this.apiKey || this.providerApiKeys.has(newProvider)) {
|
|
243
|
-
try {
|
|
244
|
-
this.getClientForModel(this.currentModel);
|
|
245
|
-
}
|
|
246
|
-
catch (error) {
|
|
247
|
-
logger.warn(`Failed to create client for new model (provider: ${newProvider}). API key may not be configured.`, error);
|
|
248
|
-
// Revert to previous model if we can't create a client
|
|
249
|
-
this.currentModel = previousModel;
|
|
250
|
-
return false;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
this.eventEmitter.emit('model-switched', { model: config });
|
|
254
|
-
if (previousProvider !== newProvider) {
|
|
255
|
-
logger.info(`Switched from ${previousProvider}/${previousModel} to ${newProvider}/${config.name} (${config.id})`);
|
|
256
|
-
}
|
|
257
|
-
else {
|
|
258
|
-
logger.info(`Switched model from ${previousModel} to ${config.name} (${config.id})`);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
return true;
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Switches to a different model (async version).
|
|
265
|
-
* Automatically loads the API key for the new model's provider if not already cached.
|
|
266
|
-
*
|
|
267
|
-
* @param modelIdOrAlias - The model ID or alias
|
|
268
|
-
* @returns True if the switch was successful
|
|
269
|
-
*/
|
|
270
|
-
async setModelAsync(modelIdOrAlias) {
|
|
271
|
-
const resolvedId = resolveModelId(modelIdOrAlias);
|
|
272
|
-
const config = getModelConfig(resolvedId);
|
|
273
|
-
if (!config) {
|
|
274
|
-
logger.warn(`Unknown model: ${modelIdOrAlias}`);
|
|
275
|
-
return false;
|
|
276
|
-
}
|
|
277
|
-
const newProvider = (config.provider || 'anthropic');
|
|
278
|
-
// Ensure we have the API key for the new provider
|
|
279
|
-
if (!this.providerApiKeys.has(newProvider)) {
|
|
280
|
-
const providerKey = await this.getApiKeyForProvider(newProvider);
|
|
281
|
-
if (!providerKey) {
|
|
282
|
-
logger.warn(`No API key configured for provider '${newProvider}'. Cannot switch to model ${modelIdOrAlias}.`);
|
|
283
|
-
return false;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
return this.setModel(modelIdOrAlias);
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* Sends a message and streams the response in real-time.
|
|
290
|
-
* Yields StreamingResponse objects as content is generated.
|
|
291
|
-
*
|
|
292
|
-
* @param messages - Array of conversation messages
|
|
293
|
-
* @param options - Optional configuration for the request
|
|
294
|
-
* @yields StreamingResponse objects containing text chunks, tool use, or completion info
|
|
295
|
-
*/
|
|
296
|
-
async *streamMessage(messages, options = {}) {
|
|
297
|
-
if (!this.apiKey) {
|
|
298
|
-
yield { type: 'error', error: 'Client not initialized. Call initialize() first.' };
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
// Super-users bypass all token limits and model restrictions
|
|
302
|
-
const compassAuth = getCompassAuthService();
|
|
303
|
-
const isSuperUser = compassAuth.isSuperUser();
|
|
304
|
-
// Support per-call model override (e.g., use haiku for cheaper summarization)
|
|
305
|
-
let model = options.model
|
|
306
|
-
? getModelConfig(resolveModelId(options.model)) || this.getCurrentModel()
|
|
307
|
-
: this.getCurrentModel();
|
|
308
|
-
// Pre-flight: model availability + rolling window limit check
|
|
309
|
-
if (!isSuperUser) {
|
|
310
|
-
const planStatus = compassAuth.getPlanStatus();
|
|
311
|
-
// Check if model is disabled for this plan — attempt fallback
|
|
312
|
-
const disabledReason = getDisabledReason(model.id, planStatus);
|
|
313
|
-
if (disabledReason) {
|
|
314
|
-
const fallback = getAvailableFallbackModel(planStatus);
|
|
315
|
-
if (fallback) {
|
|
316
|
-
logger.warn(`Model "${model.id}" unavailable on current plan — falling back to "${fallback.id}"`);
|
|
317
|
-
model = fallback;
|
|
318
|
-
}
|
|
319
|
-
else {
|
|
320
|
-
yield { type: 'error', error: disabledReason };
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
// Check rolling window token limits
|
|
325
|
-
try {
|
|
326
|
-
const tokenTracker = await getTokenTracker();
|
|
327
|
-
const planType = compassAuth.getPlanType();
|
|
328
|
-
const limitCheck = await tokenTracker.checkLimit(model.id, planStatus, planType);
|
|
329
|
-
if (!limitCheck.allowed) {
|
|
330
|
-
yield {
|
|
331
|
-
type: 'error',
|
|
332
|
-
error: `${limitCheck.reason}\nSubscribe or renew for higher limits: https://app.compassap.ai/`,
|
|
333
|
-
};
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
// Warn if approaching limit (< 10% remaining on either bucket)
|
|
337
|
-
const minRemaining = Math.min(limitCheck.generalRemaining, limitCheck.modelRemaining);
|
|
338
|
-
const effectiveLimit = Math.max(limitCheck.generalRemaining + (limitCheck.generalRemaining === minRemaining ? 0 : 1), 1);
|
|
339
|
-
if (minRemaining < effectiveLimit * 0.1 && minRemaining > 0) {
|
|
340
|
-
logger.warn(`Low token quota: ${minRemaining.toLocaleString()} remaining`);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
catch (limitCheckError) {
|
|
344
|
-
// Don't block requests if limit check fails - log and continue
|
|
345
|
-
logger.debug('Token limit check failed, proceeding with request', limitCheckError);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
const maxTokens = options.maxTokens || Math.min(DEFAULT_MAX_TOKENS, model.maxOutputTokens);
|
|
349
|
-
// Get the appropriate client for this model's base URL (after potential fallback)
|
|
350
|
-
const client = this.getClientForModel(model.id);
|
|
351
|
-
// Get audit logger
|
|
352
|
-
const auditLogger = getAuditLogger();
|
|
353
|
-
// Store request data for consolidated logging at the end
|
|
354
|
-
const requestMessages = messages.map(m => ({ role: m.role, content: String(m.content) }));
|
|
355
|
-
const systemPrompt = options.system;
|
|
356
|
-
const requestOptions = {
|
|
357
|
-
model: model.id,
|
|
358
|
-
maxTokens,
|
|
359
|
-
temperature: options.temperature ?? DEFAULT_ANTHROPIC_TEMPERATURE,
|
|
360
|
-
tools: options.tools,
|
|
361
|
-
};
|
|
362
|
-
let lastError = null;
|
|
363
|
-
let attempt = 0;
|
|
364
|
-
let fullResponseContent = '';
|
|
365
|
-
// Enable prompt caching by default for system prompts
|
|
366
|
-
const enableCaching = options.enablePromptCaching !== false;
|
|
367
|
-
const formattedSystem = formatSystemPromptForCaching(options.system, enableCaching);
|
|
368
|
-
while (attempt <= this.retryConfig.maxRetries) {
|
|
369
|
-
try {
|
|
370
|
-
const stream = await client.messages.stream({
|
|
371
|
-
model: model.id,
|
|
372
|
-
max_tokens: maxTokens,
|
|
373
|
-
temperature: options.temperature ?? DEFAULT_ANTHROPIC_TEMPERATURE,
|
|
374
|
-
system: formattedSystem,
|
|
375
|
-
messages: this.formatMessages(messages, enableCaching),
|
|
376
|
-
...(options.tools && options.tools.length > 0 && { tools: options.tools }),
|
|
377
|
-
...(options.stopSequences && { stop_sequences: options.stopSequences }),
|
|
378
|
-
}, {
|
|
379
|
-
signal: options.abortSignal,
|
|
380
|
-
});
|
|
381
|
-
let inputTokens = 0;
|
|
382
|
-
let outputTokens = 0;
|
|
383
|
-
let cacheCreationInputTokens = 0;
|
|
384
|
-
let cacheReadInputTokens = 0;
|
|
385
|
-
// let thinkingContent = '';
|
|
386
|
-
for await (const event of stream) {
|
|
387
|
-
// Check if abort was requested
|
|
388
|
-
if (options.abortSignal?.aborted) {
|
|
389
|
-
logger.info('Aborting stream due to abort signal');
|
|
390
|
-
throw new Error('Request aborted');
|
|
391
|
-
}
|
|
392
|
-
// logger.debug(`Stream event type: ${event.type}`);
|
|
393
|
-
if (event.type === 'message_start') {
|
|
394
|
-
inputTokens = event.message.usage?.input_tokens || 0;
|
|
395
|
-
cacheCreationInputTokens = event.message.usage?.cache_creation_input_tokens || 0;
|
|
396
|
-
cacheReadInputTokens = event.message.usage?.cache_read_input_tokens || 0;
|
|
397
|
-
}
|
|
398
|
-
else if (event.type === 'content_block_delta') {
|
|
399
|
-
if (event.delta.type === 'text_delta') {
|
|
400
|
-
fullResponseContent += event.delta.text;
|
|
401
|
-
yield { type: 'text', content: event.delta.text };
|
|
402
|
-
}
|
|
403
|
-
else if (event.delta.type === 'input_json_delta') {
|
|
404
|
-
fullResponseContent += event.delta.partial_json;
|
|
405
|
-
yield { type: 'tool_use', content: event.delta.partial_json };
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
else if (event.type === 'message_delta') {
|
|
409
|
-
outputTokens = event.usage?.output_tokens || 0;
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
// Log accumulated thinking content if present
|
|
413
|
-
// if (thinkingContent) {
|
|
414
|
-
// logger.debug(`Accumulated thinking content: "${thinkingContent}"`);
|
|
415
|
-
// }
|
|
416
|
-
// Get final message from stream for accurate usage data
|
|
417
|
-
// This is important for Ollama/OpenAI-compatible APIs that may not emit
|
|
418
|
-
// usage data in message_start event the same way Anthropic does.
|
|
419
|
-
// For Anthropic models, message_start already provides accurate input_tokens,
|
|
420
|
-
// and finalMessage() may hang or fail since the stream is already consumed.
|
|
421
|
-
const isAnthropicProvider = model.provider === 'anthropic' || !model.provider;
|
|
422
|
-
if (!isAnthropicProvider) {
|
|
423
|
-
try {
|
|
424
|
-
const finalMessage = await Promise.race([
|
|
425
|
-
stream.finalMessage(),
|
|
426
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error('finalMessage() timed out after 5s')), 5000)),
|
|
427
|
-
]);
|
|
428
|
-
if (finalMessage?.usage) {
|
|
429
|
-
inputTokens = finalMessage.usage.input_tokens || inputTokens;
|
|
430
|
-
outputTokens = finalMessage.usage.output_tokens || outputTokens;
|
|
431
|
-
cacheCreationInputTokens = finalMessage.usage?.cache_creation_input_tokens || cacheCreationInputTokens;
|
|
432
|
-
cacheReadInputTokens = finalMessage.usage?.cache_read_input_tokens || cacheReadInputTokens;
|
|
433
|
-
logger.debug('Got usage from finalMessage for non-Anthropic provider', {
|
|
434
|
-
provider: model.provider,
|
|
435
|
-
inputTokens,
|
|
436
|
-
outputTokens,
|
|
437
|
-
cacheCreationInputTokens,
|
|
438
|
-
cacheReadInputTokens,
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
catch (finalMessageError) {
|
|
443
|
-
// finalMessage() may fail if stream was aborted or errored
|
|
444
|
-
// Fall back to accumulated usage from events
|
|
445
|
-
logger.debug('Could not get finalMessage, using accumulated usage', finalMessageError);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
else {
|
|
449
|
-
logger.debug('Using usage from message_start event for Anthropic provider', {
|
|
450
|
-
inputTokens,
|
|
451
|
-
outputTokens,
|
|
452
|
-
cacheCreationInputTokens,
|
|
453
|
-
cacheReadInputTokens,
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
// Build final usage statistics
|
|
457
|
-
const usage = {
|
|
458
|
-
inputTokens,
|
|
459
|
-
outputTokens,
|
|
460
|
-
totalTokens: inputTokens + outputTokens,
|
|
461
|
-
cacheCreationInputTokens,
|
|
462
|
-
cacheReadInputTokens,
|
|
463
|
-
};
|
|
464
|
-
const cost = this.calculateCost(usage, model);
|
|
465
|
-
// Log complete LLM call with all data in a single entry
|
|
466
|
-
await auditLogger.logLLMCall(systemPrompt, requestMessages, fullResponseContent, usage, cost, requestOptions);
|
|
467
|
-
// Track token usage
|
|
468
|
-
try {
|
|
469
|
-
const tokenTracker = await getTokenTracker();
|
|
470
|
-
await tokenTracker.recordUsage(model.id, usage, 'streaming_message');
|
|
471
|
-
}
|
|
472
|
-
catch (trackingError) {
|
|
473
|
-
logger.debug('Failed to track token usage', trackingError);
|
|
474
|
-
}
|
|
475
|
-
// Record actual usage against rolling window limits (fire-and-forget)
|
|
476
|
-
getTokenTracker().then(tt => tt.recordLimitUsage(model.id, usage.totalTokens)).catch(err => {
|
|
477
|
-
logger.debug('Failed to record rolling window usage', err);
|
|
478
|
-
});
|
|
479
|
-
// Emit token update event
|
|
480
|
-
this.eventEmitter.emit('token-update', { usage, cost });
|
|
481
|
-
// Track usage with Compass (sessionless)
|
|
482
|
-
try {
|
|
483
|
-
const credentialStore = await getCredentialStore();
|
|
484
|
-
const compassApiKey = await credentialStore.getCompassApiKey();
|
|
485
|
-
if (compassApiKey) {
|
|
486
|
-
// Calculate cost locally for accurate tracking
|
|
487
|
-
const calculatedCost = calculateModelCost({
|
|
488
|
-
modelId: model.id,
|
|
489
|
-
inputTokens: usage.inputTokens,
|
|
490
|
-
outputTokens: usage.outputTokens,
|
|
491
|
-
cacheWriteTokens: usage.cacheCreationInputTokens ?? 0,
|
|
492
|
-
cacheReadTokens: usage.cacheReadInputTokens ?? 0,
|
|
493
|
-
provider: model.provider,
|
|
494
|
-
});
|
|
495
|
-
logger.debug('Tracking usage with Compass', {
|
|
496
|
-
input_tokens: usage.inputTokens,
|
|
497
|
-
cache_write_input_tokens: usage.cacheCreationInputTokens ?? 0,
|
|
498
|
-
cache_read_input_tokens: usage.cacheReadInputTokens ?? 0,
|
|
499
|
-
output_tokens: usage.outputTokens,
|
|
500
|
-
provider: model.provider,
|
|
501
|
-
model: model.id,
|
|
502
|
-
calculatedCost: calculatedCost?.totalCost,
|
|
503
|
-
});
|
|
504
|
-
const compassAuth = getCompassAuthService();
|
|
505
|
-
await compassAuth.trackUsage({
|
|
506
|
-
input_tokens: usage.inputTokens,
|
|
507
|
-
cache_write_input_tokens: usage.cacheCreationInputTokens ?? 0,
|
|
508
|
-
cache_read_input_tokens: usage.cacheReadInputTokens ?? 0,
|
|
509
|
-
output_tokens: usage.outputTokens,
|
|
510
|
-
provider: model.provider,
|
|
511
|
-
model: model.id,
|
|
512
|
-
// Include pre-calculated cost for backend to register
|
|
513
|
-
cost: calculatedCost ?? undefined,
|
|
514
|
-
}, compassApiKey);
|
|
515
|
-
// Record cost in local tracker (use our calculated cost, not backend response)
|
|
516
|
-
if (calculatedCost) {
|
|
517
|
-
const costTracker = getCostTracker();
|
|
518
|
-
costTracker.recordCost(calculatedCost.totalCost, calculatedCost.currency, model.id, model.provider, options.callType || 'conversation', {
|
|
519
|
-
inputTokens: usage.inputTokens,
|
|
520
|
-
outputTokens: usage.outputTokens,
|
|
521
|
-
cacheCreationTokens: usage.cacheCreationInputTokens ?? 0,
|
|
522
|
-
cacheReadTokens: usage.cacheReadInputTokens ?? 0,
|
|
523
|
-
});
|
|
524
|
-
logger.info('Cost tracked', {
|
|
525
|
-
cost: calculatedCost.totalCost,
|
|
526
|
-
currency: calculatedCost.currency,
|
|
527
|
-
callType: options.callType || 'conversation',
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
else {
|
|
532
|
-
logger.debug('No Compass API key found, skipping usage tracking');
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
catch (trackingError) {
|
|
536
|
-
logger.debug('Failed to track usage with Compass', trackingError);
|
|
537
|
-
}
|
|
538
|
-
yield { type: 'done', usage };
|
|
539
|
-
return;
|
|
540
|
-
}
|
|
541
|
-
catch (error) {
|
|
542
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
543
|
-
// Check if error is retryable
|
|
544
|
-
if (!this.isRetryableError(error) || attempt >= this.retryConfig.maxRetries) {
|
|
545
|
-
break;
|
|
546
|
-
}
|
|
547
|
-
// Calculate delay with exponential backoff and jitter
|
|
548
|
-
const delay = this.calculateRetryDelay(attempt);
|
|
549
|
-
logger.debug(`Retrying request after ${delay}ms (attempt ${attempt + 1}/${this.retryConfig.maxRetries})`);
|
|
550
|
-
await this.sleep(delay);
|
|
551
|
-
attempt++;
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
// All retries exhausted or non-retryable error
|
|
555
|
-
const friendlyMessage = this.getFriendlyErrorMessage(lastError);
|
|
556
|
-
const errorMessage = friendlyMessage || lastError?.message || 'Unknown error occurred';
|
|
557
|
-
logger.error('API request failed after retries', lastError);
|
|
558
|
-
await auditLogger.logError(errorMessage, lastError);
|
|
559
|
-
yield { type: 'error', error: errorMessage };
|
|
560
|
-
}
|
|
561
|
-
/**
|
|
562
|
-
* Sends a message and waits for the complete response.
|
|
563
|
-
* Use this for non-streaming use cases where you need the full response at once.
|
|
564
|
-
*
|
|
565
|
-
* @param messages - Array of conversation messages
|
|
566
|
-
* @param options - Optional configuration for the request
|
|
567
|
-
* @returns Promise resolving to the complete message result
|
|
568
|
-
* @throws Error if the request fails after all retries
|
|
569
|
-
*/
|
|
570
|
-
async sendMessage(messages, options = {}) {
|
|
571
|
-
// If structured output is requested, use beta parse API
|
|
572
|
-
if (options.outputFormat) {
|
|
573
|
-
return this.sendStructuredMessage(messages, options);
|
|
574
|
-
}
|
|
575
|
-
// Otherwise use standard streaming API
|
|
576
|
-
let content = '';
|
|
577
|
-
let finalUsage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
|
|
578
|
-
let errorMessage = null;
|
|
579
|
-
for await (const response of this.streamMessage(messages, options)) {
|
|
580
|
-
switch (response.type) {
|
|
581
|
-
case 'text':
|
|
582
|
-
if (response.content) {
|
|
583
|
-
content += response.content;
|
|
584
|
-
}
|
|
585
|
-
break;
|
|
586
|
-
case 'done':
|
|
587
|
-
if (response.usage) {
|
|
588
|
-
finalUsage = response.usage;
|
|
589
|
-
}
|
|
590
|
-
break;
|
|
591
|
-
case 'error':
|
|
592
|
-
errorMessage = response.error || 'Unknown error';
|
|
593
|
-
break;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
if (errorMessage) {
|
|
597
|
-
throw new Error(errorMessage);
|
|
598
|
-
}
|
|
599
|
-
const model = this.getCurrentModel();
|
|
600
|
-
const cost = this.calculateCost(finalUsage, model);
|
|
601
|
-
return {
|
|
602
|
-
content,
|
|
603
|
-
usage: finalUsage,
|
|
604
|
-
cost,
|
|
605
|
-
model: model.id,
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
/**
|
|
609
|
-
* Removes markdown code fence delimiters from JSON content.
|
|
610
|
-
* Extracts JSON from ```json or ``` code blocks, or returns trimmed content if no code fence found.
|
|
611
|
-
*
|
|
612
|
-
* @param content - The raw content string that may contain markdown code fences
|
|
613
|
-
* @returns The cleaned JSON string
|
|
614
|
-
*/
|
|
615
|
-
removeMarkdownCodeFence(content) {
|
|
616
|
-
const jsonMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
617
|
-
return jsonMatch ? jsonMatch[1].trim() : content.trim();
|
|
618
|
-
}
|
|
619
|
-
/**
|
|
620
|
-
* Creates a JSON schema output format object from the given JSON schema.
|
|
621
|
-
* If this is passed to the `.parse()` method then the response message will contain a
|
|
622
|
-
* `.parsed_output` property that is the result of parsing the content with the given JSON schema.
|
|
623
|
-
*
|
|
624
|
-
*/
|
|
625
|
-
betaJSONSchemaOutputFormat(jsonSchema, options) {
|
|
626
|
-
if (jsonSchema.type !== 'object') {
|
|
627
|
-
throw new Error(`JSON schema for tool must be an object, but got ${jsonSchema.type}`);
|
|
628
|
-
}
|
|
629
|
-
const transform = options?.transform ?? true;
|
|
630
|
-
if (transform) {
|
|
631
|
-
// todo: doing this is arguably necessary, but it does change the schema the user passed in
|
|
632
|
-
// so I'm not sure how we should handle that
|
|
633
|
-
jsonSchema = transformJSONSchema(jsonSchema);
|
|
634
|
-
}
|
|
635
|
-
// @ts-expect-error - Type instantiation complexity from generic JSON schema
|
|
636
|
-
return {
|
|
637
|
-
type: 'json_schema',
|
|
638
|
-
schema: {
|
|
639
|
-
...jsonSchema,
|
|
640
|
-
},
|
|
641
|
-
parse: (content) => {
|
|
642
|
-
try {
|
|
643
|
-
const cleanedContent = this.removeMarkdownCodeFence(content);
|
|
644
|
-
return JSON.parse(cleanedContent);
|
|
645
|
-
}
|
|
646
|
-
catch (error) {
|
|
647
|
-
throw new AnthropicError(`Failed to parse structured output: ${error}`);
|
|
648
|
-
}
|
|
649
|
-
},
|
|
650
|
-
};
|
|
651
|
-
}
|
|
652
|
-
/**
|
|
653
|
-
* Sends a message with structured JSON output using the beta parse API.
|
|
654
|
-
* This enforces the response to conform to a specific JSON schema.
|
|
655
|
-
*
|
|
656
|
-
* @param messages - Array of conversation messages
|
|
657
|
-
* @param options - Configuration including outputFormat (JSON schema)
|
|
658
|
-
* @returns Promise resolving to the complete message result with structured JSON
|
|
659
|
-
* @throws Error if the request fails or schema validation fails
|
|
660
|
-
*/
|
|
661
|
-
async sendStructuredMessage(messages, options) {
|
|
662
|
-
if (!this.apiKey) {
|
|
663
|
-
throw new Error('Client not initialized. Call initialize() first.');
|
|
664
|
-
}
|
|
665
|
-
if (!options.outputFormat) {
|
|
666
|
-
throw new Error('outputFormat is required for structured messages');
|
|
667
|
-
}
|
|
668
|
-
// Support per-call model override
|
|
669
|
-
let model = options.model
|
|
670
|
-
? getModelConfig(resolveModelId(options.model)) || this.getCurrentModel()
|
|
671
|
-
: this.getCurrentModel();
|
|
672
|
-
const auditLogger = getAuditLogger();
|
|
673
|
-
// Pre-flight: model availability + rolling window limit check
|
|
674
|
-
const compassAuth = getCompassAuthService();
|
|
675
|
-
if (!compassAuth.isSuperUser()) {
|
|
676
|
-
const planStatus = compassAuth.getPlanStatus();
|
|
677
|
-
const disabledReason = getDisabledReason(model.id, planStatus);
|
|
678
|
-
if (disabledReason) {
|
|
679
|
-
const fallback = getAvailableFallbackModel(planStatus);
|
|
680
|
-
if (fallback) {
|
|
681
|
-
logger.warn(`Model "${model.id}" unavailable on current plan — falling back to "${fallback.id}"`);
|
|
682
|
-
model = fallback;
|
|
683
|
-
}
|
|
684
|
-
else {
|
|
685
|
-
throw new Error(disabledReason);
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
const tokenTracker = await getTokenTracker();
|
|
689
|
-
const planType = compassAuth.getPlanType();
|
|
690
|
-
const limitCheck = await tokenTracker.checkLimit(model.id, planStatus, planType);
|
|
691
|
-
if (!limitCheck.allowed) {
|
|
692
|
-
throw new Error(`${limitCheck.reason}\nSubscribe or renew for higher limits: https://app.compassap.ai/`);
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
const maxTokens = options.maxTokens || Math.min(DEFAULT_MAX_TOKENS, model.maxOutputTokens);
|
|
696
|
-
// Get the appropriate client for this model's base URL (after potential fallback)
|
|
697
|
-
const client = this.getClientForModel(model.id);
|
|
698
|
-
// Enable prompt caching by default for system prompts
|
|
699
|
-
const enableCaching = options.enablePromptCaching !== false;
|
|
700
|
-
const formattedSystem = formatSystemPromptForCaching(options.system, enableCaching);
|
|
701
|
-
try {
|
|
702
|
-
// Use beta.messages.create (not .parse) to avoid SDK crash when content is null.
|
|
703
|
-
// Some models/providers may return content: null which causes parseBetaMessage to throw
|
|
704
|
-
// "Cannot read properties of null (reading 'map')".
|
|
705
|
-
const response = await client.beta.messages.create({
|
|
706
|
-
model: model.id,
|
|
707
|
-
max_tokens: maxTokens,
|
|
708
|
-
temperature: options.temperature ?? DEFAULT_ANTHROPIC_TEMPERATURE,
|
|
709
|
-
system: formattedSystem,
|
|
710
|
-
messages: this.formatMessages(messages, enableCaching),
|
|
711
|
-
output_format: this.betaJSONSchemaOutputFormat(options.outputFormat),
|
|
712
|
-
}, {
|
|
713
|
-
signal: options.abortSignal,
|
|
714
|
-
});
|
|
715
|
-
// Handle null/empty content gracefully
|
|
716
|
-
if (!response.content || response.content.length === 0) {
|
|
717
|
-
throw new Error(`Model "${model.id}" returned empty content for structured output request. ` +
|
|
718
|
-
`This model may not support the structured output format.`);
|
|
719
|
-
}
|
|
720
|
-
// Extract usage information
|
|
721
|
-
const usage = {
|
|
722
|
-
inputTokens: response.usage?.input_tokens || 0,
|
|
723
|
-
outputTokens: response.usage?.output_tokens || 0,
|
|
724
|
-
totalTokens: (response.usage?.input_tokens || 0) + (response.usage?.output_tokens || 0),
|
|
725
|
-
cacheCreationInputTokens: response.usage?.cache_creation_input_tokens || 0,
|
|
726
|
-
cacheReadInputTokens: response.usage?.cache_read_input_tokens || 0,
|
|
727
|
-
};
|
|
728
|
-
const cost = this.calculateCost(usage, model);
|
|
729
|
-
// Extract and parse JSON content from the text block
|
|
730
|
-
const textBlock = response.content.find((block) => block.type === 'text');
|
|
731
|
-
if (!textBlock || textBlock.type !== 'text') {
|
|
732
|
-
throw new Error('No text content block in structured output response');
|
|
733
|
-
}
|
|
734
|
-
let content;
|
|
735
|
-
try {
|
|
736
|
-
const parsed = JSON.parse(textBlock.text);
|
|
737
|
-
content = JSON.stringify(parsed);
|
|
738
|
-
}
|
|
739
|
-
catch {
|
|
740
|
-
// If JSON parsing fails, return the raw text so the caller can attempt its own parsing
|
|
741
|
-
content = textBlock.text;
|
|
742
|
-
}
|
|
743
|
-
// Log the LLM call
|
|
744
|
-
const requestMessages = messages.map(m => ({ role: m.role, content: String(m.content) }));
|
|
745
|
-
await auditLogger.logLLMCall(options.system, requestMessages, content, usage, cost, {
|
|
746
|
-
model: model.id,
|
|
747
|
-
maxTokens,
|
|
748
|
-
temperature: options.temperature ?? DEFAULT_ANTHROPIC_TEMPERATURE,
|
|
749
|
-
// outputFormat: 'json_schema',
|
|
750
|
-
});
|
|
751
|
-
// Track token usage
|
|
752
|
-
try {
|
|
753
|
-
const tokenTracker = await getTokenTracker();
|
|
754
|
-
await tokenTracker.recordUsage(model.id, usage, 'structured_message');
|
|
755
|
-
}
|
|
756
|
-
catch (trackingError) {
|
|
757
|
-
logger.debug('Failed to track token usage', trackingError);
|
|
758
|
-
}
|
|
759
|
-
// Record actual usage against rolling window limits (fire-and-forget)
|
|
760
|
-
getTokenTracker().then(tt => tt.recordLimitUsage(model.id, usage.totalTokens)).catch(err => {
|
|
761
|
-
logger.debug('Failed to record rolling window usage', err);
|
|
762
|
-
});
|
|
763
|
-
// Emit token update event
|
|
764
|
-
this.eventEmitter.emit('token-update', { usage, cost });
|
|
765
|
-
// Track usage with Compass (sessionless)
|
|
766
|
-
try {
|
|
767
|
-
const credentialStore = await getCredentialStore();
|
|
768
|
-
const compassApiKey = await credentialStore.getCompassApiKey();
|
|
769
|
-
if (compassApiKey) {
|
|
770
|
-
// Calculate cost locally for accurate tracking
|
|
771
|
-
const calculatedCost = calculateModelCost({
|
|
772
|
-
modelId: model.id,
|
|
773
|
-
inputTokens: usage.inputTokens,
|
|
774
|
-
outputTokens: usage.outputTokens,
|
|
775
|
-
cacheWriteTokens: usage.cacheCreationInputTokens ?? 0,
|
|
776
|
-
cacheReadTokens: usage.cacheReadInputTokens ?? 0,
|
|
777
|
-
provider: model.provider,
|
|
778
|
-
});
|
|
779
|
-
logger.debug('Tracking structured message usage with Compass', {
|
|
780
|
-
input_tokens: usage.inputTokens,
|
|
781
|
-
cache_write_input_tokens: usage.cacheCreationInputTokens ?? 0,
|
|
782
|
-
cache_read_input_tokens: usage.cacheReadInputTokens ?? 0,
|
|
783
|
-
output_tokens: usage.outputTokens,
|
|
784
|
-
provider: model.provider,
|
|
785
|
-
model: model.id,
|
|
786
|
-
calculatedCost: calculatedCost?.totalCost,
|
|
787
|
-
});
|
|
788
|
-
const compassAuth = getCompassAuthService();
|
|
789
|
-
await compassAuth.trackUsage({
|
|
790
|
-
input_tokens: usage.inputTokens,
|
|
791
|
-
cache_write_input_tokens: usage.cacheCreationInputTokens ?? 0,
|
|
792
|
-
cache_read_input_tokens: usage.cacheReadInputTokens ?? 0,
|
|
793
|
-
output_tokens: usage.outputTokens,
|
|
794
|
-
provider: model.provider,
|
|
795
|
-
model: model.id,
|
|
796
|
-
// Include pre-calculated cost for backend to register
|
|
797
|
-
cost: calculatedCost ?? undefined,
|
|
798
|
-
}, compassApiKey);
|
|
799
|
-
// Record cost in local tracker (use our calculated cost, not backend response)
|
|
800
|
-
if (calculatedCost) {
|
|
801
|
-
const costTracker = getCostTracker();
|
|
802
|
-
costTracker.recordCost(calculatedCost.totalCost, calculatedCost.currency, model.id, model.provider, options.callType || 'conversation', {
|
|
803
|
-
inputTokens: usage.inputTokens,
|
|
804
|
-
outputTokens: usage.outputTokens,
|
|
805
|
-
cacheCreationTokens: usage.cacheCreationInputTokens ?? 0,
|
|
806
|
-
cacheReadTokens: usage.cacheReadInputTokens ?? 0,
|
|
807
|
-
});
|
|
808
|
-
logger.info('Cost tracked', {
|
|
809
|
-
cost: calculatedCost.totalCost,
|
|
810
|
-
currency: calculatedCost.currency,
|
|
811
|
-
callType: options.callType || 'conversation',
|
|
812
|
-
});
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
else {
|
|
816
|
-
logger.debug('No Compass API key found, skipping usage tracking');
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
catch (trackingError) {
|
|
820
|
-
logger.debug('Failed to track usage with Compass', trackingError);
|
|
821
|
-
}
|
|
822
|
-
return {
|
|
823
|
-
content,
|
|
824
|
-
usage,
|
|
825
|
-
cost,
|
|
826
|
-
stopReason: response.stop_reason || undefined,
|
|
827
|
-
model: model.id,
|
|
828
|
-
};
|
|
829
|
-
}
|
|
830
|
-
catch (error) {
|
|
831
|
-
const isAbort = error instanceof Error && (error.message.includes('aborted') || error.name === 'AbortError' || error.name === 'APIUserAbortError');
|
|
832
|
-
if (isAbort) {
|
|
833
|
-
logger.debug('Structured message request aborted');
|
|
834
|
-
}
|
|
835
|
-
else {
|
|
836
|
-
logger.error('Structured message request failed', error);
|
|
837
|
-
}
|
|
838
|
-
throw error;
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
/**
|
|
842
|
-
* Creates a message with full response including tool use blocks.
|
|
843
|
-
* This is the primary method for the agentic loop.
|
|
844
|
-
*
|
|
845
|
-
* @param messages - Array of conversation messages (can include tool_result blocks)
|
|
846
|
-
* @param options - Configuration for the request
|
|
847
|
-
* @param onTextChunk - Optional callback for streaming text chunks
|
|
848
|
-
* @param onToolEvent - Optional callback for tool use streaming events
|
|
849
|
-
* @returns Full response with tool use blocks and stop reason
|
|
850
|
-
*/
|
|
851
|
-
async createAgenticMessage(messages, options = {}, onTextChunk, onToolEvent) {
|
|
852
|
-
if (!this.apiKey) {
|
|
853
|
-
throw new Error('Client not initialized. Call initialize() first.');
|
|
854
|
-
}
|
|
855
|
-
// Support per-call model override (e.g., use haiku for cheaper summarization)
|
|
856
|
-
let model = options.model
|
|
857
|
-
? getModelConfig(resolveModelId(options.model)) || this.getCurrentModel()
|
|
858
|
-
: this.getCurrentModel();
|
|
859
|
-
const auditLogger = getAuditLogger();
|
|
860
|
-
// Pre-flight: model availability + rolling window limit check
|
|
861
|
-
const compassAuth = getCompassAuthService();
|
|
862
|
-
if (!compassAuth.isSuperUser()) {
|
|
863
|
-
const planStatus = compassAuth.getPlanStatus();
|
|
864
|
-
const disabledReason = getDisabledReason(model.id, planStatus);
|
|
865
|
-
if (disabledReason) {
|
|
866
|
-
// Attempt automatic fallback to an available model
|
|
867
|
-
const fallback = getAvailableFallbackModel(planStatus);
|
|
868
|
-
if (fallback) {
|
|
869
|
-
logger.warn(`Model "${model.id}" unavailable on current plan — falling back to "${fallback.id}"`);
|
|
870
|
-
model = fallback;
|
|
871
|
-
}
|
|
872
|
-
else {
|
|
873
|
-
throw new Error(disabledReason);
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
const tokenTracker = await getTokenTracker();
|
|
877
|
-
const planType = compassAuth.getPlanType();
|
|
878
|
-
const limitCheck = await tokenTracker.checkLimit(model.id, planStatus, planType);
|
|
879
|
-
if (!limitCheck.allowed) {
|
|
880
|
-
throw new Error(`${limitCheck.reason}\nSubscribe or renew for higher limits: https://app.compassap.ai/`);
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
const maxTokens = options.maxTokens || Math.min(DEFAULT_MAX_TOKENS, model.maxOutputTokens);
|
|
884
|
-
// Get the appropriate client for this model's base URL (after potential fallback)
|
|
885
|
-
const client = this.getClientForModel(model.id);
|
|
886
|
-
let lastError = null;
|
|
887
|
-
let attempt = 0;
|
|
888
|
-
// Enable prompt caching by default for system prompts (can be disabled via options)
|
|
889
|
-
const enableCaching = options.enablePromptCaching !== false;
|
|
890
|
-
const formattedSystem = formatSystemPromptForCaching(options.system, enableCaching);
|
|
891
|
-
while (attempt <= this.retryConfig.maxRetries) {
|
|
892
|
-
try {
|
|
893
|
-
const stream = await client.messages.stream({
|
|
894
|
-
model: model.id,
|
|
895
|
-
max_tokens: maxTokens,
|
|
896
|
-
temperature: options.temperature ?? DEFAULT_ANTHROPIC_TEMPERATURE,
|
|
897
|
-
system: formattedSystem,
|
|
898
|
-
messages: this.formatMessages(messages, enableCaching),
|
|
899
|
-
...(options.tools && options.tools.length > 0 && { tools: options.tools }),
|
|
900
|
-
...(options.stopSequences && { stop_sequences: options.stopSequences }),
|
|
901
|
-
}, {
|
|
902
|
-
signal: options.abortSignal,
|
|
903
|
-
});
|
|
904
|
-
let inputTokens = 0;
|
|
905
|
-
let outputTokens = 0;
|
|
906
|
-
let cacheCreationInputTokens = 0;
|
|
907
|
-
let cacheReadInputTokens = 0;
|
|
908
|
-
let textContent = '';
|
|
909
|
-
const toolUseBlocks = [];
|
|
910
|
-
const contentBlocks = [];
|
|
911
|
-
let stopReason = 'end_turn';
|
|
912
|
-
// Track current tool use block being built
|
|
913
|
-
let currentToolUse = null;
|
|
914
|
-
for await (const event of stream) {
|
|
915
|
-
// Check for abort between events
|
|
916
|
-
if (options.abortSignal?.aborted) {
|
|
917
|
-
logger.info('Aborting stream due to signal');
|
|
918
|
-
throw new Error('Request aborted');
|
|
919
|
-
}
|
|
920
|
-
if (event.type === 'message_start') {
|
|
921
|
-
inputTokens = event.message.usage?.input_tokens || 0;
|
|
922
|
-
cacheCreationInputTokens = event.message.usage?.cache_creation_input_tokens || 0;
|
|
923
|
-
cacheReadInputTokens = event.message.usage?.cache_read_input_tokens || 0;
|
|
924
|
-
}
|
|
925
|
-
else if (event.type === 'content_block_start') {
|
|
926
|
-
if (event.content_block.type === 'tool_use') {
|
|
927
|
-
currentToolUse = {
|
|
928
|
-
id: event.content_block.id,
|
|
929
|
-
name: event.content_block.name,
|
|
930
|
-
inputJson: '',
|
|
931
|
-
};
|
|
932
|
-
// Emit tool_start event immediately when we know the tool name
|
|
933
|
-
if (onToolEvent) {
|
|
934
|
-
onToolEvent({
|
|
935
|
-
type: 'tool_start',
|
|
936
|
-
id: event.content_block.id,
|
|
937
|
-
name: event.content_block.name,
|
|
938
|
-
});
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
else if (event.content_block.type === 'text') {
|
|
942
|
-
// Initialize text content block
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
else if (event.type === 'content_block_delta') {
|
|
946
|
-
if (event.delta.type === 'text_delta' && event.delta.text) {
|
|
947
|
-
textContent += event.delta.text;
|
|
948
|
-
if (onTextChunk) {
|
|
949
|
-
onTextChunk(event.delta.text);
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
else if (event.delta.type === 'input_json_delta' && currentToolUse) {
|
|
953
|
-
currentToolUse.inputJson += event.delta.partial_json || '';
|
|
954
|
-
// Optionally emit progress (useful for large inputs like file content)
|
|
955
|
-
if (onToolEvent) {
|
|
956
|
-
onToolEvent({
|
|
957
|
-
type: 'tool_input_delta',
|
|
958
|
-
id: currentToolUse.id,
|
|
959
|
-
partialInput: event.delta.partial_json || '',
|
|
960
|
-
});
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
else if (event.type === 'content_block_stop') {
|
|
965
|
-
if (currentToolUse) {
|
|
966
|
-
// Parse the accumulated JSON and create tool use block
|
|
967
|
-
try {
|
|
968
|
-
const input = JSON.parse(currentToolUse.inputJson || '{}');
|
|
969
|
-
toolUseBlocks.push({
|
|
970
|
-
id: currentToolUse.id,
|
|
971
|
-
name: currentToolUse.name,
|
|
972
|
-
input,
|
|
973
|
-
});
|
|
974
|
-
contentBlocks.push({
|
|
975
|
-
type: 'tool_use',
|
|
976
|
-
id: currentToolUse.id,
|
|
977
|
-
name: currentToolUse.name,
|
|
978
|
-
input,
|
|
979
|
-
});
|
|
980
|
-
// Emit tool_complete event with parsed input
|
|
981
|
-
if (onToolEvent) {
|
|
982
|
-
onToolEvent({
|
|
983
|
-
type: 'tool_complete',
|
|
984
|
-
id: currentToolUse.id,
|
|
985
|
-
name: currentToolUse.name,
|
|
986
|
-
input,
|
|
987
|
-
});
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
catch (parseError) {
|
|
991
|
-
logger.error('Failed to parse tool input JSON', parseError);
|
|
992
|
-
}
|
|
993
|
-
currentToolUse = null;
|
|
994
|
-
}
|
|
995
|
-
else if (textContent) {
|
|
996
|
-
// Only add text block if we have content
|
|
997
|
-
if (!contentBlocks.some(b => b.type === 'text')) {
|
|
998
|
-
contentBlocks.push({
|
|
999
|
-
type: 'text',
|
|
1000
|
-
text: textContent,
|
|
1001
|
-
});
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
else if (event.type === 'message_delta') {
|
|
1006
|
-
outputTokens = event.usage?.output_tokens || 0;
|
|
1007
|
-
if (event.delta.stop_reason) {
|
|
1008
|
-
stopReason = event.delta.stop_reason;
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
// Get final message from stream for accurate usage data
|
|
1013
|
-
// This is important for Ollama/OpenAI-compatible APIs that may not emit
|
|
1014
|
-
// usage data in message_start event the same way Anthropic does.
|
|
1015
|
-
// For Anthropic models, message_start already provides accurate input_tokens,
|
|
1016
|
-
// and finalMessage() may hang or fail since the stream is already consumed.
|
|
1017
|
-
const isAnthropicProvider = model.provider === 'anthropic' || !model.provider;
|
|
1018
|
-
logger.debug('[SDK-DIAG] stream consumed', { isAnthropicProvider, provider: model.provider, model: model.id });
|
|
1019
|
-
if (!isAnthropicProvider) {
|
|
1020
|
-
try {
|
|
1021
|
-
logger.debug('[SDK-DIAG] stream.finalMessage() START');
|
|
1022
|
-
const finalMessage = await Promise.race([
|
|
1023
|
-
stream.finalMessage(),
|
|
1024
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error('finalMessage() timed out after 5s')), 5000)),
|
|
1025
|
-
]);
|
|
1026
|
-
logger.debug('[SDK-DIAG] stream.finalMessage() DONE');
|
|
1027
|
-
if (finalMessage?.usage) {
|
|
1028
|
-
inputTokens = finalMessage.usage.input_tokens || inputTokens;
|
|
1029
|
-
outputTokens = finalMessage.usage.output_tokens || outputTokens;
|
|
1030
|
-
cacheCreationInputTokens = finalMessage.usage?.cache_creation_input_tokens || cacheCreationInputTokens;
|
|
1031
|
-
cacheReadInputTokens = finalMessage.usage?.cache_read_input_tokens || cacheReadInputTokens;
|
|
1032
|
-
logger.debug('Got usage from finalMessage for non-Anthropic provider (agentic)', {
|
|
1033
|
-
provider: model.provider,
|
|
1034
|
-
inputTokens,
|
|
1035
|
-
outputTokens,
|
|
1036
|
-
cacheCreationInputTokens,
|
|
1037
|
-
cacheReadInputTokens,
|
|
1038
|
-
});
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
catch (finalMessageError) {
|
|
1042
|
-
// finalMessage() may fail if stream was aborted or errored
|
|
1043
|
-
// Fall back to accumulated usage from events
|
|
1044
|
-
logger.debug('Could not get finalMessage (agentic), using accumulated usage', finalMessageError);
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
else {
|
|
1048
|
-
logger.debug('Using usage from message_start event for Anthropic provider (agentic)', {
|
|
1049
|
-
inputTokens,
|
|
1050
|
-
outputTokens,
|
|
1051
|
-
cacheCreationInputTokens,
|
|
1052
|
-
cacheReadInputTokens,
|
|
1053
|
-
});
|
|
1054
|
-
}
|
|
1055
|
-
// Ensure text content is in contentBlocks
|
|
1056
|
-
if (textContent && !contentBlocks.some(b => b.type === 'text')) {
|
|
1057
|
-
contentBlocks.unshift({
|
|
1058
|
-
type: 'text',
|
|
1059
|
-
text: textContent,
|
|
1060
|
-
});
|
|
1061
|
-
}
|
|
1062
|
-
const usage = {
|
|
1063
|
-
inputTokens,
|
|
1064
|
-
outputTokens,
|
|
1065
|
-
totalTokens: inputTokens + outputTokens,
|
|
1066
|
-
cacheCreationInputTokens,
|
|
1067
|
-
cacheReadInputTokens,
|
|
1068
|
-
};
|
|
1069
|
-
const cost = this.calculateCost(usage, model);
|
|
1070
|
-
// Log the LLM call
|
|
1071
|
-
const requestMessages = messages.map(m => ({
|
|
1072
|
-
role: m.role,
|
|
1073
|
-
content: typeof m.content === 'string' ? m.content : JSON.stringify(m.content),
|
|
1074
|
-
}));
|
|
1075
|
-
await auditLogger.logLLMCall(options.system, requestMessages, textContent + (toolUseBlocks.length > 0 ? `\n[Tool calls: ${toolUseBlocks.map(t => t.name).join(', ')}]` : ''), usage, cost, {
|
|
1076
|
-
model: model.id,
|
|
1077
|
-
maxTokens,
|
|
1078
|
-
temperature: options.temperature ?? DEFAULT_ANTHROPIC_TEMPERATURE,
|
|
1079
|
-
tools: options.tools,
|
|
1080
|
-
});
|
|
1081
|
-
// Track token usage
|
|
1082
|
-
try {
|
|
1083
|
-
const tokenTracker = await getTokenTracker();
|
|
1084
|
-
await tokenTracker.recordUsage(model.id, usage, 'agentic_message');
|
|
1085
|
-
}
|
|
1086
|
-
catch (trackingError) {
|
|
1087
|
-
logger.debug('Failed to track token usage', trackingError);
|
|
1088
|
-
}
|
|
1089
|
-
// Record actual usage against rolling window limits (fire-and-forget)
|
|
1090
|
-
getTokenTracker().then(tt => tt.recordLimitUsage(model.id, usage.totalTokens)).catch(err => {
|
|
1091
|
-
logger.debug('Failed to record rolling window usage', err);
|
|
1092
|
-
});
|
|
1093
|
-
this.eventEmitter.emit('token-update', { usage, cost });
|
|
1094
|
-
// Track usage with Compass (sessionless)
|
|
1095
|
-
try {
|
|
1096
|
-
const credentialStore = await getCredentialStore();
|
|
1097
|
-
const compassApiKey = await credentialStore.getCompassApiKey();
|
|
1098
|
-
if (compassApiKey) {
|
|
1099
|
-
// Calculate cost locally for accurate tracking
|
|
1100
|
-
const calculatedCost = calculateModelCost({
|
|
1101
|
-
modelId: model.id,
|
|
1102
|
-
inputTokens: usage.inputTokens,
|
|
1103
|
-
outputTokens: usage.outputTokens,
|
|
1104
|
-
cacheWriteTokens: usage.cacheCreationInputTokens ?? 0,
|
|
1105
|
-
cacheReadTokens: usage.cacheReadInputTokens ?? 0,
|
|
1106
|
-
provider: model.provider,
|
|
1107
|
-
});
|
|
1108
|
-
const compassAuth = getCompassAuthService();
|
|
1109
|
-
await compassAuth.trackUsage({
|
|
1110
|
-
input_tokens: usage.inputTokens,
|
|
1111
|
-
cache_write_input_tokens: usage.cacheCreationInputTokens ?? 0,
|
|
1112
|
-
cache_read_input_tokens: usage.cacheReadInputTokens ?? 0,
|
|
1113
|
-
output_tokens: usage.outputTokens,
|
|
1114
|
-
provider: model.provider,
|
|
1115
|
-
model: model.id,
|
|
1116
|
-
// Include pre-calculated cost for backend to register
|
|
1117
|
-
cost: calculatedCost ?? undefined,
|
|
1118
|
-
}, compassApiKey);
|
|
1119
|
-
// Record cost in local tracker (use our calculated cost, not backend response)
|
|
1120
|
-
if (calculatedCost) {
|
|
1121
|
-
const costTracker = getCostTracker();
|
|
1122
|
-
costTracker.recordCost(calculatedCost.totalCost, calculatedCost.currency, model.id, model.provider, options.callType || 'conversation', {
|
|
1123
|
-
inputTokens: usage.inputTokens,
|
|
1124
|
-
outputTokens: usage.outputTokens,
|
|
1125
|
-
cacheCreationTokens: usage.cacheCreationInputTokens ?? 0,
|
|
1126
|
-
cacheReadTokens: usage.cacheReadInputTokens ?? 0,
|
|
1127
|
-
});
|
|
1128
|
-
logger.info('Cost tracked', {
|
|
1129
|
-
cost: calculatedCost.totalCost,
|
|
1130
|
-
currency: calculatedCost.currency,
|
|
1131
|
-
callType: options.callType || 'conversation',
|
|
1132
|
-
});
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
catch (trackingError) {
|
|
1137
|
-
logger.debug('Failed to track usage with Compass', trackingError);
|
|
1138
|
-
}
|
|
1139
|
-
return {
|
|
1140
|
-
textContent,
|
|
1141
|
-
toolUseBlocks,
|
|
1142
|
-
stopReason,
|
|
1143
|
-
usage,
|
|
1144
|
-
cost,
|
|
1145
|
-
contentBlocks,
|
|
1146
|
-
};
|
|
1147
|
-
}
|
|
1148
|
-
catch (error) {
|
|
1149
|
-
// Handle abort errors immediately without retry
|
|
1150
|
-
if (error instanceof Error && (error.name === 'AbortError' || error.message.includes('aborted'))) {
|
|
1151
|
-
logger.info('Request aborted by user');
|
|
1152
|
-
throw new Error('Request aborted');
|
|
1153
|
-
}
|
|
1154
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
1155
|
-
if (!this.isRetryableError(error) || attempt >= this.retryConfig.maxRetries) {
|
|
1156
|
-
break;
|
|
1157
|
-
}
|
|
1158
|
-
const delay = this.calculateRetryDelay(attempt);
|
|
1159
|
-
logger.debug(`Retrying agentic request after ${delay}ms (attempt ${attempt + 1}/${this.retryConfig.maxRetries})`);
|
|
1160
|
-
await this.sleep(delay);
|
|
1161
|
-
attempt++;
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
const friendlyMessage = this.getFriendlyErrorMessage(lastError);
|
|
1165
|
-
const errorMessage = friendlyMessage || lastError?.message || 'Unknown error occurred';
|
|
1166
|
-
logger.error('Agentic API request failed after retries', lastError);
|
|
1167
|
-
await auditLogger.logError(errorMessage, lastError);
|
|
1168
|
-
throw new Error(errorMessage);
|
|
1169
|
-
}
|
|
1170
|
-
/**
|
|
1171
|
-
* Tests the API connection by sending a minimal request.
|
|
1172
|
-
* Useful for validating API key and connectivity.
|
|
1173
|
-
*
|
|
1174
|
-
* @returns True if the connection test succeeded, false otherwise
|
|
1175
|
-
*/
|
|
1176
|
-
async testConnection() {
|
|
1177
|
-
if (!this.apiKey) {
|
|
1178
|
-
logger.warn('Cannot test connection: client not initialized');
|
|
1179
|
-
return false;
|
|
1180
|
-
}
|
|
1181
|
-
try {
|
|
1182
|
-
const client = this.getClientForModel(this.currentModel);
|
|
1183
|
-
await client.messages.create({
|
|
1184
|
-
model: this.currentModel,
|
|
1185
|
-
max_tokens: 10,
|
|
1186
|
-
messages: [{ role: 'user', content: 'Hi' }],
|
|
1187
|
-
});
|
|
1188
|
-
logger.debug('Connection test successful');
|
|
1189
|
-
return true;
|
|
1190
|
-
}
|
|
1191
|
-
catch (error) {
|
|
1192
|
-
logger.error('Connection test failed', error);
|
|
1193
|
-
return false;
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
|
-
/**
|
|
1197
|
-
* Validates an API key by attempting to make a test request.
|
|
1198
|
-
*
|
|
1199
|
-
* @param apiKey - The API key to validate
|
|
1200
|
-
* @param model - Optional model to use for validation (determines base URL)
|
|
1201
|
-
* @returns True if the API key is valid, false otherwise
|
|
1202
|
-
*/
|
|
1203
|
-
async validateApiKey(apiKey, model) {
|
|
1204
|
-
try {
|
|
1205
|
-
// Determine base URL based on model
|
|
1206
|
-
let baseURL;
|
|
1207
|
-
let testModel = model || DEFAULT_MODEL;
|
|
1208
|
-
if (model) {
|
|
1209
|
-
const resolvedId = resolveModelId(model);
|
|
1210
|
-
const modelConfig = getModelConfig(resolvedId);
|
|
1211
|
-
if (modelConfig) {
|
|
1212
|
-
baseURL = modelConfig.baseUrl;
|
|
1213
|
-
testModel = modelConfig.id;
|
|
1214
|
-
}
|
|
1215
|
-
else {
|
|
1216
|
-
baseURL = process.env.COMPASS_ANTHROPIC_BASE_URL || 'https://api.anthropic.com';
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
else {
|
|
1220
|
-
baseURL = process.env.COMPASS_ANTHROPIC_BASE_URL || 'https://api.anthropic.com';
|
|
1221
|
-
}
|
|
1222
|
-
const isOllama = baseURL.includes('ollama');
|
|
1223
|
-
const testClient = new Anthropic({
|
|
1224
|
-
apiKey,
|
|
1225
|
-
baseURL,
|
|
1226
|
-
defaultHeaders: isOllama ? { 'Authorization': 'Bearer ' + apiKey } : {}
|
|
1227
|
-
});
|
|
1228
|
-
await testClient.messages.create({
|
|
1229
|
-
model: testModel,
|
|
1230
|
-
max_tokens: 10,
|
|
1231
|
-
messages: [{ role: 'user', content: 'test' }],
|
|
1232
|
-
});
|
|
1233
|
-
return true;
|
|
1234
|
-
}
|
|
1235
|
-
catch (error) {
|
|
1236
|
-
logger.debug('API key validation failed', error);
|
|
1237
|
-
return false;
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
/**
|
|
1241
|
-
* Gets available models with their configurations.
|
|
1242
|
-
*
|
|
1243
|
-
* @returns Array of available ModelConfig objects
|
|
1244
|
-
*/
|
|
1245
|
-
getAvailableModels() {
|
|
1246
|
-
return Object.values(CLAUDE_MODELS);
|
|
1247
|
-
}
|
|
1248
|
-
/**
|
|
1249
|
-
* Estimates the cost for a given token usage with the current model.
|
|
1250
|
-
*
|
|
1251
|
-
* @param usage - Token usage to estimate cost for
|
|
1252
|
-
* @returns Cost estimate in USD
|
|
1253
|
-
*/
|
|
1254
|
-
estimateCost(usage) {
|
|
1255
|
-
return this.calculateCost(usage, this.getCurrentModel());
|
|
1256
|
-
}
|
|
1257
|
-
/**
|
|
1258
|
-
* Calculates the cost for token usage with a specific model.
|
|
1259
|
-
* Uses the centralized cost calculation from cost-tracker.ts which handles
|
|
1260
|
-
* all token types including cache operations.
|
|
1261
|
-
*
|
|
1262
|
-
* @param usage - Token usage statistics
|
|
1263
|
-
* @param model - Model configuration with pricing
|
|
1264
|
-
* @returns Cost estimate breakdown (for backward compatibility with CostEstimate type)
|
|
1265
|
-
*/
|
|
1266
|
-
calculateCost(usage, model) {
|
|
1267
|
-
const calculated = calculateModelCost({
|
|
1268
|
-
modelId: model.id,
|
|
1269
|
-
inputTokens: usage.inputTokens,
|
|
1270
|
-
outputTokens: usage.outputTokens,
|
|
1271
|
-
cacheWriteTokens: usage.cacheCreationInputTokens ?? 0,
|
|
1272
|
-
cacheReadTokens: usage.cacheReadInputTokens ?? 0,
|
|
1273
|
-
provider: model.provider,
|
|
1274
|
-
});
|
|
1275
|
-
if (!calculated) {
|
|
1276
|
-
// Fallback to simple calculation if model not found
|
|
1277
|
-
const inputCost = (usage.inputTokens / 1_000_000) * model.pricing.inputPricePerMillion;
|
|
1278
|
-
const outputCost = (usage.outputTokens / 1_000_000) * model.pricing.outputPricePerMillion;
|
|
1279
|
-
return {
|
|
1280
|
-
inputCost,
|
|
1281
|
-
outputCost,
|
|
1282
|
-
totalCost: inputCost + outputCost,
|
|
1283
|
-
currency: 'USD',
|
|
1284
|
-
};
|
|
1285
|
-
}
|
|
1286
|
-
return {
|
|
1287
|
-
inputCost: calculated.inputCost,
|
|
1288
|
-
outputCost: calculated.outputCost,
|
|
1289
|
-
totalCost: calculated.totalCost,
|
|
1290
|
-
currency: calculated.currency,
|
|
1291
|
-
};
|
|
1292
|
-
}
|
|
1293
|
-
/**
|
|
1294
|
-
* Formats messages for the Anthropic API.
|
|
1295
|
-
*
|
|
1296
|
-
* @param messages - Array of Message objects
|
|
1297
|
-
* @returns Formatted messages for the API
|
|
1298
|
-
*/
|
|
1299
|
-
formatMessages(messages, enableCaching = false) {
|
|
1300
|
-
const formatted = messages.map((m) => ({
|
|
1301
|
-
role: m.role,
|
|
1302
|
-
content: m.content,
|
|
1303
|
-
}));
|
|
1304
|
-
if (!enableCaching || formatted.length < 4) {
|
|
1305
|
-
return formatted;
|
|
1306
|
-
}
|
|
1307
|
-
// Add cache breakpoint at last user message before the final message
|
|
1308
|
-
for (let i = formatted.length - 2; i >= 0; i--) {
|
|
1309
|
-
if (formatted[i].role === 'user') {
|
|
1310
|
-
const msg = formatted[i];
|
|
1311
|
-
if (typeof msg.content === 'string') {
|
|
1312
|
-
formatted[i] = {
|
|
1313
|
-
...msg,
|
|
1314
|
-
content: [{
|
|
1315
|
-
type: 'text',
|
|
1316
|
-
text: msg.content,
|
|
1317
|
-
cache_control: { type: 'ephemeral' },
|
|
1318
|
-
}],
|
|
1319
|
-
};
|
|
1320
|
-
}
|
|
1321
|
-
else if (Array.isArray(msg.content) && msg.content.length > 0) {
|
|
1322
|
-
const blocks = [...msg.content];
|
|
1323
|
-
blocks[blocks.length - 1] = { ...blocks[blocks.length - 1], cache_control: { type: 'ephemeral' } };
|
|
1324
|
-
formatted[i] = { ...msg, content: blocks };
|
|
1325
|
-
}
|
|
1326
|
-
break;
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
return formatted;
|
|
1330
|
-
}
|
|
1331
|
-
/**
|
|
1332
|
-
* Determines if an error is retryable.
|
|
1333
|
-
*
|
|
1334
|
-
* @param error - The error to check
|
|
1335
|
-
* @returns True if the error is retryable
|
|
1336
|
-
*/
|
|
1337
|
-
getFriendlyErrorMessage(error) {
|
|
1338
|
-
if (error instanceof Anthropic.APIError) {
|
|
1339
|
-
if (error.status === 529 || error.status === 503) {
|
|
1340
|
-
return `The model is currently overloaded. Please try again later or switch to a different model.`;
|
|
1341
|
-
}
|
|
1342
|
-
if (error.status === 429) {
|
|
1343
|
-
return `Rate limit exceeded. Please wait a moment and try again, or switch to a different model.`;
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
return null;
|
|
1347
|
-
}
|
|
1348
|
-
isRetryableError(error) {
|
|
1349
|
-
if (error instanceof Anthropic.APIError) {
|
|
1350
|
-
// Retry on rate limits and server errors
|
|
1351
|
-
const retryableStatuses = [429, 500, 502, 503, 504, 529];
|
|
1352
|
-
return retryableStatuses.includes(error.status ?? 0);
|
|
1353
|
-
}
|
|
1354
|
-
// Retry on network errors
|
|
1355
|
-
if (error instanceof Error) {
|
|
1356
|
-
const networkErrors = ['ECONNRESET', 'ETIMEDOUT', 'ECONNREFUSED', 'EPIPE'];
|
|
1357
|
-
return networkErrors.some((code) => error.message.includes(code));
|
|
1358
|
-
}
|
|
1359
|
-
return false;
|
|
1360
|
-
}
|
|
1361
|
-
/**
|
|
1362
|
-
* Calculates retry delay with exponential backoff and jitter.
|
|
1363
|
-
*
|
|
1364
|
-
* @param attempt - Current attempt number (0-indexed)
|
|
1365
|
-
* @returns Delay in milliseconds
|
|
1366
|
-
*/
|
|
1367
|
-
calculateRetryDelay(attempt) {
|
|
1368
|
-
// Exponential backoff: baseDelay * 2^attempt
|
|
1369
|
-
const exponentialDelay = this.retryConfig.baseDelayMs * Math.pow(2, attempt);
|
|
1370
|
-
// Cap at max delay
|
|
1371
|
-
const cappedDelay = Math.min(exponentialDelay, this.retryConfig.maxDelayMs);
|
|
1372
|
-
// Add jitter to prevent thundering herd
|
|
1373
|
-
const jitter = cappedDelay * this.retryConfig.jitterFactor * Math.random();
|
|
1374
|
-
return Math.floor(cappedDelay + jitter);
|
|
1375
|
-
}
|
|
1376
|
-
/**
|
|
1377
|
-
* Sleeps for the specified duration.
|
|
1378
|
-
*
|
|
1379
|
-
* @param ms - Duration in milliseconds
|
|
1380
|
-
*/
|
|
1381
|
-
sleep(ms) {
|
|
1382
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1383
|
-
}
|
|
1384
|
-
/**
|
|
1385
|
-
* Resets the client state, requiring re-initialization.
|
|
1386
|
-
*/
|
|
1387
|
-
reset() {
|
|
1388
|
-
this.clients.clear();
|
|
1389
|
-
this.apiKey = null;
|
|
1390
|
-
this.providerApiKeys.clear();
|
|
1391
|
-
this.initialized = false;
|
|
1392
|
-
this.currentModel = DEFAULT_MODEL;
|
|
1393
|
-
logger.debug('Anthropic client reset');
|
|
1394
|
-
}
|
|
1395
|
-
/**
|
|
1396
|
-
* Gets the list of providers that have API keys configured.
|
|
1397
|
-
*
|
|
1398
|
-
* @returns Array of provider names with configured API keys
|
|
1399
|
-
*/
|
|
1400
|
-
getConfiguredProviders() {
|
|
1401
|
-
return Array.from(this.providerApiKeys.keys());
|
|
1402
|
-
}
|
|
1403
|
-
/**
|
|
1404
|
-
* Checks if an API key is configured for a specific provider.
|
|
1405
|
-
*
|
|
1406
|
-
* @param provider - The provider to check
|
|
1407
|
-
* @returns True if an API key is configured for this provider
|
|
1408
|
-
*/
|
|
1409
|
-
hasApiKeyForProvider(provider) {
|
|
1410
|
-
return this.providerApiKeys.has(provider);
|
|
1411
|
-
}
|
|
1412
|
-
/**
|
|
1413
|
-
* Sets an API key for a specific provider at runtime.
|
|
1414
|
-
* Useful for dynamically adding provider API keys during a session.
|
|
1415
|
-
*
|
|
1416
|
-
* @param provider - The provider name
|
|
1417
|
-
* @param apiKey - The API key to set
|
|
1418
|
-
*/
|
|
1419
|
-
setProviderApiKey(provider, apiKey) {
|
|
1420
|
-
this.providerApiKeys.set(provider, apiKey);
|
|
1421
|
-
logger.info(`Set API key for provider: ${provider}`);
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
// Singleton instance
|
|
1425
|
-
let anthropicClientInstance = null;
|
|
1426
|
-
/**
|
|
1427
|
-
* Gets the singleton AnthropicClient instance.
|
|
1428
|
-
* Creates the instance on first call.
|
|
1429
|
-
*
|
|
1430
|
-
* Note: You must call initialize() on the returned client before making API requests.
|
|
1431
|
-
*
|
|
1432
|
-
* @returns Promise resolving to the AnthropicClient instance
|
|
1433
|
-
*/
|
|
1434
|
-
export async function getAnthropicClient() {
|
|
1435
|
-
if (!anthropicClientInstance) {
|
|
1436
|
-
anthropicClientInstance = new AnthropicClient();
|
|
1437
|
-
}
|
|
1438
|
-
return anthropicClientInstance;
|
|
1439
|
-
}
|
|
1440
|
-
/**
|
|
1441
|
-
* Creates a new AnthropicClient instance with custom configuration.
|
|
1442
|
-
* Use this when you need a separate instance from the singleton.
|
|
1443
|
-
*
|
|
1444
|
-
* @param retryConfig - Optional custom retry configuration
|
|
1445
|
-
* @returns A new AnthropicClient instance
|
|
1446
|
-
*/
|
|
1447
|
-
export function createAnthropicClient(retryConfig) {
|
|
1448
|
-
return new AnthropicClient(retryConfig);
|
|
1449
|
-
}
|
|
1450
|
-
export { AnthropicClient };
|
|
1451
|
-
//# sourceMappingURL=anthropic-client.js.map
|