@mcp-abap-adt/llm-agent-server-libs 19.1.2 → 19.2.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 (107) hide show
  1. package/dist/factories/controller-factory.d.ts +18 -4
  2. package/dist/factories/controller-factory.d.ts.map +1 -1
  3. package/dist/factories/controller-factory.js +50 -10
  4. package/dist/factories/controller-factory.js.map +1 -1
  5. package/dist/generated/version.d.ts +1 -1
  6. package/dist/generated/version.js +1 -1
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/pipelines/controller.d.ts.map +1 -1
  12. package/dist/pipelines/controller.js +41 -0
  13. package/dist/pipelines/controller.js.map +1 -1
  14. package/dist/pipelines/dag.d.ts.map +1 -1
  15. package/dist/pipelines/dag.js +2 -1
  16. package/dist/pipelines/dag.js.map +1 -1
  17. package/dist/pipelines/flat.d.ts.map +1 -1
  18. package/dist/pipelines/flat.js +2 -1
  19. package/dist/pipelines/flat.js.map +1 -1
  20. package/dist/pipelines/linear.d.ts.map +1 -1
  21. package/dist/pipelines/linear.js +2 -1
  22. package/dist/pipelines/linear.js.map +1 -1
  23. package/dist/pipelines/register-skill-sources.d.ts +21 -0
  24. package/dist/pipelines/register-skill-sources.d.ts.map +1 -0
  25. package/dist/pipelines/register-skill-sources.js +57 -0
  26. package/dist/pipelines/register-skill-sources.js.map +1 -0
  27. package/dist/pipelines/server-context.d.ts +37 -1
  28. package/dist/pipelines/server-context.d.ts.map +1 -1
  29. package/dist/pipelines/server-context.js.map +1 -1
  30. package/dist/smart-agent/config.d.ts.map +1 -1
  31. package/dist/smart-agent/config.js +4 -0
  32. package/dist/smart-agent/config.js.map +1 -1
  33. package/dist/smart-agent/controller/artifacts.d.ts +116 -0
  34. package/dist/smart-agent/controller/artifacts.d.ts.map +1 -0
  35. package/dist/smart-agent/controller/artifacts.js +192 -0
  36. package/dist/smart-agent/controller/artifacts.js.map +1 -0
  37. package/dist/smart-agent/controller/board.d.ts +73 -0
  38. package/dist/smart-agent/controller/board.d.ts.map +1 -0
  39. package/dist/smart-agent/controller/board.js +233 -0
  40. package/dist/smart-agent/controller/board.js.map +1 -0
  41. package/dist/smart-agent/controller/controller-coordinator-handler.d.ts +67 -7
  42. package/dist/smart-agent/controller/controller-coordinator-handler.d.ts.map +1 -1
  43. package/dist/smart-agent/controller/controller-coordinator-handler.js +923 -61
  44. package/dist/smart-agent/controller/controller-coordinator-handler.js.map +1 -1
  45. package/dist/smart-agent/controller/finalizer.d.ts +48 -0
  46. package/dist/smart-agent/controller/finalizer.d.ts.map +1 -0
  47. package/dist/smart-agent/controller/finalizer.js +126 -0
  48. package/dist/smart-agent/controller/finalizer.js.map +1 -0
  49. package/dist/smart-agent/controller/memorizer.d.ts +2 -2
  50. package/dist/smart-agent/controller/memorizer.d.ts.map +1 -1
  51. package/dist/smart-agent/controller/memorizer.js +2 -2
  52. package/dist/smart-agent/controller/memorizer.js.map +1 -1
  53. package/dist/smart-agent/controller/outcome.d.ts +28 -0
  54. package/dist/smart-agent/controller/outcome.d.ts.map +1 -0
  55. package/dist/smart-agent/controller/outcome.js +30 -0
  56. package/dist/smart-agent/controller/outcome.js.map +1 -0
  57. package/dist/smart-agent/controller/planner.d.ts +28 -5
  58. package/dist/smart-agent/controller/planner.d.ts.map +1 -1
  59. package/dist/smart-agent/controller/planner.js +111 -29
  60. package/dist/smart-agent/controller/planner.js.map +1 -1
  61. package/dist/smart-agent/controller/reviewer.d.ts +48 -0
  62. package/dist/smart-agent/controller/reviewer.d.ts.map +1 -0
  63. package/dist/smart-agent/controller/reviewer.js +116 -0
  64. package/dist/smart-agent/controller/reviewer.js.map +1 -0
  65. package/dist/smart-agent/controller/run-scope.d.ts +50 -0
  66. package/dist/smart-agent/controller/run-scope.d.ts.map +1 -0
  67. package/dist/smart-agent/controller/run-scope.js +99 -0
  68. package/dist/smart-agent/controller/run-scope.js.map +1 -0
  69. package/dist/smart-agent/controller/session-bundle.d.ts +5 -0
  70. package/dist/smart-agent/controller/session-bundle.d.ts.map +1 -1
  71. package/dist/smart-agent/controller/session-bundle.js +27 -0
  72. package/dist/smart-agent/controller/session-bundle.js.map +1 -1
  73. package/dist/smart-agent/controller/types.d.ts +117 -7
  74. package/dist/smart-agent/controller/types.d.ts.map +1 -1
  75. package/dist/smart-agent/controller/types.js +30 -1
  76. package/dist/smart-agent/controller/types.js.map +1 -1
  77. package/dist/smart-agent/embedder-knowledge-index.d.ts +28 -0
  78. package/dist/smart-agent/embedder-knowledge-index.d.ts.map +1 -0
  79. package/dist/smart-agent/embedder-knowledge-index.js +71 -0
  80. package/dist/smart-agent/embedder-knowledge-index.js.map +1 -0
  81. package/dist/smart-agent/jsonl-knowledge-backend.d.ts +26 -10
  82. package/dist/smart-agent/jsonl-knowledge-backend.d.ts.map +1 -1
  83. package/dist/smart-agent/jsonl-knowledge-backend.js +81 -9
  84. package/dist/smart-agent/jsonl-knowledge-backend.js.map +1 -1
  85. package/dist/smart-agent/pg-pool.d.ts +58 -0
  86. package/dist/smart-agent/pg-pool.d.ts.map +1 -0
  87. package/dist/smart-agent/pg-pool.js +149 -0
  88. package/dist/smart-agent/pg-pool.js.map +1 -0
  89. package/dist/smart-agent/skill-plugins-config.d.ts +97 -0
  90. package/dist/smart-agent/skill-plugins-config.d.ts.map +1 -0
  91. package/dist/smart-agent/skill-plugins-config.js +318 -0
  92. package/dist/smart-agent/skill-plugins-config.js.map +1 -0
  93. package/dist/smart-agent/skill-plugins-config.test.d.ts +2 -0
  94. package/dist/smart-agent/skill-plugins-config.test.d.ts.map +1 -0
  95. package/dist/smart-agent/skill-plugins-config.test.js.map +1 -0
  96. package/dist/smart-agent/skill-plugins-host-factory.d.ts +98 -0
  97. package/dist/smart-agent/skill-plugins-host-factory.d.ts.map +1 -0
  98. package/dist/smart-agent/skill-plugins-host-factory.js +284 -0
  99. package/dist/smart-agent/skill-plugins-host-factory.js.map +1 -0
  100. package/dist/smart-agent/skill-plugins-host-factory.test.d.ts +2 -0
  101. package/dist/smart-agent/skill-plugins-host-factory.test.d.ts.map +1 -0
  102. package/dist/smart-agent/skill-plugins-host-factory.test.js.map +1 -0
  103. package/dist/smart-agent/smart-server.d.ts +25 -0
  104. package/dist/smart-agent/smart-server.d.ts.map +1 -1
  105. package/dist/smart-agent/smart-server.js +139 -6
  106. package/dist/smart-agent/smart-server.js.map +1 -1
  107. package/package.json +9 -7
