dsh-continual-evolve 0.15.11 → 0.15.13

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.
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Every subagent this plugin runs, declared in one table.
3
+ *
4
+ * A definition carries the job's identity, its whole instruction (system
5
+ * prompt), its output-budget fallback and its answer parser. Feature code
6
+ * loads definitions from here and never writes a prompt or a budget inline;
7
+ * adding a job means adding a row, and a job with no row cannot be called.
8
+ *
9
+ * The four review jobs are separate definitions on purpose: the memory rubric
10
+ * requires a memory to survive having its repo name stripped, while a project
11
+ * skill is *supposed* to be repo-bound, so one prompt cannot serve both.
12
+ */
13
+ import { EXTRACTION_CHEAP_SYSTEM_PROMPT, EXTRACTION_SYSTEM_PROMPT, parseCheapAnswer, parseExtractionAnswer, } from "./extraction-prompt.js";
14
+ import { parseEvolveAnswer, parseGateAnswer, REVIEW_MEMORY_CHEAP_SYSTEM_PROMPT, REVIEW_MEMORY_SYSTEM_PROMPT, REVIEW_SKILL_CHEAP_SYSTEM_PROMPT, REVIEW_SKILL_SYSTEM_PROMPT, } from "./review-prompt.js";
15
+ /**
16
+ * Output-budget fallbacks, used only for adapters that advertise no
17
+ * per-request cap of their own. A gate verdict is one JSON object plus the
18
+ * reasoning a thinking model spends before emitting it; the evolve/proposal
19
+ * calls additionally carry full replacement bodies.
20
+ */
21
+ export const GATE_MAX_TOKENS = 1024;
22
+ export const EVOLVE_MAX_TOKENS = 4096;
23
+ export const EXTRACTION_MAX_TOKENS = 4096;
24
+ /** The memory cheap gate: is this entry worth a close look at all? */
25
+ export const reviewGateMemory = {
26
+ id: "review-gate-memory",
27
+ system: REVIEW_MEMORY_CHEAP_SYSTEM_PROMPT,
28
+ maxTokens: GATE_MAX_TOKENS,
29
+ parse: (text) => parseGateAnswer(text),
30
+ };
31
+ /** The skill cheap gate: same question, scope-relative home rules. */
32
+ export const reviewGateSkill = {
33
+ id: "review-gate-skill",
34
+ system: REVIEW_SKILL_CHEAP_SYSTEM_PROMPT,
35
+ maxTokens: GATE_MAX_TOKENS,
36
+ parse: (text) => parseGateAnswer(text),
37
+ };
38
+ /** The memory evolve pass: five-dimension judgment plus the proposed rewrite. */
39
+ export const reviewEvolveMemory = {
40
+ id: "review-evolve-memory",
41
+ system: REVIEW_MEMORY_SYSTEM_PROMPT,
42
+ maxTokens: EVOLVE_MAX_TOKENS,
43
+ parse: (text) => parseEvolveAnswer(text),
44
+ };
45
+ /** The skill evolve pass: scope-relative reuse, executability, duplication. */
46
+ export const reviewEvolveSkill = {
47
+ id: "review-evolve-skill",
48
+ system: REVIEW_SKILL_SYSTEM_PROMPT,
49
+ maxTokens: EVOLVE_MAX_TOKENS,
50
+ parse: (text) => parseEvolveAnswer(text),
51
+ };
52
+ /** The extraction pre-gate: does this increment hold anything worth proposing? */
53
+ export const extractionGate = {
54
+ id: "extraction-gate",
55
+ system: EXTRACTION_CHEAP_SYSTEM_PROMPT,
56
+ maxTokens: GATE_MAX_TOKENS,
57
+ parse: (text) => parseCheapAnswer(text),
58
+ };
59
+ /** The extraction proposal call: the run's one expensive call. */
60
+ export const extractionMain = {
61
+ id: "extraction-main",
62
+ system: EXTRACTION_SYSTEM_PROMPT,
63
+ maxTokens: EXTRACTION_MAX_TOKENS,
64
+ parse: (text) => parseExtractionAnswer(text),
65
+ };
66
+ /** Every definition, for the "which jobs exist" read and the id-uniqueness check. */
67
+ export const SUBAGENT_DEFINITIONS = [
68
+ reviewGateMemory,
69
+ reviewGateSkill,
70
+ reviewEvolveMemory,
71
+ reviewEvolveSkill,
72
+ extractionGate,
73
+ extractionMain,
74
+ ];
75
+ /** The gate definition one review candidate loads, by item kind. */
76
+ export const REVIEW_GATE_BY_KIND = {
77
+ memory: reviewGateMemory,
78
+ skill: reviewGateSkill,
79
+ };
80
+ /** The evolve definition one review candidate loads, by item kind. */
81
+ export const REVIEW_EVOLVE_BY_KIND = {
82
+ memory: reviewEvolveMemory,
83
+ skill: reviewEvolveSkill,
84
+ };
85
+ //# sourceMappingURL=subagent-defs.js.map
@@ -0,0 +1,81 @@
1
+ /**
2
+ * The generic subagent and its loader: the only path from plugin feature code
3
+ * to an LLM call.
4
+ *
5
+ * A subagent is data — a strategy holding its identity, system prompt, output
6
+ * budget fallback and answer parser. The loader binds that strategy to one
7
+ * route and session, then runs it through one fixed skeleton (the template
8
+ * method): assemble the call, stream it, parse the answer, account for what
9
+ * happened. Failure accounting rides the same skeleton as success: the route
10
+ * and the usage a stream reported before it died come back on the thrown
11
+ * error, so a failed call can be audited exactly like a successful one.
12
+ *
13
+ * The structure is the point. "Which subagents exist and what each one is
14
+ * told" is readable in one table (`subagent-defs.ts`) instead of being spread
15
+ * across call sites, and a job that has no definition cannot be called.
16
+ */
17
+ import { SubagentCallError, type LlmRuntime, type ModelSelection } from "./llm-call.js";
18
+ /** One subagent definition: everything that distinguishes one job from another. */
19
+ export interface SubagentDefinition<Answer> {
20
+ /** The job's name, for diagnostics; unique across the registry (asserted by test). */
21
+ readonly id: string;
22
+ /** The job's entire instruction, sent as the system prompt — nothing is appended at the call site. */
23
+ readonly system: string;
24
+ /** Output budget fallback; the exact model's advertised cap wins when it has one. */
25
+ readonly maxTokens: number;
26
+ /**
27
+ * Parse the answer text into this definition's answer type. A parser that
28
+ * can miss (`parseGateAnswer`, `parseCheapAnswer` …) includes `null` in its
29
+ * answer type: "no answer in the agreed shape" is a value, not a throw.
30
+ */
31
+ readonly parse: (text: string) => Answer;
32
+ }
33
+ /** What one call is bound to: the LLM service, the exact route, the session identity. */
34
+ export interface SubagentCall {
35
+ llm: LlmRuntime | undefined;
36
+ route: ModelSelection;
37
+ sessionId: string | undefined;
38
+ }
39
+ /** One finished call: the parsed answer, the raw text, and the observed call facts. */
40
+ export interface SubagentAnswer<Answer> {
41
+ answer: Answer;
42
+ text: string;
43
+ /** The provider's usage payload, exactly as observed; `undefined` when it reported none. */
44
+ usage: unknown;
45
+ /** The terminal finish kind (`stop`, `max-tokens`, …); `undefined` when the stream omitted it. */
46
+ finish: string | undefined;
47
+ }
48
+ /** The loader feature code holds: bound to one route/session, it runs definitions. */
49
+ export interface SubagentLoader {
50
+ /**
51
+ * Run one definition once.
52
+ *
53
+ * @param definition - The subagent strategy to run.
54
+ * @param prompt - This call's user prompt.
55
+ * @returns The parsed answer plus the observed usage and finish kind.
56
+ * @throws On call failures (a `SubagentCallError` carries the observed usage and route) or a missing route.
57
+ */
58
+ run<Answer>(definition: SubagentDefinition<Answer>, prompt: string): Promise<SubagentAnswer<Answer>>;
59
+ }
60
+ /**
61
+ * Build the loader for one call context — the simple factory: the context
62
+ * produces the bound runner, the definitions table produces the strategies.
63
+ *
64
+ * @param call - The LLM service, the exact route, and the session identity to send.
65
+ * @returns A loader whose `run` is the only LLM entry point a feature needs.
66
+ */
67
+ export declare function subagentLoaderFor(call: SubagentCall): SubagentLoader;
68
+ /**
69
+ * Reject one answer as a failed call because the stream was cut.
70
+ *
71
+ * A cut answer is unusable by design — a half-written body must never become a
72
+ * verdict, and a gate that produced no verdict is not an approval. The error
73
+ * carries the facts the call already reported, so the failure is accounted
74
+ * exactly like a transport failure instead of vanishing.
75
+ *
76
+ * @param answer - The cut answer.
77
+ * @param route - The route it ran on.
78
+ * @returns The error to throw.
79
+ */
80
+ export declare function cutFailureOf<Answer>(answer: SubagentAnswer<Answer>, route: ModelSelection): SubagentCallError;
81
+ //# sourceMappingURL=subagent.d.ts.map
@@ -0,0 +1,52 @@
1
+ /**
2
+ * The generic subagent and its loader: the only path from plugin feature code
3
+ * to an LLM call.
4
+ *
5
+ * A subagent is data — a strategy holding its identity, system prompt, output
6
+ * budget fallback and answer parser. The loader binds that strategy to one
7
+ * route and session, then runs it through one fixed skeleton (the template
8
+ * method): assemble the call, stream it, parse the answer, account for what
9
+ * happened. Failure accounting rides the same skeleton as success: the route
10
+ * and the usage a stream reported before it died come back on the thrown
11
+ * error, so a failed call can be audited exactly like a successful one.
12
+ *
13
+ * The structure is the point. "Which subagents exist and what each one is
14
+ * told" is readable in one table (`subagent-defs.ts`) instead of being spread
15
+ * across call sites, and a job that has no definition cannot be called.
16
+ */
17
+ import { SubagentCallError, streamOnce } from "./llm-call.js";
18
+ /**
19
+ * Build the loader for one call context — the simple factory: the context
20
+ * produces the bound runner, the definitions table produces the strategies.
21
+ *
22
+ * @param call - The LLM service, the exact route, and the session identity to send.
23
+ * @returns A loader whose `run` is the only LLM entry point a feature needs.
24
+ */
25
+ export function subagentLoaderFor(call) {
26
+ return {
27
+ async run(definition, prompt) {
28
+ const result = await streamOnce(call.llm, call.route, call.sessionId, definition.system, prompt, definition.maxTokens);
29
+ return { answer: definition.parse(result.text), text: result.text, usage: result.usage, finish: result.finish };
30
+ },
31
+ };
32
+ }
33
+ /**
34
+ * Reject one answer as a failed call because the stream was cut.
35
+ *
36
+ * A cut answer is unusable by design — a half-written body must never become a
37
+ * verdict, and a gate that produced no verdict is not an approval. The error
38
+ * carries the facts the call already reported, so the failure is accounted
39
+ * exactly like a transport failure instead of vanishing.
40
+ *
41
+ * @param answer - The cut answer.
42
+ * @param route - The route it ran on.
43
+ * @returns The error to throw.
44
+ */
45
+ export function cutFailureOf(answer, route) {
46
+ return new SubagentCallError(`stream finished with ${answer.finish ?? "unknown"}`, {
47
+ usage: answer.usage,
48
+ finish: answer.finish,
49
+ route,
50
+ });
51
+ }
52
+ //# sourceMappingURL=subagent.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-continual-evolve",
3
- "version": "0.15.11",
3
+ "version": "0.15.13",
4
4
  "description": "ZCode-style workspace memory for DeepSeek Harness: one central SQLite store partitioned by workspace, index injection, and sole-writer gated writes.",
5
5
  "license": "MIT",
6
6
  "repository": {