circuschief 0.1.0
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/package.json +33 -0
- package/packages/server/bin/cli.js +4 -0
- package/packages/server/src/agents/AgentGateway.js +64 -0
- package/packages/server/src/agents/BaseAgent.js +41 -0
- package/packages/server/src/agents/LoggingAgentWrapper.js +73 -0
- package/packages/server/src/agents/adapters/ClaudeCodeAdapter.js +33 -0
- package/packages/server/src/agents/adapters/CodexAdapter.js +26 -0
- package/packages/server/src/agents/types.js +43 -0
- package/packages/server/src/agents/vcr/CassetteStore.js +111 -0
- package/packages/server/src/agents/vcr/VCRAgentAdapter.js +126 -0
- package/packages/server/src/agents/vcr/VCRSummaryWrapper.js +71 -0
- package/packages/server/src/api/canvas-helpers.js +249 -0
- package/packages/server/src/api/canvas-trash-routes.js +205 -0
- package/packages/server/src/api/canvas.js +331 -0
- package/packages/server/src/api/commandButtons.js +312 -0
- package/packages/server/src/api/commands.js +169 -0
- package/packages/server/src/api/filesystem.js +62 -0
- package/packages/server/src/api/git.js +85 -0
- package/packages/server/src/api/index.js +44 -0
- package/packages/server/src/api/kanban.js +342 -0
- package/packages/server/src/api/metrics.js +194 -0
- package/packages/server/src/api/projects-helpers.js +43 -0
- package/packages/server/src/api/projects-session-helpers.js +295 -0
- package/packages/server/src/api/projects.js +384 -0
- package/packages/server/src/api/providers.js +249 -0
- package/packages/server/src/api/quickResponses.js +129 -0
- package/packages/server/src/api/sessions-archive.js +69 -0
- package/packages/server/src/api/sessions-commands.js +220 -0
- package/packages/server/src/api/sessions-conversations.js +168 -0
- package/packages/server/src/api/sessions-draft.js +72 -0
- package/packages/server/src/api/sessions-lifecycle.js +190 -0
- package/packages/server/src/api/sessions-messages.js +141 -0
- package/packages/server/src/api/sessions-notes.js +51 -0
- package/packages/server/src/api/sessions-patch.js +252 -0
- package/packages/server/src/api/sessions-streaming.js +86 -0
- package/packages/server/src/api/sessions.js +269 -0
- package/packages/server/src/api/settings.js +194 -0
- package/packages/server/src/api/templates.js +63 -0
- package/packages/server/src/app.js +51 -0
- package/packages/server/src/database.js +58 -0
- package/packages/server/src/db/AgentCallLogRepository.js +322 -0
- package/packages/server/src/db/AttachmentRepository.js +191 -0
- package/packages/server/src/db/BaseRepository.js +39 -0
- package/packages/server/src/db/CanvasItemRepository.js +315 -0
- package/packages/server/src/db/CommandButtonRepository.js +75 -0
- package/packages/server/src/db/CommandRunRepository.js +219 -0
- package/packages/server/src/db/ConversationRepository.js +379 -0
- package/packages/server/src/db/DatabaseManager.js +91 -0
- package/packages/server/src/db/KanbanBoardRepository.js +92 -0
- package/packages/server/src/db/KanbanCardRepository.js +286 -0
- package/packages/server/src/db/KanbanLaneRepository.js +279 -0
- package/packages/server/src/db/MessageRepository.js +156 -0
- package/packages/server/src/db/ProjectDefaultsRepository.js +173 -0
- package/packages/server/src/db/ProjectRepository.js +110 -0
- package/packages/server/src/db/ProviderRepository.js +307 -0
- package/packages/server/src/db/QuickResponseRepository.js +186 -0
- package/packages/server/src/db/SessionNoteRepository.js +60 -0
- package/packages/server/src/db/SessionRepository.js +314 -0
- package/packages/server/src/db/SessionSummaryRepository.js +200 -0
- package/packages/server/src/db/SessionTemplateRepository.js +171 -0
- package/packages/server/src/db/SettingsRepository.js +211 -0
- package/packages/server/src/db/TodoRepository.js +132 -0
- package/packages/server/src/db/WorkLogRepository.js +122 -0
- package/packages/server/src/db/conversation-helpers.js +119 -0
- package/packages/server/src/db/index.js +100 -0
- package/packages/server/src/db/migrations/canvasItemsMigrations.js +109 -0
- package/packages/server/src/db/migrations/conversationsMigrations.js +183 -0
- package/packages/server/src/db/migrations/index.js +199 -0
- package/packages/server/src/db/migrations/kanbanMigrations.js +99 -0
- package/packages/server/src/db/migrations/migrationUtils.js +55 -0
- package/packages/server/src/db/migrations/miscMigrations.js +242 -0
- package/packages/server/src/db/migrations/projectsMigrations.js +95 -0
- package/packages/server/src/db/migrations/sessionsMigrations.js +282 -0
- package/packages/server/src/db/session-helpers.js +150 -0
- package/packages/server/src/index.js +106 -0
- package/packages/server/src/logger.js +22 -0
- package/packages/server/src/middleware/sessionLookup.js +57 -0
- package/packages/server/src/middleware/upload.js +94 -0
- package/packages/server/src/schema.sql +363 -0
- package/packages/server/src/services/agentCallLogger.js +116 -0
- package/packages/server/src/services/canvasStore.js +56 -0
- package/packages/server/src/services/childSessionContext.js +61 -0
- package/packages/server/src/services/commandRunner.js +422 -0
- package/packages/server/src/services/conversationContext.js +72 -0
- package/packages/server/src/services/diffService.js +172 -0
- package/packages/server/src/services/draftSessionService.js +181 -0
- package/packages/server/src/services/encryption.js +134 -0
- package/packages/server/src/services/ghService.js +169 -0
- package/packages/server/src/services/gitService.js +520 -0
- package/packages/server/src/services/gitSessionSetup.js +48 -0
- package/packages/server/src/services/hookService.js +60 -0
- package/packages/server/src/services/kanbanService.js +262 -0
- package/packages/server/src/services/kanbanTriggers.js +273 -0
- package/packages/server/src/services/nodeSpawnHelper.js +63 -0
- package/packages/server/src/services/prStatusService.js +204 -0
- package/packages/server/src/services/prUrlService.js +224 -0
- package/packages/server/src/services/providerTestService.js +81 -0
- package/packages/server/src/services/scheduleService.js +110 -0
- package/packages/server/src/services/schedulerService.js +281 -0
- package/packages/server/src/services/sessionDuplicator.js +63 -0
- package/packages/server/src/services/sessionErrors.js +173 -0
- package/packages/server/src/services/sessionExecution.js +378 -0
- package/packages/server/src/services/sessionManager.js +356 -0
- package/packages/server/src/services/sessionPrompts.js +427 -0
- package/packages/server/src/services/sessionProvider.js +107 -0
- package/packages/server/src/services/slashCommandDiscovery.js +258 -0
- package/packages/server/src/services/slashCommandPluginDiscovery.js +216 -0
- package/packages/server/src/services/slashCommandService.js +306 -0
- package/packages/server/src/services/streamEventCallbacks.js +170 -0
- package/packages/server/src/services/streamEventHandler.js +488 -0
- package/packages/server/src/services/streamUsageHandler.js +228 -0
- package/packages/server/src/services/summaryBroadcast.js +61 -0
- package/packages/server/src/services/summaryClaudeClient.js +180 -0
- package/packages/server/src/services/summaryPrompts.js +169 -0
- package/packages/server/src/services/summaryService.js +552 -0
- package/packages/server/src/services/summaryStaleCheck.js +35 -0
- package/packages/server/src/services/systemMonitor.js +281 -0
- package/packages/server/src/services/templateTriggerService.js +197 -0
- package/packages/server/src/services/terminalOutput.js +160 -0
- package/packages/server/src/services/todoStore.js +58 -0
- package/packages/server/src/services/usageTracker.js +69 -0
- package/packages/server/src/services/withConcurrencyGuard.js +110 -0
- package/packages/server/src/websocket.js +10 -0
- package/packages/server/src/ws/WebSocketManager.js +240 -0
- package/packages/server/src/ws/index.js +50 -0
- package/packages/shared/package.json +27 -0
- package/packages/shared/src/constants.js +44 -0
- package/packages/shared/src/contracts/canvas.js +25 -0
- package/packages/shared/src/contracts/commandButtons.js +36 -0
- package/packages/shared/src/contracts/kanban.js +142 -0
- package/packages/shared/src/contracts/projects.js +63 -0
- package/packages/shared/src/contracts/providers.js +81 -0
- package/packages/shared/src/contracts/quickResponses.js +44 -0
- package/packages/shared/src/contracts/sessions.js +112 -0
- package/packages/shared/src/contracts/templates.js +51 -0
- package/packages/shared/src/index.js +5 -0
- package/packages/shared/src/protocol.js +76 -0
- package/packages/shared/src/routeParams.js +36 -0
- package/packages/shared/src/types.js +167 -0
- package/packages/shared/src/utils.js +101 -0
- package/packages/web/dist/assets/ActiveSessionsView-BQc76Jc8.js +1 -0
- package/packages/web/dist/assets/ActiveSessionsView-ofSvx-K1.css +1 -0
- package/packages/web/dist/assets/AgentLogsView-CTCjHjsu.js +2 -0
- package/packages/web/dist/assets/AgentLogsView-D90PnQVk.css +1 -0
- package/packages/web/dist/assets/ApiClient-Dbs1H78V.js +1 -0
- package/packages/web/dist/assets/ArchiveConfirmModal-CCxSZ52u.js +1 -0
- package/packages/web/dist/assets/ArchiveConfirmModal-CQZeuYBz.css +1 -0
- package/packages/web/dist/assets/CommandButtonDetailView-CF_-LXpU.js +1 -0
- package/packages/web/dist/assets/CommandButtonDetailView-DBm3rzhw.css +1 -0
- package/packages/web/dist/assets/EffortLevelSelector-BQaQmU2d.css +1 -0
- package/packages/web/dist/assets/EffortLevelSelector-DPofLvm-.js +1 -0
- package/packages/web/dist/assets/GeneralSettingsView-BCf53fpC.css +1 -0
- package/packages/web/dist/assets/GeneralSettingsView-BY1G-Kv8.js +1 -0
- package/packages/web/dist/assets/InterpolationHelp-CgdbNcJB.js +1 -0
- package/packages/web/dist/assets/InterpolationHelp-iNxTxmhs.css +1 -0
- package/packages/web/dist/assets/MarkdownEditor-CqT1U8lo.js +2 -0
- package/packages/web/dist/assets/MarkdownEditor-enuH2yvP.css +1 -0
- package/packages/web/dist/assets/ModelSelector-BBn_Ve0D.js +1 -0
- package/packages/web/dist/assets/ModelSelector-DPPD-92R.css +1 -0
- package/packages/web/dist/assets/NewSessionView-Bo5l49nu.js +3 -0
- package/packages/web/dist/assets/NewSessionView-Byoi1XdQ.css +1 -0
- package/packages/web/dist/assets/PathChooser-BoMGzeg2.css +1 -0
- package/packages/web/dist/assets/PathChooser-Cx9gQ-Qt.js +1 -0
- package/packages/web/dist/assets/ProjectEditView-BFuscj-V.js +1 -0
- package/packages/web/dist/assets/ProjectEditView-DNwBUNRk.css +1 -0
- package/packages/web/dist/assets/ProjectListView-C55H1JHQ.css +1 -0
- package/packages/web/dist/assets/ProjectListView-Dj0jBZ46.js +1 -0
- package/packages/web/dist/assets/ProjectNewView-Brdp-xUu.js +1 -0
- package/packages/web/dist/assets/ProjectNewView-CpgE4R-l.css +1 -0
- package/packages/web/dist/assets/ProvidersView-B_QQF3RM.css +1 -0
- package/packages/web/dist/assets/ProvidersView-Cxc-1skq.js +1 -0
- package/packages/web/dist/assets/QuickResponseSettings-B2eVAtHW.js +1 -0
- package/packages/web/dist/assets/QuickResponseSettings-B8188A1D.css +1 -0
- package/packages/web/dist/assets/QuickResponsesPanel-DIBQFj0W.css +1 -0
- package/packages/web/dist/assets/QuickResponsesPanel-lU8pW2B0.js +1 -0
- package/packages/web/dist/assets/ResizableTextarea-B5nAA0RV.css +1 -0
- package/packages/web/dist/assets/ResizableTextarea-DSy1mWGY.js +1 -0
- package/packages/web/dist/assets/SessionCard-BvjLwVYg.js +1 -0
- package/packages/web/dist/assets/SessionCard-D20G3bX8.css +1 -0
- package/packages/web/dist/assets/SessionDetailView-BQbPg-RJ.js +36 -0
- package/packages/web/dist/assets/SessionDetailView-BrMG4p2-.css +1 -0
- package/packages/web/dist/assets/SessionFormOptions-BgqFR-5f.js +1 -0
- package/packages/web/dist/assets/SessionFormOptions-BuLlDF-7.css +1 -0
- package/packages/web/dist/assets/SessionListView-BAIBtJF7.css +1 -0
- package/packages/web/dist/assets/SessionListView-CYIHI8qF.js +1 -0
- package/packages/web/dist/assets/SessionLogStream-B-FwUMJQ.js +18 -0
- package/packages/web/dist/assets/SessionLogStream-zPUTiGbe.css +1 -0
- package/packages/web/dist/assets/SettingsView-DC8-hTQ-.css +1 -0
- package/packages/web/dist/assets/SettingsView-fZxpiGp7.js +1 -0
- package/packages/web/dist/assets/SlashCommandWizard-BB30cSvo.css +1 -0
- package/packages/web/dist/assets/SlashCommandWizard-BgaOw9W3.js +1 -0
- package/packages/web/dist/assets/SummarySettingsView-DcsmSVJI.css +1 -0
- package/packages/web/dist/assets/SummarySettingsView-eeu1Xq86.js +1 -0
- package/packages/web/dist/assets/TemplateDetailView-DEPKSwDo.js +1 -0
- package/packages/web/dist/assets/TemplateDetailView-DT2m06W7.css +1 -0
- package/packages/web/dist/assets/apl-B4CMkyY2.js +1 -0
- package/packages/web/dist/assets/asciiarmor-Df11BRmG.js +1 -0
- package/packages/web/dist/assets/asn1-EdZsLKOL.js +1 -0
- package/packages/web/dist/assets/asterisk-B-8jnY81.js +1 -0
- package/packages/web/dist/assets/brainfuck-C4LP7Hcl.js +1 -0
- package/packages/web/dist/assets/clike-B9uivgTg.js +1 -0
- package/packages/web/dist/assets/clojure-BMjYHr_A.js +1 -0
- package/packages/web/dist/assets/cmake-BQqOBYOt.js +1 -0
- package/packages/web/dist/assets/cobol-CWcv1MsR.js +1 -0
- package/packages/web/dist/assets/coffeescript-S37ZYGWr.js +1 -0
- package/packages/web/dist/assets/commandButtons-DNSHH8IA.js +4 -0
- package/packages/web/dist/assets/commonlisp-DBKNyK5s.js +1 -0
- package/packages/web/dist/assets/crystal-SjHAIU92.js +1 -0
- package/packages/web/dist/assets/css-BnMrqG3P.js +1 -0
- package/packages/web/dist/assets/cypher-C_CwsFkJ.js +1 -0
- package/packages/web/dist/assets/d-pRatUO7H.js +1 -0
- package/packages/web/dist/assets/diff-DbItnlRl.js +1 -0
- package/packages/web/dist/assets/dockerfile-BKs6k2Af.js +1 -0
- package/packages/web/dist/assets/dtd-DF_7sFjM.js +1 -0
- package/packages/web/dist/assets/dylan-DwRh75JA.js +1 -0
- package/packages/web/dist/assets/ebnf-CDyGwa7X.js +1 -0
- package/packages/web/dist/assets/ecl-Cabwm37j.js +1 -0
- package/packages/web/dist/assets/eiffel-CnydiIhH.js +1 -0
- package/packages/web/dist/assets/elm-vLlmbW-K.js +1 -0
- package/packages/web/dist/assets/erlang-BNw1qcRV.js +1 -0
- package/packages/web/dist/assets/factor-kuTfRLto.js +1 -0
- package/packages/web/dist/assets/fcl-Kvtd6kyn.js +1 -0
- package/packages/web/dist/assets/forth-Ffai-XNe.js +1 -0
- package/packages/web/dist/assets/fortran-DYz_wnZ1.js +1 -0
- package/packages/web/dist/assets/gas-Bneqetm1.js +1 -0
- package/packages/web/dist/assets/gherkin-heZmZLOM.js +1 -0
- package/packages/web/dist/assets/groovy-D9Dt4D0W.js +1 -0
- package/packages/web/dist/assets/haskell-BWDZoCOh.js +1 -0
- package/packages/web/dist/assets/haxe-H-WmDvRZ.js +1 -0
- package/packages/web/dist/assets/http-DBlCnlav.js +1 -0
- package/packages/web/dist/assets/idl-BEugSyMb.js +1 -0
- package/packages/web/dist/assets/index-BZlHgDSz.js +1 -0
- package/packages/web/dist/assets/index-BhWX8AfE.js +2 -0
- package/packages/web/dist/assets/index-Bi3XvF_f.js +1 -0
- package/packages/web/dist/assets/index-BqXoPf_D.js +1 -0
- package/packages/web/dist/assets/index-CAuTOZSD.js +1 -0
- package/packages/web/dist/assets/index-CKYk-fkb.js +1 -0
- package/packages/web/dist/assets/index-CTumW_tV.js +318 -0
- package/packages/web/dist/assets/index-CVOJVSsC.js +82 -0
- package/packages/web/dist/assets/index-CXK2Z3_z.js +1 -0
- package/packages/web/dist/assets/index-CYllQ3Vd.js +1 -0
- package/packages/web/dist/assets/index-CpsfI08O.js +1 -0
- package/packages/web/dist/assets/index-DQkhDeTA.js +3 -0
- package/packages/web/dist/assets/index-DWP8iCBp.js +1 -0
- package/packages/web/dist/assets/index-DkVb9W_J.js +1 -0
- package/packages/web/dist/assets/index-DmKHPbIa.js +1 -0
- package/packages/web/dist/assets/index-DrlQi03X.js +1 -0
- package/packages/web/dist/assets/index-gmCCsCQ1.css +1 -0
- package/packages/web/dist/assets/index-prTEzzgO.js +1 -0
- package/packages/web/dist/assets/index-wqgejMCM.js +1 -0
- package/packages/web/dist/assets/index-yh0ZHIWw.js +7 -0
- package/packages/web/dist/assets/javascript-qCveANmP.js +1 -0
- package/packages/web/dist/assets/julia-DuME0IfC.js +1 -0
- package/packages/web/dist/assets/livescript-BwQOo05w.js +1 -0
- package/packages/web/dist/assets/lua-BgMRiT3U.js +1 -0
- package/packages/web/dist/assets/mathematica-DTrFuWx2.js +1 -0
- package/packages/web/dist/assets/mbox-CNhZ1qSd.js +1 -0
- package/packages/web/dist/assets/mirc-CjQqDB4T.js +1 -0
- package/packages/web/dist/assets/mllike-CXdrOF99.js +1 -0
- package/packages/web/dist/assets/modelica-Dc1JOy9r.js +1 -0
- package/packages/web/dist/assets/mscgen-BA5vi2Kp.js +1 -0
- package/packages/web/dist/assets/mumps-BT43cFF4.js +1 -0
- package/packages/web/dist/assets/nginx-DdIZxoE0.js +1 -0
- package/packages/web/dist/assets/nsis-LdVXkNf5.js +1 -0
- package/packages/web/dist/assets/ntriples-BfvgReVJ.js +1 -0
- package/packages/web/dist/assets/octave-Ck1zUtKM.js +1 -0
- package/packages/web/dist/assets/oz-BzwKVEFT.js +1 -0
- package/packages/web/dist/assets/pascal--L3eBynH.js +1 -0
- package/packages/web/dist/assets/perl-CdXCOZ3F.js +1 -0
- package/packages/web/dist/assets/pig-CevX1Tat.js +1 -0
- package/packages/web/dist/assets/powershell-CFHJl5sT.js +1 -0
- package/packages/web/dist/assets/projects-DbBQQH-V.js +1 -0
- package/packages/web/dist/assets/properties-C78fOPTZ.js +1 -0
- package/packages/web/dist/assets/protobuf-ChK-085T.js +1 -0
- package/packages/web/dist/assets/providers-ceCc4xRU.js +1 -0
- package/packages/web/dist/assets/pug-DukmZTjD.js +1 -0
- package/packages/web/dist/assets/puppet-DMA9R1ak.js +1 -0
- package/packages/web/dist/assets/python-BuPzkPfP.js +1 -0
- package/packages/web/dist/assets/q-pXgVlZs6.js +1 -0
- package/packages/web/dist/assets/r-DUYO_cvP.js +1 -0
- package/packages/web/dist/assets/rpm-CTu-6PCP.js +1 -0
- package/packages/web/dist/assets/ruby-B2Rjki9n.js +1 -0
- package/packages/web/dist/assets/sas-B4kiWyti.js +1 -0
- package/packages/web/dist/assets/scheme-C41bIUwD.js +1 -0
- package/packages/web/dist/assets/sessions-D681M81k.js +1 -0
- package/packages/web/dist/assets/settings-D0evez2V.js +1 -0
- package/packages/web/dist/assets/shell-CjFT_Tl9.js +1 -0
- package/packages/web/dist/assets/sieve-C3Gn_uJK.js +1 -0
- package/packages/web/dist/assets/simple-mode-GW_nhZxv.js +1 -0
- package/packages/web/dist/assets/smalltalk-CnHTOXQT.js +1 -0
- package/packages/web/dist/assets/solr-DehyRSwq.js +1 -0
- package/packages/web/dist/assets/sparql-DkYu6x3z.js +1 -0
- package/packages/web/dist/assets/spreadsheet-BCZA_wO0.js +1 -0
- package/packages/web/dist/assets/sql-D0XecflT.js +1 -0
- package/packages/web/dist/assets/stex-C3f8Ysf7.js +1 -0
- package/packages/web/dist/assets/style-BTin-zR_.css +1 -0
- package/packages/web/dist/assets/stylus-B533Al4x.js +1 -0
- package/packages/web/dist/assets/swift-BzpIVaGY.js +1 -0
- package/packages/web/dist/assets/tcl-DVfN8rqt.js +1 -0
- package/packages/web/dist/assets/textile-CnDTJFAw.js +1 -0
- package/packages/web/dist/assets/tiddlywiki-DO-Gjzrf.js +1 -0
- package/packages/web/dist/assets/tiki-DGYXhP31.js +1 -0
- package/packages/web/dist/assets/toml-Bm5Em-hy.js +1 -0
- package/packages/web/dist/assets/troff-wAsdV37c.js +1 -0
- package/packages/web/dist/assets/ttcn-CfJYG6tj.js +1 -0
- package/packages/web/dist/assets/ttcn-cfg-B9xdYoR4.js +1 -0
- package/packages/web/dist/assets/turtle-B1tBg_DP.js +1 -0
- package/packages/web/dist/assets/vb-CmGdzxic.js +1 -0
- package/packages/web/dist/assets/vbscript-BuJXcnF6.js +1 -0
- package/packages/web/dist/assets/velocity-D8B20fx6.js +1 -0
- package/packages/web/dist/assets/verilog-C6RDOZhf.js +1 -0
- package/packages/web/dist/assets/vhdl-lSbBsy5d.js +1 -0
- package/packages/web/dist/assets/webidl-ZXfAyPTL.js +1 -0
- package/packages/web/dist/assets/xquery-CQfU5ijd.js +1 -0
- package/packages/web/dist/assets/yacas-BJ4BC0dw.js +1 -0
- package/packages/web/dist/assets/z80-Hz9HOZM7.js +1 -0
- package/packages/web/dist/favicon.png +0 -0
- package/packages/web/dist/index.html +17 -0
- package/packages/web/dist/logo.png +0 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import { sessions, attachments, projects, kanbanBoards, kanbanLanes } from '../database.js';
|
|
2
|
+
import { DEFAULT_SERVER_PORT, DEFAULT_SYSTEM_PROMPT } from '../../../shared/src/index.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get the base API URL for canvas and session operations.
|
|
6
|
+
* Uses CIRCUSCHIEF_API_URL environment variable if set, otherwise constructs
|
|
7
|
+
* from the runtime port to ensure dynamic port handling.
|
|
8
|
+
* @returns {string} The base API URL (e.g., http://localhost:5000)
|
|
9
|
+
*/
|
|
10
|
+
export function getApiBaseUrl() {
|
|
11
|
+
return process.env.CIRCUSCHIEF_API_URL || `http://localhost:${process.env.PORT || DEFAULT_SERVER_PORT}`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Build prompt with file attachment context for the current turn
|
|
16
|
+
* Includes text file contents inline, describes other file types
|
|
17
|
+
* @param {string} prompt - Original prompt
|
|
18
|
+
* @param {Array} fileAttachments - Array of attachment objects
|
|
19
|
+
* @returns {string} Prompt with file context
|
|
20
|
+
*/
|
|
21
|
+
export function buildPromptWithAttachments(prompt, fileAttachments) {
|
|
22
|
+
if (!fileAttachments || fileAttachments.length === 0) {
|
|
23
|
+
return prompt;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const attachmentSections = fileAttachments.map((att) => {
|
|
27
|
+
// Check if it's a text-based file that can be included inline
|
|
28
|
+
const isTextFile =
|
|
29
|
+
att.mimeType.startsWith('text/') ||
|
|
30
|
+
att.mimeType === 'application/json' ||
|
|
31
|
+
att.mimeType === 'application/javascript' ||
|
|
32
|
+
att.mimeType === 'application/xml' ||
|
|
33
|
+
att.mimeType === 'application/x-yaml' ||
|
|
34
|
+
att.mimeType === 'application/x-sh';
|
|
35
|
+
|
|
36
|
+
if (isTextFile && att.content) {
|
|
37
|
+
try {
|
|
38
|
+
const textContent = Buffer.from(att.content, 'base64').toString('utf-8');
|
|
39
|
+
return `\n--- File: ${att.filename} (${att.mimeType}) ---\n${textContent}\n--- End of ${att.filename} ---`;
|
|
40
|
+
} catch {
|
|
41
|
+
return `\n[Attached file: ${att.filename} (${att.mimeType}, ${att.size} bytes) - could not decode]`;
|
|
42
|
+
}
|
|
43
|
+
} else if (att.mimeType.startsWith('image/')) {
|
|
44
|
+
return `\n[Attached image: ${att.filename} (${att.mimeType}, ${att.size} bytes)]`;
|
|
45
|
+
} else if (att.mimeType === 'application/pdf') {
|
|
46
|
+
return `\n[Attached PDF: ${att.filename} (${att.size} bytes)]`;
|
|
47
|
+
} else {
|
|
48
|
+
return `\n[Attached file: ${att.filename} (${att.mimeType}, ${att.size} bytes)]`;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return `${prompt}\n\n## Attached Files${attachmentSections.join('\n')}`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Format file size in human-readable format
|
|
57
|
+
* @param {number} bytes - Size in bytes
|
|
58
|
+
* @returns {string} Formatted size
|
|
59
|
+
*/
|
|
60
|
+
function formatFileSize(bytes) {
|
|
61
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
62
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
63
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get session attachments context for system prompt
|
|
68
|
+
* Returns a string describing all files attached to the session that Claude can read
|
|
69
|
+
* @param {string} sessionId - Session ID
|
|
70
|
+
* @returns {string} Attachments context for system prompt
|
|
71
|
+
*/
|
|
72
|
+
export function getSessionAttachmentsContext(sessionId) {
|
|
73
|
+
const sessionAttachments = attachments.getBySessionId(sessionId);
|
|
74
|
+
|
|
75
|
+
// Only include attachments that have been saved to disk
|
|
76
|
+
const readableAttachments = sessionAttachments.filter((att) => att.filePath);
|
|
77
|
+
|
|
78
|
+
if (readableAttachments.length === 0) {
|
|
79
|
+
return '';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const fileList = readableAttachments
|
|
83
|
+
.map((att) => `- \`${att.filePath}\` (${att.filename}, ${att.mimeType}, ${formatFileSize(att.size)})`)
|
|
84
|
+
.join('\n');
|
|
85
|
+
|
|
86
|
+
return `## Session Attached Files
|
|
87
|
+
|
|
88
|
+
The user has attached the following files to this session. You can read these files at any time using your Read tool:
|
|
89
|
+
|
|
90
|
+
${fileList}
|
|
91
|
+
|
|
92
|
+
These files persist throughout the conversation. When the user asks about attached files, use the Read tool with the file paths above.`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Map session mode to SDK permissionMode
|
|
97
|
+
* @param {string} mode - Session mode ('plan', 'standard', 'yolo')
|
|
98
|
+
* @returns {string} SDK permissionMode value
|
|
99
|
+
*/
|
|
100
|
+
export function getPermissionModeForSession(mode) {
|
|
101
|
+
switch (mode) {
|
|
102
|
+
case 'yolo':
|
|
103
|
+
return 'bypassPermissions';
|
|
104
|
+
case 'plan':
|
|
105
|
+
case 'standard':
|
|
106
|
+
default:
|
|
107
|
+
return 'default';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Plan mode system prompt instructions */
|
|
112
|
+
export const PLAN_MODE_PROMPT = `## Plan Mode Active
|
|
113
|
+
|
|
114
|
+
You are in PLAN mode. Before implementing any changes:
|
|
115
|
+
|
|
116
|
+
1. **Analyze the Request**: Understand what the user is asking for
|
|
117
|
+
2. **Create a Plan**: Write a detailed implementation plan to a file:
|
|
118
|
+
- Write your plan to: \`~/.claude/plans/<descriptive-name>.md\`
|
|
119
|
+
- Create the file using the Write tool
|
|
120
|
+
- Include in your plan:
|
|
121
|
+
- Files that need to be created or modified
|
|
122
|
+
- Order of changes
|
|
123
|
+
- Key implementation decisions
|
|
124
|
+
- Potential risks or edge cases
|
|
125
|
+
3. **Get Approval**: Present the plan to the user by putting it on the canvas and wait for user approval before proceeding
|
|
126
|
+
4. **Implement**: Only after approval, implement the changes step by step
|
|
127
|
+
|
|
128
|
+
CRITICAL: Do NOT start coding until you have presented a plan and received approval. Always write the plan file to \`~/.claude/plans/\` directory.
|
|
129
|
+
|
|
130
|
+
`;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Build system prompt with canvas write instructions
|
|
134
|
+
* @param {object|null} session - Session object
|
|
135
|
+
* @returns {string}
|
|
136
|
+
*/
|
|
137
|
+
function buildCanvasWriteSystemPrompt(session) {
|
|
138
|
+
const apiUrl = getApiBaseUrl();
|
|
139
|
+
// Use root session ID, fall back to session.id if getRootSessionId returns null, fall back to 'unknown-session' if session is null
|
|
140
|
+
const sessionId = session
|
|
141
|
+
? (sessions.getRootSessionId(session.id) || session.id)
|
|
142
|
+
: 'unknown-session';
|
|
143
|
+
return `When you generate artifacts that should be displayed on the canvas (images, markdown documents, code snippets, data visualizations, PDFs), POST them to:
|
|
144
|
+
|
|
145
|
+
POST ${apiUrl}/api/sessions/${sessionId}/canvas
|
|
146
|
+
Body: {"filePath": "/path/to/file"}
|
|
147
|
+
|
|
148
|
+
The file type is automatically detected from the file extension. Supported formats:
|
|
149
|
+
- Images: .png, .jpg, .jpeg, .gif, .webp, .svg, .bmp
|
|
150
|
+
- PDFs: .pdf
|
|
151
|
+
- Markdown: .md, .mdx
|
|
152
|
+
- Code: .js, .ts, .py, .go, .rs, .java, etc.
|
|
153
|
+
- JSON: .json
|
|
154
|
+
- Text: .txt, .log, .csv`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Build system prompt with canvas read instructions
|
|
159
|
+
* @param {object|null} session - Session object
|
|
160
|
+
* @returns {string}
|
|
161
|
+
*/
|
|
162
|
+
function buildCanvasReadSystemPrompt(session) {
|
|
163
|
+
const apiUrl = getApiBaseUrl();
|
|
164
|
+
// Use root session ID, fall back to session.id if getRootSessionId returns null, fall back to 'unknown-session' if session is null
|
|
165
|
+
const sessionId = session
|
|
166
|
+
? (sessions.getRootSessionId(session.id) || session.id)
|
|
167
|
+
: 'unknown-session';
|
|
168
|
+
return `## Reading from Canvas
|
|
169
|
+
|
|
170
|
+
To list all files on the canvas:
|
|
171
|
+
\`\`\`bash
|
|
172
|
+
curl ${apiUrl}/api/sessions/${sessionId}/canvas
|
|
173
|
+
\`\`\`
|
|
174
|
+
|
|
175
|
+
To read a specific file from the canvas (returns file path for Read tool):
|
|
176
|
+
\`\`\`bash
|
|
177
|
+
curl ${apiUrl}/api/sessions/${sessionId}/canvas/file/{filename}
|
|
178
|
+
\`\`\`
|
|
179
|
+
|
|
180
|
+
Response: { filePath, type, mimeType, createdAt, version, totalVersions }
|
|
181
|
+
|
|
182
|
+
Then use the Read tool on the returned filePath to view the content.
|
|
183
|
+
|
|
184
|
+
Supported types: images, PDFs, markdown, text, JSON
|
|
185
|
+
|
|
186
|
+
### Accessing Historical Versions
|
|
187
|
+
|
|
188
|
+
If you need to access an earlier version of a file:
|
|
189
|
+
\`\`\`bash
|
|
190
|
+
curl ${apiUrl}/api/sessions/${sessionId}/canvas/file/{filename}/history/{version}
|
|
191
|
+
\`\`\`
|
|
192
|
+
|
|
193
|
+
Where version 1 = oldest, and higher numbers are newer versions.`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** Build session CRUD operations section */
|
|
197
|
+
function buildSessionCrudOps(apiUrl, projectId) {
|
|
198
|
+
return `### Create a New Session
|
|
199
|
+
\`\`\`bash
|
|
200
|
+
curl -X POST ${apiUrl}/api/projects/${projectId}/sessions \\
|
|
201
|
+
-H "Content-Type: application/json" \\
|
|
202
|
+
-d '{"prompt": "Your task description here", "name": "Optional session name"}'
|
|
203
|
+
\`\`\`
|
|
204
|
+
Optional fields: \`name\`, \`mode\`, \`thinkingEnabled\` (boolean), \`effortLevel\` (low/medium/high/max/auto), \`gitBranch\`, \`gitMode\`, \`parentSessionId\` (to create a child session)
|
|
205
|
+
|
|
206
|
+
### Send a Follow-up Message
|
|
207
|
+
\`\`\`bash
|
|
208
|
+
curl -X POST ${apiUrl}/api/sessions/<session_id>/message \\
|
|
209
|
+
-H "Content-Type: application/json" \\
|
|
210
|
+
-d '{"content": "Your follow-up message"}'
|
|
211
|
+
\`\`\`
|
|
212
|
+
|
|
213
|
+
### List All Active Sessions / Get Session Details / Get Messages
|
|
214
|
+
\`\`\`bash
|
|
215
|
+
curl ${apiUrl}/api/sessions
|
|
216
|
+
curl ${apiUrl}/api/sessions/<session_id>
|
|
217
|
+
curl ${apiUrl}/api/sessions/<session_id>/messages
|
|
218
|
+
\`\`\`
|
|
219
|
+
|
|
220
|
+
### Stop / Restart / Delete a Session
|
|
221
|
+
\`\`\`bash
|
|
222
|
+
curl -X POST ${apiUrl}/api/sessions/<session_id>/stop
|
|
223
|
+
curl -X POST ${apiUrl}/api/sessions/<session_id>/restart
|
|
224
|
+
curl -X DELETE ${apiUrl}/api/sessions/<session_id>
|
|
225
|
+
\`\`\`
|
|
226
|
+
|
|
227
|
+
### Update Session Settings
|
|
228
|
+
\`\`\`bash
|
|
229
|
+
curl -X PATCH ${apiUrl}/api/sessions/<session_id> \\
|
|
230
|
+
-H "Content-Type: application/json" \\
|
|
231
|
+
-d '{"thinkingEnabled": true, "effortLevel": "high"}'
|
|
232
|
+
\`\`\``;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** Build project, notes, and summary operations section */
|
|
236
|
+
function buildProjectNotesOps(apiUrl) {
|
|
237
|
+
return `### Project Operations
|
|
238
|
+
\`\`\`bash
|
|
239
|
+
curl ${apiUrl}/api/projects # List all projects
|
|
240
|
+
curl ${apiUrl}/api/projects/<project_id> # Get project details
|
|
241
|
+
curl ${apiUrl}/api/projects/<project_id>/sessions # List project sessions
|
|
242
|
+
curl -X POST ${apiUrl}/api/projects \\
|
|
243
|
+
-H "Content-Type: application/json" \\
|
|
244
|
+
-d '{"name": "Project Name", "workingDirectory": "/path/to/directory"}'
|
|
245
|
+
\`\`\`
|
|
246
|
+
Optional field: \`systemPrompt\`
|
|
247
|
+
|
|
248
|
+
### Session Notes
|
|
249
|
+
\`\`\`bash
|
|
250
|
+
curl ${apiUrl}/api/sessions/<session_id>/notes # Get notes
|
|
251
|
+
curl -X POST ${apiUrl}/api/sessions/<session_id>/notes \\
|
|
252
|
+
-H "Content-Type: application/json" \\
|
|
253
|
+
-d '{"content": "Note content"}'
|
|
254
|
+
\`\`\`
|
|
255
|
+
|
|
256
|
+
### Session Summary
|
|
257
|
+
\`\`\`bash
|
|
258
|
+
curl "${apiUrl}/api/sessions/<session_id>/summary?generate=true"
|
|
259
|
+
curl -X POST ${apiUrl}/api/sessions/<session_id>/summary # Regenerate
|
|
260
|
+
\`\`\``;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/** Build session API instructions for Claude to create/modify sessions */
|
|
264
|
+
function buildSessionApiInstructions(sessionId, projectId) {
|
|
265
|
+
const apiUrl = getApiBaseUrl();
|
|
266
|
+
return `## Session Management API
|
|
267
|
+
|
|
268
|
+
You can create and modify sessions in this system using curl or similar HTTP tools. Use the Bash tool to execute these commands.
|
|
269
|
+
|
|
270
|
+
**Base URL:** ${apiUrl}
|
|
271
|
+
**Current Session ID:** ${sessionId}
|
|
272
|
+
**Current Project ID:** ${projectId}
|
|
273
|
+
|
|
274
|
+
${buildSessionCrudOps(apiUrl, projectId)}
|
|
275
|
+
|
|
276
|
+
${buildProjectNotesOps(apiUrl)}`;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Build Kanban API instructions for system prompt if Kanban is enabled for the project
|
|
281
|
+
* @param {string} sessionId - Current session ID
|
|
282
|
+
* @param {string} projectId - Current project ID
|
|
283
|
+
* @returns {string} Kanban instructions or empty string if disabled
|
|
284
|
+
*/
|
|
285
|
+
function buildKanbanApiInstructions(sessionId, projectId) {
|
|
286
|
+
const project = projects.getById(projectId);
|
|
287
|
+
if (!project || !project.kanbanEnabled) {
|
|
288
|
+
return '';
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const apiUrl = getApiBaseUrl();
|
|
292
|
+
const board = kanbanBoards.getByProjectId(projectId);
|
|
293
|
+
|
|
294
|
+
// Get lane names for context
|
|
295
|
+
let laneContext = '';
|
|
296
|
+
if (board) {
|
|
297
|
+
const lanes = kanbanLanes.getByBoardId(board.id);
|
|
298
|
+
if (lanes && lanes.length > 0) {
|
|
299
|
+
const laneList = lanes.map((l) => ` - "${l.name}" (ID: ${l.id})`).join('\n');
|
|
300
|
+
laneContext = `\n### Available Lanes\n${laneList}\n`;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return `## Kanban Board API
|
|
305
|
+
|
|
306
|
+
This project has a Kanban board enabled for organizing sessions visually. You can manage the board using these API endpoints.
|
|
307
|
+
${laneContext}
|
|
308
|
+
### Get Board with All Lanes and Cards
|
|
309
|
+
\`\`\`bash
|
|
310
|
+
curl ${apiUrl}/api/projects/${projectId}/kanban
|
|
311
|
+
\`\`\`
|
|
312
|
+
|
|
313
|
+
### Add This Session to the Board
|
|
314
|
+
\`\`\`bash
|
|
315
|
+
curl -X POST ${apiUrl}/api/projects/${projectId}/kanban/cards \\
|
|
316
|
+
-H "Content-Type: application/json" \\
|
|
317
|
+
-d '{"sessionId": "${sessionId}", "laneId": "<lane_id>"}'
|
|
318
|
+
\`\`\`
|
|
319
|
+
|
|
320
|
+
### Move a Card to a Different Lane
|
|
321
|
+
\`\`\`bash
|
|
322
|
+
curl -X PATCH ${apiUrl}/api/projects/${projectId}/kanban/cards/<card_id>/move \\
|
|
323
|
+
-H "Content-Type: application/json" \\
|
|
324
|
+
-d '{"targetLaneId": "<lane_id>"}'
|
|
325
|
+
\`\`\`
|
|
326
|
+
|
|
327
|
+
### Remove a Card from the Board
|
|
328
|
+
\`\`\`bash
|
|
329
|
+
curl -X DELETE ${apiUrl}/api/projects/${projectId}/kanban/cards/<card_id>
|
|
330
|
+
\`\`\`
|
|
331
|
+
|
|
332
|
+
### Create a New Lane
|
|
333
|
+
\`\`\`bash
|
|
334
|
+
curl -X POST ${apiUrl}/api/projects/${projectId}/kanban/lanes \\
|
|
335
|
+
-H "Content-Type: application/json" \\
|
|
336
|
+
-d '{"name": "Lane Name"}'
|
|
337
|
+
\`\`\`
|
|
338
|
+
|
|
339
|
+
### Update a Lane
|
|
340
|
+
\`\`\`bash
|
|
341
|
+
curl -X PATCH ${apiUrl}/api/projects/${projectId}/kanban/lanes/<lane_id> \\
|
|
342
|
+
-H "Content-Type: application/json" \\
|
|
343
|
+
-d '{"name": "New Name"}'
|
|
344
|
+
\`\`\`
|
|
345
|
+
|
|
346
|
+
### Delete a Lane
|
|
347
|
+
\`\`\`bash
|
|
348
|
+
curl -X DELETE ${apiUrl}/api/projects/${projectId}/kanban/lanes/<lane_id>
|
|
349
|
+
\`\`\``;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Build worktree context for system prompt if session uses git worktree
|
|
354
|
+
* @param {Object} session - Session object
|
|
355
|
+
* @returns {string} Worktree context or empty string
|
|
356
|
+
*/
|
|
357
|
+
function buildWorktreeContext(session) {
|
|
358
|
+
if (!session || !session.gitWorktree) {
|
|
359
|
+
return '';
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return `## Git Worktree Session
|
|
363
|
+
|
|
364
|
+
This session is running in an isolated git worktree:
|
|
365
|
+
- Worktree path: ${session.gitWorktree}
|
|
366
|
+
- Branch: ${session.gitBranch || 'unknown'}
|
|
367
|
+
|
|
368
|
+
CRITICAL: Do NOT use \`cd\` to navigate to the main repository. Your working directory is already set to the worktree. Running \`cd /home/ubuntu/workspace/circus-chief && ...\` will escape the worktree isolation and affect the main repository instead.`;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Build child session context for system prompt
|
|
373
|
+
* @param {Object} session - Session object
|
|
374
|
+
* @returns {string} Child session context or empty string
|
|
375
|
+
*/
|
|
376
|
+
function buildChildSessionContext(session) {
|
|
377
|
+
if (!session || !session.parentSessionId) {
|
|
378
|
+
return '';
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Get root session ID using existing method
|
|
382
|
+
const rootSessionId = sessions.getRootSessionId(session.id);
|
|
383
|
+
|
|
384
|
+
return `## Child Session
|
|
385
|
+
|
|
386
|
+
This session is part of a multi-session workflow:
|
|
387
|
+
- Parent Session ID: ${session.parentSessionId}
|
|
388
|
+
- Root Session ID: ${rootSessionId}`;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Build the full system prompt configuration
|
|
393
|
+
* @param {string} sessionId
|
|
394
|
+
* @param {string} projectId
|
|
395
|
+
* @param {string|null} customSystemPrompt - Custom system prompt from project settings
|
|
396
|
+
* @param {string} mode - Session mode ('plan', 'standard', 'yolo')
|
|
397
|
+
* @returns {string} System prompt string
|
|
398
|
+
*/
|
|
399
|
+
export function buildSystemPromptConfig(sessionId, projectId, customSystemPrompt, mode) {
|
|
400
|
+
const session = sessions.getById(sessionId);
|
|
401
|
+
const canvasWriteInstructions = buildCanvasWriteSystemPrompt(session); // Pass session object
|
|
402
|
+
const canvasReadInstructions = buildCanvasReadSystemPrompt(session); // Pass session object
|
|
403
|
+
const sessionApiInstructions = buildSessionApiInstructions(sessionId, projectId);
|
|
404
|
+
const kanbanApiInstructions = buildKanbanApiInstructions(sessionId, projectId);
|
|
405
|
+
const attachmentsContext = getSessionAttachmentsContext(sessionId);
|
|
406
|
+
const worktreeContext = buildWorktreeContext(session);
|
|
407
|
+
const childSessionContext = buildChildSessionContext(session);
|
|
408
|
+
const basePrompt = customSystemPrompt || DEFAULT_SYSTEM_PROMPT;
|
|
409
|
+
|
|
410
|
+
// Prepend plan mode instructions if in plan mode
|
|
411
|
+
const modePrompt = mode === 'plan' ? PLAN_MODE_PROMPT : '';
|
|
412
|
+
|
|
413
|
+
// Build prompt parts, filtering out empty sections
|
|
414
|
+
const parts = [
|
|
415
|
+
modePrompt,
|
|
416
|
+
basePrompt,
|
|
417
|
+
childSessionContext,
|
|
418
|
+
worktreeContext,
|
|
419
|
+
attachmentsContext,
|
|
420
|
+
canvasWriteInstructions,
|
|
421
|
+
canvasReadInstructions,
|
|
422
|
+
sessionApiInstructions,
|
|
423
|
+
kanbanApiInstructions
|
|
424
|
+
].filter(Boolean);
|
|
425
|
+
|
|
426
|
+
return parts.join('\n\n');
|
|
427
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { modelProviders } from '../database.js';
|
|
2
|
+
import { createRobustEnv } from './nodeSpawnHelper.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the provider for a given model ID
|
|
6
|
+
* Looks up which provider owns the model, or returns null for Anthropic defaults
|
|
7
|
+
* @param {string|null} modelId - The model ID to look up
|
|
8
|
+
* @returns {Object|null} Provider object or null if using Anthropic default
|
|
9
|
+
*/
|
|
10
|
+
export function resolveProviderFromModel(modelId) {
|
|
11
|
+
return modelProviders.getProviderByModelId(modelId);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Build environment variables from provider configuration
|
|
16
|
+
* @param {Object|null} provider - Provider object
|
|
17
|
+
* @returns {Object} Environment variables to add to session env
|
|
18
|
+
*/
|
|
19
|
+
export function buildProviderEnv(provider) {
|
|
20
|
+
if (!provider) {
|
|
21
|
+
console.log('[SessionManager] buildProviderEnv: No provider, using SDK defaults');
|
|
22
|
+
return {}; // Use SDK defaults
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const env = {};
|
|
26
|
+
|
|
27
|
+
if (provider.baseUrl) {
|
|
28
|
+
env.ANTHROPIC_BASE_URL = provider.baseUrl;
|
|
29
|
+
}
|
|
30
|
+
if (provider.authToken) {
|
|
31
|
+
// Set BOTH ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN
|
|
32
|
+
// The SDK prioritizes ANTHROPIC_API_KEY, so we must set it to override
|
|
33
|
+
// any user's existing ANTHROPIC_API_KEY in their environment
|
|
34
|
+
env.ANTHROPIC_API_KEY = provider.authToken;
|
|
35
|
+
env.ANTHROPIC_AUTH_TOKEN = provider.authToken;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Derive default model env vars from provider_models by tier (single source of truth)
|
|
39
|
+
if (Array.isArray(provider.models)) {
|
|
40
|
+
const opusModel = provider.models.find((m) => m.tier === 'opus');
|
|
41
|
+
if (opusModel) env.ANTHROPIC_DEFAULT_OPUS_MODEL = opusModel.modelId;
|
|
42
|
+
|
|
43
|
+
const sonnetModel = provider.models.find((m) => m.tier === 'sonnet');
|
|
44
|
+
if (sonnetModel) env.ANTHROPIC_DEFAULT_SONNET_MODEL = sonnetModel.modelId;
|
|
45
|
+
|
|
46
|
+
const haikuModel = provider.models.find((m) => m.tier === 'haiku');
|
|
47
|
+
if (haikuModel) env.ANTHROPIC_DEFAULT_HAIKU_MODEL = haikuModel.modelId;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (provider.apiTimeoutMs) {
|
|
51
|
+
env.API_TIMEOUT_MS = String(provider.apiTimeoutMs);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Parse additional env vars
|
|
55
|
+
if (provider.additionalEnvVars) {
|
|
56
|
+
Object.assign(env, provider.additionalEnvVars);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log(`[SessionManager] buildProviderEnv: Provider "${provider.name}" env vars:`, {
|
|
60
|
+
ANTHROPIC_BASE_URL: env.ANTHROPIC_BASE_URL,
|
|
61
|
+
ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY ? '[SET]' : '[NOT SET]',
|
|
62
|
+
ANTHROPIC_AUTH_TOKEN: env.ANTHROPIC_AUTH_TOKEN ? '[SET]' : '[NOT SET]',
|
|
63
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: env.ANTHROPIC_DEFAULT_SONNET_MODEL,
|
|
64
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: env.ANTHROPIC_DEFAULT_OPUS_MODEL,
|
|
65
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: env.ANTHROPIC_DEFAULT_HAIKU_MODEL,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return env;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Build environment variables for Claude SDK based on provider and session settings.
|
|
73
|
+
* Always returns a robust env with Node in PATH to prevent ENOENT errors.
|
|
74
|
+
* @param {Object|null} provider - Provider object or null for Anthropic defaults
|
|
75
|
+
* @param {boolean} thinkingEnabled - Whether thinking mode is enabled
|
|
76
|
+
* @returns {Object}
|
|
77
|
+
*/
|
|
78
|
+
export function buildSessionEnv(provider, thinkingEnabled = false, effortLevel = null) {
|
|
79
|
+
const baseEnv = createRobustEnv(process.env);
|
|
80
|
+
const providerEnv = buildProviderEnv(provider);
|
|
81
|
+
|
|
82
|
+
// Combine all env vars
|
|
83
|
+
const sessionEnv = {
|
|
84
|
+
...baseEnv,
|
|
85
|
+
...providerEnv, // Add provider env vars
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// When no custom provider is configured, explicitly exclude ANTHROPIC_* variables
|
|
89
|
+
// from the environment to ensure SDK uses its defaults (not user's env vars)
|
|
90
|
+
if (!provider) {
|
|
91
|
+
delete sessionEnv.ANTHROPIC_API_KEY;
|
|
92
|
+
delete sessionEnv.ANTHROPIC_AUTH_TOKEN;
|
|
93
|
+
delete sessionEnv.ANTHROPIC_BASE_URL;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Add thinking tokens if enabled (but suppress in VCR mode to minimize cost)
|
|
97
|
+
if (thinkingEnabled && !process.env.VCR_MODE) {
|
|
98
|
+
sessionEnv.MAX_THINKING_TOKENS = '10240';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Set effort level if provided
|
|
102
|
+
if (effortLevel) {
|
|
103
|
+
sessionEnv.CLAUDE_CODE_EFFORT_LEVEL = effortLevel;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return sessionEnv;
|
|
107
|
+
}
|