@@ -1,6 +1,21 @@
1
+ import { mintCreateStepIds, mintReplanStepIds, } from './artifacts.js';
1
2
  import { extractJsonObject, parseNextStep, } from './controller-coordinator-handler.js';
2
3
  import { appendHint } from './prompts.js';
3
- const PLANNER_SYSTEM = 'You are the planner. Given the goal and progress, return a SINGLE JSON ' +
4
+ import { MAX_REQUIRE_CHARS, MAX_REQUIRES, validateRequires, } from './types.js';
5
+ // Built from the validation constants so the prompt cap can NEVER drift from what
6
+ // the parser enforces (no duplicated literals). Appended to EVERY planner/replan
7
+ // prompt as a HARD invariant so step instructions/requires are English (stable
8
+ // tool selection against the English-translated catalog) and the requires count is
9
+ // bounded.
10
+ export const ENGLISH_INSTRUCTIONS_RULE = ' Step `instructions` AND `requires` references MUST be written in English — ' +
11
+ "always, regardless of the language of the user's request. This is a hard " +
12
+ 'contract: the executor selects tools by semantic match against an ' +
13
+ 'English-translated catalog, and the reviewer matches `requires` against stored ' +
14
+ 'artifacts — so non-English instructions/requires break both. ' +
15
+ `List at MOST ${MAX_REQUIRES} \`requires\`, each a SHORT reference (a few words, ` +
16
+ `≤ ${MAX_REQUIRE_CHARS} chars) — not pasted content. (The user-facing answer is ` +
17
+ "composed separately in the user's language.)";
18
+ export const PLANNER_SYSTEM = 'You are the planner. Given the goal and progress, return a SINGLE JSON ' +
4
19
  'object: {"kind":"next","step":{"name":...,"instructions":...}} to take the ' +
5
20
  'next step, {"kind":"done","result":...} when the goal is met, or ' +
6
21
  '{"kind":"rewind","reason":...} to discard the current path. Output JSON only.\n' +
@@ -15,20 +30,43 @@ const PLANNER_SYSTEM = 'You are the planner. Given the goal and progress, return
15
30
  'Keep each step MINIMAL and do NOT broaden the scope beyond what the goal asks, ' +
16
31
  'at the granularity it asks: a LIST/SHOW/find request is satisfied by the list ' +
17
32
  'itself — do NOT plan a step that fetches the full details of every listed item ' +
