@adminiumjs/llm 0.1.0-rc.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.
- package/LICENSE +661 -0
- package/dist/apply/diff.d.ts +79 -0
- package/dist/apply/diff.d.ts.map +1 -0
- package/dist/apply/diff.js +459 -0
- package/dist/apply/diff.js.map +1 -0
- package/dist/apply/index.d.ts +6 -0
- package/dist/apply/index.d.ts.map +1 -0
- package/dist/apply/index.js +6 -0
- package/dist/apply/index.js.map +1 -0
- package/dist/apply/normalize.d.ts +55 -0
- package/dist/apply/normalize.d.ts.map +1 -0
- package/dist/apply/normalize.js +232 -0
- package/dist/apply/normalize.js.map +1 -0
- package/dist/apply/plan.d.ts +206 -0
- package/dist/apply/plan.d.ts.map +1 -0
- package/dist/apply/plan.js +422 -0
- package/dist/apply/plan.js.map +1 -0
- package/dist/apply/suggestion-id.d.ts +103 -0
- package/dist/apply/suggestion-id.d.ts.map +1 -0
- package/dist/apply/suggestion-id.js +121 -0
- package/dist/apply/suggestion-id.js.map +1 -0
- package/dist/crypto.d.ts +48 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +35 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/prompt/builder.d.ts +27 -0
- package/dist/prompt/builder.d.ts.map +1 -0
- package/dist/prompt/builder.js +263 -0
- package/dist/prompt/builder.js.map +1 -0
- package/dist/prompt/chunker.d.ts +89 -0
- package/dist/prompt/chunker.d.ts.map +1 -0
- package/dist/prompt/chunker.js +383 -0
- package/dist/prompt/chunker.js.map +1 -0
- package/dist/prompt/index.d.ts +14 -0
- package/dist/prompt/index.d.ts.map +1 -0
- package/dist/prompt/index.js +14 -0
- package/dist/prompt/index.js.map +1 -0
- package/dist/prompt/serializer.d.ts +138 -0
- package/dist/prompt/serializer.d.ts.map +1 -0
- package/dist/prompt/serializer.js +178 -0
- package/dist/prompt/serializer.js.map +1 -0
- package/dist/prompt/templates/v1.d.ts +41 -0
- package/dist/prompt/templates/v1.d.ts.map +1 -0
- package/dist/prompt/templates/v1.js +312 -0
- package/dist/prompt/templates/v1.js.map +1 -0
- package/dist/prompt/token-estimate.d.ts +16 -0
- package/dist/prompt/token-estimate.d.ts.map +1 -0
- package/dist/prompt/token-estimate.js +20 -0
- package/dist/prompt/token-estimate.js.map +1 -0
- package/dist/prompt/types.d.ts +134 -0
- package/dist/prompt/types.d.ts.map +1 -0
- package/dist/prompt/types.js +44 -0
- package/dist/prompt/types.js.map +1 -0
- package/dist/providers/anthropic.d.ts +3 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +65 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/factory.d.ts +3 -0
- package/dist/providers/factory.d.ts.map +1 -0
- package/dist/providers/factory.js +37 -0
- package/dist/providers/factory.js.map +1 -0
- package/dist/providers/http.d.ts +56 -0
- package/dist/providers/http.d.ts.map +1 -0
- package/dist/providers/http.js +148 -0
- package/dist/providers/http.js.map +1 -0
- package/dist/providers/index.d.ts +15 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +15 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/model-catalog.d.ts +21 -0
- package/dist/providers/model-catalog.d.ts.map +1 -0
- package/dist/providers/model-catalog.js +121 -0
- package/dist/providers/model-catalog.js.map +1 -0
- package/dist/providers/ollama.d.ts +3 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +55 -0
- package/dist/providers/ollama.js.map +1 -0
- package/dist/providers/openai-compatible.d.ts +3 -0
- package/dist/providers/openai-compatible.d.ts.map +1 -0
- package/dist/providers/openai-compatible.js +50 -0
- package/dist/providers/openai-compatible.js.map +1 -0
- package/dist/providers/openai.d.ts +18 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +68 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/types.d.ts +112 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +55 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/response/errors.d.ts +60 -0
- package/dist/response/errors.d.ts.map +1 -0
- package/dist/response/errors.js +101 -0
- package/dist/response/errors.js.map +1 -0
- package/dist/response/extract.d.ts +38 -0
- package/dist/response/extract.d.ts.map +1 -0
- package/dist/response/extract.js +77 -0
- package/dist/response/extract.js.map +1 -0
- package/dist/response/index.d.ts +8 -0
- package/dist/response/index.d.ts.map +1 -0
- package/dist/response/index.js +8 -0
- package/dist/response/index.js.map +1 -0
- package/dist/response/merge.d.ts +53 -0
- package/dist/response/merge.d.ts.map +1 -0
- package/dist/response/merge.js +348 -0
- package/dist/response/merge.js.map +1 -0
- package/dist/response/referential.d.ts +113 -0
- package/dist/response/referential.d.ts.map +1 -0
- package/dist/response/referential.js +556 -0
- package/dist/response/referential.js.map +1 -0
- package/dist/response/schema.d.ts +506 -0
- package/dist/response/schema.d.ts.map +1 -0
- package/dist/response/schema.js +191 -0
- package/dist/response/schema.js.map +1 -0
- package/dist/response/validate.d.ts +29 -0
- package/dist/response/validate.d.ts.map +1 -0
- package/dist/response/validate.js +167 -0
- package/dist/response/validate.js.map +1 -0
- package/dist/types.d.ts +95 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +49 -0
- package/dist/types.js.map +1 -0
- package/package.json +30 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model catalog (06-llm-assist.md §3.1 matrix): static fallback lists plus the
|
|
3
|
+
* live `listModels()` fetchers each client delegates to. Fetchers hit the
|
|
4
|
+
* provider's model-list endpoint and fall back per the matrix:
|
|
5
|
+
* - anthropic / openai → live, else the static list below
|
|
6
|
+
* - openai-compatible → live, tolerate 404 → `[]` (user free-texts the model)
|
|
7
|
+
* - ollama → live only (local models vary; no static fallback)
|
|
8
|
+
*
|
|
9
|
+
* The static ids are a conservative snapshot for offline/first-run UX; the live
|
|
10
|
+
* fetch is always attempted first, so a stale entry here never blocks a real model.
|
|
11
|
+
*/
|
|
12
|
+
import { requestJson } from './http.js';
|
|
13
|
+
import { ProviderError } from './types.js';
|
|
14
|
+
// ─── Static fallback lists ───────────────────────────────────────────────────
|
|
15
|
+
export const ANTHROPIC_STATIC_MODELS = [
|
|
16
|
+
{ id: 'claude-opus-4-8', label: 'Claude Opus 4.8' },
|
|
17
|
+
{ id: 'claude-opus-4-7', label: 'Claude Opus 4.7' },
|
|
18
|
+
{ id: 'claude-sonnet-5', label: 'Claude Sonnet 5' },
|
|
19
|
+
{ id: 'claude-sonnet-4-6', label: 'Claude Sonnet 4.6' },
|
|
20
|
+
{ id: 'claude-haiku-4-5', label: 'Claude Haiku 4.5' },
|
|
21
|
+
];
|
|
22
|
+
export const OPENAI_STATIC_MODELS = [
|
|
23
|
+
{ id: 'gpt-4o', label: 'GPT-4o' },
|
|
24
|
+
{ id: 'gpt-4o-mini', label: 'GPT-4o mini' },
|
|
25
|
+
{ id: 'gpt-4.1', label: 'GPT-4.1' },
|
|
26
|
+
{ id: 'gpt-4.1-mini', label: 'GPT-4.1 mini' },
|
|
27
|
+
];
|
|
28
|
+
const ANTHROPIC_VERSION = '2023-06-01';
|
|
29
|
+
/** `GET {baseUrl}/v1/models`; on any failure returns the static Anthropic list. */
|
|
30
|
+
export async function listAnthropicModels(opts) {
|
|
31
|
+
const apiKey = opts.apiKey ?? '';
|
|
32
|
+
try {
|
|
33
|
+
const json = await requestJson({
|
|
34
|
+
provider: 'anthropic',
|
|
35
|
+
url: `${opts.baseUrl}/v1/models`,
|
|
36
|
+
headers: { 'x-api-key': apiKey, 'anthropic-version': ANTHROPIC_VERSION },
|
|
37
|
+
apiKey,
|
|
38
|
+
...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),
|
|
39
|
+
});
|
|
40
|
+
const models = (json.data ?? [])
|
|
41
|
+
.filter((m) => typeof m.id === 'string')
|
|
42
|
+
.map((m) => ({ id: m.id, label: m.display_name ?? m.id }));
|
|
43
|
+
return models.length > 0 ? models : [...ANTHROPIC_STATIC_MODELS];
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return [...ANTHROPIC_STATIC_MODELS];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* True for ids that name a chat/completions-capable OpenAI model usable for
|
|
51
|
+
* enrichment. The o-series reasoning models (`o1`/`o3`/`o4-*`) are deliberately
|
|
52
|
+
* EXCLUDED: the Chat Completions contract this client speaks (`max_tokens` +
|
|
53
|
+
* `temperature: 0`, both fixed by §3.1) is rejected by those models — they
|
|
54
|
+
* require `max_completion_tokens` and forbid `temperature ≠ 1`, so every
|
|
55
|
+
* enrichment call on them 400s. Since temperature 0 is a non-negotiable
|
|
56
|
+
* determinism mandate (`assertEnrichmentTemperature`), offering them would be a
|
|
57
|
+
* guaranteed dead end; we filter them out of the catalog entirely.
|
|
58
|
+
*/
|
|
59
|
+
function isOpenAiChatModel(id) {
|
|
60
|
+
return /gpt|chatgpt/i.test(id);
|
|
61
|
+
}
|
|
62
|
+
/** `GET {baseUrl}/models` filtered to chat models; on any failure returns the static OpenAI list. */
|
|
63
|
+
export async function listOpenAiModels(opts) {
|
|
64
|
+
const apiKey = opts.apiKey ?? '';
|
|
65
|
+
try {
|
|
66
|
+
const json = await requestJson({
|
|
67
|
+
provider: 'openai',
|
|
68
|
+
url: `${opts.baseUrl}/models`,
|
|
69
|
+
headers: { authorization: `Bearer ${apiKey}` },
|
|
70
|
+
apiKey,
|
|
71
|
+
...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),
|
|
72
|
+
});
|
|
73
|
+
const models = (json.data ?? [])
|
|
74
|
+
.filter((m) => typeof m.id === 'string' && isOpenAiChatModel(m.id))
|
|
75
|
+
.map((m) => ({ id: m.id, label: m.id }));
|
|
76
|
+
return models.length > 0 ? models : [...OPENAI_STATIC_MODELS];
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return [...OPENAI_STATIC_MODELS];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* `GET {baseUrl}/models` for an OpenAI-compatible endpoint. A 404 (endpoint not
|
|
84
|
+
* implemented) is tolerated → `[]`, signalling the UI to offer a free-text model
|
|
85
|
+
* field. Other failures (auth, network, 5xx) propagate as `ProviderError`.
|
|
86
|
+
*/
|
|
87
|
+
export async function listOpenAiCompatibleModels(opts) {
|
|
88
|
+
const apiKey = opts.apiKey;
|
|
89
|
+
const headers = {};
|
|
90
|
+
if (apiKey !== undefined && apiKey.trim() !== '')
|
|
91
|
+
headers['authorization'] = `Bearer ${apiKey}`;
|
|
92
|
+
try {
|
|
93
|
+
const json = await requestJson({
|
|
94
|
+
provider: 'openai-compatible',
|
|
95
|
+
url: `${opts.baseUrl}/models`,
|
|
96
|
+
headers,
|
|
97
|
+
...(apiKey !== undefined ? { apiKey } : {}),
|
|
98
|
+
...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),
|
|
99
|
+
});
|
|
100
|
+
return (json.data ?? [])
|
|
101
|
+
.filter((m) => typeof m.id === 'string')
|
|
102
|
+
.map((m) => ({ id: m.id, label: m.id }));
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
if (err instanceof ProviderError && err.code === 'not_found')
|
|
106
|
+
return [];
|
|
107
|
+
throw err;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** `GET {baseUrl}/api/tags`; no static fallback — propagates `ProviderError` on failure. */
|
|
111
|
+
export async function listOllamaModels(opts) {
|
|
112
|
+
const json = await requestJson({
|
|
113
|
+
provider: 'ollama',
|
|
114
|
+
url: `${opts.baseUrl}/api/tags`,
|
|
115
|
+
...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),
|
|
116
|
+
});
|
|
117
|
+
return (json.models ?? [])
|
|
118
|
+
.filter((m) => typeof m.name === 'string')
|
|
119
|
+
.map((m) => ({ id: m.name, label: m.name }));
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=model-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-catalog.js","sourceRoot":"","sources":["../../src/providers/model-catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/providers/ollama.ts"],"names":[],"mappings":"AAQA,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAUpB,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAgDzE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local Ollama client (06-llm-assist.md §3.1): no auth, `baseUrl` defaults to
|
|
3
|
+
* `http://localhost:11434`. POST `/api/chat` (non-streaming); `GET /api/tags`
|
|
4
|
+
* for the model list. The only direct provider promoted in Electron offline mode.
|
|
5
|
+
* temperature (fixed 0) goes in `options` per the Ollama chat API.
|
|
6
|
+
*/
|
|
7
|
+
import { pingComplete, requestJson, toCompleteResult } from './http.js';
|
|
8
|
+
import { listOllamaModels } from './model-catalog.js';
|
|
9
|
+
import { assertEnrichmentTemperature, ProviderError, requireModel, stripTrailingSlash, } from './types.js';
|
|
10
|
+
const DEFAULT_BASE_URL = 'http://localhost:11434';
|
|
11
|
+
export function createOllamaClient(config) {
|
|
12
|
+
const baseUrl = config.baseUrl ? stripTrailingSlash(config.baseUrl) : DEFAULT_BASE_URL;
|
|
13
|
+
const timeoutMs = config.timeoutMs;
|
|
14
|
+
const client = {
|
|
15
|
+
id: 'ollama',
|
|
16
|
+
async listModels() {
|
|
17
|
+
return listOllamaModels({ baseUrl, ...(timeoutMs !== undefined ? { timeoutMs } : {}) });
|
|
18
|
+
},
|
|
19
|
+
async complete(req) {
|
|
20
|
+
assertEnrichmentTemperature(req.temperature, 'ollama');
|
|
21
|
+
const messages = [];
|
|
22
|
+
if (req.system.length > 0)
|
|
23
|
+
messages.push({ role: 'system', content: req.system });
|
|
24
|
+
for (const m of req.messages)
|
|
25
|
+
messages.push({ role: m.role, content: m.content });
|
|
26
|
+
const json = await requestJson({
|
|
27
|
+
provider: 'ollama',
|
|
28
|
+
method: 'POST',
|
|
29
|
+
url: `${baseUrl}/api/chat`,
|
|
30
|
+
headers: { 'content-type': 'application/json' },
|
|
31
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
32
|
+
body: {
|
|
33
|
+
model: req.model,
|
|
34
|
+
messages,
|
|
35
|
+
stream: false,
|
|
36
|
+
options: { temperature: req.temperature, num_predict: req.maxTokens },
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
const text = json.message?.content;
|
|
40
|
+
if (typeof text !== 'string' || text.length === 0) {
|
|
41
|
+
throw new ProviderError({
|
|
42
|
+
provider: 'ollama',
|
|
43
|
+
code: 'bad_response',
|
|
44
|
+
message: 'ollama: response contained no message content',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return toCompleteResult(text, json.prompt_eval_count, json.eval_count);
|
|
48
|
+
},
|
|
49
|
+
async test() {
|
|
50
|
+
return pingComplete(client, requireModel(config, 'ollama'));
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
return client;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=ollama.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/providers/ollama.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,2BAA2B,EAC3B,aAAa,EACb,YAAY,EACZ,kBAAkB,GAGnB,MAAM,YAAY,CAAC;AAEpB,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;AAQlD,MAAM,UAAU,kBAAkB,CAAC,MAAsB;IACvD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC;IACvF,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IAEnC,MAAM,MAAM,GAAmB;QAC7B,EAAE,EAAE,QAAQ;QAEZ,KAAK,CAAC,UAAU;YACd,OAAO,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,GAAG;YAChB,2BAA2B,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YACvD,MAAM,QAAQ,GAAwC,EAAE,CAAC;YACzD,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YAClF,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,QAAQ;gBAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAElF,MAAM,IAAI,GAAG,MAAM,WAAW,CAAqB;gBACjD,QAAQ,EAAE,QAAQ;gBAClB,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,GAAG,OAAO,WAAW;gBAC1B,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjD,IAAI,EAAE;oBACJ,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,QAAQ;oBACR,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,CAAC,SAAS,EAAE;iBACtE;aACF,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;YACnC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClD,MAAM,IAAI,aAAa,CAAC;oBACtB,QAAQ,EAAE,QAAQ;oBAClB,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,+CAA+C;iBACzD,CAAC,CAAC;YACL,CAAC;YACD,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACzE,CAAC;QAED,KAAK,CAAC,IAAI;YACR,OAAO,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC9D,CAAC;KACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-compatible.d.ts","sourceRoot":"","sources":["../../src/providers/openai-compatible.ts"],"names":[],"mappings":"AAaA,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CA2CnF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-compatible client (06-llm-assist.md §3.1): same Chat Completions wire
|
|
3
|
+
* format as OpenAI against a user-supplied `baseUrl` (Groq, Together, vLLM, LM
|
|
4
|
+
* Studio, …). The Bearer key is optional; the model-list endpoint may be absent,
|
|
5
|
+
* so a 404 is tolerated → empty list → free-text model field in the UI.
|
|
6
|
+
*/
|
|
7
|
+
import { buildOpenAiChatBody, parseOpenAiChatResponse, } from './openai.js';
|
|
8
|
+
import { pingComplete, requestJson } from './http.js';
|
|
9
|
+
import { listOpenAiCompatibleModels } from './model-catalog.js';
|
|
10
|
+
import { assertEnrichmentTemperature, requireBaseUrl, requireModel, } from './types.js';
|
|
11
|
+
export function createOpenAiCompatibleClient(config) {
|
|
12
|
+
const baseUrl = requireBaseUrl(config, 'openai-compatible');
|
|
13
|
+
const apiKey = config.apiKey; // optional
|
|
14
|
+
const hasKey = apiKey !== undefined && apiKey.trim() !== '';
|
|
15
|
+
const timeoutMs = config.timeoutMs;
|
|
16
|
+
const headers = () => {
|
|
17
|
+
const h = { 'content-type': 'application/json' };
|
|
18
|
+
if (hasKey)
|
|
19
|
+
h['authorization'] = `Bearer ${apiKey ?? ''}`;
|
|
20
|
+
return h;
|
|
21
|
+
};
|
|
22
|
+
const client = {
|
|
23
|
+
id: 'openai-compatible',
|
|
24
|
+
async listModels() {
|
|
25
|
+
return listOpenAiCompatibleModels({
|
|
26
|
+
baseUrl,
|
|
27
|
+
...(hasKey ? { apiKey } : {}),
|
|
28
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
async complete(req) {
|
|
32
|
+
assertEnrichmentTemperature(req.temperature, 'openai-compatible');
|
|
33
|
+
const json = await requestJson({
|
|
34
|
+
provider: 'openai-compatible',
|
|
35
|
+
method: 'POST',
|
|
36
|
+
url: `${baseUrl}/chat/completions`,
|
|
37
|
+
headers: headers(),
|
|
38
|
+
...(hasKey ? { apiKey } : {}),
|
|
39
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
40
|
+
body: buildOpenAiChatBody(req),
|
|
41
|
+
});
|
|
42
|
+
return parseOpenAiChatResponse(json, 'openai-compatible');
|
|
43
|
+
},
|
|
44
|
+
async test() {
|
|
45
|
+
return pingComplete(client, requireModel(config, 'openai-compatible'));
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
return client;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=openai-compatible.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-compatible.js","sourceRoot":"","sources":["../../src/providers/openai-compatible.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,mBAAmB,EACnB,uBAAuB,GAExB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EACL,2BAA2B,EAC3B,cAAc,EACd,YAAY,GAGb,MAAM,YAAY,CAAC;AAEpB,MAAM,UAAU,4BAA4B,CAAC,MAAsB;IACjE,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW;IACzC,MAAM,MAAM,GAAG,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;IAC5D,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IAEnC,MAAM,OAAO,GAAG,GAA2B,EAAE;QAC3C,MAAM,CAAC,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QACzE,IAAI,MAAM;YAAE,CAAC,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,IAAI,EAAE,EAAE,CAAC;QAC1D,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;IAEF,MAAM,MAAM,GAAmB;QAC7B,EAAE,EAAE,mBAAmB;QAEvB,KAAK,CAAC,UAAU;YACd,OAAO,0BAA0B,CAAC;gBAChC,OAAO;gBACP,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7B,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAClD,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,GAAG;YAChB,2BAA2B,CAAC,GAAG,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;YAClE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAqB;gBACjD,QAAQ,EAAE,mBAAmB;gBAC7B,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,GAAG,OAAO,mBAAmB;gBAClC,OAAO,EAAE,OAAO,EAAE;gBAClB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7B,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjD,IAAI,EAAE,mBAAmB,CAAC,GAAG,CAAC;aAC/B,CAAC,CAAC;YACH,OAAO,uBAAuB,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;QAC5D,CAAC;QAED,KAAK,CAAC,IAAI;YACR,OAAO,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;QACzE,CAAC;KACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type CompleteRequest, type CompleteResult, type ProviderClient, type ProviderConfig, type ProviderId } from './types.js';
|
|
2
|
+
export interface OpenAiChatResponse {
|
|
3
|
+
choices?: {
|
|
4
|
+
message?: {
|
|
5
|
+
content?: string | null;
|
|
6
|
+
};
|
|
7
|
+
}[];
|
|
8
|
+
usage?: {
|
|
9
|
+
prompt_tokens?: number;
|
|
10
|
+
completion_tokens?: number;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/** Builds the Chat Completions request body, prepending the system message when present. */
|
|
14
|
+
export declare function buildOpenAiChatBody(req: CompleteRequest): Record<string, unknown>;
|
|
15
|
+
/** Extracts assistant text + token usage from a Chat Completions response. */
|
|
16
|
+
export declare function parseOpenAiChatResponse(json: OpenAiChatResponse, provider: ProviderId): CompleteResult;
|
|
17
|
+
export declare function createOpenAiClient(config: ProviderConfig): ProviderClient;
|
|
18
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAOA,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,CAAA;KAAE,EAAE,CAAC;IACtD,KAAK,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAChE;AAED,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUjF;AAED,8EAA8E;AAC9E,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,UAAU,GAAG,cAAc,CAUtG;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAqCzE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Chat Completions client (06-llm-assist.md §3.1). Auth: `Authorization:
|
|
3
|
+
* Bearer`; POST `/v1/chat/completions`. The wire-format helpers are exported and
|
|
4
|
+
* reused by the openai-compatible client. Fetch only, temperature fixed at 0.
|
|
5
|
+
*/
|
|
6
|
+
import { pingComplete, requestJson, toCompleteResult } from './http.js';
|
|
7
|
+
import { listOpenAiModels } from './model-catalog.js';
|
|
8
|
+
import { assertEnrichmentTemperature, ProviderError, requireApiKey, requireModel, stripTrailingSlash, } from './types.js';
|
|
9
|
+
const DEFAULT_BASE_URL = 'https://api.openai.com/v1';
|
|
10
|
+
/** Builds the Chat Completions request body, prepending the system message when present. */
|
|
11
|
+
export function buildOpenAiChatBody(req) {
|
|
12
|
+
const messages = [];
|
|
13
|
+
if (req.system.length > 0)
|
|
14
|
+
messages.push({ role: 'system', content: req.system });
|
|
15
|
+
for (const m of req.messages)
|
|
16
|
+
messages.push({ role: m.role, content: m.content });
|
|
17
|
+
return {
|
|
18
|
+
model: req.model,
|
|
19
|
+
max_tokens: req.maxTokens,
|
|
20
|
+
temperature: req.temperature,
|
|
21
|
+
messages,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Extracts assistant text + token usage from a Chat Completions response. */
|
|
25
|
+
export function parseOpenAiChatResponse(json, provider) {
|
|
26
|
+
const text = json.choices?.[0]?.message?.content;
|
|
27
|
+
if (typeof text !== 'string' || text.length === 0) {
|
|
28
|
+
throw new ProviderError({
|
|
29
|
+
provider,
|
|
30
|
+
code: 'bad_response',
|
|
31
|
+
message: `${provider}: response contained no message content`,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return toCompleteResult(text, json.usage?.prompt_tokens, json.usage?.completion_tokens);
|
|
35
|
+
}
|
|
36
|
+
export function createOpenAiClient(config) {
|
|
37
|
+
const apiKey = requireApiKey(config, 'openai');
|
|
38
|
+
const baseUrl = config.baseUrl ? stripTrailingSlash(config.baseUrl) : DEFAULT_BASE_URL;
|
|
39
|
+
const timeoutMs = config.timeoutMs;
|
|
40
|
+
const headers = () => ({
|
|
41
|
+
'content-type': 'application/json',
|
|
42
|
+
authorization: `Bearer ${apiKey}`,
|
|
43
|
+
});
|
|
44
|
+
const client = {
|
|
45
|
+
id: 'openai',
|
|
46
|
+
async listModels() {
|
|
47
|
+
return listOpenAiModels({ apiKey, baseUrl, ...(timeoutMs !== undefined ? { timeoutMs } : {}) });
|
|
48
|
+
},
|
|
49
|
+
async complete(req) {
|
|
50
|
+
assertEnrichmentTemperature(req.temperature, 'openai');
|
|
51
|
+
const json = await requestJson({
|
|
52
|
+
provider: 'openai',
|
|
53
|
+
method: 'POST',
|
|
54
|
+
url: `${baseUrl}/chat/completions`,
|
|
55
|
+
headers: headers(),
|
|
56
|
+
apiKey,
|
|
57
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
58
|
+
body: buildOpenAiChatBody(req),
|
|
59
|
+
});
|
|
60
|
+
return parseOpenAiChatResponse(json, 'openai');
|
|
61
|
+
},
|
|
62
|
+
async test() {
|
|
63
|
+
return pingComplete(client, requireModel(config, 'openai'));
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
return client;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider client contracts (06-llm-assist.md §3.1). The `ProviderClient`
|
|
3
|
+
* interface below is reproduced VERBATIM from the doc — it is the wire-layer
|
|
4
|
+
* boundary every direct-API path speaks through. Everything here is browser-safe
|
|
5
|
+
* (pure TS + global `fetch`/`AbortController`); no provider SDKs, no `node:*`.
|
|
6
|
+
*/
|
|
7
|
+
import type { ProviderId } from '../types.js';
|
|
8
|
+
export type { ProviderId } from '../types.js';
|
|
9
|
+
export interface ProviderClient {
|
|
10
|
+
readonly id: ProviderId;
|
|
11
|
+
listModels(): Promise<{
|
|
12
|
+
id: string;
|
|
13
|
+
label: string;
|
|
14
|
+
}[]>;
|
|
15
|
+
complete(req: {
|
|
16
|
+
system: string;
|
|
17
|
+
messages: {
|
|
18
|
+
role: 'user' | 'assistant';
|
|
19
|
+
content: string;
|
|
20
|
+
}[];
|
|
21
|
+
model: string;
|
|
22
|
+
maxTokens: number;
|
|
23
|
+
temperature: number;
|
|
24
|
+
}): Promise<{
|
|
25
|
+
text: string;
|
|
26
|
+
usage?: {
|
|
27
|
+
inputTokens: number;
|
|
28
|
+
outputTokens: number;
|
|
29
|
+
};
|
|
30
|
+
}>;
|
|
31
|
+
test(): Promise<{
|
|
32
|
+
ok: true;
|
|
33
|
+
model: string;
|
|
34
|
+
latencyMs: number;
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Resolved provider configuration a client is constructed from (§3.2). The
|
|
39
|
+
* `apiKey` is the DECRYPTED value: the server decrypts `llm.apiKey` (AES-256-GCM,
|
|
40
|
+
* see `crypto.ts`) before building a client, and the client keeps it only in the
|
|
41
|
+
* request header — never in a log, error, or thrown value (acceptance §10).
|
|
42
|
+
*/
|
|
43
|
+
export interface ProviderConfig {
|
|
44
|
+
provider: ProviderId;
|
|
45
|
+
/** Required for `anthropic`/`openai`; optional for `openai-compatible`; unused for `ollama`. */
|
|
46
|
+
apiKey?: string;
|
|
47
|
+
/** Required for `openai-compatible`; defaults to `http://localhost:11434` for `ollama`. */
|
|
48
|
+
baseUrl?: string;
|
|
49
|
+
/** Selected model id — required to `complete()` / `test()`. */
|
|
50
|
+
model?: string;
|
|
51
|
+
/** Response budget passed as `maxTokens`; default `16_000`. */
|
|
52
|
+
maxOutputTokens?: number;
|
|
53
|
+
/** Per-request timeout in ms; default `60_000`. */
|
|
54
|
+
timeoutMs?: number;
|
|
55
|
+
}
|
|
56
|
+
/** Structural alias for `ProviderClient.complete`'s argument (not part of the verbatim interface). */
|
|
57
|
+
export interface CompleteRequest {
|
|
58
|
+
system: string;
|
|
59
|
+
messages: {
|
|
60
|
+
role: 'user' | 'assistant';
|
|
61
|
+
content: string;
|
|
62
|
+
}[];
|
|
63
|
+
model: string;
|
|
64
|
+
maxTokens: number;
|
|
65
|
+
temperature: number;
|
|
66
|
+
}
|
|
67
|
+
/** Structural alias for `ProviderClient.complete`'s result. */
|
|
68
|
+
export interface CompleteResult {
|
|
69
|
+
text: string;
|
|
70
|
+
usage?: {
|
|
71
|
+
inputTokens: number;
|
|
72
|
+
outputTokens: number;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** One entry in a model list (structural alias for `ProviderClient.listModels`'s element). */
|
|
76
|
+
export interface ModelInfo {
|
|
77
|
+
id: string;
|
|
78
|
+
label: string;
|
|
79
|
+
}
|
|
80
|
+
export declare const DEFAULT_MAX_OUTPUT_TOKENS: 16000;
|
|
81
|
+
export declare const DEFAULT_TIMEOUT_MS: 60000;
|
|
82
|
+
/**
|
|
83
|
+
* Every non-2xx response and network/timeout failure is mapped to this. It is
|
|
84
|
+
* deliberately narrow and NEVER carries the API key: constructors scrub the
|
|
85
|
+
* secret out of any provider-supplied error body before it reaches a `message`.
|
|
86
|
+
*/
|
|
87
|
+
export type ProviderErrorCode = 'config' | 'network' | 'timeout' | 'auth' | 'rate_limit' | 'not_found' | 'server' | 'http' | 'bad_response';
|
|
88
|
+
export interface ProviderErrorInit {
|
|
89
|
+
provider: ProviderId;
|
|
90
|
+
code: ProviderErrorCode;
|
|
91
|
+
message: string;
|
|
92
|
+
status?: number;
|
|
93
|
+
cause?: unknown;
|
|
94
|
+
}
|
|
95
|
+
export declare class ProviderError extends Error {
|
|
96
|
+
readonly name = "ProviderError";
|
|
97
|
+
readonly provider: ProviderId;
|
|
98
|
+
readonly code: ProviderErrorCode;
|
|
99
|
+
readonly status?: number;
|
|
100
|
+
constructor(init: ProviderErrorInit);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Enrichment runs are deterministic: temperature is fixed at 0, non-negotiable
|
|
104
|
+
* (§3.1). This asserts it at the client boundary so a misconfigured caller fails
|
|
105
|
+
* loudly rather than producing non-reproducible diffs.
|
|
106
|
+
*/
|
|
107
|
+
export declare function assertEnrichmentTemperature(temperature: number, provider: ProviderId): void;
|
|
108
|
+
export declare function requireApiKey(config: ProviderConfig, provider: ProviderId): string;
|
|
109
|
+
export declare function requireBaseUrl(config: ProviderConfig, provider: ProviderId): string;
|
|
110
|
+
export declare function requireModel(config: ProviderConfig, provider: ProviderId): string;
|
|
111
|
+
export declare function stripTrailingSlash(url: string): string;
|
|
112
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export const DEFAULT_MAX_OUTPUT_TOKENS = 16_000;
|
|
2
|
+
export const DEFAULT_TIMEOUT_MS = 60_000;
|
|
3
|
+
export class ProviderError extends Error {
|
|
4
|
+
name = 'ProviderError';
|
|
5
|
+
provider;
|
|
6
|
+
code;
|
|
7
|
+
status;
|
|
8
|
+
constructor(init) {
|
|
9
|
+
super(init.message, init.cause === undefined ? undefined : { cause: init.cause });
|
|
10
|
+
this.provider = init.provider;
|
|
11
|
+
this.code = init.code;
|
|
12
|
+
if (init.status !== undefined)
|
|
13
|
+
this.status = init.status;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// ─── Guards ──────────────────────────────────────────────────────────────────
|
|
17
|
+
/**
|
|
18
|
+
* Enrichment runs are deterministic: temperature is fixed at 0, non-negotiable
|
|
19
|
+
* (§3.1). This asserts it at the client boundary so a misconfigured caller fails
|
|
20
|
+
* loudly rather than producing non-reproducible diffs.
|
|
21
|
+
*/
|
|
22
|
+
export function assertEnrichmentTemperature(temperature, provider) {
|
|
23
|
+
if (temperature !== 0) {
|
|
24
|
+
throw new ProviderError({
|
|
25
|
+
provider,
|
|
26
|
+
code: 'config',
|
|
27
|
+
message: `enrichment runs require temperature 0 (received ${String(temperature)})`,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function requireApiKey(config, provider) {
|
|
32
|
+
const raw = config.apiKey;
|
|
33
|
+
if (raw === undefined || raw.trim() === '') {
|
|
34
|
+
throw new ProviderError({ provider, code: 'config', message: `${provider} requires an API key` });
|
|
35
|
+
}
|
|
36
|
+
return raw;
|
|
37
|
+
}
|
|
38
|
+
export function requireBaseUrl(config, provider) {
|
|
39
|
+
const raw = config.baseUrl;
|
|
40
|
+
if (raw === undefined || raw.trim() === '') {
|
|
41
|
+
throw new ProviderError({ provider, code: 'config', message: `${provider} requires a baseUrl` });
|
|
42
|
+
}
|
|
43
|
+
return stripTrailingSlash(raw);
|
|
44
|
+
}
|
|
45
|
+
export function requireModel(config, provider) {
|
|
46
|
+
const raw = config.model;
|
|
47
|
+
if (raw === undefined || raw.trim() === '') {
|
|
48
|
+
throw new ProviderError({ provider, code: 'config', message: `${provider} requires a model` });
|
|
49
|
+
}
|
|
50
|
+
return raw;
|
|
51
|
+
}
|
|
52
|
+
export function stripTrailingSlash(url) {
|
|
53
|
+
return url.replace(/\/+$/, '');
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"AAoEA,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAe,CAAC;AACzD,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAe,CAAC;AA4BlD,MAAM,OAAO,aAAc,SAAQ,KAAK;IACpB,IAAI,GAAG,eAAe,CAAC;IAChC,QAAQ,CAAa;IACrB,IAAI,CAAoB;IACxB,MAAM,CAAU;IAEzB,YAAY,IAAuB;QACjC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAClF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3D,CAAC;CACF;AAED,gFAAgF;AAEhF;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,WAAmB,EAAE,QAAoB;IACnF,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,aAAa,CAAC;YACtB,QAAQ;YACR,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,mDAAmD,MAAM,CAAC,WAAW,CAAC,GAAG;SACnF,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAsB,EAAE,QAAoB;IACxE,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1B,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,aAAa,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,QAAQ,sBAAsB,EAAE,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAsB,EAAE,QAAoB;IACzE,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;IAC3B,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,aAAa,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,QAAQ,qBAAqB,EAAE,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAsB,EAAE,QAAoB;IACvE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;IACzB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,aAAa,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,QAAQ,mBAAmB,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation error model shared by the whole response pipeline
|
|
3
|
+
* (06-llm-assist.md §7.2). Every stage — extract, parse, version, Zod, locale,
|
|
4
|
+
* referential, run-binding — reports through the ONE {@link LlmValidationError}
|
|
5
|
+
* shape so the paste UI and the CLI `--dry-run` can render a single precise
|
|
6
|
+
* per-path list (§7.2).
|
|
7
|
+
*
|
|
8
|
+
* Two axes matter downstream:
|
|
9
|
+
* - `code` — the machine code (§7.2/§7.3 tables), rendered verbatim.
|
|
10
|
+
* - `severity` — how the pipeline reacts:
|
|
11
|
+
* • `fatal` → rejects the whole run (stays `awaiting_response` / `failed`).
|
|
12
|
+
* • `item` → drops only the offending suggestion; the rest applies
|
|
13
|
+
* (acceptance criterion 4 — a hallucinated table must not
|
|
14
|
+
* discard 200 good labels).
|
|
15
|
+
* • `warning` → nothing dropped; surfaced as information (icon fallback,
|
|
16
|
+
* run-id mismatch).
|
|
17
|
+
*
|
|
18
|
+
* This module is pure data + string formatting: no Zod, no engine, no I/O — so
|
|
19
|
+
* it is safe for `@adminium/dashboard` (browser) to pull transitively.
|
|
20
|
+
*/
|
|
21
|
+
/** Every code the pipeline can emit (§7.2 stages + §7.3 referential list). */
|
|
22
|
+
export declare const LLM_VALIDATION_CODES: readonly ["LLM_JSON_PARSE", "LLM_TRUNCATED", "LLM_VERSION_MISMATCH", "LLM_MODEL_DECLINED", "LLM_SCHEMA_INVALID", "LLM_LOCALE_KEYS", "LLM_UNKNOWN_TABLE", "LLM_UNKNOWN_COLUMN", "LLM_BAD_DISPLAY_COLUMN", "LLM_NOT_AN_ENUM", "LLM_ENUM_VALUES", "LLM_UNKNOWN_RELATION", "LLM_RELATION_INVALID", "LLM_UNKNOWN_TEMPLATE", "LLM_UNKNOWN_WIDGET", "LLM_WIDGET_BINDING", "LLM_GROUP_INVALID", "LLM_UNKNOWN_ICON", "LLM_RUN_MISMATCH"];
|
|
23
|
+
export type LlmValidationCode = (typeof LLM_VALIDATION_CODES)[number];
|
|
24
|
+
export type LlmValidationSeverity = 'fatal' | 'item' | 'warning';
|
|
25
|
+
/**
|
|
26
|
+
* One validation failure. `path` is a JSON path into the response
|
|
27
|
+
* (`tables[3].table`, `dashboards[0].widgets[5].metricColumn`, `schema_version`,
|
|
28
|
+
* or `''` for the whole document) so the UI can point at the exact field.
|
|
29
|
+
* `message` is a human sentence rendered verbatim (§7.2).
|
|
30
|
+
*/
|
|
31
|
+
export interface LlmValidationError {
|
|
32
|
+
code: LlmValidationCode;
|
|
33
|
+
severity: LlmValidationSeverity;
|
|
34
|
+
/** JSON path into the response; `''` = the whole document. */
|
|
35
|
+
path: string;
|
|
36
|
+
message: string;
|
|
37
|
+
/** Extra remediation line (e.g. the §4.3 regeneration hint). */
|
|
38
|
+
hint?: string;
|
|
39
|
+
/** Stable §8.1 suggestion id of the dropped suggestion, when one applies. */
|
|
40
|
+
suggestionId?: string;
|
|
41
|
+
}
|
|
42
|
+
/** The fixed severity of a code (§7.2 "Failure class" column). */
|
|
43
|
+
export declare function severityOf(code: LlmValidationCode): LlmValidationSeverity;
|
|
44
|
+
export declare function isFatal(error: LlmValidationError): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Render a Zod (or hand-built) path array as the pipeline's JSON-path string.
|
|
47
|
+
* Numeric segments become `[n]`; string segments join with `.`; the first
|
|
48
|
+
* segment carries no leading dot (`tables[3].table`, not `.tables[3].table`).
|
|
49
|
+
*/
|
|
50
|
+
export declare function formatJsonPath(segments: ReadonlyArray<string | number | symbol>): string;
|
|
51
|
+
/**
|
|
52
|
+
* Build a validation error, stamping the code's fixed severity. `hint` /
|
|
53
|
+
* `suggestionId` are set only when provided (respects
|
|
54
|
+
* `exactOptionalPropertyTypes`).
|
|
55
|
+
*/
|
|
56
|
+
export declare function makeError(code: LlmValidationCode, path: string, message: string, extra?: {
|
|
57
|
+
hint?: string;
|
|
58
|
+
suggestionId?: string;
|
|
59
|
+
}): LlmValidationError;
|
|
60
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/response/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,oBAAoB,iaAwBvB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAYD,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,qBAAqB,CAIzE;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAE1D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAWxF;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,kBAAkB,CAUpB"}
|