@pentoshi/clai 4.1.0 → 4.2.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 (266) hide show
  1. package/README.md +14 -0
  2. package/dist/agent/compaction-executor.d.ts +68 -0
  3. package/dist/agent/compaction-executor.js +343 -0
  4. package/dist/agent/compaction-executor.js.map +1 -0
  5. package/dist/agent/context-breakdown.js +2 -0
  6. package/dist/agent/context-breakdown.js.map +1 -1
  7. package/dist/agent/context-manager.d.ts +23 -9
  8. package/dist/agent/context-manager.js +72 -43
  9. package/dist/agent/context-manager.js.map +1 -1
  10. package/dist/agent/events.d.ts +3 -0
  11. package/dist/agent/loop-guard.d.ts +2 -0
  12. package/dist/agent/loop-guard.js +48 -3
  13. package/dist/agent/loop-guard.js.map +1 -1
  14. package/dist/agent/prompt-composer.js +6 -6
  15. package/dist/agent/prompt-composer.js.map +1 -1
  16. package/dist/agent/reliability-policy.d.ts +1 -0
  17. package/dist/agent/reliability-policy.js +6 -3
  18. package/dist/agent/reliability-policy.js.map +1 -1
  19. package/dist/agent/request-accounting.d.ts +97 -0
  20. package/dist/agent/request-accounting.js +207 -0
  21. package/dist/agent/request-accounting.js.map +1 -0
  22. package/dist/agent/request-budget.d.ts +2 -2
  23. package/dist/agent/request-budget.js +2 -4
  24. package/dist/agent/request-budget.js.map +1 -1
  25. package/dist/agent/runner.d.ts +8 -2
  26. package/dist/agent/runner.js +409 -178
  27. package/dist/agent/runner.js.map +1 -1
  28. package/dist/agent/session-title.d.ts +0 -26
  29. package/dist/agent/session-title.js +0 -80
  30. package/dist/agent/session-title.js.map +1 -1
  31. package/dist/agent/tool-history.d.ts +2 -2
  32. package/dist/agent/tool-history.js +19 -6
  33. package/dist/agent/tool-history.js.map +1 -1
  34. package/dist/app/adapters/agent-event-adapter.js +19 -0
  35. package/dist/app/adapters/agent-event-adapter.js.map +1 -1
  36. package/dist/app/adapters/current-agent-adapter.js +4 -0
  37. package/dist/app/adapters/current-agent-adapter.js.map +1 -1
  38. package/dist/app/commands/catalog.js +24 -0
  39. package/dist/app/commands/catalog.js.map +1 -1
  40. package/dist/app/controllers/cancel-coordinator.d.ts +51 -0
  41. package/dist/app/controllers/cancel-coordinator.js +48 -0
  42. package/dist/app/controllers/cancel-coordinator.js.map +1 -0
  43. package/dist/app/controllers/session-compact-helper.d.ts +19 -2
  44. package/dist/app/controllers/session-compact-helper.js +100 -127
  45. package/dist/app/controllers/session-compact-helper.js.map +1 -1
  46. package/dist/app/controllers/session-context-usage.d.ts +32 -15
  47. package/dist/app/controllers/session-context-usage.js +186 -51
  48. package/dist/app/controllers/session-context-usage.js.map +1 -1
  49. package/dist/app/controllers/session-controller.d.ts +20 -11
  50. package/dist/app/controllers/session-controller.js +111 -90
  51. package/dist/app/controllers/session-controller.js.map +1 -1
  52. package/dist/app/controllers/session-naming.d.ts +31 -0
  53. package/dist/app/controllers/session-naming.js +173 -0
  54. package/dist/app/controllers/session-naming.js.map +1 -0
  55. package/dist/app/controllers/session-persistence.d.ts +2 -2
  56. package/dist/app/controllers/session-persistence.js +3 -6
  57. package/dist/app/controllers/session-persistence.js.map +1 -1
  58. package/dist/app/controllers/session-turn-request.d.ts +2 -1
  59. package/dist/app/controllers/session-turn-request.js +3 -0
  60. package/dist/app/controllers/session-turn-request.js.map +1 -1
  61. package/dist/app/controllers/turn-controller.d.ts +2 -1
  62. package/dist/app/controllers/turn-controller.js +1 -0
  63. package/dist/app/controllers/turn-controller.js.map +1 -1
  64. package/dist/app/events/app-event.d.ts +9 -0
  65. package/dist/app/events/app-event.js.map +1 -1
  66. package/dist/app/ports/agent-port.d.ts +8 -1
  67. package/dist/classic/app/ClassicApp.js +2 -1
  68. package/dist/classic/app/ClassicApp.js.map +1 -1
  69. package/dist/classic/app/app-wiring.js +1 -2
  70. package/dist/classic/app/app-wiring.js.map +1 -1
  71. package/dist/classic/app/wiring-interactions.js +2 -7
  72. package/dist/classic/app/wiring-interactions.js.map +1 -1
  73. package/dist/classic/blocks/tool-lines.js +2 -1
  74. package/dist/classic/blocks/tool-lines.js.map +1 -1
  75. package/dist/classic/input/cancel-ladder.d.ts +2 -19
  76. package/dist/classic/input/cancel-ladder.js +13 -20
  77. package/dist/classic/input/cancel-ladder.js.map +1 -1
  78. package/dist/commands/providers.js +2 -0
  79. package/dist/commands/providers.js.map +1 -1
  80. package/dist/llm/adapters/anthropic-tools.d.ts +31 -14
  81. package/dist/llm/adapters/anthropic-tools.js +124 -29
  82. package/dist/llm/adapters/anthropic-tools.js.map +1 -1
  83. package/dist/llm/adapters/gemini-tools.d.ts +16 -4
  84. package/dist/llm/adapters/gemini-tools.js +117 -16
  85. package/dist/llm/adapters/gemini-tools.js.map +1 -1
  86. package/dist/llm/adapters/openai-tools.d.ts +13 -2
  87. package/dist/llm/adapters/openai-tools.js +58 -11
  88. package/dist/llm/adapters/openai-tools.js.map +1 -1
  89. package/dist/llm/agentrouter.js +68 -45
  90. package/dist/llm/agentrouter.js.map +1 -1
  91. package/dist/llm/anthropic.js +69 -36
  92. package/dist/llm/anthropic.js.map +1 -1
  93. package/dist/llm/aws-mantle.js +70 -32
  94. package/dist/llm/aws-mantle.js.map +1 -1
  95. package/dist/llm/bynara.js +26 -69
  96. package/dist/llm/bynara.js.map +1 -1
  97. package/dist/llm/capabilities.d.ts +2 -1
  98. package/dist/llm/capabilities.js +47 -0
  99. package/dist/llm/capabilities.js.map +1 -1
  100. package/dist/llm/context-snapshot.d.ts +100 -0
  101. package/dist/llm/context-snapshot.js +277 -0
  102. package/dist/llm/context-snapshot.js.map +1 -0
  103. package/dist/llm/context-windows.d.ts +10 -0
  104. package/dist/llm/context-windows.js +129 -0
  105. package/dist/llm/context-windows.js.map +1 -0
  106. package/dist/llm/custom-provider-profile.d.ts +75 -0
  107. package/dist/llm/custom-provider-profile.js +558 -0
  108. package/dist/llm/custom-provider-profile.js.map +1 -0
  109. package/dist/llm/custom-providers.d.ts +13 -1
  110. package/dist/llm/custom-providers.js +77 -25
  111. package/dist/llm/custom-providers.js.map +1 -1
  112. package/dist/llm/effort-fallback.d.ts +44 -0
  113. package/dist/llm/effort-fallback.js +101 -0
  114. package/dist/llm/effort-fallback.js.map +1 -0
  115. package/dist/llm/fireworks.js +4 -0
  116. package/dist/llm/fireworks.js.map +1 -1
  117. package/dist/llm/free.js +4 -0
  118. package/dist/llm/free.js.map +1 -1
  119. package/dist/llm/gemini.d.ts +1 -1
  120. package/dist/llm/gemini.js +89 -51
  121. package/dist/llm/gemini.js.map +1 -1
  122. package/dist/llm/groq.js +4 -0
  123. package/dist/llm/groq.js.map +1 -1
  124. package/dist/llm/hetzner.js +4 -0
  125. package/dist/llm/hetzner.js.map +1 -1
  126. package/dist/llm/http.d.ts +49 -10
  127. package/dist/llm/http.js +417 -153
  128. package/dist/llm/http.js.map +1 -1
  129. package/dist/llm/kimchi.js +4 -0
  130. package/dist/llm/kimchi.js.map +1 -1
  131. package/dist/llm/lightning.js +4 -0
  132. package/dist/llm/lightning.js.map +1 -1
  133. package/dist/llm/meta.d.ts +2 -0
  134. package/dist/llm/meta.js +811 -655
  135. package/dist/llm/meta.js.map +1 -1
  136. package/dist/llm/modal.js +4 -0
  137. package/dist/llm/modal.js.map +1 -1
  138. package/dist/llm/model-families.d.ts +9 -0
  139. package/dist/llm/model-families.js +39 -0
  140. package/dist/llm/model-families.js.map +1 -0
  141. package/dist/llm/nvidia.js +4 -0
  142. package/dist/llm/nvidia.js.map +1 -1
  143. package/dist/llm/ollama.js +44 -40
  144. package/dist/llm/ollama.js.map +1 -1
  145. package/dist/llm/openai.js +4 -0
  146. package/dist/llm/openai.js.map +1 -1
  147. package/dist/llm/openrouter.js +4 -0
  148. package/dist/llm/openrouter.js.map +1 -1
  149. package/dist/llm/operation-ledger.d.ts +60 -0
  150. package/dist/llm/operation-ledger.js +136 -0
  151. package/dist/llm/operation-ledger.js.map +1 -0
  152. package/dist/llm/operation-usage.d.ts +32 -0
  153. package/dist/llm/operation-usage.js +172 -0
  154. package/dist/llm/operation-usage.js.map +1 -0
  155. package/dist/llm/orcarouter.d.ts +7 -0
  156. package/dist/llm/orcarouter.js +166 -0
  157. package/dist/llm/orcarouter.js.map +1 -0
  158. package/dist/llm/provider-profile-layers.d.ts +7 -0
  159. package/dist/llm/provider-profile-layers.js +961 -0
  160. package/dist/llm/provider-profile-layers.js.map +1 -0
  161. package/dist/llm/provider-profile.d.ts +181 -0
  162. package/dist/llm/provider-profile.js +329 -0
  163. package/dist/llm/provider-profile.js.map +1 -0
  164. package/dist/llm/provider-profiles.d.ts +13 -0
  165. package/dist/llm/provider-profiles.js +86 -0
  166. package/dist/llm/provider-profiles.js.map +1 -0
  167. package/dist/llm/provider.d.ts +2 -0
  168. package/dist/llm/provider.js +67 -0
  169. package/dist/llm/provider.js.map +1 -1
  170. package/dist/llm/qwen-cloud.js +4 -0
  171. package/dist/llm/qwen-cloud.js.map +1 -1
  172. package/dist/llm/reasoning-artifacts.d.ts +101 -0
  173. package/dist/llm/reasoning-artifacts.js +440 -0
  174. package/dist/llm/reasoning-artifacts.js.map +1 -0
  175. package/dist/llm/request-fingerprint.d.ts +10 -0
  176. package/dist/llm/request-fingerprint.js +313 -0
  177. package/dist/llm/request-fingerprint.js.map +1 -0
  178. package/dist/llm/request-plan.d.ts +119 -0
  179. package/dist/llm/request-plan.js +279 -0
  180. package/dist/llm/request-plan.js.map +1 -0
  181. package/dist/llm/router.d.ts +19 -1
  182. package/dist/llm/router.js +447 -75
  183. package/dist/llm/router.js.map +1 -1
  184. package/dist/llm/stream-events.d.ts +47 -0
  185. package/dist/llm/stream-events.js +55 -0
  186. package/dist/llm/stream-events.js.map +1 -0
  187. package/dist/llm/stream-terminal.d.ts +30 -0
  188. package/dist/llm/stream-terminal.js +51 -0
  189. package/dist/llm/stream-terminal.js.map +1 -0
  190. package/dist/llm/token-estimate-calibration.d.ts +23 -0
  191. package/dist/llm/token-estimate-calibration.js +140 -0
  192. package/dist/llm/token-estimate-calibration.js.map +1 -0
  193. package/dist/llm/token-usage.d.ts +35 -5
  194. package/dist/llm/token-usage.js +212 -162
  195. package/dist/llm/token-usage.js.map +1 -1
  196. package/dist/llm/tokenrouter.js +8 -2
  197. package/dist/llm/tokenrouter.js.map +1 -1
  198. package/dist/modes/ask.js +11 -5
  199. package/dist/modes/ask.js.map +1 -1
  200. package/dist/noninteractive/start-noninteractive.js +31 -2
  201. package/dist/noninteractive/start-noninteractive.js.map +1 -1
  202. package/dist/noninteractive/stream-blocks.js +15 -4
  203. package/dist/noninteractive/stream-blocks.js.map +1 -1
  204. package/dist/prompts/embedded.js +1 -1
  205. package/dist/prompts/embedded.js.map +1 -1
  206. package/dist/prompts/system.agent.md +6 -0
  207. package/dist/store/config.js +5 -1
  208. package/dist/store/config.js.map +1 -1
  209. package/dist/store/history.d.ts +2 -0
  210. package/dist/store/history.js +19 -10
  211. package/dist/store/history.js.map +1 -1
  212. package/dist/store/keys.js +11 -1
  213. package/dist/store/keys.js.map +1 -1
  214. package/dist/store/plan.js +20 -14
  215. package/dist/store/plan.js.map +1 -1
  216. package/dist/tools/elevated-shell.d.ts +1 -1
  217. package/dist/tools/elevated-shell.js +24 -72
  218. package/dist/tools/elevated-shell.js.map +1 -1
  219. package/dist/tools/nmap-runner.js +30 -36
  220. package/dist/tools/nmap-runner.js.map +1 -1
  221. package/dist/tools/sudo-session.d.ts +83 -0
  222. package/dist/tools/sudo-session.js +124 -0
  223. package/dist/tools/sudo-session.js.map +1 -0
  224. package/dist/tui-v2/app/App.js +9 -24
  225. package/dist/tui-v2/app/App.js.map +1 -1
  226. package/dist/tui-v2/components/status/context-limit-chip.js +2 -2
  227. package/dist/tui-v2/components/status/context-limit-chip.js.map +1 -1
  228. package/dist/tui-v2/components/transcript/intro-card.js +2 -1
  229. package/dist/tui-v2/components/transcript/intro-card.js.map +1 -1
  230. package/dist/tui-v2/composer/composer-editor.js +2 -1
  231. package/dist/tui-v2/composer/composer-editor.js.map +1 -1
  232. package/dist/types.d.ts +156 -1
  233. package/dist/types.js +1 -0
  234. package/dist/types.js.map +1 -1
  235. package/dist/ui-core/bootstrap/composition-root.d.ts +2 -0
  236. package/dist/ui-core/bootstrap/composition-root.js +26 -3
  237. package/dist/ui-core/bootstrap/composition-root.js.map +1 -1
  238. package/dist/ui-core/commands/picker-commands.js +11 -5
  239. package/dist/ui-core/commands/picker-commands.js.map +1 -1
  240. package/dist/ui-core/commands/session-commands.js +41 -5
  241. package/dist/ui-core/commands/session-commands.js.map +1 -1
  242. package/dist/ui-core/plan/plan-lifecycle.js +3 -2
  243. package/dist/ui-core/plan/plan-lifecycle.js.map +1 -1
  244. package/dist/ui-core/rendering/context-limit.js +4 -1
  245. package/dist/ui-core/rendering/context-limit.js.map +1 -1
  246. package/dist/ui-core/rendering/duration.d.ts +2 -1
  247. package/dist/ui-core/rendering/duration.js +13 -5
  248. package/dist/ui-core/rendering/duration.js.map +1 -1
  249. package/dist/ui-core/rendering/intro-header.js +2 -2
  250. package/dist/ui-core/rendering/intro-header.js.map +1 -1
  251. package/dist/ui-core/rendering/theme.d.ts +1 -0
  252. package/dist/ui-core/rendering/theme.js +2 -0
  253. package/dist/ui-core/rendering/theme.js.map +1 -1
  254. package/dist/ui-core/state/transcript-hydrate.js +3 -3
  255. package/dist/ui-core/state/transcript-hydrate.js.map +1 -1
  256. package/dist/ui-core/state/transcript-reducer.d.ts +5 -0
  257. package/dist/ui-core/state/transcript-reducer.js +76 -3
  258. package/dist/ui-core/state/transcript-reducer.js.map +1 -1
  259. package/dist/ui-core/state/transcript-store.d.ts +10 -1
  260. package/dist/ui-core/state/transcript-store.js +22 -1
  261. package/dist/ui-core/state/transcript-store.js.map +1 -1
  262. package/dist/ui-core/state/transcript-types.d.ts +2 -0
  263. package/dist/ui-core/state/transcript-types.js.map +1 -1
  264. package/dist/version.generated.d.ts +2 -2
  265. package/dist/version.generated.js +2 -2
  266. package/package.json +6 -1
