@hadooppei/hwcode 1.0.20 → 1.0.24
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/.pi/dist/lib/knowledge/evidence.js +10 -9
- package/.pi/dist/lib/knowledge/extractor.js +2 -0
- package/.pi/dist/lib/runtime/defaults.js +2 -1
- package/.pi/extensions/knowledge.ts +40 -8
- package/.pi/extensions/model-providers.ts +4 -2
- package/.pi/lib/knowledge/evidence.ts +12 -8
- package/.pi/lib/knowledge/extractor.ts +2 -0
- package/.pi/lib/runtime/defaults.ts +2 -1
- package/package.json +1 -1
|
@@ -81,8 +81,11 @@ function boundedExcerpt(value, limit = 900) {
|
|
|
81
81
|
if (clean.length <= limit)
|
|
82
82
|
return clean;
|
|
83
83
|
const lines = clean.split("\n");
|
|
84
|
-
const
|
|
85
|
-
|
|
84
|
+
const priority = (line) => REVERSAL_RE.test(line) ? 0
|
|
85
|
+
: FAILURE_RE.test(line) && VERIFICATION_RE.test(line) ? 1
|
|
86
|
+
: FAILURE_RE.test(line) ? 2 : 3;
|
|
87
|
+
const significant = lines.filter((line) => (REVERSAL_RE.test(line) || FAILURE_RE.test(line) || VERIFICATION_RE.test(line))).sort((left, right) => priority(left) - priority(right));
|
|
88
|
+
const selected = [...lines.slice(0, 2), ...significant.slice(0, 7), ...lines.slice(-2)];
|
|
86
89
|
return [...new Set(selected)].join("\n").slice(0, limit);
|
|
87
90
|
}
|
|
88
91
|
function compactArguments(args) {
|
|
@@ -152,10 +155,8 @@ function entryIdOf(entry, index) {
|
|
|
152
155
|
function evidenceId(entryId, suffix) {
|
|
153
156
|
return `ev-${digest(`${entryId}\0${suffix}`)}`;
|
|
154
157
|
}
|
|
155
|
-
function outcomeFor(message
|
|
156
|
-
|
|
157
|
-
return "failure";
|
|
158
|
-
return "success";
|
|
158
|
+
function outcomeFor(message) {
|
|
159
|
+
return message.isError === true ? "failure" : "success";
|
|
159
160
|
}
|
|
160
161
|
function userKind(text) {
|
|
161
162
|
return CORRECTION_RE.test(text) ? "user-correction" : "user-directive";
|
|
@@ -206,11 +207,11 @@ export function buildKnowledgeEvidence(entries) {
|
|
|
206
207
|
// lookup result as verification would let knowledge reinforce itself merely by loading it.
|
|
207
208
|
if (call?.name === "hwcode_knowledge_lookup")
|
|
208
209
|
return;
|
|
209
|
-
const outcome = outcomeFor(message
|
|
210
|
+
const outcome = outcomeFor(message);
|
|
210
211
|
const callText = call ? `[call] ${call.name}: ${compactArguments(call.args)}\n` : "";
|
|
211
212
|
evidence.push({
|
|
212
213
|
id: evidenceId(entryId, toolCallId || "tool"), entryId, timestamp,
|
|
213
|
-
kind: outcome === "failure" ? "tool-failure" :
|
|
214
|
+
kind: outcome === "failure" ? "tool-failure" : "tool-success",
|
|
214
215
|
subject: evidenceSubject(call, text), operation: operationName(call), outcome,
|
|
215
216
|
excerpt: boundedExcerpt(`${callText}[result] ${text}`),
|
|
216
217
|
});
|
|
@@ -219,7 +220,7 @@ export function buildKnowledgeEvidence(entries) {
|
|
|
219
220
|
if (role === "assistant" && text && (FAILURE_RE.test(text) || VERIFICATION_RE.test(text) || REVERSAL_RE.test(text))) {
|
|
220
221
|
evidence.push({
|
|
221
222
|
id: evidenceId(entryId, "assistant"), entryId, timestamp,
|
|
222
|
-
kind:
|
|
223
|
+
kind: "assistant-claim",
|
|
223
224
|
subject: "Assistant diagnosis or conclusion", outcome: "unknown", excerpt: boundedExcerpt(text, 800),
|
|
224
225
|
});
|
|
225
226
|
}
|
|
@@ -14,9 +14,11 @@ Treat failed, unsupported, invalid, or corrected operations as negative evidence
|
|
|
14
14
|
Use storageHint "rule" only for one short imperative instruction of at most 240 characters. A rule must not contain incident narration, example resource names, IDs, timestamps, or evidence details. Use "topic" for multi-step SOPs and detailed experience.
|
|
15
15
|
Rank knowledge by future time saved, repeated failures, hypothesis reversals, user corrections, verified resolution, reuse, and novelty. Do not favor the final task result merely because it completed the objective. Every supplied episode scoring 45 or higher must have an episodeDecisions entry, even when skipped.
|
|
16
16
|
Relevant existing knowledge may be supplied. Cheap recall only proposes related items; it does not prove duplication. Compare execution environment, symptom, and root cause. Use action "reinforce" only when the exact target already covers every claim and there is no new content. Use "extend" for new compatible claims, "correct" when direct evidence disproves old content, "retire" when the whole target is invalid, and "add" for a distinct environment or root cause. Never turn lexical similarity into reinforcement.
|
|
17
|
+
Prefer the most specific existing topic that already covers a claim over a broad conventions or SOP topic.
|
|
17
18
|
Scope may be "global" only for an explicit user directive intended across projects; otherwise use "project".
|
|
18
19
|
The prior validation context is only for checking facts and contradictions; do not persist it again unless the new delta independently reinforces it. Prefer accumulated workflow successfulSteps and failedApproaches over assistant narration.
|
|
19
20
|
Every technical claim must have a stable claim key and cite evidenceIds from the supplied evidence ledger. Tool success, tool failure, and verification evidence outrank assistant narration. Do not support a service-wide or universal claim with one operation-specific failure. Evidence for an unrelated parameter error cannot support an API-version claim.
|
|
21
|
+
Keep each candidate atomic: put separable claim sets in separate candidates, omit any claim without direct cited evidence, and prioritize the highest-value supported candidates. One unsupported claim rejects its entire candidate.
|
|
20
22
|
Each summary must be one complete sentence of at most 160 characters. Keep each topic body under 2200 characters. Escape line breaks and quotes inside JSON strings. Set durability to "stable" only after removing facts likely to change or be cheaply rediscovered. Return at most 3 candidates.
|
|
21
23
|
The body must not repeat the title as a Markdown H1. The storage renderer supplies the H1. Replace any necessary example resource value with an obvious placeholder instead of a real project, namespace, image, network, or resource name.
|
|
22
24
|
Return: {"episodeDecisions":[{"episodeId":"ep-id","decision":"add|reinforce|extend|correct|retire|skip","targetId":"existing-id or omitted","reason":"..."}],"candidates":[{"key":"stable semantic key","identityKey":"platform/runtime/problem/root-cause","targetId":"existing-id or null","episodeIds":["ep-id"],"title":"...","summary":"one complete sentence","keywords":["..."],"scope":"global|project","body":"markdown body or only the new section for extend","claims":[{"key":"stable claim key","text":"one precise claim","evidenceIds":["ev-id"]}],"evidenceIds":["ev-id"],"confidence":0.0,"storageHint":"rule|topic","action":"add|reinforce|extend|correct|retire","explicitUserDirective":false,"durability":"stable"}]}
|
|
@@ -30,6 +30,7 @@ export const KNOWLEDGE_RUNTIME_DEFAULTS = Object.freeze({
|
|
|
30
30
|
intervalMs: 60_000,
|
|
31
31
|
idleMs: 60_000,
|
|
32
32
|
capabilityPollMs: 5_000,
|
|
33
|
+
requestTimeoutMs: 45_000,
|
|
33
34
|
modelTimeoutMs: 180_000,
|
|
34
35
|
maxAttempts: 2,
|
|
35
36
|
maxFailureDetailChars: 4_000,
|
|
@@ -39,7 +40,7 @@ export const KNOWLEDGE_RUNTIME_DEFAULTS = Object.freeze({
|
|
|
39
40
|
maxEvidenceItems: 24,
|
|
40
41
|
maxEvidenceChars: 12_000,
|
|
41
42
|
mandatoryEpisodeScore: 45,
|
|
42
|
-
maxExistingContextItems:
|
|
43
|
+
maxExistingContextItems: 8,
|
|
43
44
|
maxExistingBodyItems: 2,
|
|
44
45
|
maxExistingBodyChars: 600,
|
|
45
46
|
maxCandidates: 3,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
1
|
import { existsSync } from "node:fs";
|
|
3
2
|
import { dirname } from "node:path";
|
|
4
3
|
import { fileURLToPath } from "node:url";
|
|
@@ -54,7 +53,7 @@ function compactReviewEvidence(task: KnowledgeReviewTask): {
|
|
|
54
53
|
let characters = 0;
|
|
55
54
|
const add = (item: KnowledgeEvidence | undefined): void => {
|
|
56
55
|
if (!item || seen.has(item.id) || selected.length >= KNOWLEDGE_RUNTIME_DEFAULTS.review.maxEvidenceItems) return;
|
|
57
|
-
const compact = { ...item, excerpt: item.excerpt.slice(0,
|
|
56
|
+
const compact = { ...item, excerpt: item.excerpt.slice(0, 800) };
|
|
58
57
|
const size = JSON.stringify(compact).length;
|
|
59
58
|
if (characters + size > KNOWLEDGE_RUNTIME_DEFAULTS.review.maxEvidenceChars) return;
|
|
60
59
|
selected.push(compact);
|
|
@@ -183,13 +182,20 @@ async function runReview(message: Extract<KnowledgeWorkerOutput, { type: "review
|
|
|
183
182
|
seenRelated.add(entry.id);
|
|
184
183
|
};
|
|
185
184
|
const episodeMatches = (message.task.episodes ?? []).map((episode) => (
|
|
186
|
-
matchKnowledge(
|
|
185
|
+
matchKnowledge(
|
|
186
|
+
`${episode.title}\n${episode.query}`,
|
|
187
|
+
applicableCatalog,
|
|
188
|
+
KNOWLEDGE_RUNTIME_DEFAULTS.review.maxExistingContextItems,
|
|
189
|
+
)
|
|
187
190
|
));
|
|
188
|
-
for (const matches of episodeMatches
|
|
191
|
+
for (const matches of episodeMatches) addRelated(matches[0]);
|
|
189
192
|
for (const id of message.task.loadedKnowledgeIds ?? []) {
|
|
190
193
|
addRelated(applicableCatalog.items.find((entry) => entry.id === id));
|
|
191
194
|
}
|
|
192
|
-
|
|
195
|
+
const matchDepth = Math.max(0, ...episodeMatches.map((matches) => matches.length));
|
|
196
|
+
for (let rank = 1; rank < matchDepth; rank++) {
|
|
197
|
+
for (const matches of episodeMatches) addRelated(matches[rank]);
|
|
198
|
+
}
|
|
193
199
|
for (const entry of matchKnowledge(
|
|
194
200
|
message.task.recallQuery || message.task.delta,
|
|
195
201
|
applicableCatalog,
|
|
@@ -219,7 +225,7 @@ async function runReview(message: Extract<KnowledgeWorkerOutput, { type: "review
|
|
|
219
225
|
promptContext.evidence,
|
|
220
226
|
promptContext.episodes,
|
|
221
227
|
);
|
|
222
|
-
|
|
228
|
+
const diagnostic = [
|
|
223
229
|
`reviewKey=${message.task.reviewKey}`,
|
|
224
230
|
`model=${ctx.model.provider}/${ctx.model.id}`,
|
|
225
231
|
`promptChars=${prompt.length}`,
|
|
@@ -227,7 +233,12 @@ async function runReview(message: Extract<KnowledgeWorkerOutput, { type: "review
|
|
|
227
233
|
`evidenceItems=${promptContext.evidence.length}`,
|
|
228
234
|
`episodeItems=${promptContext.episodes.length}`,
|
|
229
235
|
`existingItems=${related.length}`,
|
|
230
|
-
]
|
|
236
|
+
];
|
|
237
|
+
const requestStartedAt = Date.now();
|
|
238
|
+
const setRequestPhase = (phase: string): void => {
|
|
239
|
+
review!.diagnostic = [...diagnostic, `phase=${phase}`, `requestElapsedMs=${Date.now() - requestStartedAt}`].join("; ");
|
|
240
|
+
};
|
|
241
|
+
setRequestPhase("preparing-request");
|
|
231
242
|
const response = await ctx.modelRegistry.complete(
|
|
232
243
|
ctx.model,
|
|
233
244
|
{
|
|
@@ -241,11 +252,32 @@ async function runReview(message: Extract<KnowledgeWorkerOutput, { type: "review
|
|
|
241
252
|
timestamp: Date.now(),
|
|
242
253
|
}],
|
|
243
254
|
},
|
|
244
|
-
{
|
|
255
|
+
{
|
|
256
|
+
signal: controller.signal,
|
|
257
|
+
reasoningEffort: "low",
|
|
258
|
+
cacheRetention: "none",
|
|
259
|
+
temperature: 0,
|
|
260
|
+
timeoutMs: KNOWLEDGE_RUNTIME_DEFAULTS.review.requestTimeoutMs,
|
|
261
|
+
maxRetries: 0,
|
|
262
|
+
onPayload: () => { setRequestPhase("awaiting-http-response"); },
|
|
263
|
+
onResponse: (providerResponse: { status: number }) => {
|
|
264
|
+
setRequestPhase(`streaming-response-http-${providerResponse.status}`);
|
|
265
|
+
},
|
|
266
|
+
},
|
|
245
267
|
);
|
|
246
268
|
if (controller.signal.aborted) throw new Error(review.abortReason ?? "knowledge-review-interrupted");
|
|
269
|
+
if (response.stopReason === "error" || response.stopReason === "aborted") {
|
|
270
|
+
throw new Error(response.errorMessage ?? `knowledge-review-model-${response.stopReason}`);
|
|
271
|
+
}
|
|
272
|
+
const responseDetail = [
|
|
273
|
+
`stopReason=${response.stopReason}`,
|
|
274
|
+
`contentTypes=${response.content.map((item) => item.type).join(",") || "none"}`,
|
|
275
|
+
`outputTokens=${response.usage.output}`,
|
|
276
|
+
].join("; ");
|
|
277
|
+
if (response.stopReason === "length") throw new Error(`knowledge-review-output-truncated; ${responseDetail}`);
|
|
247
278
|
const raw = response.content.filter((item): item is { type: "text"; text: string } => item.type === "text")
|
|
248
279
|
.map((item) => item.text).join("\n");
|
|
280
|
+
if (!raw.trim()) throw new Error(`knowledge-review-model-returned-no-text; ${responseDetail}`);
|
|
249
281
|
post({ type: "review_result", leaderToken: message.leaderToken, requestId: message.requestId, raw });
|
|
250
282
|
} catch (error) {
|
|
251
283
|
const baseReason = review?.controller.signal.aborted
|
|
@@ -28,6 +28,7 @@ type OpenAIModel = Model<"openai-completions">;
|
|
|
28
28
|
interface RemoteModel {
|
|
29
29
|
id: string;
|
|
30
30
|
name?: string;
|
|
31
|
+
reasoning?: boolean;
|
|
31
32
|
input?: ModelInput[];
|
|
32
33
|
contextWindow?: number;
|
|
33
34
|
}
|
|
@@ -69,7 +70,7 @@ function toPiModel(
|
|
|
69
70
|
api: "openai-completions",
|
|
70
71
|
provider: provider.id,
|
|
71
72
|
baseUrl,
|
|
72
|
-
reasoning: override?.reasoning ?? defaults?.reasoning ?? false,
|
|
73
|
+
reasoning: override?.reasoning ?? defaults?.reasoning ?? remote.reasoning ?? false,
|
|
73
74
|
input: override?.input ?? remote.input ?? defaults?.input ?? ["text"],
|
|
74
75
|
contextWindow,
|
|
75
76
|
maxTokens: Math.min(maxTokens, contextWindow),
|
|
@@ -104,7 +105,7 @@ function remoteContextWindow(model: Record<string, unknown>): number | undefined
|
|
|
104
105
|
return undefined;
|
|
105
106
|
}
|
|
106
107
|
|
|
107
|
-
function parseRemoteModels(payload: unknown): RemoteModel[] {
|
|
108
|
+
export function parseRemoteModels(payload: unknown): RemoteModel[] {
|
|
108
109
|
const entries = Array.isArray(payload)
|
|
109
110
|
? payload
|
|
110
111
|
: isRecord(payload) && Array.isArray(payload.data)
|
|
@@ -122,6 +123,7 @@ function parseRemoteModels(payload: unknown): RemoteModel[] {
|
|
|
122
123
|
models.push({
|
|
123
124
|
id,
|
|
124
125
|
name: typeof entry.name === "string" && entry.name.trim() ? entry.name.trim() : undefined,
|
|
126
|
+
reasoning: typeof entry.reasoning === "boolean" ? entry.reasoning : isRecord(entry.reasoning) || undefined,
|
|
125
127
|
input: remoteInput(entry),
|
|
126
128
|
contextWindow: remoteContextWindow(entry),
|
|
127
129
|
});
|
|
@@ -99,8 +99,13 @@ function boundedExcerpt(value: string, limit = 900): string {
|
|
|
99
99
|
const clean = sanitizeKnowledgeText(value).replace(/\n{3,}/gu, "\n\n").trim();
|
|
100
100
|
if (clean.length <= limit) return clean;
|
|
101
101
|
const lines = clean.split("\n");
|
|
102
|
-
const
|
|
103
|
-
|
|
102
|
+
const priority = (line: string): number => REVERSAL_RE.test(line) ? 0
|
|
103
|
+
: FAILURE_RE.test(line) && VERIFICATION_RE.test(line) ? 1
|
|
104
|
+
: FAILURE_RE.test(line) ? 2 : 3;
|
|
105
|
+
const significant = lines.filter((line) => (
|
|
106
|
+
REVERSAL_RE.test(line) || FAILURE_RE.test(line) || VERIFICATION_RE.test(line)
|
|
107
|
+
)).sort((left, right) => priority(left) - priority(right));
|
|
108
|
+
const selected = [...lines.slice(0, 2), ...significant.slice(0, 7), ...lines.slice(-2)];
|
|
104
109
|
return [...new Set(selected)].join("\n").slice(0, limit);
|
|
105
110
|
}
|
|
106
111
|
|
|
@@ -163,9 +168,8 @@ function evidenceId(entryId: string, suffix: string): string {
|
|
|
163
168
|
return `ev-${digest(`${entryId}\0${suffix}`)}`;
|
|
164
169
|
}
|
|
165
170
|
|
|
166
|
-
function outcomeFor(message: Record<string, unknown
|
|
167
|
-
|
|
168
|
-
return "success";
|
|
171
|
+
function outcomeFor(message: Record<string, unknown>): "success" | "failure" {
|
|
172
|
+
return message.isError === true ? "failure" : "success";
|
|
169
173
|
}
|
|
170
174
|
|
|
171
175
|
function userKind(text: string): KnowledgeEvidenceKind {
|
|
@@ -215,11 +219,11 @@ export function buildKnowledgeEvidence(entries: SessionEntry[]): KnowledgeEviden
|
|
|
215
219
|
// Recalled knowledge is comparison context, not fresh execution evidence. Treating a
|
|
216
220
|
// lookup result as verification would let knowledge reinforce itself merely by loading it.
|
|
217
221
|
if (call?.name === "hwcode_knowledge_lookup") return;
|
|
218
|
-
const outcome = outcomeFor(message
|
|
222
|
+
const outcome = outcomeFor(message);
|
|
219
223
|
const callText = call ? `[call] ${call.name}: ${compactArguments(call.args)}\n` : "";
|
|
220
224
|
evidence.push({
|
|
221
225
|
id: evidenceId(entryId, toolCallId || "tool"), entryId, timestamp,
|
|
222
|
-
kind: outcome === "failure" ? "tool-failure" :
|
|
226
|
+
kind: outcome === "failure" ? "tool-failure" : "tool-success",
|
|
223
227
|
subject: evidenceSubject(call, text), operation: operationName(call), outcome,
|
|
224
228
|
excerpt: boundedExcerpt(`${callText}[result] ${text}`),
|
|
225
229
|
});
|
|
@@ -228,7 +232,7 @@ export function buildKnowledgeEvidence(entries: SessionEntry[]): KnowledgeEviden
|
|
|
228
232
|
if (role === "assistant" && text && (FAILURE_RE.test(text) || VERIFICATION_RE.test(text) || REVERSAL_RE.test(text))) {
|
|
229
233
|
evidence.push({
|
|
230
234
|
id: evidenceId(entryId, "assistant"), entryId, timestamp,
|
|
231
|
-
kind:
|
|
235
|
+
kind: "assistant-claim",
|
|
232
236
|
subject: "Assistant diagnosis or conclusion", outcome: "unknown", excerpt: boundedExcerpt(text, 800),
|
|
233
237
|
});
|
|
234
238
|
}
|
|
@@ -33,9 +33,11 @@ Treat failed, unsupported, invalid, or corrected operations as negative evidence
|
|
|
33
33
|
Use storageHint "rule" only for one short imperative instruction of at most 240 characters. A rule must not contain incident narration, example resource names, IDs, timestamps, or evidence details. Use "topic" for multi-step SOPs and detailed experience.
|
|
34
34
|
Rank knowledge by future time saved, repeated failures, hypothesis reversals, user corrections, verified resolution, reuse, and novelty. Do not favor the final task result merely because it completed the objective. Every supplied episode scoring 45 or higher must have an episodeDecisions entry, even when skipped.
|
|
35
35
|
Relevant existing knowledge may be supplied. Cheap recall only proposes related items; it does not prove duplication. Compare execution environment, symptom, and root cause. Use action "reinforce" only when the exact target already covers every claim and there is no new content. Use "extend" for new compatible claims, "correct" when direct evidence disproves old content, "retire" when the whole target is invalid, and "add" for a distinct environment or root cause. Never turn lexical similarity into reinforcement.
|
|
36
|
+
Prefer the most specific existing topic that already covers a claim over a broad conventions or SOP topic.
|
|
36
37
|
Scope may be "global" only for an explicit user directive intended across projects; otherwise use "project".
|
|
37
38
|
The prior validation context is only for checking facts and contradictions; do not persist it again unless the new delta independently reinforces it. Prefer accumulated workflow successfulSteps and failedApproaches over assistant narration.
|
|
38
39
|
Every technical claim must have a stable claim key and cite evidenceIds from the supplied evidence ledger. Tool success, tool failure, and verification evidence outrank assistant narration. Do not support a service-wide or universal claim with one operation-specific failure. Evidence for an unrelated parameter error cannot support an API-version claim.
|
|
40
|
+
Keep each candidate atomic: put separable claim sets in separate candidates, omit any claim without direct cited evidence, and prioritize the highest-value supported candidates. One unsupported claim rejects its entire candidate.
|
|
39
41
|
Each summary must be one complete sentence of at most 160 characters. Keep each topic body under 2200 characters. Escape line breaks and quotes inside JSON strings. Set durability to "stable" only after removing facts likely to change or be cheaply rediscovered. Return at most 3 candidates.
|
|
40
42
|
The body must not repeat the title as a Markdown H1. The storage renderer supplies the H1. Replace any necessary example resource value with an obvious placeholder instead of a real project, namespace, image, network, or resource name.
|
|
41
43
|
Return: {"episodeDecisions":[{"episodeId":"ep-id","decision":"add|reinforce|extend|correct|retire|skip","targetId":"existing-id or omitted","reason":"..."}],"candidates":[{"key":"stable semantic key","identityKey":"platform/runtime/problem/root-cause","targetId":"existing-id or null","episodeIds":["ep-id"],"title":"...","summary":"one complete sentence","keywords":["..."],"scope":"global|project","body":"markdown body or only the new section for extend","claims":[{"key":"stable claim key","text":"one precise claim","evidenceIds":["ev-id"]}],"evidenceIds":["ev-id"],"confidence":0.0,"storageHint":"rule|topic","action":"add|reinforce|extend|correct|retire","explicitUserDirective":false,"durability":"stable"}]}
|
|
@@ -31,6 +31,7 @@ export const KNOWLEDGE_RUNTIME_DEFAULTS = Object.freeze({
|
|
|
31
31
|
intervalMs: 60_000,
|
|
32
32
|
idleMs: 60_000,
|
|
33
33
|
capabilityPollMs: 5_000,
|
|
34
|
+
requestTimeoutMs: 45_000,
|
|
34
35
|
modelTimeoutMs: 180_000,
|
|
35
36
|
maxAttempts: 2,
|
|
36
37
|
maxFailureDetailChars: 4_000,
|
|
@@ -40,7 +41,7 @@ export const KNOWLEDGE_RUNTIME_DEFAULTS = Object.freeze({
|
|
|
40
41
|
maxEvidenceItems: 24,
|
|
41
42
|
maxEvidenceChars: 12_000,
|
|
42
43
|
mandatoryEpisodeScore: 45,
|
|
43
|
-
maxExistingContextItems:
|
|
44
|
+
maxExistingContextItems: 8,
|
|
44
45
|
maxExistingBodyItems: 2,
|
|
45
46
|
maxExistingBodyChars: 600,
|
|
46
47
|
maxCandidates: 3,
|