@cogenta/agents 0.2.1 → 0.5.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/dist/agents/builtins.d.ts +51 -0
- package/dist/agents/builtins.d.ts.map +1 -0
- package/dist/agents/builtins.js +190 -0
- package/dist/agents/builtins.js.map +1 -0
- package/dist/agents/orchestrator.d.ts +98 -0
- package/dist/agents/orchestrator.d.ts.map +1 -0
- package/dist/agents/orchestrator.js +286 -0
- package/dist/agents/orchestrator.js.map +1 -0
- package/dist/agents/store.d.ts +71 -0
- package/dist/agents/store.d.ts.map +1 -0
- package/dist/agents/store.js +211 -0
- package/dist/agents/store.js.map +1 -0
- package/dist/agents/types.d.ts +10 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/assist/agent-identity.d.ts +44 -0
- package/dist/assist/agent-identity.d.ts.map +1 -0
- package/dist/assist/agent-identity.js +136 -0
- package/dist/assist/agent-identity.js.map +1 -0
- package/dist/assist/chat.d.ts +2 -0
- package/dist/assist/chat.d.ts.map +1 -1
- package/dist/assist/chat.js +14 -5
- package/dist/assist/chat.js.map +1 -1
- package/dist/assist/classify.d.ts +3 -2
- package/dist/assist/classify.d.ts.map +1 -1
- package/dist/assist/classify.js +30 -11
- package/dist/assist/classify.js.map +1 -1
- package/dist/assist/faq.d.ts +3 -2
- package/dist/assist/faq.d.ts.map +1 -1
- package/dist/assist/faq.js +31 -13
- package/dist/assist/faq.js.map +1 -1
- package/dist/assist/runtime.d.ts +8 -2
- package/dist/assist/runtime.d.ts.map +1 -1
- package/dist/assist/runtime.js +2 -2
- package/dist/assist/runtime.js.map +1 -1
- package/dist/assist/toolset.d.ts +10 -0
- package/dist/assist/toolset.d.ts.map +1 -1
- package/dist/assist/toolset.js +36 -8
- package/dist/assist/toolset.js.map +1 -1
- package/dist/assist/usage.d.ts +58 -0
- package/dist/assist/usage.d.ts.map +1 -0
- package/dist/assist/usage.js +53 -0
- package/dist/assist/usage.js.map +1 -0
- package/dist/assist/writing.d.ts +10 -9
- package/dist/assist/writing.d.ts.map +1 -1
- package/dist/assist/writing.js +126 -58
- package/dist/assist/writing.js.map +1 -1
- package/dist/audit/with-audit.d.ts +13 -0
- package/dist/audit/with-audit.d.ts.map +1 -1
- package/dist/audit/with-audit.js +6 -0
- package/dist/audit/with-audit.js.map +1 -1
- package/dist/autonomy/levels.d.ts +37 -0
- package/dist/autonomy/levels.d.ts.map +1 -0
- package/dist/autonomy/levels.js +51 -0
- package/dist/autonomy/levels.js.map +1 -0
- package/dist/conversations/store.d.ts +62 -0
- package/dist/conversations/store.d.ts.map +1 -0
- package/dist/conversations/store.js +0 -0
- package/dist/conversations/store.js.map +1 -0
- package/dist/identity/context.d.ts +8 -0
- package/dist/identity/context.d.ts.map +1 -1
- package/dist/identity/context.js +19 -4
- package/dist/identity/context.js.map +1 -1
- package/dist/identity/markdown.d.ts +38 -0
- package/dist/identity/markdown.d.ts.map +1 -0
- package/dist/identity/markdown.js +85 -0
- package/dist/identity/markdown.js.map +1 -0
- package/dist/index.d.ts +62 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -3
- package/dist/index.js.map +1 -1
- package/dist/progress/job-store.d.ts +41 -0
- package/dist/progress/job-store.d.ts.map +1 -0
- package/dist/progress/job-store.js +44 -0
- package/dist/progress/job-store.js.map +1 -0
- package/dist/progress/types.d.ts +21 -0
- package/dist/progress/types.d.ts.map +1 -0
- package/dist/progress/types.js +3 -0
- package/dist/progress/types.js.map +1 -0
- package/dist/prompts/render.d.ts +23 -0
- package/dist/prompts/render.d.ts.map +1 -0
- package/dist/prompts/render.js +35 -0
- package/dist/prompts/render.js.map +1 -0
- package/dist/prompts/seeds.d.ts +34 -0
- package/dist/prompts/seeds.d.ts.map +1 -0
- package/dist/prompts/seeds.js +166 -0
- package/dist/prompts/seeds.js.map +1 -0
- package/dist/prompts/store.d.ts +8 -0
- package/dist/prompts/store.d.ts.map +1 -0
- package/dist/prompts/store.js +153 -0
- package/dist/prompts/store.js.map +1 -0
- package/dist/prompts/types.d.ts +51 -0
- package/dist/prompts/types.d.ts.map +1 -0
- package/dist/prompts/types.js +24 -0
- package/dist/prompts/types.js.map +1 -0
- package/dist/providers/anthropic.d.ts +26 -3
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +60 -12
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/catalog.d.ts +41 -0
- package/dist/providers/catalog.d.ts.map +1 -0
- package/dist/providers/catalog.js +85 -0
- package/dist/providers/catalog.js.map +1 -0
- package/dist/providers/content-parts.d.ts +12 -0
- package/dist/providers/content-parts.d.ts.map +1 -0
- package/dist/providers/content-parts.js +18 -0
- package/dist/providers/content-parts.js.map +1 -0
- package/dist/providers/defaults.d.ts +44 -0
- package/dist/providers/defaults.d.ts.map +1 -0
- package/dist/providers/defaults.js +72 -0
- package/dist/providers/defaults.js.map +1 -0
- package/dist/providers/google.d.ts +20 -3
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +53 -12
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/openai.d.ts +36 -4
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +113 -21
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/registry.d.ts +38 -21
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +64 -8
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/request-signal.d.ts +18 -0
- package/dist/providers/request-signal.d.ts.map +1 -0
- package/dist/providers/request-signal.js +21 -0
- package/dist/providers/request-signal.js.map +1 -0
- package/dist/providers/resolve.d.ts +13 -0
- package/dist/providers/resolve.d.ts.map +1 -0
- package/dist/providers/resolve.js +30 -0
- package/dist/providers/resolve.js.map +1 -0
- package/dist/providers/store.d.ts +70 -0
- package/dist/providers/store.d.ts.map +1 -0
- package/dist/providers/store.js +308 -0
- package/dist/providers/store.js.map +1 -0
- package/dist/providers/tool-names.d.ts +9 -0
- package/dist/providers/tool-names.d.ts.map +1 -0
- package/dist/providers/tool-names.js +56 -0
- package/dist/providers/tool-names.js.map +1 -0
- package/dist/providers/types.d.ts +87 -3
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/rag/reference-documents/ingest.d.ts +22 -0
- package/dist/rag/reference-documents/ingest.d.ts.map +1 -0
- package/dist/rag/reference-documents/ingest.js +69 -0
- package/dist/rag/reference-documents/ingest.js.map +1 -0
- package/dist/rag/reference-documents/store.d.ts +23 -0
- package/dist/rag/reference-documents/store.d.ts.map +1 -0
- package/dist/rag/reference-documents/store.js +140 -0
- package/dist/rag/reference-documents/store.js.map +1 -0
- package/dist/rag/reference-documents/types.d.ts +52 -0
- package/dist/rag/reference-documents/types.d.ts.map +1 -0
- package/dist/rag/reference-documents/types.js +32 -0
- package/dist/rag/reference-documents/types.js.map +1 -0
- package/dist/runtime/loop.d.ts +29 -7
- package/dist/runtime/loop.d.ts.map +1 -1
- package/dist/runtime/loop.js +209 -44
- package/dist/runtime/loop.js.map +1 -1
- package/dist/runtime/retry.d.ts +2 -0
- package/dist/runtime/retry.d.ts.map +1 -1
- package/dist/runtime/retry.js +1 -0
- package/dist/runtime/retry.js.map +1 -1
- package/dist/runtime/types.d.ts +14 -3
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/site-plan/analyse-brief.d.ts +8 -0
- package/dist/site-plan/analyse-brief.d.ts.map +1 -1
- package/dist/site-plan/analyse-brief.js +17 -8
- package/dist/site-plan/analyse-brief.js.map +1 -1
- package/dist/site-plan/approval.d.ts +2 -2
- package/dist/site-plan/approval.d.ts.map +1 -1
- package/dist/site-plan/approval.js +34 -4
- package/dist/site-plan/approval.js.map +1 -1
- package/dist/site-plan/content-model.d.ts +14 -0
- package/dist/site-plan/content-model.d.ts.map +1 -1
- package/dist/site-plan/content-model.js +51 -9
- package/dist/site-plan/content-model.js.map +1 -1
- package/dist/site-plan/demo-content.d.ts.map +1 -1
- package/dist/site-plan/demo-content.js +1 -4
- package/dist/site-plan/demo-content.js.map +1 -1
- package/dist/site-plan/propose-plan.d.ts +10 -0
- package/dist/site-plan/propose-plan.d.ts.map +1 -1
- package/dist/site-plan/propose-plan.js +25 -1
- package/dist/site-plan/propose-plan.js.map +1 -1
- package/dist/site-plan/site-context.d.ts +81 -0
- package/dist/site-plan/site-context.d.ts.map +1 -0
- package/dist/site-plan/site-context.js +76 -0
- package/dist/site-plan/site-context.js.map +1 -0
- package/dist/site-plan/skin-candidates.d.ts +13 -1
- package/dist/site-plan/skin-candidates.d.ts.map +1 -1
- package/dist/site-plan/skin-candidates.js +15 -0
- package/dist/site-plan/skin-candidates.js.map +1 -1
- package/dist/site-plan/structural-gaps.d.ts +32 -0
- package/dist/site-plan/structural-gaps.d.ts.map +1 -0
- package/dist/site-plan/structural-gaps.js +77 -0
- package/dist/site-plan/structural-gaps.js.map +1 -0
- package/dist/site-plan/types.d.ts +7 -0
- package/dist/site-plan/types.d.ts.map +1 -1
- package/dist/skills/frontmatter.d.ts +19 -1
- package/dist/skills/frontmatter.d.ts.map +1 -1
- package/dist/skills/frontmatter.js +29 -5
- package/dist/skills/frontmatter.js.map +1 -1
- package/dist/skills/library.d.ts +133 -0
- package/dist/skills/library.d.ts.map +1 -0
- package/dist/skills/library.js +332 -0
- package/dist/skills/library.js.map +1 -0
- package/dist/skills/types.d.ts +8 -1
- package/dist/skills/types.d.ts.map +1 -1
- package/dist/skin/generate.d.ts +22 -1
- package/dist/skin/generate.d.ts.map +1 -1
- package/dist/skin/generate.js +60 -5
- package/dist/skin/generate.js.map +1 -1
- package/dist/theme-creator/propose-theme.d.ts +83 -0
- package/dist/theme-creator/propose-theme.d.ts.map +1 -0
- package/dist/theme-creator/propose-theme.js +234 -0
- package/dist/theme-creator/propose-theme.js.map +1 -0
- package/dist/tools/core/agent-delegate.d.ts +8 -5
- package/dist/tools/core/agent-delegate.d.ts.map +1 -1
- package/dist/tools/core/agent-delegate.js +16 -6
- package/dist/tools/core/agent-delegate.js.map +1 -1
- package/dist/tools/core/content-browse.d.ts +74 -0
- package/dist/tools/core/content-browse.d.ts.map +1 -0
- package/dist/tools/core/content-browse.js +63 -0
- package/dist/tools/core/content-browse.js.map +1 -0
- package/dist/tools/core/content-schema.d.ts +86 -0
- package/dist/tools/core/content-schema.d.ts.map +1 -0
- package/dist/tools/core/content-schema.js +83 -0
- package/dist/tools/core/content-schema.js.map +1 -0
- package/dist/tools/core/deps-scan.d.ts +25 -0
- package/dist/tools/core/deps-scan.d.ts.map +1 -0
- package/dist/tools/core/deps-scan.js +85 -0
- package/dist/tools/core/deps-scan.js.map +1 -0
- package/dist/tools/core/media.d.ts +18 -2
- package/dist/tools/core/media.d.ts.map +1 -1
- package/dist/tools/core/media.js +8 -2
- package/dist/tools/core/media.js.map +1 -1
- package/dist/tools/core/not-found-log.d.ts +44 -0
- package/dist/tools/core/not-found-log.d.ts.map +1 -0
- package/dist/tools/core/not-found-log.js +32 -0
- package/dist/tools/core/not-found-log.js.map +1 -0
- package/dist/tools/core/redirects.d.ts +51 -0
- package/dist/tools/core/redirects.d.ts.map +1 -0
- package/dist/tools/core/redirects.js +50 -0
- package/dist/tools/core/redirects.js.map +1 -0
- package/package.json +6 -4
package/dist/providers/openai.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { CogentaError } from '@cogenta/core';
|
|
2
|
+
import { textOnlyContent } from './content-parts.js';
|
|
3
|
+
import { requestSignalWithTimeout } from './request-signal.js';
|
|
4
|
+
import { createToolNameDecoder, encodeToolName } from './tool-names.js';
|
|
2
5
|
const DEFAULT_BASE_URL = 'https://api.openai.com/v1/chat/completions';
|
|
3
6
|
const STOP_REASON = {
|
|
4
7
|
stop: 'end_turn',
|
|
@@ -6,6 +9,25 @@ const STOP_REASON = {
|
|
|
6
9
|
length: 'max_tokens',
|
|
7
10
|
content_filter: 'stop_sequence',
|
|
8
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* A plain string is passed through unchanged (byte-for-byte identical wire
|
|
14
|
+
* shape to before this adapter supported images); an array of
|
|
15
|
+
* `ChatContentPart` becomes OpenAI's multimodal content-part array, with
|
|
16
|
+
* each image re-encoded as a `data:` URL — the only form the Chat
|
|
17
|
+
* Completions API accepts for an inline image.
|
|
18
|
+
*/
|
|
19
|
+
function toOpenAiContent(content) {
|
|
20
|
+
if (content === undefined)
|
|
21
|
+
return null;
|
|
22
|
+
if (typeof content === 'string')
|
|
23
|
+
return content;
|
|
24
|
+
return content.map((part) => part.type === 'text'
|
|
25
|
+
? { type: 'text', text: part.text }
|
|
26
|
+
: {
|
|
27
|
+
type: 'image_url',
|
|
28
|
+
image_url: { url: `data:${part.mediaType};base64,${part.data}` },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
9
31
|
function toOpenAiMessage(message) {
|
|
10
32
|
if (message.role === 'tool') {
|
|
11
33
|
if (message.toolCallId === undefined) {
|
|
@@ -15,25 +37,34 @@ function toOpenAiMessage(message) {
|
|
|
15
37
|
hint: "Set toolCallId to the id the model's tool call carried.",
|
|
16
38
|
});
|
|
17
39
|
}
|
|
18
|
-
return {
|
|
40
|
+
return {
|
|
41
|
+
role: 'tool',
|
|
42
|
+
content: textOnlyContent(message.content) ?? '',
|
|
43
|
+
tool_call_id: message.toolCallId,
|
|
44
|
+
};
|
|
19
45
|
}
|
|
20
46
|
const toolCalls = message.toolCalls ?? [];
|
|
21
47
|
return {
|
|
22
48
|
role: message.role,
|
|
23
|
-
content: message.content
|
|
49
|
+
content: toOpenAiContent(message.content),
|
|
24
50
|
...(toolCalls.length === 0
|
|
25
51
|
? {}
|
|
26
52
|
: {
|
|
27
53
|
tool_calls: toolCalls.map((call) => ({
|
|
28
54
|
id: call.id,
|
|
29
55
|
type: 'function',
|
|
30
|
-
function: { name: call.name, arguments: JSON.stringify(call.input) },
|
|
56
|
+
function: { name: encodeToolName(call.name), arguments: JSON.stringify(call.input) },
|
|
31
57
|
})),
|
|
32
58
|
}),
|
|
33
59
|
};
|
|
34
60
|
}
|
|
35
|
-
/**
|
|
36
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Pure — no network. `fallbackMaxTokens` is the client's own resolved
|
|
63
|
+
* `maxOutputTokens` (the admin's per-provider value, or the site-wide
|
|
64
|
+
* default) — applied only when `request.maxTokens` itself is absent.
|
|
65
|
+
* Required, not defaulted — see `buildAnthropicRequest`'s own doc comment.
|
|
66
|
+
*/
|
|
67
|
+
export function buildOpenAiRequest(request, fallbackMaxTokens) {
|
|
37
68
|
const messages = [];
|
|
38
69
|
if (request.system !== undefined) {
|
|
39
70
|
messages.push({ role: 'system', content: request.system });
|
|
@@ -41,7 +72,7 @@ export function buildOpenAiRequest(request) {
|
|
|
41
72
|
messages.push(...request.messages.map(toOpenAiMessage));
|
|
42
73
|
return {
|
|
43
74
|
model: request.model,
|
|
44
|
-
max_tokens: request.maxTokens,
|
|
75
|
+
max_tokens: request.maxTokens ?? fallbackMaxTokens,
|
|
45
76
|
messages,
|
|
46
77
|
...(request.tools === undefined
|
|
47
78
|
? {}
|
|
@@ -49,7 +80,7 @@ export function buildOpenAiRequest(request) {
|
|
|
49
80
|
tools: request.tools.map((tool) => ({
|
|
50
81
|
type: 'function',
|
|
51
82
|
function: {
|
|
52
|
-
name: tool.name,
|
|
83
|
+
name: encodeToolName(tool.name),
|
|
53
84
|
description: tool.description,
|
|
54
85
|
parameters: tool.inputSchema,
|
|
55
86
|
},
|
|
@@ -59,18 +90,18 @@ export function buildOpenAiRequest(request) {
|
|
|
59
90
|
};
|
|
60
91
|
}
|
|
61
92
|
/** Pure — no network. */
|
|
62
|
-
export function parseOpenAiResponse(body) {
|
|
93
|
+
export function parseOpenAiResponse(body, decodeToolName = (wire) => wire) {
|
|
63
94
|
const choice = body.choices[0];
|
|
64
95
|
if (choice === undefined) {
|
|
65
96
|
throw new CogentaError({
|
|
66
97
|
code: 'PROVIDER_RESPONSE_INVALID',
|
|
67
|
-
message: 'OpenAI returned no choices.',
|
|
98
|
+
message: 'The OpenAI-compatible endpoint returned no choices.',
|
|
68
99
|
hint: 'Retry the request; this is not something the caller can fix by itself.',
|
|
69
100
|
});
|
|
70
101
|
}
|
|
71
102
|
const toolCalls = (choice.message.tool_calls ?? []).map((call) => ({
|
|
72
103
|
id: call.id,
|
|
73
|
-
name: call.function.name,
|
|
104
|
+
name: decodeToolName(call.function.name),
|
|
74
105
|
input: parseArguments(call.function.arguments),
|
|
75
106
|
}));
|
|
76
107
|
return {
|
|
@@ -90,53 +121,114 @@ function parseArguments(raw) {
|
|
|
90
121
|
catch (cause) {
|
|
91
122
|
throw new CogentaError({
|
|
92
123
|
code: 'PROVIDER_RESPONSE_INVALID',
|
|
93
|
-
message: "
|
|
124
|
+
message: "The endpoint's tool call arguments were not valid JSON.",
|
|
94
125
|
hint: 'This is a vendor-side malformed response; retry the request.',
|
|
95
126
|
cause,
|
|
96
127
|
});
|
|
97
128
|
}
|
|
98
129
|
}
|
|
130
|
+
const MAX_REASON_LENGTH = 300;
|
|
131
|
+
/**
|
|
132
|
+
* The human-readable part of an OpenAI-shaped error body
|
|
133
|
+
* (`{ error: { message } }`), or the first line of a non-JSON body, capped
|
|
134
|
+
* so a vendor's HTML error page never becomes the message. `undefined` when
|
|
135
|
+
* there is nothing legible to show.
|
|
136
|
+
*/
|
|
137
|
+
async function readErrorReason(response) {
|
|
138
|
+
const text = await response.text().catch(() => '');
|
|
139
|
+
if (text.trim() === '')
|
|
140
|
+
return undefined;
|
|
141
|
+
let reason = text;
|
|
142
|
+
try {
|
|
143
|
+
const parsed = JSON.parse(text);
|
|
144
|
+
if (typeof parsed === 'object' && parsed !== null && 'error' in parsed) {
|
|
145
|
+
const error = parsed.error;
|
|
146
|
+
if (typeof error === 'string')
|
|
147
|
+
reason = error;
|
|
148
|
+
else if (typeof error === 'object' && error !== null && 'message' in error) {
|
|
149
|
+
const message = error.message;
|
|
150
|
+
if (typeof message === 'string')
|
|
151
|
+
reason = message;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// Not JSON — keep the raw text.
|
|
157
|
+
}
|
|
158
|
+
const firstLine = reason.split('\n')[0]?.trim() ?? '';
|
|
159
|
+
if (firstLine === '')
|
|
160
|
+
return undefined;
|
|
161
|
+
return firstLine.length > MAX_REASON_LENGTH
|
|
162
|
+
? `${firstLine.slice(0, MAX_REASON_LENGTH)}…`
|
|
163
|
+
: firstLine;
|
|
164
|
+
}
|
|
99
165
|
/** API key injected at the runtime boundary — never in a prompt or tool input (rule R7). */
|
|
100
166
|
export function createOpenAiClient(config) {
|
|
101
167
|
const doFetch = config.fetchImpl ?? fetch;
|
|
102
168
|
const url = config.baseUrl ?? DEFAULT_BASE_URL;
|
|
169
|
+
const name = config.name ?? 'openai';
|
|
170
|
+
const maxOutputTokens = config.maxOutputTokens ?? config.defaults.maxOutputTokens;
|
|
171
|
+
const requestTimeoutMs = config.requestTimeoutMs ?? config.defaults.requestTimeoutMs;
|
|
172
|
+
const maxCorrectionAttempts = config.maxCorrectionAttempts ?? config.defaults.maxCorrectionAttempts;
|
|
103
173
|
return {
|
|
104
|
-
name
|
|
174
|
+
name,
|
|
105
175
|
model: config.model,
|
|
176
|
+
supportsVision: true,
|
|
177
|
+
maxOutputTokens,
|
|
178
|
+
requestTimeoutMs,
|
|
179
|
+
maxCorrectionAttempts,
|
|
106
180
|
async chat(request, options) {
|
|
181
|
+
const signal = requestSignalWithTimeout(options?.signal, requestTimeoutMs);
|
|
107
182
|
const response = await doFetch(url, {
|
|
108
183
|
method: 'POST',
|
|
109
184
|
headers: {
|
|
110
185
|
'content-type': 'application/json',
|
|
111
186
|
authorization: `Bearer ${config.apiKey}`,
|
|
112
187
|
},
|
|
113
|
-
body: JSON.stringify(buildOpenAiRequest(request)),
|
|
114
|
-
|
|
188
|
+
body: JSON.stringify(buildOpenAiRequest(request, maxOutputTokens)),
|
|
189
|
+
signal,
|
|
115
190
|
}).catch((cause) => {
|
|
191
|
+
if (signal.aborted && options?.signal?.aborted !== true) {
|
|
192
|
+
throw new CogentaError({
|
|
193
|
+
code: 'PROVIDER_REQUEST_FAILED',
|
|
194
|
+
message: `"${name}" did not answer in time.`,
|
|
195
|
+
hint: 'The vendor may be slow or unreachable right now; retry, or check its status page.',
|
|
196
|
+
cause,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
116
199
|
throw new CogentaError({
|
|
117
200
|
code: 'PROVIDER_REQUEST_FAILED',
|
|
118
|
-
message:
|
|
119
|
-
hint:
|
|
201
|
+
message: `The request to "${name}" could not be sent.`,
|
|
202
|
+
hint: "Check network connectivity and this provider's saved API key.",
|
|
120
203
|
cause,
|
|
121
204
|
});
|
|
122
205
|
});
|
|
123
206
|
if (response.status === 429) {
|
|
124
207
|
throw new CogentaError({
|
|
125
208
|
code: 'PROVIDER_RATE_LIMITED',
|
|
126
|
-
message:
|
|
209
|
+
message: `"${name}" rate-limited this request.`,
|
|
127
210
|
hint: 'Retry with backoff, or lower callsPerHour for this agent.',
|
|
128
211
|
});
|
|
129
212
|
}
|
|
130
213
|
if (!response.ok) {
|
|
214
|
+
// The vendor's own error text is the only thing that tells a 400
|
|
215
|
+
// ("model does not exist", "unsupported parameter") from a 401 —
|
|
216
|
+
// dropping it left an operator staring at a bare status code with
|
|
217
|
+
// nothing to act on. It never carries the key; it is safe to quote.
|
|
218
|
+
const reason = await readErrorReason(response);
|
|
131
219
|
throw new CogentaError({
|
|
132
220
|
code: 'PROVIDER_REQUEST_FAILED',
|
|
133
|
-
message:
|
|
134
|
-
|
|
135
|
-
|
|
221
|
+
message: reason === undefined
|
|
222
|
+
? `"${name}" returned status ${response.status}.`
|
|
223
|
+
: `"${name}" returned status ${response.status}: ${reason}`,
|
|
224
|
+
hint: response.status === 400
|
|
225
|
+
? "Check the model name saved for this provider — it must be one this endpoint actually serves — then the request. The provider's own message above usually names the field."
|
|
226
|
+
: "Check the request and this provider's saved API key.",
|
|
227
|
+
details: { status: response.status, ...(reason === undefined ? {} : { reason }) },
|
|
136
228
|
});
|
|
137
229
|
}
|
|
138
230
|
const body = (await response.json());
|
|
139
|
-
return parseOpenAiResponse(body);
|
|
231
|
+
return parseOpenAiResponse(body, createToolNameDecoder(request));
|
|
140
232
|
},
|
|
141
233
|
};
|
|
142
234
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,31 +1,48 @@
|
|
|
1
|
+
import type { ProviderTuningDefaults } from './defaults.js';
|
|
1
2
|
import type { ProviderClient } from './types.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
readonly
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Fiche 56: `provider` used to be a closed 3-literal union
|
|
5
|
+
* (`'anthropic' | 'openai' | 'google'`) — every fourth vendor (OpenRouter,
|
|
6
|
+
* DeepSeek, Qwen, GLM, a self-hosted OpenAI-compatible endpoint) needed a
|
|
7
|
+
* code change to even be expressible. It is now a plain string, validated at
|
|
8
|
+
* the write boundary (`store.ts`'s `upsert` and the `/api/providers` router),
|
|
9
|
+
* not by a type. `@cogenta/core`'s own `llmSchema.provider` was already a
|
|
10
|
+
* free string before this fiche — this only catches the registry up to a
|
|
11
|
+
* looseness the config schema already had.
|
|
12
|
+
*/
|
|
13
|
+
export type ProviderName = string;
|
|
14
|
+
export interface ProviderEntryConfig {
|
|
15
|
+
readonly apiKey: string;
|
|
16
|
+
readonly model: string;
|
|
17
|
+
/**
|
|
18
|
+
* Overrides `catalog.ts`'s `defaultBaseUrl` for a known provider (e.g. a
|
|
19
|
+
* self-hosted proxy in front of OpenAI), or — for a provider id absent
|
|
20
|
+
* from the catalog entirely — is what makes it resolvable at all: an
|
|
21
|
+
* unknown id with no `baseUrl` cannot be turned into a client (see
|
|
22
|
+
* `buildClient` below).
|
|
23
|
+
*/
|
|
24
|
+
readonly baseUrl?: string;
|
|
25
|
+
/** See `ProviderClient.maxOutputTokens` — the admin's value for this provider, or absent to fall back to the registry's own `defaults`. */
|
|
26
|
+
readonly maxOutputTokens?: number;
|
|
27
|
+
/** See `ProviderClient.requestTimeoutMs`. */
|
|
28
|
+
readonly requestTimeoutMs?: number;
|
|
29
|
+
/** See `ProviderClient.maxCorrectionAttempts`. */
|
|
30
|
+
readonly maxCorrectionAttempts?: number;
|
|
20
31
|
}
|
|
32
|
+
export type ProviderRegistryConfig = Readonly<Record<string, ProviderEntryConfig>>;
|
|
21
33
|
/**
|
|
22
34
|
* One client per configured vendor — a site with no LLM provider configured
|
|
23
35
|
* simply has an empty registry, which is exactly what rule R2 requires ("le
|
|
24
36
|
* CMS fonctionne sans IA"): nothing here fails to construct, `get()` is what
|
|
25
37
|
* refuses, and only once an agent actually tries to run.
|
|
38
|
+
*
|
|
39
|
+
* `defaults` is the site-wide tuning floor (`resolveProviderTuningDefaults`,
|
|
40
|
+
* `assistant.*` site settings) every entry's own per-provider override falls
|
|
41
|
+
* back to — required, so no adapter this registry builds can ever fall back
|
|
42
|
+
* to a hardcoded constant instead.
|
|
26
43
|
*/
|
|
27
|
-
export declare function createProviderRegistry(config: ProviderRegistryConfig): {
|
|
28
|
-
readonly get: (name:
|
|
29
|
-
readonly has: (name:
|
|
44
|
+
export declare function createProviderRegistry(config: ProviderRegistryConfig, defaults: ProviderTuningDefaults): {
|
|
45
|
+
readonly get: (name: string) => ProviderClient;
|
|
46
|
+
readonly has: (name: string) => boolean;
|
|
30
47
|
};
|
|
31
48
|
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAG3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAA;AAEjC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,2IAA2I;IAC3I,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,6CAA6C;IAC7C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAClC,kDAAkD;IAClD,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAA;CACxC;AAED,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAA;AA+DlF;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,sBAAsB,EAC9B,QAAQ,EAAE,sBAAsB,GAC/B;IACD,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,cAAc,CAAA;IAC9C,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;CACxC,CAoBA"}
|
|
@@ -1,22 +1,78 @@
|
|
|
1
1
|
import { CogentaError } from '@cogenta/core';
|
|
2
2
|
import { createAnthropicClient } from './anthropic.js';
|
|
3
|
+
import { findProviderCatalogEntry } from './catalog.js';
|
|
3
4
|
import { createGoogleClient } from './google.js';
|
|
4
5
|
import { createOpenAiClient } from './openai.js';
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* One provider entry → one client. A catalog id picks the adapter
|
|
8
|
+
* (`wireFormat`); a name the catalog does not know is only usable if the
|
|
9
|
+
* entry carries its own `baseUrl` — that is what "custom OpenAI-compatible
|
|
10
|
+
* endpoint" means structurally, not a separate `custom: true` flag to keep
|
|
11
|
+
* in sync with this lookup.
|
|
12
|
+
*/
|
|
13
|
+
function buildClient(name, entry, defaults) {
|
|
14
|
+
const catalogEntry = findProviderCatalogEntry(name);
|
|
15
|
+
const tuning = {
|
|
16
|
+
...(entry.maxOutputTokens === undefined ? {} : { maxOutputTokens: entry.maxOutputTokens }),
|
|
17
|
+
...(entry.requestTimeoutMs === undefined ? {} : { requestTimeoutMs: entry.requestTimeoutMs }),
|
|
18
|
+
...(entry.maxCorrectionAttempts === undefined
|
|
19
|
+
? {}
|
|
20
|
+
: { maxCorrectionAttempts: entry.maxCorrectionAttempts }),
|
|
21
|
+
};
|
|
22
|
+
if (catalogEntry?.wireFormat === 'anthropic') {
|
|
23
|
+
return createAnthropicClient({
|
|
24
|
+
apiKey: entry.apiKey,
|
|
25
|
+
model: entry.model,
|
|
26
|
+
...(entry.baseUrl === undefined ? {} : { baseUrl: entry.baseUrl }),
|
|
27
|
+
...tuning,
|
|
28
|
+
defaults,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (catalogEntry?.wireFormat === 'google') {
|
|
32
|
+
return createGoogleClient({
|
|
33
|
+
apiKey: entry.apiKey,
|
|
34
|
+
model: entry.model,
|
|
35
|
+
...(entry.baseUrl === undefined ? {} : { baseUrl: entry.baseUrl }),
|
|
36
|
+
...tuning,
|
|
37
|
+
defaults,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
// `wireFormat: 'openai-compatible'` (OpenAI itself, OpenRouter, DeepSeek,
|
|
41
|
+
// Qwen, GLM) and any id absent from the catalog share this one branch —
|
|
42
|
+
// exactly the "zero new network code" the fiche asks for.
|
|
43
|
+
const baseUrl = entry.baseUrl ?? catalogEntry?.defaultBaseUrl;
|
|
44
|
+
if (baseUrl === undefined) {
|
|
45
|
+
throw new CogentaError({
|
|
46
|
+
code: 'PROVIDER_CUSTOM_BASE_URL_REQUIRED',
|
|
47
|
+
message: `"${name}" is not a built-in provider and has no "baseUrl" configured.`,
|
|
48
|
+
hint: 'Set a baseUrl for a custom OpenAI-compatible endpoint, or use a catalog provider id.',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return createOpenAiClient({
|
|
52
|
+
apiKey: entry.apiKey,
|
|
53
|
+
model: entry.model,
|
|
54
|
+
baseUrl,
|
|
55
|
+
name,
|
|
56
|
+
...tuning,
|
|
57
|
+
defaults,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
6
60
|
/**
|
|
7
61
|
* One client per configured vendor — a site with no LLM provider configured
|
|
8
62
|
* simply has an empty registry, which is exactly what rule R2 requires ("le
|
|
9
63
|
* CMS fonctionne sans IA"): nothing here fails to construct, `get()` is what
|
|
10
64
|
* refuses, and only once an agent actually tries to run.
|
|
65
|
+
*
|
|
66
|
+
* `defaults` is the site-wide tuning floor (`resolveProviderTuningDefaults`,
|
|
67
|
+
* `assistant.*` site settings) every entry's own per-provider override falls
|
|
68
|
+
* back to — required, so no adapter this registry builds can ever fall back
|
|
69
|
+
* to a hardcoded constant instead.
|
|
11
70
|
*/
|
|
12
|
-
export function createProviderRegistry(config) {
|
|
71
|
+
export function createProviderRegistry(config, defaults) {
|
|
13
72
|
const clients = new Map();
|
|
14
|
-
|
|
15
|
-
clients.set(
|
|
16
|
-
|
|
17
|
-
clients.set('openai', createOpenAiClient(config.openai));
|
|
18
|
-
if (config.google !== undefined)
|
|
19
|
-
clients.set('google', createGoogleClient(config.google));
|
|
73
|
+
for (const [name, entry] of Object.entries(config)) {
|
|
74
|
+
clients.set(name, buildClient(name, entry, defaults));
|
|
75
|
+
}
|
|
20
76
|
return {
|
|
21
77
|
has: (name) => clients.has(name),
|
|
22
78
|
get(name) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The caller's own signal (if any) combined with a timeout floor, so a
|
|
3
|
+
* cancellation the run loop already wants (budget exceeded, kill switch)
|
|
4
|
+
* still works exactly as before, and an otherwise-uncancelled call still
|
|
5
|
+
* gives up eventually.
|
|
6
|
+
*
|
|
7
|
+
* `timeoutMs` is required — every real caller (the three provider adapters)
|
|
8
|
+
* always resolves a concrete `requestTimeoutMs` before calling this
|
|
9
|
+
* (`ProviderClient.requestTimeoutMs`, itself always a number: the admin's
|
|
10
|
+
* per-provider override or the site-wide `assistant.defaultRequestTimeoutSeconds`
|
|
11
|
+
* floor, `SITE_SETTINGS_REGISTRY` in `@cogenta/schema`). This function used
|
|
12
|
+
* to default it to a `DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS` constant — fiche
|
|
13
|
+
* feedback: that hid a real site behaviour (what happens when a call to a
|
|
14
|
+
* stalled vendor never returns — reproduced live once, see the changeset
|
|
15
|
+
* history) behind a number nothing but this file's own comment ever named.
|
|
16
|
+
*/
|
|
17
|
+
export declare function requestSignalWithTimeout(callerSignal: AbortSignal | undefined, timeoutMs: number): AbortSignal;
|
|
18
|
+
//# sourceMappingURL=request-signal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-signal.d.ts","sourceRoot":"","sources":["../../src/providers/request-signal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,WAAW,GAAG,SAAS,EACrC,SAAS,EAAE,MAAM,GAChB,WAAW,CAGb"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The caller's own signal (if any) combined with a timeout floor, so a
|
|
3
|
+
* cancellation the run loop already wants (budget exceeded, kill switch)
|
|
4
|
+
* still works exactly as before, and an otherwise-uncancelled call still
|
|
5
|
+
* gives up eventually.
|
|
6
|
+
*
|
|
7
|
+
* `timeoutMs` is required — every real caller (the three provider adapters)
|
|
8
|
+
* always resolves a concrete `requestTimeoutMs` before calling this
|
|
9
|
+
* (`ProviderClient.requestTimeoutMs`, itself always a number: the admin's
|
|
10
|
+
* per-provider override or the site-wide `assistant.defaultRequestTimeoutSeconds`
|
|
11
|
+
* floor, `SITE_SETTINGS_REGISTRY` in `@cogenta/schema`). This function used
|
|
12
|
+
* to default it to a `DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS` constant — fiche
|
|
13
|
+
* feedback: that hid a real site behaviour (what happens when a call to a
|
|
14
|
+
* stalled vendor never returns — reproduced live once, see the changeset
|
|
15
|
+
* history) behind a number nothing but this file's own comment ever named.
|
|
16
|
+
*/
|
|
17
|
+
export function requestSignalWithTimeout(callerSignal, timeoutMs) {
|
|
18
|
+
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
19
|
+
return callerSignal === undefined ? timeoutSignal : AbortSignal.any([callerSignal, timeoutSignal]);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=request-signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-signal.js","sourceRoot":"","sources":["../../src/providers/request-signal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,wBAAwB,CACtC,YAAqC,EACrC,SAAiB;IAEjB,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACpD,OAAO,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAA;AACpG,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ProviderRegistryConfig } from './registry.js';
|
|
2
|
+
import type { ProviderConfigStore } from './store.js';
|
|
3
|
+
/**
|
|
4
|
+
* Turns the persisted, encrypted `ProviderConfigStore` into the plaintext
|
|
5
|
+
* shape `createProviderRegistry` needs — the one place a key is decrypted
|
|
6
|
+
* for actual use (R7: never logged, never returned from this function's
|
|
7
|
+
* caller over the wire). A provider with no saved key, or saved but
|
|
8
|
+
* disabled, is simply absent from the result — exactly R2's "no provider
|
|
9
|
+
* configured" state `createProviderRegistry`'s own doc comment already
|
|
10
|
+
* describes.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveProviderRegistryConfig(store: ProviderConfigStore): Promise<ProviderRegistryConfig>;
|
|
13
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/providers/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAErD;;;;;;;;GAQG;AACH,wBAAsB,6BAA6B,CACjD,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,sBAAsB,CAAC,CA4BjC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns the persisted, encrypted `ProviderConfigStore` into the plaintext
|
|
3
|
+
* shape `createProviderRegistry` needs — the one place a key is decrypted
|
|
4
|
+
* for actual use (R7: never logged, never returned from this function's
|
|
5
|
+
* caller over the wire). A provider with no saved key, or saved but
|
|
6
|
+
* disabled, is simply absent from the result — exactly R2's "no provider
|
|
7
|
+
* configured" state `createProviderRegistry`'s own doc comment already
|
|
8
|
+
* describes.
|
|
9
|
+
*/
|
|
10
|
+
export async function resolveProviderRegistryConfig(store) {
|
|
11
|
+
const configs = await store.list();
|
|
12
|
+
const config = {};
|
|
13
|
+
for (const entry of configs) {
|
|
14
|
+
if (!entry.enabled)
|
|
15
|
+
continue;
|
|
16
|
+
const apiKey = await store.decryptKey(entry.provider);
|
|
17
|
+
config[entry.provider] = {
|
|
18
|
+
apiKey,
|
|
19
|
+
model: entry.model,
|
|
20
|
+
...(entry.baseUrl === undefined ? {} : { baseUrl: entry.baseUrl }),
|
|
21
|
+
...(entry.maxOutputTokens === undefined ? {} : { maxOutputTokens: entry.maxOutputTokens }),
|
|
22
|
+
...(entry.requestTimeoutMs === undefined ? {} : { requestTimeoutMs: entry.requestTimeoutMs }),
|
|
23
|
+
...(entry.maxCorrectionAttempts === undefined
|
|
24
|
+
? {}
|
|
25
|
+
: { maxCorrectionAttempts: entry.maxCorrectionAttempts }),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return config;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/providers/resolve.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,KAA0B;IAE1B,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;IAClC,MAAM,MAAM,GAUR,EAAE,CAAA;IACN,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,SAAQ;QAC5B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QACrD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG;YACvB,MAAM;YACN,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;YAClE,GAAG,CAAC,KAAK,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE,CAAC;YAC1F,GAAG,CAAC,KAAK,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC;YAC7F,GAAG,CAAC,KAAK,CAAC,qBAAqB,KAAK,SAAS;gBAC3C,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,qBAAqB,EAAE,KAAK,CAAC,qBAAqB,EAAE,CAAC;SAC5D,CAAA;IACH,CAAC;IACD,OAAO,MAAgC,CAAA;AACzC,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { ProviderName } from './registry.js';
|
|
2
|
+
export interface StoredProviderConfig {
|
|
3
|
+
readonly provider: ProviderName;
|
|
4
|
+
readonly enabled: boolean;
|
|
5
|
+
readonly model: string;
|
|
6
|
+
readonly baseUrl?: string;
|
|
7
|
+
/** Last 4 characters of the real key, for the admin to confirm which key is saved without ever re-displaying it in full. */
|
|
8
|
+
readonly maskedKey: string;
|
|
9
|
+
readonly updatedAt: string;
|
|
10
|
+
/**
|
|
11
|
+
* The completion budget (`ProviderClient.maxOutputTokens`), request retry
|
|
12
|
+
* count (`maxCorrectionAttempts`) and HTTP/agent-loop timeout
|
|
13
|
+
* (`requestTimeoutMs`, milliseconds) this provider's client resolves to.
|
|
14
|
+
* Absent means "use the built-in fallback" (`resolve.ts`) — every one of
|
|
15
|
+
* these was, before this admin surface existed, a number hardcoded per
|
|
16
|
+
* call site with no way for an admin to say "this particular model needs
|
|
17
|
+
* more room to think" (the exact bug a real reasoning-model run
|
|
18
|
+
* reproduced: DeepSeek's `deepseek-v4-flash` silently truncated to an
|
|
19
|
+
* empty response at a too-low hardcoded ceiling).
|
|
20
|
+
*/
|
|
21
|
+
readonly maxOutputTokens?: number;
|
|
22
|
+
readonly requestTimeoutMs?: number;
|
|
23
|
+
readonly maxCorrectionAttempts?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface ProviderConfigInput {
|
|
26
|
+
readonly provider: ProviderName;
|
|
27
|
+
readonly apiKey: string;
|
|
28
|
+
readonly model: string;
|
|
29
|
+
readonly baseUrl?: string;
|
|
30
|
+
readonly enabled?: boolean;
|
|
31
|
+
readonly maxOutputTokens?: number;
|
|
32
|
+
readonly requestTimeoutMs?: number;
|
|
33
|
+
readonly maxCorrectionAttempts?: number;
|
|
34
|
+
}
|
|
35
|
+
export interface ProviderConfigStore {
|
|
36
|
+
list(): Promise<readonly StoredProviderConfig[]>;
|
|
37
|
+
get(provider: ProviderName): Promise<StoredProviderConfig | undefined>;
|
|
38
|
+
/** Encrypts and persists `apiKey`; creates or overwrites this provider's one record. */
|
|
39
|
+
upsert(input: ProviderConfigInput): Promise<StoredProviderConfig>;
|
|
40
|
+
setEnabled(provider: ProviderName, enabled: boolean): Promise<StoredProviderConfig>;
|
|
41
|
+
/**
|
|
42
|
+
* Changes `model`/`baseUrl`/tuning without touching the saved key — so an
|
|
43
|
+
* admin can adjust any of these, including *after* the first save,
|
|
44
|
+
* without being made to re-paste an API key they may no longer have
|
|
45
|
+
* handy. `undefined` on a tuning field leaves it as saved; `null`
|
|
46
|
+
* explicitly clears it back to "use the built-in default" (the one thing
|
|
47
|
+
* a plain optional field can't express — leaving it out of the patch and
|
|
48
|
+
* clearing it back to unset need distinct wire shapes). Throws
|
|
49
|
+
* `PROVIDER_NOT_CONFIGURED` if this provider has no saved key yet.
|
|
50
|
+
*/
|
|
51
|
+
updateSettings(provider: ProviderName, patch: {
|
|
52
|
+
readonly model?: string;
|
|
53
|
+
readonly baseUrl?: string;
|
|
54
|
+
readonly maxOutputTokens?: number | null;
|
|
55
|
+
readonly requestTimeoutMs?: number | null;
|
|
56
|
+
readonly maxCorrectionAttempts?: number | null;
|
|
57
|
+
}): Promise<StoredProviderConfig>;
|
|
58
|
+
remove(provider: ProviderName): Promise<void>;
|
|
59
|
+
/** The one place the real key is ever decrypted — never exposed on `StoredProviderConfig` itself. Throws `PROVIDER_NOT_CONFIGURED` if this provider has no saved key. */
|
|
60
|
+
decryptKey(provider: ProviderName): Promise<string>;
|
|
61
|
+
}
|
|
62
|
+
export interface FileProviderConfigStoreOptions {
|
|
63
|
+
readonly dir: string;
|
|
64
|
+
/** `COGENTA_AUTH_SIGNING_KEY` — the encryption key is derived from it, never stored itself. */
|
|
65
|
+
readonly signingKey: string;
|
|
66
|
+
readonly now?: () => Date;
|
|
67
|
+
}
|
|
68
|
+
/** One `<provider>.json` record per configured provider, under `options.dir` — the same one-file-per-record shape every other file store in this package uses (R1: no external service). */
|
|
69
|
+
export declare function createFileProviderConfigStore(options: FileProviderConfigStoreOptions): ProviderConfigStore;
|
|
70
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/providers/store.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAqEjD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,4HAA4H;IAC5H,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAA;CACxC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAA;CACxC;AA+BD,MAAM,WAAW,mBAAmB;IAClC,IAAI,IAAI,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAAA;IAChD,GAAG,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAA;IACtE,wFAAwF;IACxF,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACjE,UAAU,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACnF;;;;;;;;;OASG;IACH,cAAc,CACZ,QAAQ,EAAE,YAAY,EACtB,KAAK,EAAE;QACL,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACxC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAC/C,GACA,OAAO,CAAC,oBAAoB,CAAC,CAAA;IAChC,MAAM,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7C,yKAAyK;IACzK,UAAU,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACpD;AAqDD,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,+FAA+F;IAC/F,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CAC1B;AAED,4LAA4L;AAC5L,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,8BAA8B,GACtC,mBAAmB,CAmMrB"}
|