@vijaypjavvadi/bdd2pw 3.10.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +253 -0
- package/README.md +19 -12
- package/dist/cli.js +39 -7
- package/dist/cli.js.map +1 -1
- package/dist/data/dataLoader.d.ts +78 -0
- package/dist/data/dataLoader.js +339 -0
- package/dist/data/dataLoader.js.map +1 -0
- package/dist/data/examplesInjector.d.ts +64 -0
- package/dist/data/examplesInjector.js +149 -0
- package/dist/data/examplesInjector.js.map +1 -0
- package/dist/data/synthGenerator.d.ts +71 -0
- package/dist/data/synthGenerator.js +265 -0
- package/dist/data/synthGenerator.js.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/anthropicClient.d.ts +11 -0
- package/dist/llm/anthropicClient.js +89 -0
- package/dist/llm/anthropicClient.js.map +1 -1
- package/dist/llm/geminiClient.d.ts +92 -0
- package/dist/llm/geminiClient.js +559 -0
- package/dist/llm/geminiClient.js.map +1 -0
- package/dist/llm/index.d.ts +2 -0
- package/dist/llm/index.js +13 -2
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/openaiClient.d.ts +83 -0
- package/dist/llm/openaiClient.js +529 -0
- package/dist/llm/openaiClient.js.map +1 -0
- package/dist/llm/telemetry.js +14 -0
- package/dist/llm/telemetry.js.map +1 -1
- package/dist/llm/types.d.ts +45 -2
- package/dist/types.d.ts +41 -1
- package/package.json +5 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI LLM client — v3.11.0.
|
|
3
|
+
*
|
|
4
|
+
* Implements the same `LLMClient` interface as `AnthropicLLMClient`:
|
|
5
|
+
* single-step `generateBinding`, batched `generateBatchBindings`,
|
|
6
|
+
* cache hit accounting, budget tracking, governance sanitisation,
|
|
7
|
+
* step deadlines, provider timeouts.
|
|
8
|
+
*
|
|
9
|
+
* Differences from the Anthropic client are minimal and limited to
|
|
10
|
+
* the SDK call shape:
|
|
11
|
+
*
|
|
12
|
+
* Anthropic OpenAI
|
|
13
|
+
* ------------------------------- -----------------------------
|
|
14
|
+
* anthropic.messages.create({ openai.chat.completions.create({
|
|
15
|
+
* system: SYSTEM_PROMPT, messages: [
|
|
16
|
+
* messages: [ { role: 'system',
|
|
17
|
+
* { role: 'user', content } content: SYSTEM_PROMPT },
|
|
18
|
+
* ] { role: 'user', content }
|
|
19
|
+
* }) ]
|
|
20
|
+
* })
|
|
21
|
+
*
|
|
22
|
+
* resp.content[0].text resp.choices[0].message.content
|
|
23
|
+
* resp.usage.input_tokens resp.usage.prompt_tokens
|
|
24
|
+
* resp.usage.output_tokens resp.usage.completion_tokens
|
|
25
|
+
*
|
|
26
|
+
* The prompt machinery (`SYSTEM_PROMPT`, `buildUserPrompt`,
|
|
27
|
+
* `buildBatchUserPrompt`, `cacheKey`), the parser (`parseBindingJson`),
|
|
28
|
+
* the cache (`openSqliteCache`), and the governance client
|
|
29
|
+
* (`GovernanceClient`) are all shared with the Anthropic path —
|
|
30
|
+
* cache keys interoperate, so a scaffold cached under one provider
|
|
31
|
+
* hits the cache under another (cache keys include the model name,
|
|
32
|
+
* so cross-provider hits only fire when models match).
|
|
33
|
+
*
|
|
34
|
+
* Default model: `gpt-4o-mini`. Reasoning: bdd2pw's task is
|
|
35
|
+
* structured JSON output over a small set of regex-shaped
|
|
36
|
+
* deterministic patterns. Mini handles it reliably and runs ~17x
|
|
37
|
+
* cheaper than gpt-4o ($0.15 vs $2.50 per million input tokens).
|
|
38
|
+
* Override via `LLMClientOptions.model`.
|
|
39
|
+
*/
|
|
40
|
+
import type { BindingCache } from "./cache";
|
|
41
|
+
import type { GenerateBindingInput, GenerateBindingResult, LLMClient, LLMClientOptions } from "./types";
|
|
42
|
+
export declare class OpenAILLMClient implements LLMClient {
|
|
43
|
+
private model;
|
|
44
|
+
private apiKey;
|
|
45
|
+
private maxCalls;
|
|
46
|
+
private skipGovernance;
|
|
47
|
+
private log;
|
|
48
|
+
private governance;
|
|
49
|
+
private cache;
|
|
50
|
+
private cachePath;
|
|
51
|
+
private callsCounter;
|
|
52
|
+
private attemptsCounter;
|
|
53
|
+
private openai;
|
|
54
|
+
private cachePersistent;
|
|
55
|
+
private cacheFallbackReason;
|
|
56
|
+
private providerTimeoutMs;
|
|
57
|
+
constructor(opts: LLMClientOptions, cachePathDefault: string);
|
|
58
|
+
ensureCache(): Promise<BindingCache>;
|
|
59
|
+
budgetExhausted(): boolean;
|
|
60
|
+
callsMade(): number;
|
|
61
|
+
callsAttempted(): number;
|
|
62
|
+
cacheBackendPersistent(): boolean | null;
|
|
63
|
+
cacheBackendFallbackReason(): string | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Single-step generation. Cache → governance → OpenAI → parse.
|
|
66
|
+
* Mirrors `AnthropicLLMClient.generateBinding` end-to-end.
|
|
67
|
+
*/
|
|
68
|
+
generateBinding(input: GenerateBindingInput): Promise<GenerateBindingResult>;
|
|
69
|
+
/**
|
|
70
|
+
* Batched generation — same per-step cache lookup + single batched
|
|
71
|
+
* prompt as `AnthropicLLMClient.generateBatchBindings`. The JSON array
|
|
72
|
+
* response is parsed slot by slot through `parseBindingJson`.
|
|
73
|
+
*/
|
|
74
|
+
generateBatchBindings(inputs: GenerateBindingInput[]): Promise<GenerateBindingResult[]>;
|
|
75
|
+
private lazyClient;
|
|
76
|
+
/**
|
|
77
|
+
* v4.0.0 — generic single-prompt text generation. Mirrors
|
|
78
|
+
* AnthropicLLMClient.generateText. Cache intentionally skipped;
|
|
79
|
+
* see that method for rationale.
|
|
80
|
+
*/
|
|
81
|
+
generateText(prompt: string): Promise<import("./types").GenerateTextResult>;
|
|
82
|
+
close(): Promise<void>;
|
|
83
|
+
}
|
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenAI LLM client — v3.11.0.
|
|
4
|
+
*
|
|
5
|
+
* Implements the same `LLMClient` interface as `AnthropicLLMClient`:
|
|
6
|
+
* single-step `generateBinding`, batched `generateBatchBindings`,
|
|
7
|
+
* cache hit accounting, budget tracking, governance sanitisation,
|
|
8
|
+
* step deadlines, provider timeouts.
|
|
9
|
+
*
|
|
10
|
+
* Differences from the Anthropic client are minimal and limited to
|
|
11
|
+
* the SDK call shape:
|
|
12
|
+
*
|
|
13
|
+
* Anthropic OpenAI
|
|
14
|
+
* ------------------------------- -----------------------------
|
|
15
|
+
* anthropic.messages.create({ openai.chat.completions.create({
|
|
16
|
+
* system: SYSTEM_PROMPT, messages: [
|
|
17
|
+
* messages: [ { role: 'system',
|
|
18
|
+
* { role: 'user', content } content: SYSTEM_PROMPT },
|
|
19
|
+
* ] { role: 'user', content }
|
|
20
|
+
* }) ]
|
|
21
|
+
* })
|
|
22
|
+
*
|
|
23
|
+
* resp.content[0].text resp.choices[0].message.content
|
|
24
|
+
* resp.usage.input_tokens resp.usage.prompt_tokens
|
|
25
|
+
* resp.usage.output_tokens resp.usage.completion_tokens
|
|
26
|
+
*
|
|
27
|
+
* The prompt machinery (`SYSTEM_PROMPT`, `buildUserPrompt`,
|
|
28
|
+
* `buildBatchUserPrompt`, `cacheKey`), the parser (`parseBindingJson`),
|
|
29
|
+
* the cache (`openSqliteCache`), and the governance client
|
|
30
|
+
* (`GovernanceClient`) are all shared with the Anthropic path —
|
|
31
|
+
* cache keys interoperate, so a scaffold cached under one provider
|
|
32
|
+
* hits the cache under another (cache keys include the model name,
|
|
33
|
+
* so cross-provider hits only fire when models match).
|
|
34
|
+
*
|
|
35
|
+
* Default model: `gpt-4o-mini`. Reasoning: bdd2pw's task is
|
|
36
|
+
* structured JSON output over a small set of regex-shaped
|
|
37
|
+
* deterministic patterns. Mini handles it reliably and runs ~17x
|
|
38
|
+
* cheaper than gpt-4o ($0.15 vs $2.50 per million input tokens).
|
|
39
|
+
* Override via `LLMClientOptions.model`.
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.OpenAILLMClient = void 0;
|
|
43
|
+
const cache_1 = require("./cache");
|
|
44
|
+
const governanceClient_1 = require("./governanceClient");
|
|
45
|
+
const prompt_1 = require("./prompt");
|
|
46
|
+
const anthropicClient_1 = require("./anthropicClient");
|
|
47
|
+
const DEFAULT_MODEL = "gpt-4o-mini";
|
|
48
|
+
const DEFAULT_MAX_CALLS = 50;
|
|
49
|
+
const DEFAULT_GOVERNANCE_URL = "http://localhost:4900";
|
|
50
|
+
const DEFAULT_STEP_TIMEOUT_MS = 60000;
|
|
51
|
+
const DEFAULT_PROVIDER_TIMEOUT_MS = 30000;
|
|
52
|
+
const DEFAULT_GOVERNANCE_TIMEOUT_MS = 15000;
|
|
53
|
+
class OpenAILLMClient {
|
|
54
|
+
constructor(opts, cachePathDefault) {
|
|
55
|
+
this.cache = null;
|
|
56
|
+
this.callsCounter = 0;
|
|
57
|
+
this.attemptsCounter = 0;
|
|
58
|
+
this.openai = null;
|
|
59
|
+
this.cachePersistent = null;
|
|
60
|
+
this.model = opts.model ?? DEFAULT_MODEL;
|
|
61
|
+
this.apiKey = opts.apiKey ?? process.env.OPENAI_API_KEY ?? "";
|
|
62
|
+
this.maxCalls = opts.maxCalls ?? DEFAULT_MAX_CALLS;
|
|
63
|
+
this.skipGovernance = opts.skipGovernance ?? false;
|
|
64
|
+
this.log = opts.log ?? (() => { });
|
|
65
|
+
this.providerTimeoutMs =
|
|
66
|
+
opts.providerTimeoutMs ?? DEFAULT_PROVIDER_TIMEOUT_MS;
|
|
67
|
+
this.governance = new governanceClient_1.GovernanceClient(opts.governanceUrl ?? DEFAULT_GOVERNANCE_URL, opts.governanceTimeoutMs ?? DEFAULT_GOVERNANCE_TIMEOUT_MS);
|
|
68
|
+
this.cachePath = opts.cachePath ?? cachePathDefault;
|
|
69
|
+
}
|
|
70
|
+
async ensureCache() {
|
|
71
|
+
if (!this.cache) {
|
|
72
|
+
const result = await (0, cache_1.openSqliteCache)(this.cachePath);
|
|
73
|
+
this.cache = result.cache;
|
|
74
|
+
this.cachePersistent = result.persistent;
|
|
75
|
+
this.cacheFallbackReason = result.fallbackReason;
|
|
76
|
+
if (!result.persistent && result.fallbackReason) {
|
|
77
|
+
this.log({ kind: "cache_fallback", reason: result.fallbackReason });
|
|
78
|
+
this.log({
|
|
79
|
+
kind: "error",
|
|
80
|
+
phase: "cache_load",
|
|
81
|
+
message: `Cache backend unavailable, falling back to in-memory for this run. Reason: ${result.fallbackReason}`,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return this.cache;
|
|
86
|
+
}
|
|
87
|
+
budgetExhausted() {
|
|
88
|
+
return this.attemptsCounter >= this.maxCalls;
|
|
89
|
+
}
|
|
90
|
+
callsMade() {
|
|
91
|
+
return this.callsCounter;
|
|
92
|
+
}
|
|
93
|
+
callsAttempted() {
|
|
94
|
+
return this.attemptsCounter;
|
|
95
|
+
}
|
|
96
|
+
cacheBackendPersistent() {
|
|
97
|
+
return this.cachePersistent;
|
|
98
|
+
}
|
|
99
|
+
cacheBackendFallbackReason() {
|
|
100
|
+
return this.cacheFallbackReason;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Single-step generation. Cache → governance → OpenAI → parse.
|
|
104
|
+
* Mirrors `AnthropicLLMClient.generateBinding` end-to-end.
|
|
105
|
+
*/
|
|
106
|
+
async generateBinding(input) {
|
|
107
|
+
const start = Date.now();
|
|
108
|
+
const key = (0, prompt_1.cacheKey)(input, this.model);
|
|
109
|
+
const cache = await this.ensureCache();
|
|
110
|
+
const hit = await cache.get(key);
|
|
111
|
+
if (hit) {
|
|
112
|
+
this.log({ kind: "cache_hit", key });
|
|
113
|
+
return {
|
|
114
|
+
binding: hit.binding,
|
|
115
|
+
fromCache: true,
|
|
116
|
+
model: hit.model,
|
|
117
|
+
latencyMs: Date.now() - start,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
this.log({ kind: "cache_miss", key });
|
|
121
|
+
if (this.budgetExhausted()) {
|
|
122
|
+
return {
|
|
123
|
+
error: `LLM budget exhausted (${this.callsCounter}/${this.maxCalls} calls). Increase via --llm-max-calls.`,
|
|
124
|
+
fromCache: false,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const userPrompt = (0, prompt_1.buildUserPrompt)(input);
|
|
128
|
+
let sanitisedUserPrompt = userPrompt;
|
|
129
|
+
if (!this.skipGovernance) {
|
|
130
|
+
try {
|
|
131
|
+
this.log({ kind: "sanitise_start", bytes: userPrompt.length });
|
|
132
|
+
const result = await this.governance.sanitiseCode(userPrompt);
|
|
133
|
+
sanitisedUserPrompt = result.sanitised;
|
|
134
|
+
this.log({
|
|
135
|
+
kind: "sanitise_done",
|
|
136
|
+
bytes: sanitisedUserPrompt.length,
|
|
137
|
+
findings: result.findings.length,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
const isUnreachable = err instanceof governanceClient_1.GovernanceUnreachableError;
|
|
142
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
143
|
+
this.log({ kind: "error", phase: "governance", message });
|
|
144
|
+
return {
|
|
145
|
+
error: isUnreachable
|
|
146
|
+
? `Governance sidecar unreachable; refusing to call LLM (fail-closed). ${message}`
|
|
147
|
+
: `Governance sanitise failed: ${message}`,
|
|
148
|
+
fromCache: false,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (!this.apiKey) {
|
|
153
|
+
return {
|
|
154
|
+
error: "OPENAI_API_KEY is not set; pass apiKey or set the env var.",
|
|
155
|
+
fromCache: false,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
const openai = await this.lazyClient();
|
|
159
|
+
if (!openai) {
|
|
160
|
+
return {
|
|
161
|
+
error: "openai SDK not installed. Run: npm install openai",
|
|
162
|
+
fromCache: false,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
let responseText = "";
|
|
166
|
+
let inputTokens = 0;
|
|
167
|
+
let outputTokens = 0;
|
|
168
|
+
this.attemptsCounter += 1;
|
|
169
|
+
try {
|
|
170
|
+
this.log({
|
|
171
|
+
kind: "provider_call_start",
|
|
172
|
+
model: this.model,
|
|
173
|
+
promptBytes: sanitisedUserPrompt.length,
|
|
174
|
+
});
|
|
175
|
+
const callStart = Date.now();
|
|
176
|
+
const resp = await openai.chat.completions.create({
|
|
177
|
+
model: this.model,
|
|
178
|
+
max_tokens: 1024,
|
|
179
|
+
temperature: 0,
|
|
180
|
+
messages: [
|
|
181
|
+
{ role: "system", content: prompt_1.SYSTEM_PROMPT },
|
|
182
|
+
{ role: "user", content: sanitisedUserPrompt },
|
|
183
|
+
],
|
|
184
|
+
}, { timeout: this.providerTimeoutMs });
|
|
185
|
+
this.callsCounter += 1;
|
|
186
|
+
const callLatency = Date.now() - callStart;
|
|
187
|
+
responseText = resp.choices?.[0]?.message?.content ?? "";
|
|
188
|
+
inputTokens = resp.usage?.prompt_tokens ?? 0;
|
|
189
|
+
outputTokens = resp.usage?.completion_tokens ?? 0;
|
|
190
|
+
this.log({
|
|
191
|
+
kind: "provider_call_done",
|
|
192
|
+
model: this.model,
|
|
193
|
+
latencyMs: callLatency,
|
|
194
|
+
inputTokens,
|
|
195
|
+
outputTokens,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
200
|
+
this.log({ kind: "error", phase: "openai", message });
|
|
201
|
+
return {
|
|
202
|
+
error: `OpenAI API call failed: ${message}`,
|
|
203
|
+
fromCache: false,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
const binding = (0, anthropicClient_1.parseBindingJson)(responseText, input);
|
|
207
|
+
if (!binding) {
|
|
208
|
+
this.log({
|
|
209
|
+
kind: "error",
|
|
210
|
+
phase: "parse",
|
|
211
|
+
message: `Could not parse JSON binding from LLM output: ${responseText.slice(0, 200)}`,
|
|
212
|
+
});
|
|
213
|
+
return {
|
|
214
|
+
error: `Could not parse JSON binding from LLM output (first 200 chars): ${responseText.slice(0, 200)}`,
|
|
215
|
+
fromCache: false,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
this.log({ kind: "binding_parsed", binding });
|
|
219
|
+
await cache.set(key, {
|
|
220
|
+
binding,
|
|
221
|
+
model: this.model,
|
|
222
|
+
createdAt: new Date().toISOString(),
|
|
223
|
+
});
|
|
224
|
+
return {
|
|
225
|
+
binding,
|
|
226
|
+
fromCache: false,
|
|
227
|
+
model: this.model,
|
|
228
|
+
latencyMs: Date.now() - start,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Batched generation — same per-step cache lookup + single batched
|
|
233
|
+
* prompt as `AnthropicLLMClient.generateBatchBindings`. The JSON array
|
|
234
|
+
* response is parsed slot by slot through `parseBindingJson`.
|
|
235
|
+
*/
|
|
236
|
+
async generateBatchBindings(inputs) {
|
|
237
|
+
if (inputs.length === 0)
|
|
238
|
+
return [];
|
|
239
|
+
const start = Date.now();
|
|
240
|
+
const cache = await this.ensureCache();
|
|
241
|
+
const results = new Array(inputs.length);
|
|
242
|
+
const missIndexes = [];
|
|
243
|
+
const missInputs = [];
|
|
244
|
+
const missKeys = [];
|
|
245
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
246
|
+
const key = (0, prompt_1.cacheKey)(inputs[i], this.model);
|
|
247
|
+
const hit = await cache.get(key);
|
|
248
|
+
if (hit) {
|
|
249
|
+
this.log({ kind: "cache_hit", key });
|
|
250
|
+
results[i] = {
|
|
251
|
+
binding: hit.binding,
|
|
252
|
+
fromCache: true,
|
|
253
|
+
model: hit.model,
|
|
254
|
+
latencyMs: Date.now() - start,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
this.log({ kind: "cache_miss", key });
|
|
259
|
+
missIndexes.push(i);
|
|
260
|
+
missInputs.push(inputs[i]);
|
|
261
|
+
missKeys.push(key);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (missInputs.length === 0) {
|
|
265
|
+
return results.map((r) => r);
|
|
266
|
+
}
|
|
267
|
+
if (this.budgetExhausted()) {
|
|
268
|
+
const err = {
|
|
269
|
+
error: `LLM budget exhausted (${this.callsCounter}/${this.maxCalls} calls). Increase via --llm-max-calls.`,
|
|
270
|
+
fromCache: false,
|
|
271
|
+
};
|
|
272
|
+
for (const i of missIndexes)
|
|
273
|
+
results[i] = err;
|
|
274
|
+
return results.map((r) => r);
|
|
275
|
+
}
|
|
276
|
+
const userPrompt = (0, prompt_1.buildBatchUserPrompt)(missInputs);
|
|
277
|
+
let sanitisedUserPrompt = userPrompt;
|
|
278
|
+
if (!this.skipGovernance) {
|
|
279
|
+
try {
|
|
280
|
+
this.log({ kind: "sanitise_start", bytes: userPrompt.length });
|
|
281
|
+
const sr = await this.governance.sanitiseCode(userPrompt);
|
|
282
|
+
sanitisedUserPrompt = sr.sanitised;
|
|
283
|
+
this.log({
|
|
284
|
+
kind: "sanitise_done",
|
|
285
|
+
bytes: sanitisedUserPrompt.length,
|
|
286
|
+
findings: sr.findings.length,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
const isUnreachable = err instanceof governanceClient_1.GovernanceUnreachableError;
|
|
291
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
292
|
+
this.log({ kind: "error", phase: "governance", message });
|
|
293
|
+
const errResult = {
|
|
294
|
+
error: isUnreachable
|
|
295
|
+
? `Governance sidecar unreachable; refusing to call LLM (fail-closed). ${message}`
|
|
296
|
+
: `Governance sanitise failed: ${message}`,
|
|
297
|
+
fromCache: false,
|
|
298
|
+
};
|
|
299
|
+
for (const i of missIndexes)
|
|
300
|
+
results[i] = errResult;
|
|
301
|
+
return results.map((r) => r);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (!this.apiKey) {
|
|
305
|
+
const err = {
|
|
306
|
+
error: "OPENAI_API_KEY is not set; pass apiKey or set the env var.",
|
|
307
|
+
fromCache: false,
|
|
308
|
+
};
|
|
309
|
+
for (const i of missIndexes)
|
|
310
|
+
results[i] = err;
|
|
311
|
+
return results.map((r) => r);
|
|
312
|
+
}
|
|
313
|
+
const openai = await this.lazyClient();
|
|
314
|
+
if (!openai) {
|
|
315
|
+
const err = {
|
|
316
|
+
error: "openai SDK not installed. Run: npm install openai",
|
|
317
|
+
fromCache: false,
|
|
318
|
+
};
|
|
319
|
+
for (const i of missIndexes)
|
|
320
|
+
results[i] = err;
|
|
321
|
+
return results.map((r) => r);
|
|
322
|
+
}
|
|
323
|
+
let responseText = "";
|
|
324
|
+
this.attemptsCounter += 1;
|
|
325
|
+
try {
|
|
326
|
+
this.log({
|
|
327
|
+
kind: "provider_call_start",
|
|
328
|
+
model: this.model,
|
|
329
|
+
promptBytes: sanitisedUserPrompt.length,
|
|
330
|
+
});
|
|
331
|
+
const callStart = Date.now();
|
|
332
|
+
const maxTokens = Math.min(8192, 1024 + missInputs.length * 512);
|
|
333
|
+
const resp = await openai.chat.completions.create({
|
|
334
|
+
model: this.model,
|
|
335
|
+
max_tokens: maxTokens,
|
|
336
|
+
temperature: 0,
|
|
337
|
+
messages: [
|
|
338
|
+
{ role: "system", content: prompt_1.SYSTEM_PROMPT },
|
|
339
|
+
{ role: "user", content: sanitisedUserPrompt },
|
|
340
|
+
],
|
|
341
|
+
}, { timeout: this.providerTimeoutMs });
|
|
342
|
+
this.callsCounter += 1;
|
|
343
|
+
const callLatency = Date.now() - callStart;
|
|
344
|
+
responseText = resp.choices?.[0]?.message?.content ?? "";
|
|
345
|
+
this.log({
|
|
346
|
+
kind: "provider_call_done",
|
|
347
|
+
model: this.model,
|
|
348
|
+
latencyMs: callLatency,
|
|
349
|
+
inputTokens: resp.usage?.prompt_tokens ?? 0,
|
|
350
|
+
outputTokens: resp.usage?.completion_tokens ?? 0,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
catch (err) {
|
|
354
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
355
|
+
this.log({ kind: "error", phase: "openai", message });
|
|
356
|
+
const errResult = {
|
|
357
|
+
error: `OpenAI API call failed: ${message}`,
|
|
358
|
+
fromCache: false,
|
|
359
|
+
};
|
|
360
|
+
for (const i of missIndexes)
|
|
361
|
+
results[i] = errResult;
|
|
362
|
+
return results.map((r) => r);
|
|
363
|
+
}
|
|
364
|
+
let parsedArray;
|
|
365
|
+
try {
|
|
366
|
+
let body = responseText.trim();
|
|
367
|
+
const fence = body.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/);
|
|
368
|
+
if (fence)
|
|
369
|
+
body = fence[1].trim();
|
|
370
|
+
const parsed = JSON.parse(body);
|
|
371
|
+
if (!Array.isArray(parsed))
|
|
372
|
+
throw new Error("expected a JSON array");
|
|
373
|
+
parsedArray = parsed;
|
|
374
|
+
}
|
|
375
|
+
catch (err) {
|
|
376
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
377
|
+
this.log({ kind: "error", phase: "parse", message });
|
|
378
|
+
const errResult = {
|
|
379
|
+
error: `Could not parse JSON array from batch LLM output (first 200 chars): ${responseText.slice(0, 200)}`,
|
|
380
|
+
fromCache: false,
|
|
381
|
+
};
|
|
382
|
+
for (const i of missIndexes)
|
|
383
|
+
results[i] = errResult;
|
|
384
|
+
return results.map((r) => r);
|
|
385
|
+
}
|
|
386
|
+
for (let j = 0; j < missInputs.length; j++) {
|
|
387
|
+
const slotInput = missInputs[j];
|
|
388
|
+
const slotKey = missKeys[j];
|
|
389
|
+
const slotRaw = parsedArray[j];
|
|
390
|
+
const originalIdx = missIndexes[j];
|
|
391
|
+
if (slotRaw === undefined) {
|
|
392
|
+
results[originalIdx] = {
|
|
393
|
+
error: `Batch response missing entry for step ${j}: "${slotInput.step.text}"`,
|
|
394
|
+
fromCache: false,
|
|
395
|
+
};
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
const slotJson = JSON.stringify(slotRaw);
|
|
399
|
+
const binding = (0, anthropicClient_1.parseBindingJson)(slotJson, slotInput);
|
|
400
|
+
if (!binding) {
|
|
401
|
+
results[originalIdx] = {
|
|
402
|
+
error: `Could not parse binding for step ${j} ("${slotInput.step.text}"); slot was: ${slotJson.slice(0, 200)}`,
|
|
403
|
+
fromCache: false,
|
|
404
|
+
};
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
this.log({ kind: "binding_parsed", binding });
|
|
408
|
+
await cache.set(slotKey, {
|
|
409
|
+
binding,
|
|
410
|
+
model: this.model,
|
|
411
|
+
createdAt: new Date().toISOString(),
|
|
412
|
+
});
|
|
413
|
+
results[originalIdx] = {
|
|
414
|
+
binding,
|
|
415
|
+
fromCache: false,
|
|
416
|
+
model: this.model,
|
|
417
|
+
latencyMs: Date.now() - start,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
return results.map((r) => r);
|
|
421
|
+
}
|
|
422
|
+
async lazyClient() {
|
|
423
|
+
if (this.openai)
|
|
424
|
+
return this.openai;
|
|
425
|
+
try {
|
|
426
|
+
// openai is in optionalDependencies. require() defensively so a
|
|
427
|
+
// teammate without the SDK installed gets a clean error instead
|
|
428
|
+
// of a module-load crash.
|
|
429
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
430
|
+
const mod = require("openai");
|
|
431
|
+
const OpenAI = mod.OpenAI ?? mod.default ?? mod;
|
|
432
|
+
this.openai = new OpenAI({ apiKey: this.apiKey });
|
|
433
|
+
return this.openai;
|
|
434
|
+
}
|
|
435
|
+
catch {
|
|
436
|
+
return null;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* v4.0.0 — generic single-prompt text generation. Mirrors
|
|
441
|
+
* AnthropicLLMClient.generateText. Cache intentionally skipped;
|
|
442
|
+
* see that method for rationale.
|
|
443
|
+
*/
|
|
444
|
+
async generateText(prompt) {
|
|
445
|
+
const start = Date.now();
|
|
446
|
+
if (this.budgetExhausted()) {
|
|
447
|
+
return {
|
|
448
|
+
error: `LLM budget exhausted (${this.callsCounter}/${this.maxCalls} calls). Increase via --llm-max-calls.`,
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
let sanitisedPrompt = prompt;
|
|
452
|
+
if (!this.skipGovernance) {
|
|
453
|
+
try {
|
|
454
|
+
this.log({ kind: "sanitise_start", bytes: prompt.length });
|
|
455
|
+
const result = await this.governance.sanitiseCode(prompt);
|
|
456
|
+
sanitisedPrompt = result.sanitised;
|
|
457
|
+
this.log({
|
|
458
|
+
kind: "sanitise_done",
|
|
459
|
+
bytes: sanitisedPrompt.length,
|
|
460
|
+
findings: result.findings.length,
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
catch (err) {
|
|
464
|
+
const isUnreachable = err instanceof governanceClient_1.GovernanceUnreachableError;
|
|
465
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
466
|
+
this.log({ kind: "error", phase: "governance", message });
|
|
467
|
+
return {
|
|
468
|
+
error: isUnreachable
|
|
469
|
+
? `Governance sidecar unreachable; refusing to call LLM (fail-closed). ${message}`
|
|
470
|
+
: `Governance sanitise failed: ${message}`,
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
if (!this.apiKey) {
|
|
475
|
+
return { error: "OPENAI_API_KEY is not set; pass apiKey or set the env var." };
|
|
476
|
+
}
|
|
477
|
+
const openai = await this.lazyClient();
|
|
478
|
+
if (!openai) {
|
|
479
|
+
return { error: "openai SDK not installed. Run: npm install openai" };
|
|
480
|
+
}
|
|
481
|
+
this.attemptsCounter += 1;
|
|
482
|
+
try {
|
|
483
|
+
this.log({
|
|
484
|
+
kind: "provider_call_start",
|
|
485
|
+
model: this.model,
|
|
486
|
+
promptBytes: sanitisedPrompt.length,
|
|
487
|
+
});
|
|
488
|
+
const callStart = Date.now();
|
|
489
|
+
const resp = await openai.chat.completions.create({
|
|
490
|
+
model: this.model,
|
|
491
|
+
max_tokens: 2048,
|
|
492
|
+
temperature: 0,
|
|
493
|
+
messages: [{ role: "user", content: sanitisedPrompt }],
|
|
494
|
+
}, { timeout: this.providerTimeoutMs });
|
|
495
|
+
this.callsCounter += 1;
|
|
496
|
+
const callLatency = Date.now() - callStart;
|
|
497
|
+
const text = resp.choices?.[0]?.message?.content ?? "";
|
|
498
|
+
const inputTokens = resp.usage?.prompt_tokens ?? 0;
|
|
499
|
+
const outputTokens = resp.usage?.completion_tokens ?? 0;
|
|
500
|
+
this.log({
|
|
501
|
+
kind: "provider_call_done",
|
|
502
|
+
model: this.model,
|
|
503
|
+
latencyMs: callLatency,
|
|
504
|
+
inputTokens,
|
|
505
|
+
outputTokens,
|
|
506
|
+
});
|
|
507
|
+
return {
|
|
508
|
+
text,
|
|
509
|
+
model: this.model,
|
|
510
|
+
latencyMs: Date.now() - start,
|
|
511
|
+
inputTokens,
|
|
512
|
+
outputTokens,
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
catch (err) {
|
|
516
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
517
|
+
this.log({ kind: "error", phase: "openai", message });
|
|
518
|
+
return { error: `OpenAI API call failed: ${message}` };
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
async close() {
|
|
522
|
+
if (this.cache) {
|
|
523
|
+
await this.cache.close().catch(() => undefined);
|
|
524
|
+
this.cache = null;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
exports.OpenAILLMClient = OpenAILLMClient;
|
|
529
|
+
//# sourceMappingURL=openaiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openaiClient.js","sourceRoot":"","sources":["../../src/llm/openaiClient.ts"],"names":[],"mappings":"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"}
|
package/dist/llm/telemetry.js
CHANGED
|
@@ -51,6 +51,20 @@ exports.DEFAULT_PRICING = {
|
|
|
51
51
|
inputUsdPerMillion: 0.8,
|
|
52
52
|
outputUsdPerMillion: 4,
|
|
53
53
|
},
|
|
54
|
+
// OpenAI — v3.11.0 provider parity. Q4 2025 published pricing.
|
|
55
|
+
"gpt-4o": { inputUsdPerMillion: 2.5, outputUsdPerMillion: 10 },
|
|
56
|
+
"gpt-4o-mini": { inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.6 },
|
|
57
|
+
"gpt-4-turbo": { inputUsdPerMillion: 10, outputUsdPerMillion: 30 },
|
|
58
|
+
o1: { inputUsdPerMillion: 15, outputUsdPerMillion: 60 },
|
|
59
|
+
"o1-mini": { inputUsdPerMillion: 3, outputUsdPerMillion: 12 },
|
|
60
|
+
"o1-preview": { inputUsdPerMillion: 15, outputUsdPerMillion: 60 },
|
|
61
|
+
// Google Gemini — v3.12.0 provider parity. Q4 2025 published pricing.
|
|
62
|
+
// Flash is the price/perf sweet spot for structured-JSON tasks.
|
|
63
|
+
"gemini-2.5-flash": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4 },
|
|
64
|
+
"gemini-2.5-pro": { inputUsdPerMillion: 1.25, outputUsdPerMillion: 5 },
|
|
65
|
+
"gemini-2.0-flash": { inputUsdPerMillion: 0.1, outputUsdPerMillion: 0.4 },
|
|
66
|
+
"gemini-1.5-flash": { inputUsdPerMillion: 0.075, outputUsdPerMillion: 0.3 },
|
|
67
|
+
"gemini-1.5-pro": { inputUsdPerMillion: 1.25, outputUsdPerMillion: 5 },
|
|
54
68
|
};
|
|
55
69
|
/**
|
|
56
70
|
* Telemetry collector. One instance per scaffold call. Subscribe via
|