18
- 'unless the goal explicitly asks for per-item details.';
33
+ 'unless the goal explicitly asks for per-item details.' +
34
+ ENGLISH_INSTRUCTIONS_RULE;
19
35
  const RETRY_HINT = '\nIMPORTANT: your previous reply was NOT valid JSON. Reply with ONLY the raw ' +
20
36
  'JSON object — no prose, no explanation, no markdown code fences.';
37
+ /** Append a non-empty recall block to a user message, preserving the agnostic
38
+ * message byte-for-byte when the block is empty. */
39
+ function withSkillsBlock(userContent, block) {
40
+ return block ? `${userContent}\n\n${block}` : userContent;
41
+ }
42
+ /** The planner's progress context. With a live board, render the AUTHORITATIVE
43
+ * structured board AND the plannerPrivate tail — the latter carries non-board
44
+ * deltas the planner still needs (clarify answers, legacy external-tool result).
45
+ * An empty board (decision-less IncrementalPlanner) → plannerPrivate alone,
46
+ * byte-identical to the legacy prompt. */
47
+ function progressBlock(bundle, boardText) {
48
+ return boardText && boardText.length > 0
49
+ ? `${boardText}\n${bundle.plannerPrivate}`
50
+ : bundle.plannerPrivate;
51
+ }
21
52
  export class IncrementalPlanner {
22
53
  planner;
23
54
  hint;
55
+ skillsRecall;
24
56
  constructor(planner,
25
57
  /** Optional consumer domain hint appended to the agnostic planner prompt. */
26
- hint) {
58
+ hint,
59
+ /** Optional controller-own skills recall hook (B4). */
60
+ skillsRecall) {
27
61
  this.planner = planner;
28
62
  this.hint = hint;
63
+ this.skillsRecall = skillsRecall;
29
64
  }
30
65
  async next(input) {
31
- const { bundle, prompt, retrying, logUsage } = input;
66
+ const { bundle, prompt, retrying, logUsage, options, boardText } = input;
67
+ const block = this.skillsRecall
68
+ ? await this.skillsRecall(bundle.goal, options)
69
+ : '';
32
70
  const res = await this.planner.send([
33
71
  {
34
72
  role: 'system',
@@ -36,7 +74,7 @@ export class IncrementalPlanner {
36
74
  },
37
75
  {
38
76
  role: 'user',
39
- content: `Goal: ${bundle.goal}\nProgress:${bundle.plannerPrivate}\nRequest: ${prompt}`,
77
+ content: withSkillsBlock(`Goal: ${bundle.goal}\nProgress:${progressBlock(bundle, boardText)}\nRequest: ${prompt}`, block),
40
78
  },
41
79
  ]);
42
80
  logUsage?.('planner', res.usage);
@@ -45,7 +83,7 @@ export class IncrementalPlanner {
45
83
  return parseNextStep(res.content);
46
84
  }
47
85
  }
48
- const CREATE_PLAN_SYSTEM = 'You are the planner. Produce the COMPLETE, ordered plan that covers the ENTIRE ' +
86
+ export const CREATE_PLAN_SYSTEM = 'You are the planner. Produce the COMPLETE, ordered plan that covers the ENTIRE ' +
49
87
  'goal NOW, as a SINGLE JSON object: {"plan":[{"name":...,"instructions":...}, ...]}. ' +
50
88
  'This is plan-once: there will be NO chance to add steps later (a replan happens ' +
51
89
  'only if a step FAILS), so the plan MUST already contain every step the goal ' +
@@ -71,16 +109,18 @@ const CREATE_PLAN_SYSTEM = 'You are the planner. Produce the COMPLETE, ordered p
71
109
  'Do NOT add a final step ' +
72
110
  'that summarizes, formats, or answers the user — a separate finalizer composes ' +
73
111
  'the answer from the fetched results, so the last step must be the last ' +
74
- 'data-fetch/action the goal needs. Output JSON only.';
75
- const REPLAN_SYSTEM = 'You are the planner. A step just FAILED. Given the goal, the progress so far ' +
112
+ 'data-fetch/action the goal needs. Output JSON only.' +
113
+ ENGLISH_INSTRUCTIONS_RULE;
114
+ export const REPLAN_SYSTEM = 'You are the planner. A step just FAILED. Given the goal, the progress so far ' +
76
115
  '(fetched results + the failure), produce a REVISED, MINIMAL plan for the ' +
77
116
  'REMAINING work as {"plan":[{"name":...,"instructions":...}, ...]}. Plan only ' +
78
117
  'the data-fetch/action steps still required; describe each step by INTENT — do ' +
79
118
  'NOT name or choose a specific tool, the executor selects it. Do NOT add a ' +
80
119
  'final summarize/' +
81
120
  'answer step (a separate finalizer composes the answer). If the goal is ' +
82
- 'already satisfied despite the failure, return {"plan":[]}. Output JSON only.';
83
- const EXTERNAL_RESULT_REPLAN_SYSTEM = 'You are the planner. A NEW external tool result just arrived (see Progress) — ' +
121
+ 'already satisfied despite the failure, return {"plan":[]}. Output JSON only.' +
122
+ ENGLISH_INSTRUCTIONS_RULE;
123
+ export const EXTERNAL_RESULT_REPLAN_SYSTEM = 'You are the planner. A NEW external tool result just arrived (see Progress) — ' +
84
124
  'this is NOT a failure. Given the goal and the progress (including the new ' +
85
125
  'result), produce a REVISED, MINIMAL plan for the REMAINING work as ' +
86
126
  '{"plan":[{"name":...,"instructions":...}, ...]}. Plan only the data-fetch/' +
@@ -88,7 +128,8 @@ const EXTERNAL_RESULT_REPLAN_SYSTEM = 'You are the planner. A NEW external tool
88
128
  'choose a specific tool, the executor selects it. Do NOT add a final summarize/' +
89
129
  'answer step (a ' +
90
130
  'separate finalizer composes the answer). If the goal is already satisfied by ' +
91
- 'the result, return {"plan":[]}. Output JSON only.';
131
+ 'the result, return {"plan":[]}. Output JSON only.' +
132
+ ENGLISH_INSTRUCTIONS_RULE;
92
133
  const FINALIZE_SYSTEM = 'All planned steps are complete. Using the progress below (the fetched results), ' +
93
134
  'write the final answer to the user request. Plain text, no JSON.';
94
135
  /** Parse {"plan":[{name,instructions},...]} from a (possibly fenced) reply.
@@ -110,10 +151,14 @@ function parsePlan(content) {
110
151
  if (typeof s.name !== 'string' || typeof s.instructions !== 'string') {
111
152
  return null; // malformed step → format failure (handler retries)
112
153
  }
154
+ const req = validateRequires(raw.requires);
155
+ if (req === false)
156
+ return null; // malformed requires → format failure → retry
113
157
  steps.push({
114
158
  name: s.name,
115
159
  instructions: s.instructions,
116
160
  ...(s.type ? { type: s.type } : {}),
161
+ ...(req ? { requires: req } : {}),
117
162
  });
118
163
  }
119
164
  return steps;
@@ -122,40 +167,60 @@ function parsePlan(content) {
122
167
  return null;
123
168
  }
124
169
  }
170
+ /** Queue a plan decision for the controller to persist (§A boundary: the planner
171
+ * CONSTRUCTS the decision; the controller does the durable write). */
172
+ function recordDecision(bundle, decision) {
173
+ if (!bundle.pendingPlanDecisions)
174
+ bundle.pendingPlanDecisions = [];
175
+ bundle.pendingPlanDecisions.push(decision);
176
+ }
125
177
  export class AdaptivePlanner {
126
178
  planner;
127
179
  hint;
180
+ skillsRecall;
128
181
  // No budget field: replans are bounded by the loop's maxSteps (a failed step
129
182
  // bumps stepsUsed in runStep). Replan-specific budgeting is the deferred
130
183
  // "limits as a selectable strategy" work.
131
184
  constructor(planner,
132
185
  /** Optional consumer domain hint appended to every agnostic planner/
133
186
  * create-plan/replan/finalize prompt this planner emits. */
134
- hint) {
187
+ hint,
188
+ /** Optional controller-own skills recall hook (B4). Queried before each
189
+ * create-plan/replan; its block is injected into the user message. */
190
+ skillsRecall) {
135
191
  this.planner = planner;
136
192
  this.hint = hint;
193
+ this.skillsRecall = skillsRecall;
137
194
  }
138
195
  async next(input) {
139
- const { bundle, prompt, lastOutcome, resumedExternal, retrying, logUsage } = input;
196
+ const { bundle, prompt, lastOutcome, resumedExternal, retrying, logUsage, options, boardText, } = input;
140
197
  // 1. No plan yet → create it.
141
198
  if (!bundle.plan) {
142
- const plan = await this.callPlan(CREATE_PLAN_SYSTEM, bundle, prompt, retrying, logUsage);
199
+ const plan = await this.callPlan(CREATE_PLAN_SYSTEM, bundle, prompt, retrying, logUsage, [], options, boardText);
143
200
  // An EMPTY plan from createPlan is invalid: it would skip straight to the
144
201
  // finalizer and answer WITHOUT fetching the required data. Treat it as a
145
202
  // format failure → handler re-asks (bounded by maxRetries). (An empty plan
146
203
  // is only valid on REPLAN, where it means "remaining work is done".)
147
204
  if (plan === null || plan.length === 0)
148
205
  return null;
149
- bundle.plan = plan;
206
+ const minted = mintCreateStepIds(plan, bundle.runId ?? '');
207
+ bundle.plan = minted;
150
208
  bundle.planCursor = 0;
151
- return this.stepAtCursor(bundle, prompt, logUsage);
209
+ recordDecision(bundle, {
210
+ kind: 'create',
211
+ runId: bundle.runId ?? '',
212
+ steps: minted,
213
+ });
214
+ return this.stepAtCursor(bundle, prompt, logUsage, boardText);
152
215
  }
153
216
  // 2. Previous step failed, OR an external-tool result just arrived → replan
154
217
  // the remainder from the cursor. The planner reads plannerPrivate (which
155
218
  // now holds the failure/external result), so the revised plan incorporates
156
219
  // it — no reliance on the executor seeing it. Use the matching prompt: an
157
220
  // external result is NOT a failure, so it gets its own framing.
158
- if (lastOutcome === 'failed' || resumedExternal) {
221
+ if (lastOutcome === 'failed' ||
222
+ lastOutcome === 'partial' ||
223
+ resumedExternal) {
159
224
  const system = resumedExternal
160
225
  ? EXTERNAL_RESULT_REPLAN_SYSTEM
161
226
  : REPLAN_SYSTEM;
@@ -163,29 +228,40 @@ export class AdaptivePlanner {
163
228
  // Steps before the cursor already ran successfully — pass them so the replan
164
229
  // plans only the remaining work and never repeats a completed step.
165
230
  const completed = bundle.plan.slice(0, cursor);
166
- const rest = await this.callPlan(system, bundle, prompt, retrying, logUsage, completed);
231
+ const rest = await this.callPlan(system, bundle, prompt, retrying, logUsage, completed, options, boardText);
167
232
  if (rest === null)
168
233
  return null;
169
- bundle.plan = [...bundle.plan.slice(0, cursor), ...rest];
234
+ const anchor = bundle.plan[cursor]?.stepId ?? '';
235
+ const mintedRest = mintReplanStepIds(rest, bundle.runId ?? '', anchor);
236
+ bundle.plan = [...bundle.plan.slice(0, cursor), ...mintedRest];
237
+ recordDecision(bundle, {
238
+ kind: 'replan',
239
+ runId: bundle.runId ?? '',
240
+ anchor,
241
+ steps: mintedRest,
242
+ });
170
243
  // The failure has now been consumed into the revised plan. Clear the durable
171
244
  // failure marker BEFORE the (possible) finalize below, so that: a crash after
172
245
  // this replan does NOT replan again on resume, and a finalizer error after an
173
246
  // empty replan retries only the finalizer (not another replan).
174
247
  bundle.lastOutcome = undefined;
175
- return this.stepAtCursor(bundle, prompt, logUsage);
248
+ return this.stepAtCursor(bundle, prompt, logUsage, boardText);
176
249
  }
177
250
  // 3. Otherwise emit the step at the cursor (or finalize). The cursor is
178
251
  // advanced by commit() AFTER a step succeeds — NOT here — so the advance
179
252
  // is persisted together with the step result (see Task 4), and a resume
180
253
  // with lastOutcome=undefined continues from the next uncompleted step
181
254
  // instead of repeating the last one.
182
- return this.stepAtCursor(bundle, prompt, logUsage);
255
+ return this.stepAtCursor(bundle, prompt, logUsage, boardText);
183
256
  }
184
257
  /** Commit the just-finished step's outcome so the advance is persisted with it.
185
258
  * On success the cursor moves to the next step; a failure leaves the cursor so
186
259
  * the next next() can replan from it. (No LLM call — pure bookkeeping.) */
187
260
  commit(bundle, outcome) {
188
- if (outcome === 'advanced') {
261
+ // 'advanced' and 'partial' both advance the cursor: the accepted part of a
262
+ // partial is committed and must not be re-run (the remainder is replanned at
263
+ // the next cursor). 'failed' leaves the cursor for next()'s replan.
264
+ if (outcome === 'advanced' || outcome === 'partial') {
189
265
  bundle.planCursor = (bundle.planCursor ?? 0) + 1;
190
266
  }
191
267
  }
@@ -193,7 +269,7 @@ export class AdaptivePlanner {
193
269
  * Returns null when the finalizer call fails (error / unexpected tool_call) so
194
270
  * the handler retries it (bounded by maxRetries) instead of emitting a fake
195
271
  * "completed" answer. */
196
- async stepAtCursor(bundle, prompt, logUsage) {
272
+ async stepAtCursor(bundle, prompt, logUsage, boardText) {
197
273
  const plan = bundle.plan ?? [];
198
274
  const cursor = bundle.planCursor ?? 0;
199
275
  if (cursor >= plan.length) {
@@ -201,7 +277,7 @@ export class AdaptivePlanner {
201
277
  { role: 'system', content: appendHint(FINALIZE_SYSTEM, this.hint) },
202
278
  {
203
279
  role: 'user',
204
- content: `Goal: ${bundle.goal}\nRequest: ${prompt}\nProgress:${bundle.plannerPrivate}`,
280
+ content: `Goal: ${bundle.goal}\nRequest: ${prompt}\nProgress:${progressBlock(bundle, boardText)}`,
205
281
  },
206
282
  ]);
207
283
  logUsage?.('finalizer', res.usage);
@@ -213,13 +289,19 @@ export class AdaptivePlanner {
213
289
  }
214
290
  return { kind: 'next', step: plan[cursor] };
215
291
  }
216
- async callPlan(system, bundle, prompt, retrying, logUsage, completed = []) {
292
+ async callPlan(system, bundle, prompt, retrying, logUsage, completed = [], options, boardText) {
217
293
  // On replan, the planner MUST know which steps already ran (their results are
218
294
  // in Progress / the step-result collection) so it plans ONLY the remaining
219
295
  // work and never re-executes a completed step.
220
296
  const completedBlock = completed.length
221
297
  ? `\nALREADY-EXECUTED steps — their results are in Progress above; do NOT plan or repeat these, plan only what is still missing:\n${completed.map((s) => `- ${s.name}`).join('\n')}`
222
298
  : '';
299
+ // Recall the configured controller skill group BEFORE the LLM call and inject
300
+ // its bounded block. When the hook is absent OR returns '' the user message is
301
+ // byte-identical to the agnostic prompt (the measurement toggle).
302
+ const skillsBlock = this.skillsRecall
303
+ ? await this.skillsRecall(bundle.goal, options)
304
+ : '';
223
305
  const res = await this.planner.send([
224
306
  {
225
307
  role: 'system',
@@ -230,7 +312,7 @@ export class AdaptivePlanner {
230
312
  },
231
313
  {
232
314
  role: 'user',
233
- content: `Goal: ${bundle.goal}\nProgress:${bundle.plannerPrivate}${completedBlock}\nRequest: ${prompt}`,
315
+ content: withSkillsBlock(`Goal: ${bundle.goal}\nProgress:${progressBlock(bundle, boardText)}${completedBlock}\nRequest: ${prompt}`, skillsBlock),
234
316
  },
235
317
  ]);
236
318
  logUsage?.('planner', res.usage);
@@ -239,9 +321,9 @@ export class AdaptivePlanner {
239
321
  return parsePlan(res.content);
240
322
  }
241
323
  }
242
- export function makePlanner(kind, planner, hint) {
324
+ export function makePlanner(kind, planner, hint, skillsRecall) {
243
325
  return kind === 'adaptive'
244
- ? new AdaptivePlanner(planner, hint)
245
- : new IncrementalPlanner(planner, hint);
326
+ ? new AdaptivePlanner(planner, hint, skillsRecall)
327
+ : new IncrementalPlanner(planner, hint, skillsRecall);
246
328
  }
247
329
  //# sourceMappingURL=planner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner.js","sourceRoot":"","sources":["../../../src/smart-agent/controller/planner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"planner.js","sourceRoot":"","sources":["../../../src/smart-agent/controller/planner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import type { LlmUsage } from '@mcp-abap-adt/llm-agent';
2
+ import type { ReviewOutcome } from './outcome.js';
3
+ import type { ISubagentClient } from './subagent-client.js';
4
+ import type { Step } from './types.js';
5
+ /** One reference's evidence: the closest stored artifact's content (or none). */
6
+ export interface Evidence {
7
+ ref: string;
8
+ hit: boolean;
9
+ topArtifact?: string;
10
+ }
11
+ export interface ReviewOpts {
12
+ hint?: string;
13
+ logUsage?: (role: string, u?: LlmUsage) => void;
14
+ /** Defensive cap on the returned `digest` (§B). Defaults to 500 when omitted. */
15
+ maxDigestChars?: number;
16
+ }
17
+ /** The reviewer's return: EITHER an authoritative step Outcome (incl. a genuine
18
+ * `failed` verdict → step replan), OR a judge-failure — the reviewer could not
19
+ * produce ANY usable verdict (provider/transport error, unparsable JSON, or a
20
+ * missing/invalid status). The controller re-asks a judge-failure within
21
+ * `maxReviewRetries` and, on exhaustion, DEGRADES it to a failed step (→ replan),
22
+ * bounded by `maxStepAttempts`/`maxSteps` — it does NOT abort the run. (A
23
+ * well-formed but contradictory verdict — ok/exists/partial with empty `approved` —
24
+ * is coerced to a `failed` Outcome in `parseReview`, NOT a judge-failure.) */
25
+ export type ReviewResult = {
26
+ kind: 'outcome';
27
+ outcome: ReviewOutcome;
28
+ } | {
29
+ kind: 'judge-failure';
30
+ reason: string;
31
+ };
32
+ /** Separate judging role. The controller depends ONLY on this; `status` always
33
+ * comes through a well-formed Outcome. Default impl is LLM-backed; swappable. */
34
+ export interface IReviewer {
35
+ review(step: Step, evidence: readonly Evidence[], executorResult: string, opts: ReviewOpts): Promise<ReviewResult>;
36
+ }
37
+ export declare class LlmReviewer implements IReviewer {
38
+ private readonly client;
39
+ constructor(client: ISubagentClient);
40
+ review(step: Step, evidence: readonly Evidence[], executorResult: string, opts: ReviewOpts): Promise<ReviewResult>;
41
+ }
42
+ /** Parse a reviewer reply into a ReviewResult. A well-formed verdict (any of
43
+ * ok/exists/partial/failed) is an `outcome`; ok/exists/partial with EMPTY approved
44
+ * is coerced to a `failed` outcome (contradictory → replan, not abort). Only a
45
+ * truly unusable reply — unparsable JSON or missing/invalid status — is a
46
+ * `judge-failure` (re-ask within budget, then degrade to a failed step). */
47
+ export declare function parseReview(content: string, maxDigestChars?: number): ReviewResult;
48
+ //# sourceMappingURL=reviewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewer.d.ts","sourceRoot":"","sources":["../../../src/smart-agent/controller/reviewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,iFAAiF;AACjF,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC;IAChD,iFAAiF;IACjF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;+EAO+E;AAC/E,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9C;kFACkF;AAClF,MAAM,WAAW,SAAS;IACxB,MAAM,CACJ,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,SAAS,QAAQ,EAAE,EAC7B,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,YAAY,CAAC,CAAC;CAC1B;AAwBD,qBAAa,WAAY,YAAW,SAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,eAAe;IAE9C,MAAM,CACV,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,SAAS,QAAQ,EAAE,EAC7B,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,YAAY,CAAC;CA8BzB;AAED;;;;6EAI6E;AAC7E,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,cAAc,SAAM,GACnB,YAAY,CAyDd"}
@@ -0,0 +1,116 @@
1
+ import { extractJsonObject } from './controller-coordinator-handler.js';
2
+ import { appendHint } from './prompts.js';
3
+ const REVIEWER_SYSTEM = 'You are the reviewer. You did NOT do the work — you JUDGE it. Given the ' +
4
+ "step intent, the per-reference evidence, and the executor's result, decide " +
5
+ 'the authoritative outcome and return a SINGLE JSON object: ' +
6
+ '{"status":"ok"|"exists"|"failed"|"partial","approved":<content to keep>,' +
7
+ '"remainder":<what is still missing>,"note":<short reason>,' +
8
+ '"digest":<a SHORT plain-text extract of what this step established that the ' +
9
+ 'PLANNER needs to decide the next step — e.g. the key names/ids/outcome, NOT ' +
10
+ 'the full content>}. ' +
11
+ 'Use "ok" when the step is fully satisfied, "exists" when the target already ' +
12
+ 'existed (idempotent no-op success), "partial" when only part is done (put the ' +
13
+ 'accepted content in "approved" and what remains in "remainder"), "failed" when ' +
14
+ 'the result does not satisfy the step. "approved" MUST be non-empty for ok/' +
15
+ 'exists/partial. Judge ONLY from the evidence + result; do NOT invent facts. ' +
16
+ 'The evidence lists, per required reference, the CLOSEST stored artifact (or ' +
17
+ 'MISSING). Decide for YOURSELF whether that artifact actually satisfies the ' +
18
+ 'reference — a closest-match artifact may be irrelevant; treat an unsatisfied or ' +
19
+ 'missing required reference as "failed" (note: "missing input: <ref>"). ' +
20
+ 'The "digest" is REQUIRED and MUST be a non-empty plain-text string (keep it ' +
21
+ 'brief — the full result is stored separately). ' +
22
+ 'Output JSON only.';
23
+ export class LlmReviewer {
24
+ client;
25
+ constructor(client) {
26
+ this.client = client;
27
+ }
28
+ async review(step, evidence, executorResult, opts) {
29
+ const evidenceBlock = evidence
30
+ .map((e) => e.topArtifact
31
+ ? // topArtifact is already a relevance-oriented, bounded extract.
32
+ `- ${e.ref}: closest artifact →\n${e.topArtifact}`
33
+ : `- ${e.ref}: MISSING (no artifact found)`)
34
+ .join('\n');
35
+ const res = await this.client.send([
36
+ { role: 'system', content: appendHint(REVIEWER_SYSTEM, opts.hint) },
37
+ {
38
+ role: 'user',
39
+ content: `Step: ${step.name}\nIntent: ${step.instructions}\n` +
40
+ `Evidence:\n${evidenceBlock || '(none)'}\n` +
41
+ `Executor result:\n${executorResult}`,
42
+ },
43
+ ]);
44
+ opts.logUsage?.('reviewer', res.usage);
45
+ if (res.kind !== 'content') {
46
+ // Provider/transport error → JUDGE failure (the verdict is unknown), NOT a
47
+ // step failure.
48
+ return {
49
+ kind: 'judge-failure',
50
+ reason: `reviewer error: ${res.kind === 'error' ? res.error : res.kind}`,
51
+ };
52
+ }
53
+ return parseReview(res.content, opts.maxDigestChars ?? 500);
54
+ }
55
+ }
56
+ /** Parse a reviewer reply into a ReviewResult. A well-formed verdict (any of
57
+ * ok/exists/partial/failed) is an `outcome`; ok/exists/partial with EMPTY approved
58
+ * is coerced to a `failed` outcome (contradictory → replan, not abort). Only a
59
+ * truly unusable reply — unparsable JSON or missing/invalid status — is a
60
+ * `judge-failure` (re-ask within budget, then degrade to a failed step). */
61
+ export function parseReview(content, maxDigestChars = 500) {
62
+ const json = extractJsonObject(content);
63
+ if (json === null)
64
+ return { kind: 'judge-failure', reason: 'unparsable reviewer reply' };
65
+ try {
66
+ const o = JSON.parse(json);
67
+ const status = o.status;
68
+ const approved = typeof o.approved === 'string' ? o.approved : '';
69
+ const remainder = typeof o.remainder === 'string' ? o.remainder : '';
70
+ const note = typeof o.note === 'string' ? o.note : '';
71
+ const rawDigest = typeof o.digest === 'string' ? o.digest : '';
72
+ if (status !== 'ok' &&
73
+ status !== 'exists' &&
74
+ status !== 'failed' &&
75
+ status !== 'partial') {
76
+ return { kind: 'judge-failure', reason: 'missing/invalid status' };
77
+ }
78
+ // Digest is REQUIRED on every settle (it is the planner's board content). A
79
+ // missing/empty digest is a judge-failure (re-ask), distinct from a real
80
+ // verdict. Bound it defensively (the full result is in RAG regardless).
81
+ if (rawDigest.trim().length === 0) {
82
+ return { kind: 'judge-failure', reason: 'missing digest' };
83
+ }
84
+ const digest = rawDigest.slice(0, maxDigestChars);
85
+ if ((status === 'ok' || status === 'exists' || status === 'partial') &&
86
+ approved.length === 0) {
87
+ const coercedNote = note
88
+ ? `${note} [coerced: reviewer returned ${status} with empty approved]`
89
+ : `reviewer returned ${status} with empty approved`;
90
+ return {
91
+ kind: 'outcome',
92
+ outcome: {
93
+ status: 'failed',
94
+ approved: '',
95
+ remainder: remainder || approved,
96
+ note: coercedNote,
97
+ digest: (note || coercedNote).slice(0, maxDigestChars),
98
+ },
99
+ };
100
+ }
101
+ if (status === 'partial' && remainder.trim().length === 0) {
102
+ return {
103
+ kind: 'outcome',
104
+ outcome: { status: 'ok', approved, remainder: '', note, digest },
105
+ };
106
+ }
107
+ return {
108
+ kind: 'outcome',
109
+ outcome: { status, approved, remainder, note, digest },
110
+ };
111
+ }
112
+ catch {
113
+ return { kind: 'judge-failure', reason: 'unparsable reviewer reply' };
114
+ }
115
+ }
116
+ //# sourceMappingURL=reviewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewer.js","sourceRoot":"","sources":["../../../src/smart-agent/controller/reviewer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { KnowledgeBackend } from '@mcp-abap-adt/llm-agent-libs';
2
+ import type { SessionBundle } from './types.js';
3
+ /** Injectable runId minter (matches the existing id-minter pattern); tests pass a
4
+ * deterministic counter. Default is time+random based. */
5
+ export type RunIdMinter = () => string;
6
+ /** Canonical identity fingerprint of a request: a hash of the NORMALIZED text
7
+ * (trimmed, internal whitespace collapsed). Used only for identity comparison —
8
+ * the verbatim request is kept separately for the finalizer. */
9
+ export declare function fingerprintRequest(request: string): string;
10
+ export type TerminalOutcome = {
11
+ kind: 'success';
12
+ answer: string;
13
+ } | {
14
+ kind: 'error';
15
+ error: string;
16
+ };
17
+ /** Persist a terminal outcome keyed by runId with a TTL. Written into the same
18
+ * KnowledgeBackend as the bundle but under a distinct artifactType so it
19
+ * survives the next run's bundle reset (the TTL promise). `nowIso` is passed so
20
+ * the caller controls time. */
21
+ export declare function writeTerminal(be: KnowledgeBackend, sessionId: string, runId: string, terminalOutcome: TerminalOutcome, ttlMs: number, nowIso: string): Promise<void>;
22
+ /** Read the latest non-expired terminal outcome for runId, or undefined. */
23
+ export declare function readTerminal(be: KnowledgeBackend, sessionId: string, runId: string, nowIso: string): Promise<TerminalOutcome | undefined>;
24
+ /** The runIds whose terminal entries are expired as of nowIso (backends without
25
+ * delete simply ignore stale rows on read). */
26
+ export declare function gcTerminal(be: KnowledgeBackend, sessionId: string, nowIso: string): Promise<string[]>;
27
+ export type Classification = {
28
+ kind: 'fresh';
29
+ } | {
30
+ kind: 'resume';
31
+ } | {
32
+ kind: 'replay';
33
+ runId: string;
34
+ } | {
35
+ kind: 'not-found';
36
+ };
37
+ export interface ClassifyInput {
38
+ bundle: SessionBundle;
39
+ incomingRequest: string;
40
+ /** Explicit idempotency key / runId supplied by the caller (if any). */
41
+ explicitKey?: string;
42
+ /** True when the consumer set the newRun flag for THIS request. */
43
+ newRun?: boolean;
44
+ /** Whether `explicitKey` (or, for fingerprint matches, the current bundle's
45
+ * runId) has a non-expired terminal-store entry. */
46
+ terminalExists: boolean;
47
+ }
48
+ /** Strict ordered request classification. First matching branch wins. */
49
+ export declare function classifyRequest(input: ClassifyInput): Classification;
50
+ //# sourceMappingURL=run-scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-scope.d.ts","sourceRoot":"","sources":["../../../src/smart-agent/controller/run-scope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD;2DAC2D;AAC3D,MAAM,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC;AAEvC;;iEAEiE;AACjE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1D;AAQD,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AASrC;;;gCAGgC;AAChC,wBAAsB,aAAa,CACjC,EAAE,EAAE,gBAAgB,EACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,eAAe,EAChC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAef;AAED,4EAA4E;AAC5E,wBAAsB,YAAY,CAChC,EAAE,EAAE,gBAAgB,EACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAgBtC;AAED;gDACgD;AAChD,wBAAsB,UAAU,CAC9B,EAAE,EAAE,gBAAgB,EACpB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC,CAcnB;AAMD,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC;AAE1B,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,aAAa,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;yDACqD;IACrD,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CAwBpE"}