open-multi-agent-kit 0.96.2 → 0.97.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/CHANGELOG.md +16 -0
- package/README.md +4 -2
- package/dist/core/agent-session.d.ts +9 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +84 -7
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/attachment-store.d.ts +39 -0
- package/dist/core/attachment-store.d.ts.map +1 -0
- package/dist/core/attachment-store.js +81 -0
- package/dist/core/attachment-store.js.map +1 -0
- package/dist/core/command-safety.d.ts +8 -0
- package/dist/core/command-safety.d.ts.map +1 -1
- package/dist/core/command-safety.js +140 -14
- package/dist/core/command-safety.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +6 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +35 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/context-budget-governor-v2.d.ts +1 -1
- package/dist/core/context-budget-governor-v2.d.ts.map +1 -1
- package/dist/core/context-budget-governor-v2.js +1 -1
- package/dist/core/context-budget-governor-v2.js.map +1 -1
- package/dist/core/context-budget-v2-cache-keys.d.ts +3 -0
- package/dist/core/context-budget-v2-cache-keys.d.ts.map +1 -1
- package/dist/core/context-budget-v2-cache-keys.js +2 -0
- package/dist/core/context-budget-v2-cache-keys.js.map +1 -1
- package/dist/core/context-budget-v2-plan-cache-keys.d.ts.map +1 -1
- package/dist/core/context-budget-v2-plan-cache-keys.js +3 -0
- package/dist/core/context-budget-v2-plan-cache-keys.js.map +1 -1
- package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
- package/dist/core/context-budget-v2-planner.js +2 -1
- package/dist/core/context-budget-v2-planner.js.map +1 -1
- package/dist/core/context-budget-v2-scoring.d.ts +17 -0
- package/dist/core/context-budget-v2-scoring.d.ts.map +1 -1
- package/dist/core/context-budget-v2-scoring.js +25 -8
- package/dist/core/context-budget-v2-scoring.js.map +1 -1
- package/dist/core/context-budget-v2-selection.d.ts +2 -2
- package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
- package/dist/core/context-budget-v2-selection.js +18 -1
- package/dist/core/context-budget-v2-selection.js.map +1 -1
- package/dist/core/context-budget-v2-types.d.ts +17 -0
- package/dist/core/context-budget-v2-types.d.ts.map +1 -1
- package/dist/core/context-budget-v2-types.js +15 -0
- package/dist/core/context-budget-v2-types.js.map +1 -1
- package/dist/core/extensions/builtin/command-safety-gate.d.ts +3 -1
- package/dist/core/extensions/builtin/command-safety-gate.d.ts.map +1 -1
- package/dist/core/extensions/builtin/command-safety-gate.js +7 -0
- package/dist/core/extensions/builtin/command-safety-gate.js.map +1 -1
- package/dist/core/extensions/types.d.ts +12 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-registry.d.ts +8 -3
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +71 -1
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/package-doctor-source-scan.d.ts +9 -0
- package/dist/core/package-doctor-source-scan.d.ts.map +1 -1
- package/dist/core/package-doctor-source-scan.js +77 -4
- package/dist/core/package-doctor-source-scan.js.map +1 -1
- package/dist/core/prompt-attachment.d.ts +51 -0
- package/dist/core/prompt-attachment.d.ts.map +1 -0
- package/dist/core/prompt-attachment.js +186 -0
- package/dist/core/prompt-attachment.js.map +1 -0
- package/dist/core/provider-resilience.d.ts +28 -0
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +50 -0
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/provider-retry.d.ts +1 -1
- package/dist/core/provider-retry.d.ts.map +1 -1
- package/dist/core/provider-retry.js +1 -1
- package/dist/core/provider-retry.js.map +1 -1
- package/dist/core/provider-usage.d.ts.map +1 -1
- package/dist/core/provider-usage.js +68 -2
- package/dist/core/provider-usage.js.map +1 -1
- package/dist/core/reasoning-router-promotion.d.ts +84 -0
- package/dist/core/reasoning-router-promotion.d.ts.map +1 -0
- package/dist/core/reasoning-router-promotion.js +92 -0
- package/dist/core/reasoning-router-promotion.js.map +1 -0
- package/dist/core/session-bash-service.d.ts.map +1 -1
- package/dist/core/session-bash-service.js +4 -3
- package/dist/core/session-bash-service.js.map +1 -1
- package/dist/core/session-termination.d.ts +1 -1
- package/dist/core/session-termination.d.ts.map +1 -1
- package/dist/core/session-termination.js +11 -2
- package/dist/core/session-termination.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +3 -7
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +13 -48
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -34
- package/dist/core/tools/read.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/attachment-strip.d.ts +21 -0
- package/dist/modes/interactive/components/attachment-strip.d.ts.map +1 -0
- package/dist/modes/interactive/components/attachment-strip.js +136 -0
- package/dist/modes/interactive/components/attachment-strip.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +6 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +26 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/status-sidebar.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-sidebar.js +12 -1
- package/dist/modes/interactive/components/status-sidebar.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +23 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +174 -53
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/compaction.md +1 -1
- package/docs/extensions.md +12 -3
- package/docs/index.md +4 -1
- package/docs/metrics.md +74 -2
- package/docs/provider-resilience.md +11 -0
- package/docs/usage.md +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +18 -18
- package/package.json +7 -7
- package/dist/core/tools/omp-pure-seams.d.ts +0 -41
- package/dist/core/tools/omp-pure-seams.d.ts.map +0 -1
- package/dist/core/tools/omp-pure-seams.js +0 -142
- package/dist/core/tools/omp-pure-seams.js.map +0 -1
- package/dist/core/tools/omp-seam-runtime.d.ts +0 -100
- package/dist/core/tools/omp-seam-runtime.d.ts.map +0 -1
- package/dist/core/tools/omp-seam-runtime.js +0 -40
- package/dist/core/tools/omp-seam-runtime.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-budget-v2-types.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-v2-types.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tContextBudgetItemV2,\n\tContextBudgetTierV2,\n\tContextRepresentationCacheMetadataV2,\n\tContextRepresentationCandidateV2,\n\tContextRepresentationKindV2,\n\tContextSourceRefV2,\n\tHeadroomQualityPolicyV2,\n} from \"./context-budget-headroom.ts\";\nimport type { TokenCounterAdapter } from \"./context-budget-token-counter.ts\";\nimport type { ContextCacheInvalidationSnapshot } from \"./context-budget-v2-cache-invalidation.ts\";\n\nexport const CONTEXT_BUDGET_POLICY_VERSION_V2 = \"context-budget-v2\";\n\n/** Fixed compatibility telemetry for the removed legacy token optimizer. */\nexport interface TokenOptimizerRuntimeStatus {\n\treadonly optimizerId: \"legacy-token-optimizer\";\n\treadonly status: \"quarantined_compatibility\";\n\treadonly active: false;\n\treadonly activeContextBudgetOptimizer: \"context-budget-v2\";\n\treadonly compatibilityOnly: true;\n}\n\nexport interface TierBudgetPolicyV2 {\n\treadonly floorPct: number;\n\treadonly ceilingPct: number;\n}\n\nexport const DEFAULT_TIER_POLICY_V2: Readonly<Record<ContextBudgetTierV2, TierBudgetPolicyV2>> = {\n\tsystem: { floorPct: 0.25, ceilingPct: 0.45 },\n\t\"active-goal\": { floorPct: 0.1, ceilingPct: 0.25 },\n\t\"current-files\": { floorPct: 0.08, ceilingPct: 0.2 },\n\ttools: { floorPct: 0.04, ceilingPct: 0.12 },\n\tskills: { floorPct: 0.03, ceilingPct: 0.12 },\n\tmcp: { floorPct: 0.02, ceilingPct: 0.08 },\n\thistory: { floorPct: 0.1, ceilingPct: 0.3 },\n\tevidence: { floorPct: 0.08, ceilingPct: 0.25 },\n\tscratch: { floorPct: 0, ceilingPct: 0.05 },\n};\n\nexport const ALL_TIERS_V2: readonly ContextBudgetTierV2[] = [\n\t\"system\",\n\t\"active-goal\",\n\t\"current-files\",\n\t\"tools\",\n\t\"skills\",\n\t\"mcp\",\n\t\"history\",\n\t\"evidence\",\n\t\"scratch\",\n];\n\nexport interface PromptContextBudgetInputV2 {\n\treadonly maxTokens: number;\n\treadonly responseReserveTokens?: number;\n\treadonly safetyMarginTokens?: number;\n\treadonly modelId?: string;\n\treadonly tokenizerId?: string;\n\treadonly policyVersion?: string;\n\treadonly promptHash?: string;\n\treadonly query?: string;\n\treadonly items: readonly ContextBudgetItemV2[];\n\treadonly tokenCounter?: TokenCounterAdapter;\n\treadonly tierPolicy?: Partial<Record<ContextBudgetTierV2, TierBudgetPolicyV2>>;\n\treadonly qualityPolicy?: HeadroomQualityPolicyV2;\n\treadonly cacheProvider?: ContextBudgetCacheProviderV2;\n\treadonly cacheNamespace?: string;\n\treadonly queryIntentHash?: string;\n\treadonly cacheBudgetBucket?: string;\n\treadonly redactionPolicyHash?: string;\n\treadonly safetyProfileHash?: string;\n\treadonly cacheNowEpochMs?: number;\n\treadonly cacheTtlMs?: number;\n\treadonly cacheInvalidationSnapshot?: ContextCacheInvalidationSnapshot;\n}\n\nexport interface SelectedRepresentationV2 {\n\treadonly itemId: string;\n\treadonly kind: ContextRepresentationKindV2;\n\treadonly text: string;\n\treadonly estimatedTokens: number;\n\treadonly fidelity: ContextRepresentationCandidateV2[\"fidelity\"];\n\treadonly sourceRef?: ContextSourceRefV2;\n\treadonly summaryHash?: string;\n\treadonly compressorId?: string;\n\treadonly cache?: ContextRepresentationCacheMetadataV2;\n}\n\nexport interface TierBudgetAllocationV2 {\n\treadonly tier: ContextBudgetTierV2;\n\treadonly floorTokens: number;\n\treadonly ceilingTokens: number;\n\treadonly allocatedTokens: number;\n\treadonly usedTokens: number;\n\treadonly hardTokens: number;\n}\n\nexport type QualityDiagnosticReasonV2 =\n\t| \"omitted_high_priority\"\n\t| \"retrieval_miss_risk\"\n\t| \"restore_on_demand_hint\"\n\t| \"hard_pin_over_capacity\"\n\t| \"coverage_gap\"\n\t| \"tier_ceiling_exceeded\"\n\t| \"invalid_budget\";\n\nexport interface QualityDiagnosticV2 {\n\treadonly reason: QualityDiagnosticReasonV2;\n\treadonly itemId?: string;\n\treadonly detail: string;\n}\n\nexport interface ContextBudgetObservabilityCountsV2 {\n\treadonly selected: number;\n\treadonly omitted: number;\n\treadonly pointer: number;\n\treadonly compressed: number;\n\treadonly full: number;\n\treadonly retrievalFallback: number;\n}\n\nexport interface ContextBudgetObservabilityTokensV2 {\n\treadonly available: number;\n\treadonly used: number;\n\treadonly raw: number;\n\treadonly omitted: number;\n\treadonly tokenSavings: number;\n}\n\nexport type ContextBudgetCacheLayerV2 = \"turn\" | \"session\" | \"workspace\" | \"shared\";\n\nexport type ContextBudgetRepresentationCacheRejectReasonV2 =\n\t| \"fingerprint_mismatch\"\n\t| \"kind_mismatch\"\n\t| \"model_mismatch\"\n\t| \"negative\"\n\t| \"policy_mismatch\"\n\t| \"poisoned\"\n\t| \"source_hash_mismatch\"\n\t| \"stale\"\n\t| \"token_invalid\"\n\t| \"tokenizer_mismatch\";\n\nexport type ContextBudgetRepresentationCacheKeyKindV2 = \"exact\" | \"materialized\";\n\nexport interface ContextBudgetMaterializedVerificationV2 {\n\treadonly queryCoverage?: number;\n\treadonly sourceCoverage?: number;\n\treadonly secretLeakScore?: number;\n\treadonly poisonScore?: number;\n\treadonly validatorVersion?: string;\n}\n\nexport interface ContextBudgetRepresentationCacheEntryV2 {\n\treadonly kind: ContextRepresentationKindV2;\n\treadonly text: string;\n\treadonly estimatedTokens: number;\n\treadonly fidelity: ContextRepresentationCandidateV2[\"fidelity\"];\n\treadonly sourceHash: string;\n\treadonly representationFingerprint: string;\n\treadonly keyKind?: ContextBudgetRepresentationCacheKeyKindV2;\n\treadonly modelId: string;\n\treadonly tokenizerId: string;\n\treadonly policyVersion: string;\n\treadonly sourceRef?: ContextSourceRefV2;\n\treadonly summaryHash?: string;\n\treadonly compressorId?: string;\n\treadonly compressorPolicyHash?: string;\n\treadonly qualityPolicyHash?: string;\n\treadonly queryIntentCluster?: string;\n\treadonly outputTextHash?: string;\n\treadonly targetTokenBucket?: number;\n\treadonly verification?: ContextBudgetMaterializedVerificationV2;\n\treadonly createdAtEpochMs?: number;\n}\n\nexport interface ContextBudgetRepresentationCacheReadV2 {\n\treadonly entry: ContextBudgetRepresentationCacheEntryV2;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetNegativeCacheEntryV2 {\n\treadonly reason: string;\n\treadonly createdAtEpochMs?: number;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetPlanCacheEntryV2 {\n\treadonly plan: PromptContextBudgetPlanV2;\n\treadonly sourceHashes: Readonly<Record<string, string>>;\n\treadonly createdAtEpochMs?: number;\n}\n\nexport interface ContextBudgetPlanCacheReadV2 {\n\treadonly entry: ContextBudgetPlanCacheEntryV2;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetCacheProviderV2 {\n\tgetInvalidationSnapshot?(): ContextCacheInvalidationSnapshot | undefined;\n\tsetInvalidationSnapshot?(snapshot: ContextCacheInvalidationSnapshot): void;\n\treadRepresentation(key: string): ContextBudgetRepresentationCacheReadV2 | undefined;\n\twriteRepresentation(input: { readonly key: string; readonly entry: ContextBudgetRepresentationCacheEntryV2 }): void;\n\tdeleteRepresentation?(key: string): void;\n\treadNegativeRepresentation(key: string): ContextBudgetNegativeCacheEntryV2 | undefined;\n\twriteNegativeRepresentation(input: { readonly key: string; readonly reason: string }): void;\n\tdeleteNegativeRepresentation?(key: string): void;\n\treadPlan(key: string): ContextBudgetPlanCacheReadV2 | undefined;\n\twritePlan(input: { readonly key: string; readonly entry: ContextBudgetPlanCacheEntryV2 }): void;\n\tdeletePlan?(key: string): void;\n}\n\nexport interface ContextBudgetPlanCacheTelemetryV2 {\n\treadonly hit: boolean;\n\treadonly key: string;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n\treadonly rejectedReason?: string;\n}\n\nexport interface ContextBudgetRepresentationCacheTelemetryV2 {\n\treadonly exactHits: number;\n\treadonly semanticHits: number;\n\treadonly pointerHits: number;\n\treadonly misses: number;\n\treadonly staleRejects: number;\n\treadonly poisonRejects: number;\n\treadonly negativeHits: number;\n\treadonly writes: number;\n}\n\nexport interface ContextBudgetCacheTokenTelemetryV2 {\n\treadonly raw: number;\n\treadonly rendered: number;\n\treadonly savedByCache: number;\n\treadonly savedByCompression: number;\n\treadonly savedByOmission: number;\n}\n\nexport interface TokenCacheTelemetryV2 {\n\treadonly planCache: ContextBudgetPlanCacheTelemetryV2;\n\treadonly representationCache: ContextBudgetRepresentationCacheTelemetryV2;\n\treadonly tokens: ContextBudgetCacheTokenTelemetryV2;\n}\n\nexport interface PromptContextBudgetObservabilityV2 {\n\treadonly counts: ContextBudgetObservabilityCountsV2;\n\treadonly diagnosticReasons: readonly QualityDiagnosticReasonV2[];\n\treadonly tokens: ContextBudgetObservabilityTokensV2;\n\treadonly planHash: string;\n\treadonly cache: TokenCacheTelemetryV2;\n\treadonly tokenOptimizer: TokenOptimizerRuntimeStatus;\n}\n\nexport interface PromptContextBudgetPlanV2 {\n\treadonly policyVersion: string;\n\treadonly promptHash?: string;\n\treadonly planHash: string;\n\treadonly maxTokens: number;\n\treadonly responseReserveTokens: number;\n\treadonly safetyMarginTokens: number;\n\treadonly availableTokens: number;\n\treadonly usedTokens: number;\n\treadonly omittedTokens: number;\n\treadonly rawTokens: number;\n\treadonly tokenSavingsRatio: number;\n\treadonly emergency: boolean;\n\treadonly omittedHighPriority: boolean;\n\treadonly tierAllocations: readonly TierBudgetAllocationV2[];\n\treadonly selectedRepresentations: readonly SelectedRepresentationV2[];\n\treadonly includedItemIds: readonly string[];\n\treadonly omittedItemIds: readonly string[];\n\treadonly diagnostics: readonly QualityDiagnosticV2[];\n\treadonly retrievalFallbacks: readonly ContextSourceRefV2[];\n\treadonly observability: PromptContextBudgetObservabilityV2;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"context-budget-v2-types.d.ts","sourceRoot":"","sources":["../../src/core/context-budget-v2-types.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tContextBudgetItemV2,\n\tContextBudgetTierV2,\n\tContextRepresentationCacheMetadataV2,\n\tContextRepresentationCandidateV2,\n\tContextRepresentationKindV2,\n\tContextSourceRefV2,\n\tHeadroomQualityPolicyV2,\n} from \"./context-budget-headroom.ts\";\nimport type { TokenCounterAdapter } from \"./context-budget-token-counter.ts\";\nimport type { ContextCacheInvalidationSnapshot } from \"./context-budget-v2-cache-invalidation.ts\";\n\n/**\n * Public optimizer identifier. It is reported in the system prompt and used as a\n * cache namespace, so it must stay stable across internal policy changes.\n */\nexport const CONTEXT_BUDGET_POLICY_VERSION_V2 = \"context-budget-v2\";\n\n/**\n * Internal token for the optional-item selection policy, kept separate from the\n * public identifier so a scoring or ordering change can invalidate cached plans\n * without renaming the optimizer. Bump it whenever the selected set can differ\n * for identical inputs; otherwise plans built under the previous policy keep\n * being served for the whole cache TTL, including from disk.\n *\n * `sel-2`: density-ordered selection over the cheapest admissible representation\n * (previously priority-class-ordered over full-text tokens).\n */\nexport const CONTEXT_BUDGET_SELECTION_POLICY_V2 = \"sel-2\";\n\n/** Fixed compatibility telemetry for the removed legacy token optimizer. */\nexport interface TokenOptimizerRuntimeStatus {\n\treadonly optimizerId: \"legacy-token-optimizer\";\n\treadonly status: \"quarantined_compatibility\";\n\treadonly active: false;\n\treadonly activeContextBudgetOptimizer: \"context-budget-v2\";\n\treadonly compatibilityOnly: true;\n}\n\nexport interface TierBudgetPolicyV2 {\n\treadonly floorPct: number;\n\treadonly ceilingPct: number;\n}\n\nexport const DEFAULT_TIER_POLICY_V2: Readonly<Record<ContextBudgetTierV2, TierBudgetPolicyV2>> = {\n\tsystem: { floorPct: 0.25, ceilingPct: 0.45 },\n\t\"active-goal\": { floorPct: 0.1, ceilingPct: 0.25 },\n\t\"current-files\": { floorPct: 0.08, ceilingPct: 0.2 },\n\ttools: { floorPct: 0.04, ceilingPct: 0.12 },\n\tskills: { floorPct: 0.03, ceilingPct: 0.12 },\n\tmcp: { floorPct: 0.02, ceilingPct: 0.08 },\n\thistory: { floorPct: 0.1, ceilingPct: 0.3 },\n\tevidence: { floorPct: 0.08, ceilingPct: 0.25 },\n\tscratch: { floorPct: 0, ceilingPct: 0.05 },\n};\n\nexport const ALL_TIERS_V2: readonly ContextBudgetTierV2[] = [\n\t\"system\",\n\t\"active-goal\",\n\t\"current-files\",\n\t\"tools\",\n\t\"skills\",\n\t\"mcp\",\n\t\"history\",\n\t\"evidence\",\n\t\"scratch\",\n];\n\nexport interface PromptContextBudgetInputV2 {\n\treadonly maxTokens: number;\n\treadonly responseReserveTokens?: number;\n\treadonly safetyMarginTokens?: number;\n\treadonly modelId?: string;\n\treadonly tokenizerId?: string;\n\treadonly policyVersion?: string;\n\t/** Overrides {@link CONTEXT_BUDGET_SELECTION_POLICY_V2}. */\n\treadonly selectionPolicyVersion?: string;\n\treadonly promptHash?: string;\n\treadonly query?: string;\n\treadonly items: readonly ContextBudgetItemV2[];\n\treadonly tokenCounter?: TokenCounterAdapter;\n\treadonly tierPolicy?: Partial<Record<ContextBudgetTierV2, TierBudgetPolicyV2>>;\n\treadonly qualityPolicy?: HeadroomQualityPolicyV2;\n\treadonly cacheProvider?: ContextBudgetCacheProviderV2;\n\treadonly cacheNamespace?: string;\n\treadonly queryIntentHash?: string;\n\treadonly cacheBudgetBucket?: string;\n\treadonly redactionPolicyHash?: string;\n\treadonly safetyProfileHash?: string;\n\treadonly cacheNowEpochMs?: number;\n\treadonly cacheTtlMs?: number;\n\treadonly cacheInvalidationSnapshot?: ContextCacheInvalidationSnapshot;\n}\n\nexport interface SelectedRepresentationV2 {\n\treadonly itemId: string;\n\treadonly kind: ContextRepresentationKindV2;\n\treadonly text: string;\n\treadonly estimatedTokens: number;\n\treadonly fidelity: ContextRepresentationCandidateV2[\"fidelity\"];\n\treadonly sourceRef?: ContextSourceRefV2;\n\treadonly summaryHash?: string;\n\treadonly compressorId?: string;\n\treadonly cache?: ContextRepresentationCacheMetadataV2;\n}\n\nexport interface TierBudgetAllocationV2 {\n\treadonly tier: ContextBudgetTierV2;\n\treadonly floorTokens: number;\n\treadonly ceilingTokens: number;\n\treadonly allocatedTokens: number;\n\treadonly usedTokens: number;\n\treadonly hardTokens: number;\n}\n\nexport type QualityDiagnosticReasonV2 =\n\t| \"omitted_high_priority\"\n\t| \"retrieval_miss_risk\"\n\t| \"restore_on_demand_hint\"\n\t| \"hard_pin_over_capacity\"\n\t| \"coverage_gap\"\n\t| \"tier_ceiling_exceeded\"\n\t| \"invalid_budget\";\n\nexport interface QualityDiagnosticV2 {\n\treadonly reason: QualityDiagnosticReasonV2;\n\treadonly itemId?: string;\n\treadonly detail: string;\n}\n\nexport interface ContextBudgetObservabilityCountsV2 {\n\treadonly selected: number;\n\treadonly omitted: number;\n\treadonly pointer: number;\n\treadonly compressed: number;\n\treadonly full: number;\n\treadonly retrievalFallback: number;\n}\n\nexport interface ContextBudgetObservabilityTokensV2 {\n\treadonly available: number;\n\treadonly used: number;\n\treadonly raw: number;\n\treadonly omitted: number;\n\treadonly tokenSavings: number;\n}\n\nexport type ContextBudgetCacheLayerV2 = \"turn\" | \"session\" | \"workspace\" | \"shared\";\n\nexport type ContextBudgetRepresentationCacheRejectReasonV2 =\n\t| \"fingerprint_mismatch\"\n\t| \"kind_mismatch\"\n\t| \"model_mismatch\"\n\t| \"negative\"\n\t| \"policy_mismatch\"\n\t| \"poisoned\"\n\t| \"source_hash_mismatch\"\n\t| \"stale\"\n\t| \"token_invalid\"\n\t| \"tokenizer_mismatch\";\n\nexport type ContextBudgetRepresentationCacheKeyKindV2 = \"exact\" | \"materialized\";\n\nexport interface ContextBudgetMaterializedVerificationV2 {\n\treadonly queryCoverage?: number;\n\treadonly sourceCoverage?: number;\n\treadonly secretLeakScore?: number;\n\treadonly poisonScore?: number;\n\treadonly validatorVersion?: string;\n}\n\nexport interface ContextBudgetRepresentationCacheEntryV2 {\n\treadonly kind: ContextRepresentationKindV2;\n\treadonly text: string;\n\treadonly estimatedTokens: number;\n\treadonly fidelity: ContextRepresentationCandidateV2[\"fidelity\"];\n\treadonly sourceHash: string;\n\treadonly representationFingerprint: string;\n\treadonly keyKind?: ContextBudgetRepresentationCacheKeyKindV2;\n\treadonly modelId: string;\n\treadonly tokenizerId: string;\n\treadonly policyVersion: string;\n\treadonly sourceRef?: ContextSourceRefV2;\n\treadonly summaryHash?: string;\n\treadonly compressorId?: string;\n\treadonly compressorPolicyHash?: string;\n\treadonly qualityPolicyHash?: string;\n\treadonly queryIntentCluster?: string;\n\treadonly outputTextHash?: string;\n\treadonly targetTokenBucket?: number;\n\treadonly verification?: ContextBudgetMaterializedVerificationV2;\n\treadonly createdAtEpochMs?: number;\n}\n\nexport interface ContextBudgetRepresentationCacheReadV2 {\n\treadonly entry: ContextBudgetRepresentationCacheEntryV2;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetNegativeCacheEntryV2 {\n\treadonly reason: string;\n\treadonly createdAtEpochMs?: number;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetPlanCacheEntryV2 {\n\treadonly plan: PromptContextBudgetPlanV2;\n\treadonly sourceHashes: Readonly<Record<string, string>>;\n\treadonly createdAtEpochMs?: number;\n}\n\nexport interface ContextBudgetPlanCacheReadV2 {\n\treadonly entry: ContextBudgetPlanCacheEntryV2;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetCacheProviderV2 {\n\tgetInvalidationSnapshot?(): ContextCacheInvalidationSnapshot | undefined;\n\tsetInvalidationSnapshot?(snapshot: ContextCacheInvalidationSnapshot): void;\n\treadRepresentation(key: string): ContextBudgetRepresentationCacheReadV2 | undefined;\n\twriteRepresentation(input: { readonly key: string; readonly entry: ContextBudgetRepresentationCacheEntryV2 }): void;\n\tdeleteRepresentation?(key: string): void;\n\treadNegativeRepresentation(key: string): ContextBudgetNegativeCacheEntryV2 | undefined;\n\twriteNegativeRepresentation(input: { readonly key: string; readonly reason: string }): void;\n\tdeleteNegativeRepresentation?(key: string): void;\n\treadPlan(key: string): ContextBudgetPlanCacheReadV2 | undefined;\n\twritePlan(input: { readonly key: string; readonly entry: ContextBudgetPlanCacheEntryV2 }): void;\n\tdeletePlan?(key: string): void;\n}\n\nexport interface ContextBudgetPlanCacheTelemetryV2 {\n\treadonly hit: boolean;\n\treadonly key: string;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n\treadonly rejectedReason?: string;\n}\n\nexport interface ContextBudgetRepresentationCacheTelemetryV2 {\n\treadonly exactHits: number;\n\treadonly semanticHits: number;\n\treadonly pointerHits: number;\n\treadonly misses: number;\n\treadonly staleRejects: number;\n\treadonly poisonRejects: number;\n\treadonly negativeHits: number;\n\treadonly writes: number;\n}\n\nexport interface ContextBudgetCacheTokenTelemetryV2 {\n\treadonly raw: number;\n\treadonly rendered: number;\n\treadonly savedByCache: number;\n\treadonly savedByCompression: number;\n\treadonly savedByOmission: number;\n}\n\nexport interface TokenCacheTelemetryV2 {\n\treadonly planCache: ContextBudgetPlanCacheTelemetryV2;\n\treadonly representationCache: ContextBudgetRepresentationCacheTelemetryV2;\n\treadonly tokens: ContextBudgetCacheTokenTelemetryV2;\n}\n\nexport interface PromptContextBudgetObservabilityV2 {\n\treadonly counts: ContextBudgetObservabilityCountsV2;\n\treadonly diagnosticReasons: readonly QualityDiagnosticReasonV2[];\n\treadonly tokens: ContextBudgetObservabilityTokensV2;\n\treadonly planHash: string;\n\treadonly cache: TokenCacheTelemetryV2;\n\treadonly tokenOptimizer: TokenOptimizerRuntimeStatus;\n}\n\nexport interface PromptContextBudgetPlanV2 {\n\treadonly policyVersion: string;\n\treadonly promptHash?: string;\n\treadonly planHash: string;\n\treadonly maxTokens: number;\n\treadonly responseReserveTokens: number;\n\treadonly safetyMarginTokens: number;\n\treadonly availableTokens: number;\n\treadonly usedTokens: number;\n\treadonly omittedTokens: number;\n\treadonly rawTokens: number;\n\treadonly tokenSavingsRatio: number;\n\treadonly emergency: boolean;\n\treadonly omittedHighPriority: boolean;\n\treadonly tierAllocations: readonly TierBudgetAllocationV2[];\n\treadonly selectedRepresentations: readonly SelectedRepresentationV2[];\n\treadonly includedItemIds: readonly string[];\n\treadonly omittedItemIds: readonly string[];\n\treadonly diagnostics: readonly QualityDiagnosticV2[];\n\treadonly retrievalFallbacks: readonly ContextSourceRefV2[];\n\treadonly observability: PromptContextBudgetObservabilityV2;\n}\n"]}
|
|
@@ -1,4 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public optimizer identifier. It is reported in the system prompt and used as a
|
|
3
|
+
* cache namespace, so it must stay stable across internal policy changes.
|
|
4
|
+
*/
|
|
1
5
|
export const CONTEXT_BUDGET_POLICY_VERSION_V2 = "context-budget-v2";
|
|
6
|
+
/**
|
|
7
|
+
* Internal token for the optional-item selection policy, kept separate from the
|
|
8
|
+
* public identifier so a scoring or ordering change can invalidate cached plans
|
|
9
|
+
* without renaming the optimizer. Bump it whenever the selected set can differ
|
|
10
|
+
* for identical inputs; otherwise plans built under the previous policy keep
|
|
11
|
+
* being served for the whole cache TTL, including from disk.
|
|
12
|
+
*
|
|
13
|
+
* `sel-2`: density-ordered selection over the cheapest admissible representation
|
|
14
|
+
* (previously priority-class-ordered over full-text tokens).
|
|
15
|
+
*/
|
|
16
|
+
export const CONTEXT_BUDGET_SELECTION_POLICY_V2 = "sel-2";
|
|
2
17
|
export const DEFAULT_TIER_POLICY_V2 = {
|
|
3
18
|
system: { floorPct: 0.25, ceilingPct: 0.45 },
|
|
4
19
|
"active-goal": { floorPct: 0.1, ceilingPct: 0.25 },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-budget-v2-types.js","sourceRoot":"","sources":["../../src/core/context-budget-v2-types.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,gCAAgC,GAAG,mBAAmB,CAAC;AAgBpE,MAAM,CAAC,MAAM,sBAAsB,GAA8D;IAChG,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IAC5C,aAAa,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE;IAClD,eAAe,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE;IACpD,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IAC3C,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IAC5C,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IACzC,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE;IAC3C,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IAC9C,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE;CAC1C,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAmC;IAC3D,QAAQ;IACR,aAAa;IACb,eAAe;IACf,OAAO;IACP,QAAQ;IACR,KAAK;IACL,SAAS;IACT,UAAU;IACV,SAAS;CACT,CAAC","sourcesContent":["import type {\n\tContextBudgetItemV2,\n\tContextBudgetTierV2,\n\tContextRepresentationCacheMetadataV2,\n\tContextRepresentationCandidateV2,\n\tContextRepresentationKindV2,\n\tContextSourceRefV2,\n\tHeadroomQualityPolicyV2,\n} from \"./context-budget-headroom.ts\";\nimport type { TokenCounterAdapter } from \"./context-budget-token-counter.ts\";\nimport type { ContextCacheInvalidationSnapshot } from \"./context-budget-v2-cache-invalidation.ts\";\n\nexport const CONTEXT_BUDGET_POLICY_VERSION_V2 = \"context-budget-v2\";\n\n/** Fixed compatibility telemetry for the removed legacy token optimizer. */\nexport interface TokenOptimizerRuntimeStatus {\n\treadonly optimizerId: \"legacy-token-optimizer\";\n\treadonly status: \"quarantined_compatibility\";\n\treadonly active: false;\n\treadonly activeContextBudgetOptimizer: \"context-budget-v2\";\n\treadonly compatibilityOnly: true;\n}\n\nexport interface TierBudgetPolicyV2 {\n\treadonly floorPct: number;\n\treadonly ceilingPct: number;\n}\n\nexport const DEFAULT_TIER_POLICY_V2: Readonly<Record<ContextBudgetTierV2, TierBudgetPolicyV2>> = {\n\tsystem: { floorPct: 0.25, ceilingPct: 0.45 },\n\t\"active-goal\": { floorPct: 0.1, ceilingPct: 0.25 },\n\t\"current-files\": { floorPct: 0.08, ceilingPct: 0.2 },\n\ttools: { floorPct: 0.04, ceilingPct: 0.12 },\n\tskills: { floorPct: 0.03, ceilingPct: 0.12 },\n\tmcp: { floorPct: 0.02, ceilingPct: 0.08 },\n\thistory: { floorPct: 0.1, ceilingPct: 0.3 },\n\tevidence: { floorPct: 0.08, ceilingPct: 0.25 },\n\tscratch: { floorPct: 0, ceilingPct: 0.05 },\n};\n\nexport const ALL_TIERS_V2: readonly ContextBudgetTierV2[] = [\n\t\"system\",\n\t\"active-goal\",\n\t\"current-files\",\n\t\"tools\",\n\t\"skills\",\n\t\"mcp\",\n\t\"history\",\n\t\"evidence\",\n\t\"scratch\",\n];\n\nexport interface PromptContextBudgetInputV2 {\n\treadonly maxTokens: number;\n\treadonly responseReserveTokens?: number;\n\treadonly safetyMarginTokens?: number;\n\treadonly modelId?: string;\n\treadonly tokenizerId?: string;\n\treadonly policyVersion?: string;\n\treadonly promptHash?: string;\n\treadonly query?: string;\n\treadonly items: readonly ContextBudgetItemV2[];\n\treadonly tokenCounter?: TokenCounterAdapter;\n\treadonly tierPolicy?: Partial<Record<ContextBudgetTierV2, TierBudgetPolicyV2>>;\n\treadonly qualityPolicy?: HeadroomQualityPolicyV2;\n\treadonly cacheProvider?: ContextBudgetCacheProviderV2;\n\treadonly cacheNamespace?: string;\n\treadonly queryIntentHash?: string;\n\treadonly cacheBudgetBucket?: string;\n\treadonly redactionPolicyHash?: string;\n\treadonly safetyProfileHash?: string;\n\treadonly cacheNowEpochMs?: number;\n\treadonly cacheTtlMs?: number;\n\treadonly cacheInvalidationSnapshot?: ContextCacheInvalidationSnapshot;\n}\n\nexport interface SelectedRepresentationV2 {\n\treadonly itemId: string;\n\treadonly kind: ContextRepresentationKindV2;\n\treadonly text: string;\n\treadonly estimatedTokens: number;\n\treadonly fidelity: ContextRepresentationCandidateV2[\"fidelity\"];\n\treadonly sourceRef?: ContextSourceRefV2;\n\treadonly summaryHash?: string;\n\treadonly compressorId?: string;\n\treadonly cache?: ContextRepresentationCacheMetadataV2;\n}\n\nexport interface TierBudgetAllocationV2 {\n\treadonly tier: ContextBudgetTierV2;\n\treadonly floorTokens: number;\n\treadonly ceilingTokens: number;\n\treadonly allocatedTokens: number;\n\treadonly usedTokens: number;\n\treadonly hardTokens: number;\n}\n\nexport type QualityDiagnosticReasonV2 =\n\t| \"omitted_high_priority\"\n\t| \"retrieval_miss_risk\"\n\t| \"restore_on_demand_hint\"\n\t| \"hard_pin_over_capacity\"\n\t| \"coverage_gap\"\n\t| \"tier_ceiling_exceeded\"\n\t| \"invalid_budget\";\n\nexport interface QualityDiagnosticV2 {\n\treadonly reason: QualityDiagnosticReasonV2;\n\treadonly itemId?: string;\n\treadonly detail: string;\n}\n\nexport interface ContextBudgetObservabilityCountsV2 {\n\treadonly selected: number;\n\treadonly omitted: number;\n\treadonly pointer: number;\n\treadonly compressed: number;\n\treadonly full: number;\n\treadonly retrievalFallback: number;\n}\n\nexport interface ContextBudgetObservabilityTokensV2 {\n\treadonly available: number;\n\treadonly used: number;\n\treadonly raw: number;\n\treadonly omitted: number;\n\treadonly tokenSavings: number;\n}\n\nexport type ContextBudgetCacheLayerV2 = \"turn\" | \"session\" | \"workspace\" | \"shared\";\n\nexport type ContextBudgetRepresentationCacheRejectReasonV2 =\n\t| \"fingerprint_mismatch\"\n\t| \"kind_mismatch\"\n\t| \"model_mismatch\"\n\t| \"negative\"\n\t| \"policy_mismatch\"\n\t| \"poisoned\"\n\t| \"source_hash_mismatch\"\n\t| \"stale\"\n\t| \"token_invalid\"\n\t| \"tokenizer_mismatch\";\n\nexport type ContextBudgetRepresentationCacheKeyKindV2 = \"exact\" | \"materialized\";\n\nexport interface ContextBudgetMaterializedVerificationV2 {\n\treadonly queryCoverage?: number;\n\treadonly sourceCoverage?: number;\n\treadonly secretLeakScore?: number;\n\treadonly poisonScore?: number;\n\treadonly validatorVersion?: string;\n}\n\nexport interface ContextBudgetRepresentationCacheEntryV2 {\n\treadonly kind: ContextRepresentationKindV2;\n\treadonly text: string;\n\treadonly estimatedTokens: number;\n\treadonly fidelity: ContextRepresentationCandidateV2[\"fidelity\"];\n\treadonly sourceHash: string;\n\treadonly representationFingerprint: string;\n\treadonly keyKind?: ContextBudgetRepresentationCacheKeyKindV2;\n\treadonly modelId: string;\n\treadonly tokenizerId: string;\n\treadonly policyVersion: string;\n\treadonly sourceRef?: ContextSourceRefV2;\n\treadonly summaryHash?: string;\n\treadonly compressorId?: string;\n\treadonly compressorPolicyHash?: string;\n\treadonly qualityPolicyHash?: string;\n\treadonly queryIntentCluster?: string;\n\treadonly outputTextHash?: string;\n\treadonly targetTokenBucket?: number;\n\treadonly verification?: ContextBudgetMaterializedVerificationV2;\n\treadonly createdAtEpochMs?: number;\n}\n\nexport interface ContextBudgetRepresentationCacheReadV2 {\n\treadonly entry: ContextBudgetRepresentationCacheEntryV2;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetNegativeCacheEntryV2 {\n\treadonly reason: string;\n\treadonly createdAtEpochMs?: number;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetPlanCacheEntryV2 {\n\treadonly plan: PromptContextBudgetPlanV2;\n\treadonly sourceHashes: Readonly<Record<string, string>>;\n\treadonly createdAtEpochMs?: number;\n}\n\nexport interface ContextBudgetPlanCacheReadV2 {\n\treadonly entry: ContextBudgetPlanCacheEntryV2;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetCacheProviderV2 {\n\tgetInvalidationSnapshot?(): ContextCacheInvalidationSnapshot | undefined;\n\tsetInvalidationSnapshot?(snapshot: ContextCacheInvalidationSnapshot): void;\n\treadRepresentation(key: string): ContextBudgetRepresentationCacheReadV2 | undefined;\n\twriteRepresentation(input: { readonly key: string; readonly entry: ContextBudgetRepresentationCacheEntryV2 }): void;\n\tdeleteRepresentation?(key: string): void;\n\treadNegativeRepresentation(key: string): ContextBudgetNegativeCacheEntryV2 | undefined;\n\twriteNegativeRepresentation(input: { readonly key: string; readonly reason: string }): void;\n\tdeleteNegativeRepresentation?(key: string): void;\n\treadPlan(key: string): ContextBudgetPlanCacheReadV2 | undefined;\n\twritePlan(input: { readonly key: string; readonly entry: ContextBudgetPlanCacheEntryV2 }): void;\n\tdeletePlan?(key: string): void;\n}\n\nexport interface ContextBudgetPlanCacheTelemetryV2 {\n\treadonly hit: boolean;\n\treadonly key: string;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n\treadonly rejectedReason?: string;\n}\n\nexport interface ContextBudgetRepresentationCacheTelemetryV2 {\n\treadonly exactHits: number;\n\treadonly semanticHits: number;\n\treadonly pointerHits: number;\n\treadonly misses: number;\n\treadonly staleRejects: number;\n\treadonly poisonRejects: number;\n\treadonly negativeHits: number;\n\treadonly writes: number;\n}\n\nexport interface ContextBudgetCacheTokenTelemetryV2 {\n\treadonly raw: number;\n\treadonly rendered: number;\n\treadonly savedByCache: number;\n\treadonly savedByCompression: number;\n\treadonly savedByOmission: number;\n}\n\nexport interface TokenCacheTelemetryV2 {\n\treadonly planCache: ContextBudgetPlanCacheTelemetryV2;\n\treadonly representationCache: ContextBudgetRepresentationCacheTelemetryV2;\n\treadonly tokens: ContextBudgetCacheTokenTelemetryV2;\n}\n\nexport interface PromptContextBudgetObservabilityV2 {\n\treadonly counts: ContextBudgetObservabilityCountsV2;\n\treadonly diagnosticReasons: readonly QualityDiagnosticReasonV2[];\n\treadonly tokens: ContextBudgetObservabilityTokensV2;\n\treadonly planHash: string;\n\treadonly cache: TokenCacheTelemetryV2;\n\treadonly tokenOptimizer: TokenOptimizerRuntimeStatus;\n}\n\nexport interface PromptContextBudgetPlanV2 {\n\treadonly policyVersion: string;\n\treadonly promptHash?: string;\n\treadonly planHash: string;\n\treadonly maxTokens: number;\n\treadonly responseReserveTokens: number;\n\treadonly safetyMarginTokens: number;\n\treadonly availableTokens: number;\n\treadonly usedTokens: number;\n\treadonly omittedTokens: number;\n\treadonly rawTokens: number;\n\treadonly tokenSavingsRatio: number;\n\treadonly emergency: boolean;\n\treadonly omittedHighPriority: boolean;\n\treadonly tierAllocations: readonly TierBudgetAllocationV2[];\n\treadonly selectedRepresentations: readonly SelectedRepresentationV2[];\n\treadonly includedItemIds: readonly string[];\n\treadonly omittedItemIds: readonly string[];\n\treadonly diagnostics: readonly QualityDiagnosticV2[];\n\treadonly retrievalFallbacks: readonly ContextSourceRefV2[];\n\treadonly observability: PromptContextBudgetObservabilityV2;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"context-budget-v2-types.js","sourceRoot":"","sources":["../../src/core/context-budget-v2-types.ts"],"names":[],"mappings":"AAYA;;;GAGG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,mBAAmB,CAAC;AAEpE;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,OAAO,CAAC;AAgB1D,MAAM,CAAC,MAAM,sBAAsB,GAA8D;IAChG,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IAC5C,aAAa,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE;IAClD,eAAe,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE;IACpD,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IAC3C,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IAC5C,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IACzC,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE;IAC3C,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IAC9C,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE;CAC1C,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAmC;IAC3D,QAAQ;IACR,aAAa;IACb,eAAe;IACf,OAAO;IACP,QAAQ;IACR,KAAK;IACL,SAAS;IACT,UAAU;IACV,SAAS;CACT,CAAC","sourcesContent":["import type {\n\tContextBudgetItemV2,\n\tContextBudgetTierV2,\n\tContextRepresentationCacheMetadataV2,\n\tContextRepresentationCandidateV2,\n\tContextRepresentationKindV2,\n\tContextSourceRefV2,\n\tHeadroomQualityPolicyV2,\n} from \"./context-budget-headroom.ts\";\nimport type { TokenCounterAdapter } from \"./context-budget-token-counter.ts\";\nimport type { ContextCacheInvalidationSnapshot } from \"./context-budget-v2-cache-invalidation.ts\";\n\n/**\n * Public optimizer identifier. It is reported in the system prompt and used as a\n * cache namespace, so it must stay stable across internal policy changes.\n */\nexport const CONTEXT_BUDGET_POLICY_VERSION_V2 = \"context-budget-v2\";\n\n/**\n * Internal token for the optional-item selection policy, kept separate from the\n * public identifier so a scoring or ordering change can invalidate cached plans\n * without renaming the optimizer. Bump it whenever the selected set can differ\n * for identical inputs; otherwise plans built under the previous policy keep\n * being served for the whole cache TTL, including from disk.\n *\n * `sel-2`: density-ordered selection over the cheapest admissible representation\n * (previously priority-class-ordered over full-text tokens).\n */\nexport const CONTEXT_BUDGET_SELECTION_POLICY_V2 = \"sel-2\";\n\n/** Fixed compatibility telemetry for the removed legacy token optimizer. */\nexport interface TokenOptimizerRuntimeStatus {\n\treadonly optimizerId: \"legacy-token-optimizer\";\n\treadonly status: \"quarantined_compatibility\";\n\treadonly active: false;\n\treadonly activeContextBudgetOptimizer: \"context-budget-v2\";\n\treadonly compatibilityOnly: true;\n}\n\nexport interface TierBudgetPolicyV2 {\n\treadonly floorPct: number;\n\treadonly ceilingPct: number;\n}\n\nexport const DEFAULT_TIER_POLICY_V2: Readonly<Record<ContextBudgetTierV2, TierBudgetPolicyV2>> = {\n\tsystem: { floorPct: 0.25, ceilingPct: 0.45 },\n\t\"active-goal\": { floorPct: 0.1, ceilingPct: 0.25 },\n\t\"current-files\": { floorPct: 0.08, ceilingPct: 0.2 },\n\ttools: { floorPct: 0.04, ceilingPct: 0.12 },\n\tskills: { floorPct: 0.03, ceilingPct: 0.12 },\n\tmcp: { floorPct: 0.02, ceilingPct: 0.08 },\n\thistory: { floorPct: 0.1, ceilingPct: 0.3 },\n\tevidence: { floorPct: 0.08, ceilingPct: 0.25 },\n\tscratch: { floorPct: 0, ceilingPct: 0.05 },\n};\n\nexport const ALL_TIERS_V2: readonly ContextBudgetTierV2[] = [\n\t\"system\",\n\t\"active-goal\",\n\t\"current-files\",\n\t\"tools\",\n\t\"skills\",\n\t\"mcp\",\n\t\"history\",\n\t\"evidence\",\n\t\"scratch\",\n];\n\nexport interface PromptContextBudgetInputV2 {\n\treadonly maxTokens: number;\n\treadonly responseReserveTokens?: number;\n\treadonly safetyMarginTokens?: number;\n\treadonly modelId?: string;\n\treadonly tokenizerId?: string;\n\treadonly policyVersion?: string;\n\t/** Overrides {@link CONTEXT_BUDGET_SELECTION_POLICY_V2}. */\n\treadonly selectionPolicyVersion?: string;\n\treadonly promptHash?: string;\n\treadonly query?: string;\n\treadonly items: readonly ContextBudgetItemV2[];\n\treadonly tokenCounter?: TokenCounterAdapter;\n\treadonly tierPolicy?: Partial<Record<ContextBudgetTierV2, TierBudgetPolicyV2>>;\n\treadonly qualityPolicy?: HeadroomQualityPolicyV2;\n\treadonly cacheProvider?: ContextBudgetCacheProviderV2;\n\treadonly cacheNamespace?: string;\n\treadonly queryIntentHash?: string;\n\treadonly cacheBudgetBucket?: string;\n\treadonly redactionPolicyHash?: string;\n\treadonly safetyProfileHash?: string;\n\treadonly cacheNowEpochMs?: number;\n\treadonly cacheTtlMs?: number;\n\treadonly cacheInvalidationSnapshot?: ContextCacheInvalidationSnapshot;\n}\n\nexport interface SelectedRepresentationV2 {\n\treadonly itemId: string;\n\treadonly kind: ContextRepresentationKindV2;\n\treadonly text: string;\n\treadonly estimatedTokens: number;\n\treadonly fidelity: ContextRepresentationCandidateV2[\"fidelity\"];\n\treadonly sourceRef?: ContextSourceRefV2;\n\treadonly summaryHash?: string;\n\treadonly compressorId?: string;\n\treadonly cache?: ContextRepresentationCacheMetadataV2;\n}\n\nexport interface TierBudgetAllocationV2 {\n\treadonly tier: ContextBudgetTierV2;\n\treadonly floorTokens: number;\n\treadonly ceilingTokens: number;\n\treadonly allocatedTokens: number;\n\treadonly usedTokens: number;\n\treadonly hardTokens: number;\n}\n\nexport type QualityDiagnosticReasonV2 =\n\t| \"omitted_high_priority\"\n\t| \"retrieval_miss_risk\"\n\t| \"restore_on_demand_hint\"\n\t| \"hard_pin_over_capacity\"\n\t| \"coverage_gap\"\n\t| \"tier_ceiling_exceeded\"\n\t| \"invalid_budget\";\n\nexport interface QualityDiagnosticV2 {\n\treadonly reason: QualityDiagnosticReasonV2;\n\treadonly itemId?: string;\n\treadonly detail: string;\n}\n\nexport interface ContextBudgetObservabilityCountsV2 {\n\treadonly selected: number;\n\treadonly omitted: number;\n\treadonly pointer: number;\n\treadonly compressed: number;\n\treadonly full: number;\n\treadonly retrievalFallback: number;\n}\n\nexport interface ContextBudgetObservabilityTokensV2 {\n\treadonly available: number;\n\treadonly used: number;\n\treadonly raw: number;\n\treadonly omitted: number;\n\treadonly tokenSavings: number;\n}\n\nexport type ContextBudgetCacheLayerV2 = \"turn\" | \"session\" | \"workspace\" | \"shared\";\n\nexport type ContextBudgetRepresentationCacheRejectReasonV2 =\n\t| \"fingerprint_mismatch\"\n\t| \"kind_mismatch\"\n\t| \"model_mismatch\"\n\t| \"negative\"\n\t| \"policy_mismatch\"\n\t| \"poisoned\"\n\t| \"source_hash_mismatch\"\n\t| \"stale\"\n\t| \"token_invalid\"\n\t| \"tokenizer_mismatch\";\n\nexport type ContextBudgetRepresentationCacheKeyKindV2 = \"exact\" | \"materialized\";\n\nexport interface ContextBudgetMaterializedVerificationV2 {\n\treadonly queryCoverage?: number;\n\treadonly sourceCoverage?: number;\n\treadonly secretLeakScore?: number;\n\treadonly poisonScore?: number;\n\treadonly validatorVersion?: string;\n}\n\nexport interface ContextBudgetRepresentationCacheEntryV2 {\n\treadonly kind: ContextRepresentationKindV2;\n\treadonly text: string;\n\treadonly estimatedTokens: number;\n\treadonly fidelity: ContextRepresentationCandidateV2[\"fidelity\"];\n\treadonly sourceHash: string;\n\treadonly representationFingerprint: string;\n\treadonly keyKind?: ContextBudgetRepresentationCacheKeyKindV2;\n\treadonly modelId: string;\n\treadonly tokenizerId: string;\n\treadonly policyVersion: string;\n\treadonly sourceRef?: ContextSourceRefV2;\n\treadonly summaryHash?: string;\n\treadonly compressorId?: string;\n\treadonly compressorPolicyHash?: string;\n\treadonly qualityPolicyHash?: string;\n\treadonly queryIntentCluster?: string;\n\treadonly outputTextHash?: string;\n\treadonly targetTokenBucket?: number;\n\treadonly verification?: ContextBudgetMaterializedVerificationV2;\n\treadonly createdAtEpochMs?: number;\n}\n\nexport interface ContextBudgetRepresentationCacheReadV2 {\n\treadonly entry: ContextBudgetRepresentationCacheEntryV2;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetNegativeCacheEntryV2 {\n\treadonly reason: string;\n\treadonly createdAtEpochMs?: number;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetPlanCacheEntryV2 {\n\treadonly plan: PromptContextBudgetPlanV2;\n\treadonly sourceHashes: Readonly<Record<string, string>>;\n\treadonly createdAtEpochMs?: number;\n}\n\nexport interface ContextBudgetPlanCacheReadV2 {\n\treadonly entry: ContextBudgetPlanCacheEntryV2;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n}\n\nexport interface ContextBudgetCacheProviderV2 {\n\tgetInvalidationSnapshot?(): ContextCacheInvalidationSnapshot | undefined;\n\tsetInvalidationSnapshot?(snapshot: ContextCacheInvalidationSnapshot): void;\n\treadRepresentation(key: string): ContextBudgetRepresentationCacheReadV2 | undefined;\n\twriteRepresentation(input: { readonly key: string; readonly entry: ContextBudgetRepresentationCacheEntryV2 }): void;\n\tdeleteRepresentation?(key: string): void;\n\treadNegativeRepresentation(key: string): ContextBudgetNegativeCacheEntryV2 | undefined;\n\twriteNegativeRepresentation(input: { readonly key: string; readonly reason: string }): void;\n\tdeleteNegativeRepresentation?(key: string): void;\n\treadPlan(key: string): ContextBudgetPlanCacheReadV2 | undefined;\n\twritePlan(input: { readonly key: string; readonly entry: ContextBudgetPlanCacheEntryV2 }): void;\n\tdeletePlan?(key: string): void;\n}\n\nexport interface ContextBudgetPlanCacheTelemetryV2 {\n\treadonly hit: boolean;\n\treadonly key: string;\n\treadonly layer?: ContextBudgetCacheLayerV2;\n\treadonly rejectedReason?: string;\n}\n\nexport interface ContextBudgetRepresentationCacheTelemetryV2 {\n\treadonly exactHits: number;\n\treadonly semanticHits: number;\n\treadonly pointerHits: number;\n\treadonly misses: number;\n\treadonly staleRejects: number;\n\treadonly poisonRejects: number;\n\treadonly negativeHits: number;\n\treadonly writes: number;\n}\n\nexport interface ContextBudgetCacheTokenTelemetryV2 {\n\treadonly raw: number;\n\treadonly rendered: number;\n\treadonly savedByCache: number;\n\treadonly savedByCompression: number;\n\treadonly savedByOmission: number;\n}\n\nexport interface TokenCacheTelemetryV2 {\n\treadonly planCache: ContextBudgetPlanCacheTelemetryV2;\n\treadonly representationCache: ContextBudgetRepresentationCacheTelemetryV2;\n\treadonly tokens: ContextBudgetCacheTokenTelemetryV2;\n}\n\nexport interface PromptContextBudgetObservabilityV2 {\n\treadonly counts: ContextBudgetObservabilityCountsV2;\n\treadonly diagnosticReasons: readonly QualityDiagnosticReasonV2[];\n\treadonly tokens: ContextBudgetObservabilityTokensV2;\n\treadonly planHash: string;\n\treadonly cache: TokenCacheTelemetryV2;\n\treadonly tokenOptimizer: TokenOptimizerRuntimeStatus;\n}\n\nexport interface PromptContextBudgetPlanV2 {\n\treadonly policyVersion: string;\n\treadonly promptHash?: string;\n\treadonly planHash: string;\n\treadonly maxTokens: number;\n\treadonly responseReserveTokens: number;\n\treadonly safetyMarginTokens: number;\n\treadonly availableTokens: number;\n\treadonly usedTokens: number;\n\treadonly omittedTokens: number;\n\treadonly rawTokens: number;\n\treadonly tokenSavingsRatio: number;\n\treadonly emergency: boolean;\n\treadonly omittedHighPriority: boolean;\n\treadonly tierAllocations: readonly TierBudgetAllocationV2[];\n\treadonly selectedRepresentations: readonly SelectedRepresentationV2[];\n\treadonly includedItemIds: readonly string[];\n\treadonly omittedItemIds: readonly string[];\n\treadonly diagnostics: readonly QualityDiagnosticV2[];\n\treadonly retrievalFallbacks: readonly ContextSourceRefV2[];\n\treadonly observability: PromptContextBudgetObservabilityV2;\n}\n"]}
|
|
@@ -35,7 +35,7 @@ export interface CommandGateOptions {
|
|
|
35
35
|
confirm?: ConfirmFn;
|
|
36
36
|
/** Interactive policy for non-privilege `confirm`-tier verdicts. Defaults to "ask". */
|
|
37
37
|
interactiveConfirmPolicy?: "ask" | "allow";
|
|
38
|
-
/** Headless policy for `confirm`-tier verdicts. `priv.*` is never allowed. Defaults to "deny". */
|
|
38
|
+
/** Headless policy for `confirm`-tier verdicts. `priv.*` is never allowed outside YOLO. Defaults to "deny". */
|
|
39
39
|
headlessConfirmPolicy?: "deny" | "allow";
|
|
40
40
|
/** Extra substrings that promote allow/confirm verdicts to block. Never relaxes a block. */
|
|
41
41
|
extraDeny?: string[];
|
|
@@ -58,6 +58,8 @@ export declare function evaluateBashToolCall(command: string, extraDeny?: string
|
|
|
58
58
|
/**
|
|
59
59
|
* Shared gate decision for any bash command (LLM tool call, user bash, RPC bash).
|
|
60
60
|
*
|
|
61
|
+
* - YOLO => undefined (full disable: every verdict — block, confirm, priv.* —
|
|
62
|
+
* runs without prompting; see {@link isCommandSafetyDisabled}).
|
|
61
63
|
* - block => deny.
|
|
62
64
|
* - confirm => hasUI ? (approved ? undefined : deny) : (policy === "allow" && !priv ? undefined : deny).
|
|
63
65
|
* - allow => undefined (preserve later extensions / default execution).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-safety-gate.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/command-safety-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,KAAK,YAAY,EAAuB,MAAM,aAAa,CAAC;AAErE,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9D,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB;IAClC,iEAAiE;IACjE,KAAK,EAAE,OAAO,CAAC;IACf,mEAAmE;IACnE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,uFAAuF;IACvF,wBAAwB,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IAC3C,kGAAkG;IAClG,qBAAqB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzC,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,oEAAoE;AACpE,MAAM,MAAM,uBAAuB,GAAG,kBAAkB,CAAC;AAiCzD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAAE,GAClB;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAM7C;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACxC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,kBAAkB,GACtB,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,CA2BxD;AAED,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,4BAAsB,CAAC;AAEpD,wBAAgB,+BAA+B,CAC9C,GAAG,GAAE,MAAM,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GACjF,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACtC,GAAG,GAAE,MAAM,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GACjF,OAAO,CAOT;AASD,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAOjE;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CA4BjE","sourcesContent":["/**\n * Built-in command-safety gate extension.\n *\n * Wires the pure `classifyShellCommand` verdict engine into the live bash entry\n * points with one shared decision engine (`evaluateCommandGate`):\n * - LLM tool calls (`tool_call` for the `bash` tool) — block-tier verdicts stop\n * execution via `{ block, reason }`. confirm-tier verdicts prompt when a\n * dialog-capable UI is available and otherwise deny headlessly (parity with\n * user bash). `priv.*` is never auto-allowed.\n * - User `!`/`!!` bash (`user_bash`) — block/confirm verdicts produce a synthetic\n * FAILED `BashResult` instead of running the command.\n * - RPC bash routes through `AgentSession.executeBash({ safetyGate: \"headless\" })`\n * which reuses `evaluateCommandGate` and `buildBlockedBashResult` directly.\n *\n * Fail-closed contract:\n * - `user_bash` deny NEVER throws. A thrown `user_bash` handler is logged by the\n * runner and default execution continues (fail-open). Returning a synthetic\n * failed `result` short-circuits execution safely.\n * - `confirm`-tier verdicts deny by default when no interactive UI is available.\n * - `priv.*` verdicts are never headless-allowed.\n *\n * This gate reuses `command-safety.ts` read-only and adds no new classification\n * branches. `extraDeny` patterns can only promote allow/confirm to block; they\n * can never relax a block verdict.\n */\n\nimport type { BashResult } from \"../../bash-executor.ts\";\nimport { type CommandVerdict, classifyShellCommand } from \"../../command-safety.ts\";\nimport { type ExtensionAPI, isToolCallEventType } from \"../types.ts\";\n\n/** Confirmation callback. Returns true when the user approves execution. */\nexport type ConfirmFn = (message: string) => Promise<boolean>;\n\n/** Options controlling how a bash command is evaluated by the shared gate. */\nexport interface CommandGateOptions {\n\t/** Whether a dialog-capable UI is available for confirmation. */\n\thasUI: boolean;\n\t/** Interactive confirmation callback used when `hasUI` is true. */\n\tconfirm?: ConfirmFn;\n\t/** Interactive policy for non-privilege `confirm`-tier verdicts. Defaults to \"ask\". */\n\tinteractiveConfirmPolicy?: \"ask\" | \"allow\";\n\t/** Headless policy for `confirm`-tier verdicts. `priv.*` is never allowed. Defaults to \"deny\". */\n\theadlessConfirmPolicy?: \"deny\" | \"allow\";\n\t/** Extra substrings that promote allow/confirm verdicts to block. Never relaxes a block. */\n\textraDeny?: string[];\n}\n\n/** @deprecated Back-compat alias for {@link CommandGateOptions}. */\nexport type UserBashEvaluateOptions = CommandGateOptions;\n\nfunction formatReason(verdict: CommandVerdict): string {\n\treturn `[${verdict.rule}] ${verdict.reason}`;\n}\n\nfunction matchesExtraDeny(command: string, patterns: string[] | undefined): boolean {\n\tif (!patterns || patterns.length === 0) return false;\n\tfor (const pattern of patterns) {\n\t\tif (pattern.length > 0 && command.includes(pattern)) return true;\n\t}\n\treturn false;\n}\n\n/**\n * Classify a command, applying `extraDeny` promotion.\n *\n * `extraDeny` can only escalate allow/confirm to block; an existing block\n * verdict is returned unchanged.\n */\nfunction classifyWithExtraDeny(command: string, extraDeny?: string[]): CommandVerdict {\n\tconst verdict = classifyShellCommand(command);\n\tif (verdict.risk === \"block\") return verdict;\n\tif (matchesExtraDeny(command, extraDeny)) {\n\t\treturn {\n\t\t\trisk: \"block\",\n\t\t\trule: \"command.extra_deny\",\n\t\t\treason: \"Command matches a configured deny pattern.\",\n\t\t};\n\t}\n\treturn verdict;\n}\n\n/**\n * Pure block-only check for an LLM `bash` tool call.\n *\n * Only block-tier verdicts produce a block here; confirm/allow pass through.\n * Used as a low-level non-negotiable floor (for example by the bash tool's\n * effective-command check after commandPrefix/spawnHook) where no confirm UI\n * or policy context exists. The confirm-deny behavior for the live tool_call\n * gate lives in {@link evaluateCommandGate}.\n */\nexport function evaluateBashToolCall(\n\tcommand: string,\n\textraDeny?: string[],\n): { block: true; reason: string } | undefined {\n\tconst verdict = classifyWithExtraDeny(command, extraDeny);\n\tif (verdict.risk === \"block\") {\n\t\treturn { block: true, reason: formatReason(verdict) };\n\t}\n\treturn undefined;\n}\n\n/**\n * Shared gate decision for any bash command (LLM tool call, user bash, RPC bash).\n *\n * - block => deny.\n * - confirm => hasUI ? (approved ? undefined : deny) : (policy === \"allow\" && !priv ? undefined : deny).\n * - allow => undefined (preserve later extensions / default execution).\n */\nexport async function evaluateCommandGate(\n\tcommand: string,\n\topts: CommandGateOptions,\n): Promise<{ deny: boolean; reason: string } | undefined> {\n\tconst verdict = classifyWithExtraDeny(command, opts.extraDeny);\n\n\tif (verdict.risk === \"allow\") return undefined;\n\tif (verdict.risk === \"block\") {\n\t\treturn { deny: true, reason: formatReason(verdict) };\n\t}\n\n\t// confirm-tier verdict.\n\tconst isPrivilege = verdict.rule.startsWith(\"priv.\");\n\tif (opts.hasUI) {\n\t\tif (!isPrivilege && opts.interactiveConfirmPolicy === \"allow\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (opts.confirm) {\n\t\t\tconst approved = await opts.confirm(formatReason(verdict));\n\t\t\treturn approved ? undefined : { deny: true, reason: formatReason(verdict) };\n\t\t}\n\t\t// UI claimed but no confirm callback: cannot obtain consent => fail-closed.\n\t\treturn { deny: true, reason: formatReason(verdict) };\n\t}\n\n\t// Headless: privilege escalation is never auto-allowed.\n\tif (!isPrivilege && opts.headlessConfirmPolicy === \"allow\") {\n\t\treturn undefined;\n\t}\n\treturn { deny: true, reason: formatReason(verdict) };\n}\n\n/** @deprecated Back-compat alias; prefer {@link evaluateCommandGate}. */\nexport const evaluateUserBash = evaluateCommandGate;\n\nexport function isCommandSafetyAssumeYesEnabled(\n\tenv: NodeJS.ProcessEnv | Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\t// YOLO implies assume-yes for any residual confirm-tier paths.\n\tif (isCommandSafetyDisabled(env)) return true;\n\treturn env.OMK_COMMAND_SAFETY_ASSUME_YES === \"1\" || env.OMK_COMMAND_SAFETY_ASSUME_YES === \"true\";\n}\n\n/**\n * Full disable of the command-safety gate (YOLO mode).\n * Env (any one):\n * OMK_YOLO=1|true\n * OMK_COMMAND_SAFETY=0|false|off|disable\n * OMK_DISABLE_COMMAND_SAFETY=1|true\n */\nexport function isCommandSafetyDisabled(\n\tenv: NodeJS.ProcessEnv | Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\tconst yolo = env.OMK_YOLO;\n\tif (yolo === \"1\" || yolo === \"true\" || yolo === \"yes\" || yolo === \"on\") return true;\n\tconst cs = String(env.OMK_COMMAND_SAFETY ?? \"\").toLowerCase();\n\tif (cs === \"0\" || cs === \"false\" || cs === \"off\" || cs === \"disable\" || cs === \"disabled\") return true;\n\tconst d = env.OMK_DISABLE_COMMAND_SAFETY;\n\treturn d === \"1\" || d === \"true\" || d === \"yes\" || d === \"on\";\n}\n\nfunction getAssumeYesConfirmPolicies(): Pick<CommandGateOptions, \"interactiveConfirmPolicy\" | \"headlessConfirmPolicy\"> {\n\tif (!isCommandSafetyAssumeYesEnabled()) {\n\t\treturn { interactiveConfirmPolicy: \"ask\", headlessConfirmPolicy: \"deny\" };\n\t}\n\treturn { interactiveConfirmPolicy: \"allow\", headlessConfirmPolicy: \"allow\" };\n}\n\n/** Build a synthetic failed `BashResult` surfacing the safety reason. */\nexport function buildBlockedBashResult(reason: string): BashResult {\n\treturn {\n\t\toutput: `command-safety: blocked\\n${reason}`,\n\t\texitCode: 1,\n\t\tcancelled: false,\n\t\ttruncated: false,\n\t};\n}\n\n/**\n * Extension factory. Registered as the first extension so its handlers run\n * before any discovered extension (`tool_call` short-circuits on first block;\n * `user_bash` short-circuits on first truthy result).\n */\nexport default function commandSafetyGate(omk: ExtensionAPI): void {\n\t// YOLO / disabled: register no handlers — gate is a no-op extension.\n\tif (isCommandSafetyDisabled()) return;\n\n\tomk.on(\"tool_call\", async (event, ctx) => {\n\t\tif (!isToolCallEventType(\"bash\", event)) return undefined;\n\t\tconst decision = await evaluateCommandGate(event.input.command, {\n\t\t\thasUI: ctx.hasUI,\n\t\t\tconfirm: ctx.hasUI ? (message) => ctx.ui.confirm(\"Command safety\", message) : undefined,\n\t\t\t...getAssumeYesConfirmPolicies(),\n\t\t});\n\t\tif (decision?.deny) {\n\t\t\treturn { block: true, reason: decision.reason };\n\t\t}\n\t\treturn undefined;\n\t});\n\n\tomk.on(\"user_bash\", async (event, ctx) => {\n\t\tconst decision = await evaluateCommandGate(event.command, {\n\t\t\thasUI: ctx.hasUI,\n\t\t\tconfirm: ctx.hasUI ? (message) => ctx.ui.confirm(\"Command safety\", message) : undefined,\n\t\t\t...getAssumeYesConfirmPolicies(),\n\t\t});\n\t\tif (decision?.deny) {\n\t\t\treturn { result: buildBlockedBashResult(decision.reason) };\n\t\t}\n\t\treturn undefined;\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"command-safety-gate.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/command-safety-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,KAAK,YAAY,EAAuB,MAAM,aAAa,CAAC;AAErE,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9D,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB;IAClC,iEAAiE;IACjE,KAAK,EAAE,OAAO,CAAC;IACf,mEAAmE;IACnE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,uFAAuF;IACvF,wBAAwB,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IAC3C,+GAA+G;IAC/G,qBAAqB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzC,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,oEAAoE;AACpE,MAAM,MAAM,uBAAuB,GAAG,kBAAkB,CAAC;AAiCzD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAAE,GAClB;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAM7C;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACxC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,kBAAkB,GACtB,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,CAgCxD;AAED,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,4BAAsB,CAAC;AAEpD,wBAAgB,+BAA+B,CAC9C,GAAG,GAAE,MAAM,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GACjF,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACtC,GAAG,GAAE,MAAM,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GACjF,OAAO,CAOT;AASD,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAOjE;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CA4BjE","sourcesContent":["/**\n * Built-in command-safety gate extension.\n *\n * Wires the pure `classifyShellCommand` verdict engine into the live bash entry\n * points with one shared decision engine (`evaluateCommandGate`):\n * - LLM tool calls (`tool_call` for the `bash` tool) — block-tier verdicts stop\n * execution via `{ block, reason }`. confirm-tier verdicts prompt when a\n * dialog-capable UI is available and otherwise deny headlessly (parity with\n * user bash). `priv.*` is never auto-allowed.\n * - User `!`/`!!` bash (`user_bash`) — block/confirm verdicts produce a synthetic\n * FAILED `BashResult` instead of running the command.\n * - RPC bash routes through `AgentSession.executeBash({ safetyGate: \"headless\" })`\n * which reuses `evaluateCommandGate` and `buildBlockedBashResult` directly.\n *\n * Fail-closed contract:\n * - `user_bash` deny NEVER throws. A thrown `user_bash` handler is logged by the\n * runner and default execution continues (fail-open). Returning a synthetic\n * failed `result` short-circuits execution safely.\n * - `confirm`-tier verdicts deny by default when no interactive UI is available.\n * - `priv.*` verdicts are never headless-allowed.\n *\n * This gate reuses `command-safety.ts` read-only and adds no new classification\n * branches. `extraDeny` patterns can only promote allow/confirm to block; they\n * can never relax a block verdict.\n */\n\nimport type { BashResult } from \"../../bash-executor.ts\";\nimport { type CommandVerdict, classifyShellCommand } from \"../../command-safety.ts\";\nimport { type ExtensionAPI, isToolCallEventType } from \"../types.ts\";\n\n/** Confirmation callback. Returns true when the user approves execution. */\nexport type ConfirmFn = (message: string) => Promise<boolean>;\n\n/** Options controlling how a bash command is evaluated by the shared gate. */\nexport interface CommandGateOptions {\n\t/** Whether a dialog-capable UI is available for confirmation. */\n\thasUI: boolean;\n\t/** Interactive confirmation callback used when `hasUI` is true. */\n\tconfirm?: ConfirmFn;\n\t/** Interactive policy for non-privilege `confirm`-tier verdicts. Defaults to \"ask\". */\n\tinteractiveConfirmPolicy?: \"ask\" | \"allow\";\n\t/** Headless policy for `confirm`-tier verdicts. `priv.*` is never allowed outside YOLO. Defaults to \"deny\". */\n\theadlessConfirmPolicy?: \"deny\" | \"allow\";\n\t/** Extra substrings that promote allow/confirm verdicts to block. Never relaxes a block. */\n\textraDeny?: string[];\n}\n\n/** @deprecated Back-compat alias for {@link CommandGateOptions}. */\nexport type UserBashEvaluateOptions = CommandGateOptions;\n\nfunction formatReason(verdict: CommandVerdict): string {\n\treturn `[${verdict.rule}] ${verdict.reason}`;\n}\n\nfunction matchesExtraDeny(command: string, patterns: string[] | undefined): boolean {\n\tif (!patterns || patterns.length === 0) return false;\n\tfor (const pattern of patterns) {\n\t\tif (pattern.length > 0 && command.includes(pattern)) return true;\n\t}\n\treturn false;\n}\n\n/**\n * Classify a command, applying `extraDeny` promotion.\n *\n * `extraDeny` can only escalate allow/confirm to block; an existing block\n * verdict is returned unchanged.\n */\nfunction classifyWithExtraDeny(command: string, extraDeny?: string[]): CommandVerdict {\n\tconst verdict = classifyShellCommand(command);\n\tif (verdict.risk === \"block\") return verdict;\n\tif (matchesExtraDeny(command, extraDeny)) {\n\t\treturn {\n\t\t\trisk: \"block\",\n\t\t\trule: \"command.extra_deny\",\n\t\t\treason: \"Command matches a configured deny pattern.\",\n\t\t};\n\t}\n\treturn verdict;\n}\n\n/**\n * Pure block-only check for an LLM `bash` tool call.\n *\n * Only block-tier verdicts produce a block here; confirm/allow pass through.\n * Used as a low-level non-negotiable floor (for example by the bash tool's\n * effective-command check after commandPrefix/spawnHook) where no confirm UI\n * or policy context exists. The confirm-deny behavior for the live tool_call\n * gate lives in {@link evaluateCommandGate}.\n */\nexport function evaluateBashToolCall(\n\tcommand: string,\n\textraDeny?: string[],\n): { block: true; reason: string } | undefined {\n\tconst verdict = classifyWithExtraDeny(command, extraDeny);\n\tif (verdict.risk === \"block\") {\n\t\treturn { block: true, reason: formatReason(verdict) };\n\t}\n\treturn undefined;\n}\n\n/**\n * Shared gate decision for any bash command (LLM tool call, user bash, RPC bash).\n *\n * - YOLO => undefined (full disable: every verdict — block, confirm, priv.* —\n * runs without prompting; see {@link isCommandSafetyDisabled}).\n * - block => deny.\n * - confirm => hasUI ? (approved ? undefined : deny) : (policy === \"allow\" && !priv ? undefined : deny).\n * - allow => undefined (preserve later extensions / default execution).\n */\nexport async function evaluateCommandGate(\n\tcommand: string,\n\topts: CommandGateOptions,\n): Promise<{ deny: boolean; reason: string } | undefined> {\n\t// YOLO mode: the operator opted out of the entire gate — no prompts for any\n\t// verdict, including privilege escalation. Kept inside the pure decision\n\t// engine so every direct caller (gate extension, RPC headless bash) inherits it.\n\tif (isCommandSafetyDisabled()) return undefined;\n\n\tconst verdict = classifyWithExtraDeny(command, opts.extraDeny);\n\n\tif (verdict.risk === \"allow\") return undefined;\n\tif (verdict.risk === \"block\") {\n\t\treturn { deny: true, reason: formatReason(verdict) };\n\t}\n\n\t// confirm-tier verdict.\n\tconst isPrivilege = verdict.rule.startsWith(\"priv.\");\n\tif (opts.hasUI) {\n\t\tif (!isPrivilege && opts.interactiveConfirmPolicy === \"allow\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (opts.confirm) {\n\t\t\tconst approved = await opts.confirm(formatReason(verdict));\n\t\t\treturn approved ? undefined : { deny: true, reason: formatReason(verdict) };\n\t\t}\n\t\t// UI claimed but no confirm callback: cannot obtain consent => fail-closed.\n\t\treturn { deny: true, reason: formatReason(verdict) };\n\t}\n\n\t// Headless: privilege escalation is never auto-allowed.\n\tif (!isPrivilege && opts.headlessConfirmPolicy === \"allow\") {\n\t\treturn undefined;\n\t}\n\treturn { deny: true, reason: formatReason(verdict) };\n}\n\n/** @deprecated Back-compat alias; prefer {@link evaluateCommandGate}. */\nexport const evaluateUserBash = evaluateCommandGate;\n\nexport function isCommandSafetyAssumeYesEnabled(\n\tenv: NodeJS.ProcessEnv | Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\t// YOLO implies assume-yes for any residual confirm-tier paths.\n\tif (isCommandSafetyDisabled(env)) return true;\n\treturn env.OMK_COMMAND_SAFETY_ASSUME_YES === \"1\" || env.OMK_COMMAND_SAFETY_ASSUME_YES === \"true\";\n}\n\n/**\n * Full disable of the command-safety gate (YOLO mode).\n * Env (any one):\n * OMK_YOLO=1|true\n * OMK_COMMAND_SAFETY=0|false|off|disable\n * OMK_DISABLE_COMMAND_SAFETY=1|true\n */\nexport function isCommandSafetyDisabled(\n\tenv: NodeJS.ProcessEnv | Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\tconst yolo = env.OMK_YOLO;\n\tif (yolo === \"1\" || yolo === \"true\" || yolo === \"yes\" || yolo === \"on\") return true;\n\tconst cs = String(env.OMK_COMMAND_SAFETY ?? \"\").toLowerCase();\n\tif (cs === \"0\" || cs === \"false\" || cs === \"off\" || cs === \"disable\" || cs === \"disabled\") return true;\n\tconst d = env.OMK_DISABLE_COMMAND_SAFETY;\n\treturn d === \"1\" || d === \"true\" || d === \"yes\" || d === \"on\";\n}\n\nfunction getAssumeYesConfirmPolicies(): Pick<CommandGateOptions, \"interactiveConfirmPolicy\" | \"headlessConfirmPolicy\"> {\n\tif (!isCommandSafetyAssumeYesEnabled()) {\n\t\treturn { interactiveConfirmPolicy: \"ask\", headlessConfirmPolicy: \"deny\" };\n\t}\n\treturn { interactiveConfirmPolicy: \"allow\", headlessConfirmPolicy: \"allow\" };\n}\n\n/** Build a synthetic failed `BashResult` surfacing the safety reason. */\nexport function buildBlockedBashResult(reason: string): BashResult {\n\treturn {\n\t\toutput: `command-safety: blocked\\n${reason}`,\n\t\texitCode: 1,\n\t\tcancelled: false,\n\t\ttruncated: false,\n\t};\n}\n\n/**\n * Extension factory. Registered as the first extension so its handlers run\n * before any discovered extension (`tool_call` short-circuits on first block;\n * `user_bash` short-circuits on first truthy result).\n */\nexport default function commandSafetyGate(omk: ExtensionAPI): void {\n\t// YOLO / disabled: register no handlers — gate is a no-op extension.\n\tif (isCommandSafetyDisabled()) return;\n\n\tomk.on(\"tool_call\", async (event, ctx) => {\n\t\tif (!isToolCallEventType(\"bash\", event)) return undefined;\n\t\tconst decision = await evaluateCommandGate(event.input.command, {\n\t\t\thasUI: ctx.hasUI,\n\t\t\tconfirm: ctx.hasUI ? (message) => ctx.ui.confirm(\"Command safety\", message) : undefined,\n\t\t\t...getAssumeYesConfirmPolicies(),\n\t\t});\n\t\tif (decision?.deny) {\n\t\t\treturn { block: true, reason: decision.reason };\n\t\t}\n\t\treturn undefined;\n\t});\n\n\tomk.on(\"user_bash\", async (event, ctx) => {\n\t\tconst decision = await evaluateCommandGate(event.command, {\n\t\t\thasUI: ctx.hasUI,\n\t\t\tconfirm: ctx.hasUI ? (message) => ctx.ui.confirm(\"Command safety\", message) : undefined,\n\t\t\t...getAssumeYesConfirmPolicies(),\n\t\t});\n\t\tif (decision?.deny) {\n\t\t\treturn { result: buildBlockedBashResult(decision.reason) };\n\t\t}\n\t\treturn undefined;\n\t});\n}\n"]}
|
|
@@ -75,11 +75,18 @@ export function evaluateBashToolCall(command, extraDeny) {
|
|
|
75
75
|
/**
|
|
76
76
|
* Shared gate decision for any bash command (LLM tool call, user bash, RPC bash).
|
|
77
77
|
*
|
|
78
|
+
* - YOLO => undefined (full disable: every verdict — block, confirm, priv.* —
|
|
79
|
+
* runs without prompting; see {@link isCommandSafetyDisabled}).
|
|
78
80
|
* - block => deny.
|
|
79
81
|
* - confirm => hasUI ? (approved ? undefined : deny) : (policy === "allow" && !priv ? undefined : deny).
|
|
80
82
|
* - allow => undefined (preserve later extensions / default execution).
|
|
81
83
|
*/
|
|
82
84
|
export async function evaluateCommandGate(command, opts) {
|
|
85
|
+
// YOLO mode: the operator opted out of the entire gate — no prompts for any
|
|
86
|
+
// verdict, including privilege escalation. Kept inside the pure decision
|
|
87
|
+
// engine so every direct caller (gate extension, RPC headless bash) inherits it.
|
|
88
|
+
if (isCommandSafetyDisabled())
|
|
89
|
+
return undefined;
|
|
83
90
|
const verdict = classifyWithExtraDeny(command, opts.extraDeny);
|
|
84
91
|
if (verdict.risk === "allow")
|
|
85
92
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-safety-gate.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/command-safety-gate.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Built-in command-safety gate extension.\n *\n * Wires the pure `classifyShellCommand` verdict engine into the live bash entry\n * points with one shared decision engine (`evaluateCommandGate`):\n * - LLM tool calls (`tool_call` for the `bash` tool) — block-tier verdicts stop\n * execution via `{ block, reason }`. confirm-tier verdicts prompt when a\n * dialog-capable UI is available and otherwise deny headlessly (parity with\n * user bash). `priv.*` is never auto-allowed.\n * - User `!`/`!!` bash (`user_bash`) — block/confirm verdicts produce a synthetic\n * FAILED `BashResult` instead of running the command.\n * - RPC bash routes through `AgentSession.executeBash({ safetyGate: \"headless\" })`\n * which reuses `evaluateCommandGate` and `buildBlockedBashResult` directly.\n *\n * Fail-closed contract:\n * - `user_bash` deny NEVER throws. A thrown `user_bash` handler is logged by the\n * runner and default execution continues (fail-open). Returning a synthetic\n * failed `result` short-circuits execution safely.\n * - `confirm`-tier verdicts deny by default when no interactive UI is available.\n * - `priv.*` verdicts are never headless-allowed.\n *\n * This gate reuses `command-safety.ts` read-only and adds no new classification\n * branches. `extraDeny` patterns can only promote allow/confirm to block; they\n * can never relax a block verdict.\n */\n\nimport type { BashResult } from \"../../bash-executor.ts\";\nimport { type CommandVerdict, classifyShellCommand } from \"../../command-safety.ts\";\nimport { type ExtensionAPI, isToolCallEventType } from \"../types.ts\";\n\n/** Confirmation callback. Returns true when the user approves execution. */\nexport type ConfirmFn = (message: string) => Promise<boolean>;\n\n/** Options controlling how a bash command is evaluated by the shared gate. */\nexport interface CommandGateOptions {\n\t/** Whether a dialog-capable UI is available for confirmation. */\n\thasUI: boolean;\n\t/** Interactive confirmation callback used when `hasUI` is true. */\n\tconfirm?: ConfirmFn;\n\t/** Interactive policy for non-privilege `confirm`-tier verdicts. Defaults to \"ask\". */\n\tinteractiveConfirmPolicy?: \"ask\" | \"allow\";\n\t/** Headless policy for `confirm`-tier verdicts. `priv.*` is never allowed. Defaults to \"deny\". */\n\theadlessConfirmPolicy?: \"deny\" | \"allow\";\n\t/** Extra substrings that promote allow/confirm verdicts to block. Never relaxes a block. */\n\textraDeny?: string[];\n}\n\n/** @deprecated Back-compat alias for {@link CommandGateOptions}. */\nexport type UserBashEvaluateOptions = CommandGateOptions;\n\nfunction formatReason(verdict: CommandVerdict): string {\n\treturn `[${verdict.rule}] ${verdict.reason}`;\n}\n\nfunction matchesExtraDeny(command: string, patterns: string[] | undefined): boolean {\n\tif (!patterns || patterns.length === 0) return false;\n\tfor (const pattern of patterns) {\n\t\tif (pattern.length > 0 && command.includes(pattern)) return true;\n\t}\n\treturn false;\n}\n\n/**\n * Classify a command, applying `extraDeny` promotion.\n *\n * `extraDeny` can only escalate allow/confirm to block; an existing block\n * verdict is returned unchanged.\n */\nfunction classifyWithExtraDeny(command: string, extraDeny?: string[]): CommandVerdict {\n\tconst verdict = classifyShellCommand(command);\n\tif (verdict.risk === \"block\") return verdict;\n\tif (matchesExtraDeny(command, extraDeny)) {\n\t\treturn {\n\t\t\trisk: \"block\",\n\t\t\trule: \"command.extra_deny\",\n\t\t\treason: \"Command matches a configured deny pattern.\",\n\t\t};\n\t}\n\treturn verdict;\n}\n\n/**\n * Pure block-only check for an LLM `bash` tool call.\n *\n * Only block-tier verdicts produce a block here; confirm/allow pass through.\n * Used as a low-level non-negotiable floor (for example by the bash tool's\n * effective-command check after commandPrefix/spawnHook) where no confirm UI\n * or policy context exists. The confirm-deny behavior for the live tool_call\n * gate lives in {@link evaluateCommandGate}.\n */\nexport function evaluateBashToolCall(\n\tcommand: string,\n\textraDeny?: string[],\n): { block: true; reason: string } | undefined {\n\tconst verdict = classifyWithExtraDeny(command, extraDeny);\n\tif (verdict.risk === \"block\") {\n\t\treturn { block: true, reason: formatReason(verdict) };\n\t}\n\treturn undefined;\n}\n\n/**\n * Shared gate decision for any bash command (LLM tool call, user bash, RPC bash).\n *\n * - block => deny.\n * - confirm => hasUI ? (approved ? undefined : deny) : (policy === \"allow\" && !priv ? undefined : deny).\n * - allow => undefined (preserve later extensions / default execution).\n */\nexport async function evaluateCommandGate(\n\tcommand: string,\n\topts: CommandGateOptions,\n): Promise<{ deny: boolean; reason: string } | undefined> {\n\tconst verdict = classifyWithExtraDeny(command, opts.extraDeny);\n\n\tif (verdict.risk === \"allow\") return undefined;\n\tif (verdict.risk === \"block\") {\n\t\treturn { deny: true, reason: formatReason(verdict) };\n\t}\n\n\t// confirm-tier verdict.\n\tconst isPrivilege = verdict.rule.startsWith(\"priv.\");\n\tif (opts.hasUI) {\n\t\tif (!isPrivilege && opts.interactiveConfirmPolicy === \"allow\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (opts.confirm) {\n\t\t\tconst approved = await opts.confirm(formatReason(verdict));\n\t\t\treturn approved ? undefined : { deny: true, reason: formatReason(verdict) };\n\t\t}\n\t\t// UI claimed but no confirm callback: cannot obtain consent => fail-closed.\n\t\treturn { deny: true, reason: formatReason(verdict) };\n\t}\n\n\t// Headless: privilege escalation is never auto-allowed.\n\tif (!isPrivilege && opts.headlessConfirmPolicy === \"allow\") {\n\t\treturn undefined;\n\t}\n\treturn { deny: true, reason: formatReason(verdict) };\n}\n\n/** @deprecated Back-compat alias; prefer {@link evaluateCommandGate}. */\nexport const evaluateUserBash = evaluateCommandGate;\n\nexport function isCommandSafetyAssumeYesEnabled(\n\tenv: NodeJS.ProcessEnv | Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\t// YOLO implies assume-yes for any residual confirm-tier paths.\n\tif (isCommandSafetyDisabled(env)) return true;\n\treturn env.OMK_COMMAND_SAFETY_ASSUME_YES === \"1\" || env.OMK_COMMAND_SAFETY_ASSUME_YES === \"true\";\n}\n\n/**\n * Full disable of the command-safety gate (YOLO mode).\n * Env (any one):\n * OMK_YOLO=1|true\n * OMK_COMMAND_SAFETY=0|false|off|disable\n * OMK_DISABLE_COMMAND_SAFETY=1|true\n */\nexport function isCommandSafetyDisabled(\n\tenv: NodeJS.ProcessEnv | Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\tconst yolo = env.OMK_YOLO;\n\tif (yolo === \"1\" || yolo === \"true\" || yolo === \"yes\" || yolo === \"on\") return true;\n\tconst cs = String(env.OMK_COMMAND_SAFETY ?? \"\").toLowerCase();\n\tif (cs === \"0\" || cs === \"false\" || cs === \"off\" || cs === \"disable\" || cs === \"disabled\") return true;\n\tconst d = env.OMK_DISABLE_COMMAND_SAFETY;\n\treturn d === \"1\" || d === \"true\" || d === \"yes\" || d === \"on\";\n}\n\nfunction getAssumeYesConfirmPolicies(): Pick<CommandGateOptions, \"interactiveConfirmPolicy\" | \"headlessConfirmPolicy\"> {\n\tif (!isCommandSafetyAssumeYesEnabled()) {\n\t\treturn { interactiveConfirmPolicy: \"ask\", headlessConfirmPolicy: \"deny\" };\n\t}\n\treturn { interactiveConfirmPolicy: \"allow\", headlessConfirmPolicy: \"allow\" };\n}\n\n/** Build a synthetic failed `BashResult` surfacing the safety reason. */\nexport function buildBlockedBashResult(reason: string): BashResult {\n\treturn {\n\t\toutput: `command-safety: blocked\\n${reason}`,\n\t\texitCode: 1,\n\t\tcancelled: false,\n\t\ttruncated: false,\n\t};\n}\n\n/**\n * Extension factory. Registered as the first extension so its handlers run\n * before any discovered extension (`tool_call` short-circuits on first block;\n * `user_bash` short-circuits on first truthy result).\n */\nexport default function commandSafetyGate(omk: ExtensionAPI): void {\n\t// YOLO / disabled: register no handlers — gate is a no-op extension.\n\tif (isCommandSafetyDisabled()) return;\n\n\tomk.on(\"tool_call\", async (event, ctx) => {\n\t\tif (!isToolCallEventType(\"bash\", event)) return undefined;\n\t\tconst decision = await evaluateCommandGate(event.input.command, {\n\t\t\thasUI: ctx.hasUI,\n\t\t\tconfirm: ctx.hasUI ? (message) => ctx.ui.confirm(\"Command safety\", message) : undefined,\n\t\t\t...getAssumeYesConfirmPolicies(),\n\t\t});\n\t\tif (decision?.deny) {\n\t\t\treturn { block: true, reason: decision.reason };\n\t\t}\n\t\treturn undefined;\n\t});\n\n\tomk.on(\"user_bash\", async (event, ctx) => {\n\t\tconst decision = await evaluateCommandGate(event.command, {\n\t\t\thasUI: ctx.hasUI,\n\t\t\tconfirm: ctx.hasUI ? (message) => ctx.ui.confirm(\"Command safety\", message) : undefined,\n\t\t\t...getAssumeYesConfirmPolicies(),\n\t\t});\n\t\tif (decision?.deny) {\n\t\t\treturn { result: buildBlockedBashResult(decision.reason) };\n\t\t}\n\t\treturn undefined;\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"command-safety-gate.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/command-safety-gate.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Built-in command-safety gate extension.\n *\n * Wires the pure `classifyShellCommand` verdict engine into the live bash entry\n * points with one shared decision engine (`evaluateCommandGate`):\n * - LLM tool calls (`tool_call` for the `bash` tool) — block-tier verdicts stop\n * execution via `{ block, reason }`. confirm-tier verdicts prompt when a\n * dialog-capable UI is available and otherwise deny headlessly (parity with\n * user bash). `priv.*` is never auto-allowed.\n * - User `!`/`!!` bash (`user_bash`) — block/confirm verdicts produce a synthetic\n * FAILED `BashResult` instead of running the command.\n * - RPC bash routes through `AgentSession.executeBash({ safetyGate: \"headless\" })`\n * which reuses `evaluateCommandGate` and `buildBlockedBashResult` directly.\n *\n * Fail-closed contract:\n * - `user_bash` deny NEVER throws. A thrown `user_bash` handler is logged by the\n * runner and default execution continues (fail-open). Returning a synthetic\n * failed `result` short-circuits execution safely.\n * - `confirm`-tier verdicts deny by default when no interactive UI is available.\n * - `priv.*` verdicts are never headless-allowed.\n *\n * This gate reuses `command-safety.ts` read-only and adds no new classification\n * branches. `extraDeny` patterns can only promote allow/confirm to block; they\n * can never relax a block verdict.\n */\n\nimport type { BashResult } from \"../../bash-executor.ts\";\nimport { type CommandVerdict, classifyShellCommand } from \"../../command-safety.ts\";\nimport { type ExtensionAPI, isToolCallEventType } from \"../types.ts\";\n\n/** Confirmation callback. Returns true when the user approves execution. */\nexport type ConfirmFn = (message: string) => Promise<boolean>;\n\n/** Options controlling how a bash command is evaluated by the shared gate. */\nexport interface CommandGateOptions {\n\t/** Whether a dialog-capable UI is available for confirmation. */\n\thasUI: boolean;\n\t/** Interactive confirmation callback used when `hasUI` is true. */\n\tconfirm?: ConfirmFn;\n\t/** Interactive policy for non-privilege `confirm`-tier verdicts. Defaults to \"ask\". */\n\tinteractiveConfirmPolicy?: \"ask\" | \"allow\";\n\t/** Headless policy for `confirm`-tier verdicts. `priv.*` is never allowed outside YOLO. Defaults to \"deny\". */\n\theadlessConfirmPolicy?: \"deny\" | \"allow\";\n\t/** Extra substrings that promote allow/confirm verdicts to block. Never relaxes a block. */\n\textraDeny?: string[];\n}\n\n/** @deprecated Back-compat alias for {@link CommandGateOptions}. */\nexport type UserBashEvaluateOptions = CommandGateOptions;\n\nfunction formatReason(verdict: CommandVerdict): string {\n\treturn `[${verdict.rule}] ${verdict.reason}`;\n}\n\nfunction matchesExtraDeny(command: string, patterns: string[] | undefined): boolean {\n\tif (!patterns || patterns.length === 0) return false;\n\tfor (const pattern of patterns) {\n\t\tif (pattern.length > 0 && command.includes(pattern)) return true;\n\t}\n\treturn false;\n}\n\n/**\n * Classify a command, applying `extraDeny` promotion.\n *\n * `extraDeny` can only escalate allow/confirm to block; an existing block\n * verdict is returned unchanged.\n */\nfunction classifyWithExtraDeny(command: string, extraDeny?: string[]): CommandVerdict {\n\tconst verdict = classifyShellCommand(command);\n\tif (verdict.risk === \"block\") return verdict;\n\tif (matchesExtraDeny(command, extraDeny)) {\n\t\treturn {\n\t\t\trisk: \"block\",\n\t\t\trule: \"command.extra_deny\",\n\t\t\treason: \"Command matches a configured deny pattern.\",\n\t\t};\n\t}\n\treturn verdict;\n}\n\n/**\n * Pure block-only check for an LLM `bash` tool call.\n *\n * Only block-tier verdicts produce a block here; confirm/allow pass through.\n * Used as a low-level non-negotiable floor (for example by the bash tool's\n * effective-command check after commandPrefix/spawnHook) where no confirm UI\n * or policy context exists. The confirm-deny behavior for the live tool_call\n * gate lives in {@link evaluateCommandGate}.\n */\nexport function evaluateBashToolCall(\n\tcommand: string,\n\textraDeny?: string[],\n): { block: true; reason: string } | undefined {\n\tconst verdict = classifyWithExtraDeny(command, extraDeny);\n\tif (verdict.risk === \"block\") {\n\t\treturn { block: true, reason: formatReason(verdict) };\n\t}\n\treturn undefined;\n}\n\n/**\n * Shared gate decision for any bash command (LLM tool call, user bash, RPC bash).\n *\n * - YOLO => undefined (full disable: every verdict — block, confirm, priv.* —\n * runs without prompting; see {@link isCommandSafetyDisabled}).\n * - block => deny.\n * - confirm => hasUI ? (approved ? undefined : deny) : (policy === \"allow\" && !priv ? undefined : deny).\n * - allow => undefined (preserve later extensions / default execution).\n */\nexport async function evaluateCommandGate(\n\tcommand: string,\n\topts: CommandGateOptions,\n): Promise<{ deny: boolean; reason: string } | undefined> {\n\t// YOLO mode: the operator opted out of the entire gate — no prompts for any\n\t// verdict, including privilege escalation. Kept inside the pure decision\n\t// engine so every direct caller (gate extension, RPC headless bash) inherits it.\n\tif (isCommandSafetyDisabled()) return undefined;\n\n\tconst verdict = classifyWithExtraDeny(command, opts.extraDeny);\n\n\tif (verdict.risk === \"allow\") return undefined;\n\tif (verdict.risk === \"block\") {\n\t\treturn { deny: true, reason: formatReason(verdict) };\n\t}\n\n\t// confirm-tier verdict.\n\tconst isPrivilege = verdict.rule.startsWith(\"priv.\");\n\tif (opts.hasUI) {\n\t\tif (!isPrivilege && opts.interactiveConfirmPolicy === \"allow\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (opts.confirm) {\n\t\t\tconst approved = await opts.confirm(formatReason(verdict));\n\t\t\treturn approved ? undefined : { deny: true, reason: formatReason(verdict) };\n\t\t}\n\t\t// UI claimed but no confirm callback: cannot obtain consent => fail-closed.\n\t\treturn { deny: true, reason: formatReason(verdict) };\n\t}\n\n\t// Headless: privilege escalation is never auto-allowed.\n\tif (!isPrivilege && opts.headlessConfirmPolicy === \"allow\") {\n\t\treturn undefined;\n\t}\n\treturn { deny: true, reason: formatReason(verdict) };\n}\n\n/** @deprecated Back-compat alias; prefer {@link evaluateCommandGate}. */\nexport const evaluateUserBash = evaluateCommandGate;\n\nexport function isCommandSafetyAssumeYesEnabled(\n\tenv: NodeJS.ProcessEnv | Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\t// YOLO implies assume-yes for any residual confirm-tier paths.\n\tif (isCommandSafetyDisabled(env)) return true;\n\treturn env.OMK_COMMAND_SAFETY_ASSUME_YES === \"1\" || env.OMK_COMMAND_SAFETY_ASSUME_YES === \"true\";\n}\n\n/**\n * Full disable of the command-safety gate (YOLO mode).\n * Env (any one):\n * OMK_YOLO=1|true\n * OMK_COMMAND_SAFETY=0|false|off|disable\n * OMK_DISABLE_COMMAND_SAFETY=1|true\n */\nexport function isCommandSafetyDisabled(\n\tenv: NodeJS.ProcessEnv | Readonly<Record<string, string | undefined>> = process.env,\n): boolean {\n\tconst yolo = env.OMK_YOLO;\n\tif (yolo === \"1\" || yolo === \"true\" || yolo === \"yes\" || yolo === \"on\") return true;\n\tconst cs = String(env.OMK_COMMAND_SAFETY ?? \"\").toLowerCase();\n\tif (cs === \"0\" || cs === \"false\" || cs === \"off\" || cs === \"disable\" || cs === \"disabled\") return true;\n\tconst d = env.OMK_DISABLE_COMMAND_SAFETY;\n\treturn d === \"1\" || d === \"true\" || d === \"yes\" || d === \"on\";\n}\n\nfunction getAssumeYesConfirmPolicies(): Pick<CommandGateOptions, \"interactiveConfirmPolicy\" | \"headlessConfirmPolicy\"> {\n\tif (!isCommandSafetyAssumeYesEnabled()) {\n\t\treturn { interactiveConfirmPolicy: \"ask\", headlessConfirmPolicy: \"deny\" };\n\t}\n\treturn { interactiveConfirmPolicy: \"allow\", headlessConfirmPolicy: \"allow\" };\n}\n\n/** Build a synthetic failed `BashResult` surfacing the safety reason. */\nexport function buildBlockedBashResult(reason: string): BashResult {\n\treturn {\n\t\toutput: `command-safety: blocked\\n${reason}`,\n\t\texitCode: 1,\n\t\tcancelled: false,\n\t\ttruncated: false,\n\t};\n}\n\n/**\n * Extension factory. Registered as the first extension so its handlers run\n * before any discovered extension (`tool_call` short-circuits on first block;\n * `user_bash` short-circuits on first truthy result).\n */\nexport default function commandSafetyGate(omk: ExtensionAPI): void {\n\t// YOLO / disabled: register no handlers — gate is a no-op extension.\n\tif (isCommandSafetyDisabled()) return;\n\n\tomk.on(\"tool_call\", async (event, ctx) => {\n\t\tif (!isToolCallEventType(\"bash\", event)) return undefined;\n\t\tconst decision = await evaluateCommandGate(event.input.command, {\n\t\t\thasUI: ctx.hasUI,\n\t\t\tconfirm: ctx.hasUI ? (message) => ctx.ui.confirm(\"Command safety\", message) : undefined,\n\t\t\t...getAssumeYesConfirmPolicies(),\n\t\t});\n\t\tif (decision?.deny) {\n\t\t\treturn { block: true, reason: decision.reason };\n\t\t}\n\t\treturn undefined;\n\t});\n\n\tomk.on(\"user_bash\", async (event, ctx) => {\n\t\tconst decision = await evaluateCommandGate(event.command, {\n\t\t\thasUI: ctx.hasUI,\n\t\t\tconfirm: ctx.hasUI ? (message) => ctx.ui.confirm(\"Command safety\", message) : undefined,\n\t\t\t...getAssumeYesConfirmPolicies(),\n\t\t});\n\t\tif (decision?.deny) {\n\t\t\treturn { result: buildBlockedBashResult(decision.reason) };\n\t\t}\n\t\treturn undefined;\n\t});\n}\n"]}
|
|
@@ -501,6 +501,16 @@ export interface AgentEndEvent {
|
|
|
501
501
|
type: "agent_end";
|
|
502
502
|
messages: AgentMessage[];
|
|
503
503
|
}
|
|
504
|
+
/**
|
|
505
|
+
* Fired once after an agent run fully settles: the `agent_end` that no retry
|
|
506
|
+
* follows. `agent_end` fires once per attempt, so on its own it cannot mark the
|
|
507
|
+
* end of the work when the session retries a transient provider failure. This
|
|
508
|
+
* is the boundary at which per-run state may be released exactly once.
|
|
509
|
+
*/
|
|
510
|
+
export interface AgentSettledEvent {
|
|
511
|
+
type: "agent_settled";
|
|
512
|
+
messages: AgentMessage[];
|
|
513
|
+
}
|
|
504
514
|
/** Fired at the start of each turn */
|
|
505
515
|
export interface TurnStartEvent {
|
|
506
516
|
type: "turn_start";
|
|
@@ -724,7 +734,7 @@ export declare function isToolCallEventType<TName extends string, TInput extends
|
|
|
724
734
|
input: TInput;
|
|
725
735
|
};
|
|
726
736
|
/** Union of all event types */
|
|
727
|
-
export type ExtensionEvent = ResourcesDiscoverEvent | SessionEvent | ContextEvent | BeforeProviderRequestEvent | AfterProviderResponseEvent | BeforeAgentStartEvent | AgentStartEvent | AgentEndEvent | TurnStartEvent | TurnEndEvent | MessageStartEvent | MessageUpdateEvent | MessageEndEvent | ToolExecutionStartEvent | ToolExecutionUpdateEvent | ToolExecutionEndEvent | ModelSelectEvent | ThinkingLevelSelectEvent | UserBashEvent | InputEvent | ToolCallEvent | ToolResultEvent;
|
|
737
|
+
export type ExtensionEvent = ResourcesDiscoverEvent | SessionEvent | ContextEvent | BeforeProviderRequestEvent | AfterProviderResponseEvent | BeforeAgentStartEvent | AgentStartEvent | AgentEndEvent | AgentSettledEvent | TurnStartEvent | TurnEndEvent | MessageStartEvent | MessageUpdateEvent | MessageEndEvent | ToolExecutionStartEvent | ToolExecutionUpdateEvent | ToolExecutionEndEvent | ModelSelectEvent | ThinkingLevelSelectEvent | UserBashEvent | InputEvent | ToolCallEvent | ToolResultEvent;
|
|
728
738
|
export interface ContextEventResult {
|
|
729
739
|
messages?: AgentMessage[];
|
|
730
740
|
}
|
|
@@ -814,6 +824,7 @@ export interface ExtensionAPI {
|
|
|
814
824
|
on(event: "before_agent_start", handler: ExtensionHandler<BeforeAgentStartEvent, BeforeAgentStartEventResult>): void;
|
|
815
825
|
on(event: "agent_start", handler: ExtensionHandler<AgentStartEvent>): void;
|
|
816
826
|
on(event: "agent_end", handler: ExtensionHandler<AgentEndEvent>): void;
|
|
827
|
+
on(event: "agent_settled", handler: ExtensionHandler<AgentSettledEvent>): void;
|
|
817
828
|
on(event: "turn_start", handler: ExtensionHandler<TurnStartEvent>): void;
|
|
818
829
|
on(event: "turn_end", handler: ExtensionHandler<TurnEndEvent>): void;
|
|
819
830
|
on(event: "message_start", handler: ExtensionHandler<MessageStartEvent>): void;
|