@mcp-abap-adt/llm-agent-libs 17.0.0 → 18.0.1

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 (90) hide show
  1. package/dist/builder.d.ts +9 -0
  2. package/dist/builder.d.ts.map +1 -1
  3. package/dist/builder.js +12 -0
  4. package/dist/builder.js.map +1 -1
  5. package/dist/coordinator/dag/dag-plan-interpreter.d.ts.map +1 -1
  6. package/dist/coordinator/dag/dag-plan-interpreter.js +23 -5
  7. package/dist/coordinator/dag/dag-plan-interpreter.js.map +1 -1
  8. package/dist/coordinator/dag/llm-dag-planner.d.ts +8 -1
  9. package/dist/coordinator/dag/llm-dag-planner.d.ts.map +1 -1
  10. package/dist/coordinator/dag/llm-dag-planner.js +74 -65
  11. package/dist/coordinator/dag/llm-dag-planner.js.map +1 -1
  12. package/dist/coordinator/stepper/cyclic-react-executor.d.ts +42 -0
  13. package/dist/coordinator/stepper/cyclic-react-executor.d.ts.map +1 -0
  14. package/dist/coordinator/stepper/cyclic-react-executor.js +282 -0
  15. package/dist/coordinator/stepper/cyclic-react-executor.js.map +1 -0
  16. package/dist/coordinator/stepper/index.d.ts +10 -0
  17. package/dist/coordinator/stepper/index.d.ts.map +1 -0
  18. package/dist/coordinator/stepper/index.js +10 -0
  19. package/dist/coordinator/stepper/index.js.map +1 -0
  20. package/dist/coordinator/stepper/llm-stepper-planner.d.ts +27 -0
  21. package/dist/coordinator/stepper/llm-stepper-planner.d.ts.map +1 -0
  22. package/dist/coordinator/stepper/llm-stepper-planner.js +86 -0
  23. package/dist/coordinator/stepper/llm-stepper-planner.js.map +1 -0
  24. package/dist/coordinator/stepper/llm-task-formalizer.d.ts +22 -0
  25. package/dist/coordinator/stepper/llm-task-formalizer.d.ts.map +1 -0
  26. package/dist/coordinator/stepper/llm-task-formalizer.js +73 -0
  27. package/dist/coordinator/stepper/llm-task-formalizer.js.map +1 -0
  28. package/dist/coordinator/stepper/logging-llm.d.ts +30 -0
  29. package/dist/coordinator/stepper/logging-llm.d.ts.map +1 -0
  30. package/dist/coordinator/stepper/logging-llm.js +73 -0
  31. package/dist/coordinator/stepper/logging-llm.js.map +1 -0
  32. package/dist/coordinator/stepper/need-resolver.d.ts +18 -0
  33. package/dist/coordinator/stepper/need-resolver.d.ts.map +1 -0
  34. package/dist/coordinator/stepper/need-resolver.js +42 -0
  35. package/dist/coordinator/stepper/need-resolver.js.map +1 -0
  36. package/dist/coordinator/stepper/root-finalizer.d.ts +17 -0
  37. package/dist/coordinator/stepper/root-finalizer.d.ts.map +1 -0
  38. package/dist/coordinator/stepper/root-finalizer.js +53 -0
  39. package/dist/coordinator/stepper/root-finalizer.js.map +1 -0
  40. package/dist/coordinator/stepper/static-planner.d.ts +23 -0
  41. package/dist/coordinator/stepper/static-planner.d.ts.map +1 -0
  42. package/dist/coordinator/stepper/static-planner.js +25 -0
  43. package/dist/coordinator/stepper/static-planner.js.map +1 -0
  44. package/dist/coordinator/stepper/stepper-interpreter.d.ts +6 -0
  45. package/dist/coordinator/stepper/stepper-interpreter.d.ts.map +1 -0
  46. package/dist/coordinator/stepper/stepper-interpreter.js +132 -0
  47. package/dist/coordinator/stepper/stepper-interpreter.js.map +1 -0
  48. package/dist/coordinator/stepper/stepper.d.ts +36 -0
  49. package/dist/coordinator/stepper/stepper.d.ts.map +1 -0
  50. package/dist/coordinator/stepper/stepper.js +50 -0
  51. package/dist/coordinator/stepper/stepper.js.map +1 -0
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +5 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/logger/default-request-logger.d.ts.map +1 -1
  57. package/dist/logger/default-request-logger.js +10 -0
  58. package/dist/logger/default-request-logger.js.map +1 -1
  59. package/dist/logger/noop-request-logger.d.ts.map +1 -1
  60. package/dist/logger/noop-request-logger.js +1 -0
  61. package/dist/logger/noop-request-logger.js.map +1 -1
  62. package/dist/logger/session-request-logger.d.ts.map +1 -1
  63. package/dist/logger/session-request-logger.js +10 -0
  64. package/dist/logger/session-request-logger.js.map +1 -1
  65. package/dist/pipeline/default-pipeline.d.ts +8 -0
  66. package/dist/pipeline/default-pipeline.d.ts.map +1 -1
  67. package/dist/pipeline/default-pipeline.js +9 -2
  68. package/dist/pipeline/default-pipeline.js.map +1 -1
  69. package/dist/pipeline/handlers/dag-coordinator.d.ts.map +1 -1
  70. package/dist/pipeline/handlers/dag-coordinator.js +2 -0
  71. package/dist/pipeline/handlers/dag-coordinator.js.map +1 -1
  72. package/dist/pipeline/handlers/index.d.ts +7 -0
  73. package/dist/pipeline/handlers/index.d.ts.map +1 -1
  74. package/dist/pipeline/handlers/index.js +4 -1
  75. package/dist/pipeline/handlers/index.js.map +1 -1
  76. package/dist/pipeline/handlers/tool-loop.d.ts.map +1 -1
  77. package/dist/pipeline/handlers/tool-loop.js +3 -2
  78. package/dist/pipeline/handlers/tool-loop.js.map +1 -1
  79. package/dist/rag/knowledge-rag.d.ts +74 -0
  80. package/dist/rag/knowledge-rag.d.ts.map +1 -0
  81. package/dist/rag/knowledge-rag.js +116 -0
  82. package/dist/rag/knowledge-rag.js.map +1 -0
  83. package/dist/session/session-registry.d.ts +7 -0
  84. package/dist/session/session-registry.d.ts.map +1 -1
  85. package/dist/session/session-registry.js +18 -0
  86. package/dist/session/session-registry.js.map +1 -1
  87. package/dist/subagent/smart-agent-subagent.d.ts.map +1 -1
  88. package/dist/subagent/smart-agent-subagent.js +6 -0
  89. package/dist/subagent/smart-agent-subagent.js.map +1 -1
  90. package/package.json +14 -14