@@ -10,6 +10,7 @@ let lastFetchTime = 0;
10
10
  const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour cache TTL
11
11
  export const openrouterProvider = {
12
12
  id: "openrouter",
13
+ reasoningStyle: "openrouter",
13
14
  displayName: "OpenRouter",
14
15
  defaultModel: defaultModels.openrouter,
15
16
  envVar: "OPENROUTER_API_KEY",
@@ -59,6 +60,7 @@ export const openrouterProvider = {
59
60
  tools: request.tools,
60
61
  toolChoice: request.toolChoice,
61
62
  parallelToolCalls: request.parallelToolCalls,
63
+ reasoningArtifactReplayObserver: request.onReasoningArtifactReplayDecision,
62
64
  });
63
65
  return toCompletionResult("openrouter", model, payload);
64
66
  },
@@ -79,11 +81,13 @@ export const openrouterProvider = {
79
81
  signal: request.signal,
80
82
  onToken,
81
83
  onToolCallDelta: request.onToolCallDelta,
84
+ onStreamEvent: request.onStreamEvent,
82
85
  reasoning: request.thinking,
83
86
  reasoningStyle: "openrouter",
84
87
  tools: request.tools,
85
88
  toolChoice: request.toolChoice,
86
89
  parallelToolCalls: request.parallelToolCalls,
90
+ reasoningArtifactReplayObserver: request.onReasoningArtifactReplayDecision,
87
91
  });
