@venturekit-pro/ai 0.0.0-dev.20260701100017 → 0.0.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 (58) hide show
  1. package/README.md +48 -0
  2. package/dist/chat/anthropic.d.ts.map +1 -1
  3. package/dist/chat/anthropic.js +39 -32
  4. package/dist/chat/anthropic.js.map +1 -1
  5. package/dist/chat/google.d.ts.map +1 -1
  6. package/dist/chat/google.js +32 -25
  7. package/dist/chat/google.js.map +1 -1
  8. package/dist/chat/openai.d.ts.map +1 -1
  9. package/dist/chat/openai.js +34 -27
  10. package/dist/chat/openai.js.map +1 -1
  11. package/dist/cost-ledger/index.d.ts +2 -0
  12. package/dist/cost-ledger/index.d.ts.map +1 -1
  13. package/dist/cost-ledger/index.js +1 -0
  14. package/dist/cost-ledger/index.js.map +1 -1
  15. package/dist/cost-ledger/migrations/vk_ai_cost_0001_init.sql +6 -6
  16. package/dist/cost-ledger/migrations/vk_ai_cost_0002_llm_models.sql +4 -4
  17. package/dist/cost-ledger/query.js +4 -4
  18. package/dist/cost-ledger/record.js +2 -2
  19. package/dist/cost-ledger/record.js.map +1 -1
  20. package/dist/cost-ledger/windows.d.ts +82 -0
  21. package/dist/cost-ledger/windows.d.ts.map +1 -0
  22. package/dist/cost-ledger/windows.js +147 -0
  23. package/dist/cost-ledger/windows.js.map +1 -0
  24. package/dist/image/client.d.ts +32 -0
  25. package/dist/image/client.d.ts.map +1 -0
  26. package/dist/image/client.js +25 -0
  27. package/dist/image/client.js.map +1 -0
  28. package/dist/image/google.d.ts +24 -0
  29. package/dist/image/google.d.ts.map +1 -0
  30. package/dist/image/google.js +60 -0
  31. package/dist/image/google.js.map +1 -0
  32. package/dist/image/index.d.ts +11 -0
  33. package/dist/image/index.d.ts.map +1 -0
  34. package/dist/image/index.js +9 -0
  35. package/dist/image/index.js.map +1 -0
  36. package/dist/image/types.d.ts +67 -0
  37. package/dist/image/types.d.ts.map +1 -0
  38. package/dist/image/types.js +19 -0
  39. package/dist/image/types.js.map +1 -0
  40. package/dist/index.d.ts +6 -2
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +5 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/model-catalog/crud.d.ts +42 -0
  45. package/dist/model-catalog/crud.d.ts.map +1 -0
  46. package/dist/model-catalog/crud.js +162 -0
  47. package/dist/model-catalog/crud.js.map +1 -0
  48. package/dist/model-catalog/index.d.ts +11 -0
  49. package/dist/model-catalog/index.d.ts.map +1 -0
  50. package/dist/model-catalog/index.js +10 -0
  51. package/dist/model-catalog/index.js.map +1 -0
  52. package/dist/model-catalog/types.d.ts +97 -0
  53. package/dist/model-catalog/types.d.ts.map +1 -0
  54. package/dist/model-catalog/types.js +16 -0
  55. package/dist/model-catalog/types.js.map +1 -0
  56. package/package.json +3 -3
  57. package/src/cost-ledger/migrations/vk_ai_cost_0001_init.sql +6 -6
  58. package/src/cost-ledger/migrations/vk_ai_cost_0002_llm_models.sql +4 -4
