@intutic/shared-types 1.9.0 → 1.10.1

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.
Files changed (122) hide show
  1. package/README.md +1 -1
  2. package/dist/anomaly.d.ts +11 -0
  3. package/dist/anomaly.d.ts.map +1 -1
  4. package/dist/api-contracts.d.ts +97 -9
  5. package/dist/api-contracts.d.ts.map +1 -1
  6. package/dist/api-contracts.js +9 -0
  7. package/dist/api-contracts.js.map +1 -1
  8. package/dist/auth.d.ts +157 -1
  9. package/dist/auth.d.ts.map +1 -1
  10. package/dist/auth.js +39 -1
  11. package/dist/auth.js.map +1 -1
  12. package/dist/billing.d.ts +2 -99
  13. package/dist/billing.d.ts.map +1 -1
  14. package/dist/billing.js +2 -17
  15. package/dist/billing.js.map +1 -1
  16. package/dist/enums.d.ts +341 -4
  17. package/dist/enums.d.ts.map +1 -1
  18. package/dist/enums.js +369 -6
  19. package/dist/enums.js.map +1 -1
  20. package/dist/errors.d.ts +20 -1
  21. package/dist/errors.d.ts.map +1 -1
  22. package/dist/errors.js +20 -1
  23. package/dist/errors.js.map +1 -1
  24. package/dist/finops.d.ts +97 -1
  25. package/dist/finops.d.ts.map +1 -1
  26. package/dist/governanceCoverage.d.ts +82 -0
  27. package/dist/governanceCoverage.d.ts.map +1 -0
  28. package/dist/governanceCoverage.js +72 -0
  29. package/dist/governanceCoverage.js.map +1 -0
  30. package/dist/guardrailIr.d.ts +287 -0
  31. package/dist/guardrailIr.d.ts.map +1 -0
  32. package/dist/guardrailIr.js +301 -0
  33. package/dist/guardrailIr.js.map +1 -0
  34. package/dist/guardrailRender.d.ts +154 -0
  35. package/dist/guardrailRender.d.ts.map +1 -0
  36. package/dist/guardrailRender.js +440 -0
  37. package/dist/guardrailRender.js.map +1 -0
  38. package/dist/identity.d.ts +75 -0
  39. package/dist/identity.d.ts.map +1 -1
  40. package/dist/identity.js +5 -1
  41. package/dist/identity.js.map +1 -1
  42. package/dist/index.d.ts +34 -14
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +124 -2
  45. package/dist/index.js.map +1 -1
  46. package/dist/intelligence.d.ts +37 -11
  47. package/dist/intelligence.d.ts.map +1 -1
  48. package/dist/intelligence.js.map +1 -1
  49. package/dist/modelCatalog.d.ts +89 -0
  50. package/dist/modelCatalog.d.ts.map +1 -0
  51. package/dist/modelCatalog.generated.d.ts +7204 -0
  52. package/dist/modelCatalog.generated.d.ts.map +1 -0
  53. package/dist/modelCatalog.generated.js +576 -0
  54. package/dist/modelCatalog.generated.js.map +1 -0
  55. package/dist/modelCatalog.js +112 -0
  56. package/dist/modelCatalog.js.map +1 -0
  57. package/dist/notifications.d.ts +134 -2
  58. package/dist/notifications.d.ts.map +1 -1
  59. package/dist/observability.d.ts +4 -0
  60. package/dist/observability.d.ts.map +1 -1
  61. package/dist/policyGuardrails.d.ts +433 -0
  62. package/dist/policyGuardrails.d.ts.map +1 -0
  63. package/dist/policyGuardrails.js +91 -0
  64. package/dist/policyGuardrails.js.map +1 -0
  65. package/dist/posturePresets.d.ts +74 -0
  66. package/dist/posturePresets.d.ts.map +1 -0
  67. package/dist/posturePresets.js +139 -0
  68. package/dist/posturePresets.js.map +1 -0
  69. package/dist/providerVerification.d.ts +64 -0
  70. package/dist/providerVerification.d.ts.map +1 -0
  71. package/dist/providerVerification.js +184 -0
  72. package/dist/providerVerification.js.map +1 -0
  73. package/dist/providers.d.ts +93 -0
  74. package/dist/providers.d.ts.map +1 -0
  75. package/dist/providers.js +176 -0
  76. package/dist/providers.js.map +1 -0
  77. package/dist/rulePredicateDsl.d.ts +101 -0
  78. package/dist/rulePredicateDsl.d.ts.map +1 -0
  79. package/dist/rulePredicateDsl.js +263 -0
  80. package/dist/rulePredicateDsl.js.map +1 -0
  81. package/dist/rulePredicateEval.d.ts +38 -0
  82. package/dist/rulePredicateEval.d.ts.map +1 -0
  83. package/dist/rulePredicateEval.js +124 -0
  84. package/dist/rulePredicateEval.js.map +1 -0
  85. package/dist/scriptScan.d.ts +162 -0
  86. package/dist/scriptScan.d.ts.map +1 -0
  87. package/dist/scriptScan.js +362 -0
  88. package/dist/scriptScan.js.map +1 -0
  89. package/dist/secretPatterns.d.ts +43 -0
  90. package/dist/secretPatterns.d.ts.map +1 -0
  91. package/dist/secretPatterns.js +73 -0
  92. package/dist/secretPatterns.js.map +1 -0
  93. package/dist/skillScan.d.ts +166 -0
  94. package/dist/skillScan.d.ts.map +1 -0
  95. package/dist/skillScan.js +398 -0
  96. package/dist/skillScan.js.map +1 -0
  97. package/dist/sop.d.ts +188 -9
  98. package/dist/sop.d.ts.map +1 -1
  99. package/dist/sop.js +54 -2
  100. package/dist/sop.js.map +1 -1
  101. package/dist/sourceProviders.d.ts +41 -0
  102. package/dist/sourceProviders.d.ts.map +1 -0
  103. package/dist/sourceProviders.js +48 -0
  104. package/dist/sourceProviders.js.map +1 -0
  105. package/dist/sync.d.ts +98 -8
  106. package/dist/sync.d.ts.map +1 -1
  107. package/dist/sync.js.map +1 -1
  108. package/dist/toon.d.ts +80 -0
  109. package/dist/toon.d.ts.map +1 -0
  110. package/dist/toon.js +278 -0
  111. package/dist/toon.js.map +1 -0
  112. package/dist/usage.d.ts +23 -0
  113. package/dist/usage.d.ts.map +1 -1
  114. package/dist/wasmHost.d.ts +58 -0
  115. package/dist/wasmHost.d.ts.map +1 -0
  116. package/dist/wasmHost.js +80 -0
  117. package/dist/wasmHost.js.map +1 -0
  118. package/dist/workspaceSettings.d.ts +463 -21
  119. package/dist/workspaceSettings.d.ts.map +1 -1
  120. package/dist/workspaceSettings.js +86 -1
  121. package/dist/workspaceSettings.js.map +1 -1
  122. package/package.json +4 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posturePresets.d.ts","sourceRoot":"","sources":["../src/posturePresets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAA;IAC1C,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACtC;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,aAAa,EAkD5C,CAAA;AAEV;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,aAAa,EA6CxC,CAAA;AAEV,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,MAAM,CAAA;AAE7C,yEAAyE;AACzE,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAGtF;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAA;IACd,oFAAoF;IACpF,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;CACpB"}
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ /**
3
+ * Posture presets — named bundles over knobs that already reach enforcement.
4
+ *
5
+ * A posture is one decision ("how should governance treat this workspace?")
6
+ * expressed over several settings a user would otherwise have to correlate by
7
+ * hand. Every key a preset writes has a verified consumer TODAY:
8
+ *
9
+ * - `featureFlags.*` sync to `workspace:feature_flags:{ws}` in Valkey on every
10
+ * settings write, and the proxy reads them per request (`store/valkey.rs`).
11
+ * - `bypassEnforcementTier` drives the sync-daemon's drift watcher.
12
+ * - `mcpProxyFailBehavior` decides whether a broken MCP proxy fails open or
13
+ * closed.
14
+ * - `featureFlags.ff_sql_drop_strict_block` is read by `GET
15
+ * /api/v1/policy/resolve` and applied by the sync daemon's
16
+ * `buildSnapshotRules` (Wave 7, audit-remediation) to promote the hook
17
+ * gate's `destructive.sql_drop` rule from warn to block.
18
+ *
19
+ * A preset key without a consumer would make the posture selector the exact
20
+ * inert control this product exists to remove, so adding one requires naming
21
+ * its reader here.
22
+ *
23
+ * Presets are DATA, applied through the same settings pipeline as a manual
24
+ * PUT — same merge semantics, same Valkey sync, same audit surface. Applying
25
+ * one records its name; editing an underlying knob afterwards clears it,
26
+ * because a posture that no longer matches its knobs is a label lying about
27
+ * the configuration.
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.COST_POSTURES = exports.SECURITY_POSTURES = void 0;
31
+ exports.findPosture = findPosture;
32
+ /**
33
+ * Security postures: how enforcement behaves when a guard fires.
34
+ */
35
+ exports.SECURITY_POSTURES = [
36
+ {
37
+ name: 'strict',
38
+ title: 'Strict',
39
+ description: 'Findings enforce in real time, harness configs are rewritten on drift and made ' +
40
+ 'immutable where the OS supports it, and a broken MCP proxy fails closed. ' +
41
+ 'The posture for regulated environments and production credentials.',
42
+ settings: {
43
+ bypassEnforcementTier: 'immutable',
44
+ mcpProxyFailBehavior: 'closed',
45
+ },
46
+ // ff_sql_drop_strict_block (Wave 7, audit-remediation): promotes the
47
+ // sync-daemon hook gate's `destructive.sql_drop` rule from warn to
48
+ // block, matching what the MCP path already does unconditionally. Read
49
+ // by `GET /api/v1/policy/resolve` (`sqlDropStrictBlock` on the
50
+ // response) and applied by the sync daemon's `buildSnapshotRules`
51
+ // (`services/sync-daemon/src/lib/policySnapshot.ts`) — a per-rule
52
+ // override, not a flip of `DESTRUCTIVE_TIER_SEVERITY`'s separate,
53
+ // evidence-gated promotion ramp for the other six destructive-command
54
+ // patterns. Accepts the dev-DSN false-positive risk explicitly, which is
55
+ // exactly the trade this posture's own description already commits to.
56
+ featureFlags: { ff_shadow_enforcement: false, ff_sql_drop_strict_block: true },
57
+ },
58
+ {
59
+ name: 'balanced',
60
+ title: 'Balanced',
61
+ description: 'Findings enforce in real time and drifted harness configs are rewritten, but ' +
62
+ 'nothing is made immutable and a broken MCP proxy fails open rather than ' +
63
+ 'blocking work. The default.',
64
+ settings: {
65
+ bypassEnforcementTier: 'rewrite',
66
+ mcpProxyFailBehavior: 'open',
67
+ },
68
+ featureFlags: { ff_shadow_enforcement: false },
69
+ },
70
+ {
71
+ name: 'observe',
72
+ title: 'Observe',
73
+ description: 'Every detector runs and every finding is recorded, but nothing blocks: shadow ' +
74
+ 'enforcement, drift creates incidents instead of rewrites, MCP fails open. The ' +
75
+ 'posture for evaluating Intutic against live traffic before letting it act.',
76
+ settings: {
77
+ bypassEnforcementTier: 'alert-only',
78
+ mcpProxyFailBehavior: 'open',
79
+ },
80
+ featureFlags: { ff_shadow_enforcement: true },
81
+ },
82
+ ];
83
+ /**
84
+ * Cost postures: how aggressively the workspace pursues savings.
85
+ *
86
+ * Deliberately conservative about what "savings" may claim: routing quality is
87
+ * guarded against malformed/truncated/unusable responses (the Response
88
+ * Integrity signal), not against worse-but-well-formed ones — so the
89
+ * aggressive posture is named for what it does, not "no quality loss".
90
+ */
91
+ exports.COST_POSTURES = [
92
+ {
93
+ name: 'savings',
94
+ title: 'Max savings',
95
+ description: 'Bandit routing enforces its selections, and both response caches serve ' +
96
+ 'repeats without an upstream call. Routing learns from measured integrity ' +
97
+ 'and cost; it detects malformed and truncated responses, not subtly worse ones.',
98
+ settings: {},
99
+ featureFlags: {
100
+ ff_bandit_routing: true,
101
+ ff_shadow_routing: false,
102
+ ff_response_cache_exact: true,
103
+ ff_response_cache_semantic: true,
104
+ },
105
+ },
106
+ {
107
+ name: 'balanced',
108
+ title: 'Balanced',
109
+ description: 'Routing runs in shadow — it reports what it would have picked and what that ' +
110
+ 'would have saved, while every request is served by the model you asked for. ' +
111
+ 'Exact-match caching on; semantic caching off.',
112
+ settings: {},
113
+ featureFlags: {
114
+ ff_bandit_routing: false,
115
+ ff_shadow_routing: true,
116
+ ff_response_cache_exact: true,
117
+ ff_response_cache_semantic: false,
118
+ },
119
+ },
120
+ {
121
+ name: 'quality-first',
122
+ title: 'Quality first',
123
+ description: 'No routing, no semantic cache: every request is served by the requested ' +
124
+ 'model, fresh, with only byte-identical repeats served from cache.',
125
+ settings: {},
126
+ featureFlags: {
127
+ ff_bandit_routing: false,
128
+ ff_shadow_routing: false,
129
+ ff_response_cache_exact: true,
130
+ ff_response_cache_semantic: false,
131
+ },
132
+ },
133
+ ];
134
+ /** Look up a preset, or nothing — the route turns nothing into a 400. */
135
+ function findPosture(kind, name) {
136
+ const set = kind === 'security' ? exports.SECURITY_POSTURES : exports.COST_POSTURES;
137
+ return set.find((p) => p.name === name);
138
+ }
139
+ //# sourceMappingURL=posturePresets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posturePresets.js","sourceRoot":"","sources":["../src/posturePresets.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;AA6HH,kCAGC;AApHD;;GAEG;AACU,QAAA,iBAAiB,GAA6B;IACzD;QACE,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,QAAQ;QACf,WAAW,EACT,iFAAiF;YACjF,2EAA2E;YAC3E,oEAAoE;QACtE,QAAQ,EAAE;YACR,qBAAqB,EAAE,WAAW;YAClC,oBAAoB,EAAE,QAAQ;SAC/B;QACD,qEAAqE;QACrE,mEAAmE;QACnE,uEAAuE;QACvE,+DAA+D;QAC/D,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,sEAAsE;QACtE,yEAAyE;QACzE,uEAAuE;QACvE,YAAY,EAAE,EAAE,qBAAqB,EAAE,KAAK,EAAE,wBAAwB,EAAE,IAAI,EAAE;KAC/E;IACD;QACE,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,UAAU;QACjB,WAAW,EACT,+EAA+E;YAC/E,0EAA0E;YAC1E,6BAA6B;QAC/B,QAAQ,EAAE;YACR,qBAAqB,EAAE,SAAS;YAChC,oBAAoB,EAAE,MAAM;SAC7B;QACD,YAAY,EAAE,EAAE,qBAAqB,EAAE,KAAK,EAAE;KAC/C;IACD;QACE,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,WAAW,EACT,gFAAgF;YAChF,gFAAgF;YAChF,4EAA4E;QAC9E,QAAQ,EAAE;YACR,qBAAqB,EAAE,YAAY;YACnC,oBAAoB,EAAE,MAAM;SAC7B;QACD,YAAY,EAAE,EAAE,qBAAqB,EAAE,IAAI,EAAE;KAC9C;CACO,CAAA;AAEV;;;;;;;GAOG;AACU,QAAA,aAAa,GAA6B;IACrD;QACE,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,aAAa;QACpB,WAAW,EACT,yEAAyE;YACzE,2EAA2E;YAC3E,gFAAgF;QAClF,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE;YACZ,iBAAiB,EAAE,IAAI;YACvB,iBAAiB,EAAE,KAAK;YACxB,uBAAuB,EAAE,IAAI;YAC7B,0BAA0B,EAAE,IAAI;SACjC;KACF;IACD;QACE,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,UAAU;QACjB,WAAW,EACT,8EAA8E;YAC9E,8EAA8E;YAC9E,+CAA+C;QACjD,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE;YACZ,iBAAiB,EAAE,KAAK;YACxB,iBAAiB,EAAE,IAAI;YACvB,uBAAuB,EAAE,IAAI;YAC7B,0BAA0B,EAAE,KAAK;SAClC;KACF;IACD;QACE,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,0EAA0E;YAC1E,mEAAmE;QACrE,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE;YACZ,iBAAiB,EAAE,KAAK;YACxB,iBAAiB,EAAE,KAAK;YACxB,uBAAuB,EAAE,IAAI;YAC7B,0BAA0B,EAAE,KAAK;SAClC;KACF;CACO,CAAA;AAIV,yEAAyE;AACzE,SAAgB,WAAW,CAAC,IAAiB,EAAE,IAAY;IACzD,MAAM,GAAG,GAAG,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,yBAAiB,CAAC,CAAC,CAAC,qBAAa,CAAA;IACnE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;AACzC,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Provider credential verification (LLD #70, model catalog & cohort wizard).
3
+ *
4
+ * Pure, network-free description of how to check whether a credential works —
5
+ * the cheapest authenticated call each provider's own API exposes. Two
6
+ * different executors run the same probe spec because a credential crosses a
7
+ * trust boundary differently depending on who holds it at verification time:
8
+ *
9
+ * - `tools/cli/src/lib/providerProbe.ts` — the CLI legitimately holds a raw
10
+ * key locally before it is ever sent anywhere, and probes with it directly.
11
+ * - `services/control-plane/src/lib/providerVerify.ts` — probes a credential
12
+ * already stored in Valkey, server-side, so the raw value never has to
13
+ * leave the control plane a second time.
14
+ *
15
+ * Neither executor lives in this package (no network calls here — shared-types
16
+ * is pure data and types, consumed by both the CLI and the control plane).
17
+ * This module only describes WHAT to request; each executor decides HOW to
18
+ * make that request in its own runtime.
19
+ *
20
+ * Deliberately, no probe here targets `/v1/chat/completions` —
21
+ * `services/control-plane/__tests__/unit/monitorSeparation.test.ts` treats
22
+ * every fetch call to that literal URL shape as a judge/generation call
23
+ * requiring classification. A verification probe is neither; it must not add
24
+ * a site to that census.
25
+ *
26
+ * @module
27
+ */
28
+ export interface ProviderProbeRequest {
29
+ url: string;
30
+ method: 'GET' | 'POST';
31
+ headers: Record<string, string>;
32
+ /** Present only for POST probes (currently: Anthropic's 1-token message). */
33
+ body?: string;
34
+ }
35
+ /**
36
+ * Build the cheapest authenticated request that proves a credential works,
37
+ * or `null` if this provider has no such probe defined yet.
38
+ *
39
+ * `fields` is the provider's credential field map exactly as stored — the
40
+ * same shape `PROVIDER_REGISTRY`'s `ProviderCredentialField.key`s describe
41
+ * (`providers.ts`), e.g. `{ apiKey: '...' }` for Anthropic, `{ apiKey, endpoint,
42
+ * deploymentName }` for Azure OpenAI.
43
+ *
44
+ * Bedrock and Vertex AI return `null`: verifying them means SigV4 request
45
+ * signing or a GCP OAuth2/JWT exchange, neither of which exists anywhere in
46
+ * this codebase yet (the same "real per-provider engineering, not a config
47
+ * change" boundary LLD #67 §3 draws around routing those two providers). A
48
+ * caller seeing `null` should say "cannot verify automatically," not fail
49
+ * the credential.
50
+ */
51
+ export declare function buildVerificationProbe(provider: string, fields: Record<string, string>): ProviderProbeRequest | null;
52
+ export type ProbeVerdict = 'valid' | 'invalid' | 'unknown';
53
+ /**
54
+ * Classify a probe's HTTP response. Deliberately narrow about what counts as
55
+ * "invalid": only 401/403 mean the credential itself is wrong. A 429
56
+ * (rate-limited) or 5xx (upstream trouble) still proves the key is
57
+ * authenticated — reporting either as invalid would tell an operator to
58
+ * re-enter a working key. `unknown` covers both cases plus a request that
59
+ * never got a response at all (network error, timeout) — callers should
60
+ * treat `unknown` as "could not verify," not as a failure, and let the
61
+ * operator proceed.
62
+ */
63
+ export declare function classifyProbeResponse(httpStatus: number): ProbeVerdict;
64
+ //# sourceMappingURL=providerVerification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerVerification.d.ts","sourceRoot":"","sources":["../src/providerVerification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAiBH,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,KAAK,GAAG,MAAM,CAAA;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,oBAAoB,GAAG,IAAI,CAwG7B;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAA;AAE1D;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,CAItE"}
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ /**
3
+ * Provider credential verification (LLD #70, model catalog & cohort wizard).
4
+ *
5
+ * Pure, network-free description of how to check whether a credential works —
6
+ * the cheapest authenticated call each provider's own API exposes. Two
7
+ * different executors run the same probe spec because a credential crosses a
8
+ * trust boundary differently depending on who holds it at verification time:
9
+ *
10
+ * - `tools/cli/src/lib/providerProbe.ts` — the CLI legitimately holds a raw
11
+ * key locally before it is ever sent anywhere, and probes with it directly.
12
+ * - `services/control-plane/src/lib/providerVerify.ts` — probes a credential
13
+ * already stored in Valkey, server-side, so the raw value never has to
14
+ * leave the control plane a second time.
15
+ *
16
+ * Neither executor lives in this package (no network calls here — shared-types
17
+ * is pure data and types, consumed by both the CLI and the control plane).
18
+ * This module only describes WHAT to request; each executor decides HOW to
19
+ * make that request in its own runtime.
20
+ *
21
+ * Deliberately, no probe here targets `/v1/chat/completions` —
22
+ * `services/control-plane/__tests__/unit/monitorSeparation.test.ts` treats
23
+ * every fetch call to that literal URL shape as a judge/generation call
24
+ * requiring classification. A verification probe is neither; it must not add
25
+ * a site to that census.
26
+ *
27
+ * @module
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.buildVerificationProbe = buildVerificationProbe;
31
+ exports.classifyProbeResponse = classifyProbeResponse;
32
+ /**
33
+ * Strip trailing `/` characters, without a regex. `endpoint`/`apiBase` are
34
+ * workspace-provisioned credential fields — CodeQL correctly flagged the
35
+ * original `.replace(/\/+$/, '')` as a polynomial-regex risk on uncontrolled
36
+ * input (this module is a pure function with no length bound of its own;
37
+ * the server-side 512-char cap in `providerCredentials.ts` is a different
38
+ * layer, not a guarantee this function can rely on). A plain index walk is
39
+ * linear by construction, with no backtracking to worry about.
40
+ */
41
+ function stripTrailingSlashes(s) {
42
+ let end = s.length;
43
+ while (end > 0 && s[end - 1] === '/')
44
+ end--;
45
+ return s.slice(0, end);
46
+ }
47
+ /**
48
+ * Build the cheapest authenticated request that proves a credential works,
49
+ * or `null` if this provider has no such probe defined yet.
50
+ *
51
+ * `fields` is the provider's credential field map exactly as stored — the
52
+ * same shape `PROVIDER_REGISTRY`'s `ProviderCredentialField.key`s describe
53
+ * (`providers.ts`), e.g. `{ apiKey: '...' }` for Anthropic, `{ apiKey, endpoint,
54
+ * deploymentName }` for Azure OpenAI.
55
+ *
56
+ * Bedrock and Vertex AI return `null`: verifying them means SigV4 request
57
+ * signing or a GCP OAuth2/JWT exchange, neither of which exists anywhere in
58
+ * this codebase yet (the same "real per-provider engineering, not a config
59
+ * change" boundary LLD #67 §3 draws around routing those two providers). A
60
+ * caller seeing `null` should say "cannot verify automatically," not fail
61
+ * the credential.
62
+ */
63
+ function buildVerificationProbe(provider, fields) {
64
+ switch (provider) {
65
+ case 'anthropic': {
66
+ const apiKey = fields.apiKey;
67
+ if (!apiKey)
68
+ return null;
69
+ // Anthropic's API has no /v1/models endpoint to probe cheaply, so the
70
+ // cheapest real call is a 1-max-token message — costs about one token.
71
+ return {
72
+ url: 'https://api.anthropic.com/v1/messages',
73
+ method: 'POST',
74
+ headers: {
75
+ 'x-api-key': apiKey,
76
+ 'anthropic-version': '2023-06-01',
77
+ 'content-type': 'application/json',
78
+ },
79
+ body: JSON.stringify({
80
+ model: 'claude-haiku-4-5',
81
+ max_tokens: 1,
82
+ messages: [{ role: 'user', content: 'hi' }],
83
+ }),
84
+ };
85
+ }
86
+ case 'openai': {
87
+ const apiKey = fields.apiKey;
88
+ if (!apiKey)
89
+ return null;
90
+ return {
91
+ url: 'https://api.openai.com/v1/models',
92
+ method: 'GET',
93
+ headers: { Authorization: `Bearer ${apiKey}` },
94
+ };
95
+ }
96
+ case 'mistral': {
97
+ const apiKey = fields.apiKey;
98
+ if (!apiKey)
99
+ return null;
100
+ return {
101
+ url: 'https://api.mistral.ai/v1/models',
102
+ method: 'GET',
103
+ headers: { Authorization: `Bearer ${apiKey}` },
104
+ };
105
+ }
106
+ case 'openrouter': {
107
+ const apiKey = fields.apiKey;
108
+ if (!apiKey)
109
+ return null;
110
+ return {
111
+ url: 'https://openrouter.ai/api/v1/models',
112
+ method: 'GET',
113
+ headers: { Authorization: `Bearer ${apiKey}` },
114
+ };
115
+ }
116
+ case 'cohere': {
117
+ const apiKey = fields.apiKey;
118
+ if (!apiKey)
119
+ return null;
120
+ return {
121
+ url: 'https://api.cohere.com/v1/models',
122
+ method: 'GET',
123
+ headers: { Authorization: `Bearer ${apiKey}` },
124
+ };
125
+ }
126
+ case 'gemini': {
127
+ const apiKey = fields.apiKey;
128
+ if (!apiKey)
129
+ return null;
130
+ return {
131
+ url: `https://generativelanguage.googleapis.com/v1beta/models?key=${encodeURIComponent(apiKey)}`,
132
+ method: 'GET',
133
+ headers: {},
134
+ };
135
+ }
136
+ case 'azure_openai': {
137
+ const apiKey = fields.apiKey;
138
+ const endpoint = fields.endpoint ? stripTrailingSlashes(fields.endpoint) : undefined;
139
+ if (!apiKey || !endpoint)
140
+ return null;
141
+ return {
142
+ url: `${endpoint}/openai/models?api-version=2024-02-01`,
143
+ method: 'GET',
144
+ headers: { 'api-key': apiKey },
145
+ };
146
+ }
147
+ case 'ollama': {
148
+ const apiBase = fields.apiBase ? stripTrailingSlashes(fields.apiBase) : undefined;
149
+ if (!apiBase)
150
+ return null;
151
+ // Ollama has no API key by default — this checks reachability, not
152
+ // authentication. A 200 here means "something is listening," which is
153
+ // the most this provider's shape lets a probe promise.
154
+ return {
155
+ url: `${apiBase}/api/tags`,
156
+ method: 'GET',
157
+ headers: {},
158
+ };
159
+ }
160
+ case 'bedrock':
161
+ case 'vertex_ai':
162
+ return null;
163
+ default:
164
+ return null;
165
+ }
166
+ }
167
+ /**
168
+ * Classify a probe's HTTP response. Deliberately narrow about what counts as
169
+ * "invalid": only 401/403 mean the credential itself is wrong. A 429
170
+ * (rate-limited) or 5xx (upstream trouble) still proves the key is
171
+ * authenticated — reporting either as invalid would tell an operator to
172
+ * re-enter a working key. `unknown` covers both cases plus a request that
173
+ * never got a response at all (network error, timeout) — callers should
174
+ * treat `unknown` as "could not verify," not as a failure, and let the
175
+ * operator proceed.
176
+ */
177
+ function classifyProbeResponse(httpStatus) {
178
+ if (httpStatus >= 200 && httpStatus < 300)
179
+ return 'valid';
180
+ if (httpStatus === 401 || httpStatus === 403)
181
+ return 'invalid';
182
+ return 'unknown';
183
+ }
184
+ //# sourceMappingURL=providerVerification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerVerification.js","sourceRoot":"","sources":["../src/providerVerification.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Multi-provider credential registry (LLD #67, multi-provider key wizard).
3
+ *
4
+ * `services/control-plane/src/routes/providerCredentials.ts` originally
5
+ * hardcoded exactly 3 providers (anthropic/openai/gemini), each a single
6
+ * bearer API key — sufficient for those three, but LiteLLM's real provider
7
+ * surface includes providers needing MULTIPLE credential fields (Azure
8
+ * OpenAI: endpoint + deployment + key; Bedrock: AWS region + access key +
9
+ * secret; Vertex AI: a service-account JSON blob). This registry is a
10
+ * data-driven description of a provider's credential shape, so adding a
11
+ * new provider's *field layout* is a data change here, not new code in
12
+ * every place that touches credentials.
13
+ *
14
+ * Deliberately NOT exhaustive — LiteLLM supports 100+ providers. This is a
15
+ * representative slice spanning the shapes that actually differ (single
16
+ * key, multi-field cloud credential, self-hosted endpoint, structured
17
+ * blob), chosen so the registry's own shape is proven out before claiming
18
+ * to cover the full LiteLLM catalog. Adding another provider that fits one
19
+ * of these shapes is adding one entry, not new plumbing.
20
+ *
21
+ * `routingLive: true` means `packages/proxy` actually forwards requests to
22
+ * this provider today (`fetch_provider_credential` in `proxy.rs` knows its
23
+ * field name). `routingLive: false` means the credential can be
24
+ * pre-provisioned here, but nothing in the proxy calls it yet — routing
25
+ * support is separate, real per-provider engineering (a new `Provider`
26
+ * enum variant, `get_model_provider`, pricing in `pricing.rs`), not a
27
+ * config change. The dashboard wizard must say so, not imply the key is
28
+ * live the moment it's saved.
29
+ *
30
+ * @module
31
+ */
32
+ /** How a single credential field should render in a form. */
33
+ export type ProviderFieldType = 'text' | 'password' | 'textarea';
34
+ export interface ProviderCredentialField {
35
+ /** Storage key within the provider's config blob, e.g. 'apiKey', 'awsRegion'. */
36
+ key: string;
37
+ label: string;
38
+ type: ProviderFieldType;
39
+ required: boolean;
40
+ placeholder?: string;
41
+ helpText?: string;
42
+ }
43
+ export interface ProviderDefinition {
44
+ /** Stable id — also the Valkey field/hash-key prefix. */
45
+ id: string;
46
+ displayName: string;
47
+ /** Link to the provider's own API-key docs, shown in the wizard. */
48
+ docsUrl?: string;
49
+ fields: ProviderCredentialField[];
50
+ /** See module doc — whether packages/proxy currently routes to this provider. */
51
+ routingLive: boolean;
52
+ }
53
+ /**
54
+ * The 3 providers this system supported before this registry existed —
55
+ * their storage format (`{provider}_api_key`, a flat string field) is
56
+ * unchanged here, matching what `packages/proxy/src/proxy.rs`'s
57
+ * `fetch_provider_credential` has always read for them.
58
+ *
59
+ * NOT the same question as a provider's `routingLive` flag. This constant
60
+ * decides *storage shape* (flat field vs. `{provider}_config` JSON blob);
61
+ * `routingLive` decides whether the proxy currently forwards requests to a
62
+ * provider at all. They agreed for exactly these 3 while this registry only
63
+ * covered its original scope, but multi-provider wizard phase 3 added real
64
+ * proxy routing for Mistral and OpenRouter *without* changing their storage
65
+ * format — `fetch_provider_credential` reads the JSON blob for both, never
66
+ * the flat field, so they stay off this list even though `routingLive` is
67
+ * now `true` for them. Adding a provider here changes what Valkey field
68
+ * `services/control-plane/src/routes/providerCredentials.ts` writes to —
69
+ * only do it alongside the matching proxy-side flat-field read, never for
70
+ * the "is this provider live" reason alone.
71
+ */
72
+ export declare const LIVE_ROUTING_PROVIDER_IDS: readonly ["anthropic", "openai", "gemini"];
73
+ export declare const PROVIDER_REGISTRY: ProviderDefinition[];
74
+ export declare function getProviderDefinition(id: string): ProviderDefinition | undefined;
75
+ export declare function isKnownProviderId(id: string): boolean;
76
+ /**
77
+ * Which provider the data-plane proxy would route a model name to.
78
+ *
79
+ * A hand-maintained TS mirror of `get_model_provider` in
80
+ * `packages/proxy/src/proxy.rs` — the proxy's routing decision is the ground
81
+ * truth, and this exists so the control plane / dashboard can predict it
82
+ * (e.g. the BYO judge model "Test" flow fast-failing on an unprovisioned
83
+ * provider before making a real call, LLD #70). A parity unit test pins this
84
+ * against the Rust source; if the heuristic changes there, change it here in
85
+ * the same commit.
86
+ *
87
+ * Order matters and matches the Rust exactly: claude → gemini → '/'
88
+ * (OpenRouter's vendor/model namespacing — checked before the mistral
89
+ * prefixes so "mistralai/..." routes to OpenRouter) → mistral prefixes →
90
+ * OpenAI as the default arm.
91
+ */
92
+ export declare function inferProviderForModel(model: string): 'anthropic' | 'gemini' | 'openrouter' | 'mistral' | 'openai';
93
+ //# sourceMappingURL=providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,6DAA6D;AAC7D,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAA;AAEhE,MAAM,WAAW,uBAAuB;IACtC,iFAAiF;IACjF,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,iBAAiB,CAAA;IACvB,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,yDAAyD;IACzD,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,uBAAuB,EAAE,CAAA;IACjC,iFAAiF;IACjF,WAAW,EAAE,OAAO,CAAA;CACrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,yBAAyB,4CAA6C,CAAA;AAEnF,eAAO,MAAM,iBAAiB,EAAE,kBAAkB,EAkFjD,CAAA;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEhF;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GACZ,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAS9D"}