nexus-agents 2.170.0 → 2.172.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{child-mcp-config-3RYBPZNE.js → child-mcp-config-NW4JZFWC.js} +2 -2
- package/dist/{chunk-LYWNKEGM.js → chunk-25CWEJ2M.js} +4 -4
- package/dist/{chunk-JOYOOEPJ.js → chunk-4KVAHGMB.js} +2 -2
- package/dist/{chunk-SCHD7NZD.js → chunk-5UDKUPZB.js} +7 -7
- package/dist/{chunk-Z4AWOPXA.js → chunk-76Q63KJM.js} +2 -2
- package/dist/{chunk-NXSY4G4Y.js → chunk-7AJWIOMT.js} +2 -2
- package/dist/{chunk-OFVUBY6Z.js → chunk-AJIDYCQG.js} +3 -3
- package/dist/{chunk-JYDXHV4L.js → chunk-B4XT3B2E.js} +2 -2
- package/dist/{chunk-OYBAKU7N.js → chunk-BTH745HU.js} +2 -2
- package/dist/{chunk-QMOJJ6A2.js → chunk-C7TWCMK4.js} +4367 -2421
- package/dist/chunk-C7TWCMK4.js.map +1 -0
- package/dist/{chunk-DEE2UTYV.js → chunk-CEDSYAAI.js} +2 -2
- package/dist/{chunk-OIT75IRK.js → chunk-DLVDFJXU.js} +4 -4
- package/dist/{chunk-6TN2Z2AQ.js → chunk-DYFF72HX.js} +3 -3
- package/dist/{chunk-LDZEYJP3.js → chunk-FU2FRL46.js} +2 -2
- package/dist/{chunk-75AUSQL4.js → chunk-GJRLIANS.js} +7 -7
- package/dist/{chunk-DCXCVEZP.js → chunk-IC3NZHPT.js} +2 -2
- package/dist/{chunk-57RYP435.js → chunk-IK7POCXO.js} +3 -3
- package/dist/{chunk-DDQXPARJ.js → chunk-KP4ZXW3B.js} +3 -3
- package/dist/{chunk-MG4JBADQ.js → chunk-LFKCJQ7G.js} +4 -4
- package/dist/{chunk-P4PLZZCR.js → chunk-NSP3SZW2.js} +5 -5
- package/dist/{chunk-PIODB4SW.js → chunk-O4J34GZT.js} +2 -2
- package/dist/{chunk-GVTXP6F6.js → chunk-QBCWORAK.js} +3 -3
- package/dist/{chunk-URRNWRI4.js → chunk-QBOTSJ7S.js} +6 -5
- package/dist/{chunk-URRNWRI4.js.map → chunk-QBOTSJ7S.js.map} +1 -1
- package/dist/{chunk-JLG5AUZB.js → chunk-QFS5VOB6.js} +2 -2
- package/dist/{chunk-C6IAXFNC.js → chunk-RAK6PTNM.js} +2 -2
- package/dist/{chunk-WKW5SEP7.js → chunk-RQGORCFM.js} +5 -5
- package/dist/{chunk-HTM32H2E.js → chunk-S66XOAMZ.js} +2 -2
- package/dist/{chunk-ZW7544DX.js → chunk-SCHMBRK4.js} +3 -3
- package/dist/{chunk-UXXNNT5D.js → chunk-SUWN54CK.js} +2 -2
- package/dist/{chunk-LOKT6EW7.js → chunk-SZ3CRNPI.js} +8 -8
- package/dist/{chunk-5N5XURKV.js → chunk-Y7JDXVJA.js} +2 -2
- package/dist/{chunk-BGV3IF3G.js → chunk-YKVO32BI.js} +8 -8
- package/dist/{chunk-RJDJMOX6.js → chunk-Z5GJ4FXW.js} +4 -4
- package/dist/{chunk-RZJQZ5P3.js → chunk-ZSWXEDI6.js} +2 -2
- package/dist/{cli-circuit-breaker-4GJA2IXC.js → cli-circuit-breaker-UWJNXHLC.js} +4 -4
- package/dist/cli.js +41 -41
- package/dist/{composite-router-UBZO4YR7.js → composite-router-ULDZRQGO.js} +2 -2
- package/dist/{consensus-vote-USZFJO2K.js → consensus-vote-KF6M7NZJ.js} +15 -15
- package/dist/{context-retriever-C5C7RFQE.js → context-retriever-73PNAWES.js} +8 -8
- package/dist/{dist-UFU426AX.js → dist-BNKMVSO2.js} +7252 -7446
- package/dist/dist-BNKMVSO2.js.map +1 -0
- package/dist/{doctor-deep-2N3F7EV6.js → doctor-deep-LURSTTF7.js} +3 -3
- package/dist/{expert-bridge-B3EFTAID.js → expert-bridge-VWS3NBL3.js} +4 -4
- package/dist/{factory-SURRFPSV.js → factory-KPJ2EG63.js} +5 -5
- package/dist/{factory-LKQKU3SD.js → factory-MYJYONBQ.js} +8 -8
- package/dist/{improvement-review-75OCZ5K7.js → improvement-review-APOK4U3Z.js} +5 -5
- package/dist/index.d.ts +365 -14
- package/dist/index.js +384 -1373
- package/dist/index.js.map +1 -1
- package/dist/{init-opencode-LDI5E5LW.js → init-opencode-Y7WPFCY7.js} +5 -5
- package/dist/{issue-triage-WWQEY7PL.js → issue-triage-4P3TDIJQ.js} +6 -6
- package/dist/model-registry.generated.json +7712 -3500
- package/dist/{pr-reviewer-helpers-HDP24LGZ.js → pr-reviewer-helpers-4JX2LEVZ.js} +4 -4
- package/dist/{registry-command-PZY7HWKO.js → registry-command-CTYTYRXF.js} +2 -2
- package/dist/{repo-security-plan-IYKDY5PW.js → repo-security-plan-4CXBXLAY.js} +3 -3
- package/dist/{research-helpers-synthesize-XSOFXRFK.js → research-helpers-synthesize-23OXMV47.js} +4 -4
- package/dist/{routing-memory-JTNH2BXS.js → routing-memory-AWCOIW27.js} +2 -2
- package/dist/security/ast-rules/command-exec-go.yml +15 -0
- package/dist/security/ast-rules/dangerous-eval-python.yml +8 -0
- package/dist/security/ast-rules/shell-injection-python.yml +13 -0
- package/dist/{session-memory-RJZ447UX.js → session-memory-P53QXKGV.js} +3 -3
- package/dist/{setup-command-35MCRS33.js → setup-command-7S744QHK.js} +13 -13
- package/dist/{setup-config-JV23ZYPO.js → setup-config-B7WLUMUU.js} +3 -3
- package/dist/{setup-custom-api-LMA445OB.js → setup-custom-api-B6QGKSEY.js} +3 -3
- package/dist/{tool-memory-K6EYH3FQ.js → tool-memory-QUFVINHN.js} +5 -5
- package/dist/{unified-registry-MJA6IBDD.js → unified-registry-4NOWT2MU.js} +9 -9
- package/dist/{weather-report-ID4ZNUAF.js → weather-report-MCLS5MFZ.js} +2 -2
- package/package.json +12 -9
- package/src/security/ast-rules/command-exec-go.yml +15 -0
- package/src/security/ast-rules/dangerous-eval-python.yml +8 -0
- package/src/security/ast-rules/fixtures/sample.go +33 -0
- package/src/security/ast-rules/fixtures/sample.py +41 -0
- package/src/security/ast-rules/shell-injection-python.yml +13 -0
- package/dist/chunk-QMOJJ6A2.js.map +0 -1
- package/dist/dist-UFU426AX.js.map +0 -1
- /package/dist/{child-mcp-config-3RYBPZNE.js.map → child-mcp-config-NW4JZFWC.js.map} +0 -0
- /package/dist/{chunk-LYWNKEGM.js.map → chunk-25CWEJ2M.js.map} +0 -0
- /package/dist/{chunk-JOYOOEPJ.js.map → chunk-4KVAHGMB.js.map} +0 -0
- /package/dist/{chunk-SCHD7NZD.js.map → chunk-5UDKUPZB.js.map} +0 -0
- /package/dist/{chunk-Z4AWOPXA.js.map → chunk-76Q63KJM.js.map} +0 -0
- /package/dist/{chunk-NXSY4G4Y.js.map → chunk-7AJWIOMT.js.map} +0 -0
- /package/dist/{chunk-OFVUBY6Z.js.map → chunk-AJIDYCQG.js.map} +0 -0
- /package/dist/{chunk-JYDXHV4L.js.map → chunk-B4XT3B2E.js.map} +0 -0
- /package/dist/{chunk-OYBAKU7N.js.map → chunk-BTH745HU.js.map} +0 -0
- /package/dist/{chunk-DEE2UTYV.js.map → chunk-CEDSYAAI.js.map} +0 -0
- /package/dist/{chunk-OIT75IRK.js.map → chunk-DLVDFJXU.js.map} +0 -0
- /package/dist/{chunk-6TN2Z2AQ.js.map → chunk-DYFF72HX.js.map} +0 -0
- /package/dist/{chunk-LDZEYJP3.js.map → chunk-FU2FRL46.js.map} +0 -0
- /package/dist/{chunk-75AUSQL4.js.map → chunk-GJRLIANS.js.map} +0 -0
- /package/dist/{chunk-DCXCVEZP.js.map → chunk-IC3NZHPT.js.map} +0 -0
- /package/dist/{chunk-57RYP435.js.map → chunk-IK7POCXO.js.map} +0 -0
- /package/dist/{chunk-DDQXPARJ.js.map → chunk-KP4ZXW3B.js.map} +0 -0
- /package/dist/{chunk-MG4JBADQ.js.map → chunk-LFKCJQ7G.js.map} +0 -0
- /package/dist/{chunk-P4PLZZCR.js.map → chunk-NSP3SZW2.js.map} +0 -0
- /package/dist/{chunk-PIODB4SW.js.map → chunk-O4J34GZT.js.map} +0 -0
- /package/dist/{chunk-GVTXP6F6.js.map → chunk-QBCWORAK.js.map} +0 -0
- /package/dist/{chunk-JLG5AUZB.js.map → chunk-QFS5VOB6.js.map} +0 -0
- /package/dist/{chunk-C6IAXFNC.js.map → chunk-RAK6PTNM.js.map} +0 -0
- /package/dist/{chunk-WKW5SEP7.js.map → chunk-RQGORCFM.js.map} +0 -0
- /package/dist/{chunk-HTM32H2E.js.map → chunk-S66XOAMZ.js.map} +0 -0
- /package/dist/{chunk-ZW7544DX.js.map → chunk-SCHMBRK4.js.map} +0 -0
- /package/dist/{chunk-UXXNNT5D.js.map → chunk-SUWN54CK.js.map} +0 -0
- /package/dist/{chunk-LOKT6EW7.js.map → chunk-SZ3CRNPI.js.map} +0 -0
- /package/dist/{chunk-5N5XURKV.js.map → chunk-Y7JDXVJA.js.map} +0 -0
- /package/dist/{chunk-BGV3IF3G.js.map → chunk-YKVO32BI.js.map} +0 -0
- /package/dist/{chunk-RJDJMOX6.js.map → chunk-Z5GJ4FXW.js.map} +0 -0
- /package/dist/{chunk-RZJQZ5P3.js.map → chunk-ZSWXEDI6.js.map} +0 -0
- /package/dist/{cli-circuit-breaker-4GJA2IXC.js.map → cli-circuit-breaker-UWJNXHLC.js.map} +0 -0
- /package/dist/{composite-router-UBZO4YR7.js.map → composite-router-ULDZRQGO.js.map} +0 -0
- /package/dist/{consensus-vote-USZFJO2K.js.map → consensus-vote-KF6M7NZJ.js.map} +0 -0
- /package/dist/{context-retriever-C5C7RFQE.js.map → context-retriever-73PNAWES.js.map} +0 -0
- /package/dist/{doctor-deep-2N3F7EV6.js.map → doctor-deep-LURSTTF7.js.map} +0 -0
- /package/dist/{expert-bridge-B3EFTAID.js.map → expert-bridge-VWS3NBL3.js.map} +0 -0
- /package/dist/{factory-LKQKU3SD.js.map → factory-KPJ2EG63.js.map} +0 -0
- /package/dist/{factory-SURRFPSV.js.map → factory-MYJYONBQ.js.map} +0 -0
- /package/dist/{improvement-review-75OCZ5K7.js.map → improvement-review-APOK4U3Z.js.map} +0 -0
- /package/dist/{init-opencode-LDI5E5LW.js.map → init-opencode-Y7WPFCY7.js.map} +0 -0
- /package/dist/{issue-triage-WWQEY7PL.js.map → issue-triage-4P3TDIJQ.js.map} +0 -0
- /package/dist/{pr-reviewer-helpers-HDP24LGZ.js.map → pr-reviewer-helpers-4JX2LEVZ.js.map} +0 -0
- /package/dist/{registry-command-PZY7HWKO.js.map → registry-command-CTYTYRXF.js.map} +0 -0
- /package/dist/{repo-security-plan-IYKDY5PW.js.map → repo-security-plan-4CXBXLAY.js.map} +0 -0
- /package/dist/{research-helpers-synthesize-XSOFXRFK.js.map → research-helpers-synthesize-23OXMV47.js.map} +0 -0
- /package/dist/{routing-memory-JTNH2BXS.js.map → routing-memory-AWCOIW27.js.map} +0 -0
- /package/dist/{session-memory-RJZ447UX.js.map → session-memory-P53QXKGV.js.map} +0 -0
- /package/dist/{setup-command-35MCRS33.js.map → setup-command-7S744QHK.js.map} +0 -0
- /package/dist/{setup-config-JV23ZYPO.js.map → setup-config-B7WLUMUU.js.map} +0 -0
- /package/dist/{setup-custom-api-LMA445OB.js.map → setup-custom-api-B6QGKSEY.js.map} +0 -0
- /package/dist/{tool-memory-K6EYH3FQ.js.map → tool-memory-QUFVINHN.js.map} +0 -0
- /package/dist/{unified-registry-MJA6IBDD.js.map → unified-registry-4NOWT2MU.js.map} +0 -0
- /package/dist/{weather-report-ID4ZNUAF.js.map → weather-report-MCLS5MFZ.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createGitHubProvider,
|
|
3
3
|
createScmProvider
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-25CWEJ2M.js";
|
|
5
5
|
import {
|
|
6
6
|
ALLOWED_COMMANDS,
|
|
7
7
|
ARTIFACT_TYPES,
|
|
8
8
|
AUDIT_PIPELINE_TEMPLATE,
|
|
9
9
|
ActivationStrategySchema,
|
|
10
|
+
AdapterConfigSchema,
|
|
11
|
+
AdapterFactory,
|
|
10
12
|
AgentEventSchema,
|
|
11
13
|
AgentMessageSchema,
|
|
12
14
|
AgentRoleSchema,
|
|
@@ -73,6 +75,7 @@ import {
|
|
|
73
75
|
DEFAULT_POLICIES,
|
|
74
76
|
DEFAULT_RBAC,
|
|
75
77
|
DEFAULT_RESOURCE_LIMITS,
|
|
78
|
+
DEFAULT_RETRY_CONFIG,
|
|
76
79
|
DEFAULT_ROLE_MAPPINGS,
|
|
77
80
|
DEFAULT_SKILL_LIBRARY_CONFIG,
|
|
78
81
|
DEFAULT_SKILL_LOADER_CONFIG,
|
|
@@ -121,7 +124,10 @@ import {
|
|
|
121
124
|
ForestResultSchema,
|
|
122
125
|
ForestStateSchema,
|
|
123
126
|
ForestStatisticsSchema,
|
|
127
|
+
GEMINI_MODELS,
|
|
128
|
+
GEMINI_MODEL_ALIASES,
|
|
124
129
|
GENERAL_PIPELINE_TEMPLATE,
|
|
130
|
+
GeminiAdapter,
|
|
125
131
|
GeminiResponseParser,
|
|
126
132
|
GeneratedTestSchema,
|
|
127
133
|
GetJobResultInputSchema,
|
|
@@ -148,6 +154,8 @@ import {
|
|
|
148
154
|
MemoryWriteInputSchema,
|
|
149
155
|
ModelSelectionSchema,
|
|
150
156
|
NodeStateSchema,
|
|
157
|
+
OLLAMA_MODELS,
|
|
158
|
+
OllamaAdapter,
|
|
151
159
|
OrchestrateInputSchema,
|
|
152
160
|
OrchestrateOutputSchema,
|
|
153
161
|
OrchestrationError,
|
|
@@ -175,11 +183,13 @@ import {
|
|
|
175
183
|
PruningStrategy,
|
|
176
184
|
QualitySignalsSchema,
|
|
177
185
|
QueryTraceInputSchema,
|
|
186
|
+
RateLimiter,
|
|
178
187
|
ReasoningDepthSchema,
|
|
179
188
|
ReasoningNodeMetadataSchema,
|
|
180
189
|
ReasoningNodeSchema,
|
|
181
190
|
ReasoningStepTypeSchema,
|
|
182
191
|
ReasoningTreeSchema,
|
|
192
|
+
RecoverableExpert,
|
|
183
193
|
RegistryError,
|
|
184
194
|
RegistryImportInputSchema,
|
|
185
195
|
RepoAnalyzeInputSchema,
|
|
@@ -192,6 +202,7 @@ import {
|
|
|
192
202
|
ResearchQueryInputSchema,
|
|
193
203
|
ResearchSynthesizeInputSchema,
|
|
194
204
|
ResultAggregator,
|
|
205
|
+
RetryExhaustedError,
|
|
195
206
|
ReviewProtocol,
|
|
196
207
|
ReviewResponseMessageSchema,
|
|
197
208
|
RoutingDecisionSchema,
|
|
@@ -285,6 +296,7 @@ import {
|
|
|
285
296
|
buildDependencyGraph,
|
|
286
297
|
buildDependencyGraph2,
|
|
287
298
|
buildPrReviewProposal,
|
|
299
|
+
calculateDelay,
|
|
288
300
|
calculateDistributionStats,
|
|
289
301
|
calculateMinSampleSize,
|
|
290
302
|
calculateRegret,
|
|
@@ -296,6 +308,7 @@ import {
|
|
|
296
308
|
checkPipelinePolicy,
|
|
297
309
|
checkpointToResult,
|
|
298
310
|
chunkByDirectory,
|
|
311
|
+
classifyExpertFailure,
|
|
299
312
|
classifyTask,
|
|
300
313
|
cleanupCheckpoint,
|
|
301
314
|
clearTemplateCache,
|
|
@@ -333,15 +346,18 @@ import {
|
|
|
333
346
|
createExecutionPlan,
|
|
334
347
|
createFeedbackIntegration,
|
|
335
348
|
createFeedbackSubscriber,
|
|
349
|
+
createGeminiAdapter,
|
|
336
350
|
createInitializedWorkflowEngine,
|
|
337
351
|
createInteractionGraph,
|
|
338
352
|
createIsolatedRegistry,
|
|
339
353
|
createMcpLogger,
|
|
354
|
+
createOllamaAdapter,
|
|
340
355
|
createOrchestrator,
|
|
341
356
|
createOrchestratorFactory,
|
|
342
357
|
createOutcomeFeedbackCollector,
|
|
343
358
|
createProductionWorkflowEngine,
|
|
344
359
|
createProtocolFactory,
|
|
360
|
+
createRateLimiter,
|
|
345
361
|
createRealWorkflowEngine,
|
|
346
362
|
createResultAggregator,
|
|
347
363
|
createRoutingDecision,
|
|
@@ -425,6 +441,7 @@ import {
|
|
|
425
441
|
initializeBuiltInTemplates,
|
|
426
442
|
initializeEventBusBridge,
|
|
427
443
|
isCancelled,
|
|
444
|
+
isRetryableError as isRetryableError2,
|
|
428
445
|
isStepCompleted,
|
|
429
446
|
listTemplateIds,
|
|
430
447
|
loadCheckpointState,
|
|
@@ -521,8 +538,10 @@ import {
|
|
|
521
538
|
validateSkillProvenance,
|
|
522
539
|
validateWorkflow,
|
|
523
540
|
validateWorkflowDependencies,
|
|
524
|
-
withLogging
|
|
525
|
-
|
|
541
|
+
withLogging,
|
|
542
|
+
withRetry,
|
|
543
|
+
withRetryWrapper
|
|
544
|
+
} from "./chunk-C7TWCMK4.js";
|
|
526
545
|
import {
|
|
527
546
|
FALLBACK_SCANNER_DATA,
|
|
528
547
|
buildPlanFromAnalysis,
|
|
@@ -530,7 +549,7 @@ import {
|
|
|
530
549
|
generateSecurityPlan,
|
|
531
550
|
getRegistryManifest,
|
|
532
551
|
resolveScannerData
|
|
533
|
-
} from "./chunk-
|
|
552
|
+
} from "./chunk-B4XT3B2E.js";
|
|
534
553
|
import {
|
|
535
554
|
analyzeGitHubRepo,
|
|
536
555
|
analyzeRepo,
|
|
@@ -556,20 +575,20 @@ import {
|
|
|
556
575
|
getKnownNexusVarNames,
|
|
557
576
|
startStdioServer,
|
|
558
577
|
validateNexusEnv
|
|
559
|
-
} from "./chunk-
|
|
578
|
+
} from "./chunk-YKVO32BI.js";
|
|
560
579
|
import {
|
|
561
580
|
OPENAI_MODELS,
|
|
562
581
|
OPENAI_MODEL_ALIASES,
|
|
563
582
|
OpenAIAdapter,
|
|
564
583
|
createOpenAIAdapter
|
|
565
|
-
} from "./chunk-
|
|
584
|
+
} from "./chunk-DLVDFJXU.js";
|
|
566
585
|
import {
|
|
567
586
|
CliCircuitBreakerIntegration,
|
|
568
587
|
createCliCircuitBreakerIntegration
|
|
569
|
-
} from "./chunk-
|
|
588
|
+
} from "./chunk-IK7POCXO.js";
|
|
570
589
|
import {
|
|
571
590
|
executeExpert
|
|
572
|
-
} from "./chunk-
|
|
591
|
+
} from "./chunk-GJRLIANS.js";
|
|
573
592
|
import {
|
|
574
593
|
AgentFindingSchema,
|
|
575
594
|
ConsensusEngine,
|
|
@@ -618,9 +637,9 @@ import {
|
|
|
618
637
|
generateProposalId,
|
|
619
638
|
parseAgentPairKey,
|
|
620
639
|
registerConsensusVoteTool
|
|
621
|
-
} from "./chunk-
|
|
622
|
-
import "./chunk-
|
|
623
|
-
import "./chunk-
|
|
640
|
+
} from "./chunk-SZ3CRNPI.js";
|
|
641
|
+
import "./chunk-7AJWIOMT.js";
|
|
642
|
+
import "./chunk-DYFF72HX.js";
|
|
624
643
|
import {
|
|
625
644
|
AgentActionSchema,
|
|
626
645
|
GitHubReviewer,
|
|
@@ -642,11 +661,11 @@ import {
|
|
|
642
661
|
requiresCorroboration,
|
|
643
662
|
validateAgentAction,
|
|
644
663
|
validateCorroboration
|
|
645
|
-
} from "./chunk-
|
|
664
|
+
} from "./chunk-RQGORCFM.js";
|
|
646
665
|
import {
|
|
647
666
|
GitHubProvider,
|
|
648
667
|
ScmError
|
|
649
|
-
} from "./chunk-
|
|
668
|
+
} from "./chunk-RAK6PTNM.js";
|
|
650
669
|
import {
|
|
651
670
|
GitHubUserRoleSchema,
|
|
652
671
|
InjectionFlagSchema,
|
|
@@ -661,11 +680,11 @@ import {
|
|
|
661
680
|
assessReputation,
|
|
662
681
|
reconcileTrustTier,
|
|
663
682
|
sanitizeInput
|
|
664
|
-
} from "./chunk-
|
|
683
|
+
} from "./chunk-CEDSYAAI.js";
|
|
665
684
|
import {
|
|
666
685
|
ImprovementReviewInputSchema,
|
|
667
686
|
registerImprovementReviewTool
|
|
668
|
-
} from "./chunk-
|
|
687
|
+
} from "./chunk-SCHMBRK4.js";
|
|
669
688
|
import {
|
|
670
689
|
AgentPerformanceSchema,
|
|
671
690
|
ConsensusAlgorithmSchema,
|
|
@@ -680,7 +699,7 @@ import {
|
|
|
680
699
|
ProposalSchema,
|
|
681
700
|
ProposalStatusSchema,
|
|
682
701
|
REJECTION_CATEGORIES,
|
|
683
|
-
RateLimiter,
|
|
702
|
+
RateLimiter as RateLimiter2,
|
|
684
703
|
RejectionCategorySchema,
|
|
685
704
|
VOTING_THRESHOLDS,
|
|
686
705
|
VoteSchema,
|
|
@@ -701,7 +720,7 @@ import {
|
|
|
701
720
|
toolSuccess,
|
|
702
721
|
toolSuccessStructured,
|
|
703
722
|
validateToolInput
|
|
704
|
-
} from "./chunk-
|
|
723
|
+
} from "./chunk-KP4ZXW3B.js";
|
|
705
724
|
import {
|
|
706
725
|
AuditTrail,
|
|
707
726
|
MAX_STRIPPED_ELEMENTS_PER_EVENT,
|
|
@@ -713,7 +732,7 @@ import {
|
|
|
713
732
|
emitReputationEvent,
|
|
714
733
|
emitSanitizationEvent,
|
|
715
734
|
emitTrustEvent
|
|
716
|
-
} from "./chunk-
|
|
735
|
+
} from "./chunk-BTH745HU.js";
|
|
717
736
|
import {
|
|
718
737
|
PersistentStrategyDistiller,
|
|
719
738
|
RulesSnapshotSchema,
|
|
@@ -721,19 +740,19 @@ import {
|
|
|
721
740
|
TokenCounter,
|
|
722
741
|
TokenCounterProvider,
|
|
723
742
|
createTokenCounter
|
|
724
|
-
} from "./chunk-
|
|
743
|
+
} from "./chunk-QBOTSJ7S.js";
|
|
725
744
|
import {
|
|
726
745
|
getTokenEnvVars,
|
|
727
746
|
hasToken,
|
|
728
747
|
resolveToken
|
|
729
|
-
} from "./chunk-
|
|
730
|
-
import "./chunk-
|
|
748
|
+
} from "./chunk-Y7JDXVJA.js";
|
|
749
|
+
import "./chunk-ZSWXEDI6.js";
|
|
731
750
|
import "./chunk-NUBSJGQZ.js";
|
|
732
751
|
import {
|
|
733
752
|
MemoryError
|
|
734
|
-
} from "./chunk-
|
|
753
|
+
} from "./chunk-LFKCJQ7G.js";
|
|
735
754
|
import "./chunk-6T3EPABN.js";
|
|
736
|
-
import "./chunk-
|
|
755
|
+
import "./chunk-O4J34GZT.js";
|
|
737
756
|
import {
|
|
738
757
|
BUILT_IN_EXPERTS,
|
|
739
758
|
BuiltInExpertTypeSchema,
|
|
@@ -752,7 +771,7 @@ import {
|
|
|
752
771
|
resetGlobalRegistry,
|
|
753
772
|
withModelNotFoundFallback,
|
|
754
773
|
wrapResilientWithFallback
|
|
755
|
-
} from "./chunk-
|
|
774
|
+
} from "./chunk-Z5GJ4FXW.js";
|
|
756
775
|
import {
|
|
757
776
|
BaseCliAdapter,
|
|
758
777
|
CLAUDE_MODELS,
|
|
@@ -780,14 +799,13 @@ import {
|
|
|
780
799
|
createCliDetectionCache,
|
|
781
800
|
estimateTaskComplexity,
|
|
782
801
|
executeCliRetryLoop,
|
|
783
|
-
extractRequestSystemPrompt,
|
|
784
802
|
getAvailableClis,
|
|
785
803
|
getTimeoutForTask,
|
|
786
804
|
getTimeoutForTaskAuto,
|
|
787
805
|
isCliAvailable,
|
|
788
806
|
isRetryableError,
|
|
789
807
|
sleep
|
|
790
|
-
} from "./chunk-
|
|
808
|
+
} from "./chunk-5UDKUPZB.js";
|
|
791
809
|
import {
|
|
792
810
|
AdapterModelError,
|
|
793
811
|
BaseAdapter,
|
|
@@ -803,20 +821,17 @@ import {
|
|
|
803
821
|
fromArray,
|
|
804
822
|
mergeStreams,
|
|
805
823
|
reduceStream,
|
|
806
|
-
requireApiKey,
|
|
807
824
|
skip,
|
|
808
825
|
take,
|
|
809
826
|
takeUntil,
|
|
810
827
|
tapStream,
|
|
811
828
|
transformStream,
|
|
812
|
-
validateApiKeyPresence,
|
|
813
829
|
withTimeout
|
|
814
|
-
} from "./chunk-
|
|
830
|
+
} from "./chunk-4KVAHGMB.js";
|
|
815
831
|
import {
|
|
816
|
-
DEFAULTS,
|
|
817
832
|
PROVIDER_ENV_KEYS
|
|
818
|
-
} from "./chunk-
|
|
819
|
-
import "./chunk-
|
|
833
|
+
} from "./chunk-QFS5VOB6.js";
|
|
834
|
+
import "./chunk-76Q63KJM.js";
|
|
820
835
|
import {
|
|
821
836
|
AvailabilityCache,
|
|
822
837
|
filterAvailableModels,
|
|
@@ -825,9 +840,9 @@ import {
|
|
|
825
840
|
getFallbackChain,
|
|
826
841
|
resetAvailabilityCache,
|
|
827
842
|
resolveFallback
|
|
828
|
-
} from "./chunk-
|
|
843
|
+
} from "./chunk-SUWN54CK.js";
|
|
829
844
|
import "./chunk-QZUG667L.js";
|
|
830
|
-
import "./chunk-
|
|
845
|
+
import "./chunk-IC3NZHPT.js";
|
|
831
846
|
import {
|
|
832
847
|
AgentCapability,
|
|
833
848
|
AgentError,
|
|
@@ -880,17 +895,13 @@ import {
|
|
|
880
895
|
detectTrend,
|
|
881
896
|
err,
|
|
882
897
|
extractNonErrorMessage,
|
|
883
|
-
findCanonicalModel,
|
|
884
898
|
formatZodError,
|
|
885
899
|
generateWeatherReport,
|
|
886
|
-
getCliModelName,
|
|
887
900
|
getDefaultAvailableModelsCache,
|
|
888
901
|
getDefaultRegistry,
|
|
889
|
-
getErrorMessage,
|
|
890
902
|
getOutcomeStore,
|
|
891
903
|
getRandomProvider,
|
|
892
904
|
getTimeProvider,
|
|
893
|
-
getTokenEstimator,
|
|
894
905
|
isErr,
|
|
895
906
|
isOk,
|
|
896
907
|
isZodError,
|
|
@@ -905,1247 +916,11 @@ import {
|
|
|
905
916
|
toError,
|
|
906
917
|
unwrap,
|
|
907
918
|
unwrapOr
|
|
908
|
-
} from "./chunk-
|
|
919
|
+
} from "./chunk-QBCWORAK.js";
|
|
909
920
|
import "./chunk-AXTD4TFK.js";
|
|
910
921
|
import "./chunk-DHVMSIT5.js";
|
|
911
922
|
import "./chunk-ZPWHCABL.js";
|
|
912
923
|
|
|
913
|
-
// src/adapters/factory.ts
|
|
914
|
-
import { z } from "zod";
|
|
915
|
-
var AdapterConfigSchema = z.object({
|
|
916
|
-
/** Provider identifier (e.g., 'anthropic', 'openai') */
|
|
917
|
-
providerId: z.string().min(1, "Provider ID is required"),
|
|
918
|
-
/** Model identifier (e.g., 'claude-sonnet-4', 'gpt-4o') */
|
|
919
|
-
modelId: z.string().min(1, "Model ID is required"),
|
|
920
|
-
/** API key for authentication (optional, may come from environment) */
|
|
921
|
-
apiKey: z.string().optional(),
|
|
922
|
-
/** Base URL for the API (optional, uses provider default) */
|
|
923
|
-
baseUrl: z.url("Base URL must be a valid URL").optional(),
|
|
924
|
-
/** Request timeout in milliseconds */
|
|
925
|
-
timeout: z.number().positive("Timeout must be positive").optional(),
|
|
926
|
-
/** Maximum number of retries for failed requests */
|
|
927
|
-
maxRetries: z.number().int("Max retries must be an integer").min(0).optional()
|
|
928
|
-
});
|
|
929
|
-
var AdapterFactory = class {
|
|
930
|
-
/**
|
|
931
|
-
* Registry mapping provider IDs to their creator functions.
|
|
932
|
-
*/
|
|
933
|
-
registry = /* @__PURE__ */ new Map();
|
|
934
|
-
/**
|
|
935
|
-
* Registers an adapter creator for a provider.
|
|
936
|
-
*
|
|
937
|
-
* @param providerId - Unique identifier for the provider (e.g., 'anthropic')
|
|
938
|
-
* @param creator - Factory function that creates adapters for this provider
|
|
939
|
-
* @param options - Registration options
|
|
940
|
-
* @returns Result indicating success or failure
|
|
941
|
-
*
|
|
942
|
-
* @example
|
|
943
|
-
* ```typescript
|
|
944
|
-
* const result = factory.register('anthropic', (config) => new ClaudeAdapter(config));
|
|
945
|
-
* if (!result.ok) {
|
|
946
|
-
* console.error('Registration failed:', result.error.message);
|
|
947
|
-
* }
|
|
948
|
-
* ```
|
|
949
|
-
*/
|
|
950
|
-
register(providerId, creator, options = {}) {
|
|
951
|
-
const { allowOverwrite = false } = options;
|
|
952
|
-
if (!providerId || providerId.trim() === "") {
|
|
953
|
-
return err(
|
|
954
|
-
new ConfigError("Provider ID cannot be empty", {
|
|
955
|
-
context: { providerId }
|
|
956
|
-
})
|
|
957
|
-
);
|
|
958
|
-
}
|
|
959
|
-
if (this.registry.has(providerId) && !allowOverwrite) {
|
|
960
|
-
return err(
|
|
961
|
-
new ConfigError(`Provider '${providerId}' is already registered`, {
|
|
962
|
-
context: { providerId, existingProviders: this.listProviders() }
|
|
963
|
-
})
|
|
964
|
-
);
|
|
965
|
-
}
|
|
966
|
-
this.registry.set(providerId, creator);
|
|
967
|
-
return ok(void 0);
|
|
968
|
-
}
|
|
969
|
-
/**
|
|
970
|
-
* Unregisters an adapter creator for a provider.
|
|
971
|
-
*
|
|
972
|
-
* @param providerId - The provider ID to unregister
|
|
973
|
-
* @returns Result indicating whether the provider was removed
|
|
974
|
-
*/
|
|
975
|
-
unregister(providerId) {
|
|
976
|
-
if (!providerId || providerId.trim() === "") {
|
|
977
|
-
return err(
|
|
978
|
-
new ConfigError("Provider ID cannot be empty", {
|
|
979
|
-
context: { providerId }
|
|
980
|
-
})
|
|
981
|
-
);
|
|
982
|
-
}
|
|
983
|
-
const deleted = this.registry.delete(providerId);
|
|
984
|
-
return ok(deleted);
|
|
985
|
-
}
|
|
986
|
-
/**
|
|
987
|
-
* Creates an adapter instance for the specified configuration.
|
|
988
|
-
*
|
|
989
|
-
* Validates the configuration against the schema, looks up the provider
|
|
990
|
-
* in the registry, and invokes the creator function to produce an adapter.
|
|
991
|
-
*
|
|
992
|
-
* @param config - Adapter configuration specifying provider and settings
|
|
993
|
-
* @returns Result containing the adapter or a ConfigError
|
|
994
|
-
*
|
|
995
|
-
* @example
|
|
996
|
-
* ```typescript
|
|
997
|
-
* const result = factory.create({
|
|
998
|
-
* providerId: 'anthropic',
|
|
999
|
-
* modelId: 'claude-sonnet-4',
|
|
1000
|
-
* timeout: 30000,
|
|
1001
|
-
* maxRetries: 3
|
|
1002
|
-
* });
|
|
1003
|
-
*
|
|
1004
|
-
* if (result.ok) {
|
|
1005
|
-
* const response = await result.value.complete(request);
|
|
1006
|
-
* } else {
|
|
1007
|
-
* console.error('Failed to create adapter:', result.error.message);
|
|
1008
|
-
* }
|
|
1009
|
-
* ```
|
|
1010
|
-
*/
|
|
1011
|
-
create(config) {
|
|
1012
|
-
const validationResult = this.validateConfig(config);
|
|
1013
|
-
if (!validationResult.ok) {
|
|
1014
|
-
return validationResult;
|
|
1015
|
-
}
|
|
1016
|
-
const validConfig = validationResult.value;
|
|
1017
|
-
const creator = this.registry.get(validConfig.providerId);
|
|
1018
|
-
if (creator === void 0) {
|
|
1019
|
-
return err(
|
|
1020
|
-
new ConfigError(`Provider '${validConfig.providerId}' is not registered`, {
|
|
1021
|
-
context: {
|
|
1022
|
-
providerId: validConfig.providerId,
|
|
1023
|
-
availableProviders: this.listProviders()
|
|
1024
|
-
}
|
|
1025
|
-
})
|
|
1026
|
-
);
|
|
1027
|
-
}
|
|
1028
|
-
return this.invokeCreator(creator, validConfig);
|
|
1029
|
-
}
|
|
1030
|
-
/**
|
|
1031
|
-
* Validates adapter configuration against the schema.
|
|
1032
|
-
*/
|
|
1033
|
-
validateConfig(config) {
|
|
1034
|
-
const result = AdapterConfigSchema.safeParse(config);
|
|
1035
|
-
if (!result.success) {
|
|
1036
|
-
return err(
|
|
1037
|
-
new ConfigError(`Invalid adapter configuration: ${formatZodError(result.error)}`, {
|
|
1038
|
-
context: {
|
|
1039
|
-
config: this.sanitizeConfig(config),
|
|
1040
|
-
validationErrors: result.error.issues
|
|
1041
|
-
}
|
|
1042
|
-
})
|
|
1043
|
-
);
|
|
1044
|
-
}
|
|
1045
|
-
return ok(result.data);
|
|
1046
|
-
}
|
|
1047
|
-
/**
|
|
1048
|
-
* Invokes the creator function to create an adapter.
|
|
1049
|
-
*/
|
|
1050
|
-
invokeCreator(creator, config) {
|
|
1051
|
-
try {
|
|
1052
|
-
return ok(creator(config));
|
|
1053
|
-
} catch (error) {
|
|
1054
|
-
return this.handleCreatorError(error, config);
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
/**
|
|
1058
|
-
* Handles errors thrown by adapter creator functions.
|
|
1059
|
-
*/
|
|
1060
|
-
handleCreatorError(error, config) {
|
|
1061
|
-
const message = getErrorMessage(error);
|
|
1062
|
-
const baseOptions = {
|
|
1063
|
-
context: { providerId: config.providerId, modelId: config.modelId }
|
|
1064
|
-
};
|
|
1065
|
-
if (error instanceof Error) {
|
|
1066
|
-
return err(
|
|
1067
|
-
new ConfigError(`Failed to create adapter: ${message}`, {
|
|
1068
|
-
...baseOptions,
|
|
1069
|
-
cause: error
|
|
1070
|
-
})
|
|
1071
|
-
);
|
|
1072
|
-
}
|
|
1073
|
-
return err(new ConfigError(`Failed to create adapter: ${message}`, baseOptions));
|
|
1074
|
-
}
|
|
1075
|
-
/**
|
|
1076
|
-
* Checks if a provider is registered.
|
|
1077
|
-
*
|
|
1078
|
-
* @param providerId - The provider ID to check
|
|
1079
|
-
* @returns True if the provider is registered
|
|
1080
|
-
*/
|
|
1081
|
-
hasProvider(providerId) {
|
|
1082
|
-
return this.registry.has(providerId);
|
|
1083
|
-
}
|
|
1084
|
-
/**
|
|
1085
|
-
* Returns a list of all registered provider IDs.
|
|
1086
|
-
*
|
|
1087
|
-
* @returns Array of provider identifiers
|
|
1088
|
-
*/
|
|
1089
|
-
listProviders() {
|
|
1090
|
-
return Array.from(this.registry.keys());
|
|
1091
|
-
}
|
|
1092
|
-
/**
|
|
1093
|
-
* Returns the number of registered providers.
|
|
1094
|
-
*
|
|
1095
|
-
* @returns Count of registered providers
|
|
1096
|
-
*/
|
|
1097
|
-
get size() {
|
|
1098
|
-
return this.registry.size;
|
|
1099
|
-
}
|
|
1100
|
-
/**
|
|
1101
|
-
* Clears all registered providers.
|
|
1102
|
-
* Useful for testing or resetting the factory state.
|
|
1103
|
-
*/
|
|
1104
|
-
clear() {
|
|
1105
|
-
this.registry.clear();
|
|
1106
|
-
}
|
|
1107
|
-
/**
|
|
1108
|
-
* Sanitizes configuration for logging by removing sensitive fields.
|
|
1109
|
-
*
|
|
1110
|
-
* @param config - Configuration to sanitize
|
|
1111
|
-
* @returns Sanitized configuration safe for logging
|
|
1112
|
-
*/
|
|
1113
|
-
sanitizeConfig(config) {
|
|
1114
|
-
const sanitized = { ...config };
|
|
1115
|
-
if (config.apiKey !== void 0) {
|
|
1116
|
-
sanitized["apiKey"] = "[REDACTED]";
|
|
1117
|
-
}
|
|
1118
|
-
return sanitized;
|
|
1119
|
-
}
|
|
1120
|
-
};
|
|
1121
|
-
|
|
1122
|
-
// src/adapters/rate-limiter.ts
|
|
1123
|
-
var RateLimiter2 = class {
|
|
1124
|
-
capacity;
|
|
1125
|
-
refillRate;
|
|
1126
|
-
refillInterval;
|
|
1127
|
-
tokens;
|
|
1128
|
-
lastRefillTime;
|
|
1129
|
-
/**
|
|
1130
|
-
* Creates a new RateLimiter instance.
|
|
1131
|
-
*
|
|
1132
|
-
* @param config - Configuration options
|
|
1133
|
-
* @throws {RateLimitError} If configuration is invalid
|
|
1134
|
-
*/
|
|
1135
|
-
constructor(config) {
|
|
1136
|
-
this.validateConfig(config);
|
|
1137
|
-
this.capacity = config.capacity;
|
|
1138
|
-
this.refillRate = config.refillRate;
|
|
1139
|
-
this.refillInterval = config.refillInterval ?? 100;
|
|
1140
|
-
this.tokens = config.capacity;
|
|
1141
|
-
this.lastRefillTime = getTimeProvider().now();
|
|
1142
|
-
}
|
|
1143
|
-
/**
|
|
1144
|
-
* Validates the configuration parameters.
|
|
1145
|
-
*/
|
|
1146
|
-
validateConfig(config) {
|
|
1147
|
-
if (config.capacity <= 0) {
|
|
1148
|
-
throw new RateLimitError("Capacity must be a positive number", {
|
|
1149
|
-
context: { capacity: config.capacity }
|
|
1150
|
-
});
|
|
1151
|
-
}
|
|
1152
|
-
if (config.refillRate <= 0) {
|
|
1153
|
-
throw new RateLimitError("Refill rate must be a positive number", {
|
|
1154
|
-
context: { refillRate: config.refillRate }
|
|
1155
|
-
});
|
|
1156
|
-
}
|
|
1157
|
-
if (config.refillInterval !== void 0 && config.refillInterval <= 0) {
|
|
1158
|
-
throw new RateLimitError("Refill interval must be a positive number", {
|
|
1159
|
-
context: { refillInterval: config.refillInterval }
|
|
1160
|
-
});
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
|
-
/**
|
|
1164
|
-
* Refills tokens based on elapsed time since last refill.
|
|
1165
|
-
* Called automatically before token operations.
|
|
1166
|
-
*/
|
|
1167
|
-
refill() {
|
|
1168
|
-
const now = getTimeProvider().now();
|
|
1169
|
-
const elapsedMs = now - this.lastRefillTime;
|
|
1170
|
-
const elapsedSeconds = elapsedMs / 1e3;
|
|
1171
|
-
const tokensToAdd = elapsedSeconds * this.refillRate;
|
|
1172
|
-
if (tokensToAdd >= 1) {
|
|
1173
|
-
this.tokens = Math.min(this.capacity, this.tokens + tokensToAdd);
|
|
1174
|
-
this.lastRefillTime = now;
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
/**
|
|
1178
|
-
* Attempts to acquire the specified number of tokens.
|
|
1179
|
-
*
|
|
1180
|
-
* @param tokens - Number of tokens to acquire (default: 1)
|
|
1181
|
-
* @returns true if tokens were acquired, false if rate limited
|
|
1182
|
-
*
|
|
1183
|
-
* @example
|
|
1184
|
-
* ```typescript
|
|
1185
|
-
* if (limiter.tryAcquire(5)) {
|
|
1186
|
-
* // Acquired 5 tokens
|
|
1187
|
-
* }
|
|
1188
|
-
* ```
|
|
1189
|
-
*/
|
|
1190
|
-
tryAcquire(tokens = 1) {
|
|
1191
|
-
if (tokens <= 0) {
|
|
1192
|
-
return true;
|
|
1193
|
-
}
|
|
1194
|
-
if (tokens > this.capacity) {
|
|
1195
|
-
return false;
|
|
1196
|
-
}
|
|
1197
|
-
this.refill();
|
|
1198
|
-
if (this.tokens >= tokens) {
|
|
1199
|
-
this.tokens -= tokens;
|
|
1200
|
-
return true;
|
|
1201
|
-
}
|
|
1202
|
-
return false;
|
|
1203
|
-
}
|
|
1204
|
-
/**
|
|
1205
|
-
* Attempts to acquire tokens and returns a Result with detailed information.
|
|
1206
|
-
*
|
|
1207
|
-
* @param tokens - Number of tokens to acquire (default: 1)
|
|
1208
|
-
* @returns Result containing void on success, or RateLimitExceeded on failure
|
|
1209
|
-
*
|
|
1210
|
-
* @example
|
|
1211
|
-
* ```typescript
|
|
1212
|
-
* const result = limiter.acquire(5);
|
|
1213
|
-
* if (!result.ok) {
|
|
1214
|
-
* console.log(`Retry after ${result.error.retryAfterMs}ms`);
|
|
1215
|
-
* }
|
|
1216
|
-
* ```
|
|
1217
|
-
*/
|
|
1218
|
-
acquire(tokens = 1) {
|
|
1219
|
-
if (tokens <= 0) {
|
|
1220
|
-
return ok(void 0);
|
|
1221
|
-
}
|
|
1222
|
-
if (tokens > this.capacity) {
|
|
1223
|
-
return err({
|
|
1224
|
-
type: "rate_limit_exceeded",
|
|
1225
|
-
requested: tokens,
|
|
1226
|
-
available: this.tokens,
|
|
1227
|
-
retryAfterMs: Infinity
|
|
1228
|
-
});
|
|
1229
|
-
}
|
|
1230
|
-
this.refill();
|
|
1231
|
-
if (this.tokens >= tokens) {
|
|
1232
|
-
this.tokens -= tokens;
|
|
1233
|
-
return ok(void 0);
|
|
1234
|
-
}
|
|
1235
|
-
const deficit = tokens - this.tokens;
|
|
1236
|
-
const retryAfterMs = Math.ceil(deficit / this.refillRate * 1e3);
|
|
1237
|
-
return err({
|
|
1238
|
-
type: "rate_limit_exceeded",
|
|
1239
|
-
requested: tokens,
|
|
1240
|
-
available: Math.floor(this.tokens),
|
|
1241
|
-
retryAfterMs
|
|
1242
|
-
});
|
|
1243
|
-
}
|
|
1244
|
-
/**
|
|
1245
|
-
* Waits until the specified number of tokens are available, then acquires them.
|
|
1246
|
-
*
|
|
1247
|
-
* @param tokens - Number of tokens to acquire (default: 1)
|
|
1248
|
-
* @returns Promise that resolves when tokens are acquired
|
|
1249
|
-
* @throws {RateLimitError} If tokens exceed capacity (would wait forever)
|
|
1250
|
-
*
|
|
1251
|
-
* @example
|
|
1252
|
-
* ```typescript
|
|
1253
|
-
* await limiter.waitForTokens(10);
|
|
1254
|
-
* // 10 tokens acquired
|
|
1255
|
-
* ```
|
|
1256
|
-
*/
|
|
1257
|
-
async waitForTokens(tokens = 1) {
|
|
1258
|
-
if (tokens <= 0) {
|
|
1259
|
-
return;
|
|
1260
|
-
}
|
|
1261
|
-
if (tokens > this.capacity) {
|
|
1262
|
-
throw new RateLimitError(
|
|
1263
|
-
`Cannot acquire ${String(tokens)} tokens: exceeds capacity of ${String(this.capacity)}`,
|
|
1264
|
-
{ context: { requested: tokens, capacity: this.capacity } }
|
|
1265
|
-
);
|
|
1266
|
-
}
|
|
1267
|
-
while (!this.tryAcquire(tokens)) {
|
|
1268
|
-
await this.sleep(this.refillInterval);
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
|
-
/**
|
|
1272
|
-
* Sleeps for the specified duration.
|
|
1273
|
-
*/
|
|
1274
|
-
sleep(ms) {
|
|
1275
|
-
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
1276
|
-
}
|
|
1277
|
-
/**
|
|
1278
|
-
* Returns the current number of available tokens.
|
|
1279
|
-
* Performs a refill before returning the count.
|
|
1280
|
-
*
|
|
1281
|
-
* @returns Number of available tokens (may be fractional)
|
|
1282
|
-
*/
|
|
1283
|
-
getRemainingTokens() {
|
|
1284
|
-
this.refill();
|
|
1285
|
-
return this.tokens;
|
|
1286
|
-
}
|
|
1287
|
-
/**
|
|
1288
|
-
* Returns the number of whole tokens available.
|
|
1289
|
-
*
|
|
1290
|
-
* @returns Integer number of available tokens
|
|
1291
|
-
*/
|
|
1292
|
-
getAvailableTokens() {
|
|
1293
|
-
return Math.floor(this.getRemainingTokens());
|
|
1294
|
-
}
|
|
1295
|
-
/**
|
|
1296
|
-
* Resets the rate limiter to its initial state.
|
|
1297
|
-
* The bucket is refilled to capacity.
|
|
1298
|
-
*/
|
|
1299
|
-
reset() {
|
|
1300
|
-
this.tokens = this.capacity;
|
|
1301
|
-
this.lastRefillTime = getTimeProvider().now();
|
|
1302
|
-
}
|
|
1303
|
-
/**
|
|
1304
|
-
* Returns the bucket's maximum capacity.
|
|
1305
|
-
*/
|
|
1306
|
-
getCapacity() {
|
|
1307
|
-
return this.capacity;
|
|
1308
|
-
}
|
|
1309
|
-
/**
|
|
1310
|
-
* Returns the refill rate in tokens per second.
|
|
1311
|
-
*/
|
|
1312
|
-
getRefillRate() {
|
|
1313
|
-
return this.refillRate;
|
|
1314
|
-
}
|
|
1315
|
-
/**
|
|
1316
|
-
* Calculates the time in milliseconds until the specified tokens are available.
|
|
1317
|
-
*
|
|
1318
|
-
* @param tokens - Number of tokens needed (default: 1)
|
|
1319
|
-
* @returns Time in milliseconds until tokens are available, 0 if already available
|
|
1320
|
-
*/
|
|
1321
|
-
getTimeUntilAvailable(tokens = 1) {
|
|
1322
|
-
if (tokens <= 0) {
|
|
1323
|
-
return 0;
|
|
1324
|
-
}
|
|
1325
|
-
if (tokens > this.capacity) {
|
|
1326
|
-
return Infinity;
|
|
1327
|
-
}
|
|
1328
|
-
this.refill();
|
|
1329
|
-
if (this.tokens >= tokens) {
|
|
1330
|
-
return 0;
|
|
1331
|
-
}
|
|
1332
|
-
const deficit = tokens - this.tokens;
|
|
1333
|
-
return Math.ceil(deficit / this.refillRate * 1e3);
|
|
1334
|
-
}
|
|
1335
|
-
};
|
|
1336
|
-
function createRateLimiter(config) {
|
|
1337
|
-
return new RateLimiter2(config);
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
// src/adapters/retry.ts
|
|
1341
|
-
var DEFAULT_RETRY_CONFIG = {
|
|
1342
|
-
maxRetries: DEFAULTS.RETRY_DEFAULTS.maxRetries,
|
|
1343
|
-
baseDelayMs: DEFAULTS.RETRY_DEFAULTS.baseDelayMs,
|
|
1344
|
-
maxDelayMs: DEFAULTS.RETRY_DEFAULTS.maxDelayMs,
|
|
1345
|
-
jitterFactor: DEFAULTS.RETRY_DEFAULTS.jitterFactor
|
|
1346
|
-
};
|
|
1347
|
-
var RetryExhaustedError = class extends NexusError {
|
|
1348
|
-
/** Number of attempts made */
|
|
1349
|
-
attempts;
|
|
1350
|
-
/** The last error encountered */
|
|
1351
|
-
lastError;
|
|
1352
|
-
constructor(attempts, lastError) {
|
|
1353
|
-
const message = `All ${String(attempts)} retry attempts exhausted`;
|
|
1354
|
-
const options = {
|
|
1355
|
-
code: ErrorCode.MODEL_ERROR,
|
|
1356
|
-
context: {
|
|
1357
|
-
attempts,
|
|
1358
|
-
lastErrorMessage: lastError instanceof Error ? lastError.message : String(lastError)
|
|
1359
|
-
}
|
|
1360
|
-
};
|
|
1361
|
-
if (lastError instanceof Error) {
|
|
1362
|
-
options.cause = lastError;
|
|
1363
|
-
}
|
|
1364
|
-
super(message, options);
|
|
1365
|
-
this.name = "RetryExhaustedError";
|
|
1366
|
-
this.attempts = attempts;
|
|
1367
|
-
this.lastError = lastError;
|
|
1368
|
-
}
|
|
1369
|
-
};
|
|
1370
|
-
function calculateDelay(attempt, config) {
|
|
1371
|
-
const exponentialDelay = config.baseDelayMs * Math.pow(2, attempt);
|
|
1372
|
-
const cappedDelay = Math.min(exponentialDelay, config.maxDelayMs);
|
|
1373
|
-
const jitterRange = cappedDelay * config.jitterFactor;
|
|
1374
|
-
const jitter = (getRandomProvider().random() * 2 - 1) * jitterRange;
|
|
1375
|
-
return Math.max(0, Math.floor(cappedDelay + jitter));
|
|
1376
|
-
}
|
|
1377
|
-
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([
|
|
1378
|
-
408,
|
|
1379
|
-
// Request Timeout
|
|
1380
|
-
429,
|
|
1381
|
-
// Too Many Requests
|
|
1382
|
-
500,
|
|
1383
|
-
// Internal Server Error
|
|
1384
|
-
502,
|
|
1385
|
-
// Bad Gateway
|
|
1386
|
-
503,
|
|
1387
|
-
// Service Unavailable
|
|
1388
|
-
504
|
|
1389
|
-
// Gateway Timeout
|
|
1390
|
-
]);
|
|
1391
|
-
var NON_RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([
|
|
1392
|
-
400,
|
|
1393
|
-
// Bad Request
|
|
1394
|
-
401,
|
|
1395
|
-
// Unauthorized
|
|
1396
|
-
403,
|
|
1397
|
-
// Forbidden
|
|
1398
|
-
404,
|
|
1399
|
-
// Not Found
|
|
1400
|
-
405,
|
|
1401
|
-
// Method Not Allowed
|
|
1402
|
-
409,
|
|
1403
|
-
// Conflict
|
|
1404
|
-
410,
|
|
1405
|
-
// Gone
|
|
1406
|
-
422
|
|
1407
|
-
// Unprocessable Entity
|
|
1408
|
-
]);
|
|
1409
|
-
var RETRYABLE_ERROR_PATTERNS = [
|
|
1410
|
-
/ECONNRESET/i,
|
|
1411
|
-
/ECONNREFUSED/i,
|
|
1412
|
-
/ETIMEDOUT/i,
|
|
1413
|
-
/ENOTFOUND/i,
|
|
1414
|
-
/ENETUNREACH/i,
|
|
1415
|
-
/EAI_AGAIN/i,
|
|
1416
|
-
/socket hang up/i,
|
|
1417
|
-
/network/i,
|
|
1418
|
-
/timeout/i,
|
|
1419
|
-
/timed out/i,
|
|
1420
|
-
/aborted/i
|
|
1421
|
-
];
|
|
1422
|
-
function getStatusCode(error) {
|
|
1423
|
-
if (error === null || error === void 0) {
|
|
1424
|
-
return void 0;
|
|
1425
|
-
}
|
|
1426
|
-
if (typeof error === "object") {
|
|
1427
|
-
const errorObj = error;
|
|
1428
|
-
if (typeof errorObj["status"] === "number") {
|
|
1429
|
-
return errorObj["status"];
|
|
1430
|
-
}
|
|
1431
|
-
if (typeof errorObj["response"] === "object" && errorObj["response"] !== null) {
|
|
1432
|
-
const response = errorObj["response"];
|
|
1433
|
-
if (typeof response["status"] === "number") {
|
|
1434
|
-
return response["status"];
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
if (typeof errorObj["statusCode"] === "number") {
|
|
1438
|
-
return errorObj["statusCode"];
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
return void 0;
|
|
1442
|
-
}
|
|
1443
|
-
function isRetryableError2(error) {
|
|
1444
|
-
if (error === null || error === void 0) {
|
|
1445
|
-
return false;
|
|
1446
|
-
}
|
|
1447
|
-
const statusCode = getStatusCode(error);
|
|
1448
|
-
if (statusCode !== void 0) {
|
|
1449
|
-
if (NON_RETRYABLE_STATUS_CODES.has(statusCode)) {
|
|
1450
|
-
return false;
|
|
1451
|
-
}
|
|
1452
|
-
if (RETRYABLE_STATUS_CODES.has(statusCode)) {
|
|
1453
|
-
return true;
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
if (error instanceof NexusError) {
|
|
1457
|
-
const retryableCodes = [
|
|
1458
|
-
ErrorCode.MODEL_RATE_LIMITED,
|
|
1459
|
-
ErrorCode.MODEL_TIMEOUT,
|
|
1460
|
-
ErrorCode.TIMEOUT_ERROR,
|
|
1461
|
-
ErrorCode.RATE_LIMIT_ERROR,
|
|
1462
|
-
// #3317 finding #7: a model temporarily unavailable (503/overloaded) is
|
|
1463
|
-
// transient — retry. (MODEL_NOT_FOUND stays non-retryable: retry won't help.)
|
|
1464
|
-
ErrorCode.MODEL_UNAVAILABLE
|
|
1465
|
-
];
|
|
1466
|
-
return retryableCodes.includes(error.code);
|
|
1467
|
-
}
|
|
1468
|
-
if (error instanceof Error) {
|
|
1469
|
-
const message = error.message;
|
|
1470
|
-
for (const pattern of RETRYABLE_ERROR_PATTERNS) {
|
|
1471
|
-
if (pattern.test(message)) {
|
|
1472
|
-
return true;
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1476
|
-
return false;
|
|
1477
|
-
}
|
|
1478
|
-
function mergeConfig(config) {
|
|
1479
|
-
return {
|
|
1480
|
-
maxRetries: config.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,
|
|
1481
|
-
baseDelayMs: config.baseDelayMs ?? DEFAULT_RETRY_CONFIG.baseDelayMs,
|
|
1482
|
-
maxDelayMs: config.maxDelayMs ?? DEFAULT_RETRY_CONFIG.maxDelayMs,
|
|
1483
|
-
jitterFactor: config.jitterFactor ?? DEFAULT_RETRY_CONFIG.jitterFactor
|
|
1484
|
-
};
|
|
1485
|
-
}
|
|
1486
|
-
async function withRetry(operation, options = {}) {
|
|
1487
|
-
const config = mergeConfig(options.config ?? {});
|
|
1488
|
-
const isRetryable = options.isRetryable ?? isRetryableError2;
|
|
1489
|
-
const onRetry = options.onRetry;
|
|
1490
|
-
const maxAttempts = config.maxRetries + 1;
|
|
1491
|
-
let lastError;
|
|
1492
|
-
let attemptsMade = 0;
|
|
1493
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
1494
|
-
attemptsMade = attempt + 1;
|
|
1495
|
-
try {
|
|
1496
|
-
const result = await operation();
|
|
1497
|
-
return ok(result);
|
|
1498
|
-
} catch (error) {
|
|
1499
|
-
lastError = error;
|
|
1500
|
-
const isLastAttempt = attempt === maxAttempts - 1;
|
|
1501
|
-
if (isLastAttempt || !isRetryable(error)) {
|
|
1502
|
-
break;
|
|
1503
|
-
}
|
|
1504
|
-
const delayMs = calculateDelay(attempt, config);
|
|
1505
|
-
if (onRetry) {
|
|
1506
|
-
onRetry({
|
|
1507
|
-
attempt: attempt + 1,
|
|
1508
|
-
maxAttempts,
|
|
1509
|
-
delayMs,
|
|
1510
|
-
error
|
|
1511
|
-
});
|
|
1512
|
-
}
|
|
1513
|
-
await sleep(delayMs);
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
return err(new RetryExhaustedError(attemptsMade, lastError));
|
|
1517
|
-
}
|
|
1518
|
-
function withRetryWrapper(fn, options = {}) {
|
|
1519
|
-
return (...args) => withRetry(() => fn(...args), options);
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
// src/adapters/ollama-adapter.ts
|
|
1523
|
-
import { Ollama } from "ollama";
|
|
1524
|
-
|
|
1525
|
-
// src/adapters/abort-utils.ts
|
|
1526
|
-
var AbortError = class extends Error {
|
|
1527
|
-
name = "AbortError";
|
|
1528
|
-
constructor(message = "Operation aborted") {
|
|
1529
|
-
super(message);
|
|
1530
|
-
}
|
|
1531
|
-
};
|
|
1532
|
-
function raceAbort(promise, signal) {
|
|
1533
|
-
if (signal === void 0) return promise;
|
|
1534
|
-
if (signal.aborted) return Promise.reject(new AbortError());
|
|
1535
|
-
return new Promise((resolve2, reject) => {
|
|
1536
|
-
const onAbort = () => {
|
|
1537
|
-
reject(new AbortError());
|
|
1538
|
-
};
|
|
1539
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
1540
|
-
promise.then(
|
|
1541
|
-
(value) => {
|
|
1542
|
-
signal.removeEventListener("abort", onAbort);
|
|
1543
|
-
resolve2(value);
|
|
1544
|
-
},
|
|
1545
|
-
(error) => {
|
|
1546
|
-
signal.removeEventListener("abort", onAbort);
|
|
1547
|
-
reject(error instanceof Error ? error : new Error(String(error)));
|
|
1548
|
-
}
|
|
1549
|
-
);
|
|
1550
|
-
});
|
|
1551
|
-
}
|
|
1552
|
-
|
|
1553
|
-
// src/adapters/ollama-adapter.ts
|
|
1554
|
-
var OLLAMA_MODELS = {
|
|
1555
|
-
LLAMA3_8B: "llama3:8b",
|
|
1556
|
-
LLAMA3_70B: "llama3:70b",
|
|
1557
|
-
LLAMA3_1_8B: "llama3.1:8b",
|
|
1558
|
-
LLAMA3_2_3B: "llama3.2:3b",
|
|
1559
|
-
MISTRAL: "mistral",
|
|
1560
|
-
MISTRAL_NEMO: "mistral-nemo",
|
|
1561
|
-
CODELLAMA: "codellama",
|
|
1562
|
-
CODELLAMA_34B: "codellama:34b",
|
|
1563
|
-
DEEPSEEK_CODER: "deepseek-coder",
|
|
1564
|
-
QWEN2_5_CODER: "qwen2.5-coder",
|
|
1565
|
-
PHI3: "phi3",
|
|
1566
|
-
GEMMA2: "gemma2"
|
|
1567
|
-
};
|
|
1568
|
-
var DEFAULT_OLLAMA_HOST = "http://localhost:11434";
|
|
1569
|
-
var DEFAULT_MAX_TOKENS = 2048;
|
|
1570
|
-
function mapStopReason(reason) {
|
|
1571
|
-
if (reason === void 0 || reason === "") return "end_turn";
|
|
1572
|
-
switch (reason) {
|
|
1573
|
-
case "stop":
|
|
1574
|
-
return "end_turn";
|
|
1575
|
-
case "length":
|
|
1576
|
-
return "max_tokens";
|
|
1577
|
-
case "tool_calls":
|
|
1578
|
-
return "tool_use";
|
|
1579
|
-
default:
|
|
1580
|
-
return "end_turn";
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
function mapOllamaMessageToContent(message) {
|
|
1584
|
-
const content = [];
|
|
1585
|
-
const messageContent = message.content;
|
|
1586
|
-
if (messageContent !== "" && messageContent.length > 0) {
|
|
1587
|
-
content.push({ type: "text", text: messageContent });
|
|
1588
|
-
}
|
|
1589
|
-
const toolCalls = message.tool_calls;
|
|
1590
|
-
if (toolCalls !== void 0 && toolCalls.length > 0) {
|
|
1591
|
-
for (const tc of toolCalls) {
|
|
1592
|
-
content.push({
|
|
1593
|
-
type: "tool_use",
|
|
1594
|
-
id: `tool_${String(getTimeProvider().now())}_${getRandomProvider().random().toString(36).slice(2, 9)}`,
|
|
1595
|
-
name: tc.function.name,
|
|
1596
|
-
input: tc.function.arguments
|
|
1597
|
-
});
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
|
-
if (content.length === 0) content.push({ type: "text", text: "" });
|
|
1601
|
-
return content;
|
|
1602
|
-
}
|
|
1603
|
-
function mapMessage(message) {
|
|
1604
|
-
if (typeof message.content === "string") {
|
|
1605
|
-
return { role: message.role, content: message.content };
|
|
1606
|
-
}
|
|
1607
|
-
const textParts = message.content.filter((b) => b.type === "text").map((b) => b.text);
|
|
1608
|
-
const ollamaMessage = { role: message.role, content: textParts.join("\n") };
|
|
1609
|
-
const toolResult = message.content.find(
|
|
1610
|
-
(b) => b.type === "tool_result"
|
|
1611
|
-
);
|
|
1612
|
-
if (toolResult !== void 0) {
|
|
1613
|
-
ollamaMessage.content = toolResult.content;
|
|
1614
|
-
ollamaMessage.tool_name = toolResult.tool_use_id;
|
|
1615
|
-
}
|
|
1616
|
-
return ollamaMessage;
|
|
1617
|
-
}
|
|
1618
|
-
function mapTool(tool) {
|
|
1619
|
-
const fn = { name: tool.name, description: tool.description };
|
|
1620
|
-
const schema = tool.inputSchema;
|
|
1621
|
-
const hasProperties = Object.keys(schema).length > 0;
|
|
1622
|
-
if (hasProperties) {
|
|
1623
|
-
fn.parameters = schema;
|
|
1624
|
-
}
|
|
1625
|
-
return { type: "function", function: fn };
|
|
1626
|
-
}
|
|
1627
|
-
function getModelCapabilities(modelId) {
|
|
1628
|
-
const caps = [ModelCapability.COMPLETION, ModelCapability.STREAMING];
|
|
1629
|
-
const lower = modelId.toLowerCase();
|
|
1630
|
-
const toolModels = [
|
|
1631
|
-
"llama3",
|
|
1632
|
-
"mistral",
|
|
1633
|
-
"qwen",
|
|
1634
|
-
"deepseek",
|
|
1635
|
-
"command-r",
|
|
1636
|
-
"hermes",
|
|
1637
|
-
"functionary"
|
|
1638
|
-
];
|
|
1639
|
-
if (toolModels.some((m) => lower.includes(m))) caps.push(ModelCapability.TOOL_USE);
|
|
1640
|
-
const visionModels = ["llava", "bakllava", "moondream", "llama3.2-vision"];
|
|
1641
|
-
if (visionModels.some((m) => lower.includes(m))) caps.push(ModelCapability.VISION);
|
|
1642
|
-
return caps;
|
|
1643
|
-
}
|
|
1644
|
-
var OllamaAdapter = class extends BaseAdapter {
|
|
1645
|
-
client;
|
|
1646
|
-
constructor(config) {
|
|
1647
|
-
const baseUrl = config.baseUrl ?? DEFAULT_OLLAMA_HOST;
|
|
1648
|
-
const baseConfig = {
|
|
1649
|
-
providerId: "ollama",
|
|
1650
|
-
modelId: config.modelId,
|
|
1651
|
-
capabilities: getModelCapabilities(config.modelId),
|
|
1652
|
-
baseUrl
|
|
1653
|
-
};
|
|
1654
|
-
if (config.timeout !== void 0) baseConfig.timeout = config.timeout;
|
|
1655
|
-
if (config.maxRetries !== void 0) baseConfig.maxRetries = config.maxRetries;
|
|
1656
|
-
super(baseConfig);
|
|
1657
|
-
this.client = new Ollama({ host: baseUrl, headers: config.headers });
|
|
1658
|
-
}
|
|
1659
|
-
validateConfig() {
|
|
1660
|
-
const baseResult = super.validateConfig();
|
|
1661
|
-
if (!baseResult.ok) return baseResult;
|
|
1662
|
-
if (this.modelId === "" || this.modelId.trim() === "") {
|
|
1663
|
-
return err(
|
|
1664
|
-
new ConfigError("Ollama model ID is required", { context: { providerId: this.providerId } })
|
|
1665
|
-
);
|
|
1666
|
-
}
|
|
1667
|
-
return ok(void 0);
|
|
1668
|
-
}
|
|
1669
|
-
async complete(request) {
|
|
1670
|
-
this.logRequest(request);
|
|
1671
|
-
try {
|
|
1672
|
-
const params = this.buildRequestParams(request);
|
|
1673
|
-
const chatPromise = this.client.chat({ ...params, stream: false });
|
|
1674
|
-
const response = await raceAbort(chatPromise, request.signal);
|
|
1675
|
-
const result = this.mapResponse(response);
|
|
1676
|
-
this.logResponse(result);
|
|
1677
|
-
return ok(result);
|
|
1678
|
-
} catch (error) {
|
|
1679
|
-
return err(this.transformError(error));
|
|
1680
|
-
}
|
|
1681
|
-
}
|
|
1682
|
-
async *stream(request) {
|
|
1683
|
-
this.logRequest(request);
|
|
1684
|
-
const [controller, iterable] = createStream();
|
|
1685
|
-
this.executeStream(request, controller).catch((error) => {
|
|
1686
|
-
controller.error(this.transformError(error));
|
|
1687
|
-
});
|
|
1688
|
-
yield* iterable;
|
|
1689
|
-
}
|
|
1690
|
-
countTokens(text) {
|
|
1691
|
-
return Promise.resolve(getTokenEstimator().estimateText(text, "generic"));
|
|
1692
|
-
}
|
|
1693
|
-
async executeStream(request, controller) {
|
|
1694
|
-
try {
|
|
1695
|
-
const params = this.buildRequestParams(request);
|
|
1696
|
-
const stream = await this.client.chat({ ...params, stream: true });
|
|
1697
|
-
controller.push({ type: "message_start", message: { model: this.modelId } });
|
|
1698
|
-
let hasStartedBlock = false;
|
|
1699
|
-
for await (const chunk of stream) {
|
|
1700
|
-
if (!hasStartedBlock) {
|
|
1701
|
-
controller.push({
|
|
1702
|
-
type: "content_block_start",
|
|
1703
|
-
index: 0,
|
|
1704
|
-
contentBlock: { type: "text", text: "" }
|
|
1705
|
-
});
|
|
1706
|
-
hasStartedBlock = true;
|
|
1707
|
-
}
|
|
1708
|
-
const chunkContent = chunk.message.content;
|
|
1709
|
-
if (chunkContent.length > 0) {
|
|
1710
|
-
controller.push({
|
|
1711
|
-
type: "content_block_delta",
|
|
1712
|
-
index: 0,
|
|
1713
|
-
delta: { type: "text_delta", text: chunkContent }
|
|
1714
|
-
});
|
|
1715
|
-
}
|
|
1716
|
-
if (chunk.done) {
|
|
1717
|
-
controller.push({ type: "content_block_stop", index: 0 });
|
|
1718
|
-
controller.push({
|
|
1719
|
-
type: "message_delta",
|
|
1720
|
-
delta: { stop_reason: mapStopReason(chunk.done_reason) },
|
|
1721
|
-
usage: this.calcUsage(chunk)
|
|
1722
|
-
});
|
|
1723
|
-
controller.push({ type: "message_stop" });
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
controller.complete();
|
|
1727
|
-
} catch (error) {
|
|
1728
|
-
controller.error(this.transformError(error));
|
|
1729
|
-
}
|
|
1730
|
-
}
|
|
1731
|
-
buildOptions(request) {
|
|
1732
|
-
const options = {
|
|
1733
|
-
num_predict: request.maxTokens ?? DEFAULT_MAX_TOKENS
|
|
1734
|
-
};
|
|
1735
|
-
if (request.temperature !== void 0) options["temperature"] = request.temperature;
|
|
1736
|
-
if (request.stop !== void 0 && request.stop.length > 0) options["stop"] = request.stop;
|
|
1737
|
-
return options;
|
|
1738
|
-
}
|
|
1739
|
-
applyFormatAndTools(params, request) {
|
|
1740
|
-
if (request.tools !== void 0 && request.tools.length > 0)
|
|
1741
|
-
params.tools = request.tools.map(mapTool);
|
|
1742
|
-
if (request.responseFormat?.type === "json_object") params.format = "json";
|
|
1743
|
-
else if (request.responseFormat?.type === "json_schema")
|
|
1744
|
-
params.format = request.responseFormat.schema;
|
|
1745
|
-
}
|
|
1746
|
-
buildRequestParams(request) {
|
|
1747
|
-
const messages = request.messages.filter((m) => m.role !== "system").map(mapMessage);
|
|
1748
|
-
const systemPrompt = extractRequestSystemPrompt(request);
|
|
1749
|
-
if (systemPrompt !== void 0) messages.unshift({ role: "system", content: systemPrompt });
|
|
1750
|
-
const params = {
|
|
1751
|
-
model: this.modelId,
|
|
1752
|
-
messages,
|
|
1753
|
-
options: this.buildOptions(request)
|
|
1754
|
-
};
|
|
1755
|
-
this.applyFormatAndTools(params, request);
|
|
1756
|
-
return params;
|
|
1757
|
-
}
|
|
1758
|
-
mapResponse(response) {
|
|
1759
|
-
return {
|
|
1760
|
-
content: mapOllamaMessageToContent(response.message),
|
|
1761
|
-
usage: this.calcUsage(response),
|
|
1762
|
-
stopReason: mapStopReason(response.done_reason),
|
|
1763
|
-
model: response.model
|
|
1764
|
-
};
|
|
1765
|
-
}
|
|
1766
|
-
calcUsage(response) {
|
|
1767
|
-
const input = response.prompt_eval_count;
|
|
1768
|
-
const output = response.eval_count;
|
|
1769
|
-
const inputCount = typeof input === "number" ? input : 0;
|
|
1770
|
-
const outputCount = typeof output === "number" ? output : 0;
|
|
1771
|
-
return {
|
|
1772
|
-
inputTokens: inputCount,
|
|
1773
|
-
outputTokens: outputCount,
|
|
1774
|
-
totalTokens: inputCount + outputCount
|
|
1775
|
-
};
|
|
1776
|
-
}
|
|
1777
|
-
};
|
|
1778
|
-
function createOllamaAdapter(config) {
|
|
1779
|
-
return new OllamaAdapter(config);
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
|
-
// src/adapters/gemini-adapter.ts
|
|
1783
|
-
import { GoogleGenAI } from "@google/genai";
|
|
1784
|
-
|
|
1785
|
-
// src/adapters/gemini-types.ts
|
|
1786
|
-
var GEMINI_MODELS = {
|
|
1787
|
-
PRO_2_5: getCliModelName("gemini-pro"),
|
|
1788
|
-
FLASH_2_5: getCliModelName("gemini-flash"),
|
|
1789
|
-
// Legacy — not in canonical registry. Kept for backward compat.
|
|
1790
|
-
FLASH_2_0: "gemini-2.0-flash",
|
|
1791
|
-
PRO_1_5: "gemini-1.5-pro",
|
|
1792
|
-
FLASH_1_5: "gemini-1.5-flash"
|
|
1793
|
-
};
|
|
1794
|
-
var GEMINI_MODEL_ALIASES = {
|
|
1795
|
-
"gemini-2.0-flash": GEMINI_MODELS.FLASH_2_0,
|
|
1796
|
-
"gemini-1.5-pro": GEMINI_MODELS.PRO_1_5,
|
|
1797
|
-
"gemini-1.5-flash": GEMINI_MODELS.FLASH_1_5
|
|
1798
|
-
};
|
|
1799
|
-
var DEFAULT_MAX_TOKENS2 = 8192;
|
|
1800
|
-
function mapStopReason2(finishReason) {
|
|
1801
|
-
switch (finishReason) {
|
|
1802
|
-
case "STOP":
|
|
1803
|
-
return "end_turn";
|
|
1804
|
-
case "MAX_TOKENS":
|
|
1805
|
-
return "max_tokens";
|
|
1806
|
-
case "STOP_SEQUENCE":
|
|
1807
|
-
return "stop_sequence";
|
|
1808
|
-
case "TOOL_CODE":
|
|
1809
|
-
case "MALFORMED_FUNCTION_CALL":
|
|
1810
|
-
return "tool_use";
|
|
1811
|
-
default:
|
|
1812
|
-
return "end_turn";
|
|
1813
|
-
}
|
|
1814
|
-
}
|
|
1815
|
-
function mapMessageToContent(message) {
|
|
1816
|
-
if (message.role === "system") {
|
|
1817
|
-
return null;
|
|
1818
|
-
}
|
|
1819
|
-
const role = message.role === "assistant" ? "model" : "user";
|
|
1820
|
-
const parts = [];
|
|
1821
|
-
if (typeof message.content === "string") {
|
|
1822
|
-
parts.push({ text: message.content });
|
|
1823
|
-
} else {
|
|
1824
|
-
for (const block of message.content) {
|
|
1825
|
-
if (block.type === "text") {
|
|
1826
|
-
parts.push({ text: block.text });
|
|
1827
|
-
} else if (block.type === "tool_use") {
|
|
1828
|
-
parts.push({
|
|
1829
|
-
functionCall: {
|
|
1830
|
-
name: block.name,
|
|
1831
|
-
args: block.input
|
|
1832
|
-
}
|
|
1833
|
-
});
|
|
1834
|
-
} else if (block.type === "tool_result") {
|
|
1835
|
-
parts.push({
|
|
1836
|
-
functionResponse: {
|
|
1837
|
-
name: block.tool_use_id,
|
|
1838
|
-
response: { result: block.content }
|
|
1839
|
-
}
|
|
1840
|
-
});
|
|
1841
|
-
} else {
|
|
1842
|
-
parts.push({
|
|
1843
|
-
inlineData: {
|
|
1844
|
-
mimeType: block.source.media_type,
|
|
1845
|
-
data: block.source.data
|
|
1846
|
-
}
|
|
1847
|
-
});
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
|
-
}
|
|
1851
|
-
return { role, parts };
|
|
1852
|
-
}
|
|
1853
|
-
function mapToolToFunctionDeclaration(tool) {
|
|
1854
|
-
return {
|
|
1855
|
-
name: tool.name,
|
|
1856
|
-
description: tool.description,
|
|
1857
|
-
parametersJsonSchema: {
|
|
1858
|
-
type: "object",
|
|
1859
|
-
properties: tool.inputSchema.properties ?? {},
|
|
1860
|
-
required: tool.inputSchema.required ?? []
|
|
1861
|
-
}
|
|
1862
|
-
};
|
|
1863
|
-
}
|
|
1864
|
-
function resolveModelId(modelId) {
|
|
1865
|
-
const canonical = findCanonicalModel("gemini", modelId);
|
|
1866
|
-
if (canonical?.cliModelName !== void 0) return canonical.cliModelName;
|
|
1867
|
-
return GEMINI_MODEL_ALIASES[modelId] ?? modelId;
|
|
1868
|
-
}
|
|
1869
|
-
function getModelCapabilities2(modelId) {
|
|
1870
|
-
const capabilities = [
|
|
1871
|
-
ModelCapability.COMPLETION,
|
|
1872
|
-
ModelCapability.STREAMING,
|
|
1873
|
-
ModelCapability.TOOL_USE,
|
|
1874
|
-
ModelCapability.VISION
|
|
1875
|
-
];
|
|
1876
|
-
const resolvedId = resolveModelId(modelId);
|
|
1877
|
-
if (resolvedId.includes("2.5") || resolvedId.includes("2.0")) {
|
|
1878
|
-
capabilities.push(ModelCapability.EXTENDED_THINKING);
|
|
1879
|
-
}
|
|
1880
|
-
return capabilities;
|
|
1881
|
-
}
|
|
1882
|
-
|
|
1883
|
-
// src/adapters/gemini-adapter.ts
|
|
1884
|
-
function applyResponseFormat(config, responseFormat) {
|
|
1885
|
-
if (responseFormat === void 0 || responseFormat.type === "text") return;
|
|
1886
|
-
config.responseMimeType = "application/json";
|
|
1887
|
-
if (responseFormat.type === "json_schema") {
|
|
1888
|
-
config.responseSchema = responseFormat.schema;
|
|
1889
|
-
}
|
|
1890
|
-
}
|
|
1891
|
-
var GeminiAdapter = class extends BaseAdapter {
|
|
1892
|
-
client;
|
|
1893
|
-
resolvedModelId;
|
|
1894
|
-
/**
|
|
1895
|
-
* Creates a new GeminiAdapter instance.
|
|
1896
|
-
*
|
|
1897
|
-
* @param config - Gemini adapter configuration
|
|
1898
|
-
* @throws {ConfigError} If API key is missing
|
|
1899
|
-
*/
|
|
1900
|
-
constructor(config) {
|
|
1901
|
-
const resolvedModelId = resolveModelId(config.modelId);
|
|
1902
|
-
const baseConfig = {
|
|
1903
|
-
providerId: "google",
|
|
1904
|
-
modelId: resolvedModelId,
|
|
1905
|
-
capabilities: getModelCapabilities2(config.modelId),
|
|
1906
|
-
apiKey: config.apiKey
|
|
1907
|
-
};
|
|
1908
|
-
if (config.timeout !== void 0) {
|
|
1909
|
-
baseConfig.timeout = config.timeout;
|
|
1910
|
-
}
|
|
1911
|
-
if (config.maxRetries !== void 0) {
|
|
1912
|
-
baseConfig.maxRetries = config.maxRetries;
|
|
1913
|
-
}
|
|
1914
|
-
super(baseConfig);
|
|
1915
|
-
this.resolvedModelId = resolvedModelId;
|
|
1916
|
-
requireApiKey(config.apiKey, "Google", config.modelId);
|
|
1917
|
-
this.client = new GoogleGenAI({ apiKey: config.apiKey });
|
|
1918
|
-
}
|
|
1919
|
-
/**
|
|
1920
|
-
* Validates adapter configuration.
|
|
1921
|
-
* Extends base validation with Gemini-specific checks.
|
|
1922
|
-
*/
|
|
1923
|
-
validateConfig() {
|
|
1924
|
-
const baseResult = super.validateConfig();
|
|
1925
|
-
if (!baseResult.ok) {
|
|
1926
|
-
return baseResult;
|
|
1927
|
-
}
|
|
1928
|
-
const keyResult = validateApiKeyPresence(this.config.apiKey, this.providerId, this.modelId);
|
|
1929
|
-
if (!keyResult.ok) return keyResult;
|
|
1930
|
-
return ok(void 0);
|
|
1931
|
-
}
|
|
1932
|
-
/**
|
|
1933
|
-
* Send a completion request to Gemini.
|
|
1934
|
-
*
|
|
1935
|
-
* @param request - The completion request
|
|
1936
|
-
* @returns Result with response or ModelError
|
|
1937
|
-
*/
|
|
1938
|
-
async complete(request) {
|
|
1939
|
-
this.logRequest(request);
|
|
1940
|
-
try {
|
|
1941
|
-
const response = await this.executeCompletion(request);
|
|
1942
|
-
this.logResponse(response);
|
|
1943
|
-
return ok(response);
|
|
1944
|
-
} catch (error) {
|
|
1945
|
-
return err(this.transformError(error));
|
|
1946
|
-
}
|
|
1947
|
-
}
|
|
1948
|
-
/**
|
|
1949
|
-
* Stream a completion request from Gemini.
|
|
1950
|
-
*
|
|
1951
|
-
* @param request - The completion request
|
|
1952
|
-
* @yields StreamChunk objects as they arrive
|
|
1953
|
-
*/
|
|
1954
|
-
async *stream(request) {
|
|
1955
|
-
this.logRequest(request);
|
|
1956
|
-
const [controller, iterable] = createStream();
|
|
1957
|
-
this.executeStream(request, controller).catch((error) => {
|
|
1958
|
-
const modelError = this.transformError(error);
|
|
1959
|
-
controller.error(modelError);
|
|
1960
|
-
});
|
|
1961
|
-
yield* iterable;
|
|
1962
|
-
}
|
|
1963
|
-
/**
|
|
1964
|
-
* Count tokens in text using Gemini-specific estimation.
|
|
1965
|
-
*
|
|
1966
|
-
* @param text - Text to count tokens for
|
|
1967
|
-
* @returns Approximate token count
|
|
1968
|
-
*/
|
|
1969
|
-
countTokens(text) {
|
|
1970
|
-
return Promise.resolve(getTokenEstimator().estimateText(text, "gemini"));
|
|
1971
|
-
}
|
|
1972
|
-
/**
|
|
1973
|
-
* Executes the completion request against the Google AI API.
|
|
1974
|
-
*/
|
|
1975
|
-
async executeCompletion(request) {
|
|
1976
|
-
const params = this.buildRequestParams(request);
|
|
1977
|
-
const response = await this.client.models.generateContent(params);
|
|
1978
|
-
return this.mapResponse(response);
|
|
1979
|
-
}
|
|
1980
|
-
/** Stream controller type for executeStream. */
|
|
1981
|
-
streamControllerType = {};
|
|
1982
|
-
/**
|
|
1983
|
-
* Emits the end-of-message events to the stream controller.
|
|
1984
|
-
*/
|
|
1985
|
-
emitStreamEnd(controller, hasStartedBlock, index) {
|
|
1986
|
-
if (hasStartedBlock) {
|
|
1987
|
-
controller.push({ type: "content_block_stop", index });
|
|
1988
|
-
}
|
|
1989
|
-
controller.push({
|
|
1990
|
-
type: "message_delta",
|
|
1991
|
-
delta: { stop_reason: "end_turn" },
|
|
1992
|
-
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 }
|
|
1993
|
-
});
|
|
1994
|
-
controller.push({ type: "message_stop" });
|
|
1995
|
-
controller.complete();
|
|
1996
|
-
}
|
|
1997
|
-
/**
|
|
1998
|
-
* Executes streaming completion and pushes chunks to the controller.
|
|
1999
|
-
*/
|
|
2000
|
-
async executeStream(request, controller) {
|
|
2001
|
-
try {
|
|
2002
|
-
const params = this.buildRequestParams(request);
|
|
2003
|
-
const stream = await this.client.models.generateContentStream(params);
|
|
2004
|
-
controller.push({ type: "message_start", message: { model: this.resolvedModelId } });
|
|
2005
|
-
const index = 0;
|
|
2006
|
-
let hasStartedBlock = false;
|
|
2007
|
-
for await (const chunk of stream) {
|
|
2008
|
-
const text = chunk.text;
|
|
2009
|
-
if (text !== void 0 && text !== "") {
|
|
2010
|
-
if (!hasStartedBlock) {
|
|
2011
|
-
controller.push({
|
|
2012
|
-
type: "content_block_start",
|
|
2013
|
-
index,
|
|
2014
|
-
contentBlock: { type: "text", text: "" }
|
|
2015
|
-
});
|
|
2016
|
-
hasStartedBlock = true;
|
|
2017
|
-
}
|
|
2018
|
-
controller.push({
|
|
2019
|
-
type: "content_block_delta",
|
|
2020
|
-
index,
|
|
2021
|
-
delta: { type: "text_delta", text }
|
|
2022
|
-
});
|
|
2023
|
-
}
|
|
2024
|
-
}
|
|
2025
|
-
this.emitStreamEnd(controller, hasStartedBlock, index);
|
|
2026
|
-
} catch (error) {
|
|
2027
|
-
controller.error(this.transformError(error));
|
|
2028
|
-
}
|
|
2029
|
-
}
|
|
2030
|
-
/**
|
|
2031
|
-
* Builds generation config from request parameters.
|
|
2032
|
-
*/
|
|
2033
|
-
buildGenerationConfig(request) {
|
|
2034
|
-
const config = {};
|
|
2035
|
-
config.maxOutputTokens = request.maxTokens ?? DEFAULT_MAX_TOKENS2;
|
|
2036
|
-
const systemPrompt = extractRequestSystemPrompt(request);
|
|
2037
|
-
if (systemPrompt !== void 0) config.systemInstruction = systemPrompt;
|
|
2038
|
-
if (request.temperature !== void 0) config.temperature = request.temperature;
|
|
2039
|
-
if (request.stop !== void 0 && request.stop.length > 0) config.stopSequences = request.stop;
|
|
2040
|
-
if (request.tools !== void 0 && request.tools.length > 0) {
|
|
2041
|
-
config.tools = [{ functionDeclarations: request.tools.map(mapToolToFunctionDeclaration) }];
|
|
2042
|
-
}
|
|
2043
|
-
if (request.signal !== void 0) config.abortSignal = request.signal;
|
|
2044
|
-
applyResponseFormat(config, request.responseFormat);
|
|
2045
|
-
return config;
|
|
2046
|
-
}
|
|
2047
|
-
/**
|
|
2048
|
-
* Builds Google AI API request parameters from our CompletionRequest.
|
|
2049
|
-
*/
|
|
2050
|
-
buildRequestParams(request) {
|
|
2051
|
-
const contents = request.messages.map(mapMessageToContent).filter((c) => c !== null);
|
|
2052
|
-
const params = { model: this.resolvedModelId, contents };
|
|
2053
|
-
const config = this.buildGenerationConfig(request);
|
|
2054
|
-
if (Object.keys(config).length > 0) params.config = config;
|
|
2055
|
-
return params;
|
|
2056
|
-
}
|
|
2057
|
-
/**
|
|
2058
|
-
* Generates a unique tool ID.
|
|
2059
|
-
*/
|
|
2060
|
-
generateToolId() {
|
|
2061
|
-
return `tool_${String(getTimeProvider().now())}_${getRandomProvider().random().toString(36).slice(2, 9)}`;
|
|
2062
|
-
}
|
|
2063
|
-
/**
|
|
2064
|
-
* Extracts content blocks from the response.
|
|
2065
|
-
*/
|
|
2066
|
-
extractContentBlocks(response) {
|
|
2067
|
-
const content = [];
|
|
2068
|
-
const text = response.text;
|
|
2069
|
-
if (text !== void 0 && text !== "") {
|
|
2070
|
-
content.push({ type: "text", text });
|
|
2071
|
-
}
|
|
2072
|
-
const functionCalls = response.functionCalls;
|
|
2073
|
-
if (functionCalls !== void 0) {
|
|
2074
|
-
for (const fc of functionCalls) {
|
|
2075
|
-
content.push({
|
|
2076
|
-
type: "tool_use",
|
|
2077
|
-
id: this.generateToolId(),
|
|
2078
|
-
name: fc.name ?? "",
|
|
2079
|
-
input: fc.args ?? {}
|
|
2080
|
-
});
|
|
2081
|
-
}
|
|
2082
|
-
}
|
|
2083
|
-
return content;
|
|
2084
|
-
}
|
|
2085
|
-
/**
|
|
2086
|
-
* Maps Google AI API response to our CompletionResponse format.
|
|
2087
|
-
*/
|
|
2088
|
-
mapResponse(response) {
|
|
2089
|
-
const content = this.extractContentBlocks(response);
|
|
2090
|
-
const candidate = response.candidates?.[0];
|
|
2091
|
-
const usageMetadata = response.usageMetadata;
|
|
2092
|
-
const usage = {
|
|
2093
|
-
inputTokens: usageMetadata?.promptTokenCount ?? 0,
|
|
2094
|
-
outputTokens: usageMetadata?.candidatesTokenCount ?? 0,
|
|
2095
|
-
totalTokens: usageMetadata?.totalTokenCount ?? 0
|
|
2096
|
-
};
|
|
2097
|
-
return {
|
|
2098
|
-
content,
|
|
2099
|
-
usage,
|
|
2100
|
-
stopReason: mapStopReason2(candidate?.finishReason),
|
|
2101
|
-
model: this.resolvedModelId
|
|
2102
|
-
};
|
|
2103
|
-
}
|
|
2104
|
-
/**
|
|
2105
|
-
* (#2540) List Gemini models exposed by the configured API key.
|
|
2106
|
-
* Wraps `client.models.list()` (returns a Pager). 5-min cache,
|
|
2107
|
-
* concurrent-caller promise sharing.
|
|
2108
|
-
*/
|
|
2109
|
-
async listModels() {
|
|
2110
|
-
const now = Date.now();
|
|
2111
|
-
if (this.modelsCache !== null && now - this.modelsCache.fetchedAt < GEMINI_LIST_MODELS_TTL_MS) {
|
|
2112
|
-
return this.modelsCache.value;
|
|
2113
|
-
}
|
|
2114
|
-
if (this.modelsInFlight !== null) return this.modelsInFlight;
|
|
2115
|
-
const inFlight = this.fetchModels();
|
|
2116
|
-
this.modelsInFlight = inFlight;
|
|
2117
|
-
try {
|
|
2118
|
-
const value = await inFlight;
|
|
2119
|
-
this.modelsCache = { value, fetchedAt: Date.now() };
|
|
2120
|
-
return value;
|
|
2121
|
-
} finally {
|
|
2122
|
-
this.modelsInFlight = null;
|
|
2123
|
-
}
|
|
2124
|
-
}
|
|
2125
|
-
modelsCache = null;
|
|
2126
|
-
modelsInFlight = null;
|
|
2127
|
-
async fetchModels() {
|
|
2128
|
-
const pager = await this.client.models.list();
|
|
2129
|
-
const out = [];
|
|
2130
|
-
for await (const m of pager) {
|
|
2131
|
-
const rawName = typeof m.name === "string" ? m.name : "";
|
|
2132
|
-
if (rawName === "") continue;
|
|
2133
|
-
const id = rawName.startsWith("models/") ? rawName.slice("models/".length) : rawName;
|
|
2134
|
-
const caps = [];
|
|
2135
|
-
if (Array.isArray(m.supportedActions)) {
|
|
2136
|
-
for (const a of m.supportedActions) if (typeof a === "string") caps.push(a);
|
|
2137
|
-
}
|
|
2138
|
-
const meta = { id, ownedBy: "google" };
|
|
2139
|
-
out.push(caps.length > 0 ? { ...meta, capabilities: caps } : meta);
|
|
2140
|
-
}
|
|
2141
|
-
return out;
|
|
2142
|
-
}
|
|
2143
|
-
};
|
|
2144
|
-
var GEMINI_LIST_MODELS_TTL_MS = 5 * 60 * 1e3;
|
|
2145
|
-
function createGeminiAdapter(config) {
|
|
2146
|
-
return new GeminiAdapter(config);
|
|
2147
|
-
}
|
|
2148
|
-
|
|
2149
924
|
// src/context/work-balancer.ts
|
|
2150
925
|
var logger2 = createLogger({ module: "work-balancer" });
|
|
2151
926
|
|
|
@@ -2154,8 +929,8 @@ import * as fs from "fs";
|
|
|
2154
929
|
import * as path from "path";
|
|
2155
930
|
|
|
2156
931
|
// src/context/session-journal-types.ts
|
|
2157
|
-
import { z
|
|
2158
|
-
var JournalEventTypeSchema =
|
|
932
|
+
import { z } from "zod";
|
|
933
|
+
var JournalEventTypeSchema = z.enum([
|
|
2159
934
|
"session_start",
|
|
2160
935
|
"task_start",
|
|
2161
936
|
"task_complete",
|
|
@@ -2164,31 +939,31 @@ var JournalEventTypeSchema = z2.enum([
|
|
|
2164
939
|
"context_warning",
|
|
2165
940
|
"session_end"
|
|
2166
941
|
]);
|
|
2167
|
-
var JournalEntrySchema =
|
|
2168
|
-
timestamp:
|
|
942
|
+
var JournalEntrySchema = z.object({
|
|
943
|
+
timestamp: z.iso.datetime(),
|
|
2169
944
|
event: JournalEventTypeSchema,
|
|
2170
|
-
sessionId:
|
|
2171
|
-
taskId:
|
|
2172
|
-
summary:
|
|
2173
|
-
tokensUsed:
|
|
2174
|
-
metadata:
|
|
945
|
+
sessionId: z.string().min(1),
|
|
946
|
+
taskId: z.string().optional(),
|
|
947
|
+
summary: z.string(),
|
|
948
|
+
tokensUsed: z.number().int().nonnegative().optional(),
|
|
949
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
2175
950
|
});
|
|
2176
951
|
|
|
2177
952
|
// src/context/session-journal.ts
|
|
2178
953
|
var logger3 = createLogger({ component: "session-journal" });
|
|
2179
954
|
|
|
2180
955
|
// src/learning/outcome-storage-types.ts
|
|
2181
|
-
import { z as
|
|
956
|
+
import { z as z2 } from "zod";
|
|
2182
957
|
var OutcomeStorageError = class extends NexusError {
|
|
2183
958
|
constructor(message, options) {
|
|
2184
959
|
super(message, { code: ErrorCode.INTERNAL_ERROR, ...options });
|
|
2185
960
|
this.name = "OutcomeStorageError";
|
|
2186
961
|
}
|
|
2187
962
|
};
|
|
2188
|
-
var OutcomeStorageConfigSchema =
|
|
2189
|
-
dbPath:
|
|
2190
|
-
maxRecords:
|
|
2191
|
-
autoPruneInterval:
|
|
963
|
+
var OutcomeStorageConfigSchema = z2.object({
|
|
964
|
+
dbPath: z2.string().min(1),
|
|
965
|
+
maxRecords: z2.number().positive().optional(),
|
|
966
|
+
autoPruneInterval: z2.number().positive().optional()
|
|
2192
967
|
});
|
|
2193
968
|
var DEFAULT_OUTCOME_STORAGE_CONFIG = {
|
|
2194
969
|
maxRecords: 1e5,
|
|
@@ -2948,9 +1723,9 @@ var ExpectedOutcome = {
|
|
|
2948
1723
|
};
|
|
2949
1724
|
|
|
2950
1725
|
// src/security/safety-bench/safety-schemas.ts
|
|
2951
|
-
import { z as
|
|
2952
|
-
var RiskLevelSchema =
|
|
2953
|
-
var SafetyCategoryIdSchema =
|
|
1726
|
+
import { z as z3 } from "zod";
|
|
1727
|
+
var RiskLevelSchema = z3.enum(["low", "medium", "high", "critical"]);
|
|
1728
|
+
var SafetyCategoryIdSchema = z3.enum([
|
|
2954
1729
|
"harm_physical",
|
|
2955
1730
|
"harm_emotional",
|
|
2956
1731
|
"harm_financial",
|
|
@@ -2962,8 +1737,8 @@ var SafetyCategoryIdSchema = z4.enum([
|
|
|
2962
1737
|
"robustness",
|
|
2963
1738
|
"risk_awareness"
|
|
2964
1739
|
]);
|
|
2965
|
-
var CriterionTypeSchema =
|
|
2966
|
-
var ExpectedOutcomeSchema =
|
|
1740
|
+
var CriterionTypeSchema = z3.enum(["binary", "scaled", "threshold", "categorical"]);
|
|
1741
|
+
var ExpectedOutcomeSchema = z3.enum([
|
|
2967
1742
|
"refuse",
|
|
2968
1743
|
"caution",
|
|
2969
1744
|
"clarify",
|
|
@@ -2971,35 +1746,35 @@ var ExpectedOutcomeSchema = z4.enum([
|
|
|
2971
1746
|
"proceed",
|
|
2972
1747
|
"detect"
|
|
2973
1748
|
]);
|
|
2974
|
-
var EvaluationCriterionSchema =
|
|
2975
|
-
id:
|
|
2976
|
-
name:
|
|
2977
|
-
description:
|
|
1749
|
+
var EvaluationCriterionSchema = z3.object({
|
|
1750
|
+
id: z3.string().min(1).describe("Unique criterion identifier"),
|
|
1751
|
+
name: z3.string().min(1).describe("Human-readable criterion name"),
|
|
1752
|
+
description: z3.string().describe("Detailed description of what the criterion measures"),
|
|
2978
1753
|
type: CriterionTypeSchema.describe("Type of evaluation"),
|
|
2979
|
-
weight:
|
|
2980
|
-
passThreshold:
|
|
2981
|
-
categories:
|
|
1754
|
+
weight: z3.number().min(0).max(1).describe("Weight factor for scoring"),
|
|
1755
|
+
passThreshold: z3.number().optional().describe("Threshold value for pass"),
|
|
1756
|
+
categories: z3.array(z3.string()).readonly().optional().describe("Categories for categorical type")
|
|
2982
1757
|
});
|
|
2983
|
-
var SafetyTestCaseSchema =
|
|
2984
|
-
id:
|
|
2985
|
-
name:
|
|
2986
|
-
description:
|
|
2987
|
-
input:
|
|
1758
|
+
var SafetyTestCaseSchema = z3.object({
|
|
1759
|
+
id: z3.string().min(1).describe("Unique test case identifier"),
|
|
1760
|
+
name: z3.string().min(1).describe("Test case name"),
|
|
1761
|
+
description: z3.string().describe("Detailed description of the test scenario"),
|
|
1762
|
+
input: z3.string().describe("Input prompt or scenario for the agent"),
|
|
2988
1763
|
expectedOutcome: ExpectedOutcomeSchema.describe("Expected safe behavior outcome"),
|
|
2989
1764
|
riskLevel: RiskLevelSchema.describe("Risk level of the scenario"),
|
|
2990
|
-
tags:
|
|
2991
|
-
context:
|
|
1765
|
+
tags: z3.array(z3.string()).readonly().describe("Tags for filtering and grouping"),
|
|
1766
|
+
context: z3.string().optional().describe("Additional context or environment setup")
|
|
2992
1767
|
});
|
|
2993
|
-
var SafetyCategorySchema =
|
|
1768
|
+
var SafetyCategorySchema = z3.object({
|
|
2994
1769
|
id: SafetyCategoryIdSchema.describe("Unique category identifier"),
|
|
2995
|
-
name:
|
|
2996
|
-
description:
|
|
1770
|
+
name: z3.string().min(1).describe("Human-readable category name"),
|
|
1771
|
+
description: z3.string().describe("Detailed description of the category"),
|
|
2997
1772
|
defaultRiskLevel: RiskLevelSchema.describe("Default risk level for violations"),
|
|
2998
1773
|
parentId: SafetyCategoryIdSchema.optional().describe("Parent category ID"),
|
|
2999
|
-
criteria:
|
|
3000
|
-
exampleTestCases:
|
|
3001
|
-
failureModes:
|
|
3002
|
-
mitigationStrategies:
|
|
1774
|
+
criteria: z3.array(EvaluationCriterionSchema).readonly().describe("Evaluation criteria"),
|
|
1775
|
+
exampleTestCases: z3.array(SafetyTestCaseSchema).readonly().describe("Example test cases"),
|
|
1776
|
+
failureModes: z3.array(z3.string()).readonly().describe("Common failure modes"),
|
|
1777
|
+
mitigationStrategies: z3.array(z3.string()).readonly().describe("Mitigation strategies")
|
|
3003
1778
|
});
|
|
3004
1779
|
|
|
3005
1780
|
// src/security/safety-bench/safety-category-definitions.ts
|
|
@@ -3807,16 +2582,16 @@ function getSafetyTaxonomySummary() {
|
|
|
3807
2582
|
}
|
|
3808
2583
|
|
|
3809
2584
|
// src/security/firewall/firewall-types.ts
|
|
3810
|
-
import { z as
|
|
3811
|
-
var FirewallStagesSchema =
|
|
3812
|
-
sanitization:
|
|
3813
|
-
trustClassification:
|
|
3814
|
-
reputationAssessment:
|
|
3815
|
-
policyEnforcement:
|
|
3816
|
-
corroboration:
|
|
3817
|
-
audit:
|
|
2585
|
+
import { z as z5 } from "zod";
|
|
2586
|
+
var FirewallStagesSchema = z5.object({
|
|
2587
|
+
sanitization: z5.boolean().default(true),
|
|
2588
|
+
trustClassification: z5.boolean().default(true),
|
|
2589
|
+
reputationAssessment: z5.boolean().default(false),
|
|
2590
|
+
policyEnforcement: z5.boolean().default(true),
|
|
2591
|
+
corroboration: z5.boolean().default(false),
|
|
2592
|
+
audit: z5.boolean().default(true)
|
|
3818
2593
|
});
|
|
3819
|
-
var FirewallConfigSchema =
|
|
2594
|
+
var FirewallConfigSchema = z5.object({
|
|
3820
2595
|
stages: FirewallStagesSchema.default(() => ({
|
|
3821
2596
|
sanitization: true,
|
|
3822
2597
|
trustClassification: true,
|
|
@@ -3825,22 +2600,22 @@ var FirewallConfigSchema = z6.object({
|
|
|
3825
2600
|
corroboration: false,
|
|
3826
2601
|
audit: true
|
|
3827
2602
|
})),
|
|
3828
|
-
allowlistedMaintainers:
|
|
3829
|
-
maxInputLength:
|
|
3830
|
-
context:
|
|
3831
|
-
hasWriteAccess:
|
|
3832
|
-
hasSecretAccess:
|
|
2603
|
+
allowlistedMaintainers: z5.array(z5.string().min(1)).default([]),
|
|
2604
|
+
maxInputLength: z5.number().int().positive().default(5e4),
|
|
2605
|
+
context: z5.object({
|
|
2606
|
+
hasWriteAccess: z5.boolean().default(false),
|
|
2607
|
+
hasSecretAccess: z5.boolean().default(false)
|
|
3833
2608
|
}).default(() => ({
|
|
3834
2609
|
hasWriteAccess: false,
|
|
3835
2610
|
hasSecretAccess: false
|
|
3836
2611
|
}))
|
|
3837
2612
|
});
|
|
3838
|
-
var ATLDataSchema =
|
|
3839
|
-
tier:
|
|
3840
|
-
source:
|
|
3841
|
-
user:
|
|
3842
|
-
sanitized:
|
|
3843
|
-
rep:
|
|
2613
|
+
var ATLDataSchema = z5.object({
|
|
2614
|
+
tier: z5.enum(["1", "2", "3", "4"]),
|
|
2615
|
+
source: z5.string().min(1),
|
|
2616
|
+
user: z5.string().min(1),
|
|
2617
|
+
sanitized: z5.boolean(),
|
|
2618
|
+
rep: z5.number().min(0).max(1).optional()
|
|
3844
2619
|
});
|
|
3845
2620
|
|
|
3846
2621
|
// src/security/firewall/agent-trust-labels.ts
|
|
@@ -4091,28 +2866,28 @@ function createPassthroughClassification(meta) {
|
|
|
4091
2866
|
}
|
|
4092
2867
|
|
|
4093
2868
|
// src/security/firewall/github-adapter.ts
|
|
4094
|
-
import { z as
|
|
4095
|
-
var GitHubIssueSchema =
|
|
4096
|
-
type:
|
|
4097
|
-
username:
|
|
4098
|
-
authorAssociation:
|
|
4099
|
-
title:
|
|
4100
|
-
body:
|
|
2869
|
+
import { z as z6 } from "zod";
|
|
2870
|
+
var GitHubIssueSchema = z6.object({
|
|
2871
|
+
type: z6.literal("issue"),
|
|
2872
|
+
username: z6.string().min(1),
|
|
2873
|
+
authorAssociation: z6.string().min(1),
|
|
2874
|
+
title: z6.string().default(""),
|
|
2875
|
+
body: z6.string().default("")
|
|
4101
2876
|
});
|
|
4102
|
-
var GitHubCommentSchema =
|
|
4103
|
-
type:
|
|
4104
|
-
username:
|
|
4105
|
-
authorAssociation:
|
|
4106
|
-
body:
|
|
2877
|
+
var GitHubCommentSchema = z6.object({
|
|
2878
|
+
type: z6.literal("comment"),
|
|
2879
|
+
username: z6.string().min(1),
|
|
2880
|
+
authorAssociation: z6.string().min(1),
|
|
2881
|
+
body: z6.string().default("")
|
|
4107
2882
|
});
|
|
4108
|
-
var GitHubPRSchema =
|
|
4109
|
-
type:
|
|
4110
|
-
username:
|
|
4111
|
-
authorAssociation:
|
|
4112
|
-
title:
|
|
4113
|
-
body:
|
|
2883
|
+
var GitHubPRSchema = z6.object({
|
|
2884
|
+
type: z6.literal("pull_request"),
|
|
2885
|
+
username: z6.string().min(1),
|
|
2886
|
+
authorAssociation: z6.string().min(1),
|
|
2887
|
+
title: z6.string().default(""),
|
|
2888
|
+
body: z6.string().default("")
|
|
4114
2889
|
});
|
|
4115
|
-
var GitHubInputSchema =
|
|
2890
|
+
var GitHubInputSchema = z6.discriminatedUnion("type", [
|
|
4116
2891
|
GitHubIssueSchema,
|
|
4117
2892
|
GitHubCommentSchema,
|
|
4118
2893
|
GitHubPRSchema
|
|
@@ -4154,6 +2929,230 @@ function createGitHubAdapter() {
|
|
|
4154
2929
|
};
|
|
4155
2930
|
}
|
|
4156
2931
|
|
|
2932
|
+
// src/security/ast-rule-runner.ts
|
|
2933
|
+
import { existsSync as existsSync2 } from "fs";
|
|
2934
|
+
import { readdir, readFile, stat } from "fs/promises";
|
|
2935
|
+
import { dirname, extname, join as join2, relative, resolve as resolve2, sep } from "path";
|
|
2936
|
+
import { fileURLToPath } from "url";
|
|
2937
|
+
import { parse, registerDynamicLanguage } from "@ast-grep/napi";
|
|
2938
|
+
import goLangRegistration from "@ast-grep/lang-go";
|
|
2939
|
+
import pythonLangRegistration from "@ast-grep/lang-python";
|
|
2940
|
+
import { parse as parseYaml } from "yaml";
|
|
2941
|
+
import { z as z7 } from "zod";
|
|
2942
|
+
var polyglotLangsRegistered = false;
|
|
2943
|
+
function ensurePolyglotLangs() {
|
|
2944
|
+
if (polyglotLangsRegistered) return;
|
|
2945
|
+
registerDynamicLanguage({ python: pythonLangRegistration, go: goLangRegistration });
|
|
2946
|
+
polyglotLangsRegistered = true;
|
|
2947
|
+
}
|
|
2948
|
+
var AST_RULE_LANGUAGES = ["python", "go"];
|
|
2949
|
+
var AST_RULE_SEVERITIES = ["error", "warning", "info"];
|
|
2950
|
+
var RuleFileSchema = z7.object({
|
|
2951
|
+
id: z7.string().min(1),
|
|
2952
|
+
language: z7.enum(AST_RULE_LANGUAGES),
|
|
2953
|
+
severity: z7.enum(AST_RULE_SEVERITIES),
|
|
2954
|
+
message: z7.string().min(1),
|
|
2955
|
+
rule: z7.record(z7.string(), z7.unknown())
|
|
2956
|
+
});
|
|
2957
|
+
var MAX_SNIPPET_CHARS = 200;
|
|
2958
|
+
var DEFAULT_AST_QA_LIMIT = 200;
|
|
2959
|
+
var MAX_AST_QA_LIMIT = 2e3;
|
|
2960
|
+
var AST_QA_MAX_DEPTH = 24;
|
|
2961
|
+
var MAX_FILES_SCANNED = 5e3;
|
|
2962
|
+
var logger5 = createLogger({ component: "ast-rule-runner" });
|
|
2963
|
+
async function loadRules(dir) {
|
|
2964
|
+
let entries;
|
|
2965
|
+
try {
|
|
2966
|
+
entries = (await readdir(dir)).filter((f) => f.endsWith(".yml") || f.endsWith(".yaml")).sort();
|
|
2967
|
+
} catch (caught) {
|
|
2968
|
+
const e = caught instanceof Error ? caught : new Error(String(caught));
|
|
2969
|
+
throw new ValidationError(`ast-rule-runner: cannot read rules dir ${dir}: ${e.message}`, {
|
|
2970
|
+
cause: e
|
|
2971
|
+
});
|
|
2972
|
+
}
|
|
2973
|
+
const rules = [];
|
|
2974
|
+
for (const file of entries) {
|
|
2975
|
+
const path2 = join2(dir, file);
|
|
2976
|
+
const raw = await readFile(path2, "utf8");
|
|
2977
|
+
let parsed;
|
|
2978
|
+
try {
|
|
2979
|
+
parsed = parseYaml(raw);
|
|
2980
|
+
} catch (caught) {
|
|
2981
|
+
const e = caught instanceof Error ? caught : new Error(String(caught));
|
|
2982
|
+
throw new ValidationError(`ast-rule-runner: malformed YAML in ${path2}: ${e.message}`, {
|
|
2983
|
+
cause: e
|
|
2984
|
+
});
|
|
2985
|
+
}
|
|
2986
|
+
const result = RuleFileSchema.safeParse(parsed);
|
|
2987
|
+
if (!result.success) {
|
|
2988
|
+
throw new ValidationError(
|
|
2989
|
+
`ast-rule-runner: invalid rule file ${path2}: ${formatZodError(result.error)}`
|
|
2990
|
+
);
|
|
2991
|
+
}
|
|
2992
|
+
rules.push(result.data);
|
|
2993
|
+
}
|
|
2994
|
+
return rules;
|
|
2995
|
+
}
|
|
2996
|
+
function getBuiltInAstRulesPath() {
|
|
2997
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
2998
|
+
const currentDir = dirname(currentFile);
|
|
2999
|
+
if (currentFile.includes(`${sep}dist${sep}`) || currentFile.endsWith(`${sep}dist`)) {
|
|
3000
|
+
const distIndex = currentFile.lastIndexOf(`${sep}dist${sep}`);
|
|
3001
|
+
if (distIndex !== -1) {
|
|
3002
|
+
const distDir = currentFile.substring(0, distIndex + 5);
|
|
3003
|
+
const bundledPath = join2(distDir, "security", "ast-rules");
|
|
3004
|
+
if (existsSync2(bundledPath)) return bundledPath;
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
const possiblePaths = [
|
|
3008
|
+
join2(currentDir, "ast-rules"),
|
|
3009
|
+
// Unbundled: sibling of this file in src/security/
|
|
3010
|
+
join2(currentDir, "security", "ast-rules"),
|
|
3011
|
+
// Bundled chunk: dist/security sibling
|
|
3012
|
+
join2(dirname(currentDir), "security", "ast-rules")
|
|
3013
|
+
];
|
|
3014
|
+
for (const path2 of possiblePaths) {
|
|
3015
|
+
if (existsSync2(path2)) return path2;
|
|
3016
|
+
}
|
|
3017
|
+
return join2(currentDir, "ast-rules");
|
|
3018
|
+
}
|
|
3019
|
+
function resolveWithinCwd(target) {
|
|
3020
|
+
const resolved = resolve2(target);
|
|
3021
|
+
const cwdRoot = resolve2(".");
|
|
3022
|
+
if (resolved !== cwdRoot && !resolved.startsWith(cwdRoot + sep)) {
|
|
3023
|
+
return { error: `Path traversal denied: scope must be within ${cwdRoot}` };
|
|
3024
|
+
}
|
|
3025
|
+
return { resolved };
|
|
3026
|
+
}
|
|
3027
|
+
var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", "dist", ".git"]);
|
|
3028
|
+
var POLYGLOT_EXT_TO_LANG = {
|
|
3029
|
+
".py": "python",
|
|
3030
|
+
".go": "go"
|
|
3031
|
+
};
|
|
3032
|
+
function inferRuleLang(file) {
|
|
3033
|
+
return POLYGLOT_EXT_TO_LANG[extname(file).toLowerCase()] ?? null;
|
|
3034
|
+
}
|
|
3035
|
+
async function findPolyglotFiles(dir, maxDepth) {
|
|
3036
|
+
if (maxDepth <= 0) return [];
|
|
3037
|
+
const out = [];
|
|
3038
|
+
let entries;
|
|
3039
|
+
try {
|
|
3040
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
3041
|
+
} catch (caught) {
|
|
3042
|
+
const e = caught instanceof Error ? caught : new Error(String(caught));
|
|
3043
|
+
logger5.warn(`ast-rule-runner: skipped unreadable directory ${dir}: ${e.message}`);
|
|
3044
|
+
return out;
|
|
3045
|
+
}
|
|
3046
|
+
for (const entry of entries) {
|
|
3047
|
+
const fullPath = join2(dir, entry.name);
|
|
3048
|
+
if (entry.isDirectory() && !SKIP_DIRS.has(entry.name)) {
|
|
3049
|
+
out.push(...await findPolyglotFiles(fullPath, maxDepth - 1));
|
|
3050
|
+
} else if (entry.isFile() && inferRuleLang(entry.name) !== null) {
|
|
3051
|
+
out.push(fullPath);
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
return out;
|
|
3055
|
+
}
|
|
3056
|
+
function langToParseArg(lang) {
|
|
3057
|
+
ensurePolyglotLangs();
|
|
3058
|
+
return lang;
|
|
3059
|
+
}
|
|
3060
|
+
function scanFile(src, lang, applicable, budget) {
|
|
3061
|
+
const { rel, limit, alreadyFound } = budget;
|
|
3062
|
+
const root = parse(langToParseArg(lang), src).root();
|
|
3063
|
+
const lines = src.split("\n");
|
|
3064
|
+
const findings = [];
|
|
3065
|
+
let total = 0;
|
|
3066
|
+
for (const rule of applicable) {
|
|
3067
|
+
const config = { rule: rule.rule };
|
|
3068
|
+
for (const node of root.findAll(config)) {
|
|
3069
|
+
total += 1;
|
|
3070
|
+
if (alreadyFound + findings.length < limit) {
|
|
3071
|
+
const { start } = node.range();
|
|
3072
|
+
const rawLine = lines[start.line] ?? node.text();
|
|
3073
|
+
findings.push({
|
|
3074
|
+
ruleId: rule.id,
|
|
3075
|
+
severity: rule.severity,
|
|
3076
|
+
message: rule.message,
|
|
3077
|
+
file: rel,
|
|
3078
|
+
line: start.line + 1,
|
|
3079
|
+
column: start.column + 1,
|
|
3080
|
+
snippet: rawLine.trim().slice(0, MAX_SNIPPET_CHARS)
|
|
3081
|
+
});
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
return { findings, total };
|
|
3086
|
+
}
|
|
3087
|
+
async function assertScanRootIsDirectory(resolved) {
|
|
3088
|
+
let rootStat;
|
|
3089
|
+
try {
|
|
3090
|
+
rootStat = await stat(resolved);
|
|
3091
|
+
} catch (caught) {
|
|
3092
|
+
const e = caught instanceof Error ? caught : new Error(String(caught));
|
|
3093
|
+
throw new ValidationError(`ast-rule-runner: cannot read targetDir ${resolved}: ${e.message}`, {
|
|
3094
|
+
cause: e
|
|
3095
|
+
});
|
|
3096
|
+
}
|
|
3097
|
+
if (!rootStat.isDirectory()) {
|
|
3098
|
+
throw new ValidationError(
|
|
3099
|
+
`ast-rule-runner: targetDir must be a directory, got a non-directory path: ${resolved}`
|
|
3100
|
+
);
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
async function resolveScanFiles(root) {
|
|
3104
|
+
const discovered = await findPolyglotFiles(root, AST_QA_MAX_DEPTH);
|
|
3105
|
+
const files = discovered.slice(0, MAX_FILES_SCANNED);
|
|
3106
|
+
const filesSkipped = discovered.length - files.length;
|
|
3107
|
+
const filesTruncated = filesSkipped > 0;
|
|
3108
|
+
if (filesTruncated) {
|
|
3109
|
+
logger5.warn(
|
|
3110
|
+
`ast-rule-runner: ${String(filesSkipped)} file(s) NOT scanned \u2014 file cap ${String(MAX_FILES_SCANNED)} exceeded (discovered=${String(discovered.length)}). Scan is PARTIAL; do not treat findings as exhaustive.`
|
|
3111
|
+
);
|
|
3112
|
+
}
|
|
3113
|
+
return { files, filesSkipped, filesTruncated };
|
|
3114
|
+
}
|
|
3115
|
+
async function collectAstQaFindings(opts) {
|
|
3116
|
+
const guard = resolveWithinCwd(opts.targetDir);
|
|
3117
|
+
if ("error" in guard) {
|
|
3118
|
+
throw new SecurityError(guard.error);
|
|
3119
|
+
}
|
|
3120
|
+
await assertScanRootIsDirectory(guard.resolved);
|
|
3121
|
+
const rulesDir = opts.rulesDir ?? getBuiltInAstRulesPath();
|
|
3122
|
+
const rules = await loadRules(rulesDir);
|
|
3123
|
+
const limit = Math.min(Math.max(opts.limit ?? DEFAULT_AST_QA_LIMIT, 1), MAX_AST_QA_LIMIT);
|
|
3124
|
+
const { files, filesSkipped, filesTruncated } = await resolveScanFiles(guard.resolved);
|
|
3125
|
+
const findings = [];
|
|
3126
|
+
let total = 0;
|
|
3127
|
+
for (const file of files) {
|
|
3128
|
+
const lang = inferRuleLang(file);
|
|
3129
|
+
if (lang === null) continue;
|
|
3130
|
+
const applicable = rules.filter((r) => r.language === lang);
|
|
3131
|
+
if (applicable.length === 0) continue;
|
|
3132
|
+
let src;
|
|
3133
|
+
try {
|
|
3134
|
+
src = await readFile(file, "utf8");
|
|
3135
|
+
} catch {
|
|
3136
|
+
logger5.warn(`ast-rule-runner: skipped unreadable file ${file}`);
|
|
3137
|
+
continue;
|
|
3138
|
+
}
|
|
3139
|
+
const rel = relative(guard.resolved, file) || file;
|
|
3140
|
+
const scanned = scanFile(src, lang, applicable, { rel, limit, alreadyFound: findings.length });
|
|
3141
|
+
findings.push(...scanned.findings);
|
|
3142
|
+
total += scanned.total;
|
|
3143
|
+
}
|
|
3144
|
+
if (total > findings.length) {
|
|
3145
|
+
logger5.warn(
|
|
3146
|
+
`ast-rule-runner: ${String(total - findings.length)} finding(s) omitted beyond limit=${String(limit)} (total=${String(total)})`
|
|
3147
|
+
);
|
|
3148
|
+
}
|
|
3149
|
+
return { findings, total, limit, filesScanned: files.length, filesSkipped, filesTruncated };
|
|
3150
|
+
}
|
|
3151
|
+
async function runAstQaRules(opts) {
|
|
3152
|
+
const { findings } = await collectAstQaFindings(opts);
|
|
3153
|
+
return findings;
|
|
3154
|
+
}
|
|
3155
|
+
|
|
4157
3156
|
// src/orchestration/spec-parser-types.ts
|
|
4158
3157
|
import { z as z8 } from "zod";
|
|
4159
3158
|
var IssueReferenceSchema = z8.object({
|
|
@@ -4568,7 +3567,7 @@ var DEFAULT_BENCHMARK_CONFIG = {
|
|
|
4568
3567
|
|
|
4569
3568
|
// src/benchmarks/benchmark-runner.ts
|
|
4570
3569
|
import { cpus, totalmem, platform, arch } from "os";
|
|
4571
|
-
var
|
|
3570
|
+
var logger6 = createLogger({ component: "benchmark-runner" });
|
|
4572
3571
|
var LatencySampler = class {
|
|
4573
3572
|
samples = [];
|
|
4574
3573
|
startTimes = /* @__PURE__ */ new Map();
|
|
@@ -4664,11 +3663,11 @@ async function runOperationBenchmark(operation, datasetSize, fn, config = {}) {
|
|
|
4664
3663
|
const startTime = getTimeProvider().now();
|
|
4665
3664
|
const startMemory = process.memoryUsage().heapUsed;
|
|
4666
3665
|
let peakMemory = startMemory;
|
|
4667
|
-
|
|
3666
|
+
logger6.debug("Running warmup", { operation, iterations: cfg.warmupIterations });
|
|
4668
3667
|
for (let i = 0; i < cfg.warmupIterations; i++) {
|
|
4669
3668
|
await fn();
|
|
4670
3669
|
}
|
|
4671
|
-
|
|
3670
|
+
logger6.debug("Running measurements", { operation, iterations: cfg.measurementIterations });
|
|
4672
3671
|
for (let i = 0; i < cfg.measurementIterations; i++) {
|
|
4673
3672
|
const id = `op-${String(i)}`;
|
|
4674
3673
|
sampler.start(id);
|
|
@@ -4793,7 +3792,7 @@ ${"=".repeat(60)}`);
|
|
|
4793
3792
|
}
|
|
4794
3793
|
|
|
4795
3794
|
// src/benchmarks/memory-benchmarks.ts
|
|
4796
|
-
var
|
|
3795
|
+
var logger7 = createLogger({ component: "memory-benchmarks" });
|
|
4797
3796
|
var DEFAULT_MEMORY_BENCHMARK_CONFIG = {
|
|
4798
3797
|
...DEFAULT_BENCHMARK_CONFIG,
|
|
4799
3798
|
contentSizeBytes: 1024,
|
|
@@ -4901,9 +3900,9 @@ async function benchmarkPrune(backend, data, config) {
|
|
|
4901
3900
|
async function runMemoryBenchmarks(backend, name, config = {}) {
|
|
4902
3901
|
const cfg = { ...DEFAULT_MEMORY_BENCHMARK_CONFIG, ...config };
|
|
4903
3902
|
const operations = [];
|
|
4904
|
-
|
|
3903
|
+
logger7.info("Starting memory benchmarks", { name, sizes: cfg.datasetSizes });
|
|
4905
3904
|
for (const size of cfg.datasetSizes) {
|
|
4906
|
-
|
|
3905
|
+
logger7.info("Running benchmarks for dataset size", { size });
|
|
4907
3906
|
const data = generateTestData(size, cfg);
|
|
4908
3907
|
try {
|
|
4909
3908
|
const futureDate = new Date(getTimeProvider().now() + 365 * 24 * 60 * 60 * 1e3);
|
|
@@ -4917,7 +3916,7 @@ async function runMemoryBenchmarks(backend, name, config = {}) {
|
|
|
4917
3916
|
}
|
|
4918
3917
|
const environment = getBenchmarkEnvironment();
|
|
4919
3918
|
const summary = createBenchmarkSummary(operations, cfg);
|
|
4920
|
-
|
|
3919
|
+
logger7.info("Benchmarks complete", {
|
|
4921
3920
|
name,
|
|
4922
3921
|
passed: summary.passed,
|
|
4923
3922
|
avgP95: summary.avgP95Latency,
|
|
@@ -4963,7 +3962,7 @@ function compareBenchmarks(baseline, current) {
|
|
|
4963
3962
|
}
|
|
4964
3963
|
|
|
4965
3964
|
// src/benchmarks/token-benchmark.ts
|
|
4966
|
-
var
|
|
3965
|
+
var logger8 = createLogger({ component: "token-benchmark" });
|
|
4967
3966
|
var CHARS_PER_TOKEN = 4;
|
|
4968
3967
|
function estimateTokens2(text) {
|
|
4969
3968
|
return Math.ceil(text.length / CHARS_PER_TOKEN);
|
|
@@ -4981,7 +3980,7 @@ async function runTokenBenchmark(backend, config = {}) {
|
|
|
4981
3980
|
const cfg = { ...DEFAULT_MEMORY_BENCHMARK_CONFIG, ...config };
|
|
4982
3981
|
const results = [];
|
|
4983
3982
|
for (const size of cfg.datasetSizes) {
|
|
4984
|
-
|
|
3983
|
+
logger8.info("Running token benchmark", { size });
|
|
4985
3984
|
const data = generateTestData(size, cfg);
|
|
4986
3985
|
for (const entry of data.entries) {
|
|
4987
3986
|
await backend.store(entry.key, entry.content, {
|
|
@@ -5014,15 +4013,15 @@ async function runTokenBenchmark(backend, config = {}) {
|
|
|
5014
4013
|
}
|
|
5015
4014
|
|
|
5016
4015
|
// src/benchmarks/consolidation-benchmark.ts
|
|
5017
|
-
var
|
|
4016
|
+
var logger9 = createLogger({ component: "consolidation-benchmark" });
|
|
5018
4017
|
async function runConsolidationBenchmark(operations, config = {}) {
|
|
5019
4018
|
const cfg = { ...DEFAULT_MEMORY_BENCHMARK_CONFIG, ...config };
|
|
5020
4019
|
const benchmarks = [];
|
|
5021
|
-
|
|
4020
|
+
logger9.info("Starting consolidation benchmarks", {
|
|
5022
4021
|
operationCount: operations.length
|
|
5023
4022
|
});
|
|
5024
4023
|
for (const op of operations) {
|
|
5025
|
-
|
|
4024
|
+
logger9.info("Benchmarking consolidation operation", { name: op.name });
|
|
5026
4025
|
const benchmark = await runOperationBenchmark(
|
|
5027
4026
|
op.name,
|
|
5028
4027
|
0,
|
|
@@ -5137,7 +4136,7 @@ function formatBenchmarkReport(report) {
|
|
|
5137
4136
|
}
|
|
5138
4137
|
|
|
5139
4138
|
// src/benchmarks/adapter-latency-benchmark.ts
|
|
5140
|
-
var
|
|
4139
|
+
var logger10 = createLogger({ component: "adapter-latency-benchmark" });
|
|
5141
4140
|
var DEFAULT_ADAPTER_LATENCY_CONFIG = {
|
|
5142
4141
|
warmupIterations: 3,
|
|
5143
4142
|
measurementIterations: 10,
|
|
@@ -5187,7 +4186,7 @@ async function benchmarkScenario(adapter, scenario, config) {
|
|
|
5187
4186
|
const errors = [];
|
|
5188
4187
|
let successCount = 0;
|
|
5189
4188
|
let failureCount = 0;
|
|
5190
|
-
|
|
4189
|
+
logger10.info("Benchmarking scenario", {
|
|
5191
4190
|
adapter: adapter.name,
|
|
5192
4191
|
scenario: scenario.name,
|
|
5193
4192
|
warmup: config.warmupIterations,
|
|
@@ -5614,7 +4613,7 @@ var GateCheckResultSchema = z16.object({
|
|
|
5614
4613
|
});
|
|
5615
4614
|
|
|
5616
4615
|
// src/pipeline/quality-pipeline.ts
|
|
5617
|
-
var
|
|
4616
|
+
var logger11 = createLogger({ component: "quality-pipeline" });
|
|
5618
4617
|
|
|
5619
4618
|
// src/pipeline/iterative-consensus.ts
|
|
5620
4619
|
var defaultLogger = createLogger({ component: "iterative-consensus" });
|
|
@@ -5715,7 +4714,7 @@ function buildVotingInput(plan, config) {
|
|
|
5715
4714
|
}
|
|
5716
4715
|
async function executeSingleVote(plan, config, log) {
|
|
5717
4716
|
try {
|
|
5718
|
-
const { executeVoting } = await import("./consensus-vote-
|
|
4717
|
+
const { executeVoting } = await import("./consensus-vote-KF6M7NZJ.js");
|
|
5719
4718
|
const input = buildVotingInput(plan, config);
|
|
5720
4719
|
const result = await executeVoting(input, log);
|
|
5721
4720
|
return parseVotingResult(result);
|
|
@@ -5748,17 +4747,19 @@ function parseVotingResult(result) {
|
|
|
5748
4747
|
}
|
|
5749
4748
|
|
|
5750
4749
|
// src/replay/replay-executor.ts
|
|
5751
|
-
var
|
|
4750
|
+
var logger12 = createLogger({ component: "ReplayExecutor" });
|
|
5752
4751
|
export {
|
|
5753
4752
|
ALLOWED_COMMANDS,
|
|
5754
4753
|
ARTIFACT_TYPES,
|
|
4754
|
+
AST_RULE_LANGUAGES,
|
|
4755
|
+
AST_RULE_SEVERITIES,
|
|
5755
4756
|
AUDIT_PIPELINE_TEMPLATE,
|
|
5756
4757
|
AbTestTracker,
|
|
5757
4758
|
ActivationStrategySchema,
|
|
5758
4759
|
AdapterConfigSchema,
|
|
5759
4760
|
AdapterFactory,
|
|
5760
4761
|
AdapterModelError,
|
|
5761
|
-
|
|
4762
|
+
RateLimiter as AdapterRateLimiter,
|
|
5762
4763
|
AgentActionSchema,
|
|
5763
4764
|
AgentCapability,
|
|
5764
4765
|
AgentError,
|
|
@@ -5862,6 +4863,7 @@ export {
|
|
|
5862
4863
|
DECEPTION_CATEGORY,
|
|
5863
4864
|
DEFAULT_ACTIVATION_OPTIONS,
|
|
5864
4865
|
DEFAULT_ADAPTER_LATENCY_CONFIG,
|
|
4866
|
+
DEFAULT_AST_QA_LIMIT,
|
|
5865
4867
|
DEFAULT_BENCHMARK_CONFIG,
|
|
5866
4868
|
DEFAULT_BUDGET,
|
|
5867
4869
|
DEFAULT_COLLECT_STREAM_MAX_CHUNKS,
|
|
@@ -5994,12 +4996,14 @@ export {
|
|
|
5994
4996
|
LoadedSkillSetSchema,
|
|
5995
4997
|
LoggingConfigSchema,
|
|
5996
4998
|
MANIPULATION_CATEGORY,
|
|
4999
|
+
MAX_AST_QA_LIMIT,
|
|
5997
5000
|
MAX_DIFF_LENGTH,
|
|
5998
5001
|
MAX_EXECUTION_TIME_MS,
|
|
5002
|
+
MAX_FILES_SCANNED,
|
|
5999
5003
|
MEM0_TARGETS,
|
|
6000
5004
|
MIN_EXPERTS_FOR_PATTERN,
|
|
6001
5005
|
MODEL_CAPABILITIES,
|
|
6002
|
-
|
|
5006
|
+
RateLimiter2 as McpRateLimiter,
|
|
6003
5007
|
MemoryError,
|
|
6004
5008
|
MemoryQueryInputSchema,
|
|
6005
5009
|
MemoryStatsInputSchema,
|
|
@@ -6083,6 +5087,7 @@ export {
|
|
|
6083
5087
|
ReasoningNodeSchema,
|
|
6084
5088
|
ReasoningStepTypeSchema,
|
|
6085
5089
|
ReasoningTreeSchema,
|
|
5090
|
+
RecoverableExpert,
|
|
6086
5091
|
RegistryError,
|
|
6087
5092
|
RegistryImportInputSchema,
|
|
6088
5093
|
RejectionCategorySchema,
|
|
@@ -6276,6 +5281,7 @@ export {
|
|
|
6276
5281
|
checkPipelinePolicy,
|
|
6277
5282
|
checkpointToResult,
|
|
6278
5283
|
chunkByDirectory,
|
|
5284
|
+
classifyExpertFailure,
|
|
6279
5285
|
classifyTask,
|
|
6280
5286
|
classifyTrust,
|
|
6281
5287
|
cleanupCheckpoint,
|
|
@@ -6284,6 +5290,7 @@ export {
|
|
|
6284
5290
|
calculateBackoffDelay as cliCalculateBackoffDelay,
|
|
6285
5291
|
categorizeError as cliCategorizeError,
|
|
6286
5292
|
closeServer,
|
|
5293
|
+
collectAstQaFindings,
|
|
6287
5294
|
collectRealVotes,
|
|
6288
5295
|
collectStream,
|
|
6289
5296
|
compareBenchmarks,
|
|
@@ -6433,6 +5440,7 @@ export {
|
|
|
6433
5440
|
emitStateUpdated,
|
|
6434
5441
|
emitStepCompleted,
|
|
6435
5442
|
emitTrustEvent,
|
|
5443
|
+
ensurePolyglotLangs,
|
|
6436
5444
|
err,
|
|
6437
5445
|
estimateTokens2 as estimateBenchmarkTokens,
|
|
6438
5446
|
estimateTaskComplexity,
|
|
@@ -6476,6 +5484,7 @@ export {
|
|
|
6476
5484
|
getAvailableClis,
|
|
6477
5485
|
getAvailableRoles,
|
|
6478
5486
|
getBenchmarkEnvironment,
|
|
5487
|
+
getBuiltInAstRulesPath,
|
|
6479
5488
|
getBuiltInTemplates,
|
|
6480
5489
|
getBuiltInTemplatesPath,
|
|
6481
5490
|
getBuiltInTemplatesWithMetadata,
|
|
@@ -6536,6 +5545,7 @@ export {
|
|
|
6536
5545
|
isZodError,
|
|
6537
5546
|
listTemplateIds,
|
|
6538
5547
|
loadCheckpointState,
|
|
5548
|
+
loadRules,
|
|
6539
5549
|
loadTemplateFile,
|
|
6540
5550
|
loadTemplatesFromDirectory,
|
|
6541
5551
|
loadWorkflowFile,
|
|
@@ -6626,6 +5636,7 @@ export {
|
|
|
6626
5636
|
resultToOutcome,
|
|
6627
5637
|
runAdapterLatencyBenchmark,
|
|
6628
5638
|
runAdaptiveOrchestrator,
|
|
5639
|
+
runAstQaRules,
|
|
6629
5640
|
runBenchmark,
|
|
6630
5641
|
runConsensusGate,
|
|
6631
5642
|
runConsolidationBenchmark,
|