@remnic/core 1.1.10 → 1.1.12
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/README.md +3 -3
- package/dist/access-cli.js +67 -59
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +7 -4
- package/dist/access-http.js +30 -26
- package/dist/access-mcp.d.ts +9 -4
- package/dist/access-mcp.js +29 -25
- package/dist/access-schema.d.ts +188 -8
- package/dist/access-schema.js +12 -3
- package/dist/{access-service-BTTNyo1i.d.ts → access-service-DDjzFALq.d.ts} +54 -5
- package/dist/access-service.d.ts +7 -4
- package/dist/access-service.js +26 -23
- package/dist/action-confidence.d.ts +83 -0
- package/dist/action-confidence.js +22 -0
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +4 -2
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +5 -5
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/calibration.js +4 -4
- package/dist/{capsule-export-LLEVB2RG.js → capsule-export-7QNCBZOQ.js} +3 -3
- package/dist/{capsule-import-UW45R2MZ.js → capsule-import-EPBHD2EN.js} +3 -3
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +11 -11
- package/dist/{chunk-VQXK37XA.js → chunk-23ZZK64Y.js} +1 -1
- package/dist/chunk-23ZZK64Y.js.map +1 -0
- package/dist/{chunk-HJYHRE4S.js → chunk-242S3I2A.js} +2 -2
- package/dist/{chunk-MCC6KDQF.js → chunk-3B6KIRBH.js} +131 -13
- package/dist/chunk-3B6KIRBH.js.map +1 -0
- package/dist/chunk-4RA3C3EV.js +60 -0
- package/dist/chunk-4RA3C3EV.js.map +1 -0
- package/dist/{chunk-EYNQTST2.js → chunk-4YM32CRU.js} +4 -4
- package/dist/{chunk-6AUUAZEX.js → chunk-5NXIJZFX.js} +38 -8
- package/dist/chunk-5NXIJZFX.js.map +1 -0
- package/dist/chunk-6NKAQ74D.js +2237 -0
- package/dist/chunk-6NKAQ74D.js.map +1 -0
- package/dist/{chunk-PHNGXFQ6.js → chunk-7V22HTMD.js} +3 -3
- package/dist/{chunk-363MWCD3.js → chunk-7ZM3BFKK.js} +84 -62
- package/dist/chunk-7ZM3BFKK.js.map +1 -0
- package/dist/chunk-AC5LO7IU.js +308 -0
- package/dist/chunk-AC5LO7IU.js.map +1 -0
- package/dist/chunk-AH2JUU6X.js +336 -0
- package/dist/chunk-AH2JUU6X.js.map +1 -0
- package/dist/{chunk-VX2IUQFE.js → chunk-AQJNPMOA.js} +41 -11
- package/dist/chunk-AQJNPMOA.js.map +1 -0
- package/dist/{chunk-P73JTV34.js → chunk-BBE34QBJ.js} +4 -4
- package/dist/{chunk-5GCNE7CN.js → chunk-BZSQEPRW.js} +454 -140
- package/dist/chunk-BZSQEPRW.js.map +1 -0
- package/dist/chunk-C5BCH4ZS.js +317 -0
- package/dist/chunk-C5BCH4ZS.js.map +1 -0
- package/dist/{chunk-C5HUWVH2.js → chunk-CPKTBRS2.js} +6 -6
- package/dist/{chunk-IBX3VFOM.js → chunk-D4GAOFF6.js} +118 -2
- package/dist/chunk-D4GAOFF6.js.map +1 -0
- package/dist/chunk-DB5A3NHS.js +906 -0
- package/dist/chunk-DB5A3NHS.js.map +1 -0
- package/dist/{chunk-I6BQZSML.js → chunk-DZZPC36E.js} +10 -10
- package/dist/{chunk-O4XJUPSF.js → chunk-E2UCDP5S.js} +39 -2
- package/dist/chunk-E2UCDP5S.js.map +1 -0
- package/dist/{chunk-SRBJUAMP.js → chunk-FMEBPEAO.js} +11 -67
- package/dist/chunk-FMEBPEAO.js.map +1 -0
- package/dist/{chunk-4DXC6HQQ.js → chunk-FQDPCE3I.js} +5 -5
- package/dist/{chunk-NN3LPQ5D.js → chunk-HELQZFZO.js} +155 -16
- package/dist/chunk-HELQZFZO.js.map +1 -0
- package/dist/{chunk-57QNCUEZ.js → chunk-HL5LRPNA.js} +2 -2
- package/dist/{chunk-VTU2B4VF.js → chunk-HQZVVSVB.js} +2 -1
- package/dist/chunk-HQZVVSVB.js.map +1 -0
- package/dist/{chunk-6Z6UH6TK.js → chunk-HY3L4WKC.js} +69 -3
- package/dist/chunk-HY3L4WKC.js.map +1 -0
- package/dist/{chunk-QIGOEM65.js → chunk-IB3BFHGN.js} +5 -5
- package/dist/{chunk-RXTFCYQF.js → chunk-JESOB2HO.js} +6 -6
- package/dist/{chunk-2YMTO4ZJ.js → chunk-JKDVIE52.js} +9 -2
- package/dist/chunk-JKDVIE52.js.map +1 -0
- package/dist/{chunk-WGK4VHGP.js → chunk-MNU6ZBWT.js} +302 -140
- package/dist/chunk-MNU6ZBWT.js.map +1 -0
- package/dist/chunk-OAZ5MFUB.js +4124 -0
- package/dist/chunk-OAZ5MFUB.js.map +1 -0
- package/dist/{chunk-ZTSE2ZJ6.js → chunk-OIGNEXKZ.js} +50 -3
- package/dist/chunk-OIGNEXKZ.js.map +1 -0
- package/dist/chunk-OZKZ2TRP.js +3729 -0
- package/dist/chunk-OZKZ2TRP.js.map +1 -0
- package/dist/{chunk-GGD5W7TB.js → chunk-PD6O7AXF.js} +7 -2
- package/dist/chunk-PD6O7AXF.js.map +1 -0
- package/dist/{chunk-S3IP6R6K.js → chunk-PH4C2U43.js} +23 -3
- package/dist/chunk-PH4C2U43.js.map +1 -0
- package/dist/chunk-PYPOFEMK.js +294 -0
- package/dist/chunk-PYPOFEMK.js.map +1 -0
- package/dist/{chunk-EQINRHYR.js → chunk-QDZ2RLEC.js} +243 -7
- package/dist/chunk-QDZ2RLEC.js.map +1 -0
- package/dist/{chunk-KWBPHZUU.js → chunk-RK6F44Y6.js} +3 -2
- package/dist/chunk-RK6F44Y6.js.map +1 -0
- package/dist/{chunk-36CTNQY7.js → chunk-RVPLBATS.js} +42 -10
- package/dist/chunk-RVPLBATS.js.map +1 -0
- package/dist/chunk-SOAU2OE2.js +125 -0
- package/dist/chunk-SOAU2OE2.js.map +1 -0
- package/dist/{chunk-A4ACKWIW.js → chunk-U5JMRGKX.js} +55 -4
- package/dist/chunk-U5JMRGKX.js.map +1 -0
- package/dist/{chunk-LIO5X3CM.js → chunk-UVMUAWVT.js} +2 -2
- package/dist/chunk-VWT3F4IV.js +2161 -0
- package/dist/chunk-VWT3F4IV.js.map +1 -0
- package/dist/{chunk-PB5KW5PL.js → chunk-WEJG4TB5.js} +6 -6
- package/dist/{chunk-KBYWQWSB.js → chunk-X7HPGUVG.js} +2 -2
- package/dist/{chunk-Y5KDIOKF.js → chunk-XAMBKFQS.js} +383 -9
- package/dist/chunk-XAMBKFQS.js.map +1 -0
- package/dist/{chunk-ZL4S7ARC.js → chunk-Y3VMVTYX.js} +3 -3
- package/dist/{chunk-Z5S5HNGY.js → chunk-ZG7PTKBK.js} +21 -5
- package/dist/chunk-ZG7PTKBK.js.map +1 -0
- package/dist/{chunk-6XA7UN4Z.js → chunk-ZNQN6ZTA.js} +2 -2
- package/dist/{chunk-WTFWLUSX.js → chunk-ZVTKDVVM.js} +2 -2
- package/dist/{cli-BrEwQTnW.d.ts → cli-BR8KpIU0.d.ts} +2 -2
- package/dist/cli.d.ts +7 -4
- package/dist/cli.js +44 -40
- package/dist/codex-cli-fallback.d.ts +1 -0
- package/dist/codex-cli-fallback.js +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/{contradiction-scan-3Z6YW7YA.js → contradiction-scan-QTXAMBUA.js} +3 -2
- package/dist/contradiction-scan-QTXAMBUA.js.map +1 -0
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer-wiring.js +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/{engine-FOC3IJLA.js → engine-35M5BKQ7.js} +7 -7
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +5 -5
- package/dist/entity-schema.d.ts +1 -1
- package/dist/event-order-recall.d.ts +17 -0
- package/dist/event-order-recall.js +11 -0
- package/dist/event-order-recall.js.map +1 -0
- package/dist/evidence-pack.d.ts +3 -1
- package/dist/evidence-pack.js +5 -3
- package/dist/explicit-capture.d.ts +4 -2
- package/dist/explicit-cue-recall.d.ts +19 -1
- package/dist/explicit-cue-recall.js +10 -4
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +8 -7
- package/dist/fallback-llm.d.ts +2 -1
- package/dist/fallback-llm.js +4 -4
- package/dist/focused-list-recall.d.ts +17 -0
- package/dist/focused-list-recall.js +11 -0
- package/dist/focused-list-recall.js.map +1 -0
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/{index-1qIcnbG1.d.ts → index-DJ9QWMw-.d.ts} +3 -2
- package/dist/index.d.ts +49 -12
- package/dist/index.js +289 -115
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +1 -1
- package/dist/intent.js +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +8 -4
- package/dist/local-llm.js +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +106 -0
- package/dist/mcp-memory-inspector-app.js +20 -0
- package/dist/mcp-memory-inspector-app.js.map +1 -0
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/{memory-governance-F3QOJGEY.js → memory-governance-IMPQZXFC.js} +7 -7
- package/dist/memory-governance-IMPQZXFC.js.map +1 -0
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +57 -0
- package/dist/memory-provenance.js +13 -0
- package/dist/memory-provenance.js.map +1 -0
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/objective-state-writers.d.ts +1 -1
- package/dist/objective-state-writers.js +2 -2
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +11 -11
- package/dist/{orchestrator-6IvQ-Phj.d.ts → orchestrator-DDMPqU6R.d.ts} +10 -1
- package/dist/orchestrator.d.ts +4 -2
- package/dist/orchestrator.js +53 -46
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +3 -1
- package/dist/recall-explain-renderer.js +5 -3
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +3 -1
- package/dist/recall-xray-cli.d.ts +3 -1
- package/dist/recall-xray-cli.js +6 -4
- package/dist/recall-xray-renderer.d.ts +3 -1
- package/dist/recall-xray-renderer.js +5 -3
- package/dist/recall-xray.d.ts +8 -1
- package/dist/recall-xray.js +4 -2
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resolve-provider-secret.js +1 -1
- package/dist/response-guidance-recall.d.ts +18 -0
- package/dist/response-guidance-recall.js +11 -0
- package/dist/response-guidance-recall.js.map +1 -0
- package/dist/resume-bundles.js +3 -3
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/sdk-compat.d.ts +3 -2
- package/dist/sdk-compat.js.map +1 -1
- package/dist/semantic-consolidation.d.ts +1 -1
- package/dist/semantic-consolidation.js +6 -6
- package/dist/semantic-rule-promotion.js +5 -5
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +6 -6
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +3 -1
- package/dist/storage.js +4 -4
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +6 -6
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/targeted-fact-recall.d.ts +17 -0
- package/dist/targeted-fact-recall.js +11 -0
- package/dist/targeted-fact-recall.js.map +1 -0
- package/dist/telemetry-transcript.d.ts +7 -0
- package/dist/telemetry-transcript.js +16 -0
- package/dist/telemetry-transcript.js.map +1 -0
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-supersession.js +2 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/tokens.js +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/trust-zones.d.ts +3 -2
- package/dist/trust-zones.js +1 -1
- package/dist/types.d.ts +60 -2
- package/dist/types.js +1 -1
- package/dist/user-model.d.ts +37 -0
- package/dist/user-model.js +28 -0
- package/dist/user-model.js.map +1 -0
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +6 -6
- package/package.json +1 -1
- package/dist/chunk-2YMTO4ZJ.js.map +0 -1
- package/dist/chunk-363MWCD3.js.map +0 -1
- package/dist/chunk-36CTNQY7.js.map +0 -1
- package/dist/chunk-5GCNE7CN.js.map +0 -1
- package/dist/chunk-6AUUAZEX.js.map +0 -1
- package/dist/chunk-6Z6UH6TK.js.map +0 -1
- package/dist/chunk-74WWN7ZW.js +0 -82
- package/dist/chunk-74WWN7ZW.js.map +0 -1
- package/dist/chunk-A4ACKWIW.js.map +0 -1
- package/dist/chunk-EQINRHYR.js.map +0 -1
- package/dist/chunk-ERUDW6DU.js +0 -965
- package/dist/chunk-ERUDW6DU.js.map +0 -1
- package/dist/chunk-GGD5W7TB.js.map +0 -1
- package/dist/chunk-IBX3VFOM.js.map +0 -1
- package/dist/chunk-KWBPHZUU.js.map +0 -1
- package/dist/chunk-MCC6KDQF.js.map +0 -1
- package/dist/chunk-NN3LPQ5D.js.map +0 -1
- package/dist/chunk-O4XJUPSF.js.map +0 -1
- package/dist/chunk-S3IP6R6K.js.map +0 -1
- package/dist/chunk-SRBJUAMP.js.map +0 -1
- package/dist/chunk-VQXK37XA.js.map +0 -1
- package/dist/chunk-VTU2B4VF.js.map +0 -1
- package/dist/chunk-VX2IUQFE.js.map +0 -1
- package/dist/chunk-WGK4VHGP.js.map +0 -1
- package/dist/chunk-Y5KDIOKF.js.map +0 -1
- package/dist/chunk-Z5S5HNGY.js.map +0 -1
- package/dist/chunk-ZTSE2ZJ6.js.map +0 -1
- package/dist/contradiction-scan-3Z6YW7YA.js.map +0 -1
- /package/dist/{capsule-export-LLEVB2RG.js.map → action-confidence.js.map} +0 -0
- /package/dist/{capsule-import-UW45R2MZ.js.map → capsule-export-7QNCBZOQ.js.map} +0 -0
- /package/dist/{engine-FOC3IJLA.js.map → capsule-import-EPBHD2EN.js.map} +0 -0
- /package/dist/{chunk-HJYHRE4S.js.map → chunk-242S3I2A.js.map} +0 -0
- /package/dist/{chunk-EYNQTST2.js.map → chunk-4YM32CRU.js.map} +0 -0
- /package/dist/{chunk-PHNGXFQ6.js.map → chunk-7V22HTMD.js.map} +0 -0
- /package/dist/{chunk-P73JTV34.js.map → chunk-BBE34QBJ.js.map} +0 -0
- /package/dist/{chunk-C5HUWVH2.js.map → chunk-CPKTBRS2.js.map} +0 -0
- /package/dist/{chunk-I6BQZSML.js.map → chunk-DZZPC36E.js.map} +0 -0
- /package/dist/{chunk-4DXC6HQQ.js.map → chunk-FQDPCE3I.js.map} +0 -0
- /package/dist/{chunk-57QNCUEZ.js.map → chunk-HL5LRPNA.js.map} +0 -0
- /package/dist/{chunk-QIGOEM65.js.map → chunk-IB3BFHGN.js.map} +0 -0
- /package/dist/{chunk-RXTFCYQF.js.map → chunk-JESOB2HO.js.map} +0 -0
- /package/dist/{chunk-LIO5X3CM.js.map → chunk-UVMUAWVT.js.map} +0 -0
- /package/dist/{chunk-PB5KW5PL.js.map → chunk-WEJG4TB5.js.map} +0 -0
- /package/dist/{chunk-KBYWQWSB.js.map → chunk-X7HPGUVG.js.map} +0 -0
- /package/dist/{chunk-ZL4S7ARC.js.map → chunk-Y3VMVTYX.js.map} +0 -0
- /package/dist/{chunk-6XA7UN4Z.js.map → chunk-ZNQN6ZTA.js.map} +0 -0
- /package/dist/{chunk-WTFWLUSX.js.map → chunk-ZVTKDVVM.js.map} +0 -0
- /package/dist/{memory-governance-F3QOJGEY.js.map → engine-35M5BKQ7.js.map} +0 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeRetrievedMemoryProvenance
|
|
3
|
+
} from "./chunk-AC5LO7IU.js";
|
|
4
|
+
|
|
5
|
+
// src/action-confidence.ts
|
|
6
|
+
var ACTION_CONFIDENCE_DECISIONS = [
|
|
7
|
+
"ask",
|
|
8
|
+
"draft",
|
|
9
|
+
"act",
|
|
10
|
+
"refuse",
|
|
11
|
+
"escalate"
|
|
12
|
+
];
|
|
13
|
+
var ACTION_CONFIDENCE_RISK_CATEGORIES = [
|
|
14
|
+
"low",
|
|
15
|
+
"medium",
|
|
16
|
+
"high",
|
|
17
|
+
"irreversible",
|
|
18
|
+
"restricted"
|
|
19
|
+
];
|
|
20
|
+
var ACTION_CONFIDENCE_CONTEXT_READINESS = [
|
|
21
|
+
"none",
|
|
22
|
+
"partial",
|
|
23
|
+
"sufficient"
|
|
24
|
+
];
|
|
25
|
+
var ACTION_CONFIDENCE_RULE_KINDS = [
|
|
26
|
+
"ask-before",
|
|
27
|
+
"do-not-use-outside-this-context",
|
|
28
|
+
"never",
|
|
29
|
+
"requires-escalation"
|
|
30
|
+
];
|
|
31
|
+
var ATTENTION_PRINCIPLE = "A good agent should spend the user's attention carefully.";
|
|
32
|
+
function assertConfidence(value, label) {
|
|
33
|
+
if (value === void 0) return void 0;
|
|
34
|
+
if (!Number.isFinite(value) || value < 0 || value > 1) {
|
|
35
|
+
throw new TypeError(`${label} must be a finite number between 0 and 1`);
|
|
36
|
+
}
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
function roundConfidence(value) {
|
|
40
|
+
return Math.round(Math.max(0, Math.min(1, value)) * 100) / 100;
|
|
41
|
+
}
|
|
42
|
+
function normalizeMemory(input) {
|
|
43
|
+
const normalized = normalizeRetrievedMemoryProvenance({
|
|
44
|
+
source: input.source,
|
|
45
|
+
created: input.created,
|
|
46
|
+
updated: input.updated,
|
|
47
|
+
scope: input.scope,
|
|
48
|
+
userContextScopes: input.userContextScopes,
|
|
49
|
+
retrievalReason: input.retrievalReason,
|
|
50
|
+
confidence: assertConfidence(input.confidence, "retrievedMemories[].confidence"),
|
|
51
|
+
stale: input.stale,
|
|
52
|
+
corrected: input.corrected,
|
|
53
|
+
correctionState: input.correctionState,
|
|
54
|
+
safeToUse: input.safeToUse,
|
|
55
|
+
safety: input.safety,
|
|
56
|
+
safetyReasons: input.safetyReasons
|
|
57
|
+
});
|
|
58
|
+
if (!normalized) {
|
|
59
|
+
throw new TypeError("retrievedMemories[] must be an object");
|
|
60
|
+
}
|
|
61
|
+
return normalized;
|
|
62
|
+
}
|
|
63
|
+
function inferContextReadiness(input, memories) {
|
|
64
|
+
if (input.contextReadiness) return input.contextReadiness;
|
|
65
|
+
if (memories.some((memory) => memory.safeToUse && !memory.stale)) {
|
|
66
|
+
return "partial";
|
|
67
|
+
}
|
|
68
|
+
return "none";
|
|
69
|
+
}
|
|
70
|
+
function hasScopeMismatch(memory, currentContextScopes) {
|
|
71
|
+
if (memory.userContextScopes.length === 0 || currentContextScopes.size === 0) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
return !memory.userContextScopes.some((scope) => currentContextScopes.has(scope));
|
|
75
|
+
}
|
|
76
|
+
function matchedRules(input) {
|
|
77
|
+
return (input.userRules ?? []).filter((rule) => rule.matched !== false);
|
|
78
|
+
}
|
|
79
|
+
function ruleLabel(rule) {
|
|
80
|
+
return rule.description?.trim() || rule.kind;
|
|
81
|
+
}
|
|
82
|
+
function splitActionConfidenceList(value) {
|
|
83
|
+
if (typeof value !== "string") return void 0;
|
|
84
|
+
const items = value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
|
|
85
|
+
return items.length > 0 ? items : void 0;
|
|
86
|
+
}
|
|
87
|
+
function buildActionConfidenceInputFromOptions(options) {
|
|
88
|
+
let confidence;
|
|
89
|
+
if (options.confidence !== void 0) {
|
|
90
|
+
if (typeof options.confidence !== "string") {
|
|
91
|
+
throw new Error("--confidence requires a value between 0 and 1");
|
|
92
|
+
}
|
|
93
|
+
confidence = Number(options.confidence);
|
|
94
|
+
if (!Number.isFinite(confidence) || confidence < 0 || confidence > 1) {
|
|
95
|
+
throw new Error(`--confidence must be a finite number between 0 and 1 (got ${JSON.stringify(options.confidence)})`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
let risk;
|
|
99
|
+
if (options.risk !== void 0) {
|
|
100
|
+
if (typeof options.risk !== "string" || !ACTION_CONFIDENCE_RISK_CATEGORIES.includes(options.risk)) {
|
|
101
|
+
throw new Error(`--risk must be one of: ${ACTION_CONFIDENCE_RISK_CATEGORIES.join(", ")}`);
|
|
102
|
+
}
|
|
103
|
+
risk = options.risk;
|
|
104
|
+
}
|
|
105
|
+
let contextReadiness;
|
|
106
|
+
if (options.context !== void 0) {
|
|
107
|
+
if (typeof options.context !== "string" || !ACTION_CONFIDENCE_CONTEXT_READINESS.includes(options.context)) {
|
|
108
|
+
throw new Error(`--context must be one of: ${ACTION_CONFIDENCE_CONTEXT_READINESS.join(", ")}`);
|
|
109
|
+
}
|
|
110
|
+
contextReadiness = options.context;
|
|
111
|
+
}
|
|
112
|
+
const ruleKinds = splitActionConfidenceList(options.rule);
|
|
113
|
+
const userRules = ruleKinds?.map((kind) => {
|
|
114
|
+
if (!ACTION_CONFIDENCE_RULE_KINDS.includes(kind)) {
|
|
115
|
+
throw new Error(`--rule entries must be one of: ${ACTION_CONFIDENCE_RULE_KINDS.join(", ")}`);
|
|
116
|
+
}
|
|
117
|
+
return { kind };
|
|
118
|
+
});
|
|
119
|
+
const currentContextScopes = splitActionConfidenceList(options.currentScope);
|
|
120
|
+
const memoryScopes = splitActionConfidenceList(options.memoryScope);
|
|
121
|
+
const hasMemoryFlags = memoryScopes !== void 0 || options.stale === true || options.corrected === true || options.unsafe === true;
|
|
122
|
+
return {
|
|
123
|
+
...typeof options.action === "string" && options.action.trim().length > 0 ? { intendedAction: options.action.trim() } : {},
|
|
124
|
+
...confidence !== void 0 ? { confidence } : {},
|
|
125
|
+
...risk ? { risk } : {},
|
|
126
|
+
...contextReadiness ? { contextReadiness } : {},
|
|
127
|
+
...currentContextScopes ? { currentContextScopes } : {},
|
|
128
|
+
...userRules ? { userRules } : {},
|
|
129
|
+
...hasMemoryFlags ? {
|
|
130
|
+
retrievedMemories: [
|
|
131
|
+
{
|
|
132
|
+
...confidence !== void 0 ? { confidence } : {},
|
|
133
|
+
...memoryScopes ? { userContextScopes: memoryScopes } : {},
|
|
134
|
+
...options.stale === true ? { stale: true } : {},
|
|
135
|
+
...options.corrected === true ? { corrected: true } : {},
|
|
136
|
+
...options.unsafe === true ? { safeToUse: false, safety: "blocked" } : {}
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
} : {}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function evaluateActionConfidence(input = {}) {
|
|
143
|
+
const memories = (input.retrievedMemories ?? []).map(normalizeMemory);
|
|
144
|
+
const currentContextScopes = new Set(
|
|
145
|
+
(input.currentContextScopes ?? []).map((scope) => scope.trim()).filter((scope) => scope.length > 0)
|
|
146
|
+
);
|
|
147
|
+
const rules = matchedRules(input);
|
|
148
|
+
const risk = input.risk ?? "medium";
|
|
149
|
+
const contextReadiness = inferContextReadiness(input, memories);
|
|
150
|
+
const blockedMemories = memories.filter((memory) => memory.safety === "blocked");
|
|
151
|
+
const usableMemories = memories.filter(
|
|
152
|
+
(memory) => memory.safeToUse && memory.safety !== "blocked"
|
|
153
|
+
);
|
|
154
|
+
const staleMemoryCount = usableMemories.filter((memory) => memory.stale).length;
|
|
155
|
+
const correctedMemoryCount = usableMemories.filter((memory) => memory.corrected).length;
|
|
156
|
+
const scopeMismatchCount = memories.filter(
|
|
157
|
+
(memory) => hasScopeMismatch(memory, currentContextScopes)
|
|
158
|
+
).length;
|
|
159
|
+
const explicitConfidence = assertConfidence(input.confidence, "confidence");
|
|
160
|
+
const provenanceConfidence = usableMemories.length > 0 ? usableMemories.reduce((sum, memory) => sum + memory.confidence, 0) / usableMemories.length : void 0;
|
|
161
|
+
let confidence = explicitConfidence ?? provenanceConfidence ?? 0.5;
|
|
162
|
+
const factors = [];
|
|
163
|
+
const reasons = [];
|
|
164
|
+
const blockers = [];
|
|
165
|
+
if (usableMemories.length > 0) {
|
|
166
|
+
factors.push({
|
|
167
|
+
name: "provenance",
|
|
168
|
+
status: "positive",
|
|
169
|
+
message: `${usableMemories.length} usable retrieved memory source${usableMemories.length === 1 ? "" : "s"}`
|
|
170
|
+
});
|
|
171
|
+
reasons.push("Retrieved memory has usable provenance.");
|
|
172
|
+
} else if (memories.length > 0) {
|
|
173
|
+
factors.push({
|
|
174
|
+
name: "provenance",
|
|
175
|
+
status: "negative",
|
|
176
|
+
message: "Retrieved memory exists, but none is safe and usable."
|
|
177
|
+
});
|
|
178
|
+
} else {
|
|
179
|
+
factors.push({
|
|
180
|
+
name: "provenance",
|
|
181
|
+
status: "neutral",
|
|
182
|
+
message: "No retrieved memories were supplied."
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
if (contextReadiness === "none") {
|
|
186
|
+
confidence -= 0.25;
|
|
187
|
+
factors.push({
|
|
188
|
+
name: "context",
|
|
189
|
+
status: "negative",
|
|
190
|
+
message: "No usable context was supplied."
|
|
191
|
+
});
|
|
192
|
+
} else if (contextReadiness === "sufficient") {
|
|
193
|
+
confidence += 0.08;
|
|
194
|
+
factors.push({
|
|
195
|
+
name: "context",
|
|
196
|
+
status: "positive",
|
|
197
|
+
message: "Caller marked the context as sufficient."
|
|
198
|
+
});
|
|
199
|
+
} else {
|
|
200
|
+
factors.push({
|
|
201
|
+
name: "context",
|
|
202
|
+
status: "neutral",
|
|
203
|
+
message: "Caller supplied partial context."
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
if (staleMemoryCount > 0) {
|
|
207
|
+
confidence -= Math.min(0.25, staleMemoryCount * 0.08);
|
|
208
|
+
factors.push({
|
|
209
|
+
name: "staleness",
|
|
210
|
+
status: "negative",
|
|
211
|
+
message: `${staleMemoryCount} retrieved memory source${staleMemoryCount === 1 ? " is" : "s are"} stale.`
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
if (correctedMemoryCount > 0) {
|
|
215
|
+
confidence -= Math.min(0.2, correctedMemoryCount * 0.07);
|
|
216
|
+
factors.push({
|
|
217
|
+
name: "correction",
|
|
218
|
+
status: "negative",
|
|
219
|
+
message: `${correctedMemoryCount} retrieved memory source${correctedMemoryCount === 1 ? " has" : "s have"} correction history.`
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (scopeMismatchCount > 0) {
|
|
223
|
+
confidence -= Math.min(0.35, scopeMismatchCount * 0.12);
|
|
224
|
+
factors.push({
|
|
225
|
+
name: "scope",
|
|
226
|
+
status: "negative",
|
|
227
|
+
message: `${scopeMismatchCount} retrieved memory source${scopeMismatchCount === 1 ? " does" : "s do"} not match the current context scope.`
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
if (blockedMemories.length > 0) {
|
|
231
|
+
blockers.push(`${blockedMemories.length} retrieved memory source${blockedMemories.length === 1 ? " is" : "s are"} blocked by safety or boundary metadata.`);
|
|
232
|
+
}
|
|
233
|
+
for (const rule of rules) {
|
|
234
|
+
if (rule.kind === "never") {
|
|
235
|
+
blockers.push(`User rule forbids this action: ${ruleLabel(rule)}.`);
|
|
236
|
+
} else if (rule.kind === "do-not-use-outside-this-context") {
|
|
237
|
+
blockers.push(`User boundary rule blocks this context: ${ruleLabel(rule)}.`);
|
|
238
|
+
} else if (rule.kind === "ask-before") {
|
|
239
|
+
reasons.push(`Matched ask-before rule: ${ruleLabel(rule)}.`);
|
|
240
|
+
} else if (rule.kind === "requires-escalation") {
|
|
241
|
+
reasons.push(`Matched escalation rule: ${ruleLabel(rule)}.`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
confidence = roundConfidence(confidence);
|
|
245
|
+
let decision;
|
|
246
|
+
if (blockers.length > 0) {
|
|
247
|
+
decision = "refuse";
|
|
248
|
+
} else if (rules.some((rule) => rule.kind === "requires-escalation") || risk === "restricted") {
|
|
249
|
+
decision = "escalate";
|
|
250
|
+
} else if (contextReadiness === "none") {
|
|
251
|
+
decision = "ask";
|
|
252
|
+
} else if (rules.some((rule) => rule.kind === "ask-before") || risk === "irreversible") {
|
|
253
|
+
decision = "ask";
|
|
254
|
+
} else if (risk === "high") {
|
|
255
|
+
decision = confidence >= 0.85 && contextReadiness === "sufficient" ? "draft" : "ask";
|
|
256
|
+
} else if (risk === "medium") {
|
|
257
|
+
if (confidence >= 0.85 && contextReadiness === "sufficient") {
|
|
258
|
+
decision = "act";
|
|
259
|
+
} else if (confidence >= 0.55) {
|
|
260
|
+
decision = "draft";
|
|
261
|
+
} else {
|
|
262
|
+
decision = "ask";
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
if (confidence >= 0.7 && contextReadiness === "sufficient") {
|
|
266
|
+
decision = "act";
|
|
267
|
+
} else if (confidence >= 0.45) {
|
|
268
|
+
decision = "draft";
|
|
269
|
+
} else {
|
|
270
|
+
decision = "ask";
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (decision === "act") {
|
|
274
|
+
reasons.push("Confidence, context readiness, scope, and risk allow acting without another interruption.");
|
|
275
|
+
} else if (decision === "draft") {
|
|
276
|
+
reasons.push("Drafting preserves momentum while avoiding an externally visible action.");
|
|
277
|
+
} else if (decision === "ask") {
|
|
278
|
+
reasons.push("Asking is the lowest-cost way to resolve missing or risky context.");
|
|
279
|
+
} else if (decision === "escalate") {
|
|
280
|
+
reasons.push("The request is outside the normal action-confidence envelope.");
|
|
281
|
+
} else {
|
|
282
|
+
reasons.push("The action should not proceed with the supplied memory context.");
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
schemaVersion: 1,
|
|
286
|
+
decision,
|
|
287
|
+
confidence,
|
|
288
|
+
risk,
|
|
289
|
+
contextReadiness,
|
|
290
|
+
...input.intendedAction ? { intendedAction: input.intendedAction } : {},
|
|
291
|
+
attentionPolicy: "interruption_budgeting",
|
|
292
|
+
principle: ATTENTION_PRINCIPLE,
|
|
293
|
+
reasons,
|
|
294
|
+
blockers,
|
|
295
|
+
factors,
|
|
296
|
+
retrievedMemoryCount: memories.length,
|
|
297
|
+
usableMemoryCount: usableMemories.length,
|
|
298
|
+
staleMemoryCount,
|
|
299
|
+
correctedMemoryCount,
|
|
300
|
+
scopeMismatchCount,
|
|
301
|
+
safeToAct: decision === "act"
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
function renderActionConfidenceText(result) {
|
|
305
|
+
const lines = [
|
|
306
|
+
`Action confidence: ${result.decision} (${result.confidence.toFixed(2)})`,
|
|
307
|
+
`Risk: ${result.risk}`,
|
|
308
|
+
`Context: ${result.contextReadiness}`,
|
|
309
|
+
`Policy: interruption_budgeting - ${result.principle}`,
|
|
310
|
+
`Memories: ${result.usableMemoryCount}/${result.retrievedMemoryCount} usable`
|
|
311
|
+
];
|
|
312
|
+
if (result.intendedAction) {
|
|
313
|
+
lines.splice(1, 0, `Action: ${result.intendedAction}`);
|
|
314
|
+
}
|
|
315
|
+
if (result.blockers.length > 0) {
|
|
316
|
+
lines.push("", "Blockers:");
|
|
317
|
+
for (const blocker of result.blockers) lines.push(`- ${blocker}`);
|
|
318
|
+
}
|
|
319
|
+
if (result.reasons.length > 0) {
|
|
320
|
+
lines.push("", "Reasons:");
|
|
321
|
+
for (const reason of result.reasons) lines.push(`- ${reason}`);
|
|
322
|
+
}
|
|
323
|
+
return `${lines.join("\n")}
|
|
324
|
+
`;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export {
|
|
328
|
+
ACTION_CONFIDENCE_DECISIONS,
|
|
329
|
+
ACTION_CONFIDENCE_RISK_CATEGORIES,
|
|
330
|
+
ACTION_CONFIDENCE_CONTEXT_READINESS,
|
|
331
|
+
ACTION_CONFIDENCE_RULE_KINDS,
|
|
332
|
+
buildActionConfidenceInputFromOptions,
|
|
333
|
+
evaluateActionConfidence,
|
|
334
|
+
renderActionConfidenceText
|
|
335
|
+
};
|
|
336
|
+
//# sourceMappingURL=chunk-AH2JUU6X.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/action-confidence.ts"],"sourcesContent":["import {\n normalizeRetrievedMemoryProvenance,\n type RetrievedMemoryCorrectionState,\n type RetrievedMemoryProvenance,\n type RetrievedMemorySafety,\n} from \"./memory-provenance.js\";\n\nexport const ACTION_CONFIDENCE_DECISIONS = [\n \"ask\",\n \"draft\",\n \"act\",\n \"refuse\",\n \"escalate\",\n] as const;\n\nexport type ActionConfidenceDecision = typeof ACTION_CONFIDENCE_DECISIONS[number];\n\nexport const ACTION_CONFIDENCE_RISK_CATEGORIES = [\n \"low\",\n \"medium\",\n \"high\",\n \"irreversible\",\n \"restricted\",\n] as const;\n\nexport type ActionConfidenceRiskCategory = typeof ACTION_CONFIDENCE_RISK_CATEGORIES[number];\n\nexport const ACTION_CONFIDENCE_CONTEXT_READINESS = [\n \"none\",\n \"partial\",\n \"sufficient\",\n] as const;\n\nexport type ActionConfidenceContextReadiness =\n typeof ACTION_CONFIDENCE_CONTEXT_READINESS[number];\n\nexport const ACTION_CONFIDENCE_RULE_KINDS = [\n \"ask-before\",\n \"do-not-use-outside-this-context\",\n \"never\",\n \"requires-escalation\",\n] as const;\n\nexport type ActionConfidenceRuleKind = typeof ACTION_CONFIDENCE_RULE_KINDS[number];\n\nexport interface ActionConfidenceRule {\n kind: ActionConfidenceRuleKind;\n description?: string;\n matched?: boolean;\n}\n\nexport interface ActionConfidenceMemoryInput {\n source?: string;\n created?: string;\n updated?: string;\n scope?: string;\n userContextScopes?: string[];\n retrievalReason?: string;\n confidence?: number;\n stale?: boolean;\n corrected?: boolean;\n correctionState?: RetrievedMemoryCorrectionState;\n safeToUse?: boolean;\n safety?: RetrievedMemorySafety;\n safetyReasons?: string[];\n}\n\nexport interface ActionConfidenceInput {\n intendedAction?: string;\n confidence?: number;\n risk?: ActionConfidenceRiskCategory;\n contextReadiness?: ActionConfidenceContextReadiness;\n currentContextScopes?: string[];\n userRules?: ActionConfidenceRule[];\n retrievedMemories?: ActionConfidenceMemoryInput[];\n}\n\nexport interface ActionConfidenceOptionInput {\n action?: unknown;\n confidence?: unknown;\n risk?: unknown;\n context?: unknown;\n rule?: unknown;\n currentScope?: unknown;\n memoryScope?: unknown;\n stale?: unknown;\n corrected?: unknown;\n unsafe?: unknown;\n}\n\nexport interface ActionConfidenceFactor {\n name: string;\n status: \"positive\" | \"negative\" | \"neutral\";\n message: string;\n}\n\nexport interface ActionConfidenceResult {\n schemaVersion: 1;\n decision: ActionConfidenceDecision;\n confidence: number;\n risk: ActionConfidenceRiskCategory;\n contextReadiness: ActionConfidenceContextReadiness;\n intendedAction?: string;\n attentionPolicy: \"interruption_budgeting\";\n principle: string;\n reasons: string[];\n blockers: string[];\n factors: ActionConfidenceFactor[];\n retrievedMemoryCount: number;\n usableMemoryCount: number;\n staleMemoryCount: number;\n correctedMemoryCount: number;\n scopeMismatchCount: number;\n safeToAct: boolean;\n}\n\nconst ATTENTION_PRINCIPLE =\n \"A good agent should spend the user's attention carefully.\";\n\nfunction assertConfidence(value: number | undefined, label: string): number | undefined {\n if (value === undefined) return undefined;\n if (!Number.isFinite(value) || value < 0 || value > 1) {\n throw new TypeError(`${label} must be a finite number between 0 and 1`);\n }\n return value;\n}\n\nfunction roundConfidence(value: number): number {\n return Math.round(Math.max(0, Math.min(1, value)) * 100) / 100;\n}\n\nfunction normalizeMemory(input: ActionConfidenceMemoryInput): RetrievedMemoryProvenance {\n const normalized = normalizeRetrievedMemoryProvenance({\n source: input.source,\n created: input.created,\n updated: input.updated,\n scope: input.scope,\n userContextScopes: input.userContextScopes,\n retrievalReason: input.retrievalReason,\n confidence: assertConfidence(input.confidence, \"retrievedMemories[].confidence\"),\n stale: input.stale,\n corrected: input.corrected,\n correctionState: input.correctionState,\n safeToUse: input.safeToUse,\n safety: input.safety,\n safetyReasons: input.safetyReasons,\n });\n if (!normalized) {\n throw new TypeError(\"retrievedMemories[] must be an object\");\n }\n return normalized;\n}\n\nfunction inferContextReadiness(input: ActionConfidenceInput, memories: RetrievedMemoryProvenance[]): ActionConfidenceContextReadiness {\n if (input.contextReadiness) return input.contextReadiness;\n if (memories.some((memory) => memory.safeToUse && !memory.stale)) {\n return \"partial\";\n }\n return \"none\";\n}\n\nfunction hasScopeMismatch(memory: RetrievedMemoryProvenance, currentContextScopes: Set<string>): boolean {\n if (memory.userContextScopes.length === 0 || currentContextScopes.size === 0) {\n return false;\n }\n return !memory.userContextScopes.some((scope) => currentContextScopes.has(scope));\n}\n\nfunction matchedRules(input: ActionConfidenceInput): ActionConfidenceRule[] {\n return (input.userRules ?? []).filter((rule) => rule.matched !== false);\n}\n\nfunction ruleLabel(rule: ActionConfidenceRule): string {\n return rule.description?.trim() || rule.kind;\n}\n\nfunction splitActionConfidenceList(value: unknown): string[] | undefined {\n if (typeof value !== \"string\") return undefined;\n const items = value\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n return items.length > 0 ? items : undefined;\n}\n\nexport function buildActionConfidenceInputFromOptions(\n options: ActionConfidenceOptionInput,\n): ActionConfidenceInput {\n let confidence: number | undefined;\n if (options.confidence !== undefined) {\n if (typeof options.confidence !== \"string\") {\n throw new Error(\"--confidence requires a value between 0 and 1\");\n }\n confidence = Number(options.confidence);\n if (!Number.isFinite(confidence) || confidence < 0 || confidence > 1) {\n throw new Error(`--confidence must be a finite number between 0 and 1 (got ${JSON.stringify(options.confidence)})`);\n }\n }\n\n let risk: ActionConfidenceRiskCategory | undefined;\n if (options.risk !== undefined) {\n if (\n typeof options.risk !== \"string\" ||\n !ACTION_CONFIDENCE_RISK_CATEGORIES.includes(options.risk as ActionConfidenceRiskCategory)\n ) {\n throw new Error(`--risk must be one of: ${ACTION_CONFIDENCE_RISK_CATEGORIES.join(\", \")}`);\n }\n risk = options.risk as ActionConfidenceRiskCategory;\n }\n\n let contextReadiness: ActionConfidenceContextReadiness | undefined;\n if (options.context !== undefined) {\n if (\n typeof options.context !== \"string\" ||\n !ACTION_CONFIDENCE_CONTEXT_READINESS.includes(options.context as ActionConfidenceContextReadiness)\n ) {\n throw new Error(`--context must be one of: ${ACTION_CONFIDENCE_CONTEXT_READINESS.join(\", \")}`);\n }\n contextReadiness = options.context as ActionConfidenceContextReadiness;\n }\n\n const ruleKinds = splitActionConfidenceList(options.rule);\n const userRules = ruleKinds?.map((kind) => {\n if (!ACTION_CONFIDENCE_RULE_KINDS.includes(kind as ActionConfidenceRuleKind)) {\n throw new Error(`--rule entries must be one of: ${ACTION_CONFIDENCE_RULE_KINDS.join(\", \")}`);\n }\n return { kind: kind as ActionConfidenceRuleKind };\n });\n const currentContextScopes = splitActionConfidenceList(options.currentScope);\n const memoryScopes = splitActionConfidenceList(options.memoryScope);\n const hasMemoryFlags =\n memoryScopes !== undefined ||\n options.stale === true ||\n options.corrected === true ||\n options.unsafe === true;\n\n return {\n ...(typeof options.action === \"string\" && options.action.trim().length > 0\n ? { intendedAction: options.action.trim() }\n : {}),\n ...(confidence !== undefined ? { confidence } : {}),\n ...(risk ? { risk } : {}),\n ...(contextReadiness ? { contextReadiness } : {}),\n ...(currentContextScopes ? { currentContextScopes } : {}),\n ...(userRules ? { userRules } : {}),\n ...(hasMemoryFlags\n ? {\n retrievedMemories: [\n {\n ...(confidence !== undefined ? { confidence } : {}),\n ...(memoryScopes ? { userContextScopes: memoryScopes } : {}),\n ...(options.stale === true ? { stale: true } : {}),\n ...(options.corrected === true ? { corrected: true } : {}),\n ...(options.unsafe === true\n ? { safeToUse: false, safety: \"blocked\" as const }\n : {}),\n },\n ],\n }\n : {}),\n };\n}\n\nexport function evaluateActionConfidence(input: ActionConfidenceInput = {}): ActionConfidenceResult {\n const memories = (input.retrievedMemories ?? []).map(normalizeMemory);\n const currentContextScopes = new Set(\n (input.currentContextScopes ?? [])\n .map((scope) => scope.trim())\n .filter((scope) => scope.length > 0),\n );\n const rules = matchedRules(input);\n const risk = input.risk ?? \"medium\";\n const contextReadiness = inferContextReadiness(input, memories);\n\n const blockedMemories = memories.filter((memory) => memory.safety === \"blocked\");\n const usableMemories = memories.filter(\n (memory) => memory.safeToUse && memory.safety !== \"blocked\",\n );\n const staleMemoryCount = usableMemories.filter((memory) => memory.stale).length;\n const correctedMemoryCount = usableMemories.filter((memory) => memory.corrected).length;\n const scopeMismatchCount = memories.filter((memory) =>\n hasScopeMismatch(memory, currentContextScopes),\n ).length;\n\n const explicitConfidence = assertConfidence(input.confidence, \"confidence\");\n const provenanceConfidence =\n usableMemories.length > 0\n ? usableMemories.reduce((sum, memory) => sum + memory.confidence, 0) / usableMemories.length\n : undefined;\n let confidence = explicitConfidence ?? provenanceConfidence ?? 0.5;\n\n const factors: ActionConfidenceFactor[] = [];\n const reasons: string[] = [];\n const blockers: string[] = [];\n\n if (usableMemories.length > 0) {\n factors.push({\n name: \"provenance\",\n status: \"positive\",\n message: `${usableMemories.length} usable retrieved memory source${usableMemories.length === 1 ? \"\" : \"s\"}`,\n });\n reasons.push(\"Retrieved memory has usable provenance.\");\n } else if (memories.length > 0) {\n factors.push({\n name: \"provenance\",\n status: \"negative\",\n message: \"Retrieved memory exists, but none is safe and usable.\",\n });\n } else {\n factors.push({\n name: \"provenance\",\n status: \"neutral\",\n message: \"No retrieved memories were supplied.\",\n });\n }\n\n if (contextReadiness === \"none\") {\n confidence -= 0.25;\n factors.push({\n name: \"context\",\n status: \"negative\",\n message: \"No usable context was supplied.\",\n });\n } else if (contextReadiness === \"sufficient\") {\n confidence += 0.08;\n factors.push({\n name: \"context\",\n status: \"positive\",\n message: \"Caller marked the context as sufficient.\",\n });\n } else {\n factors.push({\n name: \"context\",\n status: \"neutral\",\n message: \"Caller supplied partial context.\",\n });\n }\n\n if (staleMemoryCount > 0) {\n confidence -= Math.min(0.25, staleMemoryCount * 0.08);\n factors.push({\n name: \"staleness\",\n status: \"negative\",\n message: `${staleMemoryCount} retrieved memory source${staleMemoryCount === 1 ? \" is\" : \"s are\"} stale.`,\n });\n }\n\n if (correctedMemoryCount > 0) {\n confidence -= Math.min(0.2, correctedMemoryCount * 0.07);\n factors.push({\n name: \"correction\",\n status: \"negative\",\n message: `${correctedMemoryCount} retrieved memory source${correctedMemoryCount === 1 ? \" has\" : \"s have\"} correction history.`,\n });\n }\n\n if (scopeMismatchCount > 0) {\n confidence -= Math.min(0.35, scopeMismatchCount * 0.12);\n factors.push({\n name: \"scope\",\n status: \"negative\",\n message: `${scopeMismatchCount} retrieved memory source${scopeMismatchCount === 1 ? \" does\" : \"s do\"} not match the current context scope.`,\n });\n }\n\n if (blockedMemories.length > 0) {\n blockers.push(`${blockedMemories.length} retrieved memory source${blockedMemories.length === 1 ? \" is\" : \"s are\"} blocked by safety or boundary metadata.`);\n }\n\n for (const rule of rules) {\n if (rule.kind === \"never\") {\n blockers.push(`User rule forbids this action: ${ruleLabel(rule)}.`);\n } else if (rule.kind === \"do-not-use-outside-this-context\") {\n blockers.push(`User boundary rule blocks this context: ${ruleLabel(rule)}.`);\n } else if (rule.kind === \"ask-before\") {\n reasons.push(`Matched ask-before rule: ${ruleLabel(rule)}.`);\n } else if (rule.kind === \"requires-escalation\") {\n reasons.push(`Matched escalation rule: ${ruleLabel(rule)}.`);\n }\n }\n\n confidence = roundConfidence(confidence);\n\n let decision: ActionConfidenceDecision;\n if (blockers.length > 0) {\n decision = \"refuse\";\n } else if (rules.some((rule) => rule.kind === \"requires-escalation\") || risk === \"restricted\") {\n decision = \"escalate\";\n } else if (contextReadiness === \"none\") {\n decision = \"ask\";\n } else if (rules.some((rule) => rule.kind === \"ask-before\") || risk === \"irreversible\") {\n decision = \"ask\";\n } else if (risk === \"high\") {\n decision = confidence >= 0.85 && contextReadiness === \"sufficient\" ? \"draft\" : \"ask\";\n } else if (risk === \"medium\") {\n if (confidence >= 0.85 && contextReadiness === \"sufficient\") {\n decision = \"act\";\n } else if (confidence >= 0.55) {\n decision = \"draft\";\n } else {\n decision = \"ask\";\n }\n } else {\n if (confidence >= 0.7 && contextReadiness === \"sufficient\") {\n decision = \"act\";\n } else if (confidence >= 0.45) {\n decision = \"draft\";\n } else {\n decision = \"ask\";\n }\n }\n\n if (decision === \"act\") {\n reasons.push(\"Confidence, context readiness, scope, and risk allow acting without another interruption.\");\n } else if (decision === \"draft\") {\n reasons.push(\"Drafting preserves momentum while avoiding an externally visible action.\");\n } else if (decision === \"ask\") {\n reasons.push(\"Asking is the lowest-cost way to resolve missing or risky context.\");\n } else if (decision === \"escalate\") {\n reasons.push(\"The request is outside the normal action-confidence envelope.\");\n } else {\n reasons.push(\"The action should not proceed with the supplied memory context.\");\n }\n\n return {\n schemaVersion: 1,\n decision,\n confidence,\n risk,\n contextReadiness,\n ...(input.intendedAction ? { intendedAction: input.intendedAction } : {}),\n attentionPolicy: \"interruption_budgeting\",\n principle: ATTENTION_PRINCIPLE,\n reasons,\n blockers,\n factors,\n retrievedMemoryCount: memories.length,\n usableMemoryCount: usableMemories.length,\n staleMemoryCount,\n correctedMemoryCount,\n scopeMismatchCount,\n safeToAct: decision === \"act\",\n };\n}\n\nexport function renderActionConfidenceText(result: ActionConfidenceResult): string {\n const lines = [\n `Action confidence: ${result.decision} (${result.confidence.toFixed(2)})`,\n `Risk: ${result.risk}`,\n `Context: ${result.contextReadiness}`,\n `Policy: interruption_budgeting - ${result.principle}`,\n `Memories: ${result.usableMemoryCount}/${result.retrievedMemoryCount} usable`,\n ];\n if (result.intendedAction) {\n lines.splice(1, 0, `Action: ${result.intendedAction}`);\n }\n if (result.blockers.length > 0) {\n lines.push(\"\", \"Blockers:\");\n for (const blocker of result.blockers) lines.push(`- ${blocker}`);\n }\n if (result.reasons.length > 0) {\n lines.push(\"\", \"Reasons:\");\n for (const reason of result.reasons) lines.push(`- ${reason}`);\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n"],"mappings":";;;;;AAOO,IAAM,8BAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,IAAM,oCAAoC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,IAAM,sCAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AACF;AAKO,IAAM,+BAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA2EA,IAAM,sBACJ;AAEF,SAAS,iBAAiB,OAA2B,OAAmC;AACtF,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,KAAK,QAAQ,GAAG;AACrD,UAAM,IAAI,UAAU,GAAG,KAAK,0CAA0C;AAAA,EACxE;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAuB;AAC9C,SAAO,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,IAAI;AAC7D;AAEA,SAAS,gBAAgB,OAA+D;AACtF,QAAM,aAAa,mCAAmC;AAAA,IACpD,QAAQ,MAAM;AAAA,IACd,SAAS,MAAM;AAAA,IACf,SAAS,MAAM;AAAA,IACf,OAAO,MAAM;AAAA,IACb,mBAAmB,MAAM;AAAA,IACzB,iBAAiB,MAAM;AAAA,IACvB,YAAY,iBAAiB,MAAM,YAAY,gCAAgC;AAAA,IAC/E,OAAO,MAAM;AAAA,IACb,WAAW,MAAM;AAAA,IACjB,iBAAiB,MAAM;AAAA,IACvB,WAAW,MAAM;AAAA,IACjB,QAAQ,MAAM;AAAA,IACd,eAAe,MAAM;AAAA,EACvB,CAAC;AACD,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,UAAU,uCAAuC;AAAA,EAC7D;AACA,SAAO;AACT;AAEA,SAAS,sBAAsB,OAA8B,UAAyE;AACpI,MAAI,MAAM,iBAAkB,QAAO,MAAM;AACzC,MAAI,SAAS,KAAK,CAAC,WAAW,OAAO,aAAa,CAAC,OAAO,KAAK,GAAG;AAChE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,QAAmC,sBAA4C;AACvG,MAAI,OAAO,kBAAkB,WAAW,KAAK,qBAAqB,SAAS,GAAG;AAC5E,WAAO;AAAA,EACT;AACA,SAAO,CAAC,OAAO,kBAAkB,KAAK,CAAC,UAAU,qBAAqB,IAAI,KAAK,CAAC;AAClF;AAEA,SAAS,aAAa,OAAsD;AAC1E,UAAQ,MAAM,aAAa,CAAC,GAAG,OAAO,CAAC,SAAS,KAAK,YAAY,KAAK;AACxE;AAEA,SAAS,UAAU,MAAoC;AACrD,SAAO,KAAK,aAAa,KAAK,KAAK,KAAK;AAC1C;AAEA,SAAS,0BAA0B,OAAsC;AACvE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,QAAQ,MACX,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AACnC,SAAO,MAAM,SAAS,IAAI,QAAQ;AACpC;AAEO,SAAS,sCACd,SACuB;AACvB,MAAI;AACJ,MAAI,QAAQ,eAAe,QAAW;AACpC,QAAI,OAAO,QAAQ,eAAe,UAAU;AAC1C,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AACA,iBAAa,OAAO,QAAQ,UAAU;AACtC,QAAI,CAAC,OAAO,SAAS,UAAU,KAAK,aAAa,KAAK,aAAa,GAAG;AACpE,YAAM,IAAI,MAAM,6DAA6D,KAAK,UAAU,QAAQ,UAAU,CAAC,GAAG;AAAA,IACpH;AAAA,EACF;AAEA,MAAI;AACJ,MAAI,QAAQ,SAAS,QAAW;AAC9B,QACE,OAAO,QAAQ,SAAS,YACxB,CAAC,kCAAkC,SAAS,QAAQ,IAAoC,GACxF;AACA,YAAM,IAAI,MAAM,0BAA0B,kCAAkC,KAAK,IAAI,CAAC,EAAE;AAAA,IAC1F;AACA,WAAO,QAAQ;AAAA,EACjB;AAEA,MAAI;AACJ,MAAI,QAAQ,YAAY,QAAW;AACjC,QACE,OAAO,QAAQ,YAAY,YAC3B,CAAC,oCAAoC,SAAS,QAAQ,OAA2C,GACjG;AACA,YAAM,IAAI,MAAM,6BAA6B,oCAAoC,KAAK,IAAI,CAAC,EAAE;AAAA,IAC/F;AACA,uBAAmB,QAAQ;AAAA,EAC7B;AAEA,QAAM,YAAY,0BAA0B,QAAQ,IAAI;AACxD,QAAM,YAAY,WAAW,IAAI,CAAC,SAAS;AACzC,QAAI,CAAC,6BAA6B,SAAS,IAAgC,GAAG;AAC5E,YAAM,IAAI,MAAM,kCAAkC,6BAA6B,KAAK,IAAI,CAAC,EAAE;AAAA,IAC7F;AACA,WAAO,EAAE,KAAuC;AAAA,EAClD,CAAC;AACD,QAAM,uBAAuB,0BAA0B,QAAQ,YAAY;AAC3E,QAAM,eAAe,0BAA0B,QAAQ,WAAW;AAClE,QAAM,iBACJ,iBAAiB,UACjB,QAAQ,UAAU,QAClB,QAAQ,cAAc,QACtB,QAAQ,WAAW;AAErB,SAAO;AAAA,IACL,GAAI,OAAO,QAAQ,WAAW,YAAY,QAAQ,OAAO,KAAK,EAAE,SAAS,IACrE,EAAE,gBAAgB,QAAQ,OAAO,KAAK,EAAE,IACxC,CAAC;AAAA,IACL,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,IACjD,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,IACvB,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,IAC/C,GAAI,uBAAuB,EAAE,qBAAqB,IAAI,CAAC;AAAA,IACvD,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,GAAI,iBACA;AAAA,MACE,mBAAmB;AAAA,QACjB;AAAA,UACE,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,UACjD,GAAI,eAAe,EAAE,mBAAmB,aAAa,IAAI,CAAC;AAAA,UAC1D,GAAI,QAAQ,UAAU,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;AAAA,UAChD,GAAI,QAAQ,cAAc,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;AAAA,UACxD,GAAI,QAAQ,WAAW,OACnB,EAAE,WAAW,OAAO,QAAQ,UAAmB,IAC/C,CAAC;AAAA,QACP;AAAA,MACF;AAAA,IACF,IACA,CAAC;AAAA,EACP;AACF;AAEO,SAAS,yBAAyB,QAA+B,CAAC,GAA2B;AAClG,QAAM,YAAY,MAAM,qBAAqB,CAAC,GAAG,IAAI,eAAe;AACpE,QAAM,uBAAuB,IAAI;AAAA,KAC9B,MAAM,wBAAwB,CAAC,GAC7B,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AAAA,EACvC;AACA,QAAM,QAAQ,aAAa,KAAK;AAChC,QAAM,OAAO,MAAM,QAAQ;AAC3B,QAAM,mBAAmB,sBAAsB,OAAO,QAAQ;AAE9D,QAAM,kBAAkB,SAAS,OAAO,CAAC,WAAW,OAAO,WAAW,SAAS;AAC/E,QAAM,iBAAiB,SAAS;AAAA,IAC9B,CAAC,WAAW,OAAO,aAAa,OAAO,WAAW;AAAA,EACpD;AACA,QAAM,mBAAmB,eAAe,OAAO,CAAC,WAAW,OAAO,KAAK,EAAE;AACzE,QAAM,uBAAuB,eAAe,OAAO,CAAC,WAAW,OAAO,SAAS,EAAE;AACjF,QAAM,qBAAqB,SAAS;AAAA,IAAO,CAAC,WAC1C,iBAAiB,QAAQ,oBAAoB;AAAA,EAC/C,EAAE;AAEF,QAAM,qBAAqB,iBAAiB,MAAM,YAAY,YAAY;AAC1E,QAAM,uBACJ,eAAe,SAAS,IACpB,eAAe,OAAO,CAAC,KAAK,WAAW,MAAM,OAAO,YAAY,CAAC,IAAI,eAAe,SACpF;AACN,MAAI,aAAa,sBAAsB,wBAAwB;AAE/D,QAAM,UAAoC,CAAC;AAC3C,QAAM,UAAoB,CAAC;AAC3B,QAAM,WAAqB,CAAC;AAE5B,MAAI,eAAe,SAAS,GAAG;AAC7B,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,GAAG,eAAe,MAAM,kCAAkC,eAAe,WAAW,IAAI,KAAK,GAAG;AAAA,IAC3G,CAAC;AACD,YAAQ,KAAK,yCAAyC;AAAA,EACxD,WAAW,SAAS,SAAS,GAAG;AAC9B,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH,OAAO;AACL,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,MAAI,qBAAqB,QAAQ;AAC/B,kBAAc;AACd,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH,WAAW,qBAAqB,cAAc;AAC5C,kBAAc;AACd,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH,OAAO;AACL,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,MAAI,mBAAmB,GAAG;AACxB,kBAAc,KAAK,IAAI,MAAM,mBAAmB,IAAI;AACpD,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,GAAG,gBAAgB,2BAA2B,qBAAqB,IAAI,QAAQ,OAAO;AAAA,IACjG,CAAC;AAAA,EACH;AAEA,MAAI,uBAAuB,GAAG;AAC5B,kBAAc,KAAK,IAAI,KAAK,uBAAuB,IAAI;AACvD,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,GAAG,oBAAoB,2BAA2B,yBAAyB,IAAI,SAAS,QAAQ;AAAA,IAC3G,CAAC;AAAA,EACH;AAEA,MAAI,qBAAqB,GAAG;AAC1B,kBAAc,KAAK,IAAI,MAAM,qBAAqB,IAAI;AACtD,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,GAAG,kBAAkB,2BAA2B,uBAAuB,IAAI,UAAU,MAAM;AAAA,IACtG,CAAC;AAAA,EACH;AAEA,MAAI,gBAAgB,SAAS,GAAG;AAC9B,aAAS,KAAK,GAAG,gBAAgB,MAAM,2BAA2B,gBAAgB,WAAW,IAAI,QAAQ,OAAO,0CAA0C;AAAA,EAC5J;AAEA,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,SAAS;AACzB,eAAS,KAAK,kCAAkC,UAAU,IAAI,CAAC,GAAG;AAAA,IACpE,WAAW,KAAK,SAAS,mCAAmC;AAC1D,eAAS,KAAK,2CAA2C,UAAU,IAAI,CAAC,GAAG;AAAA,IAC7E,WAAW,KAAK,SAAS,cAAc;AACrC,cAAQ,KAAK,4BAA4B,UAAU,IAAI,CAAC,GAAG;AAAA,IAC7D,WAAW,KAAK,SAAS,uBAAuB;AAC9C,cAAQ,KAAK,4BAA4B,UAAU,IAAI,CAAC,GAAG;AAAA,IAC7D;AAAA,EACF;AAEA,eAAa,gBAAgB,UAAU;AAEvC,MAAI;AACJ,MAAI,SAAS,SAAS,GAAG;AACvB,eAAW;AAAA,EACb,WAAW,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,qBAAqB,KAAK,SAAS,cAAc;AAC7F,eAAW;AAAA,EACb,WAAW,qBAAqB,QAAQ;AACtC,eAAW;AAAA,EACb,WAAW,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,YAAY,KAAK,SAAS,gBAAgB;AACtF,eAAW;AAAA,EACb,WAAW,SAAS,QAAQ;AAC1B,eAAW,cAAc,QAAQ,qBAAqB,eAAe,UAAU;AAAA,EACjF,WAAW,SAAS,UAAU;AAC5B,QAAI,cAAc,QAAQ,qBAAqB,cAAc;AAC3D,iBAAW;AAAA,IACb,WAAW,cAAc,MAAM;AAC7B,iBAAW;AAAA,IACb,OAAO;AACL,iBAAW;AAAA,IACb;AAAA,EACF,OAAO;AACL,QAAI,cAAc,OAAO,qBAAqB,cAAc;AAC1D,iBAAW;AAAA,IACb,WAAW,cAAc,MAAM;AAC7B,iBAAW;AAAA,IACb,OAAO;AACL,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,MAAI,aAAa,OAAO;AACtB,YAAQ,KAAK,2FAA2F;AAAA,EAC1G,WAAW,aAAa,SAAS;AAC/B,YAAQ,KAAK,0EAA0E;AAAA,EACzF,WAAW,aAAa,OAAO;AAC7B,YAAQ,KAAK,oEAAoE;AAAA,EACnF,WAAW,aAAa,YAAY;AAClC,YAAQ,KAAK,+DAA+D;AAAA,EAC9E,OAAO;AACL,YAAQ,KAAK,iEAAiE;AAAA,EAChF;AAEA,SAAO;AAAA,IACL,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,MAAM,iBAAiB,EAAE,gBAAgB,MAAM,eAAe,IAAI,CAAC;AAAA,IACvE,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA,sBAAsB,SAAS;AAAA,IAC/B,mBAAmB,eAAe;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,aAAa;AAAA,EAC1B;AACF;AAEO,SAAS,2BAA2B,QAAwC;AACjF,QAAM,QAAQ;AAAA,IACZ,sBAAsB,OAAO,QAAQ,KAAK,OAAO,WAAW,QAAQ,CAAC,CAAC;AAAA,IACtE,SAAS,OAAO,IAAI;AAAA,IACpB,YAAY,OAAO,gBAAgB;AAAA,IACnC,oCAAoC,OAAO,SAAS;AAAA,IACpD,aAAa,OAAO,iBAAiB,IAAI,OAAO,oBAAoB;AAAA,EACtE;AACA,MAAI,OAAO,gBAAgB;AACzB,UAAM,OAAO,GAAG,GAAG,WAAW,OAAO,cAAc,EAAE;AAAA,EACvD;AACA,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,UAAM,KAAK,IAAI,WAAW;AAC1B,eAAW,WAAW,OAAO,SAAU,OAAM,KAAK,KAAK,OAAO,EAAE;AAAA,EAClE;AACA,MAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,UAAM,KAAK,IAAI,UAAU;AACzB,eAAW,UAAU,OAAO,QAAS,OAAM,KAAK,KAAK,MAAM,EAAE;AAAA,EAC/D;AACA,SAAO,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA;AAC5B;","names":[]}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getGatewayRuntimeAuthForModel,
|
|
3
3
|
resolveProviderApiKey
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PH4C2U43.js";
|
|
5
|
+
import {
|
|
6
|
+
loadModelsJsonProviders
|
|
7
|
+
} from "./chunk-7SI52C65.js";
|
|
5
8
|
import {
|
|
6
9
|
buildChatCompletionTemperature,
|
|
7
10
|
buildChatCompletionTokenLimit,
|
|
8
11
|
shouldAssumeOpenAiChatCompletions
|
|
9
12
|
} from "./chunk-L2EXJQJP.js";
|
|
10
|
-
import {
|
|
11
|
-
loadModelsJsonProviders
|
|
12
|
-
} from "./chunk-7SI52C65.js";
|
|
13
13
|
import {
|
|
14
14
|
extractJsonCandidates
|
|
15
15
|
} from "./chunk-UZB5KHKX.js";
|
|
16
16
|
import {
|
|
17
17
|
callCodexCliFallback
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-RK6F44Y6.js";
|
|
19
19
|
import {
|
|
20
20
|
expandTildePath
|
|
21
21
|
} from "./chunk-IXEJRKCZ.js";
|
|
@@ -72,12 +72,15 @@ var FallbackLlmClient = class {
|
|
|
72
72
|
log.warn("fallback LLM: no models configured in gateway");
|
|
73
73
|
return null;
|
|
74
74
|
}
|
|
75
|
-
const runChain = async () => {
|
|
75
|
+
const runChain = async (runOptions) => {
|
|
76
76
|
for (let i = 0; i < models.length; i++) {
|
|
77
|
+
if (runOptions.signal?.aborted) {
|
|
78
|
+
throw abortReason(runOptions.signal);
|
|
79
|
+
}
|
|
77
80
|
const model = models[i];
|
|
78
81
|
const isFallback = i > 0;
|
|
79
82
|
try {
|
|
80
|
-
const result = await this.tryModel(model, messages,
|
|
83
|
+
const result = await this.tryModel(model, messages, runOptions);
|
|
81
84
|
if (result) {
|
|
82
85
|
if (isFallback) {
|
|
83
86
|
log.debug(`fallback LLM: succeeded using ${model.modelString} (fallback ${i})`);
|
|
@@ -89,6 +92,9 @@ var FallbackLlmClient = class {
|
|
|
89
92
|
};
|
|
90
93
|
}
|
|
91
94
|
} catch (err) {
|
|
95
|
+
if (runOptions.signal?.aborted) {
|
|
96
|
+
throw abortReason(runOptions.signal);
|
|
97
|
+
}
|
|
92
98
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
93
99
|
log.debug(`fallback LLM: ${model.modelString} failed (${errorMsg}), trying next...`);
|
|
94
100
|
}
|
|
@@ -102,21 +108,37 @@ var FallbackLlmClient = class {
|
|
|
102
108
|
return null;
|
|
103
109
|
}
|
|
104
110
|
let timeoutHandle;
|
|
111
|
+
const controller = new AbortController();
|
|
112
|
+
const onCallerAbort = () => {
|
|
113
|
+
controller.abort(abortReason(options.signal));
|
|
114
|
+
};
|
|
115
|
+
options.signal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
116
|
+
if (options.signal?.aborted) {
|
|
117
|
+
onCallerAbort();
|
|
118
|
+
}
|
|
119
|
+
const timedOptions = { ...options, signal: controller.signal };
|
|
120
|
+
const chain = runChain(timedOptions);
|
|
121
|
+
chain.catch(() => {
|
|
122
|
+
});
|
|
105
123
|
try {
|
|
106
124
|
return await Promise.race([
|
|
107
|
-
|
|
125
|
+
chain,
|
|
108
126
|
new Promise((resolve) => {
|
|
109
127
|
timeoutHandle = setTimeout(() => {
|
|
110
128
|
log.warn(`fallback LLM: timed out after ${options.timeoutMs}ms`);
|
|
129
|
+
controller.abort(
|
|
130
|
+
new Error(`fallback LLM timed out after ${options.timeoutMs}ms`)
|
|
131
|
+
);
|
|
111
132
|
resolve(null);
|
|
112
133
|
}, options.timeoutMs);
|
|
113
134
|
})
|
|
114
135
|
]);
|
|
115
136
|
} finally {
|
|
116
137
|
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
138
|
+
options.signal?.removeEventListener("abort", onCallerAbort);
|
|
117
139
|
}
|
|
118
140
|
}
|
|
119
|
-
return await runChain();
|
|
141
|
+
return await runChain(options);
|
|
120
142
|
}
|
|
121
143
|
/**
|
|
122
144
|
* Make a request with structured output (Zod schema).
|
|
@@ -304,7 +326,7 @@ var FallbackLlmClient = class {
|
|
|
304
326
|
effectiveConfig,
|
|
305
327
|
model.modelId,
|
|
306
328
|
messages,
|
|
307
|
-
{ timeoutMs: options.timeoutMs }
|
|
329
|
+
{ timeoutMs: options.timeoutMs, signal: options.signal }
|
|
308
330
|
);
|
|
309
331
|
}
|
|
310
332
|
if (model.providerConfig.api === "ollama-chat") {
|
|
@@ -398,6 +420,7 @@ var FallbackLlmClient = class {
|
|
|
398
420
|
const response = await fetch(url, {
|
|
399
421
|
method: "POST",
|
|
400
422
|
headers,
|
|
423
|
+
signal: options.signal,
|
|
401
424
|
body: JSON.stringify(body)
|
|
402
425
|
});
|
|
403
426
|
if (!response.ok) {
|
|
@@ -436,6 +459,7 @@ var FallbackLlmClient = class {
|
|
|
436
459
|
const response = await fetch(url, {
|
|
437
460
|
method: "POST",
|
|
438
461
|
headers,
|
|
462
|
+
signal: options.signal,
|
|
439
463
|
body: JSON.stringify({
|
|
440
464
|
model: modelId,
|
|
441
465
|
messages,
|
|
@@ -502,6 +526,7 @@ var FallbackLlmClient = class {
|
|
|
502
526
|
const response = await fetch(url, {
|
|
503
527
|
method: "POST",
|
|
504
528
|
headers,
|
|
529
|
+
signal: options.signal,
|
|
505
530
|
body: JSON.stringify(body)
|
|
506
531
|
});
|
|
507
532
|
if (!response.ok) {
|
|
@@ -554,6 +579,7 @@ var FallbackLlmClient = class {
|
|
|
554
579
|
const response = await fetch(url, {
|
|
555
580
|
method: "POST",
|
|
556
581
|
headers,
|
|
582
|
+
signal: options.signal,
|
|
557
583
|
body: JSON.stringify(body)
|
|
558
584
|
});
|
|
559
585
|
if (!response.ok) {
|
|
@@ -575,6 +601,10 @@ var FallbackLlmClient = class {
|
|
|
575
601
|
};
|
|
576
602
|
}
|
|
577
603
|
};
|
|
604
|
+
function abortReason(signal) {
|
|
605
|
+
const reason = signal?.reason;
|
|
606
|
+
return reason instanceof Error ? reason : new Error("fallback LLM request aborted");
|
|
607
|
+
}
|
|
578
608
|
function normalizeRuntimePath(value) {
|
|
579
609
|
if (typeof value !== "string") return void 0;
|
|
580
610
|
const trimmed = value.trim();
|
|
@@ -610,4 +640,4 @@ function extractResponsesOutputText(data) {
|
|
|
610
640
|
export {
|
|
611
641
|
FallbackLlmClient
|
|
612
642
|
};
|
|
613
|
-
//# sourceMappingURL=chunk-
|
|
643
|
+
//# sourceMappingURL=chunk-AQJNPMOA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/fallback-llm.ts"],"sourcesContent":["import { log } from \"./logger.js\";\nimport path from \"node:path\";\nimport type { GatewayConfig, ModelProviderConfig, AgentPersona } from \"./types.js\";\nimport { extractJsonCandidates } from \"./json-extract.js\";\nimport {\n buildChatCompletionTemperature,\n buildChatCompletionTokenLimit,\n shouldAssumeOpenAiChatCompletions,\n} from \"./openai-chat-compat.js\";\nimport { resolveProviderApiKey, getGatewayRuntimeAuthForModel } from \"./resolve-provider-secret.js\";\nimport { loadModelsJsonProviders } from \"./models-json.js\";\nimport { callCodexCliFallback } from \"./codex-cli-fallback.js\";\nimport { resolveHomeDir } from \"./runtime/env.js\";\nimport { expandTildePath } from \"./utils/path.js\";\n\nexport interface FallbackLlmOptions {\n temperature?: number;\n maxTokens?: number;\n timeoutMs?: number;\n signal?: AbortSignal;\n /** Override which agent persona's model chain to use (by ID from agents.list[]). */\n agentId?: string;\n}\n\nexport interface FallbackLlmResponse {\n content: string;\n modelUsed: string;\n usage?: {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n };\n}\n\nexport interface FallbackLlmRuntimeContext {\n agentDir?: string;\n workspaceDir?: string;\n}\n\ninterface ModelRef {\n providerId: string;\n modelId: string;\n providerConfig: ModelProviderConfig;\n modelString: string;\n}\n\nconst PROVIDER_ALIASES: Record<string, readonly string[]> = {\n \"openai-codex\": [\"codex\"],\n codex: [\"openai-codex\"],\n \"claude-cli\": [\"anthropic\"],\n};\n\nconst LEGACY_PROVIDER_IDS = new Set([\"openai-codex\", \"claude-cli\"]);\n\nconst MANAGED_SECRETREF_MARKER = [\"secretref\", \"managed\"].join(\"-\");\nconst PROVIDER_API_KEY_FIELD = [\"api\", \"Key\"].join(\"\") as keyof ModelProviderConfig;\n\nconst BUILT_IN_PROVIDER_FALLBACKS: Record<string, ModelProviderConfig> = {\n anthropic: {\n baseUrl: \"https://api.anthropic.com/v1\",\n api: \"anthropic-messages\",\n models: [],\n [PROVIDER_API_KEY_FIELD]: MANAGED_SECRETREF_MARKER,\n },\n};\n\n/**\n * Generic fallback LLM client that uses the gateway's default AI configuration\n * and walks through the full fallback chain (primary + fallbacks).\n * Supports OpenAI and Anthropic API formats.\n */\nexport class FallbackLlmClient {\n private gatewayConfig: GatewayConfig | undefined;\n private runtimeContext: FallbackLlmRuntimeContext;\n\n constructor(\n gatewayConfig?: GatewayConfig,\n runtimeContext: FallbackLlmRuntimeContext = {},\n ) {\n this.gatewayConfig = gatewayConfig;\n this.runtimeContext = {\n ...runtimeContext,\n workspaceDir:\n normalizeRuntimePath(runtimeContext.workspaceDir) ??\n readGatewayWorkspaceDir(gatewayConfig) ??\n defaultOpenClawWorkspaceDir(),\n };\n }\n\n /**\n * Check if fallback is available (gateway config has at least one model).\n */\n isAvailable(agentId?: string): boolean {\n const models = this.getModelChain(agentId);\n return models.length > 0;\n }\n\n /**\n * Make a chat completion request using the gateway's default AI chain.\n * Tries primary first, then each fallback in order.\n * When agentId is provided, uses that agent persona's model chain instead of defaults.\n */\n async chatCompletion(\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions = {},\n ): Promise<FallbackLlmResponse | null> {\n const models = this.getModelChain(options.agentId);\n if (models.length === 0) {\n log.warn(\"fallback LLM: no models configured in gateway\");\n return null;\n }\n\n const runChain = async (\n runOptions: FallbackLlmOptions,\n ): Promise<FallbackLlmResponse | null> => {\n // Try each model in the chain\n for (let i = 0; i < models.length; i++) {\n if (runOptions.signal?.aborted) {\n throw abortReason(runOptions.signal);\n }\n const model = models[i];\n const isFallback = i > 0;\n\n try {\n const result = await this.tryModel(model, messages, runOptions);\n if (result) {\n if (isFallback) {\n log.debug(`fallback LLM: succeeded using ${model.modelString} (fallback ${i})`);\n }\n return {\n content: result.content,\n modelUsed: model.modelString,\n usage: result.usage,\n };\n }\n } catch (err) {\n if (runOptions.signal?.aborted) {\n throw abortReason(runOptions.signal);\n }\n const errorMsg = err instanceof Error ? err.message : String(err);\n log.debug(`fallback LLM: ${model.modelString} failed (${errorMsg}), trying next...`);\n // Continue to next model in chain\n }\n }\n\n log.warn(`fallback LLM: all ${models.length} models in chain failed`);\n return null;\n };\n\n if (typeof options.timeoutMs === \"number\") {\n if (options.timeoutMs <= 0) {\n log.warn(\"fallback LLM: timed out before request started\");\n return null;\n }\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n const controller = new AbortController();\n const onCallerAbort = (): void => {\n controller.abort(abortReason(options.signal));\n };\n options.signal?.addEventListener(\"abort\", onCallerAbort, { once: true });\n if (options.signal?.aborted) {\n onCallerAbort();\n }\n const timedOptions = { ...options, signal: controller.signal };\n const chain = runChain(timedOptions);\n chain.catch(() => {});\n try {\n return await Promise.race([\n chain,\n new Promise<null>((resolve) => {\n timeoutHandle = setTimeout(() => {\n log.warn(`fallback LLM: timed out after ${options.timeoutMs}ms`);\n controller.abort(\n new Error(`fallback LLM timed out after ${options.timeoutMs}ms`),\n );\n resolve(null);\n }, options.timeoutMs);\n }),\n ]);\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n options.signal?.removeEventListener(\"abort\", onCallerAbort);\n }\n }\n\n return await runChain(options);\n }\n\n /**\n * Make a request with structured output (Zod schema).\n * Returns parsed JSON or null on failure.\n */\n async parseWithSchema<T>(\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n schema: { parse: (data: unknown) => T },\n options: FallbackLlmOptions = {},\n ): Promise<T | null> {\n const detailed = await this.parseWithSchemaDetailed(messages, schema, options);\n return detailed?.result ?? null;\n }\n\n /**\n * Like parseWithSchema but also returns the model that was used,\n * so callers can emit accurate trace events.\n */\n async parseWithSchemaDetailed<T>(\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n schema: { parse: (data: unknown) => T },\n options: FallbackLlmOptions = {},\n ): Promise<{ result: T; modelUsed: string } | null> {\n const response = await this.chatCompletion(messages, options);\n if (!response?.content) return null;\n\n try {\n const candidates = extractJsonCandidates(response.content);\n for (const c of candidates) {\n try {\n const parsed = JSON.parse(c);\n return { result: schema.parse(parsed), modelUsed: response.modelUsed };\n } catch {\n // keep trying other candidates\n }\n }\n return null;\n } catch (err) {\n log.warn(\"fallback LLM: failed to parse structured output:\", err);\n return null;\n }\n }\n\n /**\n * Get the full model chain from gateway config.\n * Returns array of models in order: [primary, fallback1, fallback2, ...]\n *\n * When agentId is provided, looks up the matching entry in agents.list[]\n * and uses that persona's model chain. Falls back to agents.defaults.model\n * if agentId is not found or not provided.\n */\n private getModelChain(agentId?: string): ModelRef[] {\n const chain: ModelRef[] = [];\n const providers = this.gatewayConfig?.models?.providers ?? {};\n\n // Resolve the model config: agent persona chain or global defaults\n let modelConfig: { primary?: string; fallbacks?: string[] } | undefined;\n\n if (agentId) {\n const persona = this.gatewayConfig?.agents?.list?.find(\n (a) => a.id === agentId,\n );\n if (persona?.model) {\n modelConfig = persona.model;\n log.debug(`fallback LLM: using agent persona \"${agentId}\" model chain`);\n } else {\n log.warn(\n `fallback LLM: agent persona \"${agentId}\" not found or has no model config, falling back to defaults`,\n );\n }\n }\n\n if (!modelConfig) {\n modelConfig = this.gatewayConfig?.agents?.defaults?.model;\n }\n\n // Build list of model strings: primary + fallbacks\n const modelStrings: string[] = [];\n\n if (modelConfig?.primary) {\n modelStrings.push(modelConfig.primary);\n }\n\n if (Array.isArray(modelConfig?.fallbacks)) {\n for (const fb of modelConfig.fallbacks) {\n if (typeof fb === \"string\" && !modelStrings.includes(fb)) {\n modelStrings.push(fb);\n }\n }\n }\n\n // Parse each model string and look up provider config\n for (const modelString of modelStrings) {\n const modelRef = this.parseModelString(modelString, providers);\n if (modelRef) {\n chain.push(modelRef);\n }\n }\n\n return chain;\n }\n\n /**\n * Parse a \"provider/model\" string and look up its config.\n */\n private parseModelString(\n modelString: string,\n providers: Record<string, ModelProviderConfig>,\n ): ModelRef | null {\n // Parse \"provider/model\" format (e.g., \"openai/gpt-5.2\", \"anthropic/claude-opus-4-6\")\n const parts = modelString.split(\"/\");\n if (parts.length < 2) {\n log.warn(`fallback LLM: invalid model format: ${modelString}`);\n return null;\n }\n\n const requestedProviderId = parts[0];\n const modelId = parts.slice(1).join(\"/\"); // Handle cases like \"openai/gpt-5.2-turbo\"\n\n // Respect the active gateway config first so profile-local overrides and\n // credentials win. Fall back to the materialized models.json only when\n // the provider is absent from the loaded config (for built-in providers\n // registered by the gateway at runtime).\n const resolvedProvider = this.resolveProviderConfig(requestedProviderId, providers);\n const providerConfig = resolvedProvider?.config;\n if (!providerConfig) {\n log.warn(\n `fallback LLM: provider not found: ${requestedProviderId} ` +\n `(tried: ${this.providerResolutionCandidates(requestedProviderId).join(\", \")})`,\n );\n return null;\n }\n\n return {\n providerId: resolvedProvider.providerId,\n modelId,\n providerConfig,\n modelString,\n };\n }\n\n private resolveProviderConfig(\n providerId: string,\n providers: Record<string, ModelProviderConfig>,\n ): { providerId: string; config: ModelProviderConfig } | null {\n const candidates = this.providerResolutionCandidates(providerId);\n const aliasCandidates = candidates.filter((candidate) => candidate !== providerId);\n const fallbackCandidates = LEGACY_PROVIDER_IDS.has(providerId)\n ? [...aliasCandidates, providerId]\n : [providerId, ...aliasCandidates];\n for (const candidate of candidates) {\n const config = providers[candidate];\n if (config) {\n if (candidate !== providerId) {\n log.debug(`fallback LLM: provider \"${providerId}\" resolved via alias \"${candidate}\"`);\n }\n return { providerId: candidate, config };\n }\n }\n for (const candidate of fallbackCandidates) {\n const config = this.resolveFromModelsJson(candidate);\n if (config) {\n if (candidate !== providerId) {\n log.debug(`fallback LLM: provider \"${providerId}\" resolved via models.json alias \"${candidate}\"`);\n }\n return { providerId: candidate, config };\n }\n const builtInConfig = BUILT_IN_PROVIDER_FALLBACKS[candidate];\n if (builtInConfig) {\n if (candidate === providerId) {\n log.debug(`fallback LLM: provider \"${providerId}\" resolved from built-in defaults`);\n return { providerId, config: builtInConfig };\n }\n log.debug(`fallback LLM: provider \"${providerId}\" resolved via built-in alias \"${candidate}\"`);\n return { providerId: candidate, config: builtInConfig };\n }\n }\n return null;\n }\n\n private providerResolutionCandidates(providerId: string): string[] {\n const candidates = [providerId, ...(PROVIDER_ALIASES[providerId] ?? [])];\n return [...new Set(candidates)];\n }\n\n /**\n * Look up a provider from the gateway's materialized models.json, which\n * contains all providers including built-in ones (openai-codex, google-vertex,\n * etc.) that aren't in the user's openclaw.json but are registered by\n * gateway plugins. Returns null if the provider isn't found there either.\n */\n private resolveFromModelsJson(providerId: string): ModelProviderConfig | null {\n const allProviders = loadModelsJsonProviders();\n const config = allProviders[providerId];\n if (config) {\n log.debug(`fallback LLM: resolved provider \"${providerId}\" from models.json (api: ${config.api ?? \"default\"})`);\n return config;\n }\n return null;\n }\n\n /**\n * Try to call a single model.\n *\n * Uses the gateway's native getRuntimeAuthForModel when available — this\n * handles all provider-specific auth transforms (OAuth token exchange,\n * base URL overrides for codex/copilot/etc.) through the same codepath\n * the gateway itself uses. Falls back to resolveProviderApiKey for\n * simpler providers or when the runtime module isn't loaded.\n */\n private async tryModel(\n model: ModelRef,\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions,\n ): Promise<{ content: string; usage?: FallbackLlmResponse[\"usage\"] } | null> {\n // Try the gateway's native runtime auth first — it handles all provider-\n // specific transforms (OAuth exchange, base URL rewrite, etc.)\n const runtimeAuth = model.providerConfig.api === \"codex-cli\"\n ? null\n : await this.resolveRuntimeAuth(model);\n const effectiveBaseUrl = runtimeAuth?.baseUrl ?? model.providerConfig.baseUrl;\n const resolvedApiKey = runtimeAuth?.apiKey\n ?? (\n model.providerConfig.api === \"codex-cli\" && model.providerConfig.apiKey === undefined\n ? undefined\n : await this.resolveFallbackApiKey(model)\n );\n\n // If the raw key looks like an unresolved secret ref and resolution fails,\n // skip this provider entirely so the chain falls through to the next.\n const rawKey = model.providerConfig.apiKey;\n const needsResolution = rawKey === \"secretref-managed\"\n || (typeof rawKey === \"object\" && rawKey !== null);\n if (needsResolution && !resolvedApiKey) {\n throw new Error(`API key for provider \"${model.providerId}\" could not be resolved from secret ref`);\n }\n\n const effectiveConfig: ModelProviderConfig = {\n ...model.providerConfig,\n baseUrl: effectiveBaseUrl,\n ...(resolvedApiKey ? { apiKey: resolvedApiKey } : {}),\n };\n\n if (model.providerConfig.api === \"anthropic-messages\") {\n return await this.callAnthropic(effectiveConfig, model.modelId, messages, options);\n }\n\n if (model.providerConfig.api === \"codex-cli\") {\n return await callCodexCliFallback(\n effectiveConfig,\n model.modelId,\n messages,\n { timeoutMs: options.timeoutMs, signal: options.signal },\n );\n }\n\n if (model.providerConfig.api === \"ollama-chat\") {\n return await this.callOllamaChat(effectiveConfig, model.modelId, messages, options);\n }\n\n if (\n model.providerConfig.api === \"openai-responses\" ||\n model.providerConfig.api === \"openai-codex-responses\" ||\n model.providerConfig.api === \"azure-openai-responses\"\n ) {\n return await this.callOpenAIResponses(\n effectiveConfig,\n model.modelId,\n messages,\n options,\n );\n }\n\n // For OpenAI-compatible chat-completions APIs (openai-completions,\n // ollama, etc.) and unknown formats, use chat completions — the gateway's\n // runtime auth resolver returns request-ready base URL and credentials for\n // most providers.\n return await this.callOpenAI(\n effectiveConfig,\n model.modelId,\n messages,\n options,\n shouldAssumeOpenAiChatCompletions(effectiveConfig.baseUrl),\n );\n }\n\n /**\n * Resolve request-ready auth through the gateway's native runtime, which\n * handles provider-specific transforms (OAuth token exchange for codex/copilot,\n * base URL rewrite, etc.). Returns null if the runtime isn't available.\n */\n private async resolveRuntimeAuth(\n model: ModelRef,\n ): Promise<{ apiKey?: string; baseUrl?: string } | null> {\n try {\n const getRuntimeAuth = await getGatewayRuntimeAuthForModel();\n if (!getRuntimeAuth) return null;\n\n const result = await getRuntimeAuth({\n model: {\n provider: model.providerId,\n id: model.modelId,\n api: model.providerConfig.api,\n baseUrl: model.providerConfig.baseUrl,\n },\n cfg: this.gatewayConfig,\n workspaceDir: this.runtimeContext.workspaceDir,\n });\n\n if (result?.apiKey || result?.baseUrl) {\n log.debug(\n `fallback LLM: resolved runtime auth for \"${model.modelString}\" (source: ${result.source ?? \"unknown\"}, mode: ${result.mode ?? \"unknown\"})`,\n );\n return { apiKey: result.apiKey, baseUrl: result.baseUrl };\n }\n } catch (err) {\n log.debug(\n `fallback LLM: gateway runtime auth failed for \"${model.modelString}\": ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return null;\n }\n\n /**\n * Resolve API key through the existing provider-level resolution (env vars,\n * secret refs, etc.). Used as fallback when gateway runtime auth isn't available.\n */\n private async resolveFallbackApiKey(model: ModelRef): Promise<string | undefined> {\n return resolveProviderApiKey(\n model.providerId,\n model.providerConfig.apiKey,\n this.gatewayConfig,\n this.runtimeContext.agentDir,\n );\n }\n\n /**\n * Call OpenAI-compatible API.\n */\n private async callOpenAI(\n config: ModelProviderConfig,\n modelId: string,\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions,\n assumeOpenAI: boolean,\n ): Promise<{ content: string; usage?: FallbackLlmResponse[\"usage\"] } | null> {\n const base = config.baseUrl.replace(/\\/$/, \"\");\n const url = base.endsWith(\"/v1\")\n ? `${base}/chat/completions`\n : `${base}/v1/chat/completions`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...config.headers,\n };\n\n // Handle auth — apiKey is already resolved to a string by tryModel()\n if (config.apiKey && typeof config.apiKey === \"string\") {\n if (config.authHeader !== false) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n }\n\n const body = {\n model: modelId,\n messages,\n ...buildChatCompletionTemperature(modelId, options.temperature ?? 0.3, {\n assumeOpenAI,\n }),\n ...buildChatCompletionTokenLimit(modelId, options.maxTokens ?? 4096, {\n assumeOpenAI,\n }),\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n signal: options.signal,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`OpenAI API error: ${response.status} ${error}`);\n }\n\n const data = (await response.json()) as {\n choices: Array<{\n message: {\n content: string;\n };\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_tokens?: number;\n };\n };\n\n const content = data.choices?.[0]?.message?.content;\n if (!content) {\n throw new Error(\"Empty response from OpenAI API\");\n }\n\n return {\n content,\n usage: data.usage\n ? {\n inputTokens: data.usage.prompt_tokens,\n outputTokens: data.usage.completion_tokens,\n totalTokens: data.usage.total_tokens,\n }\n : undefined,\n };\n }\n\n /**\n * Call Ollama's native /api/chat transport. This lets benchmark-isolated\n * gateway configs route Remnic's own internal LLM calls to Ollama Cloud\n * without requiring an OpenAI-compatible shim.\n */\n private async callOllamaChat(\n config: ModelProviderConfig,\n modelId: string,\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions,\n ): Promise<{ content: string; usage?: FallbackLlmResponse[\"usage\"] } | null> {\n const base = config.baseUrl.replace(/\\/$/, \"\");\n const url = base.endsWith(\"/api\") ? `${base}/chat` : `${base}/api/chat`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...config.headers,\n };\n if (config.apiKey && typeof config.apiKey === \"string\" && config.authHeader !== false) {\n headers.Authorization = `Bearer ${config.apiKey}`;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n signal: options.signal,\n body: JSON.stringify({\n model: modelId,\n messages,\n stream: false,\n ...(config.disableThinking ? { think: false } : {}),\n options: {\n temperature: options.temperature ?? 0.3,\n num_predict: options.maxTokens ?? 4096,\n },\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Ollama API error: ${response.status} ${error}`);\n }\n\n const data = (await response.json()) as {\n message?: { content?: string };\n response?: string;\n prompt_eval_count?: number;\n eval_count?: number;\n };\n const content = data.message?.content ?? data.response;\n if (!content) {\n throw new Error(\"Empty response from Ollama API\");\n }\n\n const inputTokens = data.prompt_eval_count ?? 0;\n const outputTokens = data.eval_count ?? 0;\n return {\n content,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n },\n };\n }\n\n /**\n * Call an OpenAI-compatible Responses API.\n */\n private async callOpenAIResponses(\n config: ModelProviderConfig,\n modelId: string,\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions,\n ): Promise<{ content: string; usage?: FallbackLlmResponse[\"usage\"] } | null> {\n const base = config.baseUrl.replace(/\\/$/, \"\");\n const url = base.endsWith(\"/v1\")\n ? `${base}/responses`\n : `${base}/v1/responses`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...config.headers,\n };\n\n if (config.apiKey && typeof config.apiKey === \"string\" && config.authHeader !== false) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n\n const instructions = messages\n .filter((message) => message.role === \"system\")\n .map((message) => message.content)\n .join(\"\\n\\n\")\n .trim();\n const input = messages\n .filter((message) => message.role !== \"system\")\n .map((message) => ({\n role: message.role,\n content: [{\n type: message.role === \"assistant\" ? \"output_text\" : \"input_text\",\n text: message.content,\n }],\n }));\n\n const body: Record<string, unknown> = {\n model: modelId,\n input,\n max_output_tokens: Math.max(0, Math.floor(options.maxTokens ?? 4096)),\n ...buildChatCompletionTemperature(modelId, options.temperature ?? 0.3, {\n assumeOpenAI: shouldAssumeOpenAiChatCompletions(config.baseUrl),\n }),\n };\n if (instructions.length > 0) {\n body.instructions = instructions;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n signal: options.signal,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`OpenAI Responses API error: ${response.status} ${error}`);\n }\n\n const data = (await response.json()) as {\n output_text?: string;\n output?: Array<{\n type?: string;\n text?: string;\n content?: Array<{\n type?: string;\n text?: string;\n }>;\n }>;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n total_tokens?: number;\n };\n };\n\n const outputText = extractResponsesOutputText(data);\n if (!outputText) {\n throw new Error(\"Empty response from OpenAI Responses API\");\n }\n\n return {\n content: outputText,\n usage: data.usage\n ? {\n inputTokens: data.usage.input_tokens,\n outputTokens: data.usage.output_tokens,\n totalTokens: data.usage.total_tokens,\n }\n : undefined,\n };\n }\n\n /**\n * Call Anthropic Messages API.\n */\n private async callAnthropic(\n config: ModelProviderConfig,\n modelId: string,\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions,\n ): Promise<{ content: string; usage?: FallbackLlmResponse[\"usage\"] } | null> {\n const base = config.baseUrl.replace(/\\/$/, \"\");\n const url = base.endsWith(\"/v1\")\n ? `${base}/messages`\n : `${base}/v1/messages`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"anthropic-version\": \"2023-06-01\",\n ...config.headers,\n };\n\n // Handle auth - Anthropic uses x-api-key header (apiKey resolved by tryModel)\n if (config.apiKey && typeof config.apiKey === \"string\") {\n headers[\"x-api-key\"] = config.apiKey;\n }\n\n // Extract system message (Anthropic handles it separately)\n const systemMessage = messages.find((m) => m.role === \"system\")?.content;\n const nonSystemMessages = messages.filter((m) => m.role !== \"system\");\n\n // Convert messages to Anthropic format\n const anthropicMessages = nonSystemMessages.map((m) => ({\n role: m.role,\n content: m.content,\n }));\n\n const body: Record<string, unknown> = {\n model: modelId,\n messages: anthropicMessages,\n max_tokens: options.maxTokens ?? 4096,\n temperature: options.temperature ?? 0.3,\n };\n\n if (systemMessage) {\n body.system = systemMessage;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n signal: options.signal,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Anthropic API error: ${response.status} ${error}`);\n }\n\n const data = (await response.json()) as {\n content: Array<{\n type: string;\n text: string;\n }>;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n };\n };\n\n const content = data.content?.[0]?.text;\n if (!content) {\n throw new Error(\"Empty response from Anthropic API\");\n }\n\n return {\n content,\n usage: data.usage\n ? {\n inputTokens: data.usage.input_tokens,\n outputTokens: data.usage.output_tokens,\n totalTokens: (data.usage.input_tokens ?? 0) + (data.usage.output_tokens ?? 0),\n }\n : undefined,\n };\n }\n}\n\nfunction abortReason(signal: AbortSignal | undefined): Error {\n const reason = signal?.reason;\n return reason instanceof Error ? reason : new Error(\"fallback LLM request aborted\");\n}\n\nfunction normalizeRuntimePath(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? expandTildePath(trimmed) : undefined;\n}\n\nfunction readGatewayWorkspaceDir(gatewayConfig: GatewayConfig | undefined): string | undefined {\n if (!gatewayConfig || typeof gatewayConfig !== \"object\") return undefined;\n const raw = gatewayConfig as Record<string, unknown>;\n return (\n normalizeRuntimePath(raw.workspaceDir) ??\n normalizeRuntimePath(raw.workspacePath) ??\n normalizeRuntimePath(raw.workspace)\n );\n}\n\nfunction defaultOpenClawWorkspaceDir(): string {\n return path.join(resolveHomeDir(), \".openclaw\", \"workspace\");\n}\n\nfunction extractResponsesOutputText(data: {\n output_text?: string;\n output?: Array<{\n type?: string;\n text?: string;\n content?: Array<{\n type?: string;\n text?: string;\n }>;\n }>;\n}): string | null {\n if (typeof data.output_text === \"string\" && data.output_text.trim().length > 0) {\n return data.output_text;\n }\n\n const chunks: string[] = [];\n for (const item of data.output ?? []) {\n if (typeof item.text === \"string\" && item.text.trim().length > 0) {\n chunks.push(item.text);\n }\n for (const part of item.content ?? []) {\n if (\n (part.type === \"output_text\" || part.type === \"text\") &&\n typeof part.text === \"string\" &&\n part.text.trim().length > 0\n ) {\n chunks.push(part.text);\n }\n }\n }\n\n const joined = chunks.join(\"\\n\").trim();\n return joined.length > 0 ? joined : null;\n}\n"],"mappings":"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","names":[]}
|