package/README.md CHANGED
@@ -108,6 +108,54 @@ const agent = createAgent({
108
108
  const response = await agent.run('How do I set up authentication?');
109
109
  ```
110
110
 
111
+ ## Chat Completion
112
+
113
+ Provider-neutral single- or multi-turn text completion across Anthropic,
114
+ OpenAI, and Google. Construct one client per `(provider, apiKey)` and call
115
+ `.complete()`; supply `pricing` to get a USD cost stamp back.
116
+
117
+ ```typescript
118
+ import { createChatClient } from '@venturekit-pro/ai';
119
+
120
+ const client = createChatClient({ provider: 'anthropic', apiKey: process.env.ANTHROPIC_API_KEY! });
121
+
122
+ const result = await client.complete({
123
+ model: 'claude-sonnet-4-5-20250929',
124
+ messages: [
125
+ { role: 'system', content: 'You are a concise assistant.' },
126
+ { role: 'user', content: 'Three words about cats.' },
127
+ ],
128
+ maxTokens: 100,
129
+ pricing: { costPer1kInputUsd: 0.003, costPer1kOutputUsd: 0.015 },
130
+ });
131
+
132
+ console.log(result.output, result.usage, result.cost);
133
+ ```
134
+
135
+ Pair with `withFallback` / `retryWithBackoff` from the fallback module to add
136
+ primary→backup routing or exponential-backoff retries.
137
+
138
+ ## Image Generation
139
+
140
+ Provider-neutral text-to-image (currently Google Imagen), returning raw image
141
+ bytes. The caller owns prompt composition (brand/style suffixes) and cost
142
+ attribution — the result carries provider/model echo and latency only.
143
+
144
+ ```typescript
145
+ import { createImageClient } from '@venturekit-pro/ai';
146
+
147
+ const client = createImageClient({ provider: 'google', apiKey: process.env.GOOGLE_API_KEY! });
148
+
149
+ const { images } = await client.generate({
150
+ model: 'imagen-4.0-ultra-generate-001',
151
+ prompt: 'A sunlit Casablanca apartment, editorial photographic style.',
152
+ aspectRatio: '16:9',
153
+ count: 1,
154
+ });
155
+
156
+ // images[0].bytes (Uint8Array), images[0].mimeType
157
+ ```
158
+
111
159
  ## API Reference
112
160
 
113
161
  See the [API reference](https://venturekit.dev/api-reference/ai) for full documentation.
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/chat/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAWD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CA+E/B"}
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/chat/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAWD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAsF/B"}
@@ -43,10 +43,17 @@ export async function completeWithAnthropic(config, request) {
43
43
  if (system !== undefined)
44
44
  body.system = system;
45
45
  const controller = new AbortController();
46
+ // The timeout must cover the FULL request — establishing the
47
+ // connection AND reading the response body. Clearing it the moment
48
+ // `fetch` resolves (i.e. once response headers arrive) would leave the
49
+ // `response.json()` / `response.text()` body reads below unprotected:
50
+ // a provider that sends headers then stalls the body would hang this
51
+ // call — and any workflow run awaiting it — indefinitely. Keep the
52
+ // abort signal armed until the body is fully consumed; clear it only
53
+ // in `finally` (success, error, or abort).
46
54
  const timer = setTimeout(() => controller.abort(), timeoutMs);
47
- let response;
48
55
  try {
49
- response = await fetch(`${baseUrl}/v1/messages`, {
56
+ const response = await fetch(`${baseUrl}/v1/messages`, {
50
57
  method: 'POST',
51
58
  headers: {
52
59
  'x-api-key': config.apiKey,
@@ -57,40 +64,40 @@ export async function completeWithAnthropic(config, request) {
57
64
  body: JSON.stringify(body),
58
65
  signal: controller.signal,
59
66
  });
67
+ if (!response.ok) {
68
+ const text = (await response.text()).slice(0, 500);
69
+ throw new Error(`[ai/chat/anthropic] ${response.status} ${response.statusText}: ${text}`);
70
+ }
71
+ const json = (await response.json());
72
+ // Anthropic returns a `content` array of blocks; we concatenate
73
+ // all `text` blocks. Tool-use blocks pass through silently (this
74
+ // module doesn't support tools — if a caller routes a tool-using
75
+ // prompt here, they'll see an empty completion and our error
76
+ // below will fire).
77
+ const output = (json.content ?? [])
78
+ .filter((b) => b.type === 'text' && typeof b.text === 'string')
79
+ .map((b) => b.text)
80
+ .join('');
81
+ if (output.length === 0) {
82
+ throw new Error(`[ai/chat/anthropic] Empty completion (stop_reason=${json.stop_reason ?? 'unknown'})`);
83
+ }
84
+ const usage = {
85
+ tokensIn: json.usage?.input_tokens ?? null,
86
+ tokensOut: json.usage?.output_tokens ?? null,
87
+ };
88
+ return {
89
+ output,
90
+ provider: 'anthropic',
91
+ model: request.model,
92
+ usage,
93
+ cost: stampCost(usage, request.pricing),
94
+ latencyMs: Date.now() - startedAt,
95
+ finishReason: mapFinishReason(json.stop_reason ?? null),
96
+ };
60
97
  }
61
98
  finally {
62
99
  clearTimeout(timer);
63
100
  }
64
- if (!response.ok) {
65
- const text = (await response.text()).slice(0, 500);
66
- throw new Error(`[ai/chat/anthropic] ${response.status} ${response.statusText}: ${text}`);
67
- }
68
- const json = (await response.json());
69
- // Anthropic returns a `content` array of blocks; we concatenate
70
- // all `text` blocks. Tool-use blocks pass through silently (this
71
- // module doesn't support tools — if a caller routes a tool-using
72
- // prompt here, they'll see an empty completion and our error
73
- // below will fire).
74
- const output = (json.content ?? [])
75
- .filter((b) => b.type === 'text' && typeof b.text === 'string')
76
- .map((b) => b.text)
77
- .join('');
78
- if (output.length === 0) {
79
- throw new Error(`[ai/chat/anthropic] Empty completion (stop_reason=${json.stop_reason ?? 'unknown'})`);
80
- }
81
- const usage = {
82
- tokensIn: json.usage?.input_tokens ?? null,
83
- tokensOut: json.usage?.output_tokens ?? null,
84
- };
85
- return {
86
- output,
87
- provider: 'anthropic',
88
- model: request.model,
89
- usage,
90
- cost: stampCost(usage, request.pricing),
91
- latencyMs: Date.now() - startedAt,
92
- finishReason: mapFinishReason(json.stop_reason ?? null),
93
- };
94
101
  }
95
102
  /**
96
103
  * Split a leading `system` message off the conversation. Anthropic
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/chat/anthropic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/chat/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAkB3C,sEAAsE;AACtE,MAAM,yBAAyB,GAAG,YAAY,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAA8B,EAC9B,OAA8B;IAE9B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,2BAA2B,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACpF,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,yBAAyB,CAAC;IAClE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC;IAElE,+DAA+D;IAC/D,8DAA8D;IAC9D,gDAAgD;IAChD,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE/D,MAAM,IAAI,GAA4B;QACpC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,UAAU,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;QACrC,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;KAC1E,CAAC;IACF,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;QAAE,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAC9E,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1D,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAChF,IAAI,MAAM,KAAK,SAAS;QAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IAE/C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,6DAA6D;IAC7D,mEAAmE;IACnE,uEAAuE;IACvE,sEAAsE;IACtE,qEAAqE;IACrE,mEAAmE;IACnE,qEAAqE;IACrE,2CAA2C;IAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,cAAc,EAAE;YACrD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,WAAW,EAAE,MAAM,CAAC,MAAM;gBAC1B,mBAAmB,EAAE,UAAU;gBAC/B,cAAc,EAAE,kBAAkB;gBAClC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjF;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAC1B,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACnD,MAAM,IAAI,KAAK,CACb,uBAAuB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,KAAK,IAAI,EAAE,CACzE,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA8B,CAAC;QAElE,gEAAgE;QAChE,iEAAiE;QACjE,iEAAiE;QACjE,6DAA6D;QAC7D,oBAAoB;QACpB,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;aAChC,MAAM,CAAC,CAAC,CAAC,EAAuC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;aACnG,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAClB,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,qDAAqD,IAAI,CAAC,WAAW,IAAI,SAAS,GAAG,CACtF,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG;YACZ,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,YAAY,IAAI,IAAI;YAC1C,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,aAAa,IAAI,IAAI;SAC7C,CAAC;QAEF,OAAO;YACL,MAAM;YACN,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK;YACL,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC;YACvC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;YACjC,YAAY,EAAE,eAAe,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC;SACxD,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,QAAuB;IAI1C,IAAI,MAA0B,CAAC;IAC/B,MAAM,YAAY,GAAsD,EAAE,CAAC;IAC3E,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxB,IAAI,MAAM,KAAK,SAAS,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpD,MAAM,IAAI,KAAK,CACb,uEAAuE,CACxE,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,eAAe,CAAC,GAAkB;IACzC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,UAAU,CAAC;QAChB,KAAK,eAAe;YAClB,OAAO,MAAM,CAAC;QAChB,KAAK,YAAY;YACf,OAAO,QAAQ,CAAC;QAClB,KAAK,UAAU;YACb,OAAO,YAAY,CAAC;QACtB;YACE,OAAO,GAAG,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/chat/google.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CA6E/B"}
1
+ {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/chat/google.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAoF/B"}
@@ -45,42 +45,49 @@ export async function completeWithGoogle(config, request) {
45
45
  // the URL.
46
46
  const url = `${baseUrl}/${apiVersion}/models/${encodeURIComponent(request.model)}:generateContent?key=${encodeURIComponent(config.apiKey)}`;
47
47
  const controller = new AbortController();
48
+ // The timeout must cover the FULL request — establishing the
49
+ // connection AND reading the response body. Clearing it the moment
50
+ // `fetch` resolves (i.e. once response headers arrive) would leave the
51
+ // `response.json()` / `response.text()` body reads below unprotected:
52
+ // a provider that sends headers then stalls the body would hang this
53
+ // call — and any workflow run awaiting it — indefinitely. Keep the
54
+ // abort signal armed until the body is fully consumed; clear it only
55
+ // in `finally` (success, error, or abort).
48
56
  const timer = setTimeout(() => controller.abort(), timeoutMs);
49
- let response;
50
57
  try {
51
- response = await fetch(url, {
58
+ const response = await fetch(url, {
52
59
  method: 'POST',
53
60
  headers: { 'Content-Type': 'application/json' },
54
61
  body: JSON.stringify(body),
55
62
  signal: controller.signal,
56
63
  });
64
+ if (!response.ok) {
65
+ const text = (await response.text()).slice(0, 500);
66
+ throw new Error(`[ai/chat/google] ${response.status} ${response.statusText}: ${text}`);
67
+ }
68
+ const json = (await response.json());
69
+ const candidate = json.candidates?.[0];
70
+ const text = candidate?.content?.parts?.map((p) => p.text ?? '').join('') ?? '';
71
+ if (text.length === 0) {
72
+ throw new Error(`[ai/chat/google] Empty completion (finishReason=${candidate?.finishReason ?? 'unknown'})`);
73
+ }
74
+ const usage = {
75
+ tokensIn: json.usageMetadata?.promptTokenCount ?? null,
76
+ tokensOut: json.usageMetadata?.candidatesTokenCount ?? null,
77
+ };
78
+ return {
79
+ output: text,
80
+ provider: 'google',
81
+ model: request.model,
82
+ usage,
83
+ cost: stampCost(usage, request.pricing),
84
+ latencyMs: Date.now() - startedAt,
85
+ finishReason: mapFinishReason(candidate?.finishReason ?? null),
86
+ };
57
87
  }
58
88
  finally {
59
89
  clearTimeout(timer);
60
90
  }
61
- if (!response.ok) {
62
- const text = (await response.text()).slice(0, 500);
63
- throw new Error(`[ai/chat/google] ${response.status} ${response.statusText}: ${text}`);
64
- }
65
- const json = (await response.json());
66
- const candidate = json.candidates?.[0];
67
- const text = candidate?.content?.parts?.map((p) => p.text ?? '').join('') ?? '';
68
- if (text.length === 0) {
69
- throw new Error(`[ai/chat/google] Empty completion (finishReason=${candidate?.finishReason ?? 'unknown'})`);
70
- }
71
- const usage = {
72
- tokensIn: json.usageMetadata?.promptTokenCount ?? null,
73
- tokensOut: json.usageMetadata?.candidatesTokenCount ?? null,
74
- };
75
- return {
76
- output: text,
77
- provider: 'google',
78
- model: request.model,
79
- usage,
80
- cost: stampCost(usage, request.pricing),
81
- latencyMs: Date.now() - startedAt,
82
- finishReason: mapFinishReason(candidate?.finishReason ?? null),
83
- };
84
91
  }
85
92
  function splitSystem(messages) {
86
93
  let system;
@@ -1 +1 @@
1
- {"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/chat/google.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/chat/google.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/chat/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAkE/B"}
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/chat/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAyE/B"}
@@ -37,10 +37,17 @@ export async function completeWithOpenAi(config, request) {
37
37
  if (request.stop && request.stop.length > 0)
38
38
  body.stop = request.stop;
39
39
  const controller = new AbortController();
40
+ // The timeout must cover the FULL request — establishing the
41
+ // connection AND reading the response body. Clearing it the moment
42
+ // `fetch` resolves (i.e. once response headers arrive) would leave the
43
+ // `response.json()` / `response.text()` body reads below unprotected:
44
+ // a provider that sends headers then stalls the body would hang this
45
+ // call — and any workflow run awaiting it — indefinitely. Keep the
46
+ // abort signal armed until the body is fully consumed; clear it only
47
+ // in `finally` (success, error, or abort).
40
48
  const timer = setTimeout(() => controller.abort(), timeoutMs);
41
- let response;
42
49
  try {
43
- response = await fetch(`${baseUrl}/v1/chat/completions`, {
50
+ const response = await fetch(`${baseUrl}/v1/chat/completions`, {
44
51
  method: 'POST',
45
52
  headers: {
46
53
  Authorization: `Bearer ${config.apiKey}`,
@@ -52,35 +59,35 @@ export async function completeWithOpenAi(config, request) {
52
59
  body: JSON.stringify(body),
53
60
  signal: controller.signal,
54
61
  });
62
+ if (!response.ok) {
63
+ // Truncate the response body so the error message stays
64
+ // log-friendly. Full body is recoverable via the upstream
65
+ // caller's `audit_events.error_message` when wired through.
66
+ const text = (await response.text()).slice(0, 500);
67
+ throw new Error(`[ai/chat/openai] ${response.status} ${response.statusText}: ${text}`);
68
+ }
69
+ const json = (await response.json());
70
+ const text = json.choices?.[0]?.message?.content;
71
+ if (!text) {
72
+ throw new Error('[ai/chat/openai] Empty completion');
73
+ }
74
+ const usage = {
75
+ tokensIn: json.usage?.prompt_tokens ?? null,
76
+ tokensOut: json.usage?.completion_tokens ?? null,
77
+ };
78
+ return {
79
+ output: text,
80
+ provider: 'openai',
81
+ model: request.model,
82
+ usage,
83
+ cost: stampCost(usage, request.pricing),
84
+ latencyMs: Date.now() - startedAt,
85
+ finishReason: mapFinishReason(json.choices?.[0]?.finish_reason ?? null),
86
+ };
55
87
  }
56
88
  finally {
57
89
  clearTimeout(timer);
58
90
  }
59
- if (!response.ok) {
60
- // Truncate the response body so the error message stays
61
- // log-friendly. Full body is recoverable via the upstream
62
- // caller's `audit_events.error_message` when wired through.
63
- const text = (await response.text()).slice(0, 500);
64
- throw new Error(`[ai/chat/openai] ${response.status} ${response.statusText}: ${text}`);
65
- }
66
- const json = (await response.json());
67
- const text = json.choices?.[0]?.message?.content;
68
- if (!text) {
69
- throw new Error('[ai/chat/openai] Empty completion');
70
- }
71
- const usage = {
72
- tokensIn: json.usage?.prompt_tokens ?? null,
73
- tokensOut: json.usage?.completion_tokens ?? null,
74
- };
75
- return {
76
- output: text,
77
- provider: 'openai',
78
- model: request.model,
79
- usage,
80
- cost: stampCost(usage, request.pricing),
81
- latencyMs: Date.now() - startedAt,
82
- finishReason: mapFinishReason(json.choices?.[0]?.finish_reason ?? null),
83
- };
84
91
  }
85
92
  function mapFinishReason(raw) {
86
93
  if (!raw)
@@ -1 +1 @@
1
- {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/chat/openai.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/chat/openai.ts"],"names":[],"mappings":"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"}
@@ -9,5 +9,7 @@ export type { LlmCostInput, LlmCostEvent, LlmCostRollup, Querier, } from './type
9
9
  export { recordLlmCost } from './record.js';
10
10
  export { listLlmCosts, costByTarget, costByCorrelation, costByTenant, costByMonth, } from './query.js';
11
11
  export type { ListLlmCostsArgs, CostByTargetArgs, CostByCorrelationArgs, CostByTenantArgs, CostByMonthArgs, MonthlyCostBucket, } from './query.js';
12
+ export { computeWindows, rollupCostWindow } from './windows.js';
13
+ export type { CostWindowKey, CostWindowRange, CostTotals, CostByModelRow, CostBySourceRow, CostRollupResult, RollupCostWindowArgs, } from './windows.js';
12
14
  export { getAiCostMigrationsDir } from './path.js';
13
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cost-ledger/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,OAAO,GACR,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cost-ledger/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,OAAO,GACR,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhE,YAAY,EACV,aAAa,EACb,eAAe,EACf,UAAU,EACV,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC"}
@@ -7,5 +7,6 @@
7
7
  */
8
8
  export { recordLlmCost } from './record.js';
9
9
  export { listLlmCosts, costByTarget, costByCorrelation, costByTenant, costByMonth, } from './query.js';
10
+ export { computeWindows, rollupCostWindow } from './windows.js';
10
11
  export { getAiCostMigrationsDir } from './path.js';
11
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cost-ledger/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AAWpB,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cost-ledger/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AAWpB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAYhE,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC"}
@@ -16,7 +16,7 @@
16
16
 
17
17
  CREATE EXTENSION IF NOT EXISTS pgcrypto;
18
18
 
19
- CREATE TABLE IF NOT EXISTS llm_cost_events (
19
+ CREATE TABLE IF NOT EXISTS vk_llm_cost_events (
20
20
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
21
21
  -- Nullable to match the audit-events convention; platform-wide
22
22
  -- LLM calls (e.g. eval / smoke tests) carry tenant_id = NULL.
@@ -56,19 +56,19 @@ CREATE TABLE IF NOT EXISTS llm_cost_events (
56
56
  -- ─── Indexes ────────────────────────────────────────────────────────
57
57
 
58
58
  CREATE INDEX IF NOT EXISTS llm_cost_events_tenant_created_idx
59
- ON llm_cost_events (tenant_id, created_at DESC);
59
+ ON vk_llm_cost_events (tenant_id, created_at DESC);
60
60
 
61
61
  CREATE INDEX IF NOT EXISTS llm_cost_events_target_idx
62
- ON llm_cost_events (tenant_id, target_type, target_id, created_at DESC);
62
+ ON vk_llm_cost_events (tenant_id, target_type, target_id, created_at DESC);
63
63
 
64
64
  CREATE INDEX IF NOT EXISTS llm_cost_events_correlation_idx
65
- ON llm_cost_events (correlation_id, created_at DESC)
65
+ ON vk_llm_cost_events (correlation_id, created_at DESC)
66
66
  WHERE correlation_id IS NOT NULL;
67
67
 
68
68
  CREATE INDEX IF NOT EXISTS llm_cost_events_tenant_provider_idx
69
- ON llm_cost_events (tenant_id, provider, created_at DESC);
69
+ ON vk_llm_cost_events (tenant_id, provider, created_at DESC);
70
70
 
71
71
  -- Idempotency dedup. Partial because most rows have NULL key.
72
72
  CREATE UNIQUE INDEX IF NOT EXISTS llm_cost_events_idempotency_unique
73
- ON llm_cost_events (idempotency_key)
73
+ ON vk_llm_cost_events (idempotency_key)
74
74
  WHERE idempotency_key IS NOT NULL;
@@ -51,7 +51,7 @@ CREATE TYPE llm_model_status AS ENUM (
51
51
 
52
52
  -- ─── llm_models ────────────────────────────────────────────────────
53
53
 
54
- CREATE TABLE IF NOT EXISTS llm_models (
54
+ CREATE TABLE IF NOT EXISTS vk_llm_models (
55
55
  -- Stable catalog id. App-side rows (e.g. `editorial_personas.model`
56
56
  -- in the CMS) store THIS, not the vendor's wire id. Lets vendors
57
57
  -- rename / replace a SKU without re-stamping every consumer.
@@ -69,7 +69,7 @@ CREATE TABLE IF NOT EXISTS llm_models (
69
69
  -- When status='deprecated', the suggested replacement `key`. Used
70
70
  -- by the CMS's persona picker to surface "Use <replacement>
71
71
  -- instead" nudges (§4.10).
72
- replacement_key varchar(64) REFERENCES llm_models(key) ON DELETE SET NULL,
72
+ replacement_key varchar(64) REFERENCES vk_llm_models(key) ON DELETE SET NULL,
73
73
 
74
74
  -- ─── Pricing (USD per 1K tokens) ────────────────────────────────
75
75
  -- Nullable for experimental / on-prem models with no published
@@ -116,9 +116,9 @@ CREATE TABLE IF NOT EXISTS llm_models (
116
116
  );
117
117
 
118
118
  CREATE INDEX IF NOT EXISTS llm_models_status_idx
119
- ON llm_models (status);
119
+ ON vk_llm_models (status);
120
120
  CREATE INDEX IF NOT EXISTS llm_models_provider_idx
121
- ON llm_models (provider);
121
+ ON vk_llm_models (provider);
122
122
 
123
123
  -- ─── No seed ───────────────────────────────────────────────────────
124
124
  -- Intentionally empty. See file header for the rationale: catalog
@@ -21,13 +21,13 @@ async function fetchTotals(querier, whereClause, params) {
21
21
  COUNT(*) AS "eventCount",
22
22
  COALESCE(SUM(tokens_in), 0) AS "totalTokensIn",
23
23
  COALESCE(SUM(tokens_out), 0) AS "totalTokensOut"
24
- FROM llm_cost_events
24
+ FROM vk_llm_cost_events
25
25
  WHERE ${whereClause}`, params);
26
26
  return rows[0];
27
27
  }
