@lcv-ideas-software/cross-review 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.
Files changed (122) hide show
  1. package/CHANGELOG.md +2568 -0
  2. package/LICENSE +201 -0
  3. package/NOTICE +26 -0
  4. package/README.md +208 -0
  5. package/SECURITY.md +52 -0
  6. package/dist/scripts/api-streaming-smoke.d.ts +1 -0
  7. package/dist/scripts/api-streaming-smoke.js +78 -0
  8. package/dist/scripts/api-streaming-smoke.js.map +1 -0
  9. package/dist/scripts/runtime-default-smoke.d.ts +1 -0
  10. package/dist/scripts/runtime-default-smoke.js +88 -0
  11. package/dist/scripts/runtime-default-smoke.js.map +1 -0
  12. package/dist/scripts/runtime-smoke.d.ts +1 -0
  13. package/dist/scripts/runtime-smoke.js +148 -0
  14. package/dist/scripts/runtime-smoke.js.map +1 -0
  15. package/dist/scripts/smoke.d.ts +1 -0
  16. package/dist/scripts/smoke.js +6156 -0
  17. package/dist/scripts/smoke.js.map +1 -0
  18. package/dist/src/core/cache-manifest.d.ts +22 -0
  19. package/dist/src/core/cache-manifest.js +133 -0
  20. package/dist/src/core/cache-manifest.js.map +1 -0
  21. package/dist/src/core/caller-tokens.d.ts +32 -0
  22. package/dist/src/core/caller-tokens.js +240 -0
  23. package/dist/src/core/caller-tokens.js.map +1 -0
  24. package/dist/src/core/config.d.ts +9 -0
  25. package/dist/src/core/config.js +643 -0
  26. package/dist/src/core/config.js.map +1 -0
  27. package/dist/src/core/convergence.d.ts +5 -0
  28. package/dist/src/core/convergence.js +186 -0
  29. package/dist/src/core/convergence.js.map +1 -0
  30. package/dist/src/core/cost.d.ts +59 -0
  31. package/dist/src/core/cost.js +359 -0
  32. package/dist/src/core/cost.js.map +1 -0
  33. package/dist/src/core/file-config.d.ts +316 -0
  34. package/dist/src/core/file-config.js +490 -0
  35. package/dist/src/core/file-config.js.map +1 -0
  36. package/dist/src/core/orchestrator.d.ts +199 -0
  37. package/dist/src/core/orchestrator.js +3430 -0
  38. package/dist/src/core/orchestrator.js.map +1 -0
  39. package/dist/src/core/prompt-parts.d.ts +58 -0
  40. package/dist/src/core/prompt-parts.js +122 -0
  41. package/dist/src/core/prompt-parts.js.map +1 -0
  42. package/dist/src/core/relator-lottery.d.ts +23 -0
  43. package/dist/src/core/relator-lottery.js +112 -0
  44. package/dist/src/core/relator-lottery.js.map +1 -0
  45. package/dist/src/core/reports.d.ts +2 -0
  46. package/dist/src/core/reports.js +82 -0
  47. package/dist/src/core/reports.js.map +1 -0
  48. package/dist/src/core/session-store.d.ts +149 -0
  49. package/dist/src/core/session-store.js +1923 -0
  50. package/dist/src/core/session-store.js.map +1 -0
  51. package/dist/src/core/status.d.ts +61 -0
  52. package/dist/src/core/status.js +249 -0
  53. package/dist/src/core/status.js.map +1 -0
  54. package/dist/src/core/timeouts.d.ts +2 -0
  55. package/dist/src/core/timeouts.js +3 -0
  56. package/dist/src/core/timeouts.js.map +1 -0
  57. package/dist/src/core/types.d.ts +604 -0
  58. package/dist/src/core/types.js +36 -0
  59. package/dist/src/core/types.js.map +1 -0
  60. package/dist/src/dashboard/server.d.ts +2 -0
  61. package/dist/src/dashboard/server.js +339 -0
  62. package/dist/src/dashboard/server.js.map +1 -0
  63. package/dist/src/mcp/server.d.ts +54 -0
  64. package/dist/src/mcp/server.js +1584 -0
  65. package/dist/src/mcp/server.js.map +1 -0
  66. package/dist/src/observability/logger.d.ts +9 -0
  67. package/dist/src/observability/logger.js +24 -0
  68. package/dist/src/observability/logger.js.map +1 -0
  69. package/dist/src/peers/anthropic.d.ts +14 -0
  70. package/dist/src/peers/anthropic.js +290 -0
  71. package/dist/src/peers/anthropic.js.map +1 -0
  72. package/dist/src/peers/base.d.ts +72 -0
  73. package/dist/src/peers/base.js +416 -0
  74. package/dist/src/peers/base.js.map +1 -0
  75. package/dist/src/peers/deepseek.d.ts +12 -0
  76. package/dist/src/peers/deepseek.js +246 -0
  77. package/dist/src/peers/deepseek.js.map +1 -0
  78. package/dist/src/peers/errors.d.ts +2 -0
  79. package/dist/src/peers/errors.js +185 -0
  80. package/dist/src/peers/errors.js.map +1 -0
  81. package/dist/src/peers/gemini.d.ts +13 -0
  82. package/dist/src/peers/gemini.js +215 -0
  83. package/dist/src/peers/gemini.js.map +1 -0
  84. package/dist/src/peers/grok.d.ts +17 -0
  85. package/dist/src/peers/grok.js +346 -0
  86. package/dist/src/peers/grok.js.map +1 -0
  87. package/dist/src/peers/model-selection.d.ts +4 -0
  88. package/dist/src/peers/model-selection.js +260 -0
  89. package/dist/src/peers/model-selection.js.map +1 -0
  90. package/dist/src/peers/openai.d.ts +14 -0
  91. package/dist/src/peers/openai.js +299 -0
  92. package/dist/src/peers/openai.js.map +1 -0
  93. package/dist/src/peers/perplexity.d.ts +18 -0
  94. package/dist/src/peers/perplexity.js +375 -0
  95. package/dist/src/peers/perplexity.js.map +1 -0
  96. package/dist/src/peers/registry.d.ts +3 -0
  97. package/dist/src/peers/registry.js +77 -0
  98. package/dist/src/peers/registry.js.map +1 -0
  99. package/dist/src/peers/retry.d.ts +2 -0
  100. package/dist/src/peers/retry.js +36 -0
  101. package/dist/src/peers/retry.js.map +1 -0
  102. package/dist/src/peers/stub.d.ts +13 -0
  103. package/dist/src/peers/stub.js +344 -0
  104. package/dist/src/peers/stub.js.map +1 -0
  105. package/dist/src/peers/text.d.ts +18 -0
  106. package/dist/src/peers/text.js +39 -0
  107. package/dist/src/peers/text.js.map +1 -0
  108. package/dist/src/security/redact.d.ts +2 -0
  109. package/dist/src/security/redact.js +128 -0
  110. package/dist/src/security/redact.js.map +1 -0
  111. package/docs/api-keys.md +34 -0
  112. package/docs/architecture.md +118 -0
  113. package/docs/caching.md +135 -0
  114. package/docs/costs.md +40 -0
  115. package/docs/evidence-preflight.md +88 -0
  116. package/docs/github-security-baseline.md +32 -0
  117. package/docs/model-selection.md +105 -0
  118. package/docs/reports/cross-review-v2-api-capability-smoke-2026-04-30.md +354 -0
  119. package/docs/reports/cross-review-v2-format-recovery-findings-2026-04-28.md +223 -0
  120. package/docs/reports/cross-review-v2-official-provider-docs-refresh-2026-05-05.md +60 -0
  121. package/docs/reports/cross-review-v2-token-streaming-smoke-2026-04-30.md +119 -0
  122. package/package.json +88 -0
