dsh-continual-evolve 0.7.1 → 0.7.3
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/README.md +23 -14
- package/README.zh.md +18 -14
- package/lib/approval.d.ts +11 -4
- package/lib/approval.js +23 -7
- package/lib/auto.d.ts +35 -5
- package/lib/auto.js +247 -82
- package/lib/command.d.ts +2 -3
- package/lib/command.js +19 -17
- package/lib/fate.d.ts +1 -1
- package/lib/fate.js +4 -4
- package/lib/index.d.ts +4 -4
- package/lib/index.js +29 -24
- package/lib/llm-text.d.ts +48 -5
- package/lib/llm-text.js +94 -27
- package/lib/memory-agent.d.ts +111 -0
- package/lib/memory-agent.js +535 -0
- package/lib/planner.d.ts +5 -0
- package/lib/planner.js +1 -1
- package/lib/review-scheduler.d.ts +38 -0
- package/lib/review-scheduler.js +192 -0
- package/lib/review.d.ts +4 -2
- package/lib/review.js +7 -6
- package/lib/runtime.d.ts +13 -13
- package/lib/runtime.js +41 -37
- package/lib/service.d.ts +9 -0
- package/lib/service.js +46 -20
- package/lib/token-usage.d.ts +1 -1
- package/lib/token-usage.js +8 -8
- package/lib/turn-snapshot.d.ts +68 -0
- package/lib/turn-snapshot.js +222 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Mounts the evolution engine, registers the model-facing evolve_* tools,
|
|
5
5
|
* the human-facing /evolve command, the system-prompt guidance section, and
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* the automatic memory+review pipeline. The listener is always registered,
|
|
7
|
+
* while its effective state is controlled by the runtime switch. Successful
|
|
8
|
+
* turns feed a dedicated memory agent and general review through one
|
|
9
|
+
* per-session serial scheduler.
|
|
9
10
|
*/
|
|
10
11
|
import { join } from "node:path";
|
|
11
12
|
import z from "@deepseek-ai/schemastery";
|
|
@@ -29,9 +30,9 @@ export const Config = z.object({
|
|
|
29
30
|
baseDir: z.string(),
|
|
30
31
|
/** System-prompt section order for the evolution guidance. */
|
|
31
32
|
sectionOrder: z.natural().default(118),
|
|
32
|
-
/**
|
|
33
|
+
/** Initial automatic-review default when no runtime switch exists (off by default: it costs model calls). */
|
|
33
34
|
autoReview: z.boolean().default(false),
|
|
34
|
-
/**
|
|
35
|
+
/** Legacy/local-fate cadence fallback; successful-turn review is snapshot-driven. */
|
|
35
36
|
reviewIntervalTurns: z.natural().default(6),
|
|
36
37
|
/** Trajectory slice handed to the gate, in characters. */
|
|
37
38
|
maxReviewInputChars: z.natural().default(40000),
|
|
@@ -177,25 +178,29 @@ export function apply(ctx, config) {
|
|
|
177
178
|
void restoreMounted(ctx, baseDir).catch((cause) => {
|
|
178
179
|
ctx.logger("continual-evolve").warn(`mount restore failed: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
179
180
|
});
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
|
|
181
|
+
// The listener is always registered. `autoReview` is only the initial
|
|
182
|
+
// runtime default; `/evolve resume` can enable it without a profile edit
|
|
183
|
+
// or process restart, while manual tools and commands stay independent.
|
|
184
|
+
registerAutoReview(ctx, engine, {
|
|
185
|
+
intervalTurns: config.reviewIntervalTurns ?? 6,
|
|
186
|
+
enabledByDefault: config.autoReview ?? false,
|
|
187
|
+
maxInputChars: config.maxReviewInputChars ?? 40000,
|
|
188
|
+
budgetTokens: config.reviewBudgetTokens ?? 4096,
|
|
189
|
+
notifyOnAutoReview: config.notifyOnAutoReview ?? true,
|
|
190
|
+
localFate: config.localFate ?? true,
|
|
191
|
+
fateIntervalTurns: config.fateIntervalTurns ?? config.reviewIntervalTurns ?? 6,
|
|
192
|
+
goalBlockedWrapupTurns: config.goalBlockedWrapupTurns ?? 3,
|
|
193
|
+
promotionPolicy,
|
|
194
|
+
autoCase: config.autoCase ?? true,
|
|
195
|
+
rubricKey,
|
|
196
|
+
...(config.historyRetain?.reviews !== undefined ? { reviewsRetain: config.historyRetain.reviews } : {}),
|
|
197
|
+
...(config.reviewModel ? { reviewModel: config.reviewModel } : {}),
|
|
198
|
+
requireGlobalApproval: config.requireGlobalApproval ?? true,
|
|
199
|
+
...(config.plannerPrefixCache ? { prefixCacheMode: config.plannerPrefixCache } : {}),
|
|
200
|
+
...(config.plannerPrefixMaxChars !== undefined ? { prefixMaxChars: config.plannerPrefixMaxChars } : {}),
|
|
201
|
+
});
|
|
202
|
+
const runtimeDefault = config.autoReview ?? false;
|
|
203
|
+
ctx.logger("continual-evolve").info(`continual-evolve auto-review registered (default ${runtimeDefault ? "on" : "off"}; successful-turn memory agent + general review; local-fate ${config.localFate ?? true ? "on" : "off"} every ${config.fateIntervalTurns ?? config.reviewIntervalTurns ?? 6} turns)`);
|
|
199
204
|
ctx.logger("continual-evolve").info(`continual-evolve mounted (baseDir=${baseDir})`);
|
|
200
205
|
}
|
|
201
206
|
//# sourceMappingURL=index.js.map
|
package/lib/llm-text.d.ts
CHANGED
|
@@ -9,13 +9,15 @@
|
|
|
9
9
|
* and JSON parsing.
|
|
10
10
|
*/
|
|
11
11
|
import type { Context } from "@deepseek-ai/cordis";
|
|
12
|
-
import { type Message, type TokenUsage } from "@deepseek-ai/dsh-llm";
|
|
12
|
+
import { type ContentBlock, type LlmResolvedModelInfo, type Message, type ReasoningEffortId, type RequestMessage, type TokenUsage, type ToolSchema } from "@deepseek-ai/dsh-llm";
|
|
13
13
|
/** Terminal outcome of one shared direct LLM call. */
|
|
14
14
|
export type StreamTextOutcome = "success" | "max-tokens" | "error" | "aborted" | "empty";
|
|
15
15
|
/** Provider usage and terminal result observed after the stream settles. */
|
|
16
16
|
export interface StreamTextObservation {
|
|
17
17
|
usage?: TokenUsage;
|
|
18
18
|
outcome: StreamTextOutcome;
|
|
19
|
+
/** Exact capability-derived effort used for this call; absent when no metadata was exposed. */
|
|
20
|
+
reasoningEffort?: ReasoningEffortId;
|
|
19
21
|
}
|
|
20
22
|
/** Diagnostic observer invoked before streamText returns or throws. */
|
|
21
23
|
export type StreamTextUsageObserver = (observation: StreamTextObservation) => void;
|
|
@@ -40,14 +42,55 @@ export interface StreamTextOptions {
|
|
|
40
42
|
*/
|
|
41
43
|
onUsage?: StreamTextUsageObserver;
|
|
42
44
|
}
|
|
45
|
+
/** One provider request for a bounded internal agent/tool loop. */
|
|
46
|
+
export interface StreamModelTurnOptions {
|
|
47
|
+
provider: string;
|
|
48
|
+
model: string;
|
|
49
|
+
messages: readonly RequestMessage[];
|
|
50
|
+
/** One-shot system slot. Omit when messages already carry the system prompt. */
|
|
51
|
+
system?: string;
|
|
52
|
+
/** Closed tool schemas for this request; omitted means no tools. */
|
|
53
|
+
tools?: readonly ToolSchema[];
|
|
54
|
+
maxTokens?: number;
|
|
55
|
+
signal?: AbortSignal | undefined;
|
|
56
|
+
/** Require at least one text block; tool-only turns must leave this false. */
|
|
57
|
+
requireText?: boolean;
|
|
58
|
+
/** Require visible text or a tool call; reasoning-only agent turns are empty. */
|
|
59
|
+
requireTextOrToolCall?: boolean;
|
|
60
|
+
/** Same diagnostic observer contract as {@link StreamTextOptions.onUsage}. */
|
|
61
|
+
onUsage?: StreamTextUsageObserver;
|
|
62
|
+
}
|
|
43
63
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
64
|
+
* Select the lowest reasoning effort an exact model advertises.
|
|
65
|
+
*
|
|
66
|
+
* An enabled effort wins over a declared closing effort. The adapter-preferred
|
|
67
|
+
* first enabled effort is the lowest enabled level it exposes; a closing effort
|
|
68
|
+
* is only a fallback when the model publishes no enabled level. No capability
|
|
69
|
+
* list means no caller-supplied effort.
|
|
70
|
+
*
|
|
71
|
+
* @param modelInfo - exact resolved-model metadata, when the provider exposes it.
|
|
72
|
+
* @returns The selected provider-owned effort id, or `undefined` when unknown.
|
|
73
|
+
*/
|
|
74
|
+
export declare function selectLowestReasoningEffort(modelInfo: Pick<LlmResolvedModelInfo, "reasoning"> | undefined): ReasoningEffortId | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Stream a single-turn text completion through `ctx.llm`. The request uses the
|
|
77
|
+
* exact provider/model's lowest advertised reasoning effort, omitting the field
|
|
78
|
+
* when the model exposes no reasoning metadata.
|
|
48
79
|
*
|
|
49
80
|
* @returns The concatenated text blocks from the response.
|
|
50
81
|
* @throws On provider error, abort, max-token truncation, or empty output.
|
|
51
82
|
*/
|
|
83
|
+
/**
|
|
84
|
+
* Stream one provider/model turn and return its assembled content blocks.
|
|
85
|
+
* This is the shared primitive for text callers and bounded tool loops; finish
|
|
86
|
+
* state, capability-derived effort, cancellation, and usage observation stay
|
|
87
|
+
* inside this boundary.
|
|
88
|
+
*
|
|
89
|
+
* @param ctx - DSH context providing the LLM runtime.
|
|
90
|
+
* @param opts - Exact route, messages, optional tools, and output requirements.
|
|
91
|
+
* @returns The assembled content blocks; caller decides how to interpret them.
|
|
92
|
+
* @throws On provider error, abort, max-token truncation, or capability lookup failure.
|
|
93
|
+
*/
|
|
94
|
+
export declare function streamModelTurn(ctx: Context, opts: StreamModelTurnOptions): Promise<ContentBlock[]>;
|
|
52
95
|
export declare function streamText(ctx: Context, opts: StreamTextOptions): Promise<string>;
|
|
53
96
|
//# sourceMappingURL=llm-text.d.ts.map
|
package/lib/llm-text.js
CHANGED
|
@@ -1,30 +1,71 @@
|
|
|
1
|
-
import { BlockAssembler, createUserMessage,
|
|
1
|
+
import { BlockAssembler, createUserMessage, } from "@deepseek-ai/dsh-llm";
|
|
2
2
|
import { EVOLVE_MESSAGE_SOURCE } from "./message-source.js";
|
|
3
|
+
const CLOSED_REASONING_EFFORTS = new Set(["disabled", "off", "none"]);
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Select the lowest reasoning effort an exact model advertises.
|
|
6
|
+
*
|
|
7
|
+
* An enabled effort wins over a declared closing effort. The adapter-preferred
|
|
8
|
+
* first enabled effort is the lowest enabled level it exposes; a closing effort
|
|
9
|
+
* is only a fallback when the model publishes no enabled level. No capability
|
|
10
|
+
* list means no caller-supplied effort.
|
|
11
|
+
*
|
|
12
|
+
* @param modelInfo - exact resolved-model metadata, when the provider exposes it.
|
|
13
|
+
* @returns The selected provider-owned effort id, or `undefined` when unknown.
|
|
14
|
+
*/
|
|
15
|
+
export function selectLowestReasoningEffort(modelInfo) {
|
|
16
|
+
const efforts = modelInfo?.reasoning?.efforts;
|
|
17
|
+
if (efforts !== undefined && !Array.isArray(efforts)) {
|
|
18
|
+
throw new Error("evolve: invalid model reasoning metadata");
|
|
19
|
+
}
|
|
20
|
+
if (!efforts || efforts.length === 0)
|
|
21
|
+
return undefined;
|
|
22
|
+
for (const effort of efforts) {
|
|
23
|
+
if (typeof effort?.id !== "string") {
|
|
24
|
+
throw new Error("evolve: invalid model reasoning metadata");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return efforts.find((effort) => !CLOSED_REASONING_EFFORTS.has(effort.id))?.id ?? efforts[0]?.id;
|
|
28
|
+
}
|
|
29
|
+
async function resolveReasoningEffort(ctx, opts) {
|
|
30
|
+
// The current DSH host exposes this method. Keep a capability-less test or
|
|
31
|
+
// older host usable by treating the absent query as unknown metadata.
|
|
32
|
+
if (typeof ctx.llm.resolveModelInfo !== "function")
|
|
33
|
+
return undefined;
|
|
34
|
+
const modelInfo = await ctx.llm.resolveModelInfo(opts.provider, opts.model);
|
|
35
|
+
return selectLowestReasoningEffort(modelInfo);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Stream a single-turn text completion through `ctx.llm`. The request uses the
|
|
39
|
+
* exact provider/model's lowest advertised reasoning effort, omitting the field
|
|
40
|
+
* when the model exposes no reasoning metadata.
|
|
8
41
|
*
|
|
9
42
|
* @returns The concatenated text blocks from the response.
|
|
10
43
|
* @throws On provider error, abort, max-token truncation, or empty output.
|
|
11
44
|
*/
|
|
12
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Stream one provider/model turn and return its assembled content blocks.
|
|
47
|
+
* This is the shared primitive for text callers and bounded tool loops; finish
|
|
48
|
+
* state, capability-derived effort, cancellation, and usage observation stay
|
|
49
|
+
* inside this boundary.
|
|
50
|
+
*
|
|
51
|
+
* @param ctx - DSH context providing the LLM runtime.
|
|
52
|
+
* @param opts - Exact route, messages, optional tools, and output requirements.
|
|
53
|
+
* @returns The assembled content blocks; caller decides how to interpret them.
|
|
54
|
+
* @throws On provider error, abort, max-token truncation, or capability lookup failure.
|
|
55
|
+
*/
|
|
56
|
+
export async function streamModelTurn(ctx, opts) {
|
|
13
57
|
const assembler = new BlockAssembler();
|
|
14
58
|
let outcome = "error";
|
|
59
|
+
let reasoningEffort;
|
|
15
60
|
try {
|
|
61
|
+
reasoningEffort = await resolveReasoningEffort(ctx, opts);
|
|
16
62
|
for await (const chunk of ctx.llm.stream({
|
|
17
63
|
provider: opts.provider,
|
|
18
64
|
model: opts.model,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
content: [{ type: "text", text: opts.prompt }],
|
|
24
|
-
source: EVOLVE_MESSAGE_SOURCE,
|
|
25
|
-
}),
|
|
26
|
-
],
|
|
27
|
-
reasoningEffort: ReasoningEffortId("off"),
|
|
65
|
+
messages: [...opts.messages],
|
|
66
|
+
...(opts.system === undefined ? {} : { system: opts.system }),
|
|
67
|
+
...(opts.tools === undefined ? {} : { tools: [...opts.tools] }),
|
|
68
|
+
...(reasoningEffort === undefined ? {} : { reasoningEffort }),
|
|
28
69
|
maxTokens: opts.maxTokens ?? 8000,
|
|
29
70
|
...(opts.signal ? { signal: opts.signal } : {}),
|
|
30
71
|
})) {
|
|
@@ -43,25 +84,51 @@ export async function streamText(ctx, opts) {
|
|
|
43
84
|
outcome = "max-tokens";
|
|
44
85
|
throw new Error("evolve: LLM output budget exhausted (max-tokens)");
|
|
45
86
|
}
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
throw new Error("evolve: LLM produced no text output");
|
|
54
|
-
}
|
|
55
|
-
outcome = "success";
|
|
56
|
-
return text;
|
|
87
|
+
const blocks = assembler.blocks();
|
|
88
|
+
const hasText = blocks.some((block) => block.type === "text" && block.text.length > 0);
|
|
89
|
+
const hasToolCall = blocks.some((block) => block.type === "tool-call");
|
|
90
|
+
const missingRequiredOutput = (opts.requireText === true && !hasText)
|
|
91
|
+
|| (opts.requireTextOrToolCall === true && !hasText && !hasToolCall);
|
|
92
|
+
outcome = blocks.length === 0 || missingRequiredOutput ? "empty" : "success";
|
|
93
|
+
return blocks;
|
|
57
94
|
}
|
|
58
95
|
finally {
|
|
59
96
|
try {
|
|
60
|
-
opts.onUsage?.({
|
|
97
|
+
opts.onUsage?.({
|
|
98
|
+
...(assembler.usage ? { usage: assembler.usage } : {}),
|
|
99
|
+
outcome,
|
|
100
|
+
...(reasoningEffort === undefined ? {} : { reasoningEffort }),
|
|
101
|
+
});
|
|
61
102
|
}
|
|
62
103
|
catch {
|
|
63
104
|
// Usage observation is diagnostic; its failure must not alter the model call.
|
|
64
105
|
}
|
|
65
106
|
}
|
|
66
107
|
}
|
|
108
|
+
export async function streamText(ctx, opts) {
|
|
109
|
+
const blocks = await streamModelTurn(ctx, {
|
|
110
|
+
provider: opts.provider,
|
|
111
|
+
model: opts.model,
|
|
112
|
+
system: opts.system,
|
|
113
|
+
messages: [
|
|
114
|
+
...(opts.prefixMessages ?? []),
|
|
115
|
+
createUserMessage({
|
|
116
|
+
content: [{ type: "text", text: opts.prompt }],
|
|
117
|
+
source: EVOLVE_MESSAGE_SOURCE,
|
|
118
|
+
}),
|
|
119
|
+
],
|
|
120
|
+
requireText: true,
|
|
121
|
+
...(opts.maxTokens === undefined ? {} : { maxTokens: opts.maxTokens }),
|
|
122
|
+
...(opts.signal ? { signal: opts.signal } : {}),
|
|
123
|
+
...(opts.onUsage ? { onUsage: opts.onUsage } : {}),
|
|
124
|
+
});
|
|
125
|
+
const text = blocks
|
|
126
|
+
.filter((block) => block.type === "text")
|
|
127
|
+
.map((block) => block.text)
|
|
128
|
+
.join("\n");
|
|
129
|
+
if (text.length === 0) {
|
|
130
|
+
throw new Error("evolve: LLM produced no text output");
|
|
131
|
+
}
|
|
132
|
+
return text;
|
|
133
|
+
}
|
|
67
134
|
//# sourceMappingURL=llm-text.js.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dedicated background memory extraction agent.
|
|
3
|
+
*
|
|
4
|
+
* This is the DSH counterpart of ZCode's project-memory agent loop. It keeps
|
|
5
|
+
* an independent request history, exposes only a frozen memory manifest and a
|
|
6
|
+
* structured proposal tool, and never writes state itself. Every accepted edit
|
|
7
|
+
* is handed to EvolutionEngine so scope approval, snapshots, versioning,
|
|
8
|
+
* rollback, and audit remain mandatory.
|
|
9
|
+
*/
|
|
10
|
+
import type { Context } from "@deepseek-ai/cordis";
|
|
11
|
+
import type { Agent } from "@deepseek-ai/dsh-agent";
|
|
12
|
+
import { type ToolSchema } from "@deepseek-ai/dsh-llm";
|
|
13
|
+
import { type ScopeApprovalDecision } from "./approval.js";
|
|
14
|
+
import { type PrefixCacheOptions } from "./prefix-cache.js";
|
|
15
|
+
import { type EvolutionEngine } from "./service.js";
|
|
16
|
+
import { type TokenUsageTarget } from "./token-usage.js";
|
|
17
|
+
import type { EntrySource, HarnessEntry, HarnessScope, HarnessState, RefinementEdit, RefinementProposal, RefinementResult } from "./types.js";
|
|
18
|
+
/** ZCode parity: the extractor may inspect memory and propose at most five times. */
|
|
19
|
+
export declare const MEMORY_AGENT_MAX_TURNS = 5;
|
|
20
|
+
/** Bound one proposal so approval text and engine compensation stay reviewable. */
|
|
21
|
+
export declare const MEMORY_AGENT_MAX_EDITS = 20;
|
|
22
|
+
/** The complete tool-name allowlist exposed by the memory agent. */
|
|
23
|
+
export declare const MEMORY_AGENT_TOOL_NAMES: readonly ["memory_search", "memory_propose"];
|
|
24
|
+
export type MemoryAgentToolName = (typeof MEMORY_AGENT_TOOL_NAMES)[number];
|
|
25
|
+
/** One frozen memory entry visible to the extractor for the whole run. */
|
|
26
|
+
export type MemoryManifestEntry = HarnessEntry;
|
|
27
|
+
/** A memory-only edit with an explicit persistence target. */
|
|
28
|
+
export type ScopedMemoryEdit = RefinementEdit & {
|
|
29
|
+
kind: "memory";
|
|
30
|
+
targetScope: HarnessScope;
|
|
31
|
+
};
|
|
32
|
+
/** Structured result returned by `memory_propose`. */
|
|
33
|
+
export interface MemoryExtractionProposal extends Omit<RefinementProposal, "edits"> {
|
|
34
|
+
edits: ScopedMemoryEdit[];
|
|
35
|
+
}
|
|
36
|
+
/** Baseline states captured before the first extractor model turn. */
|
|
37
|
+
export interface MemoryScopeBaselines {
|
|
38
|
+
local: HarnessState;
|
|
39
|
+
project?: HarnessState;
|
|
40
|
+
global: HarnessState;
|
|
41
|
+
}
|
|
42
|
+
/** Result of one bounded extractor loop. */
|
|
43
|
+
export interface MemoryAgentRun {
|
|
44
|
+
proposal: MemoryExtractionProposal;
|
|
45
|
+
turns: number;
|
|
46
|
+
searches: number;
|
|
47
|
+
}
|
|
48
|
+
/** Scoped results after the proposal crosses the governed engine boundary. */
|
|
49
|
+
export interface MemoryApplicationResult {
|
|
50
|
+
results: RefinementResult[];
|
|
51
|
+
declinedScopes: HarnessScope[];
|
|
52
|
+
}
|
|
53
|
+
/** Provider-facing schemas for the closed memory-only tool set. */
|
|
54
|
+
export declare const MEMORY_AGENT_TOOL_SCHEMAS: readonly ToolSchema[];
|
|
55
|
+
/** Instructions for the dedicated loop; model text is always untrusted. */
|
|
56
|
+
export declare const MEMORY_AGENT_SYSTEM_PROMPT = "You are the dedicated background memory extraction agent for a continual-evolution harness.\n\nYou receive only an incremental conversation checkpoint and a frozen manifest of existing memory entries. Your entire job is to decide whether this checkpoint contains a durable fact worth remembering. Never propose prompt notes, skills, subagent specs, code changes, or general conversation summaries.\n\nRules:\n- Use memory_search before creating when the manifest may already cover the topic. Update an existing entry instead of creating a near-duplicate.\n- Every memory entry contains exactly one fact. Classify it with metadata.memoryType = user | feedback | project | reference.\n- feedback and project memories must state the fact, Why it matters, and How to apply it next time.\n- Never invent a user preference. Ground every proposal in the supplied conversation evidence and existing memory.\n- Every edit must have kind=memory, an explicit targetScope, and a coherent blastRadius.\n- targetScope=local is session staging. project persists within the current repository. global persists across projects. project/global require human approval before application.\n- update/delete/archive must name an existing id from the same targetScope. Prefer archive over delete when the fact is obsolete but should remain restorable.\n- You cannot read or write source files, call agents, use MCP, use the network, or mutate the harness directly. memory_propose is the only finish tool and never writes state itself.\n- If no durable memory is justified, call memory_propose with edits=[].\n- Always finish by calling memory_propose. Do not return unproposed prose.";
|
|
57
|
+
/** Build the frozen memory manifest from a merged harness view. */
|
|
58
|
+
export declare function buildMemoryManifest(state: HarnessState): MemoryManifestEntry[];
|
|
59
|
+
/** Render a bounded manifest index; full bodies remain available through memory_search. */
|
|
60
|
+
export declare function formatMemoryManifest(entries: readonly MemoryManifestEntry[], maxChars?: number): string;
|
|
61
|
+
/** Rank frozen manifest entries with CJK-aware token overlap and stable tie-breaking. */
|
|
62
|
+
export declare function searchMemoryManifest(entries: readonly MemoryManifestEntry[], query: string, maxResults?: number): MemoryManifestEntry[];
|
|
63
|
+
/** Inputs for one bounded background memory extraction loop. */
|
|
64
|
+
export interface MemoryAgentOptions {
|
|
65
|
+
provider: string;
|
|
66
|
+
model: string;
|
|
67
|
+
manifest: readonly MemoryManifestEntry[];
|
|
68
|
+
trajectory: string;
|
|
69
|
+
trajectoryEvents?: readonly unknown[];
|
|
70
|
+
prefixCache?: PrefixCacheOptions;
|
|
71
|
+
maxOutputTokens?: number;
|
|
72
|
+
signal?: AbortSignal;
|
|
73
|
+
tokenUsage?: TokenUsageTarget;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Run the dedicated loop against a frozen manifest.
|
|
77
|
+
*
|
|
78
|
+
* @throws On provider failure, abort, malformed tool arguments, policy denial,
|
|
79
|
+
* a non-memory proposal, or exhaustion of the bounded internal turn budget.
|
|
80
|
+
*/
|
|
81
|
+
export declare function runMemoryAgent(ctx: Context, options: MemoryAgentOptions): Promise<MemoryAgentRun>;
|
|
82
|
+
/** Strictly parse and policy-check the structured `memory_propose` payload. */
|
|
83
|
+
export declare function parseMemoryExtractionProposal(value: unknown, manifest: readonly MemoryManifestEntry[]): MemoryExtractionProposal;
|
|
84
|
+
export interface ApplyMemoryProposalOptions {
|
|
85
|
+
agent: Agent;
|
|
86
|
+
baselines: MemoryScopeBaselines;
|
|
87
|
+
projectKey?: string;
|
|
88
|
+
requireApproval: boolean;
|
|
89
|
+
source?: EntrySource;
|
|
90
|
+
signal?: AbortSignal;
|
|
91
|
+
/** Outer cursor used to scope reusable approval decisions. */
|
|
92
|
+
decisionCursor?: string;
|
|
93
|
+
/** Prior decisions for the same cursor and exact scoped proposal. */
|
|
94
|
+
scopeDecisions?: Readonly<Record<string, ScopeApprovalDecision>>;
|
|
95
|
+
/** Persist each decision before a later scope can fail. */
|
|
96
|
+
onScopeDecision?: (key: string, decision: ScopeApprovalDecision) => void;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Render the authoritative persistent-scope diff shown to the human. Model
|
|
100
|
+
* prose is retained only as an explicitly untrusted summary; actions, targets,
|
|
101
|
+
* content previews, memory types, and conflict warnings come from code.
|
|
102
|
+
*/
|
|
103
|
+
export declare function renderMemoryApprovalDetails(proposal: MemoryExtractionProposal, scope: "project" | "global", state: HarnessState, maxChars?: number): string;
|
|
104
|
+
/**
|
|
105
|
+
* Apply one accepted proposal through the only mutation engine. All persistent
|
|
106
|
+
* approvals are resolved before the first write, so an unavailable approval
|
|
107
|
+
* boundary cannot leave a partially applied batch. Explicit rejection is a
|
|
108
|
+
* no-op for that scope; service/question failures remain retryable errors.
|
|
109
|
+
*/
|
|
110
|
+
export declare function applyMemoryExtractionProposal(ctx: Context, engine: EvolutionEngine, proposal: MemoryExtractionProposal, options: ApplyMemoryProposalOptions): Promise<MemoryApplicationResult>;
|
|
111
|
+
//# sourceMappingURL=memory-agent.d.ts.map
|