28
28
  async function fetchProviderSplit(querier, whereClause, params) {
29
29
  const rows = await querier(`SELECT provider, COALESCE(SUM(cost_usd), 0) AS "costUsd"
30
- FROM llm_cost_events
30
+ FROM vk_llm_cost_events
31
31
  WHERE ${whereClause}
32
32
  GROUP BY provider`, params);
33
33
  const out = {};
@@ -82,7 +82,7 @@ export async function listLlmCosts(querier, args) {
82
82
  }
83
83
  const limit = Math.min(Math.max(args.limit ?? 50, 1), 500);
84
84
  params.push(limit);
85
- return querier(`SELECT * FROM llm_cost_events
85
+ return querier(`SELECT * FROM vk_llm_cost_events
86
86
  WHERE ${conditions.join(' AND ')}
87
87
  ORDER BY created_at DESC, id DESC
88
88
  LIMIT $${params.length}`, params);
@@ -122,7 +122,7 @@ export async function costByMonth(querier, args) {
122
122
  COALESCE(SUM(c.tokens_in), 0) AS "totalTokensIn",
123
123
  COALESCE(SUM(c.tokens_out), 0) AS "totalTokensOut"
124
124
  FROM months
125
- LEFT JOIN llm_cost_events c
125
+ LEFT JOIN vk_llm_cost_events c
126
126
  ON c.tenant_id = $1
127
127
  AND c.created_at >= months.month_start
128
128
  AND c.created_at < months.month_start + interval '1 month'
@@ -25,7 +25,7 @@ export async function recordLlmCost(querier, input) {
25
25
  }
26
26
  const payload = sanitizePayload(input.payload);
27
27
  const sql = `
28
- INSERT INTO llm_cost_events (
28
+ INSERT INTO vk_llm_cost_events (
29
29
  tenant_id,
30
30
  source,
31
31
  target_type,
@@ -74,7 +74,7 @@ export async function recordLlmCost(querier, input) {
74
74
  if (input.idempotencyKey &&
75
75
  isUniqueViolation(err) &&
76
76
  isIdempotencyConstraint(err)) {
77
- const existing = await querier(`SELECT * FROM llm_cost_events WHERE idempotency_key = $1 LIMIT 1`, [input.idempotencyKey]);
77
+ const existing = await querier(`SELECT * FROM vk_llm_cost_events WHERE idempotency_key = $1 LIMIT 1`, [input.idempotencyKey]);
78
78
  if (existing[0])
79
79
  return existing[0];
80
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"record.js","sourceRoot":"","sources":["../../src/cost-ledger/record.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"record.js","sourceRoot":"","sources":["../../src/cost-ledger/record.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Window-based cost rollups over `vk_llm_cost_events`.
3
+ *
4
+ * Generic, app-agnostic aggregation for the "cost dashboard" use-case:
5
+ * pick a trailing window (`7d` / `30d` / `90d` / `ytd`), get KPI totals
6
+ * + a per-model and per-source breakdown, plus the same totals for the
7
+ * immediately-prior window so the page can render a period-over-period
8
+ * delta.
9
+ *
10
+ * Distinct from the `query.ts` rollups (which split by `provider` and
11
+ * return `LlmCostRollup`): this module is keyed on the canonical
12
+ * `cost_micro_usd` (bigint — safer to SUM than the `cost_usd` numeric)
13
+ * and surfaces both micro-USD (client math) and USD (display).
14
+ *
15
+ * App-specific rollups that JOIN the consumer's own tables (e.g. the
16
+ * CMS's per-blog-post rollup over `editorial_runs`) stay in the app —
17
+ * this module only covers the table the package owns.
18
+ */
19
+ import type { Querier } from './types.js';
20
+ export type CostWindowKey = '7d' | '30d' | '90d' | 'ytd';
21
+ export interface CostWindowRange {
22
+ /** Inclusive start (ISO). */
23
+ startedAt: string;
24
+ /** Exclusive end (ISO) — typically `now`. */
25
+ endedAt: string;
26
+ }
27
+ export interface CostTotals {
28
+ costMicroUsd: number;
29
+ costUsd: number;
30
+ calls: number;
31
+ tokensIn: number;
32
+ tokensOut: number;
33
+ }
34
+ export interface CostByModelRow {
35
+ provider: string;
36
+ model: string;
37
+ calls: number;
38
+ costMicroUsd: number;
39
+ costUsd: number;
40
+ tokensIn: number;
41
+ tokensOut: number;
42
+ }
43
+ export interface CostBySourceRow {
44
+ source: string;
45
+ calls: number;
46
+ costMicroUsd: number;
47
+ costUsd: number;
48
+ }
49
+ export interface CostRollupResult {
50
+ window: CostWindowRange;
51
+ prevWindow: CostWindowRange;
52
+ totals: CostTotals;
53
+ prevTotals: CostTotals;
54
+ byModel: CostByModelRow[];
55
+ bySource: CostBySourceRow[];
56
+ }
57
+ /**
58
+ * Resolve `(current, previous)` ranges for the given key. `now` is
59
+ * threaded through so callers / tests can pin the clock.
60
+ *
61
+ * The `ytd` prior window is the same span last year, ending at "today"
62
+ * one year ago. Fixed windows (`7d`/`30d`/`90d`) use the immediately
63
+ * preceding span of equal length.
64
+ */
65
+ export declare function computeWindows(key: CostWindowKey, now?: Date): {
66
+ current: CostWindowRange;
67
+ previous: CostWindowRange;
68
+ };
69
+ export interface RollupCostWindowArgs {
70
+ tenantId: string;
71
+ windowKey: CostWindowKey;
72
+ /** Pin the clock (tests / replay). Defaults to `new Date()`. */
73
+ now?: Date;
74
+ }
75
+ /**
76
+ * Roll up costs for one tenant over the given window. Issues four
77
+ * parallel queries (totals, prev totals, byModel, bySource) and combines
78
+ * them into a single dashboard DTO. Empty windows return zeros (not
79
+ * NULLs) so callers can do delta math without null-guarding.
80
+ */
81
+ export declare function rollupCostWindow(querier: Querier, args: RollupCostWindowArgs): Promise<CostRollupResult>;
82
+ //# sourceMappingURL=windows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windows.d.ts","sourceRoot":"","sources":["../../src/cost-ledger/windows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,UAAU,EAAE,eAAe,CAAC;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAID;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,aAAa,EAClB,GAAG,GAAE,IAAiB,GACrB;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,CAoCzD;AAwHD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,CAAC;IACzB,gEAAgE;IAChE,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAgB3B"}