@@ -0,0 +1,246 @@
1
+ import { statusInstruction } from "../core/status.js";
2
+ import { BasePeerAdapter, StreamBuffer } from "./base.js";
3
+ import { classifyProviderError } from "./errors.js";
4
+ import { loadOpenAICtor } from "./openai.js";
5
+ import { withRetry } from "./retry.js";
6
+ import { userPrompt } from "./text.js";
7
+ function usageFromChat(usage) {
8
+ if (!usage)
9
+ return undefined;
10
+ const cacheHit = usage.prompt_cache_hit_tokens ?? 0;
11
+ const cacheMiss = usage.prompt_cache_miss_tokens ?? 0;
12
+ const result = {
13
+ input_tokens: usage.prompt_tokens,
14
+ output_tokens: usage.completion_tokens,
15
+ total_tokens: usage.total_tokens,
16
+ reasoning_tokens: usage.completion_tokens_details?.reasoning_tokens,
17
+ };
18
+ if (cacheHit > 0 || cacheMiss > 0) {
19
+ if (cacheHit > 0)
20
+ result.cache_read_tokens = cacheHit;
21
+ if (cacheMiss > 0)
22
+ result.cache_write_tokens = cacheMiss;
23
+ result.cache_provider_mode = "auto";
24
+ }
25
+ return result;
26
+ }
27
+ function chatText(response) {
28
+ return response.choices?.[0]?.message?.content?.trim() || JSON.stringify(response);
29
+ }
30
+ function deepSeekReasoningEffort(value) {
31
+ return value === "max" || value === "xhigh" ? "max" : "high";
32
+ }
33
+ function deepSeekThinking(config, override) {
34
+ return {
35
+ thinking: {
36
+ type: "enabled",
37
+ reasoning_effort: deepSeekReasoningEffort(override ?? config.reasoning_effort.deepseek),
38
+ },
39
+ };
40
+ }
41
+ export class DeepSeekAdapter extends BasePeerAdapter {
42
+ id = "deepseek";
43
+ provider = "deepseek";
44
+ model;
45
+ constructor(config, modelOverride) {
46
+ super(config);
47
+ this.model = modelOverride ?? config.models.deepseek;
48
+ }
49
+ async client() {
50
+ const apiKey = this.config.api_keys.deepseek;
51
+ if (!apiKey)
52
+ throw new Error("DEEPSEEK_API_KEY was not found in environment variables.");
53
+ const Ctor = await loadOpenAICtor();
54
+ return new Ctor({ apiKey, baseURL: "https://api.deepseek.com" });
55
+ }
56
+ async probe() {
57
+ const started = Date.now();
58
+ const authPresent = Boolean(this.config.api_keys.deepseek);
59
+ if (!authPresent) {
60
+ return {
61
+ peer: this.id,
62
+ provider: this.provider,
63
+ model: this.model,
64
+ available: false,
65
+ auth_present: false,
66
+ latency_ms: Date.now() - started,
67
+ model_selection: this.config.model_selection.deepseek,
68
+ message: "DEEPSEEK_API_KEY is missing.",
69
+ };
70
+ }
71
+ try {
72
+ const probeClient = await this.client();
73
+ await probeClient.models.list({ timeout: this.config.retry.timeout_ms });
74
+ return {
75
+ peer: this.id,
76
+ provider: this.provider,
77
+ model: this.model,
78
+ available: true,
79
+ auth_present: true,
80
+ latency_ms: Date.now() - started,
81
+ model_selection: this.config.model_selection.deepseek,
82
+ };
83
+ }
84
+ catch (error) {
85
+ const failure = classifyProviderError(this.id, this.provider, this.model, error, 1, started);
86
+ return {
87
+ peer: this.id,
88
+ provider: this.provider,
89
+ model: this.model,
90
+ available: false,
91
+ auth_present: true,
92
+ latency_ms: Date.now() - started,
93
+ model_selection: this.config.model_selection.deepseek,
94
+ message: failure.message,
95
+ };
96
+ }
97
+ }
98
+ async call(prompt, context) {
99
+ const started = Date.now();
100
+ return withRetry(this.config, async (attempt) => {
101
+ context.emit({
102
+ type: "peer.call.started",
103
+ session_id: context.session_id,
104
+ round: context.round,
105
+ peer: this.id,
106
+ message: `DeepSeek review attempt ${attempt}`,
107
+ });
108
+ const payload = {
109
+ ...deepSeekThinking(this.config, context.reasoning_effort_override),
110
+ model: this.model,
111
+ messages: [
112
+ { role: "system", content: this.systemPrompt(context) },
113
+ { role: "user", content: `${userPrompt(prompt)}\n\n${statusInstruction()}` },
114
+ ],
115
+ response_format: { type: "json_object" },
116
+ max_tokens: this.config.max_output_tokens,
117
+ };
118
+ // DeepSeek's OpenAI-compatible API accepts the non-OpenAI `thinking` body field;
119
+ // the OpenAI JS client forwards unknown body keys, and the real API smoke verifies it.
120
+ if (this.shouldStreamTokens(context)) {
121
+ const streamPayload = {
122
+ ...payload,
123
+ stream: true,
124
+ stream_options: { include_usage: true },
125
+ };
126
+ const reviewClient = await this.client();
127
+ const stream = await reviewClient.chat.completions.create(streamPayload, {
128
+ signal: context.signal,
129
+ timeout: this.config.retry.timeout_ms,
130
+ });
131
+ const stream_buffer = new StreamBuffer(this.id);
132
+ const tokenStream = this.createTokenEventBuffer(context, "review", "chat.completion.chunk.delta");
133
+ let usage;
134
+ let modelReported;
135
+ let chunks = 0;
136
+ for await (const chunk of stream) {
137
+ chunks += 1;
138
+ modelReported = chunk.model ?? modelReported;
139
+ usage = usageFromChat(chunk.usage) ?? usage;
140
+ for (const choice of chunk.choices ?? []) {
141
+ const delta = choice.delta?.content ?? "";
142
+ stream_buffer.append(delta);
143
+ tokenStream.append(delta);
144
+ }
145
+ }
146
+ const text = stream_buffer.text();
147
+ tokenStream.complete(text.length);
148
+ return this.resultFromText({
149
+ text,
150
+ raw: { streamed: true, provider: this.provider, chunks, model: modelReported },
151
+ usage,
152
+ started,
153
+ attempts: attempt,
154
+ modelReported,
155
+ });
156
+ }
157
+ const reviewClient = await this.client();
158
+ const response = await reviewClient.chat.completions.create(payload, {
159
+ signal: context.signal,
160
+ timeout: this.config.retry.timeout_ms,
161
+ });
162
+ return this.resultFromText({
163
+ text: chatText(response),
164
+ raw: response,
165
+ usage: usageFromChat(response.usage),
166
+ started,
167
+ attempts: attempt,
168
+ modelReported: response.model,
169
+ });
170
+ }, (error, attempt) => classifyProviderError(this.id, this.provider, this.model, error, attempt, started));
171
+ }
172
+ async generate(prompt, context) {
173
+ const started = Date.now();
174
+ return withRetry(this.config, async (attempt) => {
175
+ context.emit({
176
+ type: "peer.generate.started",
177
+ session_id: context.session_id,
178
+ round: context.round,
179
+ peer: this.id,
180
+ message: `DeepSeek generation attempt ${attempt}`,
181
+ });
182
+ const payload = {
183
+ ...deepSeekThinking(this.config, context.reasoning_effort_override),
184
+ model: this.model,
185
+ messages: [
186
+ { role: "system", content: this.systemPrompt(context) },
187
+ { role: "user", content: userPrompt(prompt) },
188
+ ],
189
+ max_tokens: this.config.max_output_tokens,
190
+ };
191
+ // DeepSeek's OpenAI-compatible API accepts the non-OpenAI `thinking` body field;
192
+ // the OpenAI JS client forwards unknown body keys, and the real API smoke verifies it.
193
+ if (this.shouldStreamTokens(context)) {
194
+ const streamPayload = {
195
+ ...payload,
196
+ stream: true,
197
+ stream_options: { include_usage: true },
198
+ };
199
+ const generateClient = await this.client();
200
+ const stream = await generateClient.chat.completions.create(streamPayload, {
201
+ signal: context.signal,
202
+ timeout: this.config.retry.timeout_ms,
203
+ });
204
+ const stream_buffer = new StreamBuffer(this.id);
205
+ const tokenStream = this.createTokenEventBuffer(context, "generation", "chat.completion.chunk.delta");
206
+ let usage;
207
+ let modelReported;
208
+ let chunks = 0;
209
+ for await (const chunk of stream) {
210
+ chunks += 1;
211
+ modelReported = chunk.model ?? modelReported;
212
+ usage = usageFromChat(chunk.usage) ?? usage;
213
+ for (const choice of chunk.choices ?? []) {
214
+ const delta = choice.delta?.content ?? "";
215
+ stream_buffer.append(delta);
216
+ tokenStream.append(delta);
217
+ }
218
+ }
219
+ const text = stream_buffer.text();
220
+ tokenStream.complete(text.length);
221
+ return this.generationFromText({
222
+ text,
223
+ raw: { streamed: true, provider: this.provider, chunks, model: modelReported },
224
+ usage,
225
+ started,
226
+ attempts: attempt,
227
+ modelReported,
228
+ });
229
+ }
230
+ const generateClient = await this.client();
231
+ const response = await generateClient.chat.completions.create(payload, {
232
+ signal: context.signal,
233
+ timeout: this.config.retry.timeout_ms,
234
+ });
235
+ return this.generationFromText({
236
+ text: chatText(response),
237
+ raw: response,
238
+ usage: usageFromChat(response.usage),
239
+ started,
240
+ attempts: attempt,
241
+ modelReported: response.model,
242
+ });
243
+ }, (error, attempt) => classifyProviderError(this.id, this.provider, this.model, error, attempt, started));
244
+ }
245
+ }
246
+ //# sourceMappingURL=deepseek.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deepseek.js","sourceRoot":"","sources":["../../../src/peers/deepseek.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { PeerFailure, PeerId } from "../core/types.js";
2
+ export declare function classifyProviderError(peer: PeerId, provider: string, model: string, error: unknown, attempts: number, started: number): PeerFailure;
@@ -0,0 +1,185 @@
1
+ import { safeErrorMessage } from "../security/redact.js";
2
+ // v2.4.0 / audit closure (P2.7): extract `Retry-After` from provider
3
+ // SDK error objects. Anthropic, OpenAI, Google GenAI and the OpenAI-
4
+ // compatible DeepSeek client all surface this header through `error.headers`
5
+ // (fetch-style) or `error.response.headers` (legacy axios-style). The
6
+ // retry loop already consumes `failure.retry_after_ms`, so honoring the
7
+ // server-authoritative hint is a one-place fix that helps every provider
8
+ // at once. Returns ms or undefined.
9
+ function extractRetryAfterMs(error) {
10
+ if (!error || typeof error !== "object")
11
+ return undefined;
12
+ const candidates = [];
13
+ const errorObj = error;
14
+ if (errorObj.headers)
15
+ candidates.push(errorObj.headers);
16
+ const response = errorObj.response;
17
+ if (response && typeof response === "object") {
18
+ const respHeaders = response.headers;
19
+ if (respHeaders)
20
+ candidates.push(respHeaders);
21
+ }
22
+ for (const headers of candidates) {
23
+ let value;
24
+ if (headers && typeof headers.get === "function") {
25
+ try {
26
+ value =
27
+ headers.get("retry-after") ?? undefined;
28
+ }
29
+ catch {
30
+ // some Headers implementations throw on missing key — ignore.
31
+ }
32
+ }
33
+ else if (headers && typeof headers === "object") {
34
+ const h = headers;
35
+ const raw = h["retry-after"] ?? h["Retry-After"];
36
+ if (typeof raw === "string")
37
+ value = raw;
38
+ else if (typeof raw === "number" && Number.isFinite(raw))
39
+ value = String(raw);
40
+ }
41
+ if (!value)
42
+ continue;
43
+ const trimmed = value.trim();
44
+ if (!trimmed)
45
+ continue;
46
+ // Numeric (delta-seconds).
47
+ const seconds = Number.parseFloat(trimmed);
48
+ if (Number.isFinite(seconds) && seconds >= 0)
49
+ return Math.round(seconds * 1000);
50
+ // HTTP-date.
51
+ const date = Date.parse(trimmed);
52
+ if (Number.isFinite(date)) {
53
+ const delta = date - Date.now();
54
+ if (delta > 0)
55
+ return delta;
56
+ return 0;
57
+ }
58
+ }
59
+ return undefined;
60
+ }
61
+ // v2.4.0 / audit closure (P4.17): treat upstream gateway errors (502 Bad
62
+ // Gateway, 503 Service Unavailable, 504 Gateway Timeout) as retryable.
63
+ // Pre-v2.4.0 these collapsed into the generic `provider_error` class and
64
+ // the retry loop never re-tried them, even though they are textbook
65
+ // transient failures. Retain `provider_error` as the default class so
66
+ // upstream observability semantics don't change.
67
+ const GATEWAY_5XX_RE = /\b(?:5(?:0[234]|9\d))\b|\b(?:bad\s+gateway|service\s+unavailable|gateway\s+timeout)\b/i;
68
+ // v2.15.0 (item 5, operator directive 2026-05-04 — feedback_consult_docs_before_amputating.md):
69
+ // detect 4xx errors that cite a named provider parameter so the operator
70
+ // (and the agent reading the failure) gets a docs URL pointer FIRST,
71
+ // before considering the amputation reflex (rip the offending field out
72
+ // to silence the 400). The xAI grok-4-latest case is the canonical
73
+ // example: `reasoning.effort` is rejected on non-multi-agent models;
74
+ // the docs page lists exactly which models accept it. Surfacing the
75
+ // docs URL on the failure object makes the resolution path obvious and
76
+ // pushes the agent toward the correct fix (allowlist gate or model
77
+ // switch) rather than removing the feature.
78
+ //
79
+ // Pattern matches: "parameter X", "X is not supported", "Argument not
80
+ // supported on this model: X", "Invalid parameter: X", "Unrecognized
81
+ // request argument: X", "field X". Captures the parameter name (alphanum,
82
+ // underscore, dot for nested) for inclusion on `docs_hint.parameter`.
83
+ // Prefix form: "<keyword>: <param>" — captures the parameter name
84
+ // after a known prefix (Argument not supported on this model:, Invalid
85
+ // parameter:, Unrecognized request argument:, Unknown parameter:).
86
+ const PARAM_REJECTION_PREFIX_RE = /(?:argument\s+not\s+supported(?:\s+on\s+this\s+model)?\s*:|invalid\s+(?:request\s+)?(?:parameter|argument)\s*:|unrecognized\s+(?:request\s+)?(?:parameter|argument)\s*:|unknown\s+parameter\s*:)\s*["'`]?([a-z_][a-z0-9_]*(?:\.[a-z_][a-z0-9_]*)*)/i;
87
+ // Suffix form: "parameter <param> is not supported" — captures when the
88
+ // parameter precedes an explicit rejection clause.
89
+ const PARAM_REJECTION_SUFFIX_RE = /\b(?:parameter|field|argument)s?\s+["'`]?([a-z_][a-z0-9_]*(?:\.[a-z_][a-z0-9_]*)*)["'`]?\s+(?:is\s+(?:not\s+supported|invalid|unknown|deprecated)|not\s+supported|cannot\s+be\s+used|is\s+only\s+(?:supported|available)|requires)/i;
90
+ const STATUS_4XX_RE = /\b(?:400|404|405|409|413|415|422)\b/i;
91
+ const PROVIDER_DOCS_URLS = {
92
+ openai: "https://platform.openai.com/docs/api-reference",
93
+ anthropic: "https://docs.anthropic.com/en/api/messages",
94
+ google: "https://ai.google.dev/api/generate-content",
95
+ deepseek: "https://api-docs.deepseek.com/api/create-chat-completion",
96
+ xai: "https://docs.x.ai/docs/api-reference",
97
+ };
98
+ // Provider-specific deep links for known sticky parameters. Looked up
99
+ // after the generic provider docs URL when a parameter rename is known.
100
+ const PROVIDER_PARAM_DOCS = {
101
+ xai: {
102
+ "reasoning.effort": "https://docs.x.ai/developers/model-capabilities/text/reasoning",
103
+ },
104
+ openai: {
105
+ "reasoning.effort": "https://platform.openai.com/docs/api-reference/responses/create#responses-create-reasoning",
106
+ },
107
+ anthropic: {
108
+ thinking: "https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking",
109
+ },
110
+ };
111
+ export function classifyProviderError(peer, provider, model, error, attempts, started) {
112
+ const message = safeErrorMessage(error);
113
+ const contextual429 = /\b(?:http|status|statuscode|code|error)\s*[:=]?\s*["'(]?\s*429\b/i.test(message) ||
114
+ /\b429\s+(?:too many requests|rate[-_\s]?limit|quota|retry-after)\b/i.test(message);
115
+ const rateLimited = contextual429 ||
116
+ /\b(?:too many requests|rate[-_\s]?limit(?:ed|ing)?|quota exceeded|resource_exhausted|retry-after)\b/i.test(message);
117
+ const auth = /\b(?:401|403|unauthorized|forbidden|invalid api key|missing api key|expired api key|authentication failed|authentication required)\b/i.test(message);
118
+ const cancelled = /\b(?:aborterror|operation was aborted|call cancelled|session_cancelled)\b/i.test(message);
119
+ const moderation = /\b(?:invalid_prompt|prompt[_\s-]?flagged|moderation|moderated|safety policy|safety system|usage policy|responsibleaipolicyviolation|content[_\s-]?filter|blocked by policy|policy violation|could not be processed|input was rejected)\b/i.test(message);
120
+ const timeout = /\b(?:timeout|aborted|aborterror)\b/i.test(message);
121
+ const network = /\b(?:econnreset|enotfound|etimedout|network|fetch failed)\b/i.test(message);
122
+ const gateway5xx = GATEWAY_5XX_RE.test(message);
123
+ const failureClass = auth
124
+ ? "auth"
125
+ : cancelled
126
+ ? "cancelled"
127
+ : moderation
128
+ ? "prompt_flagged_by_moderation"
129
+ : rateLimited
130
+ ? "rate_limit"
131
+ : timeout
132
+ ? "timeout"
133
+ : network
134
+ ? "network"
135
+ : "provider_error";
136
+ // v2.15.0 (item 5): docs hint for 4xx parameter rejections. Only
137
+ // applies when the failure class is `provider_error` (avoid stomping
138
+ // on rate_limit/auth/network advice). The 4xx status check is a soft
139
+ // gate — many SDKs surface the parameter-rejection message without an
140
+ // explicit status code in the .message field, so we run the pattern
141
+ // even when STATUS_4XX_RE doesn't match, but only set docs_hint when
142
+ // both the regex matches AND the failure isn't already a known class.
143
+ let docsHint;
144
+ let docsAdvice;
145
+ if (failureClass === "provider_error") {
146
+ const prefixMatch = PARAM_REJECTION_PREFIX_RE.exec(message);
147
+ const suffixMatch = prefixMatch ? null : PARAM_REJECTION_SUFFIX_RE.exec(message);
148
+ const paramMatch = prefixMatch ?? suffixMatch;
149
+ if (paramMatch && (STATUS_4XX_RE.test(message) || /\bnot\s+supported\b/i.test(message))) {
150
+ const parameter = paramMatch[1];
151
+ const providerKey = provider.toLowerCase();
152
+ const deepLink = PROVIDER_PARAM_DOCS[providerKey]?.[parameter];
153
+ const fallbackLink = PROVIDER_DOCS_URLS[providerKey];
154
+ const docsUrl = deepLink ?? fallbackLink;
155
+ docsHint = { parameter, docs_url: docsUrl };
156
+ docsAdvice =
157
+ `Provider rejected parameter "${parameter}". HARD RULE (workspace memory feedback_consult_docs_before_amputating): consult official docs FIRST` +
158
+ (docsUrl ? ` at ${docsUrl}` : "") +
159
+ ", do NOT amputate the field to silence the 400. Likely fix: gate the field on a model-capability allowlist (see peers/grok.ts GROK_REASONING_EFFORT_MODELS for precedent), or switch to a model that accepts it.";
160
+ }
161
+ }
162
+ return {
163
+ peer,
164
+ provider,
165
+ model,
166
+ failure_class: failureClass,
167
+ message,
168
+ retryable: !cancelled && !auth && (rateLimited || timeout || network || gateway5xx),
169
+ recovery_hint: rateLimited
170
+ ? "wait_and_retry"
171
+ : moderation
172
+ ? "reformulate_and_retry"
173
+ : docsHint
174
+ ? "consult_docs_then_revise"
175
+ : undefined,
176
+ reformulation_advice: moderation
177
+ ? "Rephrase the request in neutral technical language, compact prior peer discussion, avoid quoting flagged text, and keep the same engineering intent."
178
+ : docsAdvice,
179
+ retry_after_ms: extractRetryAfterMs(error),
180
+ attempts,
181
+ latency_ms: Date.now() - started,
182
+ docs_hint: docsHint,
183
+ };
184
+ }
185
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/peers/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { AppConfig, GenerationResult, PeerAdapter, PeerCallContext, PeerId, PeerProbeResult, PeerResult } from "../core/types.js";
2
+ import { BasePeerAdapter } from "./base.js";
3
+ export declare function loadGenaiModule(): Promise<typeof import("@google/genai")>;
4
+ export declare class GeminiAdapter extends BasePeerAdapter implements PeerAdapter {
5
+ id: PeerId;
6
+ provider: string;
7
+ model: string;
8
+ constructor(config: AppConfig, modelOverride?: string);
9
+ private client;
10
+ probe(): Promise<PeerProbeResult>;
11
+ call(prompt: string, context: PeerCallContext): Promise<PeerResult>;
12
+ generate(prompt: string, context: PeerCallContext): Promise<GenerationResult>;
13
+ }