@mcpc-tech/core 0.2.5 → 0.2.7-beta.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/index.mjs +76 -35
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -685,9 +685,42 @@ function stripMarkdownAndText(text) {
|
|
|
685
685
|
text = text.replace(/^```(?:json)?\s*\n?/i, "");
|
|
686
686
|
text = text.replace(/\n?```\s*$/, "");
|
|
687
687
|
text = text.replace(/^(?:here is|here's|response|result|output|json):\s*/i, "");
|
|
688
|
-
const
|
|
689
|
-
if (
|
|
690
|
-
text =
|
|
688
|
+
const firstJsonIndex = text.search(/[\{\[]/);
|
|
689
|
+
if (firstJsonIndex >= 0) {
|
|
690
|
+
text = text.slice(firstJsonIndex);
|
|
691
|
+
let depth = 0;
|
|
692
|
+
let inString = false;
|
|
693
|
+
let escapeNext = false;
|
|
694
|
+
const startChar = text[0];
|
|
695
|
+
const endChar = startChar === "{" ? "}" : "]";
|
|
696
|
+
for (let i = 0; i < text.length; i++) {
|
|
697
|
+
const char = text[i];
|
|
698
|
+
if (escapeNext) {
|
|
699
|
+
escapeNext = false;
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
702
|
+
if (char === "\\") {
|
|
703
|
+
escapeNext = true;
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
if (char === '"' && !inString) {
|
|
707
|
+
inString = true;
|
|
708
|
+
continue;
|
|
709
|
+
}
|
|
710
|
+
if (char === '"' && inString) {
|
|
711
|
+
inString = false;
|
|
712
|
+
continue;
|
|
713
|
+
}
|
|
714
|
+
if (inString) continue;
|
|
715
|
+
if (char === startChar) {
|
|
716
|
+
depth++;
|
|
717
|
+
} else if (char === endChar) {
|
|
718
|
+
depth--;
|
|
719
|
+
if (depth === 0) {
|
|
720
|
+
return text.slice(0, i + 1);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
691
724
|
}
|
|
692
725
|
return text.trim();
|
|
693
726
|
}
|
|
@@ -1464,13 +1497,13 @@ var AgenticExecutor = class {
|
|
|
1464
1497
|
this.tracingEnabled = false;
|
|
1465
1498
|
}
|
|
1466
1499
|
}
|
|
1467
|
-
async execute(args, schema) {
|
|
1500
|
+
async execute(args, schema, parentSpan) {
|
|
1468
1501
|
const executeSpan = this.tracingEnabled ? startSpan("mcpc.agentic_execute", {
|
|
1469
1502
|
agent: this.name,
|
|
1470
1503
|
action: String(args[this.ACTION_KEY] ?? "unknown"),
|
|
1471
1504
|
nextAction: String(args[this.NEXT_ACTION_KEY] ?? "none"),
|
|
1472
1505
|
args: JSON.stringify(args)
|
|
1473
|
-
}) : null;
|
|
1506
|
+
}, parentSpan ?? void 0) : null;
|
|
1474
1507
|
try {
|
|
1475
1508
|
const validationResult = this.validate(args, schema);
|
|
1476
1509
|
if (!validationResult.valid) {
|
|
@@ -2064,7 +2097,7 @@ var BaseSamplingExecutor = class {
|
|
|
2064
2097
|
role: "user",
|
|
2065
2098
|
content: {
|
|
2066
2099
|
type: "text",
|
|
2067
|
-
text: 'Return ONLY raw JSON (no code fences or
|
|
2100
|
+
text: 'Return ONE AND ONLY ONE raw JSON object (no code fences, explanations, or multiple objects). The JSON MUST include action and decision. Example: {"action":"<tool>","decision":"proceed|complete","<tool>":{}}'
|
|
2068
2101
|
}
|
|
2069
2102
|
}
|
|
2070
2103
|
];
|
|
@@ -2100,15 +2133,13 @@ var BaseSamplingExecutor = class {
|
|
|
2100
2133
|
if (iterationSpan) endSpan(iterationSpan);
|
|
2101
2134
|
continue;
|
|
2102
2135
|
}
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
});
|
|
2111
|
-
}
|
|
2136
|
+
this.conversationHistory.push({
|
|
2137
|
+
role: "assistant",
|
|
2138
|
+
content: {
|
|
2139
|
+
type: "text",
|
|
2140
|
+
text: JSON.stringify(parsedData, null, 2)
|
|
2141
|
+
}
|
|
2142
|
+
});
|
|
2112
2143
|
const action = parsedData["action"];
|
|
2113
2144
|
const actionStr = action && typeof action === "string" ? String(action) : "unknown_action";
|
|
2114
2145
|
const spanName = `mcpc.sampling_iteration.${actionStr}`;
|
|
@@ -2132,7 +2163,7 @@ var BaseSamplingExecutor = class {
|
|
|
2132
2163
|
if (iterationSpan) endSpan(iterationSpan);
|
|
2133
2164
|
continue;
|
|
2134
2165
|
}
|
|
2135
|
-
const result = await this.processAction(parsedData, schema, state,
|
|
2166
|
+
const result = await this.processAction(parsedData, schema, state, iterationSpan);
|
|
2136
2167
|
this.logIterationProgress(parsedData, result, model, stopReason, role);
|
|
2137
2168
|
if (iterationSpan) {
|
|
2138
2169
|
let rawJson = "{}";
|
|
@@ -2186,23 +2217,15 @@ var BaseSamplingExecutor = class {
|
|
|
2186
2217
|
return await this.createExecutionError(error, loopSpan);
|
|
2187
2218
|
}
|
|
2188
2219
|
}
|
|
2189
|
-
addParsingErrorToHistory(
|
|
2190
|
-
|
|
2191
|
-
role: "assistant",
|
|
2192
|
-
content: {
|
|
2193
|
-
type: "text",
|
|
2194
|
-
text: `JSON parsing failed. Response was: ${responseText}`
|
|
2195
|
-
}
|
|
2196
|
-
});
|
|
2220
|
+
addParsingErrorToHistory(_responseText, parseError) {
|
|
2221
|
+
const errorMsg = parseError instanceof Error ? parseError.message : String(parseError);
|
|
2197
2222
|
this.conversationHistory.push({
|
|
2198
2223
|
role: "user",
|
|
2199
2224
|
content: {
|
|
2200
2225
|
type: "text",
|
|
2201
|
-
text:
|
|
2202
|
-
errorMessage: `JSON parsing failed: ${parseError instanceof Error ? parseError.message : String(parseError)}
|
|
2226
|
+
text: `Invalid JSON: ${errorMsg}
|
|
2203
2227
|
|
|
2204
|
-
|
|
2205
|
-
})
|
|
2228
|
+
Respond with valid JSON.`
|
|
2206
2229
|
}
|
|
2207
2230
|
});
|
|
2208
2231
|
}
|
|
@@ -2340,11 +2363,11 @@ ${msg.content.text}`;
|
|
|
2340
2363
|
});
|
|
2341
2364
|
}
|
|
2342
2365
|
injectJsonInstruction({ prompt, schema, schemaPrefix = "JSON schema:", schemaSuffix = `STRICT REQUIREMENTS:
|
|
2343
|
-
1. Return ONLY raw JSON that passes JSON.parse() - no markdown, code blocks, explanatory text, or
|
|
2366
|
+
1. Return ONE AND ONLY ONE raw JSON object that passes JSON.parse() - no markdown, code blocks, explanatory text, or multiple JSON objects
|
|
2344
2367
|
2. Include ALL required fields with correct data types and satisfy ALL schema constraints (anyOf, oneOf, allOf, not, enum, pattern, min/max, conditionals)
|
|
2345
|
-
3. Your response must be
|
|
2368
|
+
3. Your response must be a single JSON object, nothing else
|
|
2346
2369
|
|
|
2347
|
-
INVALID: \`\`\`json{"key":"value"}\`\`\` or "Here is: {"key":"value"}"
|
|
2370
|
+
INVALID: \`\`\`json{"key":"value"}\`\`\` or "Here is: {"key":"value"}" or {"key":"value"}{"key":"value"}
|
|
2348
2371
|
VALID: {"key":"value"}` }) {
|
|
2349
2372
|
return [
|
|
2350
2373
|
prompt != null && prompt.length > 0 ? prompt : void 0,
|
|
@@ -2420,12 +2443,21 @@ var SamplingExecutor = class extends BaseSamplingExecutor {
|
|
|
2420
2443
|
}
|
|
2421
2444
|
async processAction(parsedData, schema, _state, parentSpan) {
|
|
2422
2445
|
const toolCallData = parsedData;
|
|
2446
|
+
const isComplete = toolCallData.decision === "complete";
|
|
2447
|
+
const actionName = toolCallData.action;
|
|
2448
|
+
if (isComplete && actionName && actionName !== "complete") {
|
|
2449
|
+
this.logger.debug({
|
|
2450
|
+
message: "Decision is 'complete' with action present, treating as 'proceed'",
|
|
2451
|
+
action: actionName
|
|
2452
|
+
});
|
|
2453
|
+
toolCallData.decision = "proceed";
|
|
2454
|
+
}
|
|
2423
2455
|
if (toolCallData.decision === "complete") {
|
|
2424
2456
|
return await this.createCompletionResult("Task completed", parentSpan);
|
|
2425
2457
|
}
|
|
2426
2458
|
try {
|
|
2427
2459
|
const { action: _action, decision: _decision, ..._toolArgs } = toolCallData;
|
|
2428
|
-
const toolResult = await this.agenticExecutor.execute(toolCallData, schema);
|
|
2460
|
+
const toolResult = await this.agenticExecutor.execute(toolCallData, schema, parentSpan);
|
|
2429
2461
|
const resultText = toolResult.content?.filter((content) => content.type === "text")?.map((content) => content.text)?.join("\n") || "No result";
|
|
2430
2462
|
this.conversationHistory.push({
|
|
2431
2463
|
role: "assistant",
|
|
@@ -2465,10 +2497,10 @@ ${JSON.stringify(context2, null, 2)}`;
|
|
|
2465
2497
|
const taskPrompt = `
|
|
2466
2498
|
|
|
2467
2499
|
## Current Task
|
|
2468
|
-
|
|
2500
|
+
You will now use agentic sampling to complete the following task: "${userRequest}"${contextInfo}
|
|
2469
2501
|
|
|
2470
|
-
When
|
|
2471
|
-
When the task is complete,
|
|
2502
|
+
When you need to use a tool, specify the tool name in 'action' and provide tool-specific parameters as additional properties.
|
|
2503
|
+
When the task is complete, use "action": "complete".`;
|
|
2472
2504
|
return this.injectJsonInstruction({
|
|
2473
2505
|
prompt: basePrompt + taskPrompt,
|
|
2474
2506
|
schema: agenticSchema
|
|
@@ -3040,6 +3072,15 @@ var WorkflowSamplingExecutor = class extends BaseSamplingExecutor {
|
|
|
3040
3072
|
throw new Error("WorkflowState is required for workflow");
|
|
3041
3073
|
}
|
|
3042
3074
|
const toolCallData = parsedData;
|
|
3075
|
+
const isComplete = toolCallData.decision === "complete";
|
|
3076
|
+
const actionName = toolCallData.action;
|
|
3077
|
+
if (isComplete && actionName && actionName !== "complete") {
|
|
3078
|
+
this.logger.debug({
|
|
3079
|
+
message: "Decision is 'complete' with action present, treating as 'proceed'",
|
|
3080
|
+
action: actionName
|
|
3081
|
+
});
|
|
3082
|
+
toolCallData.decision = "proceed";
|
|
3083
|
+
}
|
|
3043
3084
|
if (toolCallData.decision === "complete") {
|
|
3044
3085
|
return await this.createCompletionResult("Task completed", parentSpan);
|
|
3045
3086
|
}
|