pybao-cli 1.5.50 → 1.5.52
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/REPL-CDBGUX7H.js +53 -0
- package/dist/{acp-VXAHCMQ4.js → acp-KC4VUW7Q.js} +47 -47
- package/dist/{agentsValidate-PFVCK6ZC.js → agentsValidate-YGJMW4T4.js} +9 -9
- package/dist/{ask-7RQ2G5S3.js → ask-YHWMV475.js} +46 -46
- package/dist/{autoUpdater-TDN3ABMG.js → autoUpdater-76RMCNA7.js} +4 -4
- package/dist/{blockParser-QPLEX5NJ.js → blockParser-RZPICWAA.js} +2 -2
- package/dist/{chunk-L4CGYTJQ.js → chunk-2EQA5NLL.js} +1 -1
- package/dist/{chunk-FNDIHEBT.js → chunk-33EYH7S3.js} +5 -5
- package/dist/{chunk-IXFDCJ25.js → chunk-3I35GELX.js} +5 -5
- package/dist/{chunk-CHH6TEXB.js → chunk-4MAX5UNY.js} +1 -1
- package/dist/{chunk-ZDDVFBS4.js → chunk-4UQCXDKA.js} +4 -4
- package/dist/{chunk-DBMDQEQO.js → chunk-6QSG5OON.js} +5 -5
- package/dist/{chunk-VAZ4VRTA.js → chunk-AZF3LTDE.js} +3 -3
- package/dist/{chunk-XHAEEYYH.js → chunk-CBDJJ2WQ.js} +2 -2
- package/dist/{chunk-YFVKGHW2.js → chunk-DPE2QUR4.js} +4 -4
- package/dist/{chunk-CNBKKQSV.js → chunk-DYLRL3GG.js} +1 -1
- package/dist/{chunk-F4AXICO7.js → chunk-EXNV3ROJ.js} +1 -1
- package/dist/{chunk-NBDDIZNJ.js → chunk-FNMZKMUC.js} +2 -2
- package/dist/{chunk-ZKW5V7MR.js → chunk-HSOB4XJ2.js} +1 -1
- package/dist/{chunk-7MR3XX5X.js → chunk-I42N2MZA.js} +3 -3
- package/dist/{chunk-KKNO6B2K.js → chunk-JGECWVPT.js} +1873 -766
- package/dist/{chunk-UJRT7VK2.js → chunk-KPZ4UMNV.js} +1 -1
- package/dist/{chunk-CNW45NOZ.js → chunk-KQBUAEA5.js} +4 -4
- package/dist/{chunk-NQGIALRP.js → chunk-L2JZIHLB.js} +6 -6
- package/dist/{chunk-5ITEAEJC.js → chunk-NQJAXQZX.js} +3 -3
- package/dist/{chunk-A45A3UUU.js → chunk-O6CVVWZV.js} +1 -1
- package/dist/{chunk-Y7I4XTJJ.js → chunk-OEHXDSEI.js} +4 -4
- package/dist/{chunk-NRORTICH.js → chunk-PA5FTBIQ.js} +2 -2
- package/dist/{chunk-NSFU6Y4R.js → chunk-QEPBMPEE.js} +1 -1
- package/dist/{chunk-5AGDLQAW.js → chunk-QQ27ECXF.js} +1 -1
- package/dist/{chunk-J6HKEIL2.js → chunk-QYVB7FJ4.js} +1 -1
- package/dist/{chunk-K3QEELFX.js → chunk-R64GVTIZ.js} +3 -3
- package/dist/{chunk-LE5VGGP6.js → chunk-RETS7G2B.js} +6 -6
- package/dist/{chunk-EY3ZOE75.js → chunk-SZS6SEDB.js} +1 -1
- package/dist/{chunk-PXRUNRK7.js → chunk-UCNZU6OO.js} +2 -2
- package/dist/{chunk-BQCQ3DEN.js → chunk-UG7ZFONK.js} +4 -4
- package/dist/{chunk-C7BUAPKP.js → chunk-VFFYWI27.js} +4 -4
- package/dist/{chunk-OMELVAJD.js → chunk-YQ6JLMLS.js} +1 -1
- package/dist/{chunk-3IPEAISZ.js → chunk-ZFLQSIXD.js} +3 -3
- package/dist/{chunk-5P4A6TN2.js → chunk-ZWTGVUTI.js} +3 -3
- package/dist/{cli-PMOATR2H.js → cli-JMJIGYNF.js} +120 -120
- package/dist/commands-N4RLEJU6.js +57 -0
- package/dist/{config-PQYZDDGW.js → config-6AW7SYEB.js} +6 -6
- package/dist/{context-BWXP2WB4.js → context-VGBWHZ57.js} +9 -9
- package/dist/{conversationPersistence-CS2SQ6Z6.js → conversationPersistence-AAJPHPUT.js} +4 -4
- package/dist/{conversationTracker-3OLKEYWM.js → conversationTracker-MVX6VQG2.js} +5 -5
- package/dist/{costTracker-DJVFVAVZ.js → costTracker-KBXHS4NS.js} +2 -2
- package/dist/{customCommands-VPTXXYYR.js → customCommands-PJI43HDH.js} +6 -6
- package/dist/{env-G5ZYCG5S.js → env-JEHV2OD5.js} +3 -3
- package/dist/{file-2I2KXCVN.js → file-G3IOPSJE.js} +5 -5
- package/dist/index.js +4 -4
- package/dist/{llm-KXF74SNS.js → llm-CVILTZMI.js} +50 -50
- package/dist/{llmLazy-L3IJUBN2.js → llmLazy-TS22QBZC.js} +2 -2
- package/dist/{loader-CJOJNOV7.js → loader-DA33SOZU.js} +7 -7
- package/dist/{lsp-OKPL75YW.js → lsp-M5NJ7YC7.js} +9 -9
- package/dist/{lspAnchor-7Z5YNXX3.js → lspAnchor-LUE27QI2.js} +10 -10
- package/dist/{mcp-C65V4JYM.js → mcp-3R7KNW6M.js} +10 -10
- package/dist/{mentionProcessor-EDZBHP7Y.js → mentionProcessor-KM7DJSIF.js} +8 -8
- package/dist/{messages-YBAYUMKL.js → messages-EUS4CRVP.js} +3 -3
- package/dist/{model-7WMFC6F7.js → model-3GE72U3P.js} +7 -7
- package/dist/{openai-YWEX6G4I.js → openai-3TL5XAIV.js} +8 -8
- package/dist/{outputStyles-N6S27KGD.js → outputStyles-7FC4BJZX.js} +7 -7
- package/dist/{pluginRuntime-3XWIAPQ7.js → pluginRuntime-IWKORZEI.js} +8 -8
- package/dist/{pluginValidation-2JLTTMJL.js → pluginValidation-DC2PWTS3.js} +8 -8
- package/dist/prompts-X5RHKH65.js +59 -0
- package/dist/{pybAgentSessionId-EPCAMQ25.js → pybAgentSessionId-3LL4RMFU.js} +2 -2
- package/dist/{pybAgentSessionLoad-XJ6XWCK5.js → pybAgentSessionLoad-DCESKISD.js} +6 -6
- package/dist/{pybAgentSessionResume-SMNXFGFB.js → pybAgentSessionResume-CIJIMHTT.js} +8 -8
- package/dist/{pybAgentStreamJson-EQPO52B6.js → pybAgentStreamJson-K7E4VEFE.js} +2 -2
- package/dist/{pybAgentStreamJsonSession-33YU7WNJ.js → pybAgentStreamJsonSession-SZMCWTVW.js} +4 -4
- package/dist/{pybAgentStructuredStdio-ROCSOGNT.js → pybAgentStructuredStdio-T6JJLJVC.js} +3 -3
- package/dist/{pybHooks-6JRPW3VW.js → pybHooks-CYAJNZ6G.js} +7 -7
- package/dist/query-7PFFQCW2.js +57 -0
- package/dist/{registry-67P26WKJ.js → registry-HF5Y4WZS.js} +6 -6
- package/dist/{replSessionBridge-EBXNFUAD.js → replSessionBridge-4XEXXNRH.js} +3 -3
- package/dist/{responsesStreaming-NPGJLPV3.js → responsesStreaming-RZW2QVJU.js} +3 -3
- package/dist/{ripgrep-DPLWHL7O.js → ripgrep-W5ULQHU4.js} +4 -4
- package/dist/{skillMarketplace-MGU4KRUF.js → skillMarketplace-WKOGEWIO.js} +4 -4
- package/dist/{smart-edit-AWHJDSU6.js → smart-edit-EQBEMPKQ.js} +2 -2
- package/dist/{state-NZVNNCHH.js → state-GWKESQ7O.js} +3 -3
- package/dist/theme-VRKM2HNU.js +14 -0
- package/dist/{toolPermissionContext-BSFV23IL.js → toolPermissionContext-TAUII5GX.js} +2 -2
- package/dist/{toolPermissionSettings-NEXN25B3.js → toolPermissionSettings-Z2I77LVO.js} +9 -9
- package/dist/tools-VM7IZKXZ.js +57 -0
- package/dist/{userInput-PHXM4ITY.js → userInput-Q2HIIFPM.js} +49 -49
- package/dist/{uuid-CVHEFGW4.js → uuid-EJN2AIBK.js} +2 -2
- package/package.json +3 -3
- package/dist/REPL-5XUDCAF4.js +0 -53
- package/dist/REPL-5XUDCAF4.js.map +0 -7
- package/dist/acp-VXAHCMQ4.js.map +0 -7
- package/dist/agentsValidate-PFVCK6ZC.js.map +0 -7
- package/dist/ask-7RQ2G5S3.js.map +0 -7
- package/dist/autoUpdater-TDN3ABMG.js.map +0 -7
- package/dist/blockParser-QPLEX5NJ.js.map +0 -7
- package/dist/chunk-2RXKUCFS.js.map +0 -7
- package/dist/chunk-3DFBSQIT.js.map +0 -7
- package/dist/chunk-3IPEAISZ.js.map +0 -7
- package/dist/chunk-5AGDLQAW.js.map +0 -7
- package/dist/chunk-5ITEAEJC.js.map +0 -7
- package/dist/chunk-5JHD6MUL.js.map +0 -7
- package/dist/chunk-5P4A6TN2.js.map +0 -7
- package/dist/chunk-5P7HBXTD.js.map +0 -7
- package/dist/chunk-7MR3XX5X.js.map +0 -7
- package/dist/chunk-A3BVXXA3.js.map +0 -7
- package/dist/chunk-A45A3UUU.js.map +0 -7
- package/dist/chunk-B6IMQJZM.js.map +0 -7
- package/dist/chunk-BJSWTHRM.js.map +0 -7
- package/dist/chunk-BKCAVW2G.js.map +0 -7
- package/dist/chunk-BQCQ3DEN.js.map +0 -7
- package/dist/chunk-C7BUAPKP.js.map +0 -7
- package/dist/chunk-CHH6TEXB.js.map +0 -7
- package/dist/chunk-CNBKKQSV.js.map +0 -7
- package/dist/chunk-CNW45NOZ.js.map +0 -7
- package/dist/chunk-CZZKRPE2.js.map +0 -7
- package/dist/chunk-DBMDQEQO.js.map +0 -7
- package/dist/chunk-EY3ZOE75.js.map +0 -7
- package/dist/chunk-F4AXICO7.js.map +0 -7
- package/dist/chunk-FNDIHEBT.js.map +0 -7
- package/dist/chunk-I3J4JYES.js.map +0 -7
- package/dist/chunk-IXFDCJ25.js.map +0 -7
- package/dist/chunk-J6HKEIL2.js.map +0 -7
- package/dist/chunk-K3QEELFX.js.map +0 -7
- package/dist/chunk-KFEHHKZ2.js.map +0 -7
- package/dist/chunk-KKNO6B2K.js.map +0 -7
- package/dist/chunk-L4CGYTJQ.js.map +0 -7
- package/dist/chunk-LE5VGGP6.js.map +0 -7
- package/dist/chunk-MWPFU2KU.js.map +0 -7
- package/dist/chunk-NBDDIZNJ.js.map +0 -7
- package/dist/chunk-NQGIALRP.js.map +0 -7
- package/dist/chunk-NRORTICH.js.map +0 -7
- package/dist/chunk-NSFU6Y4R.js.map +0 -7
- package/dist/chunk-OMELVAJD.js.map +0 -7
- package/dist/chunk-OUXHGDLH.js.map +0 -7
- package/dist/chunk-PXRUNRK7.js.map +0 -7
- package/dist/chunk-QWIBSCDN.js.map +0 -7
- package/dist/chunk-RQVLBMP7.js.map +0 -7
- package/dist/chunk-TFHFYID3.js.map +0 -7
- package/dist/chunk-UJRT7VK2.js.map +0 -7
- package/dist/chunk-UNNVICVU.js.map +0 -7
- package/dist/chunk-UZ34JEUK.js.map +0 -7
- package/dist/chunk-VAZ4VRTA.js.map +0 -7
- package/dist/chunk-XHAEEYYH.js.map +0 -7
- package/dist/chunk-XKYHFZEC.js.map +0 -7
- package/dist/chunk-Y7I4XTJJ.js.map +0 -7
- package/dist/chunk-YFVKGHW2.js.map +0 -7
- package/dist/chunk-ZDDVFBS4.js.map +0 -7
- package/dist/chunk-ZKW5V7MR.js.map +0 -7
- package/dist/cli-PMOATR2H.js.map +0 -7
- package/dist/commands-HA2TW7NU.js +0 -57
- package/dist/commands-HA2TW7NU.js.map +0 -7
- package/dist/config-PQYZDDGW.js.map +0 -7
- package/dist/context-BWXP2WB4.js.map +0 -7
- package/dist/conversationPersistence-CS2SQ6Z6.js.map +0 -7
- package/dist/conversationTracker-3OLKEYWM.js.map +0 -7
- package/dist/costTracker-DJVFVAVZ.js.map +0 -7
- package/dist/customCommands-VPTXXYYR.js.map +0 -7
- package/dist/env-G5ZYCG5S.js.map +0 -7
- package/dist/file-2I2KXCVN.js.map +0 -7
- package/dist/index.js.map +0 -7
- package/dist/llm-KXF74SNS.js.map +0 -7
- package/dist/llmLazy-L3IJUBN2.js.map +0 -7
- package/dist/loader-CJOJNOV7.js.map +0 -7
- package/dist/lsp-OKPL75YW.js.map +0 -7
- package/dist/lspAnchor-7Z5YNXX3.js.map +0 -7
- package/dist/mcp-C65V4JYM.js.map +0 -7
- package/dist/mentionProcessor-EDZBHP7Y.js.map +0 -7
- package/dist/messages-YBAYUMKL.js.map +0 -7
- package/dist/model-7WMFC6F7.js.map +0 -7
- package/dist/openai-YWEX6G4I.js.map +0 -7
- package/dist/outputStyles-N6S27KGD.js.map +0 -7
- package/dist/pluginRuntime-3XWIAPQ7.js.map +0 -7
- package/dist/pluginValidation-2JLTTMJL.js.map +0 -7
- package/dist/prompts-HCGQPTDJ.js +0 -59
- package/dist/prompts-HCGQPTDJ.js.map +0 -7
- package/dist/pybAgentSessionId-EPCAMQ25.js.map +0 -7
- package/dist/pybAgentSessionLoad-XJ6XWCK5.js.map +0 -7
- package/dist/pybAgentSessionResume-SMNXFGFB.js.map +0 -7
- package/dist/pybAgentStreamJson-EQPO52B6.js.map +0 -7
- package/dist/pybAgentStreamJsonSession-33YU7WNJ.js.map +0 -7
- package/dist/pybAgentStructuredStdio-ROCSOGNT.js.map +0 -7
- package/dist/pybHooks-6JRPW3VW.js.map +0 -7
- package/dist/query-GGJC3XT2.js +0 -57
- package/dist/query-GGJC3XT2.js.map +0 -7
- package/dist/registry-67P26WKJ.js.map +0 -7
- package/dist/replSessionBridge-EBXNFUAD.js.map +0 -7
- package/dist/responsesStreaming-NPGJLPV3.js.map +0 -7
- package/dist/ripgrep-DPLWHL7O.js.map +0 -7
- package/dist/skillMarketplace-MGU4KRUF.js.map +0 -7
- package/dist/smart-edit-AWHJDSU6.js.map +0 -7
- package/dist/state-NZVNNCHH.js.map +0 -7
- package/dist/theme-XV4CTBG6.js +0 -14
- package/dist/theme-XV4CTBG6.js.map +0 -7
- package/dist/toolPermissionContext-BSFV23IL.js.map +0 -7
- package/dist/toolPermissionSettings-NEXN25B3.js.map +0 -7
- package/dist/tools-R7EDLOFS.js +0 -57
- package/dist/tools-R7EDLOFS.js.map +0 -7
- package/dist/userInput-PHXM4ITY.js.map +0 -7
- package/dist/uuid-CVHEFGW4.js.map +0 -7
- /package/dist/{chunk-UZ34JEUK.js → chunk-7HEKZ73X.js} +0 -0
- /package/dist/{chunk-5JHD6MUL.js → chunk-ADD7XJ5F.js} +0 -0
- /package/dist/{chunk-B6IMQJZM.js → chunk-DRSLDSBY.js} +0 -0
- /package/dist/{chunk-KFEHHKZ2.js → chunk-F3JSDBR6.js} +0 -0
- /package/dist/{chunk-QWIBSCDN.js → chunk-GEEDQS2I.js} +0 -0
- /package/dist/{chunk-2RXKUCFS.js → chunk-ISMRCABJ.js} +0 -0
- /package/dist/{chunk-MWPFU2KU.js → chunk-JVKJ7J5H.js} +0 -0
- /package/dist/{chunk-BJSWTHRM.js → chunk-KNUG3M6O.js} +0 -0
- /package/dist/{chunk-UNNVICVU.js → chunk-LG65MFKB.js} +0 -0
- /package/dist/{chunk-CZZKRPE2.js → chunk-MGN3VYPN.js} +0 -0
- /package/dist/{chunk-A3BVXXA3.js → chunk-OQEZC7X2.js} +0 -0
- /package/dist/{chunk-I3J4JYES.js → chunk-OYT6EI36.js} +0 -0
- /package/dist/{chunk-RQVLBMP7.js → chunk-PDH2QHLY.js} +0 -0
- /package/dist/{chunk-5P7HBXTD.js → chunk-QAMAR4LW.js} +0 -0
- /package/dist/{chunk-TFHFYID3.js → chunk-TNCBVAVV.js} +0 -0
- /package/dist/{chunk-XKYHFZEC.js → chunk-U6BMHOQT.js} +0 -0
- /package/dist/{chunk-OUXHGDLH.js → chunk-VEHLCRJN.js} +0 -0
- /package/dist/{chunk-3DFBSQIT.js → chunk-XZG5WCDK.js} +0 -0
- /package/dist/{chunk-BKCAVW2G.js → chunk-ZY2PESP4.js} +0 -0
|
@@ -2,17 +2,17 @@ import { createRequire as __pybCreateRequire } from "node:module";
|
|
|
2
2
|
const require = __pybCreateRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
loadPybAgentSessionMessages
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QEPBMPEE.js";
|
|
6
6
|
import {
|
|
7
7
|
appendSessionCustomTitleRecord,
|
|
8
8
|
appendSessionJsonlFromMessage,
|
|
9
9
|
appendSessionTagRecord,
|
|
10
10
|
listPybAgentSessions
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-3I35GELX.js";
|
|
12
12
|
import {
|
|
13
13
|
formatValidationResult,
|
|
14
14
|
validatePluginOrMarketplacePath
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-R64GVTIZ.js";
|
|
16
16
|
import {
|
|
17
17
|
ConversationTracker,
|
|
18
18
|
appendFinishState,
|
|
@@ -20,13 +20,13 @@ import {
|
|
|
20
20
|
getConversationTrackerForContext,
|
|
21
21
|
isFinishComplete,
|
|
22
22
|
mapFinishReason
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-2EQA5NLL.js";
|
|
24
24
|
import {
|
|
25
25
|
FileSystemConversationPersistence
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-QYVB7FJ4.js";
|
|
27
27
|
import {
|
|
28
28
|
beginReplSessionScope
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-EXNV3ROJ.js";
|
|
30
30
|
import {
|
|
31
31
|
drainHookSystemPromptAdditions,
|
|
32
32
|
getHookTranscriptPath,
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
runStopHooks,
|
|
39
39
|
runUserPromptSubmitHooks,
|
|
40
40
|
updateHookTranscriptForMessages
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-6QSG5OON.js";
|
|
42
42
|
import {
|
|
43
43
|
DEFAULT_OUTPUT_STYLE,
|
|
44
44
|
getAvailableOutputStyles,
|
|
@@ -47,20 +47,20 @@ import {
|
|
|
47
47
|
getOutputStyleSystemPromptAdditions,
|
|
48
48
|
resolveOutputStyleName,
|
|
49
49
|
setCurrentOutputStyle
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-UG7ZFONK.js";
|
|
51
51
|
import {
|
|
52
52
|
fetchCustomModels,
|
|
53
53
|
getModelFeatures
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-ZWTGVUTI.js";
|
|
55
55
|
import {
|
|
56
56
|
getCurrentSessionId,
|
|
57
57
|
getSessionState
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-U6BMHOQT.js";
|
|
59
59
|
import {
|
|
60
60
|
queryLLM,
|
|
61
61
|
queryQuick,
|
|
62
62
|
verifyApiKey
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-4UQCXDKA.js";
|
|
64
64
|
import {
|
|
65
65
|
DEFAULT_TIMEOUT_MS,
|
|
66
66
|
DESCRIPTION,
|
|
@@ -92,7 +92,7 @@ import {
|
|
|
92
92
|
listMCPServers,
|
|
93
93
|
loadMergedSettings,
|
|
94
94
|
normalizeSandboxRuntimeConfigFromSettings
|
|
95
|
-
} from "./chunk-
|
|
95
|
+
} from "./chunk-33EYH7S3.js";
|
|
96
96
|
import {
|
|
97
97
|
addMarketplace,
|
|
98
98
|
disableSkillPlugin,
|
|
@@ -105,29 +105,29 @@ import {
|
|
|
105
105
|
refreshMarketplaceAsync,
|
|
106
106
|
removeMarketplace,
|
|
107
107
|
uninstallSkillPlugin
|
|
108
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-4MAX5UNY.js";
|
|
109
109
|
import {
|
|
110
110
|
loadToolPermissionContextFromDisk,
|
|
111
111
|
persistToolPermissionUpdateToDisk
|
|
112
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-OEHXDSEI.js";
|
|
113
113
|
import {
|
|
114
114
|
applyToolPermissionContextUpdate,
|
|
115
115
|
applyToolPermissionContextUpdates,
|
|
116
116
|
createDefaultToolPermissionContext
|
|
117
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-LG65MFKB.js";
|
|
118
118
|
import {
|
|
119
119
|
emitReminderEvent,
|
|
120
120
|
generateSystemReminders,
|
|
121
121
|
resetReminderSession,
|
|
122
122
|
systemReminderService
|
|
123
|
-
} from "./chunk-
|
|
123
|
+
} from "./chunk-PA5FTBIQ.js";
|
|
124
124
|
import {
|
|
125
125
|
clearAgentCache,
|
|
126
126
|
getActiveAgents,
|
|
127
127
|
getAgentByType,
|
|
128
128
|
getAllAgents,
|
|
129
129
|
getAvailableAgentTypes
|
|
130
|
-
} from "./chunk-
|
|
130
|
+
} from "./chunk-DPE2QUR4.js";
|
|
131
131
|
import {
|
|
132
132
|
API_ERROR_MESSAGE_PREFIX,
|
|
133
133
|
CANCEL_MESSAGE,
|
|
@@ -162,16 +162,16 @@ import {
|
|
|
162
162
|
reorderMessages,
|
|
163
163
|
resetAutoCompactTelemetry,
|
|
164
164
|
stripSystemMessages
|
|
165
|
-
} from "./chunk-
|
|
165
|
+
} from "./chunk-UCNZU6OO.js";
|
|
166
166
|
import {
|
|
167
167
|
getRequestStatus,
|
|
168
168
|
setRequestStatus,
|
|
169
169
|
subscribeRequestStatus
|
|
170
|
-
} from "./chunk-
|
|
170
|
+
} from "./chunk-XZG5WCDK.js";
|
|
171
171
|
import {
|
|
172
172
|
getPybAgentSessionId,
|
|
173
173
|
setPybAgentSessionId
|
|
174
|
-
} from "./chunk-
|
|
174
|
+
} from "./chunk-DRSLDSBY.js";
|
|
175
175
|
import {
|
|
176
176
|
formatDuration,
|
|
177
177
|
formatNumber,
|
|
@@ -180,7 +180,7 @@ import {
|
|
|
180
180
|
getTotalCost,
|
|
181
181
|
getTotalDuration,
|
|
182
182
|
wrapText
|
|
183
|
-
} from "./chunk-
|
|
183
|
+
} from "./chunk-VEHLCRJN.js";
|
|
184
184
|
import {
|
|
185
185
|
addLineNumbers,
|
|
186
186
|
detectFileEncoding,
|
|
@@ -194,13 +194,13 @@ import {
|
|
|
194
194
|
normalizeFilePath,
|
|
195
195
|
readTextContent,
|
|
196
196
|
writeTextContent
|
|
197
|
-
} from "./chunk-
|
|
197
|
+
} from "./chunk-FNMZKMUC.js";
|
|
198
198
|
import {
|
|
199
199
|
parseBlockEdits
|
|
200
|
-
} from "./chunk-
|
|
200
|
+
} from "./chunk-GEEDQS2I.js";
|
|
201
201
|
import {
|
|
202
202
|
toLspToolFallbackEvent
|
|
203
|
-
} from "./chunk-
|
|
203
|
+
} from "./chunk-ISMRCABJ.js";
|
|
204
204
|
import {
|
|
205
205
|
LspAPI,
|
|
206
206
|
LspFacade,
|
|
@@ -208,31 +208,31 @@ import {
|
|
|
208
208
|
formatDiagnosticsPretty,
|
|
209
209
|
initParser,
|
|
210
210
|
loadLanguage
|
|
211
|
-
} from "./chunk-
|
|
211
|
+
} from "./chunk-L2JZIHLB.js";
|
|
212
212
|
import {
|
|
213
213
|
emitTelemetryEvent,
|
|
214
214
|
registerTelemetryListener
|
|
215
|
-
} from "./chunk-
|
|
215
|
+
} from "./chunk-TNCBVAVV.js";
|
|
216
216
|
import {
|
|
217
217
|
getSettingsFileCandidates,
|
|
218
218
|
loadSettingsWithLegacyFallback,
|
|
219
219
|
readSettingsFile
|
|
220
|
-
} from "./chunk-
|
|
220
|
+
} from "./chunk-DYLRL3GG.js";
|
|
221
221
|
import {
|
|
222
222
|
getCustomCommandDirectories,
|
|
223
223
|
hasCustomCommands,
|
|
224
224
|
loadCustomCommands,
|
|
225
225
|
reloadCustomCommands
|
|
226
|
-
} from "./chunk-
|
|
226
|
+
} from "./chunk-I42N2MZA.js";
|
|
227
227
|
import {
|
|
228
228
|
getSessionPlugins
|
|
229
|
-
} from "./chunk-
|
|
229
|
+
} from "./chunk-KNUG3M6O.js";
|
|
230
230
|
import {
|
|
231
231
|
ModelManager,
|
|
232
232
|
buildModelProfileKey,
|
|
233
233
|
getModelManager,
|
|
234
234
|
isDefaultSlowAndCapableModel
|
|
235
|
-
} from "./chunk-
|
|
235
|
+
} from "./chunk-AZF3LTDE.js";
|
|
236
236
|
import {
|
|
237
237
|
getCodeStyle,
|
|
238
238
|
getContext,
|
|
@@ -240,16 +240,16 @@ import {
|
|
|
240
240
|
getIsGit,
|
|
241
241
|
getProjectDocs,
|
|
242
242
|
getProjectStructureStatisticsBlock
|
|
243
|
-
} from "./chunk-
|
|
243
|
+
} from "./chunk-RETS7G2B.js";
|
|
244
244
|
import {
|
|
245
245
|
getRipgrepPath,
|
|
246
246
|
getRipgrepPolicyMode,
|
|
247
247
|
resolveRipgrepPolicy,
|
|
248
248
|
ripGrep
|
|
249
|
-
} from "./chunk-
|
|
249
|
+
} from "./chunk-HSOB4XJ2.js";
|
|
250
250
|
import {
|
|
251
251
|
getTheme
|
|
252
|
-
} from "./chunk-
|
|
252
|
+
} from "./chunk-SZS6SEDB.js";
|
|
253
253
|
import {
|
|
254
254
|
DEFAULT_GLOBAL_CONFIG,
|
|
255
255
|
enableConfigs,
|
|
@@ -262,16 +262,16 @@ import {
|
|
|
262
262
|
saveGlobalConfig,
|
|
263
263
|
setAllPointersToModel,
|
|
264
264
|
setModelPointer
|
|
265
|
-
} from "./chunk-
|
|
265
|
+
} from "./chunk-KQBUAEA5.js";
|
|
266
266
|
import {
|
|
267
267
|
AbortError
|
|
268
|
-
} from "./chunk-
|
|
268
|
+
} from "./chunk-PDH2QHLY.js";
|
|
269
269
|
import {
|
|
270
270
|
debug,
|
|
271
271
|
getCurrentRequest,
|
|
272
272
|
logUserFriendly,
|
|
273
273
|
markPhase
|
|
274
|
-
} from "./chunk-
|
|
274
|
+
} from "./chunk-O6CVVWZV.js";
|
|
275
275
|
import {
|
|
276
276
|
ASCII_LOGO,
|
|
277
277
|
BunShell,
|
|
@@ -315,13 +315,13 @@ import {
|
|
|
315
315
|
setCwd,
|
|
316
316
|
shouldApplyToolOutputTruncation,
|
|
317
317
|
truncateToolOutput
|
|
318
|
-
} from "./chunk-
|
|
318
|
+
} from "./chunk-KPZ4UMNV.js";
|
|
319
319
|
import {
|
|
320
320
|
MACRO
|
|
321
|
-
} from "./chunk-
|
|
321
|
+
} from "./chunk-NQJAXQZX.js";
|
|
322
322
|
import {
|
|
323
323
|
__export
|
|
324
|
-
} from "./chunk-
|
|
324
|
+
} from "./chunk-OYT6EI36.js";
|
|
325
325
|
|
|
326
326
|
// src/tools/system/BashTool/BashTool.tsx
|
|
327
327
|
import { statSync as statSync16 } from "fs";
|
|
@@ -499,7 +499,7 @@ var getCommandSubcommandPrefix = memoize(
|
|
|
499
499
|
var getCommandPrefix = memoize(
|
|
500
500
|
async (command4, abortSignal) => {
|
|
501
501
|
const { systemPrompt, userPrompt } = buildBashCommandPrefixDetectionPrompt(command4);
|
|
502
|
-
const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryQuick: queryQuick2 } = await import("./llm-
|
|
502
|
+
const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryQuick: queryQuick2 } = await import("./llm-CVILTZMI.js");
|
|
503
503
|
const response = await queryQuick2({
|
|
504
504
|
systemPrompt,
|
|
505
505
|
userPrompt,
|
|
@@ -4301,7 +4301,7 @@ function formatParseError(error) {
|
|
|
4301
4301
|
return error instanceof Error ? error.message : String(error);
|
|
4302
4302
|
}
|
|
4303
4303
|
async function defaultGateQuery(args) {
|
|
4304
|
-
const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryLLM: queryLLM2 } = await import("./llm-
|
|
4304
|
+
const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryLLM: queryLLM2 } = await import("./llm-CVILTZMI.js");
|
|
4305
4305
|
const queryLLMFn = args.queryLLMOverride ?? queryLLM2;
|
|
4306
4306
|
const messages = [
|
|
4307
4307
|
{
|
|
@@ -6793,14 +6793,14 @@ var FileEditTool = {
|
|
|
6793
6793
|
}
|
|
6794
6794
|
let editOperations = [];
|
|
6795
6795
|
if (edits) {
|
|
6796
|
-
const { parseBlockEdits: parseBlockEdits2 } = await import("./blockParser-
|
|
6796
|
+
const { parseBlockEdits: parseBlockEdits2 } = await import("./blockParser-RZPICWAA.js");
|
|
6797
6797
|
editOperations = parseBlockEdits2(edits);
|
|
6798
6798
|
}
|
|
6799
6799
|
let currentFileContent = fileExistsBun(fullFilePath) ? normalizeLineEndings(await readFileBun(fullFilePath) ?? "") : "";
|
|
6800
6800
|
const originalFileContent = currentFileContent;
|
|
6801
6801
|
let totalPatch = [];
|
|
6802
|
-
const { SmartEdit } = await import("./smart-edit-
|
|
6803
|
-
const { findLspAnchor } = await import("./lspAnchor-
|
|
6802
|
+
const { SmartEdit } = await import("./smart-edit-EQBEMPKQ.js");
|
|
6803
|
+
const { findLspAnchor } = await import("./lspAnchor-LUE27QI2.js");
|
|
6804
6804
|
for (const op of editOperations) {
|
|
6805
6805
|
const normalizedSearch = normalizeLineEndings(op.search);
|
|
6806
6806
|
const normalizedReplace = normalizeLineEndings(op.replace);
|
|
@@ -8756,6 +8756,7 @@ var inputSchema7 = z7.strictObject({
|
|
|
8756
8756
|
});
|
|
8757
8757
|
var MAX_RESULT_CHARS = 2e4;
|
|
8758
8758
|
var EXCLUDED_DIRS = [".git", ".svn", ".hg", ".bzr"];
|
|
8759
|
+
var DEFAULT_FILES_WITH_MATCHES_LIMIT = 1500;
|
|
8759
8760
|
function paginate(items, limit, offset) {
|
|
8760
8761
|
if (offset > 0) {
|
|
8761
8762
|
items = items.slice(offset);
|
|
@@ -8884,7 +8885,9 @@ Found ${numMatches} total ${numMatches === 1 ? "occurrence" : "occurrences"} acr
|
|
|
8884
8885
|
"No files found\nSuggestion: Read the target directory path to confirm one-level structure and search scope, then broaden matching conditions (case/regex/keyword variants, semantic=true), and if needed switch to content mode or expand the file set before searching again."
|
|
8885
8886
|
);
|
|
8886
8887
|
}
|
|
8887
|
-
const
|
|
8888
|
+
const totalFiles = result.totalFiles ?? result.numFiles;
|
|
8889
|
+
const truncatedLabel = result.truncated && result.appliedLimit !== void 0 ? ` (showing first ${result.appliedLimit}; use head_limit/offset to paginate)` : "";
|
|
8890
|
+
const header = `Found ${totalFiles} file${totalFiles === 1 ? "" : "s"}${truncatedLabel}${pagination && !result.truncated ? ` ${pagination}` : ""}
|
|
8888
8891
|
${result.filenames.join("\n")}`;
|
|
8889
8892
|
return appendNotice(truncateToCharBudget(header));
|
|
8890
8893
|
},
|
|
@@ -8942,7 +8945,7 @@ ${result.filenames.join("\n")}`;
|
|
|
8942
8945
|
if (type3) {
|
|
8943
8946
|
baseArgs.push("--type", type3);
|
|
8944
8947
|
}
|
|
8945
|
-
const appliedLimit = head_limit !== void 0 ? head_limit : void 0;
|
|
8948
|
+
const appliedLimit = head_limit !== void 0 ? head_limit : output_mode === "files_with_matches" ? DEFAULT_FILES_WITH_MATCHES_LIMIT : void 0;
|
|
8946
8949
|
const appliedOffset = offset || 0;
|
|
8947
8950
|
if (glob) {
|
|
8948
8951
|
for (const g of parseGlobString(glob)) {
|
|
@@ -9195,10 +9198,13 @@ ${result.filenames.join("\n")}`;
|
|
|
9195
9198
|
const window = paginate(sorted, appliedLimit, appliedOffset).map(
|
|
9196
9199
|
toProjectRelativeIfPossible
|
|
9197
9200
|
);
|
|
9201
|
+
const totalFiles = sorted.length;
|
|
9198
9202
|
const output = {
|
|
9199
9203
|
mode: "files_with_matches",
|
|
9200
9204
|
filenames: window,
|
|
9201
9205
|
numFiles: window.length,
|
|
9206
|
+
totalFiles,
|
|
9207
|
+
truncated: window.length < totalFiles,
|
|
9202
9208
|
...appliedLimit !== void 0 ? { appliedLimit } : {},
|
|
9203
9209
|
...appliedOffset > 0 ? { appliedOffset } : {},
|
|
9204
9210
|
durationMs: Date.now() - start,
|
|
@@ -12402,7 +12408,7 @@ async function createAndStoreApiKey(accessToken) {
|
|
|
12402
12408
|
}
|
|
12403
12409
|
saveGlobalConfig(config2);
|
|
12404
12410
|
try {
|
|
12405
|
-
const { resetAnthropicClient } = await import("./llm-
|
|
12411
|
+
const { resetAnthropicClient } = await import("./llm-CVILTZMI.js");
|
|
12406
12412
|
resetAnthropicClient();
|
|
12407
12413
|
} catch {
|
|
12408
12414
|
}
|
|
@@ -16826,7 +16832,7 @@ async function refreshPluginRuntimeFromInstalls() {
|
|
|
16826
16832
|
const existingRoots = getSessionPlugins().map((p) => p.rootDir);
|
|
16827
16833
|
const dirs = Array.from(/* @__PURE__ */ new Set([...existingRoots, ...installedRoots]));
|
|
16828
16834
|
if (dirs.length === 0) return [];
|
|
16829
|
-
const { configureSessionPlugins } = await import("./pluginRuntime-
|
|
16835
|
+
const { configureSessionPlugins } = await import("./pluginRuntime-IWKORZEI.js");
|
|
16830
16836
|
const { errors } = await configureSessionPlugins({ pluginDirs: dirs });
|
|
16831
16837
|
return errors;
|
|
16832
16838
|
}
|
|
@@ -17501,7 +17507,7 @@ async function call(onDone, context) {
|
|
|
17501
17507
|
ModelConfig,
|
|
17502
17508
|
{
|
|
17503
17509
|
onClose: () => {
|
|
17504
|
-
import("./model-
|
|
17510
|
+
import("./model-3GE72U3P.js").then(({ reloadModelManager: reloadModelManager2 }) => {
|
|
17505
17511
|
reloadModelManager2();
|
|
17506
17512
|
triggerModelConfigChange();
|
|
17507
17513
|
onDone();
|
|
@@ -18270,7 +18276,7 @@ var rename = {
|
|
|
18270
18276
|
var rename_default = rename;
|
|
18271
18277
|
|
|
18272
18278
|
// src/server/index.ts
|
|
18273
|
-
import { Hono as
|
|
18279
|
+
import { Hono as Hono10 } from "hono";
|
|
18274
18280
|
import { cors } from "hono/cors";
|
|
18275
18281
|
import { logger } from "hono/logger";
|
|
18276
18282
|
import { streamSSE as streamSSE2 } from "hono/streaming";
|
|
@@ -21043,7 +21049,7 @@ function buildAutoCompactAggregationFields(params) {
|
|
|
21043
21049
|
}
|
|
21044
21050
|
|
|
21045
21051
|
// src/utils/session/compactionBudget.ts
|
|
21046
|
-
var DEFAULT_TOTAL_BUDGET_TOKENS =
|
|
21052
|
+
var DEFAULT_TOTAL_BUDGET_TOKENS = 5e4;
|
|
21047
21053
|
var DEFAULT_SUMMARY_RATIO = 0.45;
|
|
21048
21054
|
var DEFAULT_CONVERSATION_RATIO = 0.2;
|
|
21049
21055
|
var DEFAULT_RECOVERED_RATIO = 0.35;
|
|
@@ -25990,605 +25996,13 @@ async function* runToolUse(toolUse, siblingToolUseIDs, assistantMessage, canUseT
|
|
|
25990
25996
|
}
|
|
25991
25997
|
}
|
|
25992
25998
|
|
|
25993
|
-
// src/server/bus/index.ts
|
|
25994
|
-
var BusEvent;
|
|
25995
|
-
((BusEvent2) => {
|
|
25996
|
-
const registry = /* @__PURE__ */ new Map();
|
|
25997
|
-
function define(type3, properties) {
|
|
25998
|
-
const result = { type: type3, properties };
|
|
25999
|
-
registry.set(type3, result);
|
|
26000
|
-
return result;
|
|
26001
|
-
}
|
|
26002
|
-
BusEvent2.define = define;
|
|
26003
|
-
function getSchema(type3) {
|
|
26004
|
-
return registry.get(type3);
|
|
26005
|
-
}
|
|
26006
|
-
BusEvent2.getSchema = getSchema;
|
|
26007
|
-
})(BusEvent || (BusEvent = {}));
|
|
26008
|
-
var Bus;
|
|
26009
|
-
((Bus2) => {
|
|
26010
|
-
const state = {
|
|
26011
|
-
subscriptions: /* @__PURE__ */ new Map()
|
|
26012
|
-
};
|
|
26013
|
-
async function publish(def, properties) {
|
|
26014
|
-
const payload = {
|
|
26015
|
-
type: def.type,
|
|
26016
|
-
properties
|
|
26017
|
-
};
|
|
26018
|
-
const pending = [];
|
|
26019
|
-
for (const key of [def.type, "*"]) {
|
|
26020
|
-
const match = state.subscriptions.get(key);
|
|
26021
|
-
if (match) {
|
|
26022
|
-
for (const sub of match) {
|
|
26023
|
-
const result = sub(payload);
|
|
26024
|
-
if (result instanceof Promise) {
|
|
26025
|
-
pending.push(result);
|
|
26026
|
-
}
|
|
26027
|
-
}
|
|
26028
|
-
}
|
|
26029
|
-
}
|
|
26030
|
-
await Promise.all(pending);
|
|
26031
|
-
}
|
|
26032
|
-
Bus2.publish = publish;
|
|
26033
|
-
function subscribe(def, callback) {
|
|
26034
|
-
return raw(def.type, callback);
|
|
26035
|
-
}
|
|
26036
|
-
Bus2.subscribe = subscribe;
|
|
26037
|
-
function subscribeAll(callback) {
|
|
26038
|
-
return raw("*", callback);
|
|
26039
|
-
}
|
|
26040
|
-
Bus2.subscribeAll = subscribeAll;
|
|
26041
|
-
function raw(type3, callback) {
|
|
26042
|
-
const match = state.subscriptions.get(type3) ?? [];
|
|
26043
|
-
match.push(callback);
|
|
26044
|
-
state.subscriptions.set(type3, match);
|
|
26045
|
-
return () => {
|
|
26046
|
-
const subscriptions = state.subscriptions.get(type3);
|
|
26047
|
-
if (!subscriptions) return;
|
|
26048
|
-
const index = subscriptions.indexOf(callback);
|
|
26049
|
-
if (index !== -1) {
|
|
26050
|
-
subscriptions.splice(index, 1);
|
|
26051
|
-
}
|
|
26052
|
-
};
|
|
26053
|
-
}
|
|
26054
|
-
})(Bus || (Bus = {}));
|
|
26055
|
-
|
|
26056
|
-
// src/server/events/definitions.ts
|
|
26057
|
-
import { z as z10 } from "zod";
|
|
26058
|
-
var ServerEvents = {
|
|
26059
|
-
Connected: BusEvent.define("server.connected", z10.object({
|
|
26060
|
-
serverVersion: z10.string(),
|
|
26061
|
-
protocolVersion: z10.string(),
|
|
26062
|
-
features: z10.array(z10.string())
|
|
26063
|
-
})),
|
|
26064
|
-
Heartbeat: BusEvent.define("server.heartbeat", z10.object({
|
|
26065
|
-
timestamp: z10.number()
|
|
26066
|
-
})),
|
|
26067
|
-
Status: BusEvent.define("server.status", z10.object({
|
|
26068
|
-
status: z10.enum(["healthy", "degraded", "unhealthy"]),
|
|
26069
|
-
components: z10.object({
|
|
26070
|
-
llm: z10.enum(["connected", "disconnected"]),
|
|
26071
|
-
mcp: z10.enum(["connected", "disconnected"]),
|
|
26072
|
-
tools: z10.enum(["ready", "initializing"])
|
|
26073
|
-
})
|
|
26074
|
-
}))
|
|
26075
|
-
};
|
|
26076
|
-
var SessionEvents = {
|
|
26077
|
-
Created: BusEvent.define("session.created", z10.object({
|
|
26078
|
-
sessionId: z10.string(),
|
|
26079
|
-
config: z10.object({
|
|
26080
|
-
model: z10.string(),
|
|
26081
|
-
agent: z10.string(),
|
|
26082
|
-
outputStyle: z10.string()
|
|
26083
|
-
}),
|
|
26084
|
-
resumedFrom: z10.string().optional()
|
|
26085
|
-
})),
|
|
26086
|
-
Updated: BusEvent.define("session.updated", z10.object({
|
|
26087
|
-
sessionId: z10.string(),
|
|
26088
|
-
title: z10.string().optional(),
|
|
26089
|
-
config: z10.object({
|
|
26090
|
-
model: z10.string().optional(),
|
|
26091
|
-
agent: z10.string().optional(),
|
|
26092
|
-
outputStyle: z10.string().optional()
|
|
26093
|
-
}).optional()
|
|
26094
|
-
})),
|
|
26095
|
-
Deleted: BusEvent.define("session.deleted", z10.object({
|
|
26096
|
-
sessionId: z10.string()
|
|
26097
|
-
})),
|
|
26098
|
-
Status: BusEvent.define("session.status", z10.object({
|
|
26099
|
-
sessionId: z10.string(),
|
|
26100
|
-
status: z10.enum(["active", "idle", "waiting_input", "processing"]),
|
|
26101
|
-
currentRequestId: z10.string().optional()
|
|
26102
|
-
}))
|
|
26103
|
-
};
|
|
26104
|
-
var MessageEvents = {
|
|
26105
|
-
Created: BusEvent.define("message.created", z10.object({
|
|
26106
|
-
sessionId: z10.string(),
|
|
26107
|
-
message: z10.any()
|
|
26108
|
-
})),
|
|
26109
|
-
Updated: BusEvent.define("message.updated", z10.object({
|
|
26110
|
-
sessionId: z10.string(),
|
|
26111
|
-
message: z10.any(),
|
|
26112
|
-
delta: z10.object({
|
|
26113
|
-
type: z10.enum(["text", "tool_use"]),
|
|
26114
|
-
content: z10.string(),
|
|
26115
|
-
index: z10.number().optional()
|
|
26116
|
-
}).optional()
|
|
26117
|
-
})),
|
|
26118
|
-
Completed: BusEvent.define("message.completed", z10.object({
|
|
26119
|
-
sessionId: z10.string(),
|
|
26120
|
-
messageId: z10.string(),
|
|
26121
|
-
finishReason: z10.enum(["end_turn", "tool_calls", "max_tokens", "aborted"]),
|
|
26122
|
-
usage: z10.object({
|
|
26123
|
-
inputTokens: z10.number(),
|
|
26124
|
-
outputTokens: z10.number(),
|
|
26125
|
-
totalTokens: z10.number()
|
|
26126
|
-
}),
|
|
26127
|
-
cost: z10.object({
|
|
26128
|
-
costUSD: z10.number()
|
|
26129
|
-
})
|
|
26130
|
-
})),
|
|
26131
|
-
RequestStarted: BusEvent.define("request.started", z10.object({
|
|
26132
|
-
sessionId: z10.string(),
|
|
26133
|
-
requestId: z10.string(),
|
|
26134
|
-
userMessage: z10.string()
|
|
26135
|
-
})),
|
|
26136
|
-
RequestCompleted: BusEvent.define("request.completed", z10.object({
|
|
26137
|
-
sessionId: z10.string(),
|
|
26138
|
-
requestId: z10.string(),
|
|
26139
|
-
finishReason: z10.enum(["end_turn", "tool_calls", "max_tokens", "aborted"]),
|
|
26140
|
-
duration: z10.number(),
|
|
26141
|
-
totalTokens: z10.number(),
|
|
26142
|
-
costUSD: z10.number()
|
|
26143
|
-
}))
|
|
26144
|
-
};
|
|
26145
|
-
var ToolEvents = {
|
|
26146
|
-
Started: BusEvent.define("tool.started", z10.object({
|
|
26147
|
-
sessionId: z10.string(),
|
|
26148
|
-
toolUseId: z10.string(),
|
|
26149
|
-
toolName: z10.string(),
|
|
26150
|
-
input: z10.record(z10.unknown()),
|
|
26151
|
-
dangerousLevel: z10.enum(["safe", "moderate", "dangerous"]),
|
|
26152
|
-
requiresPermission: z10.boolean()
|
|
26153
|
-
})),
|
|
26154
|
-
Progress: BusEvent.define("tool.progress", z10.object({
|
|
26155
|
-
sessionId: z10.string(),
|
|
26156
|
-
toolUseId: z10.string(),
|
|
26157
|
-
toolName: z10.string(),
|
|
26158
|
-
progress: z10.number(),
|
|
26159
|
-
message: z10.string().optional(),
|
|
26160
|
-
output: z10.string().optional()
|
|
26161
|
-
})),
|
|
26162
|
-
Completed: BusEvent.define("tool.completed", z10.object({
|
|
26163
|
-
sessionId: z10.string(),
|
|
26164
|
-
toolUseId: z10.string(),
|
|
26165
|
-
toolName: z10.string(),
|
|
26166
|
-
result: z10.string(),
|
|
26167
|
-
isError: z10.boolean(),
|
|
26168
|
-
duration: z10.number()
|
|
26169
|
-
})),
|
|
26170
|
-
Error: BusEvent.define("tool.error", z10.object({
|
|
26171
|
-
sessionId: z10.string(),
|
|
26172
|
-
toolUseId: z10.string(),
|
|
26173
|
-
toolName: z10.string(),
|
|
26174
|
-
error: z10.object({
|
|
26175
|
-
code: z10.string(),
|
|
26176
|
-
message: z10.string(),
|
|
26177
|
-
details: z10.unknown().optional()
|
|
26178
|
-
})
|
|
26179
|
-
}))
|
|
26180
|
-
};
|
|
26181
|
-
var PermissionEvents = {
|
|
26182
|
-
Requested: BusEvent.define("permission.requested", z10.object({
|
|
26183
|
-
sessionId: z10.string(),
|
|
26184
|
-
permissionId: z10.string(),
|
|
26185
|
-
toolName: z10.string(),
|
|
26186
|
-
toolUseId: z10.string(),
|
|
26187
|
-
input: z10.record(z10.unknown()),
|
|
26188
|
-
risk: z10.enum(["safe", "moderate", "dangerous"]),
|
|
26189
|
-
message: z10.string(),
|
|
26190
|
-
suggestedAction: z10.enum(["allow", "deny"]).optional(),
|
|
26191
|
-
timeout: z10.number().optional()
|
|
26192
|
-
})),
|
|
26193
|
-
Responded: BusEvent.define("permission.responded", z10.object({
|
|
26194
|
-
sessionId: z10.string(),
|
|
26195
|
-
permissionId: z10.string(),
|
|
26196
|
-
decision: z10.enum(["allow", "deny", "allowAll"]),
|
|
26197
|
-
remember: z10.boolean(),
|
|
26198
|
-
scope: z10.enum(["session", "project", "global"]).optional()
|
|
26199
|
-
})),
|
|
26200
|
-
Timeout: BusEvent.define("permission.timeout", z10.object({
|
|
26201
|
-
sessionId: z10.string(),
|
|
26202
|
-
permissionId: z10.string(),
|
|
26203
|
-
toolName: z10.string(),
|
|
26204
|
-
defaultAction: z10.enum(["allow", "deny"])
|
|
26205
|
-
}))
|
|
26206
|
-
};
|
|
26207
|
-
var ErrorEvents = {
|
|
26208
|
-
General: BusEvent.define("error", z10.object({
|
|
26209
|
-
sessionId: z10.string().optional(),
|
|
26210
|
-
code: z10.string(),
|
|
26211
|
-
message: z10.string(),
|
|
26212
|
-
details: z10.unknown().optional(),
|
|
26213
|
-
recoverable: z10.boolean(),
|
|
26214
|
-
suggestedAction: z10.string().optional()
|
|
26215
|
-
})),
|
|
26216
|
-
Stream: BusEvent.define("error.stream", z10.object({
|
|
26217
|
-
reason: z10.enum(["timeout", "aborted", "network", "server"]),
|
|
26218
|
-
message: z10.string(),
|
|
26219
|
-
retryable: z10.boolean(),
|
|
26220
|
-
retryAfter: z10.number().optional()
|
|
26221
|
-
}))
|
|
26222
|
-
};
|
|
26223
|
-
|
|
26224
|
-
// src/server/adapters/queryRunner.ts
|
|
26225
|
-
var QueryRunner = class {
|
|
26226
|
-
constructor(config2, sessionState) {
|
|
26227
|
-
this.config = config2;
|
|
26228
|
-
this.sessionState = sessionState;
|
|
26229
|
-
this.requestId = uuidv4();
|
|
26230
|
-
this.abortController = new AbortController();
|
|
26231
|
-
}
|
|
26232
|
-
requestId;
|
|
26233
|
-
abortController;
|
|
26234
|
-
isRunning = false;
|
|
26235
|
-
messages = [];
|
|
26236
|
-
startTime = 0;
|
|
26237
|
-
totalCost = 0;
|
|
26238
|
-
totalInputTokens = 0;
|
|
26239
|
-
totalOutputTokens = 0;
|
|
26240
|
-
async run(userMessage) {
|
|
26241
|
-
if (this.isRunning) {
|
|
26242
|
-
throw new Error("QueryRunner is already running");
|
|
26243
|
-
}
|
|
26244
|
-
this.isRunning = true;
|
|
26245
|
-
this.startTime = Date.now();
|
|
26246
|
-
this.messages = [];
|
|
26247
|
-
await Bus.publish(MessageEvents.RequestStarted, {
|
|
26248
|
-
sessionId: this.config.sessionId,
|
|
26249
|
-
requestId: this.requestId,
|
|
26250
|
-
userMessage
|
|
26251
|
-
});
|
|
26252
|
-
this.config.onRequestStart?.(this.requestId);
|
|
26253
|
-
try {
|
|
26254
|
-
const messages = this.buildMessages(userMessage);
|
|
26255
|
-
const systemPrompt = this.buildSystemPrompt();
|
|
26256
|
-
const context = this.buildContext();
|
|
26257
|
-
const canUseTool = this.createCanUseToolFn();
|
|
26258
|
-
const toolUseContext = this.createToolUseContext();
|
|
26259
|
-
const generator = query(
|
|
26260
|
-
messages,
|
|
26261
|
-
systemPrompt,
|
|
26262
|
-
context,
|
|
26263
|
-
canUseTool,
|
|
26264
|
-
toolUseContext
|
|
26265
|
-
);
|
|
26266
|
-
let finishReason = "end_turn";
|
|
26267
|
-
for await (const message of generator) {
|
|
26268
|
-
if (this.abortController.signal.aborted) {
|
|
26269
|
-
finishReason = "aborted";
|
|
26270
|
-
break;
|
|
26271
|
-
}
|
|
26272
|
-
await this.handleMessage(message);
|
|
26273
|
-
if (message.type === "assistant") {
|
|
26274
|
-
const candidate = message.finish;
|
|
26275
|
-
if (candidate === "end_turn" || candidate === "tool_calls" || candidate === "max_tokens") {
|
|
26276
|
-
finishReason = candidate;
|
|
26277
|
-
}
|
|
26278
|
-
}
|
|
26279
|
-
}
|
|
26280
|
-
const result = {
|
|
26281
|
-
requestId: this.requestId,
|
|
26282
|
-
finishReason,
|
|
26283
|
-
messages: this.messages,
|
|
26284
|
-
usage: {
|
|
26285
|
-
inputTokens: this.totalInputTokens,
|
|
26286
|
-
outputTokens: this.totalOutputTokens,
|
|
26287
|
-
totalTokens: this.totalInputTokens + this.totalOutputTokens
|
|
26288
|
-
},
|
|
26289
|
-
cost: {
|
|
26290
|
-
costUSD: this.totalCost
|
|
26291
|
-
},
|
|
26292
|
-
duration: Date.now() - this.startTime
|
|
26293
|
-
};
|
|
26294
|
-
await Bus.publish(MessageEvents.RequestCompleted, {
|
|
26295
|
-
sessionId: this.config.sessionId,
|
|
26296
|
-
requestId: this.requestId,
|
|
26297
|
-
finishReason: result.finishReason,
|
|
26298
|
-
duration: result.duration,
|
|
26299
|
-
totalTokens: result.usage.totalTokens,
|
|
26300
|
-
costUSD: result.cost.costUSD
|
|
26301
|
-
});
|
|
26302
|
-
this.config.onRequestComplete?.(this.requestId, result);
|
|
26303
|
-
return result;
|
|
26304
|
-
} catch (error) {
|
|
26305
|
-
this.config.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
26306
|
-
throw error;
|
|
26307
|
-
} finally {
|
|
26308
|
-
this.isRunning = false;
|
|
26309
|
-
}
|
|
26310
|
-
}
|
|
26311
|
-
abort() {
|
|
26312
|
-
this.abortController.abort();
|
|
26313
|
-
}
|
|
26314
|
-
getStatus() {
|
|
26315
|
-
return {
|
|
26316
|
-
isRunning: this.isRunning,
|
|
26317
|
-
requestId: this.isRunning ? this.requestId : null,
|
|
26318
|
-
messageCount: this.messages.length
|
|
26319
|
-
};
|
|
26320
|
-
}
|
|
26321
|
-
async handleMessage(message) {
|
|
26322
|
-
this.messages.push(message);
|
|
26323
|
-
await Bus.publish(MessageEvents.Created, {
|
|
26324
|
-
sessionId: this.config.sessionId,
|
|
26325
|
-
message
|
|
26326
|
-
});
|
|
26327
|
-
this.config.onMessageYield?.(message);
|
|
26328
|
-
if (message.type === "assistant") {
|
|
26329
|
-
const assistantMsg = message;
|
|
26330
|
-
if (assistantMsg.message?.usage) {
|
|
26331
|
-
this.totalInputTokens += assistantMsg.message.usage.input_tokens ?? 0;
|
|
26332
|
-
this.totalOutputTokens += assistantMsg.message.usage.output_tokens ?? 0;
|
|
26333
|
-
}
|
|
26334
|
-
}
|
|
26335
|
-
}
|
|
26336
|
-
buildMessages(userMessage) {
|
|
26337
|
-
const history = this.sessionState.messages.filter((message) => message.type !== "progress");
|
|
26338
|
-
const nextMessage = createUserMessageFromText(userMessage);
|
|
26339
|
-
return [...history, nextMessage];
|
|
26340
|
-
}
|
|
26341
|
-
buildSystemPrompt() {
|
|
26342
|
-
return this.sessionState.config.systemPrompt ?? [];
|
|
26343
|
-
}
|
|
26344
|
-
buildContext() {
|
|
26345
|
-
return {
|
|
26346
|
-
cwd: this.sessionState.cwd
|
|
26347
|
-
};
|
|
26348
|
-
}
|
|
26349
|
-
createCanUseToolFn() {
|
|
26350
|
-
return async () => ({ result: true });
|
|
26351
|
-
}
|
|
26352
|
-
createToolUseContext() {
|
|
26353
|
-
return {
|
|
26354
|
-
abortController: this.abortController,
|
|
26355
|
-
onQueryLifecycleEvent: (event) => {
|
|
26356
|
-
},
|
|
26357
|
-
sessionContext: new SessionContext(),
|
|
26358
|
-
options: {
|
|
26359
|
-
commands: [],
|
|
26360
|
-
forkNumber: 0,
|
|
26361
|
-
messageLogName: this.requestId,
|
|
26362
|
-
tools: [],
|
|
26363
|
-
verbose: false,
|
|
26364
|
-
safeMode: false,
|
|
26365
|
-
maxThinkingTokens: 16e3
|
|
26366
|
-
},
|
|
26367
|
-
readFileTimestamps: {},
|
|
26368
|
-
setToolJSX: () => {
|
|
26369
|
-
},
|
|
26370
|
-
requestId: this.requestId,
|
|
26371
|
-
messageId: void 0
|
|
26372
|
-
};
|
|
26373
|
-
}
|
|
26374
|
-
};
|
|
26375
|
-
|
|
26376
|
-
// src/server/routes/session.ts
|
|
26377
|
-
function createSessionRoutes() {
|
|
26378
|
-
const router = new Hono();
|
|
26379
|
-
router.post("/", async (c) => {
|
|
26380
|
-
const body = await c.req.json();
|
|
26381
|
-
const { resumeFrom, config: config2 } = body;
|
|
26382
|
-
if (resumeFrom !== void 0 && resumeFrom !== null) {
|
|
26383
|
-
return c.json(
|
|
26384
|
-
{
|
|
26385
|
-
success: false,
|
|
26386
|
-
error: {
|
|
26387
|
-
code: "RESUME_NOT_SUPPORTED",
|
|
26388
|
-
message: "resumeFrom is not supported in current session backend"
|
|
26389
|
-
}
|
|
26390
|
-
},
|
|
26391
|
-
400
|
|
26392
|
-
);
|
|
26393
|
-
}
|
|
26394
|
-
const session = await sessionStateManager.create(
|
|
26395
|
-
process.cwd(),
|
|
26396
|
-
config2
|
|
26397
|
-
);
|
|
26398
|
-
return c.json({
|
|
26399
|
-
success: true,
|
|
26400
|
-
data: {
|
|
26401
|
-
sessionId: session.id,
|
|
26402
|
-
createdAt: session.createdAt,
|
|
26403
|
-
config: session.config
|
|
26404
|
-
}
|
|
26405
|
-
}, 201);
|
|
26406
|
-
});
|
|
26407
|
-
router.get("/", (c) => {
|
|
26408
|
-
const sessions = sessionStateManager.list();
|
|
26409
|
-
const page = parseInt(c.req.query("page") ?? "1");
|
|
26410
|
-
const limit = parseInt(c.req.query("limit") ?? "20");
|
|
26411
|
-
const status = c.req.query("status");
|
|
26412
|
-
let filtered = sessions;
|
|
26413
|
-
if (status) {
|
|
26414
|
-
filtered = filtered.filter((s) => s.status === status);
|
|
26415
|
-
}
|
|
26416
|
-
const start = (page - 1) * limit;
|
|
26417
|
-
const items = filtered.slice(start, start + limit);
|
|
26418
|
-
return c.json({
|
|
26419
|
-
success: true,
|
|
26420
|
-
data: {
|
|
26421
|
-
items: items.map((s) => ({
|
|
26422
|
-
id: s.id,
|
|
26423
|
-
title: s.title,
|
|
26424
|
-
status: s.status,
|
|
26425
|
-
messageCount: s.messages.length,
|
|
26426
|
-
createdAt: s.createdAt,
|
|
26427
|
-
updatedAt: s.updatedAt,
|
|
26428
|
-
config: s.config
|
|
26429
|
-
})),
|
|
26430
|
-
pagination: {
|
|
26431
|
-
page,
|
|
26432
|
-
limit,
|
|
26433
|
-
total: filtered.length,
|
|
26434
|
-
hasMore: start + limit < filtered.length
|
|
26435
|
-
}
|
|
26436
|
-
}
|
|
26437
|
-
});
|
|
26438
|
-
});
|
|
26439
|
-
router.get("/:sessionId", (c) => {
|
|
26440
|
-
const sessionId = c.req.param("sessionId");
|
|
26441
|
-
const session = sessionStateManager.get(sessionId);
|
|
26442
|
-
if (!session) {
|
|
26443
|
-
return c.json({ success: false, error: { code: "SESSION_NOT_FOUND", message: "Session not found" } }, 404);
|
|
26444
|
-
}
|
|
26445
|
-
return c.json({
|
|
26446
|
-
success: true,
|
|
26447
|
-
data: {
|
|
26448
|
-
id: session.id,
|
|
26449
|
-
title: session.title,
|
|
26450
|
-
status: session.status,
|
|
26451
|
-
messages: session.messages,
|
|
26452
|
-
createdAt: session.createdAt,
|
|
26453
|
-
updatedAt: session.updatedAt,
|
|
26454
|
-
config: session.config
|
|
26455
|
-
}
|
|
26456
|
-
});
|
|
26457
|
-
});
|
|
26458
|
-
router.get("/:sessionId/messages", (c) => {
|
|
26459
|
-
const sessionId = c.req.param("sessionId");
|
|
26460
|
-
const session = sessionStateManager.get(sessionId);
|
|
26461
|
-
if (!session) {
|
|
26462
|
-
return c.json({ success: false, error: { code: "SESSION_NOT_FOUND", message: "Session not found" } }, 404);
|
|
26463
|
-
}
|
|
26464
|
-
const after = c.req.query("after");
|
|
26465
|
-
const before = c.req.query("before");
|
|
26466
|
-
const limit = Math.max(1, parseInt(c.req.query("limit") ?? "50", 10));
|
|
26467
|
-
let items = [...session.messages];
|
|
26468
|
-
if (after) {
|
|
26469
|
-
const index = items.findIndex((item) => item.uuid === after);
|
|
26470
|
-
if (index >= 0) {
|
|
26471
|
-
items = items.slice(index + 1);
|
|
26472
|
-
}
|
|
26473
|
-
}
|
|
26474
|
-
if (before) {
|
|
26475
|
-
const index = items.findIndex((item) => item.uuid === before);
|
|
26476
|
-
if (index >= 0) {
|
|
26477
|
-
items = items.slice(0, index);
|
|
26478
|
-
}
|
|
26479
|
-
}
|
|
26480
|
-
items = items.slice(0, limit);
|
|
26481
|
-
return c.json({
|
|
26482
|
-
success: true,
|
|
26483
|
-
data: { items }
|
|
26484
|
-
});
|
|
26485
|
-
});
|
|
26486
|
-
router.patch("/:sessionId", async (c) => {
|
|
26487
|
-
const sessionId = c.req.param("sessionId");
|
|
26488
|
-
const body = await c.req.json();
|
|
26489
|
-
const updated = await sessionStateManager.update(sessionId, body);
|
|
26490
|
-
if (!updated) {
|
|
26491
|
-
return c.json({ success: false, error: { code: "SESSION_NOT_FOUND", message: "Session not found" } }, 404);
|
|
26492
|
-
}
|
|
26493
|
-
const session = sessionStateManager.get(sessionId);
|
|
26494
|
-
return c.json({ success: true, data: session });
|
|
26495
|
-
});
|
|
26496
|
-
router.delete("/:sessionId", async (c) => {
|
|
26497
|
-
const sessionId = c.req.param("sessionId");
|
|
26498
|
-
const deleted = await sessionStateManager.delete(sessionId);
|
|
26499
|
-
return c.json({
|
|
26500
|
-
success: true,
|
|
26501
|
-
data: { deleted, sessionId }
|
|
26502
|
-
});
|
|
26503
|
-
});
|
|
26504
|
-
router.post("/:sessionId/prompt", async (c) => {
|
|
26505
|
-
const sessionId = c.req.param("sessionId");
|
|
26506
|
-
const body = await c.req.json();
|
|
26507
|
-
const { message, attachments, options } = body;
|
|
26508
|
-
const session = sessionStateManager.get(sessionId);
|
|
26509
|
-
if (!session) {
|
|
26510
|
-
return c.json({ success: false, error: { code: "SESSION_NOT_FOUND", message: "Session not found" } }, 404);
|
|
26511
|
-
}
|
|
26512
|
-
const acceptHeader = c.req.header("Accept") ?? "";
|
|
26513
|
-
const wantsSSE = acceptHeader.includes("text/event-stream") || options?.stream !== false;
|
|
26514
|
-
if (wantsSSE) {
|
|
26515
|
-
return streamSSE(c, async (stream) => {
|
|
26516
|
-
const runner = new QueryRunner(
|
|
26517
|
-
{ sessionId },
|
|
26518
|
-
session
|
|
26519
|
-
);
|
|
26520
|
-
sessionStateManager.setCurrentRunner(sessionId, runner);
|
|
26521
|
-
try {
|
|
26522
|
-
const result = await runner.run(message);
|
|
26523
|
-
await stream.writeSSE({
|
|
26524
|
-
event: "request.completed",
|
|
26525
|
-
data: JSON.stringify({
|
|
26526
|
-
type: "request.completed",
|
|
26527
|
-
sessionId,
|
|
26528
|
-
timestamp: Date.now(),
|
|
26529
|
-
data: {
|
|
26530
|
-
finishReason: result.finishReason,
|
|
26531
|
-
usage: result.usage,
|
|
26532
|
-
cost: result.cost,
|
|
26533
|
-
duration: result.duration
|
|
26534
|
-
}
|
|
26535
|
-
})
|
|
26536
|
-
});
|
|
26537
|
-
} catch (error) {
|
|
26538
|
-
await stream.writeSSE({
|
|
26539
|
-
event: "error",
|
|
26540
|
-
data: JSON.stringify({
|
|
26541
|
-
type: "error",
|
|
26542
|
-
sessionId,
|
|
26543
|
-
timestamp: Date.now(),
|
|
26544
|
-
data: {
|
|
26545
|
-
code: "QUERY_ERROR",
|
|
26546
|
-
message: error instanceof Error ? error.message : String(error),
|
|
26547
|
-
recoverable: false
|
|
26548
|
-
}
|
|
26549
|
-
})
|
|
26550
|
-
});
|
|
26551
|
-
} finally {
|
|
26552
|
-
sessionStateManager.clearCurrentRunner(sessionId);
|
|
26553
|
-
}
|
|
26554
|
-
});
|
|
26555
|
-
} else {
|
|
26556
|
-
const runner = new QueryRunner({ sessionId }, session);
|
|
26557
|
-
sessionStateManager.setCurrentRunner(sessionId, runner);
|
|
26558
|
-
try {
|
|
26559
|
-
const result = await runner.run(message);
|
|
26560
|
-
return c.json({ success: true, data: result });
|
|
26561
|
-
} finally {
|
|
26562
|
-
sessionStateManager.clearCurrentRunner(sessionId);
|
|
26563
|
-
}
|
|
26564
|
-
}
|
|
26565
|
-
});
|
|
26566
|
-
router.post("/:sessionId/abort", (c) => {
|
|
26567
|
-
const sessionId = c.req.param("sessionId");
|
|
26568
|
-
const session = sessionStateManager.get(sessionId);
|
|
26569
|
-
if (!session) {
|
|
26570
|
-
return c.json({ success: false, error: { code: "SESSION_NOT_FOUND", message: "Session not found" } }, 404);
|
|
26571
|
-
}
|
|
26572
|
-
const runner = sessionStateManager.getCurrentRunner(sessionId);
|
|
26573
|
-
if (runner) {
|
|
26574
|
-
runner.abort();
|
|
26575
|
-
return c.json({ success: true, data: { aborted: true } });
|
|
26576
|
-
}
|
|
26577
|
-
return c.json({ success: true, data: { aborted: false, reason: "No running query" } });
|
|
26578
|
-
});
|
|
26579
|
-
return router;
|
|
26580
|
-
}
|
|
26581
|
-
|
|
26582
|
-
// src/server/routes/tool.ts
|
|
26583
|
-
import { Hono as Hono2 } from "hono";
|
|
26584
|
-
|
|
26585
25999
|
// src/tools/index.ts
|
|
26586
26000
|
import { memoize as memoize4 } from "lodash-es";
|
|
26587
26001
|
|
|
26588
26002
|
// src/tools/ai/AskExpertModelTool/AskExpertModelTool.tsx
|
|
26589
26003
|
import * as React47 from "react";
|
|
26590
26004
|
import { Box as Box36, Text as Text40 } from "ink";
|
|
26591
|
-
import { z as
|
|
26005
|
+
import { z as z10 } from "zod";
|
|
26592
26006
|
|
|
26593
26007
|
// src/utils/session/expertChatStorage.ts
|
|
26594
26008
|
import { existsSync as existsSync17, readFileSync as readFileSync9, writeFileSync as writeFileSync4, mkdirSync as mkdirSync10 } from "fs";
|
|
@@ -26879,14 +26293,14 @@ Current situation: Users report 3-5 second delays when scrolling through the lis
|
|
|
26879
26293
|
Question: What are the most effective React optimization techniques for handling large lists, and how should I prioritize implementing virtualization vs memoization vs other approaches?"`;
|
|
26880
26294
|
|
|
26881
26295
|
// src/tools/ai/AskExpertModelTool/AskExpertModelTool.tsx
|
|
26882
|
-
var inputSchema9 =
|
|
26883
|
-
question:
|
|
26296
|
+
var inputSchema9 = z10.strictObject({
|
|
26297
|
+
question: z10.string().describe(
|
|
26884
26298
|
"COMPLETE SELF-CONTAINED QUESTION: Must include full background context, relevant details, and a clear independent question. The expert model will receive ONLY this content with no access to previous conversation or external context. Structure as: 1) Background/Context 2) Specific situation/problem 3) Clear question. Ensure the expert can fully understand and respond without needing additional information."
|
|
26885
26299
|
),
|
|
26886
|
-
expert_model:
|
|
26300
|
+
expert_model: z10.string().describe(
|
|
26887
26301
|
"The expert model to use (e.g., gpt-5, claude-3-5-sonnet-20241022)"
|
|
26888
26302
|
),
|
|
26889
|
-
chat_session_id:
|
|
26303
|
+
chat_session_id: z10.string().describe(
|
|
26890
26304
|
'Chat session ID: use "new" for new session or existing session ID'
|
|
26891
26305
|
)
|
|
26892
26306
|
});
|
|
@@ -27238,7 +26652,7 @@ Please check your model configuration with /model command.`
|
|
|
27238
26652
|
// src/tools/interaction/AskUserQuestionTool/AskUserQuestionTool.tsx
|
|
27239
26653
|
import { Box as Box37, Text as Text41 } from "ink";
|
|
27240
26654
|
import React48 from "react";
|
|
27241
|
-
import { z as
|
|
26655
|
+
import { z as z11 } from "zod";
|
|
27242
26656
|
|
|
27243
26657
|
// src/constants/figures.ts
|
|
27244
26658
|
var BLACK_CIRCLE = env.platform === "macos" ? "\u23FA" : "\u25CF";
|
|
@@ -27258,19 +26672,19 @@ Usage notes:
|
|
|
27258
26672
|
- If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label`;
|
|
27259
26673
|
|
|
27260
26674
|
// src/tools/interaction/AskUserQuestionTool/AskUserQuestionTool.tsx
|
|
27261
|
-
var optionSchema =
|
|
27262
|
-
label:
|
|
27263
|
-
description:
|
|
26675
|
+
var optionSchema = z11.object({
|
|
26676
|
+
label: z11.string(),
|
|
26677
|
+
description: z11.string()
|
|
27264
26678
|
});
|
|
27265
|
-
var questionSchema =
|
|
27266
|
-
question:
|
|
27267
|
-
header:
|
|
27268
|
-
options:
|
|
27269
|
-
multiSelect:
|
|
26679
|
+
var questionSchema = z11.object({
|
|
26680
|
+
question: z11.string(),
|
|
26681
|
+
header: z11.string(),
|
|
26682
|
+
options: z11.array(optionSchema).min(2).max(4),
|
|
26683
|
+
multiSelect: z11.boolean()
|
|
27270
26684
|
});
|
|
27271
|
-
var inputSchema10 =
|
|
27272
|
-
questions:
|
|
27273
|
-
answers:
|
|
26685
|
+
var inputSchema10 = z11.strictObject({
|
|
26686
|
+
questions: z11.array(questionSchema).min(1).max(4),
|
|
26687
|
+
answers: z11.record(z11.string(), z11.string()).optional()
|
|
27274
26688
|
}).refine(
|
|
27275
26689
|
(input) => {
|
|
27276
26690
|
const questionTexts = input.questions.map((q) => q.question);
|
|
@@ -27340,7 +26754,7 @@ var AskUserQuestionTool = {
|
|
|
27340
26754
|
// src/tools/system/TaskOutputTool/TaskOutputTool.tsx
|
|
27341
26755
|
import { Box as Box38, Text as Text42 } from "ink";
|
|
27342
26756
|
import React49 from "react";
|
|
27343
|
-
import { z as
|
|
26757
|
+
import { z as z12 } from "zod";
|
|
27344
26758
|
|
|
27345
26759
|
// src/utils/session/backgroundTasks.ts
|
|
27346
26760
|
var backgroundTasks = /* @__PURE__ */ new Map();
|
|
@@ -27502,11 +26916,11 @@ The assistant defers analysis because:
|
|
|
27502
26916
|
// src/tools/system/TaskOutputTool/TaskOutputTool.tsx
|
|
27503
26917
|
var TOOL_PROGRESS_OPEN_TAG2 = ["<tool", "-progress>"].join("");
|
|
27504
26918
|
var TOOL_PROGRESS_CLOSE_TAG2 = ["</tool", "-progress>"].join("");
|
|
27505
|
-
var inputSchema11 =
|
|
27506
|
-
task_id:
|
|
27507
|
-
block:
|
|
27508
|
-
timeout:
|
|
27509
|
-
analyze:
|
|
26919
|
+
var inputSchema11 = z12.strictObject({
|
|
26920
|
+
task_id: z12.string().describe("The task ID to get output from"),
|
|
26921
|
+
block: z12.boolean().optional().default(true).describe("Whether to wait for completion"),
|
|
26922
|
+
timeout: z12.number().min(0).max(6e5).optional().default(3e4).describe("Max wait time in ms"),
|
|
26923
|
+
analyze: z12.boolean().optional().describe("Analyze the output for errors and warnings")
|
|
27510
26924
|
});
|
|
27511
26925
|
function isTaskOutputLspAnalysisEnabled() {
|
|
27512
26926
|
const raw = String(process.env.PYB_TASKOUTPUT_LSP_ANALYSIS ?? "").trim().toLowerCase();
|
|
@@ -27583,7 +26997,7 @@ async function analyzeOutputWithLsp(output, exitCode) {
|
|
|
27583
26997
|
if (exitCode !== 0 || errorCount > 0 || warningCount > 0) {
|
|
27584
26998
|
try {
|
|
27585
26999
|
const { isAbsolute: isAbsolute11, resolve: resolve16 } = await import("path");
|
|
27586
|
-
const { getSessionRoot: getSessionRoot2 } = await import("./state-
|
|
27000
|
+
const { getSessionRoot: getSessionRoot2 } = await import("./state-GWKESQ7O.js");
|
|
27587
27001
|
const lines = output.split("\n");
|
|
27588
27002
|
const uniqueFiles = /* @__PURE__ */ new Set();
|
|
27589
27003
|
const lspSuggestions = [];
|
|
@@ -27854,7 +27268,7 @@ ${output.task.output.trimEnd()}
|
|
|
27854
27268
|
import { rmSync as rmSync2, existsSync as existsSync18, statSync as statSync12 } from "fs";
|
|
27855
27269
|
import { Box as Box39, Text as Text43 } from "ink";
|
|
27856
27270
|
import * as React50 from "react";
|
|
27857
|
-
import { z as
|
|
27271
|
+
import { z as z13 } from "zod";
|
|
27858
27272
|
import { isAbsolute as isAbsolute9, relative as relative11, resolve as resolve10 } from "path";
|
|
27859
27273
|
|
|
27860
27274
|
// src/tools/filesystem/DeleteTool/prompt.ts
|
|
@@ -27921,11 +27335,11 @@ Delete({
|
|
|
27921
27335
|
`.trim();
|
|
27922
27336
|
|
|
27923
27337
|
// src/tools/filesystem/DeleteTool/DeleteTool.tsx
|
|
27924
|
-
var inputSchema12 =
|
|
27925
|
-
file_paths:
|
|
27338
|
+
var inputSchema12 = z13.strictObject({
|
|
27339
|
+
file_paths: z13.array(z13.string()).describe(
|
|
27926
27340
|
"The list of file paths you want to delete, you MUST set file path to absolute path."
|
|
27927
27341
|
),
|
|
27928
|
-
force:
|
|
27342
|
+
force: z13.boolean().optional().describe(
|
|
27929
27343
|
"Force deletion even if the file is referenced by other files (LSP check)."
|
|
27930
27344
|
)
|
|
27931
27345
|
});
|
|
@@ -27985,7 +27399,7 @@ var DeleteTool = {
|
|
|
27985
27399
|
}
|
|
27986
27400
|
if (!force) {
|
|
27987
27401
|
try {
|
|
27988
|
-
const { LspFacade: LspFacade2 } = await import("./lsp-
|
|
27402
|
+
const { LspFacade: LspFacade2 } = await import("./lsp-M5NJ7YC7.js");
|
|
27989
27403
|
const referenceDetail = await LspFacade2.checkFileReferences(fullPath);
|
|
27990
27404
|
if (referenceDetail) {
|
|
27991
27405
|
failedItems.push(
|
|
@@ -28045,7 +27459,7 @@ var DeleteTool = {
|
|
|
28045
27459
|
// src/tools/system/KillShellTool/KillShellTool.tsx
|
|
28046
27460
|
import { Box as Box40, Text as Text44 } from "ink";
|
|
28047
27461
|
import React51 from "react";
|
|
28048
|
-
import { z as
|
|
27462
|
+
import { z as z14 } from "zod";
|
|
28049
27463
|
|
|
28050
27464
|
// src/tools/system/KillShellTool/prompt.ts
|
|
28051
27465
|
var TOOL_NAME16 = "KillShell";
|
|
@@ -28059,8 +27473,8 @@ var PROMPT11 = `
|
|
|
28059
27473
|
`;
|
|
28060
27474
|
|
|
28061
27475
|
// src/tools/system/KillShellTool/KillShellTool.tsx
|
|
28062
|
-
var inputSchema13 =
|
|
28063
|
-
shell_id:
|
|
27476
|
+
var inputSchema13 = z14.strictObject({
|
|
27477
|
+
shell_id: z14.string().describe("The ID of the background shell to kill")
|
|
28064
27478
|
});
|
|
28065
27479
|
var KillShellTool = {
|
|
28066
27480
|
name: TOOL_NAME16,
|
|
@@ -28136,7 +27550,7 @@ var KillShellTool = {
|
|
|
28136
27550
|
// src/tools/mcp/ListMcpResourcesTool/ListMcpResourcesTool.tsx
|
|
28137
27551
|
import { Box as Box41, Text as Text45 } from "ink";
|
|
28138
27552
|
import React52 from "react";
|
|
28139
|
-
import { z as
|
|
27553
|
+
import { z as z15 } from "zod";
|
|
28140
27554
|
import { ListResourcesResultSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
28141
27555
|
|
|
28142
27556
|
// src/tools/mcp/ListMcpResourcesTool/prompt.ts
|
|
@@ -28156,8 +27570,8 @@ Parameters:
|
|
|
28156
27570
|
resources from all servers will be returned.`;
|
|
28157
27571
|
|
|
28158
27572
|
// src/tools/mcp/ListMcpResourcesTool/ListMcpResourcesTool.tsx
|
|
28159
|
-
var inputSchema14 =
|
|
28160
|
-
server:
|
|
27573
|
+
var inputSchema14 = z15.strictObject({
|
|
27574
|
+
server: z15.string().optional().describe("Optional server name to filter resources by")
|
|
28161
27575
|
});
|
|
28162
27576
|
var ListMcpResourcesTool = {
|
|
28163
27577
|
name: TOOL_NAME17,
|
|
@@ -28256,9 +27670,9 @@ import { existsSync as existsSync19, readFileSync as readFileSync10, statSync as
|
|
|
28256
27670
|
import { Box as Box42, Text as Text46 } from "ink";
|
|
28257
27671
|
import { relative as relative12, resolve as resolve11 } from "path";
|
|
28258
27672
|
import React53 from "react";
|
|
28259
|
-
import { z as
|
|
28260
|
-
var inputSchema15 =
|
|
28261
|
-
operation:
|
|
27673
|
+
import { z as z16 } from "zod";
|
|
27674
|
+
var inputSchema15 = z16.strictObject({
|
|
27675
|
+
operation: z16.enum([
|
|
28262
27676
|
"goToDefinition",
|
|
28263
27677
|
"findReferences",
|
|
28264
27678
|
"hover",
|
|
@@ -28271,15 +27685,15 @@ var inputSchema15 = z17.strictObject({
|
|
|
28271
27685
|
"getScope",
|
|
28272
27686
|
"diagnostics"
|
|
28273
27687
|
]).describe("The LSP operation to perform"),
|
|
28274
|
-
filePath:
|
|
28275
|
-
line:
|
|
28276
|
-
character:
|
|
28277
|
-
query:
|
|
28278
|
-
waitForDiagnostics:
|
|
28279
|
-
timeout:
|
|
27688
|
+
filePath: z16.string().describe("The absolute or relative path to the file"),
|
|
27689
|
+
line: z16.number().int().positive().optional().describe("The line number (1-based, as shown in editors). Required for location-based operations."),
|
|
27690
|
+
character: z16.number().int().positive().optional().describe("The character offset (1-based, as shown in editors). Required for location-based operations."),
|
|
27691
|
+
query: z16.string().optional().describe('The query string for workspaceSymbol. Required when operation is "workspaceSymbol".'),
|
|
27692
|
+
waitForDiagnostics: z16.boolean().optional().describe('If true, wait for fresh diagnostics from the server (used with "diagnostics" operation)'),
|
|
27693
|
+
timeout: z16.number().optional().describe("Timeout in milliseconds for waiting operations (default: 5000)")
|
|
28280
27694
|
});
|
|
28281
|
-
var outputSchema =
|
|
28282
|
-
operation:
|
|
27695
|
+
var outputSchema = z16.object({
|
|
27696
|
+
operation: z16.enum([
|
|
28283
27697
|
"goToDefinition",
|
|
28284
27698
|
"findReferences",
|
|
28285
27699
|
"hover",
|
|
@@ -28292,10 +27706,10 @@ var outputSchema = z17.object({
|
|
|
28292
27706
|
"getScope",
|
|
28293
27707
|
"diagnostics"
|
|
28294
27708
|
]).describe("The LSP operation that was performed"),
|
|
28295
|
-
result:
|
|
28296
|
-
filePath:
|
|
28297
|
-
resultCount:
|
|
28298
|
-
fileCount:
|
|
27709
|
+
result: z16.string().describe("The formatted result of the LSP operation"),
|
|
27710
|
+
filePath: z16.string().describe("The file path the operation was performed on"),
|
|
27711
|
+
resultCount: z16.number().int().nonnegative().optional().describe("Number of results (definitions, references, symbols)"),
|
|
27712
|
+
fileCount: z16.number().int().nonnegative().optional().describe("Number of files containing results")
|
|
28299
27713
|
});
|
|
28300
27714
|
var OPERATION_LABELS = {
|
|
28301
27715
|
goToDefinition: { singular: "definition", plural: "definitions" },
|
|
@@ -28718,7 +28132,7 @@ var LspTool = {
|
|
|
28718
28132
|
// src/tools/mcp/ReadMcpResourceTool/ReadMcpResourceTool.tsx
|
|
28719
28133
|
import { Box as Box43, Text as Text47 } from "ink";
|
|
28720
28134
|
import React54 from "react";
|
|
28721
|
-
import { z as
|
|
28135
|
+
import { z as z17 } from "zod";
|
|
28722
28136
|
import { ReadResourceResultSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
28723
28137
|
|
|
28724
28138
|
// src/tools/mcp/ReadMcpResourceTool/prompt.ts
|
|
@@ -28736,9 +28150,9 @@ Parameters:
|
|
|
28736
28150
|
- uri (required): The URI of the resource to read`;
|
|
28737
28151
|
|
|
28738
28152
|
// src/tools/mcp/ReadMcpResourceTool/ReadMcpResourceTool.tsx
|
|
28739
|
-
var inputSchema16 =
|
|
28740
|
-
server:
|
|
28741
|
-
uri:
|
|
28153
|
+
var inputSchema16 = z17.strictObject({
|
|
28154
|
+
server: z17.string().describe("The MCP server name"),
|
|
28155
|
+
uri: z17.string().describe("The resource URI to read")
|
|
28742
28156
|
});
|
|
28743
28157
|
var ReadMcpResourceTool = {
|
|
28744
28158
|
name: TOOL_NAME18,
|
|
@@ -28847,18 +28261,18 @@ var ReadMcpResourceTool = {
|
|
|
28847
28261
|
};
|
|
28848
28262
|
|
|
28849
28263
|
// src/tools/ai/SkillTool/SkillTool.tsx
|
|
28850
|
-
import { z as
|
|
28264
|
+
import { z as z18 } from "zod";
|
|
28851
28265
|
import * as React55 from "react";
|
|
28852
28266
|
|
|
28853
28267
|
// src/tools/ai/SkillTool/prompt.ts
|
|
28854
28268
|
var TOOL_NAME19 = "Skill";
|
|
28855
28269
|
|
|
28856
28270
|
// src/tools/ai/SkillTool/SkillTool.tsx
|
|
28857
|
-
var inputSchema17 =
|
|
28858
|
-
skill:
|
|
28271
|
+
var inputSchema17 = z18.strictObject({
|
|
28272
|
+
skill: z18.string().describe(
|
|
28859
28273
|
"The skill name (no arguments). Use a value from <available_skills>."
|
|
28860
28274
|
),
|
|
28861
|
-
args:
|
|
28275
|
+
args: z18.string().optional().describe("Optional arguments for the skill (freeform text)")
|
|
28862
28276
|
});
|
|
28863
28277
|
function normalizeCommandModelName(model) {
|
|
28864
28278
|
if (typeof model !== "string") return void 0;
|
|
@@ -29083,7 +28497,7 @@ function findCommand(commandName, commands) {
|
|
|
29083
28497
|
import { last as last2, memoize as memoize3 } from "lodash-es";
|
|
29084
28498
|
import React56 from "react";
|
|
29085
28499
|
import { Box as Box44, Text as Text48 } from "ink";
|
|
29086
|
-
import { z as
|
|
28500
|
+
import { z as z19 } from "zod";
|
|
29087
28501
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
29088
28502
|
import { existsSync as existsSync20, readFileSync as readFileSync11 } from "fs";
|
|
29089
28503
|
|
|
@@ -29243,17 +28657,17 @@ assistant: "I'm going to use the Task tool to launch the with the greeting-respo
|
|
|
29243
28657
|
}
|
|
29244
28658
|
|
|
29245
28659
|
// src/tools/agent/TaskTool/TaskTool.tsx
|
|
29246
|
-
var inputSchema18 =
|
|
29247
|
-
description:
|
|
29248
|
-
prompt:
|
|
29249
|
-
subagent_type:
|
|
29250
|
-
model:
|
|
28660
|
+
var inputSchema18 = z19.object({
|
|
28661
|
+
description: z19.string().describe("A short (3-5 word) description of the task"),
|
|
28662
|
+
prompt: z19.string().describe("The task for the agent to perform"),
|
|
28663
|
+
subagent_type: z19.string().describe("The type of specialized agent to use for this task"),
|
|
28664
|
+
model: z19.enum(["sonnet", "opus", "haiku"]).optional().describe(
|
|
29251
28665
|
"Optional model to use for this agent. If not specified, inherits from parent. Prefer haiku for quick, straightforward tasks to minimize cost and latency."
|
|
29252
28666
|
),
|
|
29253
|
-
resume:
|
|
28667
|
+
resume: z19.string().optional().describe(
|
|
29254
28668
|
"Optional agent ID to resume from. If provided, the agent will continue from the previous execution transcript."
|
|
29255
28669
|
),
|
|
29256
|
-
run_in_background:
|
|
28670
|
+
run_in_background: z19.boolean().optional().describe(
|
|
29257
28671
|
"Set to true to run this agent in the background. Use TaskOutput to read the output later."
|
|
29258
28672
|
)
|
|
29259
28673
|
});
|
|
@@ -29779,21 +29193,21 @@ var TaskTool = {
|
|
|
29779
29193
|
};
|
|
29780
29194
|
|
|
29781
29195
|
// src/tools/interaction/TaskCreateTool/TaskCreateTool.tsx
|
|
29782
|
-
import { z as
|
|
29196
|
+
import { z as z21 } from "zod";
|
|
29783
29197
|
|
|
29784
29198
|
// src/utils/session/taskToolUtils.ts
|
|
29785
|
-
import { z as
|
|
29786
|
-
var jsonValueSchema =
|
|
29787
|
-
() =>
|
|
29788
|
-
|
|
29789
|
-
|
|
29790
|
-
|
|
29791
|
-
|
|
29792
|
-
|
|
29793
|
-
|
|
29199
|
+
import { z as z20 } from "zod";
|
|
29200
|
+
var jsonValueSchema = z20.lazy(
|
|
29201
|
+
() => z20.union([
|
|
29202
|
+
z20.string(),
|
|
29203
|
+
z20.number(),
|
|
29204
|
+
z20.boolean(),
|
|
29205
|
+
z20.null(),
|
|
29206
|
+
z20.array(jsonValueSchema),
|
|
29207
|
+
z20.record(jsonValueSchema)
|
|
29794
29208
|
])
|
|
29795
29209
|
);
|
|
29796
|
-
var metadataSchema =
|
|
29210
|
+
var metadataSchema = z20.record(jsonValueSchema);
|
|
29797
29211
|
function mapStatusToOutput(status) {
|
|
29798
29212
|
if (status === "done") return "completed";
|
|
29799
29213
|
if (status === "deleted") return "deleted";
|
|
@@ -30223,11 +29637,11 @@ The assistant used TaskCreate because:
|
|
|
30223
29637
|
`.trim();
|
|
30224
29638
|
|
|
30225
29639
|
// src/tools/interaction/TaskCreateTool/TaskCreateTool.tsx
|
|
30226
|
-
var inputSchema19 =
|
|
30227
|
-
listId:
|
|
30228
|
-
subject:
|
|
30229
|
-
description:
|
|
30230
|
-
activeForm:
|
|
29640
|
+
var inputSchema19 = z21.strictObject({
|
|
29641
|
+
listId: z21.string().min(1).optional(),
|
|
29642
|
+
subject: z21.string().min(1),
|
|
29643
|
+
description: z21.string().min(1),
|
|
29644
|
+
activeForm: z21.string().min(1),
|
|
30231
29645
|
metadata: metadataSchema.optional()
|
|
30232
29646
|
});
|
|
30233
29647
|
var TaskCreateTool = {
|
|
@@ -30304,7 +29718,7 @@ var TaskCreateTool = {
|
|
|
30304
29718
|
};
|
|
30305
29719
|
|
|
30306
29720
|
// src/tools/interaction/TaskGetTool/TaskGetTool.tsx
|
|
30307
|
-
import { z as
|
|
29721
|
+
import { z as z22 } from "zod";
|
|
30308
29722
|
|
|
30309
29723
|
// src/tools/interaction/TaskGetTool/prompt.ts
|
|
30310
29724
|
var TOOL_NAME21 = "TaskGet";
|
|
@@ -30340,9 +29754,9 @@ Assistant: I'll fetch the task details first.
|
|
|
30340
29754
|
`.trim();
|
|
30341
29755
|
|
|
30342
29756
|
// src/tools/interaction/TaskGetTool/TaskGetTool.tsx
|
|
30343
|
-
var inputSchema20 =
|
|
30344
|
-
listId:
|
|
30345
|
-
taskId:
|
|
29757
|
+
var inputSchema20 = z22.strictObject({
|
|
29758
|
+
listId: z22.string().min(1).optional(),
|
|
29759
|
+
taskId: z22.string().min(1)
|
|
30346
29760
|
});
|
|
30347
29761
|
var TaskGetTool = {
|
|
30348
29762
|
name: TOOL_NAME21,
|
|
@@ -30404,7 +29818,7 @@ var TaskGetTool = {
|
|
|
30404
29818
|
};
|
|
30405
29819
|
|
|
30406
29820
|
// src/tools/interaction/TaskListTool/TaskListTool.tsx
|
|
30407
|
-
import { z as
|
|
29821
|
+
import { z as z23 } from "zod";
|
|
30408
29822
|
|
|
30409
29823
|
// src/tools/interaction/TaskListTool/prompt.ts
|
|
30410
29824
|
var TOOL_NAME22 = "TaskList";
|
|
@@ -30455,9 +29869,9 @@ Assistant: I'll list tasks to show the updated ready/blocked breakdown.
|
|
|
30455
29869
|
`.trim();
|
|
30456
29870
|
|
|
30457
29871
|
// src/tools/interaction/TaskListTool/TaskListTool.tsx
|
|
30458
|
-
var inputSchema21 =
|
|
30459
|
-
listId:
|
|
30460
|
-
status:
|
|
29872
|
+
var inputSchema21 = z23.strictObject({
|
|
29873
|
+
listId: z23.string().min(1).optional(),
|
|
29874
|
+
status: z23.enum(["pending", "in_progress", "completed", "deleted"]).optional()
|
|
30461
29875
|
});
|
|
30462
29876
|
var filterByStatus = (tasks, statuses) => {
|
|
30463
29877
|
if (!statuses || statuses.length === 0) {
|
|
@@ -30558,7 +29972,7 @@ var TaskListTool = {
|
|
|
30558
29972
|
};
|
|
30559
29973
|
|
|
30560
29974
|
// src/tools/interaction/TaskUpdateTool/TaskUpdateTool.tsx
|
|
30561
|
-
import { z as
|
|
29975
|
+
import { z as z24 } from "zod";
|
|
30562
29976
|
|
|
30563
29977
|
// src/tools/interaction/TaskUpdateTool/prompt.ts
|
|
30564
29978
|
var TOOL_NAME23 = "TaskUpdate";
|
|
@@ -31002,16 +30416,16 @@ var compareTaskId = (left, right) => {
|
|
|
31002
30416
|
if (rightIsNumber) return 1;
|
|
31003
30417
|
return left.id.localeCompare(right.id);
|
|
31004
30418
|
};
|
|
31005
|
-
var inputSchema22 =
|
|
31006
|
-
listId:
|
|
31007
|
-
taskId:
|
|
31008
|
-
subject:
|
|
31009
|
-
description:
|
|
31010
|
-
activeForm:
|
|
31011
|
-
status:
|
|
30419
|
+
var inputSchema22 = z24.strictObject({
|
|
30420
|
+
listId: z24.string().min(1).optional(),
|
|
30421
|
+
taskId: z24.string().min(1),
|
|
30422
|
+
subject: z24.string().optional(),
|
|
30423
|
+
description: z24.string().optional(),
|
|
30424
|
+
activeForm: z24.string().optional(),
|
|
30425
|
+
status: z24.enum(["pending", "in_progress", "completed", "deleted"]).optional(),
|
|
31012
30426
|
metadata: metadataSchema.optional(),
|
|
31013
|
-
addBlockedBy:
|
|
31014
|
-
addBlocks:
|
|
30427
|
+
addBlockedBy: z24.array(z24.string()).optional(),
|
|
30428
|
+
addBlocks: z24.array(z24.string()).optional()
|
|
31015
30429
|
});
|
|
31016
30430
|
var TaskUpdateTool = {
|
|
31017
30431
|
name: TOOL_NAME23,
|
|
@@ -31286,7 +30700,7 @@ import { existsSync as existsSync21, lstatSync, mkdirSync as mkdirSync11, readdi
|
|
|
31286
30700
|
import { Box as Box45, Text as Text49 } from "ink";
|
|
31287
30701
|
import { join as join12 } from "path";
|
|
31288
30702
|
import * as React57 from "react";
|
|
31289
|
-
import { z as
|
|
30703
|
+
import { z as z25 } from "zod";
|
|
31290
30704
|
|
|
31291
30705
|
// src/tools/memory/MemoryReadTool/prompt.ts
|
|
31292
30706
|
var TOOL_NAME24 = "MemoryRead";
|
|
@@ -31310,8 +30724,8 @@ Security:
|
|
|
31310
30724
|
`;
|
|
31311
30725
|
|
|
31312
30726
|
// src/tools/memory/MemoryReadTool/MemoryReadTool.tsx
|
|
31313
|
-
var inputSchema23 =
|
|
31314
|
-
file_path:
|
|
30727
|
+
var inputSchema23 = z25.strictObject({
|
|
30728
|
+
file_path: z25.string().optional().describe("Optional path to a specific memory file to read")
|
|
31315
30729
|
});
|
|
31316
30730
|
var MemoryReadTool = {
|
|
31317
30731
|
name: TOOL_NAME24,
|
|
@@ -31420,7 +30834,7 @@ ${files}`;
|
|
|
31420
30834
|
// src/tools/memory/MemoryWriteTool/MemoryWriteTool.tsx
|
|
31421
30835
|
import { Box as Box46, Text as Text50 } from "ink";
|
|
31422
30836
|
import * as React58 from "react";
|
|
31423
|
-
import { z as
|
|
30837
|
+
import { z as z26 } from "zod";
|
|
31424
30838
|
|
|
31425
30839
|
// src/services/memory/write.ts
|
|
31426
30840
|
import {
|
|
@@ -31496,10 +30910,10 @@ This is the summary of the task execution...",
|
|
|
31496
30910
|
`;
|
|
31497
30911
|
|
|
31498
30912
|
// src/tools/memory/MemoryWriteTool/MemoryWriteTool.tsx
|
|
31499
|
-
var inputSchema24 =
|
|
31500
|
-
file_path:
|
|
31501
|
-
content:
|
|
31502
|
-
mode:
|
|
30913
|
+
var inputSchema24 = z26.strictObject({
|
|
30914
|
+
file_path: z26.string().describe("Path to the memory file to write"),
|
|
30915
|
+
content: z26.string().describe("Content to write to the file"),
|
|
30916
|
+
mode: z26.enum(["append", "replace"]).optional().describe("Write mode: append adds to existing content, replace overwrites")
|
|
31503
30917
|
});
|
|
31504
30918
|
var MemoryWriteTool = {
|
|
31505
30919
|
name: TOOL_NAME25,
|
|
@@ -31619,7 +31033,622 @@ var getReadOnlyTools = memoize4(async () => {
|
|
|
31619
31033
|
return tools.filter((_, index) => isEnabled5[index]);
|
|
31620
31034
|
});
|
|
31621
31035
|
|
|
31036
|
+
// src/server/bus/eventIdGenerator.ts
|
|
31037
|
+
var EventIdGenerator = class {
|
|
31038
|
+
sequenceMap = /* @__PURE__ */ new Map();
|
|
31039
|
+
nextId(sessionId) {
|
|
31040
|
+
const next = (this.sequenceMap.get(sessionId) ?? 0) + 1;
|
|
31041
|
+
this.sequenceMap.set(sessionId, next);
|
|
31042
|
+
return `sess-${sessionId}-seq-${String(next).padStart(6, "0")}`;
|
|
31043
|
+
}
|
|
31044
|
+
};
|
|
31045
|
+
function parseSessionIdFromEventId(eventId) {
|
|
31046
|
+
const match = eventId.match(/^sess-(.+)-seq-(\d+)$/);
|
|
31047
|
+
return match?.[1] ?? null;
|
|
31048
|
+
}
|
|
31049
|
+
|
|
31050
|
+
// src/server/bus/index.ts
|
|
31051
|
+
var BusEvent;
|
|
31052
|
+
((BusEvent2) => {
|
|
31053
|
+
const registry = /* @__PURE__ */ new Map();
|
|
31054
|
+
function define(type3, properties) {
|
|
31055
|
+
const result = { type: type3, properties };
|
|
31056
|
+
registry.set(type3, result);
|
|
31057
|
+
return result;
|
|
31058
|
+
}
|
|
31059
|
+
BusEvent2.define = define;
|
|
31060
|
+
function getSchema(type3) {
|
|
31061
|
+
return registry.get(type3);
|
|
31062
|
+
}
|
|
31063
|
+
BusEvent2.getSchema = getSchema;
|
|
31064
|
+
})(BusEvent || (BusEvent = {}));
|
|
31065
|
+
var Bus;
|
|
31066
|
+
((Bus2) => {
|
|
31067
|
+
const state = {
|
|
31068
|
+
subscriptions: /* @__PURE__ */ new Map()
|
|
31069
|
+
};
|
|
31070
|
+
const eventIdGenerator = new EventIdGenerator();
|
|
31071
|
+
async function publish(def, properties) {
|
|
31072
|
+
const sessionId = typeof properties.sessionId === "string" ? properties.sessionId : void 0;
|
|
31073
|
+
const payload = {
|
|
31074
|
+
type: def.type,
|
|
31075
|
+
...sessionId ? { id: eventIdGenerator.nextId(sessionId) } : {},
|
|
31076
|
+
properties
|
|
31077
|
+
};
|
|
31078
|
+
const pending = [];
|
|
31079
|
+
for (const key of [def.type, "*"]) {
|
|
31080
|
+
const match = state.subscriptions.get(key);
|
|
31081
|
+
if (match) {
|
|
31082
|
+
for (const sub of match) {
|
|
31083
|
+
const result = sub(payload);
|
|
31084
|
+
if (result instanceof Promise) {
|
|
31085
|
+
pending.push(result);
|
|
31086
|
+
}
|
|
31087
|
+
}
|
|
31088
|
+
}
|
|
31089
|
+
}
|
|
31090
|
+
await Promise.all(pending);
|
|
31091
|
+
}
|
|
31092
|
+
Bus2.publish = publish;
|
|
31093
|
+
function subscribe(def, callback) {
|
|
31094
|
+
return raw(def.type, callback);
|
|
31095
|
+
}
|
|
31096
|
+
Bus2.subscribe = subscribe;
|
|
31097
|
+
function subscribeAll(callback) {
|
|
31098
|
+
return raw("*", callback);
|
|
31099
|
+
}
|
|
31100
|
+
Bus2.subscribeAll = subscribeAll;
|
|
31101
|
+
function raw(type3, callback) {
|
|
31102
|
+
const match = state.subscriptions.get(type3) ?? [];
|
|
31103
|
+
match.push(callback);
|
|
31104
|
+
state.subscriptions.set(type3, match);
|
|
31105
|
+
return () => {
|
|
31106
|
+
const subscriptions = state.subscriptions.get(type3);
|
|
31107
|
+
if (!subscriptions) return;
|
|
31108
|
+
const index = subscriptions.indexOf(callback);
|
|
31109
|
+
if (index !== -1) {
|
|
31110
|
+
subscriptions.splice(index, 1);
|
|
31111
|
+
}
|
|
31112
|
+
};
|
|
31113
|
+
}
|
|
31114
|
+
})(Bus || (Bus = {}));
|
|
31115
|
+
|
|
31116
|
+
// src/server/events/definitions.ts
|
|
31117
|
+
import { z as z27 } from "zod";
|
|
31118
|
+
var ServerEvents = {
|
|
31119
|
+
Connected: BusEvent.define("server.connected", z27.object({
|
|
31120
|
+
serverVersion: z27.string(),
|
|
31121
|
+
protocolVersion: z27.string(),
|
|
31122
|
+
features: z27.array(z27.string())
|
|
31123
|
+
})),
|
|
31124
|
+
Heartbeat: BusEvent.define("server.heartbeat", z27.object({
|
|
31125
|
+
timestamp: z27.number()
|
|
31126
|
+
})),
|
|
31127
|
+
Status: BusEvent.define("server.status", z27.object({
|
|
31128
|
+
status: z27.enum(["healthy", "degraded", "unhealthy"]),
|
|
31129
|
+
components: z27.object({
|
|
31130
|
+
llm: z27.enum(["connected", "disconnected"]),
|
|
31131
|
+
mcp: z27.enum(["connected", "disconnected"]),
|
|
31132
|
+
tools: z27.enum(["ready", "initializing"])
|
|
31133
|
+
})
|
|
31134
|
+
}))
|
|
31135
|
+
};
|
|
31136
|
+
var SessionEvents = {
|
|
31137
|
+
Created: BusEvent.define("session.created", z27.object({
|
|
31138
|
+
sessionId: z27.string(),
|
|
31139
|
+
config: z27.object({
|
|
31140
|
+
model: z27.string(),
|
|
31141
|
+
agent: z27.string(),
|
|
31142
|
+
outputStyle: z27.string()
|
|
31143
|
+
}),
|
|
31144
|
+
resumedFrom: z27.string().optional()
|
|
31145
|
+
})),
|
|
31146
|
+
Updated: BusEvent.define("session.updated", z27.object({
|
|
31147
|
+
sessionId: z27.string(),
|
|
31148
|
+
title: z27.string().optional(),
|
|
31149
|
+
config: z27.object({
|
|
31150
|
+
model: z27.string().optional(),
|
|
31151
|
+
agent: z27.string().optional(),
|
|
31152
|
+
outputStyle: z27.string().optional()
|
|
31153
|
+
}).optional()
|
|
31154
|
+
})),
|
|
31155
|
+
Deleted: BusEvent.define("session.deleted", z27.object({
|
|
31156
|
+
sessionId: z27.string()
|
|
31157
|
+
})),
|
|
31158
|
+
Status: BusEvent.define("session.status", z27.object({
|
|
31159
|
+
sessionId: z27.string(),
|
|
31160
|
+
status: z27.enum(["active", "idle", "waiting_input", "processing"]),
|
|
31161
|
+
currentRequestId: z27.string().optional()
|
|
31162
|
+
}))
|
|
31163
|
+
};
|
|
31164
|
+
var MessageEvents = {
|
|
31165
|
+
Created: BusEvent.define("message.created", z27.object({
|
|
31166
|
+
sessionId: z27.string(),
|
|
31167
|
+
message: z27.any()
|
|
31168
|
+
})),
|
|
31169
|
+
Updated: BusEvent.define("message.updated", z27.object({
|
|
31170
|
+
sessionId: z27.string(),
|
|
31171
|
+
message: z27.any(),
|
|
31172
|
+
delta: z27.object({
|
|
31173
|
+
type: z27.enum(["text", "tool_use"]),
|
|
31174
|
+
content: z27.string(),
|
|
31175
|
+
index: z27.number().optional()
|
|
31176
|
+
}).optional()
|
|
31177
|
+
})),
|
|
31178
|
+
Completed: BusEvent.define("message.completed", z27.object({
|
|
31179
|
+
sessionId: z27.string(),
|
|
31180
|
+
messageId: z27.string(),
|
|
31181
|
+
finishReason: z27.enum(["end_turn", "tool_calls", "max_tokens", "aborted"]),
|
|
31182
|
+
usage: z27.object({
|
|
31183
|
+
inputTokens: z27.number(),
|
|
31184
|
+
outputTokens: z27.number(),
|
|
31185
|
+
totalTokens: z27.number()
|
|
31186
|
+
}),
|
|
31187
|
+
cost: z27.object({
|
|
31188
|
+
costUSD: z27.number()
|
|
31189
|
+
})
|
|
31190
|
+
})),
|
|
31191
|
+
RequestStarted: BusEvent.define("request.started", z27.object({
|
|
31192
|
+
sessionId: z27.string(),
|
|
31193
|
+
requestId: z27.string(),
|
|
31194
|
+
userMessage: z27.string()
|
|
31195
|
+
})),
|
|
31196
|
+
RequestCompleted: BusEvent.define("request.completed", z27.object({
|
|
31197
|
+
sessionId: z27.string(),
|
|
31198
|
+
requestId: z27.string(),
|
|
31199
|
+
finishReason: z27.enum(["end_turn", "tool_calls", "max_tokens", "aborted"]),
|
|
31200
|
+
duration: z27.number(),
|
|
31201
|
+
totalTokens: z27.number(),
|
|
31202
|
+
costUSD: z27.number()
|
|
31203
|
+
}))
|
|
31204
|
+
};
|
|
31205
|
+
var ToolEvents = {
|
|
31206
|
+
Started: BusEvent.define("tool.started", z27.object({
|
|
31207
|
+
sessionId: z27.string(),
|
|
31208
|
+
toolUseId: z27.string(),
|
|
31209
|
+
toolName: z27.string(),
|
|
31210
|
+
input: z27.record(z27.unknown()),
|
|
31211
|
+
dangerousLevel: z27.enum(["safe", "moderate", "dangerous"]),
|
|
31212
|
+
requiresPermission: z27.boolean()
|
|
31213
|
+
})),
|
|
31214
|
+
Progress: BusEvent.define("tool.progress", z27.object({
|
|
31215
|
+
sessionId: z27.string(),
|
|
31216
|
+
toolUseId: z27.string(),
|
|
31217
|
+
toolName: z27.string(),
|
|
31218
|
+
progress: z27.number(),
|
|
31219
|
+
message: z27.string().optional(),
|
|
31220
|
+
output: z27.string().optional()
|
|
31221
|
+
})),
|
|
31222
|
+
Completed: BusEvent.define("tool.completed", z27.object({
|
|
31223
|
+
sessionId: z27.string(),
|
|
31224
|
+
toolUseId: z27.string(),
|
|
31225
|
+
toolName: z27.string(),
|
|
31226
|
+
result: z27.string(),
|
|
31227
|
+
isError: z27.boolean(),
|
|
31228
|
+
duration: z27.number()
|
|
31229
|
+
})),
|
|
31230
|
+
Error: BusEvent.define("tool.error", z27.object({
|
|
31231
|
+
sessionId: z27.string(),
|
|
31232
|
+
toolUseId: z27.string(),
|
|
31233
|
+
toolName: z27.string(),
|
|
31234
|
+
error: z27.object({
|
|
31235
|
+
code: z27.string(),
|
|
31236
|
+
message: z27.string(),
|
|
31237
|
+
details: z27.unknown().optional()
|
|
31238
|
+
})
|
|
31239
|
+
}))
|
|
31240
|
+
};
|
|
31241
|
+
var PermissionEvents = {
|
|
31242
|
+
Requested: BusEvent.define("permission.requested", z27.object({
|
|
31243
|
+
sessionId: z27.string(),
|
|
31244
|
+
permissionId: z27.string(),
|
|
31245
|
+
toolName: z27.string(),
|
|
31246
|
+
toolUseId: z27.string(),
|
|
31247
|
+
input: z27.record(z27.unknown()),
|
|
31248
|
+
risk: z27.enum(["safe", "moderate", "dangerous"]),
|
|
31249
|
+
message: z27.string(),
|
|
31250
|
+
suggestedAction: z27.enum(["allow", "deny"]).optional(),
|
|
31251
|
+
timeout: z27.number().optional()
|
|
31252
|
+
})),
|
|
31253
|
+
Responded: BusEvent.define("permission.responded", z27.object({
|
|
31254
|
+
sessionId: z27.string(),
|
|
31255
|
+
permissionId: z27.string(),
|
|
31256
|
+
decision: z27.enum(["allow", "deny", "allowAll"]),
|
|
31257
|
+
remember: z27.boolean(),
|
|
31258
|
+
scope: z27.enum(["session", "project", "global"]).optional()
|
|
31259
|
+
})),
|
|
31260
|
+
Timeout: BusEvent.define("permission.timeout", z27.object({
|
|
31261
|
+
sessionId: z27.string(),
|
|
31262
|
+
permissionId: z27.string(),
|
|
31263
|
+
toolName: z27.string(),
|
|
31264
|
+
defaultAction: z27.enum(["allow", "deny"])
|
|
31265
|
+
}))
|
|
31266
|
+
};
|
|
31267
|
+
var ErrorEvents = {
|
|
31268
|
+
General: BusEvent.define("error", z27.object({
|
|
31269
|
+
sessionId: z27.string().optional(),
|
|
31270
|
+
code: z27.string(),
|
|
31271
|
+
message: z27.string(),
|
|
31272
|
+
details: z27.unknown().optional(),
|
|
31273
|
+
recoverable: z27.boolean(),
|
|
31274
|
+
suggestedAction: z27.string().optional()
|
|
31275
|
+
})),
|
|
31276
|
+
Stream: BusEvent.define("error.stream", z27.object({
|
|
31277
|
+
reason: z27.enum(["timeout", "aborted", "network", "server"]),
|
|
31278
|
+
message: z27.string(),
|
|
31279
|
+
retryable: z27.boolean(),
|
|
31280
|
+
retryAfter: z27.number().optional()
|
|
31281
|
+
}))
|
|
31282
|
+
};
|
|
31283
|
+
|
|
31284
|
+
// src/server/adapters/queryRunner.ts
|
|
31285
|
+
var QueryRunner = class {
|
|
31286
|
+
constructor(config2, sessionState) {
|
|
31287
|
+
this.config = config2;
|
|
31288
|
+
this.sessionState = sessionState;
|
|
31289
|
+
this.requestId = uuidv4();
|
|
31290
|
+
this.abortController = new AbortController();
|
|
31291
|
+
}
|
|
31292
|
+
requestId;
|
|
31293
|
+
abortController;
|
|
31294
|
+
isRunning = false;
|
|
31295
|
+
messages = [];
|
|
31296
|
+
startTime = 0;
|
|
31297
|
+
totalCost = 0;
|
|
31298
|
+
totalInputTokens = 0;
|
|
31299
|
+
totalOutputTokens = 0;
|
|
31300
|
+
async run(userMessage) {
|
|
31301
|
+
if (this.isRunning) {
|
|
31302
|
+
throw new Error("QueryRunner is already running");
|
|
31303
|
+
}
|
|
31304
|
+
this.isRunning = true;
|
|
31305
|
+
this.startTime = Date.now();
|
|
31306
|
+
this.messages = [];
|
|
31307
|
+
await Bus.publish(MessageEvents.RequestStarted, {
|
|
31308
|
+
sessionId: this.config.sessionId,
|
|
31309
|
+
requestId: this.requestId,
|
|
31310
|
+
userMessage
|
|
31311
|
+
});
|
|
31312
|
+
this.config.onRequestStart?.(this.requestId);
|
|
31313
|
+
try {
|
|
31314
|
+
const messages = this.buildMessages(userMessage);
|
|
31315
|
+
const [systemPrompt, context, toolUseContext] = await Promise.all([
|
|
31316
|
+
this.buildSystemPrompt(),
|
|
31317
|
+
this.buildContext(),
|
|
31318
|
+
this.createToolUseContext()
|
|
31319
|
+
]);
|
|
31320
|
+
const canUseTool = this.createCanUseToolFn();
|
|
31321
|
+
const generator = query(
|
|
31322
|
+
messages,
|
|
31323
|
+
systemPrompt,
|
|
31324
|
+
context,
|
|
31325
|
+
canUseTool,
|
|
31326
|
+
toolUseContext
|
|
31327
|
+
);
|
|
31328
|
+
let finishReason = "end_turn";
|
|
31329
|
+
for await (const message of generator) {
|
|
31330
|
+
if (this.abortController.signal.aborted) {
|
|
31331
|
+
finishReason = "aborted";
|
|
31332
|
+
break;
|
|
31333
|
+
}
|
|
31334
|
+
await this.handleMessage(message);
|
|
31335
|
+
if (message.type === "assistant") {
|
|
31336
|
+
const candidate = message.finish;
|
|
31337
|
+
if (candidate === "end_turn" || candidate === "tool_calls" || candidate === "max_tokens") {
|
|
31338
|
+
finishReason = candidate;
|
|
31339
|
+
}
|
|
31340
|
+
}
|
|
31341
|
+
}
|
|
31342
|
+
const result = {
|
|
31343
|
+
requestId: this.requestId,
|
|
31344
|
+
finishReason,
|
|
31345
|
+
messages: this.messages,
|
|
31346
|
+
usage: {
|
|
31347
|
+
inputTokens: this.totalInputTokens,
|
|
31348
|
+
outputTokens: this.totalOutputTokens,
|
|
31349
|
+
totalTokens: this.totalInputTokens + this.totalOutputTokens
|
|
31350
|
+
},
|
|
31351
|
+
cost: {
|
|
31352
|
+
costUSD: this.totalCost
|
|
31353
|
+
},
|
|
31354
|
+
duration: Date.now() - this.startTime
|
|
31355
|
+
};
|
|
31356
|
+
await Bus.publish(MessageEvents.RequestCompleted, {
|
|
31357
|
+
sessionId: this.config.sessionId,
|
|
31358
|
+
requestId: this.requestId,
|
|
31359
|
+
finishReason: result.finishReason,
|
|
31360
|
+
duration: result.duration,
|
|
31361
|
+
totalTokens: result.usage.totalTokens,
|
|
31362
|
+
costUSD: result.cost.costUSD
|
|
31363
|
+
});
|
|
31364
|
+
this.config.onRequestComplete?.(this.requestId, result);
|
|
31365
|
+
return result;
|
|
31366
|
+
} catch (error) {
|
|
31367
|
+
this.config.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
31368
|
+
throw error;
|
|
31369
|
+
} finally {
|
|
31370
|
+
this.isRunning = false;
|
|
31371
|
+
}
|
|
31372
|
+
}
|
|
31373
|
+
abort() {
|
|
31374
|
+
this.abortController.abort();
|
|
31375
|
+
}
|
|
31376
|
+
getStatus() {
|
|
31377
|
+
return {
|
|
31378
|
+
isRunning: this.isRunning,
|
|
31379
|
+
requestId: this.isRunning ? this.requestId : null,
|
|
31380
|
+
messageCount: this.messages.length
|
|
31381
|
+
};
|
|
31382
|
+
}
|
|
31383
|
+
async handleMessage(message) {
|
|
31384
|
+
this.messages.push(message);
|
|
31385
|
+
await Bus.publish(MessageEvents.Created, {
|
|
31386
|
+
sessionId: this.config.sessionId,
|
|
31387
|
+
message
|
|
31388
|
+
});
|
|
31389
|
+
this.config.onMessageYield?.(message);
|
|
31390
|
+
if (message.type === "assistant") {
|
|
31391
|
+
const assistantMsg = message;
|
|
31392
|
+
if (assistantMsg.message?.usage) {
|
|
31393
|
+
this.totalInputTokens += assistantMsg.message.usage.input_tokens ?? 0;
|
|
31394
|
+
this.totalOutputTokens += assistantMsg.message.usage.output_tokens ?? 0;
|
|
31395
|
+
}
|
|
31396
|
+
}
|
|
31397
|
+
}
|
|
31398
|
+
buildMessages(userMessage) {
|
|
31399
|
+
const history = this.sessionState.messages.filter((message) => message.type !== "progress");
|
|
31400
|
+
const nextMessage = createUserMessageFromText(userMessage);
|
|
31401
|
+
return [...history, nextMessage];
|
|
31402
|
+
}
|
|
31403
|
+
async buildSystemPrompt() {
|
|
31404
|
+
const basePrompt = await getSystemPrompt();
|
|
31405
|
+
const sessionPrompt = this.sessionState.config.systemPrompt ?? [];
|
|
31406
|
+
if (sessionPrompt.length === 0) return basePrompt;
|
|
31407
|
+
return [...basePrompt, ...sessionPrompt];
|
|
31408
|
+
}
|
|
31409
|
+
async buildContext() {
|
|
31410
|
+
const baseContext = await getContext();
|
|
31411
|
+
return {
|
|
31412
|
+
...baseContext,
|
|
31413
|
+
cwd: this.sessionState.cwd
|
|
31414
|
+
};
|
|
31415
|
+
}
|
|
31416
|
+
createCanUseToolFn() {
|
|
31417
|
+
return async (tool, input, toolUseContext, assistantMessage) => hasPermissionsToUseTool(tool, input, toolUseContext, assistantMessage);
|
|
31418
|
+
}
|
|
31419
|
+
async createToolUseContext() {
|
|
31420
|
+
const tools = await getTools();
|
|
31421
|
+
return {
|
|
31422
|
+
abortController: this.abortController,
|
|
31423
|
+
onQueryLifecycleEvent: (event) => {
|
|
31424
|
+
},
|
|
31425
|
+
sessionContext: new SessionContext(),
|
|
31426
|
+
options: {
|
|
31427
|
+
commands: [],
|
|
31428
|
+
forkNumber: 0,
|
|
31429
|
+
messageLogName: this.requestId,
|
|
31430
|
+
tools,
|
|
31431
|
+
verbose: false,
|
|
31432
|
+
safeMode: false,
|
|
31433
|
+
maxThinkingTokens: 16e3
|
|
31434
|
+
},
|
|
31435
|
+
readFileTimestamps: {},
|
|
31436
|
+
setToolJSX: () => {
|
|
31437
|
+
},
|
|
31438
|
+
requestId: this.requestId,
|
|
31439
|
+
messageId: void 0
|
|
31440
|
+
};
|
|
31441
|
+
}
|
|
31442
|
+
};
|
|
31443
|
+
|
|
31444
|
+
// src/server/routes/session.ts
|
|
31445
|
+
function createSessionRoutes() {
|
|
31446
|
+
const router = new Hono();
|
|
31447
|
+
router.post("/", async (c) => {
|
|
31448
|
+
const body = await c.req.json();
|
|
31449
|
+
const { resumeFrom, config: config2 } = body;
|
|
31450
|
+
if (resumeFrom !== void 0 && resumeFrom !== null) {
|
|
31451
|
+
return c.json(
|
|
31452
|
+
{
|
|
31453
|
+
success: false,
|
|
31454
|
+
error: {
|
|
31455
|
+
code: "RESUME_NOT_SUPPORTED",
|
|
31456
|
+
message: "resumeFrom is not supported in current session backend"
|
|
31457
|
+
}
|
|
31458
|
+
},
|
|
31459
|
+
400
|
|
31460
|
+
);
|
|
31461
|
+
}
|
|
31462
|
+
const session = await sessionStateManager.create(
|
|
31463
|
+
process.cwd(),
|
|
31464
|
+
config2
|
|
31465
|
+
);
|
|
31466
|
+
return c.json({
|
|
31467
|
+
success: true,
|
|
31468
|
+
data: {
|
|
31469
|
+
sessionId: session.id,
|
|
31470
|
+
createdAt: session.createdAt,
|
|
31471
|
+
config: session.config
|
|
31472
|
+
}
|
|
31473
|
+
}, 201);
|
|
31474
|
+
});
|
|
31475
|
+
router.get("/", (c) => {
|
|
31476
|
+
const sessions = sessionStateManager.list();
|
|
31477
|
+
const page = parseInt(c.req.query("page") ?? "1");
|
|
31478
|
+
const limit = parseInt(c.req.query("limit") ?? "20");
|
|
31479
|
+
const status = c.req.query("status");
|
|
31480
|
+
let filtered = sessions;
|
|
31481
|
+
if (status) {
|
|
31482
|
+
filtered = filtered.filter((s) => s.status === status);
|
|
31483
|
+
}
|
|
31484
|
+
const start = (page - 1) * limit;
|
|
31485
|
+
const items = filtered.slice(start, start + limit);
|
|
31486
|
+
return c.json({
|
|
31487
|
+
success: true,
|
|
31488
|
+
data: {
|
|
31489
|
+
items: items.map((s) => ({
|
|
31490
|
+
id: s.id,
|
|
31491
|
+
title: s.title,
|
|
31492
|
+
status: s.status,
|
|
31493
|
+
messageCount: s.messages.length,
|
|
31494
|
+
createdAt: s.createdAt,
|
|
31495
|
+
updatedAt: s.updatedAt,
|
|
31496
|
+
config: s.config
|
|
31497
|
+
})),
|
|
31498
|
+
pagination: {
|
|
31499
|
+
page,
|
|
31500
|
+
limit,
|
|
31501
|
+
total: filtered.length,
|
|
31502
|
+
hasMore: start + limit < filtered.length
|
|
31503
|
+
}
|
|
31504
|
+
}
|
|
31505
|
+
});
|
|
31506
|
+
});
|
|
31507
|
+
router.get("/:sessionId", (c) => {
|
|
31508
|
+
const sessionId = c.req.param("sessionId");
|
|
31509
|
+
const session = sessionStateManager.get(sessionId);
|
|
31510
|
+
if (!session) {
|
|
31511
|
+
return c.json({ success: false, error: { code: "SESSION_NOT_FOUND", message: "Session not found" } }, 404);
|
|
31512
|
+
}
|
|
31513
|
+
return c.json({
|
|
31514
|
+
success: true,
|
|
31515
|
+
data: {
|
|
31516
|
+
id: session.id,
|
|
31517
|
+
title: session.title,
|
|
31518
|
+
status: session.status,
|
|
31519
|
+
messages: session.messages,
|
|
31520
|
+
createdAt: session.createdAt,
|
|
31521
|
+
updatedAt: session.updatedAt,
|
|
31522
|
+
config: session.config
|
|
31523
|
+
}
|
|
31524
|
+
});
|
|
31525
|
+
});
|
|
31526
|
+
router.get("/:sessionId/messages", (c) => {
|
|
31527
|
+
const sessionId = c.req.param("sessionId");
|
|
31528
|
+
const session = sessionStateManager.get(sessionId);
|
|
31529
|
+
if (!session) {
|
|
31530
|
+
return c.json({ success: false, error: { code: "SESSION_NOT_FOUND", message: "Session not found" } }, 404);
|
|
31531
|
+
}
|
|
31532
|
+
const after = c.req.query("after");
|
|
31533
|
+
const before = c.req.query("before");
|
|
31534
|
+
const limit = Math.max(1, parseInt(c.req.query("limit") ?? "50", 10));
|
|
31535
|
+
let items = [...session.messages];
|
|
31536
|
+
if (after) {
|
|
31537
|
+
const index = items.findIndex((item) => item.uuid === after);
|
|
31538
|
+
if (index >= 0) {
|
|
31539
|
+
items = items.slice(index + 1);
|
|
31540
|
+
}
|
|
31541
|
+
}
|
|
31542
|
+
if (before) {
|
|
31543
|
+
const index = items.findIndex((item) => item.uuid === before);
|
|
31544
|
+
if (index >= 0) {
|
|
31545
|
+
items = items.slice(0, index);
|
|
31546
|
+
}
|
|
31547
|
+
}
|
|
31548
|
+
items = items.slice(0, limit);
|
|
31549
|
+
return c.json({
|
|
31550
|
+
success: true,
|
|
31551
|
+
data: { items }
|
|
31552
|
+
});
|
|
31553
|
+
});
|
|
31554
|
+
router.patch("/:sessionId", async (c) => {
|
|
31555
|
+
const sessionId = c.req.param("sessionId");
|
|
31556
|
+
const body = await c.req.json();
|
|
31557
|
+
const updated = await sessionStateManager.update(sessionId, body);
|
|
31558
|
+
if (!updated) {
|
|
31559
|
+
return c.json({ success: false, error: { code: "SESSION_NOT_FOUND", message: "Session not found" } }, 404);
|
|
31560
|
+
}
|
|
31561
|
+
const session = sessionStateManager.get(sessionId);
|
|
31562
|
+
return c.json({ success: true, data: session });
|
|
31563
|
+
});
|
|
31564
|
+
router.delete("/:sessionId", async (c) => {
|
|
31565
|
+
const sessionId = c.req.param("sessionId");
|
|
31566
|
+
const deleted = await sessionStateManager.delete(sessionId);
|
|
31567
|
+
return c.json({
|
|
31568
|
+
success: true,
|
|
31569
|
+
data: { deleted, sessionId }
|
|
31570
|
+
});
|
|
31571
|
+
});
|
|
31572
|
+
router.post("/:sessionId/prompt", async (c) => {
|
|
31573
|
+
const sessionId = c.req.param("sessionId");
|
|
31574
|
+
const body = await c.req.json();
|
|
31575
|
+
const { message, attachments, options } = body;
|
|
31576
|
+
const session = sessionStateManager.get(sessionId);
|
|
31577
|
+
if (!session) {
|
|
31578
|
+
return c.json({ success: false, error: { code: "SESSION_NOT_FOUND", message: "Session not found" } }, 404);
|
|
31579
|
+
}
|
|
31580
|
+
const acceptHeader = c.req.header("Accept") ?? "";
|
|
31581
|
+
const wantsSSE = acceptHeader.includes("text/event-stream") || options?.stream !== false;
|
|
31582
|
+
if (wantsSSE) {
|
|
31583
|
+
return streamSSE(c, async (stream) => {
|
|
31584
|
+
const runner = new QueryRunner(
|
|
31585
|
+
{ sessionId },
|
|
31586
|
+
session
|
|
31587
|
+
);
|
|
31588
|
+
sessionStateManager.setCurrentRunner(sessionId, runner);
|
|
31589
|
+
try {
|
|
31590
|
+
const result = await runner.run(message);
|
|
31591
|
+
await stream.writeSSE({
|
|
31592
|
+
event: "request.completed",
|
|
31593
|
+
data: JSON.stringify({
|
|
31594
|
+
type: "request.completed",
|
|
31595
|
+
sessionId,
|
|
31596
|
+
timestamp: Date.now(),
|
|
31597
|
+
data: {
|
|
31598
|
+
finishReason: result.finishReason,
|
|
31599
|
+
usage: result.usage,
|
|
31600
|
+
cost: result.cost,
|
|
31601
|
+
duration: result.duration
|
|
31602
|
+
}
|
|
31603
|
+
})
|
|
31604
|
+
});
|
|
31605
|
+
} catch (error) {
|
|
31606
|
+
await stream.writeSSE({
|
|
31607
|
+
event: "error",
|
|
31608
|
+
data: JSON.stringify({
|
|
31609
|
+
type: "error",
|
|
31610
|
+
sessionId,
|
|
31611
|
+
timestamp: Date.now(),
|
|
31612
|
+
data: {
|
|
31613
|
+
code: "QUERY_ERROR",
|
|
31614
|
+
message: error instanceof Error ? error.message : String(error),
|
|
31615
|
+
recoverable: false
|
|
31616
|
+
}
|
|
31617
|
+
})
|
|
31618
|
+
});
|
|
31619
|
+
} finally {
|
|
31620
|
+
sessionStateManager.clearCurrentRunner(sessionId);
|
|
31621
|
+
}
|
|
31622
|
+
});
|
|
31623
|
+
} else {
|
|
31624
|
+
const runner = new QueryRunner({ sessionId }, session);
|
|
31625
|
+
sessionStateManager.setCurrentRunner(sessionId, runner);
|
|
31626
|
+
try {
|
|
31627
|
+
const result = await runner.run(message);
|
|
31628
|
+
return c.json({ success: true, data: result });
|
|
31629
|
+
} finally {
|
|
31630
|
+
sessionStateManager.clearCurrentRunner(sessionId);
|
|
31631
|
+
}
|
|
31632
|
+
}
|
|
31633
|
+
});
|
|
31634
|
+
router.post("/:sessionId/abort", (c) => {
|
|
31635
|
+
const sessionId = c.req.param("sessionId");
|
|
31636
|
+
const session = sessionStateManager.get(sessionId);
|
|
31637
|
+
if (!session) {
|
|
31638
|
+
return c.json({ success: false, error: { code: "SESSION_NOT_FOUND", message: "Session not found" } }, 404);
|
|
31639
|
+
}
|
|
31640
|
+
const runner = sessionStateManager.getCurrentRunner(sessionId);
|
|
31641
|
+
if (runner) {
|
|
31642
|
+
runner.abort();
|
|
31643
|
+
return c.json({ success: true, data: { aborted: true } });
|
|
31644
|
+
}
|
|
31645
|
+
return c.json({ success: true, data: { aborted: false, reason: "No running query" } });
|
|
31646
|
+
});
|
|
31647
|
+
return router;
|
|
31648
|
+
}
|
|
31649
|
+
|
|
31622
31650
|
// src/server/routes/tool.ts
|
|
31651
|
+
import { Hono as Hono2 } from "hono";
|
|
31623
31652
|
function createToolRoutes() {
|
|
31624
31653
|
const router = new Hono2();
|
|
31625
31654
|
router.get("/", async (c) => {
|
|
@@ -31892,6 +31921,971 @@ function createMCPRoutes() {
|
|
|
31892
31921
|
return router;
|
|
31893
31922
|
}
|
|
31894
31923
|
|
|
31924
|
+
// src/server/routes/providers.ts
|
|
31925
|
+
import * as crypto2 from "crypto";
|
|
31926
|
+
import { Hono as Hono6 } from "hono";
|
|
31927
|
+
|
|
31928
|
+
// src/server/modelPool/providerCatalog.ts
|
|
31929
|
+
function normalizeText(input) {
|
|
31930
|
+
return String(input ?? "").trim();
|
|
31931
|
+
}
|
|
31932
|
+
function normalizeProviderID(input) {
|
|
31933
|
+
return normalizeText(input).toLowerCase();
|
|
31934
|
+
}
|
|
31935
|
+
function rankSources(priority) {
|
|
31936
|
+
const rank = /* @__PURE__ */ new Map();
|
|
31937
|
+
priority.forEach((source, index) => {
|
|
31938
|
+
rank.set(source, index);
|
|
31939
|
+
});
|
|
31940
|
+
return rank;
|
|
31941
|
+
}
|
|
31942
|
+
function composeProviderCatalog(sources, priority = ["env", "auth", "plugin", "config"]) {
|
|
31943
|
+
const ranks = rankSources(priority);
|
|
31944
|
+
const fallbackRank = priority.length + 1;
|
|
31945
|
+
const sortedSources = [...sources].sort((a, b) => {
|
|
31946
|
+
const aRank = ranks.get(a.sourceType) ?? fallbackRank;
|
|
31947
|
+
const bRank = ranks.get(b.sourceType) ?? fallbackRank;
|
|
31948
|
+
return aRank - bRank;
|
|
31949
|
+
});
|
|
31950
|
+
const providerMap = /* @__PURE__ */ new Map();
|
|
31951
|
+
for (const source of sortedSources) {
|
|
31952
|
+
for (const provider of source.providers) {
|
|
31953
|
+
const providerID = normalizeProviderID(provider?.providerID);
|
|
31954
|
+
if (!providerID) continue;
|
|
31955
|
+
const displayName = normalizeText(provider?.displayName) || providerID;
|
|
31956
|
+
const connected2 = provider?.connected === true;
|
|
31957
|
+
const existing = providerMap.get(providerID);
|
|
31958
|
+
if (!existing) {
|
|
31959
|
+
providerMap.set(providerID, {
|
|
31960
|
+
providerID,
|
|
31961
|
+
displayName,
|
|
31962
|
+
connected: connected2
|
|
31963
|
+
});
|
|
31964
|
+
continue;
|
|
31965
|
+
}
|
|
31966
|
+
if (!existing.connected && connected2) {
|
|
31967
|
+
existing.connected = true;
|
|
31968
|
+
}
|
|
31969
|
+
}
|
|
31970
|
+
}
|
|
31971
|
+
const all = [...providerMap.values()].sort(
|
|
31972
|
+
(a, b) => a.providerID.localeCompare(b.providerID)
|
|
31973
|
+
);
|
|
31974
|
+
const connected = all.filter((item) => item.connected).map((item) => item.providerID);
|
|
31975
|
+
let defaultModel = null;
|
|
31976
|
+
for (const source of sortedSources) {
|
|
31977
|
+
if (source.defaultModel) {
|
|
31978
|
+
defaultModel = source.defaultModel;
|
|
31979
|
+
break;
|
|
31980
|
+
}
|
|
31981
|
+
}
|
|
31982
|
+
return {
|
|
31983
|
+
all,
|
|
31984
|
+
default: defaultModel,
|
|
31985
|
+
connected
|
|
31986
|
+
};
|
|
31987
|
+
}
|
|
31988
|
+
function buildProviderSourceFromProfiles(sourceType, profiles, defaultModel) {
|
|
31989
|
+
const providerMap = /* @__PURE__ */ new Map();
|
|
31990
|
+
for (const profile of profiles) {
|
|
31991
|
+
if (profile?.isActive !== true) continue;
|
|
31992
|
+
const providerID = normalizeProviderID(profile?.provider);
|
|
31993
|
+
if (!providerID) continue;
|
|
31994
|
+
const existing = providerMap.get(providerID);
|
|
31995
|
+
const connected = normalizeText(profile?.apiKey).length > 0;
|
|
31996
|
+
const displayName = normalizeText(profile?.provider) || providerID;
|
|
31997
|
+
if (!existing) {
|
|
31998
|
+
providerMap.set(providerID, {
|
|
31999
|
+
providerID,
|
|
32000
|
+
displayName,
|
|
32001
|
+
connected
|
|
32002
|
+
});
|
|
32003
|
+
continue;
|
|
32004
|
+
}
|
|
32005
|
+
if (!existing.connected && connected) {
|
|
32006
|
+
existing.connected = true;
|
|
32007
|
+
}
|
|
32008
|
+
}
|
|
32009
|
+
return {
|
|
32010
|
+
sourceType,
|
|
32011
|
+
providers: [...providerMap.values()].sort(
|
|
32012
|
+
(a, b) => a.providerID.localeCompare(b.providerID)
|
|
32013
|
+
),
|
|
32014
|
+
defaultModel
|
|
32015
|
+
};
|
|
32016
|
+
}
|
|
32017
|
+
|
|
32018
|
+
// src/server/modelPool/authKernel.ts
|
|
32019
|
+
function parseTtlMs(input) {
|
|
32020
|
+
const parsed = Number(input);
|
|
32021
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
32022
|
+
return 5 * 60 * 1e3;
|
|
32023
|
+
}
|
|
32024
|
+
return Math.floor(parsed);
|
|
32025
|
+
}
|
|
32026
|
+
var AuthKernel = class {
|
|
32027
|
+
ttlMs;
|
|
32028
|
+
pendingByProvider = /* @__PURE__ */ new Map();
|
|
32029
|
+
consumedStatesByProvider = /* @__PURE__ */ new Map();
|
|
32030
|
+
constructor(ttlMs = parseTtlMs(process.env.PYB_OAUTH_PENDING_TTL_MS)) {
|
|
32031
|
+
this.ttlMs = ttlMs;
|
|
32032
|
+
}
|
|
32033
|
+
setOAuthPendingTtlMs(ttlMs) {
|
|
32034
|
+
if (!Number.isFinite(ttlMs) || ttlMs <= 0) {
|
|
32035
|
+
throw new Error("ttlMs must be a positive number");
|
|
32036
|
+
}
|
|
32037
|
+
this.ttlMs = Math.floor(ttlMs);
|
|
32038
|
+
}
|
|
32039
|
+
beginOAuthSession(providerID, state, codeVerifier) {
|
|
32040
|
+
const now = Date.now();
|
|
32041
|
+
this.pruneConsumedStates(providerID, now);
|
|
32042
|
+
this.pendingByProvider.set(providerID, {
|
|
32043
|
+
state,
|
|
32044
|
+
codeVerifier,
|
|
32045
|
+
createdAt: now
|
|
32046
|
+
});
|
|
32047
|
+
}
|
|
32048
|
+
consumeOAuthSession(providerID, state) {
|
|
32049
|
+
const now = Date.now();
|
|
32050
|
+
this.pruneConsumedStates(providerID, now);
|
|
32051
|
+
const consumed = this.consumedStatesByProvider.get(providerID);
|
|
32052
|
+
if (consumed?.has(state)) {
|
|
32053
|
+
return { success: false, errorCode: "OAUTH_STATE_REPLAYED" };
|
|
32054
|
+
}
|
|
32055
|
+
const pending = this.pendingByProvider.get(providerID);
|
|
32056
|
+
if (!pending || pending.state !== state) {
|
|
32057
|
+
return { success: false, errorCode: "OAUTH_STATE_MISMATCH" };
|
|
32058
|
+
}
|
|
32059
|
+
if (now - pending.createdAt > this.ttlMs) {
|
|
32060
|
+
this.pendingByProvider.delete(providerID);
|
|
32061
|
+
return { success: false, errorCode: "OAUTH_STATE_EXPIRED" };
|
|
32062
|
+
}
|
|
32063
|
+
this.pendingByProvider.delete(providerID);
|
|
32064
|
+
let nextConsumed = this.consumedStatesByProvider.get(providerID);
|
|
32065
|
+
if (!nextConsumed) {
|
|
32066
|
+
nextConsumed = /* @__PURE__ */ new Map();
|
|
32067
|
+
this.consumedStatesByProvider.set(providerID, nextConsumed);
|
|
32068
|
+
}
|
|
32069
|
+
nextConsumed.set(state, now);
|
|
32070
|
+
return {
|
|
32071
|
+
success: true,
|
|
32072
|
+
codeVerifier: pending.codeVerifier
|
|
32073
|
+
};
|
|
32074
|
+
}
|
|
32075
|
+
pruneConsumedStates(providerID, now) {
|
|
32076
|
+
const consumed = this.consumedStatesByProvider.get(providerID);
|
|
32077
|
+
if (!consumed) return;
|
|
32078
|
+
for (const [state, consumedAt] of consumed.entries()) {
|
|
32079
|
+
if (now - consumedAt > this.ttlMs) {
|
|
32080
|
+
consumed.delete(state);
|
|
32081
|
+
}
|
|
32082
|
+
}
|
|
32083
|
+
if (consumed.size === 0) {
|
|
32084
|
+
this.consumedStatesByProvider.delete(providerID);
|
|
32085
|
+
}
|
|
32086
|
+
}
|
|
32087
|
+
};
|
|
32088
|
+
|
|
32089
|
+
// src/server/routes/providers.ts
|
|
32090
|
+
var authKernel = new AuthKernel();
|
|
32091
|
+
function normalizeText2(input) {
|
|
32092
|
+
return String(input ?? "").trim();
|
|
32093
|
+
}
|
|
32094
|
+
function normalizeProviderID2(input) {
|
|
32095
|
+
return normalizeText2(input).toLowerCase();
|
|
32096
|
+
}
|
|
32097
|
+
function getActiveProfiles(config2) {
|
|
32098
|
+
const profiles = Array.isArray(config2?.modelProfiles) ? config2.modelProfiles : [];
|
|
32099
|
+
return profiles.filter((profile) => profile?.isActive === true);
|
|
32100
|
+
}
|
|
32101
|
+
function hasProvider(config2, providerID) {
|
|
32102
|
+
const profiles = Array.isArray(config2?.modelProfiles) ? config2.modelProfiles : [];
|
|
32103
|
+
return profiles.some((profile) => normalizeProviderID2(profile?.provider) === providerID);
|
|
32104
|
+
}
|
|
32105
|
+
function setProviderApiKey(providerID, apiKey) {
|
|
32106
|
+
const config2 = getGlobalConfig();
|
|
32107
|
+
const profiles = Array.isArray(config2?.modelProfiles) ? config2.modelProfiles : [];
|
|
32108
|
+
let updated = false;
|
|
32109
|
+
const nextProfiles = profiles.map((profile) => {
|
|
32110
|
+
if (normalizeProviderID2(profile?.provider) !== providerID) return profile;
|
|
32111
|
+
updated = true;
|
|
32112
|
+
return {
|
|
32113
|
+
...profile,
|
|
32114
|
+
apiKey
|
|
32115
|
+
};
|
|
32116
|
+
});
|
|
32117
|
+
if (!updated) return false;
|
|
32118
|
+
saveGlobalConfig({
|
|
32119
|
+
...config2,
|
|
32120
|
+
modelProfiles: nextProfiles
|
|
32121
|
+
});
|
|
32122
|
+
return true;
|
|
32123
|
+
}
|
|
32124
|
+
function setProviderAuthValue(providerIDRaw, apiKeyRaw) {
|
|
32125
|
+
const providerID = normalizeProviderID2(providerIDRaw);
|
|
32126
|
+
const apiKey = normalizeText2(apiKeyRaw);
|
|
32127
|
+
if (!providerID) {
|
|
32128
|
+
return {
|
|
32129
|
+
success: false,
|
|
32130
|
+
code: "INVALID_PROVIDER_ID",
|
|
32131
|
+
message: "providerID is required"
|
|
32132
|
+
};
|
|
32133
|
+
}
|
|
32134
|
+
if (!apiKey) {
|
|
32135
|
+
return {
|
|
32136
|
+
success: false,
|
|
32137
|
+
code: "INVALID_AUTH_INPUT",
|
|
32138
|
+
message: "apiKey is required"
|
|
32139
|
+
};
|
|
32140
|
+
}
|
|
32141
|
+
const config2 = getGlobalConfig();
|
|
32142
|
+
if (!hasProvider(config2, providerID)) {
|
|
32143
|
+
return {
|
|
32144
|
+
success: false,
|
|
32145
|
+
code: "PROVIDER_NOT_FOUND",
|
|
32146
|
+
message: `Provider '${providerID}' not found`
|
|
32147
|
+
};
|
|
32148
|
+
}
|
|
32149
|
+
const updated = setProviderApiKey(providerID, apiKey);
|
|
32150
|
+
if (!updated) {
|
|
32151
|
+
return {
|
|
32152
|
+
success: false,
|
|
32153
|
+
code: "PROVIDER_AUTH_UPDATE_FAILED",
|
|
32154
|
+
message: "Failed to update provider auth"
|
|
32155
|
+
};
|
|
32156
|
+
}
|
|
32157
|
+
return { success: true };
|
|
32158
|
+
}
|
|
32159
|
+
function removeProviderAuthValue(providerIDRaw) {
|
|
32160
|
+
const providerID = normalizeProviderID2(providerIDRaw);
|
|
32161
|
+
if (!providerID) {
|
|
32162
|
+
return {
|
|
32163
|
+
success: false,
|
|
32164
|
+
code: "INVALID_PROVIDER_ID",
|
|
32165
|
+
message: "providerID is required"
|
|
32166
|
+
};
|
|
32167
|
+
}
|
|
32168
|
+
const config2 = getGlobalConfig();
|
|
32169
|
+
if (!hasProvider(config2, providerID)) {
|
|
32170
|
+
return {
|
|
32171
|
+
success: false,
|
|
32172
|
+
code: "PROVIDER_NOT_FOUND",
|
|
32173
|
+
message: `Provider '${providerID}' not found`
|
|
32174
|
+
};
|
|
32175
|
+
}
|
|
32176
|
+
const updated = setProviderApiKey(providerID, "");
|
|
32177
|
+
if (!updated) {
|
|
32178
|
+
return {
|
|
32179
|
+
success: false,
|
|
32180
|
+
code: "PROVIDER_AUTH_REMOVE_FAILED",
|
|
32181
|
+
message: "Failed to remove provider auth"
|
|
32182
|
+
};
|
|
32183
|
+
}
|
|
32184
|
+
return { success: true };
|
|
32185
|
+
}
|
|
32186
|
+
function buildCodeVerifier() {
|
|
32187
|
+
return crypto2.randomBytes(32).toString("base64url");
|
|
32188
|
+
}
|
|
32189
|
+
function buildCodeChallenge(verifier) {
|
|
32190
|
+
return crypto2.createHash("sha256").update(verifier).digest("base64url");
|
|
32191
|
+
}
|
|
32192
|
+
function resolveDefaultModelRef(config2, activeProfiles) {
|
|
32193
|
+
const pointer = normalizeText2(config2?.modelPointers?.main);
|
|
32194
|
+
if (!pointer) return null;
|
|
32195
|
+
const normalizedPointer = pointer.toLowerCase();
|
|
32196
|
+
const profile = activeProfiles.find((item) => {
|
|
32197
|
+
const providerID = normalizeProviderID2(item?.provider);
|
|
32198
|
+
const modelID = normalizeText2(item?.modelName);
|
|
32199
|
+
const profileName = normalizeText2(item?.name);
|
|
32200
|
+
const providerQualifiedModel = `${providerID}:${modelID}`.toLowerCase();
|
|
32201
|
+
const providerQualifiedName = `${providerID}:${profileName}`.toLowerCase();
|
|
32202
|
+
return modelID === pointer || profileName === pointer || providerQualifiedModel === normalizedPointer || providerQualifiedName === normalizedPointer;
|
|
32203
|
+
});
|
|
32204
|
+
if (!profile) return null;
|
|
32205
|
+
return {
|
|
32206
|
+
providerID: normalizeProviderID2(profile.provider),
|
|
32207
|
+
modelID: normalizeText2(profile.modelName),
|
|
32208
|
+
displayName: normalizeText2(profile.name) || normalizeText2(profile.modelName),
|
|
32209
|
+
capabilities: []
|
|
32210
|
+
};
|
|
32211
|
+
}
|
|
32212
|
+
function createProviderListPayload(config2) {
|
|
32213
|
+
const activeProfiles = getActiveProfiles(config2);
|
|
32214
|
+
const defaultModel = resolveDefaultModelRef(config2, activeProfiles);
|
|
32215
|
+
const configSource = buildProviderSourceFromProfiles(
|
|
32216
|
+
"config",
|
|
32217
|
+
activeProfiles,
|
|
32218
|
+
defaultModel
|
|
32219
|
+
);
|
|
32220
|
+
return composeProviderCatalog([configSource], ["env", "auth", "plugin", "config"]);
|
|
32221
|
+
}
|
|
32222
|
+
function createProviderAuthMethods(providers2) {
|
|
32223
|
+
return providers2.map((provider) => ({
|
|
32224
|
+
providerID: provider.providerID,
|
|
32225
|
+
type: "api",
|
|
32226
|
+
label: "API Key",
|
|
32227
|
+
scopes: []
|
|
32228
|
+
}));
|
|
32229
|
+
}
|
|
32230
|
+
function createProvidersRoutes() {
|
|
32231
|
+
const router = new Hono6();
|
|
32232
|
+
router.get("/", (c) => {
|
|
32233
|
+
const config2 = getGlobalConfig();
|
|
32234
|
+
const data = createProviderListPayload(config2);
|
|
32235
|
+
return c.json({
|
|
32236
|
+
success: true,
|
|
32237
|
+
data
|
|
32238
|
+
});
|
|
32239
|
+
});
|
|
32240
|
+
router.get("/auth", (c) => {
|
|
32241
|
+
const config2 = getGlobalConfig();
|
|
32242
|
+
const data = createProviderListPayload(config2);
|
|
32243
|
+
return c.json({
|
|
32244
|
+
success: true,
|
|
32245
|
+
data: createProviderAuthMethods(data.all)
|
|
32246
|
+
});
|
|
32247
|
+
});
|
|
32248
|
+
router.post("/:providerID/oauth/authorize", async (c) => {
|
|
32249
|
+
const providerID = normalizeProviderID2(c.req.param("providerID"));
|
|
32250
|
+
const config2 = getGlobalConfig();
|
|
32251
|
+
if (!hasProvider(config2, providerID)) {
|
|
32252
|
+
return c.json(
|
|
32253
|
+
{
|
|
32254
|
+
success: false,
|
|
32255
|
+
error: {
|
|
32256
|
+
code: "PROVIDER_NOT_FOUND",
|
|
32257
|
+
message: `Provider '${providerID}' not found`,
|
|
32258
|
+
recoverable: true
|
|
32259
|
+
}
|
|
32260
|
+
},
|
|
32261
|
+
404
|
|
32262
|
+
);
|
|
32263
|
+
}
|
|
32264
|
+
const body = await c.req.json().catch(() => ({}));
|
|
32265
|
+
const redirectUri = normalizeText2(body?.redirectUri) || `http://localhost:4096/v1/providers/${providerID}/oauth/callback`;
|
|
32266
|
+
const scope = normalizeText2(body?.scope) || "default";
|
|
32267
|
+
const state = crypto2.randomBytes(24).toString("base64url");
|
|
32268
|
+
const codeVerifier = buildCodeVerifier();
|
|
32269
|
+
const codeChallenge = buildCodeChallenge(codeVerifier);
|
|
32270
|
+
authKernel.beginOAuthSession(providerID, state, codeVerifier);
|
|
32271
|
+
const authorizationUrl = new URL(
|
|
32272
|
+
`https://auth.${providerID || "provider"}.example.com/oauth/authorize`
|
|
32273
|
+
);
|
|
32274
|
+
authorizationUrl.searchParams.set("response_type", "code");
|
|
32275
|
+
authorizationUrl.searchParams.set("client_id", "pyb-cli");
|
|
32276
|
+
authorizationUrl.searchParams.set("redirect_uri", redirectUri);
|
|
32277
|
+
authorizationUrl.searchParams.set("scope", scope);
|
|
32278
|
+
authorizationUrl.searchParams.set("state", state);
|
|
32279
|
+
authorizationUrl.searchParams.set("code_challenge", codeChallenge);
|
|
32280
|
+
authorizationUrl.searchParams.set("code_challenge_method", "S256");
|
|
32281
|
+
return c.json({
|
|
32282
|
+
success: true,
|
|
32283
|
+
data: {
|
|
32284
|
+
providerID,
|
|
32285
|
+
authorizationUrl: authorizationUrl.toString(),
|
|
32286
|
+
state,
|
|
32287
|
+
codeChallengeMethod: "S256"
|
|
32288
|
+
}
|
|
32289
|
+
});
|
|
32290
|
+
});
|
|
32291
|
+
router.post("/:providerID/oauth/callback", async (c) => {
|
|
32292
|
+
const providerID = normalizeProviderID2(c.req.param("providerID"));
|
|
32293
|
+
const config2 = getGlobalConfig();
|
|
32294
|
+
if (!hasProvider(config2, providerID)) {
|
|
32295
|
+
return c.json(
|
|
32296
|
+
{
|
|
32297
|
+
success: false,
|
|
32298
|
+
error: {
|
|
32299
|
+
code: "PROVIDER_NOT_FOUND",
|
|
32300
|
+
message: `Provider '${providerID}' not found`,
|
|
32301
|
+
recoverable: true
|
|
32302
|
+
}
|
|
32303
|
+
},
|
|
32304
|
+
404
|
|
32305
|
+
);
|
|
32306
|
+
}
|
|
32307
|
+
const body = await c.req.json().catch(() => ({}));
|
|
32308
|
+
const state = normalizeText2(body?.state);
|
|
32309
|
+
const code = normalizeText2(body?.code);
|
|
32310
|
+
if (!state || !code) {
|
|
32311
|
+
return c.json(
|
|
32312
|
+
{
|
|
32313
|
+
success: false,
|
|
32314
|
+
error: {
|
|
32315
|
+
code: "INVALID_OAUTH_CALLBACK",
|
|
32316
|
+
message: "code and state are required",
|
|
32317
|
+
recoverable: true
|
|
32318
|
+
}
|
|
32319
|
+
},
|
|
32320
|
+
400
|
|
32321
|
+
);
|
|
32322
|
+
}
|
|
32323
|
+
const consumed = authKernel.consumeOAuthSession(providerID, state);
|
|
32324
|
+
if (consumed.success === false) {
|
|
32325
|
+
const errorCode = consumed.errorCode;
|
|
32326
|
+
const errorMap = {
|
|
32327
|
+
OAUTH_STATE_MISMATCH: "Invalid oauth state",
|
|
32328
|
+
OAUTH_STATE_EXPIRED: "OAuth state expired",
|
|
32329
|
+
OAUTH_STATE_REPLAYED: "OAuth state already consumed"
|
|
32330
|
+
};
|
|
32331
|
+
return c.json(
|
|
32332
|
+
{
|
|
32333
|
+
success: false,
|
|
32334
|
+
error: {
|
|
32335
|
+
code: errorCode,
|
|
32336
|
+
message: errorMap[errorCode],
|
|
32337
|
+
recoverable: true
|
|
32338
|
+
}
|
|
32339
|
+
},
|
|
32340
|
+
400
|
|
32341
|
+
);
|
|
32342
|
+
}
|
|
32343
|
+
const synthesizedApiKey = crypto2.createHash("sha256").update(`${providerID}:${code}:${consumed.codeVerifier}:${state}`).digest("hex").slice(0, 40);
|
|
32344
|
+
const result = setProviderAuthValue(providerID, `oauth_${synthesizedApiKey}`);
|
|
32345
|
+
if (!result.success) {
|
|
32346
|
+
return c.json(
|
|
32347
|
+
{
|
|
32348
|
+
success: false,
|
|
32349
|
+
error: {
|
|
32350
|
+
code: result.code ?? "PROVIDER_AUTH_UPDATE_FAILED",
|
|
32351
|
+
message: result.message ?? "Failed to update provider auth",
|
|
32352
|
+
recoverable: true
|
|
32353
|
+
}
|
|
32354
|
+
},
|
|
32355
|
+
400
|
|
32356
|
+
);
|
|
32357
|
+
}
|
|
32358
|
+
return c.json({
|
|
32359
|
+
success: true,
|
|
32360
|
+
data: {
|
|
32361
|
+
providerID,
|
|
32362
|
+
connected: true,
|
|
32363
|
+
method: "oauth"
|
|
32364
|
+
}
|
|
32365
|
+
});
|
|
32366
|
+
});
|
|
32367
|
+
return router;
|
|
32368
|
+
}
|
|
32369
|
+
|
|
32370
|
+
// src/server/routes/auth.ts
|
|
32371
|
+
import { Hono as Hono7 } from "hono";
|
|
32372
|
+
function isNotFound(code) {
|
|
32373
|
+
return code === "PROVIDER_NOT_FOUND";
|
|
32374
|
+
}
|
|
32375
|
+
function createAuthRoutes() {
|
|
32376
|
+
const router = new Hono7();
|
|
32377
|
+
router.put("/:providerID", async (c) => {
|
|
32378
|
+
const providerID = c.req.param("providerID");
|
|
32379
|
+
const body = await c.req.json().catch(() => ({}));
|
|
32380
|
+
const result = setProviderAuthValue(providerID, body?.apiKey);
|
|
32381
|
+
if (!result.success) {
|
|
32382
|
+
return c.json(
|
|
32383
|
+
{
|
|
32384
|
+
success: false,
|
|
32385
|
+
error: {
|
|
32386
|
+
code: result.code ?? "PROVIDER_AUTH_UPDATE_FAILED",
|
|
32387
|
+
message: result.message ?? "Failed to update provider auth",
|
|
32388
|
+
recoverable: true
|
|
32389
|
+
}
|
|
32390
|
+
},
|
|
32391
|
+
isNotFound(result.code) ? 404 : 400
|
|
32392
|
+
);
|
|
32393
|
+
}
|
|
32394
|
+
return c.json({
|
|
32395
|
+
success: true,
|
|
32396
|
+
data: {
|
|
32397
|
+
providerID: providerID.toLowerCase(),
|
|
32398
|
+
connected: true,
|
|
32399
|
+
method: "api"
|
|
32400
|
+
}
|
|
32401
|
+
});
|
|
32402
|
+
});
|
|
32403
|
+
router.delete("/:providerID", (c) => {
|
|
32404
|
+
const providerID = c.req.param("providerID");
|
|
32405
|
+
const result = removeProviderAuthValue(providerID);
|
|
32406
|
+
if (!result.success) {
|
|
32407
|
+
return c.json(
|
|
32408
|
+
{
|
|
32409
|
+
success: false,
|
|
32410
|
+
error: {
|
|
32411
|
+
code: result.code ?? "PROVIDER_AUTH_REMOVE_FAILED",
|
|
32412
|
+
message: result.message ?? "Failed to remove provider auth",
|
|
32413
|
+
recoverable: true
|
|
32414
|
+
}
|
|
32415
|
+
},
|
|
32416
|
+
isNotFound(result.code) ? 404 : 400
|
|
32417
|
+
);
|
|
32418
|
+
}
|
|
32419
|
+
return c.json({
|
|
32420
|
+
success: true,
|
|
32421
|
+
data: {
|
|
32422
|
+
providerID: providerID.toLowerCase(),
|
|
32423
|
+
removed: true
|
|
32424
|
+
}
|
|
32425
|
+
});
|
|
32426
|
+
});
|
|
32427
|
+
return router;
|
|
32428
|
+
}
|
|
32429
|
+
|
|
32430
|
+
// src/server/routes/model.ts
|
|
32431
|
+
import { Hono as Hono8 } from "hono";
|
|
32432
|
+
|
|
32433
|
+
// src/server/modelPool/modelCatalog.ts
|
|
32434
|
+
function normalizeText3(input) {
|
|
32435
|
+
return String(input ?? "").trim();
|
|
32436
|
+
}
|
|
32437
|
+
function normalizeProviderID3(input) {
|
|
32438
|
+
return normalizeText3(input).toLowerCase();
|
|
32439
|
+
}
|
|
32440
|
+
function isActiveProfile(profile) {
|
|
32441
|
+
return profile?.isActive === true;
|
|
32442
|
+
}
|
|
32443
|
+
function resolveModelSelection(profiles, providerID, modelID) {
|
|
32444
|
+
const providerProfiles = profiles.filter(
|
|
32445
|
+
(profile) => normalizeProviderID3(profile?.provider) === providerID
|
|
32446
|
+
);
|
|
32447
|
+
if (providerProfiles.length === 0) {
|
|
32448
|
+
return {
|
|
32449
|
+
success: false,
|
|
32450
|
+
errorCode: "PROVIDER_NOT_FOUND",
|
|
32451
|
+
message: `Provider '${providerID}' not found`,
|
|
32452
|
+
status: 404
|
|
32453
|
+
};
|
|
32454
|
+
}
|
|
32455
|
+
const matchingProfiles = providerProfiles.filter(
|
|
32456
|
+
(profile) => normalizeText3(profile?.modelName) === modelID
|
|
32457
|
+
);
|
|
32458
|
+
if (matchingProfiles.length === 0) {
|
|
32459
|
+
return {
|
|
32460
|
+
success: false,
|
|
32461
|
+
errorCode: "MODEL_NOT_FOUND",
|
|
32462
|
+
message: `Model '${modelID}' not found under provider '${providerID}'`,
|
|
32463
|
+
status: 404
|
|
32464
|
+
};
|
|
32465
|
+
}
|
|
32466
|
+
const enabledProfile = matchingProfiles.find(isActiveProfile);
|
|
32467
|
+
if (!enabledProfile) {
|
|
32468
|
+
return {
|
|
32469
|
+
success: false,
|
|
32470
|
+
errorCode: "MODEL_DISABLED",
|
|
32471
|
+
message: `Model '${modelID}' is disabled under provider '${providerID}'`,
|
|
32472
|
+
status: 409
|
|
32473
|
+
};
|
|
32474
|
+
}
|
|
32475
|
+
return {
|
|
32476
|
+
success: true,
|
|
32477
|
+
current: {
|
|
32478
|
+
providerID,
|
|
32479
|
+
modelID,
|
|
32480
|
+
displayName: normalizeText3(enabledProfile?.name) || modelID,
|
|
32481
|
+
capabilities: []
|
|
32482
|
+
}
|
|
32483
|
+
};
|
|
32484
|
+
}
|
|
32485
|
+
|
|
32486
|
+
// src/server/modelPool/policyEngine.ts
|
|
32487
|
+
function normalizeText4(input) {
|
|
32488
|
+
return String(input ?? "").trim();
|
|
32489
|
+
}
|
|
32490
|
+
function normalizeProviderID4(input) {
|
|
32491
|
+
return normalizeText4(input).toLowerCase();
|
|
32492
|
+
}
|
|
32493
|
+
function readBlockedModelRules() {
|
|
32494
|
+
const raw = process.env.PYB_POLICY_BLOCKED_MODELS ?? "";
|
|
32495
|
+
const entries = raw.split(",").map((item) => item.trim().toLowerCase()).filter(Boolean);
|
|
32496
|
+
return new Set(entries);
|
|
32497
|
+
}
|
|
32498
|
+
function evaluateDefaultModelPolicy(input) {
|
|
32499
|
+
const providerID = normalizeProviderID4(input.providerID);
|
|
32500
|
+
const modelID = normalizeText4(input.modelID).toLowerCase();
|
|
32501
|
+
const blocked = readBlockedModelRules();
|
|
32502
|
+
const exactKey = `${providerID}:${modelID}`;
|
|
32503
|
+
const wildcardProviderKey = `${providerID}:*`;
|
|
32504
|
+
const wildcardGlobalKey = `*:${modelID}`;
|
|
32505
|
+
const fullWildcardKey = "*:*";
|
|
32506
|
+
if (blocked.has(exactKey) || blocked.has(wildcardProviderKey) || blocked.has(wildcardGlobalKey) || blocked.has(fullWildcardKey)) {
|
|
32507
|
+
return {
|
|
32508
|
+
allowed: false,
|
|
32509
|
+
errorCode: "POLICY_REJECTED",
|
|
32510
|
+
message: `Policy rejected model '${modelID}' under provider '${providerID}'`,
|
|
32511
|
+
status: 403
|
|
32512
|
+
};
|
|
32513
|
+
}
|
|
32514
|
+
return { allowed: true };
|
|
32515
|
+
}
|
|
32516
|
+
|
|
32517
|
+
// src/server/routes/model.ts
|
|
32518
|
+
function normalizeText5(input) {
|
|
32519
|
+
return String(input ?? "").trim();
|
|
32520
|
+
}
|
|
32521
|
+
function normalizeProviderID5(input) {
|
|
32522
|
+
return normalizeText5(input).toLowerCase();
|
|
32523
|
+
}
|
|
32524
|
+
function isSupportedScope(input) {
|
|
32525
|
+
return input === "global" || input === "workspace";
|
|
32526
|
+
}
|
|
32527
|
+
function resolveScope(input) {
|
|
32528
|
+
const scope = normalizeText5(input).toLowerCase();
|
|
32529
|
+
if (!scope) return "global";
|
|
32530
|
+
if (isSupportedScope(scope)) return scope;
|
|
32531
|
+
throw new Error("INVALID_SCOPE");
|
|
32532
|
+
}
|
|
32533
|
+
function createModelRoutes() {
|
|
32534
|
+
const router = new Hono8();
|
|
32535
|
+
router.put("/default", async (c) => {
|
|
32536
|
+
const body = await c.req.json().catch(() => ({}));
|
|
32537
|
+
const providerID = normalizeProviderID5(body?.providerID);
|
|
32538
|
+
const modelID = normalizeText5(body?.modelID);
|
|
32539
|
+
if (!providerID || !modelID) {
|
|
32540
|
+
return c.json(
|
|
32541
|
+
{
|
|
32542
|
+
success: false,
|
|
32543
|
+
error: {
|
|
32544
|
+
code: "INVALID_MODEL_REF",
|
|
32545
|
+
message: "providerID and modelID are required",
|
|
32546
|
+
recoverable: true
|
|
32547
|
+
}
|
|
32548
|
+
},
|
|
32549
|
+
400
|
|
32550
|
+
);
|
|
32551
|
+
}
|
|
32552
|
+
let requestedScope;
|
|
32553
|
+
try {
|
|
32554
|
+
requestedScope = resolveScope(body?.scope);
|
|
32555
|
+
} catch {
|
|
32556
|
+
return c.json(
|
|
32557
|
+
{
|
|
32558
|
+
success: false,
|
|
32559
|
+
error: {
|
|
32560
|
+
code: "INVALID_SCOPE",
|
|
32561
|
+
message: "scope must be global or workspace",
|
|
32562
|
+
recoverable: true
|
|
32563
|
+
}
|
|
32564
|
+
},
|
|
32565
|
+
400
|
|
32566
|
+
);
|
|
32567
|
+
}
|
|
32568
|
+
const globalConfig = getGlobalConfig();
|
|
32569
|
+
const profiles = Array.isArray(globalConfig.modelProfiles) ? globalConfig.modelProfiles : [];
|
|
32570
|
+
const selection = resolveModelSelection(profiles, providerID, modelID);
|
|
32571
|
+
if (selection.success === false) {
|
|
32572
|
+
return c.json(
|
|
32573
|
+
{
|
|
32574
|
+
success: false,
|
|
32575
|
+
error: {
|
|
32576
|
+
code: selection.errorCode,
|
|
32577
|
+
message: selection.message,
|
|
32578
|
+
recoverable: true
|
|
32579
|
+
}
|
|
32580
|
+
},
|
|
32581
|
+
selection.status
|
|
32582
|
+
);
|
|
32583
|
+
}
|
|
32584
|
+
const policy = evaluateDefaultModelPolicy({
|
|
32585
|
+
providerID,
|
|
32586
|
+
modelID,
|
|
32587
|
+
scope: requestedScope
|
|
32588
|
+
});
|
|
32589
|
+
if (policy.allowed === false) {
|
|
32590
|
+
return c.json(
|
|
32591
|
+
{
|
|
32592
|
+
success: false,
|
|
32593
|
+
error: {
|
|
32594
|
+
code: policy.errorCode,
|
|
32595
|
+
message: policy.message,
|
|
32596
|
+
recoverable: true
|
|
32597
|
+
}
|
|
32598
|
+
},
|
|
32599
|
+
policy.status
|
|
32600
|
+
);
|
|
32601
|
+
}
|
|
32602
|
+
const appliedScope = "global";
|
|
32603
|
+
const fallbackReason = requestedScope === "workspace" ? "workspace_scope_not_supported" : null;
|
|
32604
|
+
const currentPointers = globalConfig.modelPointers ?? {};
|
|
32605
|
+
const nextPointers = {
|
|
32606
|
+
...currentPointers,
|
|
32607
|
+
main: modelID,
|
|
32608
|
+
task: currentPointers.task ?? modelID,
|
|
32609
|
+
compact: currentPointers.compact ?? modelID,
|
|
32610
|
+
quick: currentPointers.quick ?? modelID
|
|
32611
|
+
};
|
|
32612
|
+
saveGlobalConfig({
|
|
32613
|
+
...globalConfig,
|
|
32614
|
+
modelPointers: nextPointers
|
|
32615
|
+
});
|
|
32616
|
+
return c.json({
|
|
32617
|
+
success: true,
|
|
32618
|
+
data: {
|
|
32619
|
+
scope: appliedScope,
|
|
32620
|
+
requestedScope,
|
|
32621
|
+
applied: true,
|
|
32622
|
+
fallbackReason,
|
|
32623
|
+
current: selection.current
|
|
32624
|
+
}
|
|
32625
|
+
});
|
|
32626
|
+
});
|
|
32627
|
+
return router;
|
|
32628
|
+
}
|
|
32629
|
+
|
|
32630
|
+
// src/server/routes/modelPools.ts
|
|
32631
|
+
import { Hono as Hono9 } from "hono";
|
|
32632
|
+
|
|
32633
|
+
// src/server/modelPool/sourceResolver.ts
|
|
32634
|
+
function normalize2(input) {
|
|
32635
|
+
return input.trim();
|
|
32636
|
+
}
|
|
32637
|
+
function normalizeID(input) {
|
|
32638
|
+
return normalize2(input).toLowerCase();
|
|
32639
|
+
}
|
|
32640
|
+
function parseGitHubRepo(spec) {
|
|
32641
|
+
const ssh = spec.match(/^git@github\.com:([^/]+\/[^/]+?)(?:\.git)?$/i);
|
|
32642
|
+
if (ssh?.[1]) return normalizeID(ssh[1]);
|
|
32643
|
+
const https = spec.match(/^https?:\/\/github\.com\/([^/]+\/[^/]+?)(?:\.git)?(?:#.*)?$/i);
|
|
32644
|
+
if (https?.[1]) return normalizeID(https[1]);
|
|
32645
|
+
return null;
|
|
32646
|
+
}
|
|
32647
|
+
function extractLocalPluginID(spec) {
|
|
32648
|
+
try {
|
|
32649
|
+
const url2 = new URL(spec);
|
|
32650
|
+
const path6 = decodeURIComponent(url2.pathname);
|
|
32651
|
+
const segments = path6.split("/").filter(Boolean);
|
|
32652
|
+
const tail = segments[segments.length - 1] ?? "local-plugin";
|
|
32653
|
+
return normalizeID(tail.replace(/\.(tgz|tar\.gz|zip)$/i, ""));
|
|
32654
|
+
} catch {
|
|
32655
|
+
return "local-plugin";
|
|
32656
|
+
}
|
|
32657
|
+
}
|
|
32658
|
+
function parseMarketplaceSpec(spec) {
|
|
32659
|
+
const trimmed = normalize2(spec);
|
|
32660
|
+
const parts = trimmed.split("@");
|
|
32661
|
+
if (parts.length !== 2) return null;
|
|
32662
|
+
if (trimmed.startsWith("@")) return null;
|
|
32663
|
+
const plugin2 = normalize2(parts[0] ?? "");
|
|
32664
|
+
const marketplace = normalize2(parts[1] ?? "");
|
|
32665
|
+
if (!plugin2 || !marketplace) return null;
|
|
32666
|
+
if (marketplace.includes("/")) return null;
|
|
32667
|
+
return {
|
|
32668
|
+
pluginID: normalizeID(plugin2),
|
|
32669
|
+
marketplace: normalizeID(marketplace)
|
|
32670
|
+
};
|
|
32671
|
+
}
|
|
32672
|
+
function stripNpmVersion(spec) {
|
|
32673
|
+
const trimmed = normalize2(spec);
|
|
32674
|
+
if (!trimmed) throw new Error("pluginSpec is required");
|
|
32675
|
+
if (trimmed.startsWith("@")) {
|
|
32676
|
+
const slash = trimmed.indexOf("/");
|
|
32677
|
+
const lastAt = trimmed.lastIndexOf("@");
|
|
32678
|
+
if (slash > 0 && lastAt > slash) {
|
|
32679
|
+
return normalizeID(trimmed.slice(0, lastAt));
|
|
32680
|
+
}
|
|
32681
|
+
return normalizeID(trimmed);
|
|
32682
|
+
}
|
|
32683
|
+
const at = trimmed.lastIndexOf("@");
|
|
32684
|
+
if (at > 0) {
|
|
32685
|
+
return normalizeID(trimmed.slice(0, at));
|
|
32686
|
+
}
|
|
32687
|
+
return normalizeID(trimmed);
|
|
32688
|
+
}
|
|
32689
|
+
function resolvePluginSourceRecord(pluginSpecRaw) {
|
|
32690
|
+
const pluginSpec = normalize2(pluginSpecRaw);
|
|
32691
|
+
if (!pluginSpec) throw new Error("pluginSpec is required");
|
|
32692
|
+
if (pluginSpec.startsWith("file://")) {
|
|
32693
|
+
const pluginID2 = extractLocalPluginID(pluginSpec);
|
|
32694
|
+
return {
|
|
32695
|
+
pluginSpec,
|
|
32696
|
+
pluginID: pluginID2,
|
|
32697
|
+
sourceID: `local:${pluginSpec}`,
|
|
32698
|
+
sourceType: "local"
|
|
32699
|
+
};
|
|
32700
|
+
}
|
|
32701
|
+
const githubRepo = parseGitHubRepo(pluginSpec);
|
|
32702
|
+
if (githubRepo) {
|
|
32703
|
+
return {
|
|
32704
|
+
pluginSpec,
|
|
32705
|
+
pluginID: githubRepo,
|
|
32706
|
+
sourceID: `github:${githubRepo}`,
|
|
32707
|
+
sourceType: "github"
|
|
32708
|
+
};
|
|
32709
|
+
}
|
|
32710
|
+
const marketplace = parseMarketplaceSpec(pluginSpec);
|
|
32711
|
+
if (marketplace) {
|
|
32712
|
+
return {
|
|
32713
|
+
pluginSpec,
|
|
32714
|
+
pluginID: marketplace.pluginID,
|
|
32715
|
+
sourceID: `marketplace:${marketplace.marketplace}`,
|
|
32716
|
+
sourceType: "marketplace"
|
|
32717
|
+
};
|
|
32718
|
+
}
|
|
32719
|
+
const pluginID = stripNpmVersion(pluginSpec);
|
|
32720
|
+
return {
|
|
32721
|
+
pluginSpec,
|
|
32722
|
+
pluginID,
|
|
32723
|
+
sourceID: "npm:registry",
|
|
32724
|
+
sourceType: "npm"
|
|
32725
|
+
};
|
|
32726
|
+
}
|
|
32727
|
+
function dedupeSourceRecordsByPluginID(records, sourcePriority = ["marketplace", "github", "npm", "local"]) {
|
|
32728
|
+
const priority = /* @__PURE__ */ new Map();
|
|
32729
|
+
sourcePriority.forEach((source, index) => {
|
|
32730
|
+
priority.set(source, index);
|
|
32731
|
+
});
|
|
32732
|
+
const fallbackRank = sourcePriority.length + 1;
|
|
32733
|
+
const deduped = /* @__PURE__ */ new Map();
|
|
32734
|
+
for (const record of records) {
|
|
32735
|
+
const key = normalizeID(record.pluginID);
|
|
32736
|
+
const current = deduped.get(key);
|
|
32737
|
+
if (!current) {
|
|
32738
|
+
deduped.set(key, { ...record, pluginID: key });
|
|
32739
|
+
continue;
|
|
32740
|
+
}
|
|
32741
|
+
const currentRank = priority.get(current.sourceType) ?? fallbackRank;
|
|
32742
|
+
const nextRank = priority.get(record.sourceType) ?? fallbackRank;
|
|
32743
|
+
if (nextRank < currentRank) {
|
|
32744
|
+
deduped.set(key, { ...record, pluginID: key });
|
|
32745
|
+
}
|
|
32746
|
+
}
|
|
32747
|
+
return Array.from(deduped.values());
|
|
32748
|
+
}
|
|
32749
|
+
var ModelPoolRegistry = class {
|
|
32750
|
+
pools = /* @__PURE__ */ new Map();
|
|
32751
|
+
register(definition) {
|
|
32752
|
+
const modelPoolID = normalizeID(definition.modelPoolID);
|
|
32753
|
+
if (!modelPoolID) throw new Error("modelPoolID is required");
|
|
32754
|
+
if (this.pools.has(modelPoolID)) {
|
|
32755
|
+
throw new Error(`model pool already exists: ${modelPoolID}`);
|
|
32756
|
+
}
|
|
32757
|
+
this.pools.set(modelPoolID, {
|
|
32758
|
+
definition: {
|
|
32759
|
+
modelPoolID,
|
|
32760
|
+
pluginSpecs: definition.pluginSpecs.map(normalize2).filter(Boolean),
|
|
32761
|
+
metadata: definition.metadata ?? {}
|
|
32762
|
+
},
|
|
32763
|
+
state: "registered"
|
|
32764
|
+
});
|
|
32765
|
+
}
|
|
32766
|
+
activate(modelPoolIDRaw) {
|
|
32767
|
+
const modelPoolID = normalizeID(modelPoolIDRaw);
|
|
32768
|
+
const record = this.pools.get(modelPoolID);
|
|
32769
|
+
if (!record) throw new Error(`model pool not found: ${modelPoolID}`);
|
|
32770
|
+
record.state = "active";
|
|
32771
|
+
}
|
|
32772
|
+
deactivate(modelPoolIDRaw) {
|
|
32773
|
+
const modelPoolID = normalizeID(modelPoolIDRaw);
|
|
32774
|
+
const record = this.pools.get(modelPoolID);
|
|
32775
|
+
if (!record) throw new Error(`model pool not found: ${modelPoolID}`);
|
|
32776
|
+
record.state = "inactive";
|
|
32777
|
+
}
|
|
32778
|
+
getStatus() {
|
|
32779
|
+
const pools = Array.from(this.pools.values()).map((record) => {
|
|
32780
|
+
const resolved = record.definition.pluginSpecs.map(resolvePluginSourceRecord);
|
|
32781
|
+
const deduped = dedupeSourceRecordsByPluginID(resolved);
|
|
32782
|
+
return {
|
|
32783
|
+
modelPoolID: record.definition.modelPoolID,
|
|
32784
|
+
state: record.state,
|
|
32785
|
+
pluginCount: deduped.length,
|
|
32786
|
+
sourceRecords: deduped,
|
|
32787
|
+
metadata: record.definition.metadata ?? {}
|
|
32788
|
+
};
|
|
32789
|
+
});
|
|
32790
|
+
const active2 = pools.filter((item) => item.state === "active").length;
|
|
32791
|
+
return {
|
|
32792
|
+
total: pools.length,
|
|
32793
|
+
active: active2,
|
|
32794
|
+
pools
|
|
32795
|
+
};
|
|
32796
|
+
}
|
|
32797
|
+
};
|
|
32798
|
+
|
|
32799
|
+
// src/server/routes/modelPools.ts
|
|
32800
|
+
function normalizeProviderID6(input) {
|
|
32801
|
+
return String(input ?? "").trim().toLowerCase();
|
|
32802
|
+
}
|
|
32803
|
+
function buildPluginSpecsFromProfiles(profiles) {
|
|
32804
|
+
const specs = /* @__PURE__ */ new Set();
|
|
32805
|
+
for (const profile of profiles) {
|
|
32806
|
+
if (profile?.isActive !== true) continue;
|
|
32807
|
+
const providerID = normalizeProviderID6(profile?.provider);
|
|
32808
|
+
if (!providerID) continue;
|
|
32809
|
+
specs.add(`${providerID}@config`);
|
|
32810
|
+
}
|
|
32811
|
+
return [...specs];
|
|
32812
|
+
}
|
|
32813
|
+
function createModelPoolRoutes() {
|
|
32814
|
+
const router = new Hono9();
|
|
32815
|
+
router.get("/status", async (c) => {
|
|
32816
|
+
const globalConfig = getGlobalConfig();
|
|
32817
|
+
const profiles = Array.isArray(globalConfig.modelProfiles) ? globalConfig.modelProfiles : [];
|
|
32818
|
+
const pluginSpecs = buildPluginSpecsFromProfiles(profiles);
|
|
32819
|
+
const registry = new ModelPoolRegistry();
|
|
32820
|
+
const modelPoolID = "default";
|
|
32821
|
+
registry.register({
|
|
32822
|
+
modelPoolID,
|
|
32823
|
+
pluginSpecs,
|
|
32824
|
+
metadata: {
|
|
32825
|
+
source: "config"
|
|
32826
|
+
}
|
|
32827
|
+
});
|
|
32828
|
+
registry.activate(modelPoolID);
|
|
32829
|
+
return c.json({
|
|
32830
|
+
success: true,
|
|
32831
|
+
data: registry.getStatus()
|
|
32832
|
+
});
|
|
32833
|
+
});
|
|
32834
|
+
return router;
|
|
32835
|
+
}
|
|
32836
|
+
|
|
32837
|
+
// src/server/events/eventBuffer.ts
|
|
32838
|
+
var SessionEventRingBuffer = class {
|
|
32839
|
+
buffers = /* @__PURE__ */ new Map();
|
|
32840
|
+
touchedAt = /* @__PURE__ */ new Map();
|
|
32841
|
+
maxSize;
|
|
32842
|
+
ttlMs;
|
|
32843
|
+
constructor(maxSize = 100, ttlMs = 15 * 60 * 1e3) {
|
|
32844
|
+
this.maxSize = maxSize;
|
|
32845
|
+
this.ttlMs = ttlMs;
|
|
32846
|
+
}
|
|
32847
|
+
push(sessionId, event) {
|
|
32848
|
+
this.pruneExpired(Date.now());
|
|
32849
|
+
const buffer = this.buffers.get(sessionId) ?? [];
|
|
32850
|
+
buffer.push(event);
|
|
32851
|
+
if (buffer.length > this.maxSize) {
|
|
32852
|
+
buffer.shift();
|
|
32853
|
+
}
|
|
32854
|
+
this.buffers.set(sessionId, buffer);
|
|
32855
|
+
this.touchedAt.set(sessionId, Date.now());
|
|
32856
|
+
}
|
|
32857
|
+
replayAfter(sessionId, lastEventId) {
|
|
32858
|
+
const buffer = this.buffers.get(sessionId);
|
|
32859
|
+
if (!buffer || buffer.length === 0) {
|
|
32860
|
+
return { kind: "gap", reason: "last_event_not_found" };
|
|
32861
|
+
}
|
|
32862
|
+
const index = buffer.findIndex((item) => item.id === lastEventId);
|
|
32863
|
+
if (index === -1) {
|
|
32864
|
+
return { kind: "gap", reason: "buffer_evicted" };
|
|
32865
|
+
}
|
|
32866
|
+
return { kind: "ok", events: buffer.slice(index + 1) };
|
|
32867
|
+
}
|
|
32868
|
+
clear(sessionId) {
|
|
32869
|
+
this.buffers.delete(sessionId);
|
|
32870
|
+
this.touchedAt.delete(sessionId);
|
|
32871
|
+
}
|
|
32872
|
+
getStats(sessionId) {
|
|
32873
|
+
const buffer = this.buffers.get(sessionId) ?? [];
|
|
32874
|
+
return {
|
|
32875
|
+
count: buffer.length,
|
|
32876
|
+
oldestId: buffer[0]?.id,
|
|
32877
|
+
newestId: buffer[buffer.length - 1]?.id
|
|
32878
|
+
};
|
|
32879
|
+
}
|
|
32880
|
+
pruneExpired(now) {
|
|
32881
|
+
for (const [sessionId, touchedAt] of this.touchedAt.entries()) {
|
|
32882
|
+
if (now - touchedAt > this.ttlMs) {
|
|
32883
|
+
this.clear(sessionId);
|
|
32884
|
+
}
|
|
32885
|
+
}
|
|
32886
|
+
}
|
|
32887
|
+
};
|
|
32888
|
+
|
|
31895
32889
|
// src/server/version.ts
|
|
31896
32890
|
import { readFileSync as readFileSync14 } from "fs";
|
|
31897
32891
|
import { resolve as resolve12 } from "path";
|
|
@@ -31909,17 +32903,66 @@ function resolveServerVersion() {
|
|
|
31909
32903
|
var SERVER_VERSION = resolveServerVersion();
|
|
31910
32904
|
|
|
31911
32905
|
// src/server/index.ts
|
|
32906
|
+
var DEFAULT_HEARTBEAT_INTERVAL_MS = 5e3;
|
|
32907
|
+
var MIN_HEARTBEAT_INTERVAL_MS = 3e3;
|
|
32908
|
+
var MAX_HEARTBEAT_INTERVAL_MS = 5e3;
|
|
31912
32909
|
function toPublicSSEEvent(event) {
|
|
31913
32910
|
const sessionId = typeof event.properties.sessionId === "string" ? event.properties.sessionId : void 0;
|
|
31914
32911
|
return {
|
|
31915
32912
|
type: event.type,
|
|
32913
|
+
...typeof event.id === "string" ? { id: event.id } : {},
|
|
31916
32914
|
timestamp: Date.now(),
|
|
31917
32915
|
...sessionId ? { sessionId } : {},
|
|
31918
32916
|
data: event.properties
|
|
31919
32917
|
};
|
|
31920
32918
|
}
|
|
32919
|
+
function resolveIdleTimeoutSeconds(value) {
|
|
32920
|
+
if (value === void 0 || value === "0") return 0;
|
|
32921
|
+
const ms = Number(value);
|
|
32922
|
+
if (!Number.isFinite(ms) || ms < 0) return 0;
|
|
32923
|
+
return ms >= 6e4 ? Math.floor(ms / 1e3) : 0;
|
|
32924
|
+
}
|
|
32925
|
+
function resolveHeartbeatIntervalMs(value) {
|
|
32926
|
+
if (value === void 0) return DEFAULT_HEARTBEAT_INTERVAL_MS;
|
|
32927
|
+
const ms = Number(value);
|
|
32928
|
+
if (!Number.isFinite(ms) || ms < MIN_HEARTBEAT_INTERVAL_MS || ms > MAX_HEARTBEAT_INTERVAL_MS) {
|
|
32929
|
+
return DEFAULT_HEARTBEAT_INTERVAL_MS;
|
|
32930
|
+
}
|
|
32931
|
+
return ms;
|
|
32932
|
+
}
|
|
32933
|
+
function resolveIdleTimeoutSecondsFromOptions(input) {
|
|
32934
|
+
const override = input.idleTimeoutMs;
|
|
32935
|
+
if (override !== void 0) {
|
|
32936
|
+
return resolveIdleTimeoutSeconds(String(override));
|
|
32937
|
+
}
|
|
32938
|
+
return resolveIdleTimeoutSeconds(input.env.PYB_SSE_IDLE_TIMEOUT_MS);
|
|
32939
|
+
}
|
|
32940
|
+
function resolveHeartbeatIntervalMsFromOptions(input) {
|
|
32941
|
+
const override = input.heartbeatIntervalMs;
|
|
32942
|
+
if (override !== void 0) {
|
|
32943
|
+
return resolveHeartbeatIntervalMs(String(override));
|
|
32944
|
+
}
|
|
32945
|
+
return resolveHeartbeatIntervalMs(input.env.PYB_SSE_HEARTBEAT_INTERVAL_MS);
|
|
32946
|
+
}
|
|
32947
|
+
function resolveSSEServerRuntimeConfig(env2 = process.env, options = {}) {
|
|
32948
|
+
return {
|
|
32949
|
+
idleTimeoutSeconds: resolveIdleTimeoutSecondsFromOptions({
|
|
32950
|
+
env: env2,
|
|
32951
|
+
idleTimeoutMs: options.idleTimeoutMs
|
|
32952
|
+
}),
|
|
32953
|
+
heartbeatIntervalMs: resolveHeartbeatIntervalMsFromOptions({
|
|
32954
|
+
env: env2,
|
|
32955
|
+
heartbeatIntervalMs: options.heartbeatIntervalMs
|
|
32956
|
+
})
|
|
32957
|
+
};
|
|
32958
|
+
}
|
|
31921
32959
|
function createServer2(options = {}) {
|
|
31922
|
-
const app = new
|
|
32960
|
+
const app = new Hono10();
|
|
32961
|
+
const sseRuntimeConfig = resolveSSEServerRuntimeConfig(process.env, {
|
|
32962
|
+
heartbeatIntervalMs: options.heartbeatIntervalMs,
|
|
32963
|
+
idleTimeoutMs: options.idleTimeoutMs
|
|
32964
|
+
});
|
|
32965
|
+
const eventBuffer = new SessionEventRingBuffer();
|
|
31923
32966
|
app.use("*", cors());
|
|
31924
32967
|
app.use("*", logger());
|
|
31925
32968
|
app.get("/v1/health", (c) => {
|
|
@@ -31939,9 +32982,15 @@ function createServer2(options = {}) {
|
|
|
31939
32982
|
app.route("/v1/permissions", createPermissionRoutes());
|
|
31940
32983
|
app.route("/v1/config", createConfigRoutes());
|
|
31941
32984
|
app.route("/v1/mcp", createMCPRoutes());
|
|
32985
|
+
app.route("/v1/providers", createProvidersRoutes());
|
|
32986
|
+
app.route("/v1/auth", createAuthRoutes());
|
|
32987
|
+
app.route("/v1/models", createModelRoutes());
|
|
32988
|
+
app.route("/v1/model-pools", createModelPoolRoutes());
|
|
31942
32989
|
app.get("/v1/events", (c) => {
|
|
31943
32990
|
c.header("X-Accel-Buffering", "no");
|
|
31944
32991
|
c.header("X-Content-Type-Options", "nosniff");
|
|
32992
|
+
const requestedLastEventId = c.req.query("lastEventId") ?? c.req.header("Last-Event-ID");
|
|
32993
|
+
const replaySessionId = typeof requestedLastEventId === "string" ? parseSessionIdFromEventId(requestedLastEventId) : null;
|
|
31945
32994
|
return streamSSE2(c, async (stream) => {
|
|
31946
32995
|
await stream.writeSSE({
|
|
31947
32996
|
event: "server.connected",
|
|
@@ -31955,22 +33004,75 @@ function createServer2(options = {}) {
|
|
|
31955
33004
|
}
|
|
31956
33005
|
})
|
|
31957
33006
|
});
|
|
33007
|
+
if (requestedLastEventId && replaySessionId) {
|
|
33008
|
+
const replayResult = eventBuffer.replayAfter(replaySessionId, requestedLastEventId);
|
|
33009
|
+
if (replayResult.kind === "ok") {
|
|
33010
|
+
for (const replayEvent of replayResult.events) {
|
|
33011
|
+
await stream.writeSSE({
|
|
33012
|
+
event: replayEvent.type,
|
|
33013
|
+
data: JSON.stringify(replayEvent.data)
|
|
33014
|
+
});
|
|
33015
|
+
}
|
|
33016
|
+
} else {
|
|
33017
|
+
await stream.writeSSE({
|
|
33018
|
+
event: "sse.replay_gap",
|
|
33019
|
+
data: JSON.stringify({
|
|
33020
|
+
type: "sse.replay_gap",
|
|
33021
|
+
timestamp: Date.now(),
|
|
33022
|
+
data: {
|
|
33023
|
+
lastEventId: requestedLastEventId,
|
|
33024
|
+
reason: replayResult.reason
|
|
33025
|
+
}
|
|
33026
|
+
})
|
|
33027
|
+
});
|
|
33028
|
+
}
|
|
33029
|
+
await stream.writeSSE({
|
|
33030
|
+
event: "sse.replay",
|
|
33031
|
+
data: JSON.stringify({
|
|
33032
|
+
type: "sse.replay",
|
|
33033
|
+
timestamp: Date.now(),
|
|
33034
|
+
data: {
|
|
33035
|
+
replayCount: replayResult.kind === "ok" ? replayResult.events.length : 0,
|
|
33036
|
+
replayGapCount: replayResult.kind === "gap" ? 1 : 0,
|
|
33037
|
+
lastEventId: requestedLastEventId,
|
|
33038
|
+
firstReplayId: replayResult.kind === "ok" ? replayResult.events[0]?.id ?? null : null,
|
|
33039
|
+
lastReplayId: replayResult.kind === "ok" ? replayResult.events[replayResult.events.length - 1]?.id ?? null : null
|
|
33040
|
+
}
|
|
33041
|
+
})
|
|
33042
|
+
});
|
|
33043
|
+
}
|
|
31958
33044
|
const unsubscribe = Bus.subscribeAll(async (event) => {
|
|
33045
|
+
const publicEvent = toPublicSSEEvent(event);
|
|
33046
|
+
if (typeof publicEvent.sessionId === "string" && typeof publicEvent.id === "string") {
|
|
33047
|
+
eventBuffer.push(publicEvent.sessionId, {
|
|
33048
|
+
id: publicEvent.id,
|
|
33049
|
+
type: event.type,
|
|
33050
|
+
timestamp: publicEvent.timestamp,
|
|
33051
|
+
data: publicEvent
|
|
33052
|
+
});
|
|
33053
|
+
}
|
|
33054
|
+
if (event.type === "session.deleted" && typeof publicEvent.sessionId === "string") {
|
|
33055
|
+
eventBuffer.clear(publicEvent.sessionId);
|
|
33056
|
+
}
|
|
31959
33057
|
await stream.writeSSE({
|
|
31960
33058
|
event: event.type,
|
|
31961
|
-
data: JSON.stringify(
|
|
33059
|
+
data: JSON.stringify(publicEvent)
|
|
31962
33060
|
});
|
|
31963
33061
|
});
|
|
31964
33062
|
const heartbeatInterval = setInterval(async () => {
|
|
31965
|
-
|
|
31966
|
-
|
|
31967
|
-
|
|
31968
|
-
|
|
31969
|
-
|
|
31970
|
-
|
|
31971
|
-
|
|
31972
|
-
|
|
31973
|
-
|
|
33063
|
+
try {
|
|
33064
|
+
await stream.writeSSE({
|
|
33065
|
+
event: "server.heartbeat",
|
|
33066
|
+
data: JSON.stringify({
|
|
33067
|
+
type: "server.heartbeat",
|
|
33068
|
+
timestamp: Date.now(),
|
|
33069
|
+
data: { timestamp: Date.now() }
|
|
33070
|
+
})
|
|
33071
|
+
});
|
|
33072
|
+
} catch (error) {
|
|
33073
|
+
console.error("[pyb-sse-heartbeat] write failed", error);
|
|
33074
|
+
}
|
|
33075
|
+
}, sseRuntimeConfig.heartbeatIntervalMs);
|
|
31974
33076
|
await new Promise((resolve16) => {
|
|
31975
33077
|
stream.onAbort(() => {
|
|
31976
33078
|
clearInterval(heartbeatInterval);
|
|
@@ -31986,13 +33088,18 @@ async function startServer(options = {}) {
|
|
|
31986
33088
|
const port = options.port ?? 4096;
|
|
31987
33089
|
const host = options.host ?? "localhost";
|
|
31988
33090
|
const app = createServer2(options);
|
|
33091
|
+
const sseRuntimeConfig = resolveSSEServerRuntimeConfig(process.env, {
|
|
33092
|
+
heartbeatIntervalMs: options.heartbeatIntervalMs,
|
|
33093
|
+
idleTimeoutMs: options.idleTimeoutMs
|
|
33094
|
+
});
|
|
31989
33095
|
if (typeof Bun === "undefined" || typeof Bun.serve !== "function") {
|
|
31990
33096
|
throw new Error("Bun runtime is required to start the web server");
|
|
31991
33097
|
}
|
|
31992
33098
|
const server = Bun.serve({
|
|
31993
33099
|
fetch: app.fetch,
|
|
31994
33100
|
hostname: host,
|
|
31995
|
-
port
|
|
33101
|
+
port,
|
|
33102
|
+
idleTimeout: sseRuntimeConfig.idleTimeoutSeconds
|
|
31996
33103
|
});
|
|
31997
33104
|
console.log(`PYB-CLI Web Server starting on http://${host}:${port}`);
|
|
31998
33105
|
return {
|
|
@@ -38297,7 +39404,7 @@ function useStatusLine() {
|
|
|
38297
39404
|
// src/ui/components/PromptInput.tsx
|
|
38298
39405
|
async function interpretHashCommand(input) {
|
|
38299
39406
|
try {
|
|
38300
|
-
const { queryQuick: queryQuick2 } = await import("./llm-
|
|
39407
|
+
const { queryQuick: queryQuick2 } = await import("./llm-CVILTZMI.js");
|
|
38301
39408
|
const systemPrompt = [
|
|
38302
39409
|
"You're helping the user structure notes that will be added to their PYB.md file.",
|
|
38303
39410
|
"Format the user's input into a well-structured note that will be useful for later reference.",
|
|
@@ -38610,7 +39717,7 @@ function PromptInput({
|
|
|
38610
39717
|
if (messages2.length) {
|
|
38611
39718
|
if (mode === "bash") {
|
|
38612
39719
|
onQuery(messages2, newAbortController).then(async () => {
|
|
38613
|
-
const { getCwd: getCwd2 } = await import("./state-
|
|
39720
|
+
const { getCwd: getCwd2 } = await import("./state-GWKESQ7O.js");
|
|
38614
39721
|
setCurrentPwd(getCwd2());
|
|
38615
39722
|
});
|
|
38616
39723
|
} else {
|
|
@@ -40240,7 +41347,7 @@ import { homedir as homedir8 } from "os";
|
|
|
40240
41347
|
// src/commands/agents/generation.ts
|
|
40241
41348
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
40242
41349
|
async function generateAgentWithClaude(prompt) {
|
|
40243
|
-
const { queryModel } = await import("./llm-
|
|
41350
|
+
const { queryModel } = await import("./llm-CVILTZMI.js");
|
|
40244
41351
|
const systemPrompt = `You are an expert at creating AI agent configurations. Based on the user's description, generate a specialized agent configuration.
|
|
40245
41352
|
|
|
40246
41353
|
Return your response as a JSON object with exactly these fields:
|