@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.
- package/dist/builder.d.ts +9 -0
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +12 -0
- package/dist/builder.js.map +1 -1
- package/dist/coordinator/dag/dag-plan-interpreter.d.ts.map +1 -1
- package/dist/coordinator/dag/dag-plan-interpreter.js +23 -5
- package/dist/coordinator/dag/dag-plan-interpreter.js.map +1 -1
- package/dist/coordinator/dag/llm-dag-planner.d.ts +8 -1
- package/dist/coordinator/dag/llm-dag-planner.d.ts.map +1 -1
- package/dist/coordinator/dag/llm-dag-planner.js +74 -65
- package/dist/coordinator/dag/llm-dag-planner.js.map +1 -1
- package/dist/coordinator/stepper/cyclic-react-executor.d.ts +42 -0
- package/dist/coordinator/stepper/cyclic-react-executor.d.ts.map +1 -0
- package/dist/coordinator/stepper/cyclic-react-executor.js +282 -0
- package/dist/coordinator/stepper/cyclic-react-executor.js.map +1 -0
- package/dist/coordinator/stepper/index.d.ts +10 -0
- package/dist/coordinator/stepper/index.d.ts.map +1 -0
- package/dist/coordinator/stepper/index.js +10 -0
- package/dist/coordinator/stepper/index.js.map +1 -0
- package/dist/coordinator/stepper/llm-stepper-planner.d.ts +27 -0
- package/dist/coordinator/stepper/llm-stepper-planner.d.ts.map +1 -0
- package/dist/coordinator/stepper/llm-stepper-planner.js +86 -0
- package/dist/coordinator/stepper/llm-stepper-planner.js.map +1 -0
- package/dist/coordinator/stepper/llm-task-formalizer.d.ts +22 -0
- package/dist/coordinator/stepper/llm-task-formalizer.d.ts.map +1 -0
- package/dist/coordinator/stepper/llm-task-formalizer.js +73 -0
- package/dist/coordinator/stepper/llm-task-formalizer.js.map +1 -0
- package/dist/coordinator/stepper/logging-llm.d.ts +30 -0
- package/dist/coordinator/stepper/logging-llm.d.ts.map +1 -0
- package/dist/coordinator/stepper/logging-llm.js +73 -0
- package/dist/coordinator/stepper/logging-llm.js.map +1 -0
- package/dist/coordinator/stepper/need-resolver.d.ts +18 -0
- package/dist/coordinator/stepper/need-resolver.d.ts.map +1 -0
- package/dist/coordinator/stepper/need-resolver.js +42 -0
- package/dist/coordinator/stepper/need-resolver.js.map +1 -0
- package/dist/coordinator/stepper/root-finalizer.d.ts +17 -0
- package/dist/coordinator/stepper/root-finalizer.d.ts.map +1 -0
- package/dist/coordinator/stepper/root-finalizer.js +53 -0
- package/dist/coordinator/stepper/root-finalizer.js.map +1 -0
- package/dist/coordinator/stepper/static-planner.d.ts +23 -0
- package/dist/coordinator/stepper/static-planner.d.ts.map +1 -0
- package/dist/coordinator/stepper/static-planner.js +25 -0
- package/dist/coordinator/stepper/static-planner.js.map +1 -0
- package/dist/coordinator/stepper/stepper-interpreter.d.ts +6 -0
- package/dist/coordinator/stepper/stepper-interpreter.d.ts.map +1 -0
- package/dist/coordinator/stepper/stepper-interpreter.js +132 -0
- package/dist/coordinator/stepper/stepper-interpreter.js.map +1 -0
- package/dist/coordinator/stepper/stepper.d.ts +36 -0
- package/dist/coordinator/stepper/stepper.d.ts.map +1 -0
- package/dist/coordinator/stepper/stepper.js +50 -0
- package/dist/coordinator/stepper/stepper.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/logger/default-request-logger.d.ts.map +1 -1
- package/dist/logger/default-request-logger.js +10 -0
- package/dist/logger/default-request-logger.js.map +1 -1
- package/dist/logger/noop-request-logger.d.ts.map +1 -1
- package/dist/logger/noop-request-logger.js +1 -0
- package/dist/logger/noop-request-logger.js.map +1 -1
- package/dist/logger/session-request-logger.d.ts.map +1 -1
- package/dist/logger/session-request-logger.js +10 -0
- package/dist/logger/session-request-logger.js.map +1 -1
- package/dist/pipeline/default-pipeline.d.ts +8 -0
- package/dist/pipeline/default-pipeline.d.ts.map +1 -1
- package/dist/pipeline/default-pipeline.js +9 -2
- package/dist/pipeline/default-pipeline.js.map +1 -1
- package/dist/pipeline/handlers/dag-coordinator.d.ts.map +1 -1
- package/dist/pipeline/handlers/dag-coordinator.js +2 -0
- package/dist/pipeline/handlers/dag-coordinator.js.map +1 -1
- package/dist/pipeline/handlers/index.d.ts +7 -0
- package/dist/pipeline/handlers/index.d.ts.map +1 -1
- package/dist/pipeline/handlers/index.js +4 -1
- package/dist/pipeline/handlers/index.js.map +1 -1
- package/dist/pipeline/handlers/tool-loop.d.ts.map +1 -1
- package/dist/pipeline/handlers/tool-loop.js +3 -2
- package/dist/pipeline/handlers/tool-loop.js.map +1 -1
- package/dist/rag/knowledge-rag.d.ts +74 -0
- package/dist/rag/knowledge-rag.d.ts.map +1 -0
- package/dist/rag/knowledge-rag.js +116 -0
- package/dist/rag/knowledge-rag.js.map +1 -0
- package/dist/session/session-registry.d.ts +7 -0
- package/dist/session/session-registry.d.ts.map +1 -1
- package/dist/session/session-registry.js +18 -0
- package/dist/session/session-registry.js.map +1 -1
- package/dist/subagent/smart-agent-subagent.d.ts.map +1 -1
- package/dist/subagent/smart-agent-subagent.js +6 -0
- package/dist/subagent/smart-agent-subagent.js.map +1 -1
- 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":"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"}
|
|
@@ -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"}
|