88
92
  return toCompletionResult("openrouter", model, payload);
89
93
  },
@@ -1 +1 @@
1
- {"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/llm/openrouter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/llm/openrouter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import type { GenerationAttemptHandle, GenerationAttemptInput } from "../types.js";
2
+ import { OperationUsageRecorder, type OperationUsageSnapshot } from "./operation-usage.js";
3
+ export type OperationKind = "turn" | "compaction" | "provider_validation" | "background";
4
+ export type OperationTerminalOutcome = "completed" | "failed" | "cancelled" | "budget-exceeded" | "semantic-output-stopped";
5
+ export interface OperationPolicy {
6
+ readonly kind: OperationKind;
7
+ readonly admissionBudget: number;
8
+ readonly continuationBudget: number;
9
+ }
10
+ export declare function turnOperationPolicy(admissionBudget?: number, continuationBudget?: number): OperationPolicy;
11
+ export declare function singleAdmissionOperationPolicy(kind: OperationKind, admissionBudget?: number): OperationPolicy;
12
+ interface OperationLedgerIdentity {
13
+ readonly operationId: string;
14
+ readonly kind: OperationKind;
15
+ readonly admissionBudget: number;
16
+ readonly continuationBudget: number;
17
+ }
18
+ export declare class OperationAdmissionBudgetExceededError extends Error {
19
+ readonly name = "OperationAdmissionBudgetExceededError";
20
+ readonly operation: OperationLedgerIdentity;
21
+ constructor(operation: OperationLedgerIdentity);
22
+ }
23
+ export declare class OperationSemanticOutputError extends Error {
24
+ readonly name = "OperationSemanticOutputError";
25
+ readonly operation: OperationLedgerIdentity;
26
+ constructor(operation: OperationLedgerIdentity);
27
+ }
28
+ export declare function isOperationPolicyError(error: unknown): error is OperationAdmissionBudgetExceededError | OperationSemanticOutputError;
29
+ export declare class OperationLedger {
30
+ readonly operationId: string;
31
+ readonly policy: OperationPolicy;
32
+ private readonly recorder;
33
+ private admissions;
34
+ private continuations;
35
+ private refusals;
36
+ private semanticOutput;
37
+ private terminal;
38
+ constructor(policy?: OperationPolicy, recorder?: OperationUsageRecorder);
39
+ get kind(): OperationKind;
40
+ get admissionsUsed(): number;
41
+ get continuationsUsed(): number;
42
+ get semanticOutputPublished(): boolean;
43
+ /** True once this ledger refused a dispatch the caller tried to make. */
44
+ get admissionRefused(): boolean;
45
+ get terminalOutcome(): OperationTerminalOutcome | undefined;
46
+ begin(input: GenerationAttemptInput): GenerationAttemptHandle;
47
+ noteSemanticOutput(): void;
48
+ beginContinuation(): void;
49
+ /**
50
+ * Callers surface the failure that caused the operation to stop, which is the
51
+ * provider error rather than the guard that refused the retry. The ledger
52
+ * still records the budget as the terminal reason so telemetry is not lost.
53
+ */
54
+ settle(outcome: OperationTerminalOutcome): void;
55
+ snapshot(): OperationUsageSnapshot;
56
+ private identity;
57
+ }
58
+ export declare function operationTerminalOutcome(error: unknown, signal?: AbortSignal): OperationTerminalOutcome;
59
+ export declare function operationUsageFromError(error: unknown): OperationUsageSnapshot | undefined;
60
+ export {};
@@ -0,0 +1,136 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { OperationUsageRecorder, } from "./operation-usage.js";
3
+ const DEFAULT_TURN_ADMISSION_BUDGET = 64;
4
+ export function turnOperationPolicy(admissionBudget = DEFAULT_TURN_ADMISSION_BUDGET, continuationBudget = 0) {
5
+ return Object.freeze({
6
+ kind: "turn",
7
+ admissionBudget,
8
+ continuationBudget,
9
+ });
10
+ }
11
+ export function singleAdmissionOperationPolicy(kind, admissionBudget = 1) {
12
+ return Object.freeze({
13
+ kind,
14
+ admissionBudget,
15
+ continuationBudget: 0,
16
+ });
17
+ }
18
+ export class OperationAdmissionBudgetExceededError extends Error {
19
+ name = "OperationAdmissionBudgetExceededError";
20
+ operation;
21
+ constructor(operation) {
22
+ super(`${operation.kind} operation ${operation.operationId} exhausted its admission budget (${operation.admissionBudget}) before another generation dispatch`);
23
+ this.operation = Object.freeze({ ...operation });
24
+ }
25
+ }
26
+ export class OperationSemanticOutputError extends Error {
27
+ name = "OperationSemanticOutputError";
28
+ operation;
29
+ constructor(operation) {
30
+ super(`${operation.kind} operation ${operation.operationId} already published typed semantic output; transparent regeneration is not allowed`);
31
+ this.operation = Object.freeze({ ...operation });
32
+ }
33
+ }
34
+ export function isOperationPolicyError(error) {
35
+ return (error instanceof OperationAdmissionBudgetExceededError ||
36
+ error instanceof OperationSemanticOutputError);
37
+ }
38
+ const TRANSPARENT_RETRY_REASONS = new Set(["retry", "fallback", "adaptation", "provider-retry"]);
39
+ export class OperationLedger {
40
+ operationId = randomUUID();
41
+ policy;
42
+ recorder;
43
+ admissions = 0;
44
+ continuations = 0;
45
+ refusals = 0;
46
+ semanticOutput = false;
47
+ terminal;
48
+ constructor(policy = turnOperationPolicy(), recorder = new OperationUsageRecorder()) {
49
+ this.policy = Object.freeze({ ...policy });
50
+ this.recorder = recorder;
51
+ }
52
+ get kind() {
53
+ return this.policy.kind;
54
+ }
55
+ get admissionsUsed() {
56
+ return this.admissions;
57
+ }
58
+ get continuationsUsed() {
59
+ return this.continuations;
60
+ }
61
+ get semanticOutputPublished() {
62
+ return this.semanticOutput;
63
+ }
64
+ /** True once this ledger refused a dispatch the caller tried to make. */
65
+ get admissionRefused() {
66
+ return this.refusals > 0;
67
+ }
68
+ get terminalOutcome() {
69
+ return this.terminal;
70
+ }
71
+ begin(input) {
72
+ if (this.admissions >= this.policy.admissionBudget) {
73
+ this.refusals += 1;
74
+ throw new OperationAdmissionBudgetExceededError(this.identity());
75
+ }
76
+ if (this.semanticOutput && TRANSPARENT_RETRY_REASONS.has(input.reason)) {
77
+ throw new OperationSemanticOutputError(this.identity());
78
+ }
79
+ this.admissions += 1;
80
+ return this.recorder.begin(input);
81
+ }
82
+ noteSemanticOutput() {
83
+ this.semanticOutput = true;
84
+ }
85
+ beginContinuation() {
86
+ if (this.continuations >= this.policy.continuationBudget) {
87
+ throw new OperationAdmissionBudgetExceededError(this.identity());
88
+ }
89
+ this.continuations += 1;
90
+ this.admissions = 0;
91
+ }
92
+ /**
93
+ * Callers surface the failure that caused the operation to stop, which is the
94
+ * provider error rather than the guard that refused the retry. The ledger
95
+ * still records the budget as the terminal reason so telemetry is not lost.
96
+ */
97
+ settle(outcome) {
98
+ this.terminal ??=
99
+ outcome === "failed" && this.refusals > 0 ? "budget-exceeded" : outcome;
100
+ }
101
+ snapshot() {
102
+ return this.recorder.snapshot();
103
+ }
104
+ identity() {
105
+ return {
106
+ operationId: this.operationId,
107
+ kind: this.policy.kind,
108
+ admissionBudget: this.policy.admissionBudget,
109
+ continuationBudget: this.policy.continuationBudget,
110
+ };
111
+ }
112
+ }
113
+ export function operationTerminalOutcome(error, signal) {
114
+ if (error instanceof OperationAdmissionBudgetExceededError) {
115
+ return "budget-exceeded";
116
+ }
117
+ if (error instanceof OperationSemanticOutputError) {
118
+ return "semantic-output-stopped";
119
+ }
120
+ if (signal?.aborted)
121
+ return "cancelled";
122
+ return "failed";
123
+ }
124
+ export function operationUsageFromError(error) {
125
+ if (!error || typeof error !== "object" || !("operationUsage" in error)) {
126
+ return undefined;
127
+ }
128
+ const snapshot = error.operationUsage;
129
+ if (!snapshot || typeof snapshot !== "object")
130
+ return undefined;
131
+ if (!Array.isArray(snapshot.attempts)) {
132
+ return undefined;
133
+ }
134
+ return snapshot;
135
+ }
136
+ //# sourceMappingURL=operation-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation-ledger.js","sourceRoot":"","sources":["../../src/llm/operation-ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { CompletionRequest, CompletionResult, GenerationAttemptHandle, GenerationAttemptInput, GenerationAttemptOutcome, GenerationAttemptUsageSink, TokenUsage } from "../types.js";
2
+ export type AttemptUsageValue = {
3
+ readonly kind: "known";
4
+ readonly value: TokenUsage;
5
+ } | {
6
+ readonly kind: "unknown";
7
+ };
8
+ export interface GenerationAttemptRecord extends GenerationAttemptInput {
9
+ readonly sequence: number;
10
+ readonly outcome: GenerationAttemptOutcome;
11
+ readonly usage: AttemptUsageValue;
12
+ readonly statusCode?: number | undefined;
13
+ }
14
+ export interface OperationUsageAggregate {
15
+ readonly status: "known" | "partial" | "unknown";
16
+ readonly knownAdmissions: number;
17
+ readonly unknownAdmissions: number;
18
+ readonly usage?: TokenUsage | undefined;
19
+ }
20
+ export interface OperationUsageSnapshot {
21
+ readonly attempts: readonly GenerationAttemptRecord[];
22
+ readonly aggregate: OperationUsageAggregate;
23
+ }
24
+ export declare function completeGenerationAttempt(outcome: GenerationAttemptOutcome, usage?: TokenUsage, statusCode?: number): void;
25
+ export declare function generationFetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
26
+ export declare function runGenerationAttempt(request: CompletionRequest, input: GenerationAttemptInput, run: () => Promise<CompletionResult>): Promise<CompletionResult>;
27
+ export declare class OperationUsageRecorder implements GenerationAttemptUsageSink {
28
+ private nextSequence;
29
+ private readonly records;
30
+ begin(input: GenerationAttemptInput): GenerationAttemptHandle;
31
+ snapshot(): OperationUsageSnapshot;
32
+ }
@@ -0,0 +1,172 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { fingerprintFinalRequest } from "./request-fingerprint.js";
3
+ function immutableUsage(usage) {
4
+ return Object.freeze({ ...usage });
5
+ }
6
+ function immutableRequestFingerprint(fingerprint) {
7
+ return Object.freeze({
8
+ ...fingerprint,
9
+ serializer: Object.freeze({ ...fingerprint.serializer }),
10
+ body: Object.freeze({ ...fingerprint.body }),
11
+ sections: Object.freeze(fingerprint.sections.map((section) => Object.freeze({ ...section }))),
12
+ prefixes: Object.freeze(fingerprint.prefixes.map((prefix) => Object.freeze({ ...prefix }))),
13
+ });
14
+ }
15
+ function aggregateAttempts(attempts) {
16
+ const known = attempts.filter((attempt) => attempt.usage.kind === "known");
17
+ const unknownAdmissions = attempts.length - known.length;
18
+ if (known.length === 0) {
19
+ return Object.freeze({
20
+ status: "unknown",
21
+ knownAdmissions: 0,
22
+ unknownAdmissions,
23
+ });
24
+ }
25
+ const allAdmissionsKnown = unknownAdmissions === 0;
26
+ const usage = immutableUsage({
27
+ promptTokens: known.reduce((total, attempt) => total + attempt.usage.value.promptTokens, 0),
28
+ completionTokens: known.reduce((total, attempt) => total + attempt.usage.value.completionTokens, 0),
29
+ totalTokens: known.reduce((total, attempt) => total + attempt.usage.value.totalTokens, 0),
30
+ exact: known.every((attempt) => attempt.usage.value.exact),
31
+ ...(allAdmissionsKnown &&
32
+ known.every((attempt) => attempt.usage.value.cachedPromptTokens !== undefined)
33
+ ? {
34
+ cachedPromptTokens: known.reduce((total, attempt) => total + attempt.usage.value.cachedPromptTokens, 0),
35
+ }
36
+ : {}),
37
+ ...(allAdmissionsKnown &&
38
+ known.every((attempt) => attempt.usage.value.cacheCreationTokens !== undefined)
39
+ ? {
40
+ cacheCreationTokens: known.reduce((total, attempt) => total + attempt.usage.value.cacheCreationTokens, 0),
41
+ }
42
+ : {}),
43
+ ...(allAdmissionsKnown &&
44
+ known.every((attempt) => attempt.usage.value.uncachedPromptTokens !== undefined)
45
+ ? {
46
+ uncachedPromptTokens: known.reduce((total, attempt) => total + attempt.usage.value.uncachedPromptTokens, 0),
47
+ }
48
+ : {}),
49
+ ...(allAdmissionsKnown &&
50
+ known.every((attempt) => attempt.usage.value.reasoningTokens !== undefined)
51
+ ? {
52
+ reasoningTokens: known.reduce((total, attempt) => total + attempt.usage.value.reasoningTokens, 0),
53
+ }
54
+ : {}),
55
+ });
56
+ return Object.freeze({
57
+ status: unknownAdmissions === 0 ? "known" : "partial",
58
+ knownAdmissions: known.length,
59
+ unknownAdmissions,
60
+ usage,
61
+ });
62
+ }
63
+ function canonicalUsageFromError(error) {
64
+ if (!error || typeof error !== "object" || !("usage" in error))
65
+ return undefined;
66
+ const usage = error.usage;
67
+ if (!usage || typeof usage !== "object")
68
+ return undefined;
69
+ const value = usage;
70
+ if (typeof value.promptTokens !== "number" ||
71
+ typeof value.completionTokens !== "number" ||
72
+ typeof value.totalTokens !== "number" ||
73
+ typeof value.exact !== "boolean") {
74
+ return undefined;
75
+ }
76
+ return value;
77
+ }
78
+ function statusCodeFromError(error) {
79
+ if (!error || typeof error !== "object" || !("status" in error))
80
+ return undefined;
81
+ const status = Number(error.status);
82
+ return Number.isFinite(status) && status > 0 ? status : undefined;
83
+ }
84
+ const generationAttemptContext = new AsyncLocalStorage();
85
+ function settleActiveAttempt(context, outcome, usage, statusCode) {
86
+ context.active?.complete(outcome, usage, statusCode);
87
+ context.active = undefined;
88
+ }
89
+ export function completeGenerationAttempt(outcome, usage, statusCode) {
90
+ const context = generationAttemptContext.getStore();
91
+ if (!context)
92
+ return;
93
+ settleActiveAttempt(context, outcome, usage, statusCode);
94
+ }
95
+ export async function generationFetch(input, init) {
96
+ const context = generationAttemptContext.getStore();
97
+ if (!context?.request.attemptUsage)
98
+ return fetch(input, init);
99
+ if (context.active) {
100
+ throw new Error("generation admission started before the prior admission settled");
101
+ }
102
+ const reason = context.admissions === 0 ? context.input.reason : "provider-retry";
103
+ const requestFingerprint = fingerprintFinalRequest(context.input, init?.body);
104
+ context.admissions += 1;
105
+ context.active = context.request.attemptUsage.begin({
106
+ provider: context.input.provider,
107
+ model: context.input.model,
108
+ mode: context.input.mode,
109
+ reason,
110
+ ...(requestFingerprint ? { requestFingerprint } : {}),
111
+ });
112
+ try {
113
+ const response = await fetch(input, init);
114
+ if (!response.ok) {
115
+ settleActiveAttempt(context, "failure", undefined, response.status);
116
+ }
117
+ return response;
118
+ }
119
+ catch (error) {
120
+ settleActiveAttempt(context, context.request.signal?.aborted ? "cancelled" : "failure", canonicalUsageFromError(error), statusCodeFromError(error));
121
+ throw error;
122
+ }
123
+ }
124
+ export async function runGenerationAttempt(request, input, run) {
125
+ const context = { request, input, admissions: 0 };
126
+ return generationAttemptContext.run(context, async () => {
127
+ try {
128
+ const result = await run();
129
+ settleActiveAttempt(context, "success", result.usage);
130
+ return result;
131
+ }
132
+ catch (error) {
133
+ settleActiveAttempt(context, request.signal?.aborted ? "cancelled" : "failure", canonicalUsageFromError(error), statusCodeFromError(error));
134
+ throw error;
135
+ }
136
+ });
137
+ }
138
+ export class OperationUsageRecorder {
139
+ nextSequence = 1;
140
+ records = new Map();
141
+ begin(input) {
142
+ const sequence = this.nextSequence;
143
+ this.nextSequence += 1;
144
+ let completed = false;
145
+ return Object.freeze({
146
+ complete: (outcome, usage, statusCode) => {
147
+ if (completed)
148
+ return;
149
+ completed = true;
150
+ const { requestFingerprint, ...attemptInput } = input;
151
+ const record = Object.freeze({
152
+ ...attemptInput,
153
+ ...(requestFingerprint
154
+ ? { requestFingerprint: immutableRequestFingerprint(requestFingerprint) }
155
+ : {}),
156
+ sequence,
157
+ outcome,
158
+ usage: usage
159
+ ? Object.freeze({ kind: "known", value: immutableUsage(usage) })
160
+ : Object.freeze({ kind: "unknown" }),
161
+ ...(statusCode !== undefined ? { statusCode } : {}),
162
+ });
163
+ this.records.set(sequence, record);
164
+ },
165
+ });
166
+ }
167
+ snapshot() {
168
+ const attempts = Object.freeze([...this.records.values()].sort((left, right) => left.sequence - right.sequence));
169
+ return Object.freeze({ attempts, aggregate: aggregateAttempts(attempts) });
170
+ }
171
+ }
172
+ //# sourceMappingURL=operation-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation-usage.js","sourceRoot":"","sources":["../../src/llm/operation-usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type LlmProvider } from "./provider.js";
2
+ /**
3
+ * Offline fallback catalog (documented chat models) used when `/models` is
4
+ * unreachable. The live catalog is authoritative when it can be fetched.
5
+ */
6
+ export declare const orcarouterFallbackModels: string[];
7
+ export declare const orcarouterProvider: LlmProvider;
@@ -0,0 +1,166 @@
1
+ import { defaultModels, } from "./provider.js";
2
+ import { singleLeadingSystemMessages } from "./system-messages.js";
3
+ import { ingestOpenAiModelCatalog, openAiCompatibleComplete, openAiCompatiblePing, openAiCompatibleStream, readJson, toCompletionResult, } from "./http.js";
4
+ /**
5
+ * OrcaRouter — an OpenAI-compatible multi-provider gateway
6
+ * (https://api.orcarouter.ai/v1) that routes OpenAI, Anthropic, Google
7
+ * Gemini, DeepSeek, xAI Grok, Qwen, Kimi, MiniMax, Z.ai GLM and more behind
8
+ * one bearer key at provider cost price. Model ids are provider-prefixed
9
+ * (`openai/gpt-4o-mini`, `anthropic/claude-sonnet-4.6`, …).
10
+ *
11
+ * Chat Completions with SSE streaming, native tool calling, structured
12
+ * outputs (`response_format`), vision via `image_url` and a unified
13
+ * top-level `reasoning_effort` knob that the gateway translates to each
14
+ * upstream's native reasoning shape. Reasoning output arrives as
15
+ * `reasoning_content`, which the shared OpenAI helper folds into the
16
+ * thinking block.
17
+ */
18
+ const baseUrl = "https://api.orcarouter.ai/v1";
19
+ /**
20
+ * Offline fallback catalog (documented chat models) used when `/models` is
21
+ * unreachable. The live catalog is authoritative when it can be fetched.
22
+ */
23
+ export const orcarouterFallbackModels = [
24
+ "orcarouter/auto",
25
+ "openai/gpt-4o-mini",
26
+ "openai/gpt-4o",
27
+ "openai/gpt-5",
28
+ "openai/gpt-5-mini",
29
+ "openai/o3-mini",
30
+ "openai/o4-mini",
31
+ "anthropic/claude-sonnet-4.6",
32
+ "anthropic/claude-opus-4.7",
33
+ "google/gemini-2.5-flash",
34
+ "google/gemini-2.5-pro",
35
+ "google/gemini-3-pro-preview",
36
+ "deepseek/deepseek-chat",
37
+ "deepseek/deepseek-reasoner",
38
+ "grok/grok-4-fast-reasoning",
39
+ "qwen/qwen3-max",
40
+ "qwen/qwen3.6-plus",
41
+ "kimi/kimi-k2.6",
42
+ "minimax/minimax-m2.7",
43
+ "z-ai/glm-5.1",
44
+ ];
45
+ /** Non-chat modalities that still advertise an `openai` endpoint type. */
46
+ const NON_CHAT_MODEL = /image|imagen|dall-e|tts|whisper|embed|video|imagine|dreamina|seedance|kling|moderation/i;
47
+ /**
48
+ * Keep only models reachable over Chat Completions. OrcaRouter's catalog
49
+ * flags each entry with `supported_endpoint_types`; anything that does not
50
+ * list `openai` (plus image/video/tts/embedding ids that do) would 404 on
51
+ * `/chat/completions` and pollutes the `/model` picker.
52
+ */
53
+ function chatModelsFromCatalog(payload) {
54
+ const container = payload;
55
+ const entries = Array.isArray(payload)
56
+ ? payload
57
+ : Array.isArray(container?.data)
58
+ ? container.data
59
+ : [];
60
+ return entries.filter((entry) => {
61
+ if (typeof entry === "string")
62
+ return !NON_CHAT_MODEL.test(entry);
63
+ const item = entry;
64
+ const id = typeof item.id === "string" ? item.id : "";
65
+ if (!id || NON_CHAT_MODEL.test(id))
66
+ return false;
67
+ const endpoints = item.supported_endpoint_types;
68
+ if (Array.isArray(endpoints) && endpoints.length > 0) {
69
+ return endpoints.includes("openai");
70
+ }
71
+ return true;
72
+ });
73
+ }
74
+ let cachedModels = null;
75
+ let lastFetchTime = 0;
76
+ const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour cache TTL
77
+ export const orcarouterProvider = {
78
+ id: "orcarouter",
79
+ reasoningStyle: "openai",
80
+ displayName: "OrcaRouter",
81
+ defaultModel: defaultModels.orcarouter,
82
+ envVar: "ORCAROUTER_API_KEY",
83
+ validateKey: (key) => /^sk-[A-Za-z0-9_-]{8,}$/.test(key),
84
+ async listModels(auth) {
85
+ const now = Date.now();
86
+ if (cachedModels && now - lastFetchTime < CACHE_TTL_MS) {
87
+ return cachedModels;
88
+ }
89
+ try {
90
+ const reqHeaders = {};
91
+ if (auth.apiKey)
92
+ reqHeaders["authorization"] = `Bearer ${auth.apiKey}`;
93
+ const response = await fetch(`${baseUrl}/models`, {
94
+ headers: reqHeaders,
95
+ });
96
+ if (!response.ok)
97
+ throw new Error(`HTTP ${response.status}`);
98
+ const data = await readJson(response);
99
+ const models = ingestOpenAiModelCatalog("orcarouter", chatModelsFromCatalog(data));
100
+ if (models.length > 0) {
101
+ cachedModels = models;
102
+ lastFetchTime = now;
103
+ return models;
104
+ }
105
+ return cachedModels ?? orcarouterFallbackModels;
106
+ }
107
+ catch {
108
+ return cachedModels ?? orcarouterFallbackModels;
109
+ }
110
+ },
111
+ async ping(auth) {
112
+ if (!auth.apiKey)
113
+ throw new Error("OrcaRouter API key is required");
114
+ await openAiCompatiblePing(baseUrl, auth.apiKey);
115
+ },
116
+ async complete(request, auth) {
117
+ if (!auth.apiKey)
118
+ throw new Error("OrcaRouter API key is required");
119
+ const model = request.model ?? defaultModels.orcarouter;
120
+ const payload = await openAiCompatibleComplete({
121
+ provider: "OrcaRouter",
122
+ providerId: "orcarouter",
123
+ baseUrl,
124
+ apiKey: auth.apiKey,
125
+ model,
126
+ messages: singleLeadingSystemMessages(request.messages),
127
+ maxTokens: request.maxTokens,
128
+ temperature: request.temperature,
129
+ signal: request.signal,
130
+ reasoning: request.thinking,
131
+ reasoningStyle: "openai",
132
+ tools: request.tools,
133
+ toolChoice: request.toolChoice,
134
+ parallelToolCalls: request.parallelToolCalls,
135
+ reasoningArtifactReplayObserver: request.onReasoningArtifactReplayDecision,
136
+ });
137
+ return toCompletionResult("orcarouter", model, payload);
138
+ },
139
+ async stream(request, auth, onToken) {
140
+ if (!auth.apiKey)
141
+ throw new Error("OrcaRouter API key is required");
142
+ const model = request.model ?? defaultModels.orcarouter;
143
+ const payload = await openAiCompatibleStream({
144
+ provider: "OrcaRouter",
145
+ providerId: "orcarouter",
146
+ baseUrl,
147
+ apiKey: auth.apiKey,
148
+ model,
149
+ messages: singleLeadingSystemMessages(request.messages),
150
+ maxTokens: request.maxTokens,
151
+ temperature: request.temperature,
152
+ signal: request.signal,
153
+ onToken,
154
+ onToolCallDelta: request.onToolCallDelta,
155
+ onStreamEvent: request.onStreamEvent,
156
+ reasoning: request.thinking,
157
+ reasoningStyle: "openai",
158
+ tools: request.tools,
159
+ toolChoice: request.toolChoice,
160
+ parallelToolCalls: request.parallelToolCalls,
161
+ reasoningArtifactReplayObserver: request.onReasoningArtifactReplayDecision,
162
+ });
163
+ return toCompletionResult("orcarouter", model, payload);
164
+ },
165
+ };
166
+ //# sourceMappingURL=orcarouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orcarouter.js","sourceRoot":"","sources":["../../src/llm/orcarouter.ts"],"names":[],"mappings":"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"}