@@ -0,0 +1,282 @@
1
+ import { renderTaskSpec, } from '@mcp-abap-adt/llm-agent';
2
+ /**
3
+ * Task-agnostic tool-use protocol for the executor. It says NOTHING about the
4
+ * task type or any specific tool/MCP — only how to behave when a needed
5
+ * capability is missing or a tool fails. This is what makes the always-on
6
+ * unmet-need detection (INeedResolver) effective: the model is told to VOICE the
7
+ * gap instead of guessing or silently finishing, so a no-tool-call "I need X"
8
+ * utterance is produced, which the tool-definer then turns into a toolsRag
9
+ * re-query. Keep it generic — the runtime is MCP- and task-agnostic.
10
+ */
11
+ // NOTE (18.0): the executor is deliberately TASK-AGNOSTIC and does NOT
12
+ // self-assess completeness. Completeness/prerequisite judgement is the smart
13
+ // model's job — the planner (which now carries a completeness clause) today and
14
+ // the dedicated 18.1 Evaluator tomorrow. A cheap executor (e.g. haiku) told to
15
+ // "ensure the complete artifact" still satisfices (proven live: gi=0), and a
16
+ // task-type clause here breaks the agnostic-prompt invariant. So cyclic ships
17
+ // thin: thoroughness comes from the consumer (a knowledgeSeed / prompt
18
+ // prerequisite) or from a smart planner above it — never from this prompt.
19
+ export const EXECUTOR_SYSTEM = `You complete the task by calling the available tools. If you need a capability the available tools do not provide, or a tool call fails or returns an error / empty / "not found" result, do NOT guess, fabricate, or give a final answer prematurely. Instead, state in ONE sentence the capability you still need (e.g. "I need a tool to <do X>"). Produce your final answer only once you actually have the data the task requires.`;
20
+ const ZERO = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
21
+ const add = (a, b) => b
22
+ ? {
23
+ promptTokens: a.promptTokens + b.promptTokens,
24
+ completionTokens: a.completionTokens + b.completionTokens,
25
+ totalTokens: a.totalTokens + b.totalTokens,
26
+ }
27
+ : a;
28
+ export class CyclicReActExecutor {
29
+ deps;
30
+ name = 'cyclic-react';
31
+ constructor(deps) {
32
+ this.deps = deps;
33
+ }
34
+ async execute(input) {
35
+ const { llm, callMcp, component, maxIterations } = this.deps;
36
+ const { prompt, knowledgeRag, toolsRag, budget, identity, taskSpec, signal, onProgress, } = input;
37
+ // Persistent "main task" anchor — rendered ONCE and pinned in the system
38
+ // message, so it survives EVERY iteration (even as tool results pile up) and
39
+ // the executor never loses the overall task. Bounded (a few lines), not the
40
+ // full conversation. Absent → behaves as before.
41
+ const taskAnchor = taskSpec ? `\n\n${renderTaskSpec(taskSpec)}` : '';
42
+ // Always-on: prefer a per-call resolver, else the deps-injected one.
43
+ const needResolver = input.needResolver ?? this.deps.needResolver;
44
+ const ref = {
45
+ stepperId: identity.stepperId,
46
+ parentStepperId: identity.parentStepperId,
47
+ name: this.name,
48
+ };
49
+ // Read the shared blackboard before the first turn so the executor benefits
50
+ // from seeded guidance (e.g. tool-usage routing rules) and prior facts — the
51
+ // planner does this too, but in cyclic-react the planner is trivial, so the
52
+ // executor is the only component that can surface guidance to the model that
53
+ // actually chooses tools. Bounded k + per-fact truncation keep the prompt
54
+ // lean; large fetched artifacts stay in the blackboard for the finalizer.
55
+ let factsPrefix = '';
56
+ try {
57
+ const facts = await knowledgeRag.query(prompt, { k: 5 });
58
+ if (facts.length > 0) {
59
+ factsPrefix = `${'Known facts and guidance (from the shared knowledge store):\n'}${facts
60
+ .map((f) => `- ${truncateFact(f.content, 300)}`)
61
+ .join('\n')}\n\n`;
62
+ }
63
+ }
64
+ catch {
65
+ // knowledge store unavailable — proceed without the prefix
66
+ }
67
+ const messages = [
68
+ {
69
+ role: 'system',
70
+ content: `${this.deps.systemPrompt ?? EXECUTOR_SYSTEM}${taskAnchor}`,
71
+ },
72
+ { role: 'user', content: `${factsPrefix}${prompt}` },
73
+ ];
74
+ const tools = [...input.tools];
75
+ let usage = ZERO;
76
+ // Counts consecutive unmet-need iterations whose tool re-query surfaced NO
77
+ // new tool. One such "nudge" is allowed (the tool may already be present and
78
+ // the model just needs prompting); a second consecutive no-progress need
79
+ // means the capability is genuinely unavailable → return incomplete instead
80
+ // of looping to maxIterations or passing a half-answer off as ok.
81
+ let noProgressNeeds = 0;
82
+ // Proactive tool seeding: if no tools were supplied by the dispatcher, query
83
+ // toolsRag BEFORE the first LLM call so a capable model that never emits
84
+ // "I can't" still sees the relevant tools from turn 1.
85
+ // ORDER MATTERS: enrich the search text with the knowledge-RAG context
86
+ // (guidance) FIRST, then vectorize THAT for tool discovery. Seeded guidance
87
+ // like "read an include body via GetInclude" must steer which tools surface
88
+ // — querying the bare prompt would never rank GetInclude for a "review
89
+ // program" task, so the model would fall back to the wrong tool. This is the
90
+ // contextual-RAG-then-tool-search ordering.
91
+ if (tools.length === 0) {
92
+ // The seed query reflects the OVERALL intent (taskSpec) + shared guidance
93
+ // (factsPrefix) + this node's prompt — so tool-search ranks tools for the
94
+ // whole task, not just the narrow sub-goal.
95
+ const seedQuery = `${taskAnchor ? `${renderTaskSpec(taskSpec)}\n` : ''}${factsPrefix}${prompt}`;
96
+ const seeded = await toolsRag.query(seedQuery, 10);
97
+ for (const t of seeded)
98
+ tools.push(t);
99
+ input.sessionLogger?.logStep('executor_tool_seed', {
100
+ source: ref,
101
+ seededCount: seeded.length,
102
+ });
103
+ }
104
+ // Issue #167: MERGE client-provided external tools (consumer-executed, e.g.
105
+ // create_file / rag_add) with the seeded MCP tools — AFTER seeding, so they
106
+ // never suppress the MCP seed (which only runs when `tools.length === 0`).
107
+ // De-dup by name so a tool present in both sets is offered once.
108
+ if (input.externalTools && input.externalTools.length > 0) {
109
+ const have = new Set(tools.map((t) => t.name));
110
+ for (const t of input.externalTools)
111
+ if (!have.has(t.name))
112
+ tools.push(t);
113
+ }
114
+ for (let iter = 0; iter < maxIterations; iter++) {
115
+ // Gate BEFORE any further work (review R2-F1/R6-F1). The ledger is the
116
+ // SHARED run-wide counter (not a local snapshot). If it is exhausted we
117
+ // refuse to start another LLM round and bubble budget-exhausted — this
118
+ // is the gate that the budget-extension ClarifySignal depends on: it
119
+ // fires only when MORE work is wanted but the budget is gone. A clean
120
+ // final answer (below) that completes the task returns ok even if its
121
+ // own call nudged the ledger negative — that bounded overshoot is the
122
+ // documented soft cap; there is nothing left to "extend", so no clarify.
123
+ if (budget.tokens.exhausted()) {
124
+ return { status: 'budget-exhausted', usage };
125
+ }
126
+ onProgress?.({
127
+ kind: 'llm-call-start',
128
+ source: ref,
129
+ component,
130
+ model: llm.model ?? 'unknown',
131
+ });
132
+ const res = await llm.chat(messages, tools, { signal });
133
+ onProgress?.({
134
+ kind: 'llm-call-end',
135
+ source: ref,
136
+ component,
137
+ durationMs: 0,
138
+ });
139
+ if (res.ok === false)
140
+ return {
141
+ status: 'incomplete',
142
+ missing: [res.error?.message ?? 'llm error'],
143
+ usage,
144
+ };
145
+ const v = res.value;
146
+ usage = add(usage, v.usage);
147
+ if (v.usage) {
148
+ budget.tokens.spend(v.usage); // decrement the shared ledger immediately
149
+ onProgress?.({
150
+ kind: 'tokens-used',
151
+ source: ref,
152
+ component,
153
+ delta: v.usage,
154
+ });
155
+ }
156
+ const toolCalls = v.toolCalls ?? [];
157
+ if (toolCalls.length > 0) {
158
+ // Relay the assistant turn WITH its tool_calls, then one tool message
159
+ // per call carrying the matching tool_call_id. Anthropic/SAP AI SDK (and
160
+ // the DeepSeek/OpenAI protocol) reject a `tool` message that does not
161
+ // follow an assistant `tool_calls` with the same id — an orphaned
162
+ // tool_result is a hard 400. (Mirrors the 17.0 tool-loop wire shape.)
163
+ messages.push({
164
+ role: 'assistant',
165
+ content: v.content || null,
166
+ tool_calls: toolCalls.map((tc) => ({
167
+ id: tc.id,
168
+ type: 'function',
169
+ function: {
170
+ name: tc.name,
171
+ arguments: JSON.stringify(tc.arguments ?? {}),
172
+ },
173
+ })),
174
+ });
175
+ for (const tc of toolCalls) {
176
+ const toolName = tc.name;
177
+ onProgress?.({
178
+ kind: 'mcp-call',
179
+ source: ref,
180
+ tool: toolName,
181
+ args: tc.arguments,
182
+ });
183
+ const result = await callMcp(toolName, tc.arguments, signal);
184
+ onProgress?.({
185
+ kind: 'mcp-result',
186
+ source: ref,
187
+ tool: toolName,
188
+ durationMs: 0,
189
+ bytes: result.length,
190
+ });
191
+ await knowledgeRag.write({
192
+ content: result,
193
+ metadata: {
194
+ traceId: identity.traceId,
195
+ turnId: identity.turnId,
196
+ stepperId: identity.stepperId,
197
+ parentStepperId: identity.parentStepperId,
198
+ task: prompt,
199
+ artifactType: 'mcp-result',
200
+ toolName,
201
+ createdAt: nowIso(),
202
+ },
203
+ });
204
+ messages.push({
205
+ role: 'tool',
206
+ content: result,
207
+ tool_call_id: tc.id,
208
+ });
209
+ }
210
+ noProgressNeeds = 0; // a tool call is progress — reset the no-new-tool gate
211
+ continue;
212
+ }
213
+ // No tool call → this answer is a CANDIDATE final answer. ALWAYS analyze
214
+ // it (gated by the resolver/classifier) for an unmet-tool need. The gate
215
+ // is the resolver's verdict — NOT "did toolsRag return anything": a query
216
+ // over a complete answer almost always has near neighbours, so gating on
217
+ // results would false-positive. We re-query ONLY when the classifier says
218
+ // the model expressed a need.
219
+ const need = needResolver
220
+ ? await needResolver.resolve(v.content ?? '')
221
+ : undefined;
222
+ if (need?.queryToolsRag) {
223
+ const found = await toolsRag.query(need.queryToolsRag, 5);
224
+ const have = new Set(tools.map((t) => t.name));
225
+ let added = 0;
226
+ for (const t of found)
227
+ if (!have.has(t.name)) {
228
+ tools.push(t);
229
+ added++;
230
+ }
231
+ if (added === 0) {
232
+ // Re-query surfaced nothing new. Allow one nudge (tool may already be
233
+ // present); on a second consecutive no-progress need, the capability
234
+ // is genuinely unavailable — stop honestly.
235
+ if (++noProgressNeeds >= 2) {
236
+ return {
237
+ status: 'incomplete',
238
+ missing: [need.queryToolsRag],
239
+ usage,
240
+ };
241
+ }
242
+ }
243
+ else {
244
+ noProgressNeeds = 0;
245
+ }
246
+ messages.push({ role: 'assistant', content: v.content ?? '' });
247
+ messages.push({
248
+ role: 'user',
249
+ content: `You now have additional tools available. ${prompt}`,
250
+ });
251
+ continue;
252
+ }
253
+ // Clean final answer → write + return ok.
254
+ await knowledgeRag.write({
255
+ content: v.content ?? '',
256
+ metadata: {
257
+ traceId: identity.traceId,
258
+ turnId: identity.turnId,
259
+ stepperId: identity.stepperId,
260
+ parentStepperId: identity.parentStepperId,
261
+ task: prompt,
262
+ artifactType: 'analysis-finding',
263
+ createdAt: nowIso(),
264
+ },
265
+ });
266
+ return { status: 'ok', usage };
267
+ }
268
+ return { status: 'incomplete', missing: ['max iterations reached'], usage };
269
+ }
270
+ }
271
+ // Injectable clock kept out of the hot path; callers in deterministic test
272
+ // contexts can monkeypatch if needed. ISO string only used for ordering.
273
+ function nowIso() {
274
+ return new Date().toISOString();
275
+ }
276
+ /** Keep blackboard facts short in the executor prompt — guidance entries are
277
+ * brief and survive intact; large fetched artifacts are truncated (the full
278
+ * copy stays in the knowledge store for the finalizer's exhaustive list). */
279
+ function truncateFact(s, n) {
280
+ return s.length > n ? `${s.slice(0, n)}…` : s;
281
+ }
282
+ //# sourceMappingURL=cyclic-react-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cyclic-react-executor.js","sourceRoot":"","sources":["../../../src/coordinator/stepper/cyclic-react-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export { CyclicReActExecutor } from './cyclic-react-executor.js';
2
+ export { LlmStepperPlanner, STEPPER_PLANNER_SYSTEM, } from './llm-stepper-planner.js';
3
+ export { LlmTaskFormalizer, parseTaskSpec, TASK_FORMALIZER_SYSTEM, } from './llm-task-formalizer.js';
4
+ export { LoggingLlm } from './logging-llm.js';
5
+ export { LlmNeedResolver, RegexNeedResolver } from './need-resolver.js';
6
+ export { RootFinalizer } from './root-finalizer.js';
7
+ export { StaticPlanner } from './static-planner.js';
8
+ export { Stepper, type StepperDeps } from './stepper.js';
9
+ export { StepperInterpreter } from './stepper-interpreter.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/coordinator/stepper/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EACL,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,10 @@
1
+ export { CyclicReActExecutor } from './cyclic-react-executor.js';
2
+ export { LlmStepperPlanner, STEPPER_PLANNER_SYSTEM, } from './llm-stepper-planner.js';
3
+ export { LlmTaskFormalizer, parseTaskSpec, TASK_FORMALIZER_SYSTEM, } from './llm-task-formalizer.js';
4
+ export { LoggingLlm } from './logging-llm.js';
5
+ export { LlmNeedResolver, RegexNeedResolver } from './need-resolver.js';
6
+ export { RootFinalizer } from './root-finalizer.js';
7
+ export { StaticPlanner } from './static-planner.js';
8
+ export { Stepper } from './stepper.js';
9
+ export { StepperInterpreter } from './stepper-interpreter.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/coordinator/stepper/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EACL,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAoB,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { DagPlan, IKnowledgeRagHandle, ILlm, IStepperPlanner, ITaskSpec, IToolsRagHandle, RunIdentity } from '@mcp-abap-adt/llm-agent';
2
+ export declare const STEPPER_PLANNER_SYSTEM = "You are a planner in a recursive Stepper hierarchy. Decompose the task into a SHALLOW DAG of steps.\nCOMPLETENESS: first assess whether the task states everything needed to execute it. If a prerequisite is implied but not stated \u2014 e.g. an analysis/review needs the COMPLETE artifact (all of its parts/sub-parts), not only its top level \u2014 add explicit steps to obtain it FIRST. Use the \"Known facts\" to decide what \"complete\" means for this domain.\nRAG-FIRST: the \"Known facts\" section lists what is already in the shared knowledge store. If a fact you need is already there, DO NOT add a step to re-fetch it \u2014 use it. Only add a step to obtain information that is genuinely missing.\nFETCH STEPS \u2014 NOT needInfo: Workers can read the live system by calling the tools listed in the \"Available tools\" section below. For ANY data a worker could fetch (program source, includes, table contents, object metadata, search results), emit a fetch STEP whose goal names the fetch \u2014 NEVER use needInfo for fetchable data.\nDECOMPOSE TO CONCRETE LEAVES: if a task is achievable by ONE tool call, emit a single-step plan whose goal is that concrete leaf call \u2014 do NOT re-emit the parent's task verbatim (that causes infinite recursion). Each node spawns a fresh worker that does NOT share your context; over-decomposition multiplies cost.\nDELEGATION: if an \"Available workers\" section is listed below, you MAY set a node's \"agent\" to one of those worker names to delegate a SUB-GOAL to that recursive worker (it will plan and execute the sub-goal itself). Omit \"agent\" for a concrete leaf you want executed directly. Only delegate when the sub-goal is a distinct unit of work that benefits from its own planning \u2014 otherwise emit a direct leaf.\nEach node: {\"id\",\"goal\",\"agent\"(optional worker name),\"dependsOn\"(optional ids)}.\nRespond with ONLY one of:\n{\"objective\":\"...\",\"nodes\":[...]}\n{\"needInfo\":\"<query>\"} \u2014 ONLY for a fact that NO listed tool can obtain (e.g. a human decision, or knowledge external to the system). If a listed tool below could get it, plan a step instead.\n{\"clarify\":\"<question>\"} \u2014 you need a human decision before planning";
3
+ export declare class LlmStepperPlanner implements IStepperPlanner {
4
+ private readonly llm;
5
+ readonly name = "llm-stepper";
6
+ readonly model?: string;
7
+ private readonly granularity;
8
+ /** Base system prompt; a consumer may override STEPPER_PLANNER_SYSTEM via
9
+ * `coordinator.flow.planner.systemPrompt` (yaml) or the builder. The
10
+ * granularity directive is still appended to whatever base is used. */
11
+ private readonly systemPrompt;
12
+ constructor(llm: ILlm, granularity?: 'shallow' | 'detailed', systemPrompt?: string);
13
+ plan(input: {
14
+ prompt: string;
15
+ knowledgeRag: IKnowledgeRagHandle;
16
+ toolsRag: IToolsRagHandle;
17
+ parentPath: string[];
18
+ identity: RunIdentity;
19
+ agents?: ReadonlyArray<{
20
+ name: string;
21
+ description?: string;
22
+ }>;
23
+ taskSpec?: ITaskSpec;
24
+ signal?: AbortSignal;
25
+ }): Promise<DagPlan>;
26
+ }
27
+ //# sourceMappingURL=llm-stepper-planner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-stepper-planner.d.ts","sourceRoot":"","sources":["../../../src/coordinator/stepper/llm-stepper-planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,mBAAmB,EACnB,IAAI,EACJ,eAAe,EACf,SAAS,EACT,eAAe,EACf,WAAW,EACZ,MAAM,yBAAyB,CAAC;AAQjC,eAAO,MAAM,sBAAsB,mrEAUmC,CAAC;AAYvE,qBAAa,iBAAkB,YAAW,eAAe;IAUrD,OAAO,CAAC,QAAQ,CAAC,GAAG;IATtB,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyB;IACrD;;4EAEwE;IACxE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAGnB,GAAG,EAAE,IAAI,EAC1B,WAAW,GAAE,SAAS,GAAG,UAAsB,EAC/C,YAAY,GAAE,MAA+B;IAOzC,IAAI,CAAC,KAAK,EAAE;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,mBAAmB,CAAC;QAClC,QAAQ,EAAE,eAAe,CAAC;QAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,QAAQ,EAAE,WAAW,CAAC;QACtB,MAAM,CAAC,EAAE,aAAa,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC/D,QAAQ,CAAC,EAAE,SAAS,CAAC;QACrB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,OAAO,CAAC;CA0DrB"}
@@ -0,0 +1,86 @@
1
+ import { renderTaskSpec } from '@mcp-abap-adt/llm-agent';
2
+ import { parseDagPlan } from '../dag/llm-dag-planner.js';
3
+ // NOTE (18.0 workaround): the COMPLETENESS clause below is a SOFT stand-in for
4
+ // the dedicated 18.1 Evaluator (judging prompt/plan completeness WITH the RAG
5
+ // context, routing executable / needs-work / needs-consumer). When the Evaluator
6
+ // lands, this clause may DOUBLE-JUDGE / conflict — revisit then.
7
+ export const STEPPER_PLANNER_SYSTEM = `You are a planner in a recursive Stepper hierarchy. Decompose the task into a SHALLOW DAG of steps.
8
+ COMPLETENESS: first assess whether the task states everything needed to execute it. If a prerequisite is implied but not stated — e.g. an analysis/review needs the COMPLETE artifact (all of its parts/sub-parts), not only its top level — add explicit steps to obtain it FIRST. Use the "Known facts" to decide what "complete" means for this domain.
9
+ RAG-FIRST: the "Known facts" section lists what is already in the shared knowledge store. If a fact you need is already there, DO NOT add a step to re-fetch it — use it. Only add a step to obtain information that is genuinely missing.
10
+ FETCH STEPS — NOT needInfo: Workers can read the live system by calling the tools listed in the "Available tools" section below. For ANY data a worker could fetch (program source, includes, table contents, object metadata, search results), emit a fetch STEP whose goal names the fetch — NEVER use needInfo for fetchable data.
11
+ DECOMPOSE TO CONCRETE LEAVES: if a task is achievable by ONE tool call, emit a single-step plan whose goal is that concrete leaf call — do NOT re-emit the parent's task verbatim (that causes infinite recursion). Each node spawns a fresh worker that does NOT share your context; over-decomposition multiplies cost.
12
+ DELEGATION: if an "Available workers" section is listed below, you MAY set a node's "agent" to one of those worker names to delegate a SUB-GOAL to that recursive worker (it will plan and execute the sub-goal itself). Omit "agent" for a concrete leaf you want executed directly. Only delegate when the sub-goal is a distinct unit of work that benefits from its own planning — otherwise emit a direct leaf.
13
+ Each node: {"id","goal","agent"(optional worker name),"dependsOn"(optional ids)}.
14
+ Respond with ONLY one of:
15
+ {"objective":"...","nodes":[...]}
16
+ {"needInfo":"<query>"} — ONLY for a fact that NO listed tool can obtain (e.g. a human decision, or knowledge external to the system). If a listed tool below could get it, plan a step instead.
17
+ {"clarify":"<question>"} — you need a human decision before planning`;
18
+ /** Granularity directive appended to the planner system prompt — the eager
19
+ * decomposition knob (see DESIGN). 'shallow' defers detail to executors;
20
+ * 'detailed' decomposes fully into concrete leaves up front. */
21
+ const GRANULARITY_DIRECTIVE = {
22
+ shallow: '\nGRANULARITY: produce a SHALLOW plan — a few high-level steps; defer fine-grained detail to the executors that run each step.',
23
+ detailed: '\nGRANULARITY: produce a DETAILED plan NOW — decompose fully into concrete, single-action leaf steps with explicit dependsOn; do not defer detail to the executors.',
24
+ };
25
+ export class LlmStepperPlanner {
26
+ llm;
27
+ name = 'llm-stepper';
28
+ model;
29
+ granularity;
30
+ /** Base system prompt; a consumer may override STEPPER_PLANNER_SYSTEM via
31
+ * `coordinator.flow.planner.systemPrompt` (yaml) or the builder. The
32
+ * granularity directive is still appended to whatever base is used. */
33
+ systemPrompt;
34
+ constructor(llm, granularity = 'shallow', systemPrompt = STEPPER_PLANNER_SYSTEM) {
35
+ this.llm = llm;
36
+ this.model = llm.model;
37
+ this.granularity = granularity;
38
+ this.systemPrompt = systemPrompt;
39
+ }
40
+ async plan(input) {
41
+ const facts = await input.knowledgeRag.query(input.prompt, { k: 8 });
42
+ const factBlock = facts.length
43
+ ? `Known facts (already in the knowledge store):\n${facts.map((f) => `- [${f.metadata.artifactType}] ${truncate(f.content, 400)}`).join('\n')}\n\n`
44
+ : 'Known facts: (none yet)\n\n';
45
+ let toolsBlock = '';
46
+ try {
47
+ const tools = await input.toolsRag.query(input.prompt, 15);
48
+ if (tools.length > 0) {
49
+ toolsBlock =
50
+ `Available tools (workers can call these to FETCH data):\n` +
51
+ tools
52
+ .map((t) => `- ${t.name}: ${truncate(t.description, 200)}`)
53
+ .join('\n') +
54
+ '\n\n';
55
+ }
56
+ }
57
+ catch {
58
+ // toolsRag unavailable — omit the section gracefully
59
+ }
60
+ const agentsBlock = input.agents && input.agents.length > 0
61
+ ? `Available workers (set a node's "agent" to delegate a sub-goal):\n${input.agents
62
+ .map((a) => `- ${a.name}: ${truncate(a.description ?? '(no description)', 200)}`)
63
+ .join('\n')}\n\n`
64
+ : '';
65
+ // Overall-task anchor: every planner at every level sees the formalized
66
+ // global task (with its constraints), not just its local sub-prompt.
67
+ const taskBlock = input.taskSpec
68
+ ? `${renderTaskSpec(input.taskSpec)}\n\n`
69
+ : '';
70
+ const user = `${taskBlock}${factBlock}${toolsBlock}${agentsBlock}Task: ${input.prompt}`;
71
+ const res = await this.llm.chat([
72
+ {
73
+ role: 'system',
74
+ content: `${this.systemPrompt}${GRANULARITY_DIRECTIVE[this.granularity]}`,
75
+ },
76
+ { role: 'user', content: user },
77
+ ], [], { signal: input.signal });
78
+ if (res.ok === false)
79
+ throw new Error(`stepper planner: ${res.error?.message ?? 'llm error'}`);
80
+ return parseDagPlan(res.value.content);
81
+ }
82
+ }
83
+ function truncate(s, n) {
84
+ return s.length > n ? `${s.slice(0, n)}…` : s;
85
+ }
86
+ //# sourceMappingURL=llm-stepper-planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-stepper-planner.js","sourceRoot":"","sources":["../../../src/coordinator/stepper/llm-stepper-planner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { ILlm, ITaskFormalizer, ITaskSpec } from '@mcp-abap-adt/llm-agent';
2
+ export declare const TASK_FORMALIZER_SYSTEM = "You formalize a user's request into a COMPACT task specification for a multi-step agent that works on a system through tools.\nExtract ONLY what is needed to keep every later step aligned to the overall task. Be terse \u2014 a few lines, not an essay. Do NOT invent requirements the user did not state; do NOT plan steps or name tools.\nRespond with ONLY this JSON:\n{\"objective\":\"one sentence \u2014 the overall goal\",\"scope\":\"what must be covered (optional)\",\"constraints\":[\"hard constraints that every step must respect\"],\"deliverable\":\"shape of the final answer (optional)\"}\nThe \"constraints\" array must capture everything that must be known throughout the run (e.g. \"analyse the complete source including all includes\", \"read-only\", required dimensions). Keep each entry short.";
3
+ /**
4
+ * Formalizes the raw prompt into a compact {@link ITaskSpec} with one LLM call
5
+ * (use the strong/planner-tier model). NEVER throws: on any LLM or parse error
6
+ * it falls back to `{ objective: prompt, raw: prompt }`, so the run proceeds
7
+ * exactly as if no formalizer were configured.
8
+ */
9
+ export declare class LlmTaskFormalizer implements ITaskFormalizer {
10
+ private readonly llm;
11
+ readonly name = "llm-task-formalizer";
12
+ readonly model?: string;
13
+ constructor(llm: ILlm);
14
+ formalize(input: {
15
+ prompt: string;
16
+ signal?: AbortSignal;
17
+ }): Promise<ITaskSpec>;
18
+ }
19
+ /** Parse the formalizer's JSON reply into an ITaskSpec. Returns null on failure
20
+ * so the caller falls back. Tolerates ```json fences and surrounding prose. */
21
+ export declare function parseTaskSpec(content: string, raw: string): ITaskSpec | null;
22
+ //# sourceMappingURL=llm-task-formalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-task-formalizer.d.ts","sourceRoot":"","sources":["../../../src/coordinator/stepper/llm-task-formalizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEhF,eAAO,MAAM,sBAAsB,0yBAIyK,CAAC;AAE7M;;;;;GAKG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IAI3C,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHhC,QAAQ,CAAC,IAAI,yBAAyB;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;gBAEK,GAAG,EAAE,IAAI;IAIhC,SAAS,CAAC,KAAK,EAAE;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,SAAS,CAAC;CAkBvB;AAED;gFACgF;AAChF,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAoC5E"}
@@ -0,0 +1,73 @@
1
+ export const TASK_FORMALIZER_SYSTEM = `You formalize a user's request into a COMPACT task specification for a multi-step agent that works on a system through tools.
2
+ Extract ONLY what is needed to keep every later step aligned to the overall task. Be terse — a few lines, not an essay. Do NOT invent requirements the user did not state; do NOT plan steps or name tools.
3
+ Respond with ONLY this JSON:
4
+ {"objective":"one sentence — the overall goal","scope":"what must be covered (optional)","constraints":["hard constraints that every step must respect"],"deliverable":"shape of the final answer (optional)"}
5
+ The "constraints" array must capture everything that must be known throughout the run (e.g. "analyse the complete source including all includes", "read-only", required dimensions). Keep each entry short.`;
6
+ /**
7
+ * Formalizes the raw prompt into a compact {@link ITaskSpec} with one LLM call
8
+ * (use the strong/planner-tier model). NEVER throws: on any LLM or parse error
9
+ * it falls back to `{ objective: prompt, raw: prompt }`, so the run proceeds
10
+ * exactly as if no formalizer were configured.
11
+ */
12
+ export class LlmTaskFormalizer {
13
+ llm;
14
+ name = 'llm-task-formalizer';
15
+ model;
16
+ constructor(llm) {
17
+ this.llm = llm;
18
+ this.model = llm.model;
19
+ }
20
+ async formalize(input) {
21
+ const fallback = { objective: input.prompt, raw: input.prompt };
22
+ try {
23
+ const res = await this.llm.chat([
24
+ { role: 'system', content: TASK_FORMALIZER_SYSTEM },
25
+ { role: 'user', content: input.prompt },
26
+ ], [], { signal: input.signal });
27
+ if (res.ok === false)
28
+ return fallback;
29
+ const content = res.value.content;
30
+ return parseTaskSpec(content, input.prompt) ?? fallback;
31
+ }
32
+ catch {
33
+ return fallback;
34
+ }
35
+ }
36
+ }
37
+ /** Parse the formalizer's JSON reply into an ITaskSpec. Returns null on failure
38
+ * so the caller falls back. Tolerates ```json fences and surrounding prose. */
39
+ export function parseTaskSpec(content, raw) {
40
+ const start = content.indexOf('{');
41
+ const end = content.lastIndexOf('}');
42
+ if (start === -1 || end <= start)
43
+ return null;
44
+ let obj;
45
+ try {
46
+ obj = JSON.parse(content.slice(start, end + 1));
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ const objective = typeof obj.objective === 'string' && obj.objective.trim()
52
+ ? obj.objective.trim()
53
+ : raw;
54
+ const scope = typeof obj.scope === 'string' && obj.scope.trim()
55
+ ? obj.scope.trim()
56
+ : undefined;
57
+ const deliverable = typeof obj.deliverable === 'string' && obj.deliverable.trim()
58
+ ? obj.deliverable.trim()
59
+ : undefined;
60
+ const constraints = Array.isArray(obj.constraints)
61
+ ? obj.constraints
62
+ .filter((c) => typeof c === 'string' && c.trim().length > 0)
63
+ .map((c) => c.trim())
64
+ : undefined;
65
+ return {
66
+ objective,
67
+ raw,
68
+ ...(scope ? { scope } : {}),
69
+ ...(deliverable ? { deliverable } : {}),
70
+ ...(constraints && constraints.length > 0 ? { constraints } : {}),
71
+ };
72
+ }
73
+ //# sourceMappingURL=llm-task-formalizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-task-formalizer.js","sourceRoot":"","sources":["../../../src/coordinator/stepper/llm-task-formalizer.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;4MAIsK,CAAC;AAE7M;;;;;GAKG;AACH,MAAM,OAAO,iBAAiB;IAIC;IAHpB,IAAI,GAAG,qBAAqB,CAAC;IAC7B,KAAK,CAAU;IAExB,YAA6B,GAAS;QAAT,QAAG,GAAH,GAAG,CAAM;QACpC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAGf;QACC,MAAM,QAAQ,GAAc,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;QAC3E,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAC7B;gBACE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,sBAAsB,EAAE;gBACnD,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE;aAC/B,EACV,EAAW,EACX,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CACzB,CAAC;YACF,IAAK,GAAuB,CAAC,EAAE,KAAK,KAAK;gBAAE,OAAO,QAAQ,CAAC;YAC3D,MAAM,OAAO,GAAI,GAAsC,CAAC,KAAK,CAAC,OAAO,CAAC;YACtE,OAAO,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;CACF;AAED;gFACgF;AAChF,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,GAAW;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,IAAI,KAAK;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,GAA4B,CAAC;IACjC,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,SAAS,GACb,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE;QACvD,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE;QACtB,CAAC,CAAC,GAAG,CAAC;IACV,MAAM,KAAK,GACT,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE;QAC/C,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE;QAClB,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,WAAW,GACf,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE;QAC3D,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE;QACxB,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QAChD,CAAC,CAAC,GAAG,CAAC,WAAW;aACZ,MAAM,CACL,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CACjE;aACA,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzB,CAAC,CAAC,SAAS,CAAC;IACd,OAAO;QACL,SAAS;QACT,GAAG;QACH,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { CallOptions, ILlm, LlmError, LlmResponse, LlmStreamChunk, LlmTool, LlmUsage, Message, Result } from '@mcp-abap-adt/llm-agent';
2
+ /**
3
+ * An ILlm decorator that reports token usage after every `chat` or `streamChat`
4
+ * call via an injected `logUsage` callback. This is the authoritative path for
5
+ * per-role usage logging in the Stepper runtime — it ensures every role's LLM
6
+ * call is captured in the request-scoped byComponent breakdown regardless of
7
+ * whether the role is the executor, planner, reviewer, or finalizer.
8
+ *
9
+ * Usage:
10
+ * const logged = new LoggingLlm(innerLlm, (u, d) =>
11
+ * requestLogger.logLlmCall({ component: 'planner', model, ...u, durationMs: d })
12
+ * );
13
+ *
14
+ * For `streamChat`, usage is accumulated from stream chunks and logged once the
15
+ * stream ends.
16
+ */
17
+ export declare class LoggingLlm implements ILlm {
18
+ private readonly inner;
19
+ /** Called once per LLM invocation with the accumulated usage and duration. */
20
+ private readonly logUsage;
21
+ constructor(inner: ILlm,
22
+ /** Called once per LLM invocation with the accumulated usage and duration. */
23
+ logUsage: (usage: LlmUsage, durationMs: number) => void);
24
+ get model(): string | undefined;
25
+ chat(messages: Message[], tools?: LlmTool[], options?: CallOptions): Promise<Result<LlmResponse, LlmError>>;
26
+ streamChat(messages: Message[], tools?: LlmTool[], options?: CallOptions): AsyncIterable<Result<LlmStreamChunk, LlmError>>;
27
+ healthCheck?(options?: CallOptions): Promise<Result<boolean, LlmError>>;
28
+ getModels?(options?: CallOptions): Promise<Result<import('@mcp-abap-adt/llm-agent').IModelInfo[], LlmError>>;
29
+ }
30
+ //# sourceMappingURL=logging-llm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging-llm.d.ts","sourceRoot":"","sources":["../../../src/coordinator/stepper/logging-llm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,IAAI,EACJ,QAAQ,EACR,WAAW,EACX,cAAc,EACd,OAAO,EACP,QAAQ,EACR,OAAO,EACP,MAAM,EACP,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;GAcG;AACH,qBAAa,UAAW,YAAW,IAAI;IAEnC,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAFR,KAAK,EAAE,IAAI;IAC5B,8EAA8E;IAC7D,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI;IAG1E,IAAI,KAAK,IAAI,MAAM,GAAG,SAAS,CAE9B;IAEK,IAAI,CACR,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,CAAC,EAAE,OAAO,EAAE,EACjB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAUlC,UAAU,CACf,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,CAAC,EAAE,OAAO,EAAE,EACjB,OAAO,CAAC,EAAE,WAAW,GACpB,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IA6BlD,WAAW,CAAC,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IASvE,SAAS,CAAC,CACR,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,OAAO,yBAAyB,EAAE,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAC;CAI7E"}