pulse-coder-engine 0.0.1-alpha.3 → 0.0.1-alpha.6
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/LICENSE +21 -0
- package/dist/built-in/index.cjs +522 -63
- package/dist/built-in/index.cjs.map +1 -1
- package/dist/built-in/index.d.cts +1 -1
- package/dist/built-in/index.d.ts +1 -1
- package/dist/built-in/index.js +504 -47
- package/dist/built-in/index.js.map +1 -1
- package/dist/index-BkkQyz2L.d.cts +291 -0
- package/dist/index-BkkQyz2L.d.ts +291 -0
- package/dist/index.cjs +599 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +106 -46
- package/dist/index.d.ts +106 -46
- package/dist/index.js +575 -65
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/dist/index-DDqISE31.d.cts +0 -120
- package/dist/index-DDqISE31.d.ts +0 -120
package/dist/built-in/index.cjs
CHANGED
|
@@ -30,9 +30,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/built-in/index.ts
|
|
31
31
|
var built_in_exports = {};
|
|
32
32
|
__export(built_in_exports, {
|
|
33
|
+
BuiltInPlanModeService: () => BuiltInPlanModeService,
|
|
33
34
|
BuiltInSkillRegistry: () => BuiltInSkillRegistry,
|
|
34
35
|
SubAgentPlugin: () => SubAgentPlugin,
|
|
35
36
|
builtInMCPPlugin: () => builtInMCPPlugin,
|
|
37
|
+
builtInPlanModePlugin: () => builtInPlanModePlugin,
|
|
36
38
|
builtInPlugins: () => builtInPlugins,
|
|
37
39
|
builtInSkillsPlugin: () => builtInSkillsPlugin,
|
|
38
40
|
default: () => built_in_default
|
|
@@ -70,7 +72,7 @@ function createHTTPTransport(config) {
|
|
|
70
72
|
};
|
|
71
73
|
}
|
|
72
74
|
var builtInMCPPlugin = {
|
|
73
|
-
name: "
|
|
75
|
+
name: "pulse-coder-engine/built-in-mcp",
|
|
74
76
|
version: "1.0.0",
|
|
75
77
|
async initialize(context) {
|
|
76
78
|
const config = await loadMCPConfig(process.cwd());
|
|
@@ -257,7 +259,7 @@ function generateSkillTool(skills) {
|
|
|
257
259
|
};
|
|
258
260
|
}
|
|
259
261
|
var builtInSkillsPlugin = {
|
|
260
|
-
name: "
|
|
262
|
+
name: "pulse-coder-engine/built-in-skills",
|
|
261
263
|
version: "1.0.0",
|
|
262
264
|
async initialize(context) {
|
|
263
265
|
const registry = new BuiltInSkillRegistry();
|
|
@@ -274,10 +276,410 @@ var builtInSkillsPlugin = {
|
|
|
274
276
|
}
|
|
275
277
|
};
|
|
276
278
|
|
|
279
|
+
// src/built-in/plan-mode-plugin/index.ts
|
|
280
|
+
var PLANNING_POLICY = {
|
|
281
|
+
mode: "planning",
|
|
282
|
+
allowedCategories: ["read", "search", "other"],
|
|
283
|
+
disallowedCategories: ["write", "execute"],
|
|
284
|
+
notes: "Planning mode is prompt-constrained only. Disallowed tool attempts are observed and logged, not hard-blocked."
|
|
285
|
+
};
|
|
286
|
+
var EXECUTING_POLICY = {
|
|
287
|
+
mode: "executing",
|
|
288
|
+
allowedCategories: ["read", "search", "write", "execute", "other"],
|
|
289
|
+
disallowedCategories: []
|
|
290
|
+
};
|
|
291
|
+
var EXECUTE_PATTERNS = [
|
|
292
|
+
/开始执行/i,
|
|
293
|
+
/按这个计划做/i,
|
|
294
|
+
/可以改代码了/i,
|
|
295
|
+
/直接实现/i,
|
|
296
|
+
/go\s+ahead/i,
|
|
297
|
+
/proceed/i,
|
|
298
|
+
/implement\s+it/i,
|
|
299
|
+
/start\s+implement/i,
|
|
300
|
+
/start\s+coding/i
|
|
301
|
+
];
|
|
302
|
+
var NEGATIVE_PATTERNS = [
|
|
303
|
+
/先不(要)?执行/i,
|
|
304
|
+
/先别执行/i,
|
|
305
|
+
/不要执行/i,
|
|
306
|
+
/暂时不要执行/i,
|
|
307
|
+
/先别改代码/i,
|
|
308
|
+
/先不要改代码/i,
|
|
309
|
+
/先不要实现/i,
|
|
310
|
+
/not\s+now/i,
|
|
311
|
+
/hold\s+off/i,
|
|
312
|
+
/do\s+not\s+(start|execute|implement|proceed)/i,
|
|
313
|
+
/don't\s+(start|execute|implement|proceed)/i
|
|
314
|
+
];
|
|
315
|
+
var PLAN_PATTERNS = [/先计划/i, /先分析/i, /先出方案/i, /plan\s+first/i, /analysis\s+first/i];
|
|
316
|
+
function appendSystemPrompt(base, append) {
|
|
317
|
+
if (!append.trim()) {
|
|
318
|
+
return base ?? { append: "" };
|
|
319
|
+
}
|
|
320
|
+
if (!base) {
|
|
321
|
+
return { append };
|
|
322
|
+
}
|
|
323
|
+
if (typeof base === "string") {
|
|
324
|
+
return `${base}
|
|
325
|
+
|
|
326
|
+
${append}`;
|
|
327
|
+
}
|
|
328
|
+
if (typeof base === "function") {
|
|
329
|
+
return () => `${base()}
|
|
330
|
+
|
|
331
|
+
${append}`;
|
|
332
|
+
}
|
|
333
|
+
const currentAppend = base.append.trim();
|
|
334
|
+
return {
|
|
335
|
+
append: currentAppend ? `${currentAppend}
|
|
336
|
+
|
|
337
|
+
${append}` : append
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
var KNOWN_TOOL_META = {
|
|
341
|
+
read: {
|
|
342
|
+
category: "read",
|
|
343
|
+
risk: "low",
|
|
344
|
+
description: "Read file contents from the workspace."
|
|
345
|
+
},
|
|
346
|
+
ls: {
|
|
347
|
+
category: "read",
|
|
348
|
+
risk: "low",
|
|
349
|
+
description: "List files and directories."
|
|
350
|
+
},
|
|
351
|
+
grep: {
|
|
352
|
+
category: "search",
|
|
353
|
+
risk: "low",
|
|
354
|
+
description: "Search text content across files."
|
|
355
|
+
},
|
|
356
|
+
tavily: {
|
|
357
|
+
category: "search",
|
|
358
|
+
risk: "low",
|
|
359
|
+
description: "Search web results from external sources."
|
|
360
|
+
},
|
|
361
|
+
skill: {
|
|
362
|
+
category: "search",
|
|
363
|
+
risk: "low",
|
|
364
|
+
description: "Load procedural guidance from installed skills."
|
|
365
|
+
},
|
|
366
|
+
write: {
|
|
367
|
+
category: "write",
|
|
368
|
+
risk: "high",
|
|
369
|
+
description: "Create or overwrite file content."
|
|
370
|
+
},
|
|
371
|
+
edit: {
|
|
372
|
+
category: "write",
|
|
373
|
+
risk: "high",
|
|
374
|
+
description: "Modify existing files using exact replacements."
|
|
375
|
+
},
|
|
376
|
+
bash: {
|
|
377
|
+
category: "execute",
|
|
378
|
+
risk: "high",
|
|
379
|
+
description: "Execute shell commands."
|
|
380
|
+
},
|
|
381
|
+
clarify: {
|
|
382
|
+
category: "other",
|
|
383
|
+
risk: "low",
|
|
384
|
+
description: "Ask the user a targeted clarification question."
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
var BuiltInPlanModeService = class {
|
|
388
|
+
constructor(logger, eventEmitter, initialMode = "executing") {
|
|
389
|
+
this.logger = logger;
|
|
390
|
+
this.eventEmitter = eventEmitter;
|
|
391
|
+
this.mode = initialMode;
|
|
392
|
+
this.emitEvent("mode_entered", { reason: "initialize" });
|
|
393
|
+
}
|
|
394
|
+
mode;
|
|
395
|
+
events = [];
|
|
396
|
+
getMode() {
|
|
397
|
+
return this.mode;
|
|
398
|
+
}
|
|
399
|
+
setMode(mode, reason = "manual") {
|
|
400
|
+
if (this.mode === mode) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
this.mode = mode;
|
|
404
|
+
this.emitEvent("mode_entered", { reason });
|
|
405
|
+
}
|
|
406
|
+
detectIntent(input) {
|
|
407
|
+
const text = input.trim();
|
|
408
|
+
if (!text) {
|
|
409
|
+
return "UNCLEAR";
|
|
410
|
+
}
|
|
411
|
+
if (NEGATIVE_PATTERNS.some((pattern) => pattern.test(text))) {
|
|
412
|
+
return "PLAN_ONLY";
|
|
413
|
+
}
|
|
414
|
+
if (EXECUTE_PATTERNS.some((pattern) => pattern.test(text))) {
|
|
415
|
+
return "EXECUTE_NOW";
|
|
416
|
+
}
|
|
417
|
+
if (PLAN_PATTERNS.some((pattern) => pattern.test(text))) {
|
|
418
|
+
return "PLAN_ONLY";
|
|
419
|
+
}
|
|
420
|
+
return "UNCLEAR";
|
|
421
|
+
}
|
|
422
|
+
processContextMessages(messages) {
|
|
423
|
+
const userInput = this.getLatestUserText(messages);
|
|
424
|
+
const modeBefore = this.mode;
|
|
425
|
+
if (!userInput) {
|
|
426
|
+
return {
|
|
427
|
+
modeBefore,
|
|
428
|
+
modeAfter: this.mode,
|
|
429
|
+
switched: false,
|
|
430
|
+
intent: "UNCLEAR",
|
|
431
|
+
userInput: ""
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
const intent = this.detectIntent(userInput);
|
|
435
|
+
if (intent === "EXECUTE_NOW") {
|
|
436
|
+
this.emitEvent("execution_intent_detected", { intent, userInput });
|
|
437
|
+
if (this.mode === "planning") {
|
|
438
|
+
this.mode = "executing";
|
|
439
|
+
this.emitEvent("mode_switched_by_intent", {
|
|
440
|
+
from: "planning",
|
|
441
|
+
to: "executing",
|
|
442
|
+
userInput
|
|
443
|
+
});
|
|
444
|
+
this.emitEvent("mode_entered", {
|
|
445
|
+
reason: "intent",
|
|
446
|
+
from: "planning"
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
return {
|
|
451
|
+
modeBefore,
|
|
452
|
+
modeAfter: this.mode,
|
|
453
|
+
switched: modeBefore !== this.mode,
|
|
454
|
+
intent,
|
|
455
|
+
userInput
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
getModePolicy(mode = this.mode) {
|
|
459
|
+
return mode === "planning" ? PLANNING_POLICY : EXECUTING_POLICY;
|
|
460
|
+
}
|
|
461
|
+
getToolMetadata(toolNames) {
|
|
462
|
+
return Array.from(new Set(toolNames)).sort().map((name) => this.inferToolMeta(name));
|
|
463
|
+
}
|
|
464
|
+
buildPromptAppend(toolNames, transition) {
|
|
465
|
+
const mode = this.mode;
|
|
466
|
+
const policy = this.getModePolicy(mode);
|
|
467
|
+
const toolMeta = this.getToolMetadata(toolNames);
|
|
468
|
+
const shownTools = toolMeta.slice(0, 40);
|
|
469
|
+
const omittedCount = toolMeta.length - shownTools.length;
|
|
470
|
+
const lines = [
|
|
471
|
+
"## Plan Mode Policy (Built-in Plugin)",
|
|
472
|
+
`Current mode: ${mode.toUpperCase()}`,
|
|
473
|
+
`Allowed tool categories: ${policy.allowedCategories.join(", ")}`,
|
|
474
|
+
`Disallowed tool categories: ${policy.disallowedCategories.join(", ") || "none"}`,
|
|
475
|
+
policy.notes ? `Policy notes: ${policy.notes}` : ""
|
|
476
|
+
].filter(Boolean);
|
|
477
|
+
if (mode === "planning") {
|
|
478
|
+
lines.push(
|
|
479
|
+
"Planning objective: prioritize reading, analysis, and plan generation.",
|
|
480
|
+
"In planning mode, do not intentionally perform write/edit/execute actions.",
|
|
481
|
+
"If implementation is requested but intent is not explicit, ask for execution authorization.",
|
|
482
|
+
"Before each tool call in planning mode, self-check category compliance.",
|
|
483
|
+
"Plan format must include: goals, assumptions, steps, risks, validation approach."
|
|
484
|
+
);
|
|
485
|
+
} else {
|
|
486
|
+
lines.push(
|
|
487
|
+
"Executing objective: follow the agreed plan before broad exploration.",
|
|
488
|
+
"Make targeted edits and keep changes scoped.",
|
|
489
|
+
"Report what changed and how it was validated."
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
if (transition?.switched && transition.modeAfter === "executing") {
|
|
493
|
+
lines.push(
|
|
494
|
+
"Mode transition: the latest user message explicitly authorized execution.",
|
|
495
|
+
"In your next reply, acknowledge switching to EXECUTING mode before implementation details."
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
lines.push("Tool metadata (prompt-level policy reference):");
|
|
499
|
+
for (const meta of shownTools) {
|
|
500
|
+
lines.push(`- ${meta.name}: category=${meta.category}, risk=${meta.risk}, ${meta.description}`);
|
|
501
|
+
}
|
|
502
|
+
if (omittedCount > 0) {
|
|
503
|
+
lines.push(`- ... ${omittedCount} additional tool(s) omitted for brevity.`);
|
|
504
|
+
}
|
|
505
|
+
return lines.join("\n");
|
|
506
|
+
}
|
|
507
|
+
applyHooks(baseHooks) {
|
|
508
|
+
return {
|
|
509
|
+
onBeforeToolCall: async (name, input) => {
|
|
510
|
+
this.observePotentialPolicyViolation(name, input);
|
|
511
|
+
if (baseHooks?.onBeforeToolCall) {
|
|
512
|
+
const nextInput = await baseHooks.onBeforeToolCall(name, input);
|
|
513
|
+
return nextInput ?? input;
|
|
514
|
+
}
|
|
515
|
+
return input;
|
|
516
|
+
},
|
|
517
|
+
onAfterToolCall: async (name, input, output) => {
|
|
518
|
+
if (baseHooks?.onAfterToolCall) {
|
|
519
|
+
const nextOutput = await baseHooks.onAfterToolCall(name, input, output);
|
|
520
|
+
return nextOutput ?? output;
|
|
521
|
+
}
|
|
522
|
+
return output;
|
|
523
|
+
}
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
getEvents(limit = 50) {
|
|
527
|
+
return this.events.slice(-Math.max(0, limit));
|
|
528
|
+
}
|
|
529
|
+
observePotentialPolicyViolation(toolName, input) {
|
|
530
|
+
if (this.mode !== "planning") {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
const meta = this.inferToolMeta(toolName);
|
|
534
|
+
const policy = this.getModePolicy("planning");
|
|
535
|
+
if (!policy.disallowedCategories.includes(meta.category)) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
this.emitEvent("disallowed_tool_attempt_in_planning", {
|
|
539
|
+
toolName,
|
|
540
|
+
category: meta.category,
|
|
541
|
+
risk: meta.risk,
|
|
542
|
+
input
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
inferToolMeta(name) {
|
|
546
|
+
const knownMeta = KNOWN_TOOL_META[name];
|
|
547
|
+
if (knownMeta) {
|
|
548
|
+
return {
|
|
549
|
+
name,
|
|
550
|
+
...knownMeta
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
if (name.startsWith("mcp_")) {
|
|
554
|
+
return {
|
|
555
|
+
name,
|
|
556
|
+
category: "execute",
|
|
557
|
+
risk: "medium",
|
|
558
|
+
description: "MCP external tool invocation."
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
if (name.endsWith("_agent")) {
|
|
562
|
+
return {
|
|
563
|
+
name,
|
|
564
|
+
category: "execute",
|
|
565
|
+
risk: "high",
|
|
566
|
+
description: "Sub-agent task execution tool."
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
if (/read|list|cat/i.test(name)) {
|
|
570
|
+
return {
|
|
571
|
+
name,
|
|
572
|
+
category: "read",
|
|
573
|
+
risk: "low",
|
|
574
|
+
description: "Likely a read-only inspection tool inferred by name."
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
if (/search|find|query|grep/i.test(name)) {
|
|
578
|
+
return {
|
|
579
|
+
name,
|
|
580
|
+
category: "search",
|
|
581
|
+
risk: "low",
|
|
582
|
+
description: "Likely a search tool inferred by name."
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
if (/write|edit|patch|update|create|delete|remove/i.test(name)) {
|
|
586
|
+
return {
|
|
587
|
+
name,
|
|
588
|
+
category: "write",
|
|
589
|
+
risk: "high",
|
|
590
|
+
description: "Likely a file-modifying tool inferred by name."
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
if (/bash|exec|run|shell|deploy|build|test/i.test(name)) {
|
|
594
|
+
return {
|
|
595
|
+
name,
|
|
596
|
+
category: "execute",
|
|
597
|
+
risk: "high",
|
|
598
|
+
description: "Likely a command execution tool inferred by name."
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
return {
|
|
602
|
+
name,
|
|
603
|
+
category: "other",
|
|
604
|
+
risk: "low",
|
|
605
|
+
description: "Tool category could not be inferred with high confidence."
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
getLatestUserText(messages) {
|
|
609
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
610
|
+
const message = messages[i];
|
|
611
|
+
if (message.role !== "user") {
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
614
|
+
return this.messageContentToText(message.content);
|
|
615
|
+
}
|
|
616
|
+
return "";
|
|
617
|
+
}
|
|
618
|
+
messageContentToText(content) {
|
|
619
|
+
if (typeof content === "string") {
|
|
620
|
+
return content;
|
|
621
|
+
}
|
|
622
|
+
if (!Array.isArray(content)) {
|
|
623
|
+
return "";
|
|
624
|
+
}
|
|
625
|
+
const textParts = [];
|
|
626
|
+
for (const part of content) {
|
|
627
|
+
if (typeof part === "string") {
|
|
628
|
+
textParts.push(part);
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
if (part && typeof part === "object" && "text" in part && typeof part.text === "string") {
|
|
632
|
+
textParts.push(part.text);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return textParts.join("\n");
|
|
636
|
+
}
|
|
637
|
+
emitEvent(name, payload) {
|
|
638
|
+
const event = {
|
|
639
|
+
name,
|
|
640
|
+
mode: this.mode,
|
|
641
|
+
timestamp: Date.now(),
|
|
642
|
+
payload
|
|
643
|
+
};
|
|
644
|
+
this.events.push(event);
|
|
645
|
+
if (this.events.length > 500) {
|
|
646
|
+
this.events.shift();
|
|
647
|
+
}
|
|
648
|
+
this.eventEmitter.emit(name, event);
|
|
649
|
+
this.eventEmitter.emit("plan_mode_event", event);
|
|
650
|
+
if (name === "disallowed_tool_attempt_in_planning") {
|
|
651
|
+
this.logger.warn("[PlanMode] Soft violation detected in planning mode", payload);
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
this.logger.info(`[PlanMode] ${name}`, payload);
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
var builtInPlanModePlugin = {
|
|
658
|
+
name: "pulse-coder-engine/built-in-plan-mode",
|
|
659
|
+
version: "1.0.0",
|
|
660
|
+
async initialize(context) {
|
|
661
|
+
const service = new BuiltInPlanModeService(context.logger, context.events, "executing");
|
|
662
|
+
context.registerRunHook("plan-mode", ({ context: runContext, tools, systemPrompt, hooks }) => {
|
|
663
|
+
const transition = service.processContextMessages(runContext.messages);
|
|
664
|
+
const append = service.buildPromptAppend(Object.keys(tools), transition);
|
|
665
|
+
const finalSystemPrompt = appendSystemPrompt(systemPrompt, append);
|
|
666
|
+
return {
|
|
667
|
+
systemPrompt: finalSystemPrompt,
|
|
668
|
+
hooks: service.applyHooks(hooks)
|
|
669
|
+
};
|
|
670
|
+
});
|
|
671
|
+
context.registerService("planMode", service);
|
|
672
|
+
context.registerService("planModeService", service);
|
|
673
|
+
context.logger.info("[PlanMode] Built-in plan mode plugin initialized", {
|
|
674
|
+
mode: service.getMode()
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
|
|
277
679
|
// src/built-in/sub-agent-plugin/index.ts
|
|
278
680
|
var import_zod10 = require("zod");
|
|
279
|
-
var
|
|
280
|
-
var
|
|
681
|
+
var import_fs9 = require("fs");
|
|
682
|
+
var import_path3 = __toESM(require("path"), 1);
|
|
281
683
|
|
|
282
684
|
// src/ai/index.ts
|
|
283
685
|
var import_ai = require("ai");
|
|
@@ -293,7 +695,7 @@ var CoderAI = process.env.USE_ANTHROPIC ? (0, import_anthropic.createAnthropic)(
|
|
|
293
695
|
}) : (0, import_openai.createOpenAI)({
|
|
294
696
|
apiKey: process.env.OPENAI_API_KEY || "",
|
|
295
697
|
baseURL: process.env.OPENAI_API_URL || "https://api.openai.com/v1"
|
|
296
|
-
}).
|
|
698
|
+
}).responses;
|
|
297
699
|
var DEFAULT_MODEL = process.env.ANTHROPIC_MODEL || process.env.OPENAI_MODEL || "novita/deepseek/deepseek_v3";
|
|
298
700
|
var MAX_ERROR_COUNT = 3;
|
|
299
701
|
var MAX_STEPS = 100;
|
|
@@ -309,8 +711,9 @@ var CLARIFICATION_TIMEOUT = Number(process.env.CLARIFICATION_TIMEOUT ?? 3e5);
|
|
|
309
711
|
var CLARIFICATION_ENABLED = process.env.CLARIFICATION_ENABLED !== "false";
|
|
310
712
|
|
|
311
713
|
// src/prompt/system.ts
|
|
312
|
-
var
|
|
313
|
-
|
|
714
|
+
var import_fs3 = __toESM(require("fs"), 1);
|
|
715
|
+
var import_path = __toESM(require("path"), 1);
|
|
716
|
+
var DEFAULT_PROMPT = `
|
|
314
717
|
You are Pulse Coder, the best coding agent on the planet.
|
|
315
718
|
|
|
316
719
|
You are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
|
|
@@ -390,7 +793,7 @@ Use the 'clarify' tool when you genuinely need information from the user to proc
|
|
|
390
793
|
- Explain briefly what would change based on the answer
|
|
391
794
|
|
|
392
795
|
Example usage: Call clarify with a question, optional context, and optional default answer. The tool will pause and wait for the user's response.
|
|
393
|
-
- For substantial work, summarize clearly; follow final
|
|
796
|
+
- For substantial work, summarize clearly; follow final-answer formatting.
|
|
394
797
|
- Skip heavy formatting for simple confirmations.
|
|
395
798
|
- Don't dump large files you've written; reference paths only.
|
|
396
799
|
- No "save/copy this file" - User is on the same machine.
|
|
@@ -404,19 +807,19 @@ Example usage: Call clarify with a question, optional context, and optional defa
|
|
|
404
807
|
## Final answer structure and style guidelines
|
|
405
808
|
|
|
406
809
|
- Plain text; CLI handles styling. Use structure only when it helps scanability.
|
|
407
|
-
- Headers: optional; short Title Case (1-3 words) wrapped in
|
|
408
|
-
- Bullets: use - ; merge related points; keep to one line when possible; 4
|
|
810
|
+
- Headers: optional; short Title Case (1-3 words) wrapped in **...**; no blank line before the first bullet; add only if they truly help.
|
|
811
|
+
- Bullets: use - ; merge related points; keep to one line when possible; 4-6 per list ordered by importance; keep phrasing consistent.
|
|
409
812
|
- Monospace: backticks for commands/paths/env vars/code ids and inline examples; use for literal keyword bullets; never combine with **.
|
|
410
813
|
- Code samples or multi-line snippets should be wrapped in fenced code blocks; include an info string as often as possible.
|
|
411
|
-
- Structure: group related bullets; order sections general
|
|
412
|
-
- Tone: collaborative, concise, factual; present tense, active voice; self
|
|
413
|
-
- Don'ts: no nested bullets/hierarchies; no ANSI codes; don't cram unrelated keywords; keep keyword lists short
|
|
414
|
-
- Adaptation: code explanations
|
|
814
|
+
- Structure: group related bullets; order sections general -> specific -> supporting; for subsections, start with a bolded keyword bullet, then items; match complexity to the task.
|
|
815
|
+
- Tone: collaborative, concise, factual; present tense, active voice; self-contained; no "above/below"; parallel wording.
|
|
816
|
+
- Don'ts: no nested bullets/hierarchies; no ANSI codes; don't cram unrelated keywords; keep keyword lists short-wrap/reformat if long; avoid naming formatting styles in answers.
|
|
817
|
+
- Adaptation: code explanations -> precise, structured with code refs; simple tasks -> lead with outcome; big changes -> logical walkthrough + rationale + next actions; casual one-offs -> plain sentences, no headers/bullets.
|
|
415
818
|
- File References: When referencing files in your response follow the below rules:
|
|
416
819
|
* Use inline code to make file paths clickable.
|
|
417
820
|
* Each reference should have a stand alone path. Even if it's the same file.
|
|
418
|
-
* Accepted: absolute, workspace
|
|
419
|
-
* Optionally include line/column (1
|
|
821
|
+
* Accepted: absolute, workspace-relative, a/ or b/ diff prefixes, or bare filename/suffix.
|
|
822
|
+
* Optionally include line/column (1-based): :line[:column] or #Lline[Ccolumn] (column defaults to 1).
|
|
420
823
|
* Do not use URIs like file://, vscode://, or https://.
|
|
421
824
|
* Do not provide range of lines
|
|
422
825
|
* Examples: src/app.ts, src/app.ts:42, b/server/index.js#L10, C:\repoprojectmain.rs:12:5
|
|
@@ -430,11 +833,37 @@ Here is some useful information about the environment you are running in:
|
|
|
430
833
|
<files>
|
|
431
834
|
|
|
432
835
|
</files>`;
|
|
433
|
-
|
|
836
|
+
var AGENTS_FILE_REGEX = /^agents\.md$/i;
|
|
837
|
+
var loadAgentsPrompt = () => {
|
|
838
|
+
try {
|
|
839
|
+
const cwd = process.cwd();
|
|
840
|
+
const entries = import_fs3.default.readdirSync(cwd, { withFileTypes: true });
|
|
841
|
+
const target = entries.find((entry) => entry.isFile() && AGENTS_FILE_REGEX.test(entry.name));
|
|
842
|
+
if (!target) {
|
|
843
|
+
return null;
|
|
844
|
+
}
|
|
845
|
+
const filePath = import_path.default.join(cwd, target.name);
|
|
846
|
+
const content = import_fs3.default.readFileSync(filePath, "utf8").trim();
|
|
847
|
+
return content.length > 0 ? content : null;
|
|
848
|
+
} catch {
|
|
849
|
+
return null;
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
var generateSystemPrompt = () => {
|
|
853
|
+
return loadAgentsPrompt() ?? DEFAULT_PROMPT;
|
|
434
854
|
};
|
|
435
855
|
|
|
436
856
|
// src/ai/index.ts
|
|
437
|
-
var providerOptions =
|
|
857
|
+
var providerOptions = { openai: { store: false, reasoningEffort: OPENAI_REASONING_EFFORT } };
|
|
858
|
+
var resolveSystemPrompt = (option) => {
|
|
859
|
+
const base = generateSystemPrompt();
|
|
860
|
+
if (!option) return base;
|
|
861
|
+
if (typeof option === "string") return option;
|
|
862
|
+
if (typeof option === "function") return option();
|
|
863
|
+
return `${base}
|
|
864
|
+
|
|
865
|
+
${option.append}`;
|
|
866
|
+
};
|
|
438
867
|
var wrapToolsWithContext = (tools, context) => {
|
|
439
868
|
const wrappedTools = {};
|
|
440
869
|
for (const [name, tool2] of Object.entries(tools)) {
|
|
@@ -448,17 +877,13 @@ var wrapToolsWithContext = (tools, context) => {
|
|
|
448
877
|
return wrappedTools;
|
|
449
878
|
};
|
|
450
879
|
var streamTextAI = (messages, tools, options) => {
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
role: "system",
|
|
454
|
-
content: generateSystemPrompt()
|
|
455
|
-
},
|
|
456
|
-
...messages
|
|
457
|
-
];
|
|
880
|
+
const provider = options?.provider ?? CoderAI;
|
|
881
|
+
const model = options?.model ?? DEFAULT_MODEL;
|
|
458
882
|
const wrappedTools = options?.toolExecutionContext ? wrapToolsWithContext(tools, options.toolExecutionContext) : tools;
|
|
459
883
|
return (0, import_ai.streamText)({
|
|
460
|
-
model:
|
|
461
|
-
|
|
884
|
+
model: provider(model),
|
|
885
|
+
system: resolveSystemPrompt(options?.systemPrompt),
|
|
886
|
+
messages,
|
|
462
887
|
tools: wrappedTools,
|
|
463
888
|
providerOptions,
|
|
464
889
|
abortSignal: options?.abortSignal,
|
|
@@ -467,6 +892,8 @@ var streamTextAI = (messages, tools, options) => {
|
|
|
467
892
|
});
|
|
468
893
|
};
|
|
469
894
|
var summarizeMessages = async (messages, options) => {
|
|
895
|
+
const provider = options?.provider ?? CoderAI;
|
|
896
|
+
const model = options?.model ?? DEFAULT_MODEL;
|
|
470
897
|
const SUMMARY_SYSTEM_PROMPT = "\u4F60\u662F\u8D1F\u8D23\u538B\u7F29\u5BF9\u8BDD\u4E0A\u4E0B\u6587\u7684\u52A9\u624B\u3002\u8BF7\u57FA\u4E8E\u7ED9\u5B9A\u5386\u53F2\u6D88\u606F\uFF0C\u63D0\u70BC\u5173\u952E\u4E8B\u5B9E\u4E0E\u51B3\u7B56\uFF0C\u907F\u514D\u81C6\u6D4B\u6216\u6269\u5C55\u3002";
|
|
471
898
|
const SUMMARY_USER_PROMPT = [
|
|
472
899
|
"\u8BF7\u5C06\u4EE5\u4E0A\u5BF9\u8BDD\u538B\u7F29\u4E3A\u4EE5\u4E0B\u683C\u5F0F\uFF0C\u4F7F\u7528\u4E2D\u6587\uFF1A",
|
|
@@ -481,9 +908,9 @@ var summarizeMessages = async (messages, options) => {
|
|
|
481
908
|
"\u8981\u6C42\uFF1A\u5185\u5BB9\u7B80\u6D01\u51C6\u786E\uFF0C\u4E0D\u8981\u7F16\u9020\u3002"
|
|
482
909
|
].join("\n");
|
|
483
910
|
const result = await (0, import_ai.generateText)({
|
|
484
|
-
model:
|
|
911
|
+
model: provider(model),
|
|
912
|
+
system: SUMMARY_SYSTEM_PROMPT,
|
|
485
913
|
messages: [
|
|
486
|
-
{ role: "system", content: SUMMARY_SYSTEM_PROMPT },
|
|
487
914
|
...messages,
|
|
488
915
|
{ role: "user", content: SUMMARY_USER_PROMPT }
|
|
489
916
|
],
|
|
@@ -571,7 +998,10 @@ var maybeCompactContext = async (context, options) => {
|
|
|
571
998
|
return { didCompact: false };
|
|
572
999
|
}
|
|
573
1000
|
try {
|
|
574
|
-
const summary = await summarizeMessages(oldMessages
|
|
1001
|
+
const summary = await summarizeMessages(oldMessages, {
|
|
1002
|
+
provider: options?.provider,
|
|
1003
|
+
model: options?.model
|
|
1004
|
+
});
|
|
575
1005
|
const summaryText = ensureSummaryPrefix(summary);
|
|
576
1006
|
if (!summaryText) {
|
|
577
1007
|
throw new Error("Empty summary result");
|
|
@@ -598,6 +1028,20 @@ var maybeCompactContext = async (context, options) => {
|
|
|
598
1028
|
};
|
|
599
1029
|
|
|
600
1030
|
// src/core/loop.ts
|
|
1031
|
+
function applyToolHooks(tools, hooks) {
|
|
1032
|
+
const wrapped = {};
|
|
1033
|
+
for (const [name, t] of Object.entries(tools)) {
|
|
1034
|
+
wrapped[name] = {
|
|
1035
|
+
...t,
|
|
1036
|
+
execute: async (input, ctx) => {
|
|
1037
|
+
const finalInput = hooks.onBeforeToolCall ? await hooks.onBeforeToolCall(name, input) ?? input : input;
|
|
1038
|
+
const output = await t.execute(finalInput, ctx);
|
|
1039
|
+
return hooks.onAfterToolCall ? await hooks.onAfterToolCall(name, finalInput, output) ?? output : output;
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
return wrapped;
|
|
1044
|
+
}
|
|
601
1045
|
async function loop(context, options) {
|
|
602
1046
|
let errorCount = 0;
|
|
603
1047
|
let totalSteps = 0;
|
|
@@ -605,7 +1049,10 @@ async function loop(context, options) {
|
|
|
605
1049
|
while (true) {
|
|
606
1050
|
try {
|
|
607
1051
|
if (compactionAttempts < MAX_COMPACTION_ATTEMPTS) {
|
|
608
|
-
const { didCompact, newMessages } = await maybeCompactContext(context
|
|
1052
|
+
const { didCompact, newMessages } = await maybeCompactContext(context, {
|
|
1053
|
+
provider: options?.provider,
|
|
1054
|
+
model: options?.model
|
|
1055
|
+
});
|
|
609
1056
|
if (didCompact) {
|
|
610
1057
|
compactionAttempts++;
|
|
611
1058
|
if (newMessages) {
|
|
@@ -614,7 +1061,10 @@ async function loop(context, options) {
|
|
|
614
1061
|
continue;
|
|
615
1062
|
}
|
|
616
1063
|
}
|
|
617
|
-
|
|
1064
|
+
let tools = options?.tools || {};
|
|
1065
|
+
if (options?.hooks) {
|
|
1066
|
+
tools = applyToolHooks(tools, options.hooks);
|
|
1067
|
+
}
|
|
618
1068
|
const toolExecutionContext = {
|
|
619
1069
|
onClarificationRequest: options?.onClarificationRequest,
|
|
620
1070
|
abortSignal: options?.abortSignal
|
|
@@ -622,6 +1072,9 @@ async function loop(context, options) {
|
|
|
622
1072
|
const result = streamTextAI(context.messages, tools, {
|
|
623
1073
|
abortSignal: options?.abortSignal,
|
|
624
1074
|
toolExecutionContext,
|
|
1075
|
+
provider: options?.provider,
|
|
1076
|
+
model: options?.model,
|
|
1077
|
+
systemPrompt: options?.systemPrompt,
|
|
625
1078
|
onStepFinish: (step) => {
|
|
626
1079
|
options?.onStepFinish?.(step);
|
|
627
1080
|
},
|
|
@@ -654,7 +1107,11 @@ async function loop(context, options) {
|
|
|
654
1107
|
}
|
|
655
1108
|
if (finishReason === "length") {
|
|
656
1109
|
if (compactionAttempts < MAX_COMPACTION_ATTEMPTS) {
|
|
657
|
-
const { didCompact, newMessages } = await maybeCompactContext(context, {
|
|
1110
|
+
const { didCompact, newMessages } = await maybeCompactContext(context, {
|
|
1111
|
+
force: true,
|
|
1112
|
+
provider: options?.provider,
|
|
1113
|
+
model: options?.model
|
|
1114
|
+
});
|
|
658
1115
|
if (didCompact) {
|
|
659
1116
|
compactionAttempts++;
|
|
660
1117
|
if (newMessages) {
|
|
@@ -705,7 +1162,7 @@ function sleep(ms) {
|
|
|
705
1162
|
|
|
706
1163
|
// src/tools/read.ts
|
|
707
1164
|
var import_zod2 = __toESM(require("zod"), 1);
|
|
708
|
-
var
|
|
1165
|
+
var import_fs4 = require("fs");
|
|
709
1166
|
|
|
710
1167
|
// src/tools/utils.ts
|
|
711
1168
|
var truncateOutput = (output) => {
|
|
@@ -731,14 +1188,14 @@ var ReadTool = {
|
|
|
731
1188
|
limit: import_zod2.default.number().optional().describe("The number of lines to read. Only provide if the file is too large to read at once.")
|
|
732
1189
|
}),
|
|
733
1190
|
execute: async ({ filePath, offset, limit }) => {
|
|
734
|
-
if (!(0,
|
|
1191
|
+
if (!(0, import_fs4.existsSync)(filePath)) {
|
|
735
1192
|
throw new Error(`File does not exist: ${filePath}`);
|
|
736
1193
|
}
|
|
737
|
-
const stats = (0,
|
|
1194
|
+
const stats = (0, import_fs4.statSync)(filePath);
|
|
738
1195
|
if (stats.isDirectory()) {
|
|
739
1196
|
throw new Error(`Cannot read directory: ${filePath}. Use 'ls' tool to list directory contents.`);
|
|
740
1197
|
}
|
|
741
|
-
const content = (0,
|
|
1198
|
+
const content = (0, import_fs4.readFileSync)(filePath, "utf-8");
|
|
742
1199
|
const lines = content.split("\n");
|
|
743
1200
|
const totalLines = lines.length;
|
|
744
1201
|
if (offset === void 0 && limit === void 0) {
|
|
@@ -766,8 +1223,8 @@ var ReadTool = {
|
|
|
766
1223
|
|
|
767
1224
|
// src/tools/write.ts
|
|
768
1225
|
var import_zod3 = __toESM(require("zod"), 1);
|
|
769
|
-
var
|
|
770
|
-
var
|
|
1226
|
+
var import_fs5 = require("fs");
|
|
1227
|
+
var import_path2 = require("path");
|
|
771
1228
|
var WriteTool = {
|
|
772
1229
|
name: "write",
|
|
773
1230
|
description: "Write contents to a file. Automatically creates parent directories if they do not exist. Will overwrite existing files.",
|
|
@@ -776,12 +1233,12 @@ var WriteTool = {
|
|
|
776
1233
|
content: import_zod3.default.string().describe("The content to write to the file")
|
|
777
1234
|
}),
|
|
778
1235
|
execute: async ({ filePath, content }) => {
|
|
779
|
-
const fileExists = (0,
|
|
780
|
-
const dir = (0,
|
|
781
|
-
if (!(0,
|
|
782
|
-
(0,
|
|
1236
|
+
const fileExists = (0, import_fs5.existsSync)(filePath);
|
|
1237
|
+
const dir = (0, import_path2.dirname)(filePath);
|
|
1238
|
+
if (!(0, import_fs5.existsSync)(dir)) {
|
|
1239
|
+
(0, import_fs5.mkdirSync)(dir, { recursive: true });
|
|
783
1240
|
}
|
|
784
|
-
(0,
|
|
1241
|
+
(0, import_fs5.writeFileSync)(filePath, content, "utf-8");
|
|
785
1242
|
const bytes = Buffer.byteLength(content, "utf-8");
|
|
786
1243
|
return {
|
|
787
1244
|
success: true,
|
|
@@ -793,7 +1250,7 @@ var WriteTool = {
|
|
|
793
1250
|
|
|
794
1251
|
// src/tools/edit.ts
|
|
795
1252
|
var import_zod4 = __toESM(require("zod"), 1);
|
|
796
|
-
var
|
|
1253
|
+
var import_fs6 = require("fs");
|
|
797
1254
|
var EditTool = {
|
|
798
1255
|
name: "edit",
|
|
799
1256
|
description: "Performs exact string replacements in files. Use this to edit existing files by replacing old_string with new_string.",
|
|
@@ -807,7 +1264,7 @@ var EditTool = {
|
|
|
807
1264
|
if (oldString === newString) {
|
|
808
1265
|
throw new Error("old_string and new_string must be different");
|
|
809
1266
|
}
|
|
810
|
-
const content = (0,
|
|
1267
|
+
const content = (0, import_fs6.readFileSync)(filePath, "utf-8");
|
|
811
1268
|
if (!content.includes(oldString)) {
|
|
812
1269
|
throw new Error(`old_string not found in file: ${filePath}`);
|
|
813
1270
|
}
|
|
@@ -831,7 +1288,7 @@ var EditTool = {
|
|
|
831
1288
|
newContent = content.slice(0, index) + newString + content.slice(index + oldString.length);
|
|
832
1289
|
replacements = 1;
|
|
833
1290
|
}
|
|
834
|
-
(0,
|
|
1291
|
+
(0, import_fs6.writeFileSync)(filePath, newContent, "utf-8");
|
|
835
1292
|
const changedIndex = newContent.indexOf(newString);
|
|
836
1293
|
const contextLength = 200;
|
|
837
1294
|
const start = Math.max(0, changedIndex - contextLength);
|
|
@@ -850,7 +1307,7 @@ var EditTool = {
|
|
|
850
1307
|
// src/tools/grep.ts
|
|
851
1308
|
var import_zod5 = __toESM(require("zod"), 1);
|
|
852
1309
|
var import_child_process = require("child_process");
|
|
853
|
-
var
|
|
1310
|
+
var import_fs7 = require("fs");
|
|
854
1311
|
var GrepTool = {
|
|
855
1312
|
name: "grep",
|
|
856
1313
|
description: "A powerful search tool built on ripgrep. Supports regex patterns, file filtering, and multiple output modes.",
|
|
@@ -868,7 +1325,7 @@ var GrepTool = {
|
|
|
868
1325
|
}),
|
|
869
1326
|
execute: async ({
|
|
870
1327
|
pattern,
|
|
871
|
-
path:
|
|
1328
|
+
path: path4 = ".",
|
|
872
1329
|
glob,
|
|
873
1330
|
type,
|
|
874
1331
|
outputMode = "files_with_matches",
|
|
@@ -903,11 +1360,11 @@ var GrepTool = {
|
|
|
903
1360
|
if (type) {
|
|
904
1361
|
args.push("--type", type);
|
|
905
1362
|
}
|
|
906
|
-
if (
|
|
907
|
-
if (!(0,
|
|
908
|
-
throw new Error(`Path does not exist: ${
|
|
1363
|
+
if (path4 && path4 !== ".") {
|
|
1364
|
+
if (!(0, import_fs7.existsSync)(path4)) {
|
|
1365
|
+
throw new Error(`Path does not exist: ${path4}`);
|
|
909
1366
|
}
|
|
910
|
-
args.push(
|
|
1367
|
+
args.push(path4);
|
|
911
1368
|
}
|
|
912
1369
|
let command = args.map((arg) => {
|
|
913
1370
|
if (arg.includes(" ") || arg.includes("$") || arg.includes("*")) {
|
|
@@ -955,15 +1412,15 @@ Command: ${command}`
|
|
|
955
1412
|
|
|
956
1413
|
// src/tools/ls.ts
|
|
957
1414
|
var import_zod6 = __toESM(require("zod"), 1);
|
|
958
|
-
var
|
|
1415
|
+
var import_fs8 = require("fs");
|
|
959
1416
|
var LsTool = {
|
|
960
1417
|
name: "ls",
|
|
961
1418
|
description: "List files and directories in a given path",
|
|
962
1419
|
inputSchema: import_zod6.default.object({
|
|
963
1420
|
path: import_zod6.default.string().optional().describe("The path to list files from (defaults to current directory)")
|
|
964
1421
|
}),
|
|
965
|
-
execute: async ({ path:
|
|
966
|
-
const files = (0,
|
|
1422
|
+
execute: async ({ path: path4 = "." }) => {
|
|
1423
|
+
const files = (0, import_fs8.readdirSync)(path4);
|
|
967
1424
|
return { files };
|
|
968
1425
|
}
|
|
969
1426
|
};
|
|
@@ -1134,8 +1591,8 @@ var ConfigLoader = class {
|
|
|
1134
1591
|
const fileInfos = [];
|
|
1135
1592
|
for (let configDir of configDirs) {
|
|
1136
1593
|
try {
|
|
1137
|
-
await
|
|
1138
|
-
const files = await
|
|
1594
|
+
await import_fs9.promises.access(configDir);
|
|
1595
|
+
const files = await import_fs9.promises.readdir(configDir);
|
|
1139
1596
|
fileInfos.push({ files, configDir });
|
|
1140
1597
|
} catch {
|
|
1141
1598
|
continue;
|
|
@@ -1152,7 +1609,7 @@ var ConfigLoader = class {
|
|
|
1152
1609
|
const files = fileInfo.files;
|
|
1153
1610
|
for (const file of files) {
|
|
1154
1611
|
if (file.endsWith(".md")) {
|
|
1155
|
-
const config = await this.parseConfig(
|
|
1612
|
+
const config = await this.parseConfig(import_path3.default.join(fileInfo.configDir, file));
|
|
1156
1613
|
if (config) configs.push(config);
|
|
1157
1614
|
}
|
|
1158
1615
|
}
|
|
@@ -1164,7 +1621,7 @@ var ConfigLoader = class {
|
|
|
1164
1621
|
}
|
|
1165
1622
|
async parseConfig(filePath) {
|
|
1166
1623
|
try {
|
|
1167
|
-
const content = await
|
|
1624
|
+
const content = await import_fs9.promises.readFile(filePath, "utf-8");
|
|
1168
1625
|
const lines = content.split("\n");
|
|
1169
1626
|
let name = "";
|
|
1170
1627
|
let description = "";
|
|
@@ -1193,7 +1650,7 @@ var ConfigLoader = class {
|
|
|
1193
1650
|
}
|
|
1194
1651
|
}
|
|
1195
1652
|
if (!name) {
|
|
1196
|
-
name =
|
|
1653
|
+
name = import_path3.default.basename(filePath, ".md");
|
|
1197
1654
|
}
|
|
1198
1655
|
return {
|
|
1199
1656
|
name: name.trim(),
|
|
@@ -1211,7 +1668,6 @@ var AgentRunner = class {
|
|
|
1211
1668
|
async runAgent(config, task, context, tools) {
|
|
1212
1669
|
const subContext = {
|
|
1213
1670
|
messages: [
|
|
1214
|
-
{ role: "system", content: config.systemPrompt },
|
|
1215
1671
|
{ role: "user", content: task }
|
|
1216
1672
|
]
|
|
1217
1673
|
};
|
|
@@ -1222,7 +1678,7 @@ var AgentRunner = class {
|
|
|
1222
1678
|
${JSON.stringify(context, null, 2)}`
|
|
1223
1679
|
});
|
|
1224
1680
|
}
|
|
1225
|
-
return await loop(subContext, { tools });
|
|
1681
|
+
return await loop(subContext, { tools, systemPrompt: config.systemPrompt });
|
|
1226
1682
|
}
|
|
1227
1683
|
};
|
|
1228
1684
|
var SubAgentPlugin = class {
|
|
@@ -1277,14 +1733,17 @@ var SubAgentPlugin = class {
|
|
|
1277
1733
|
var builtInPlugins = [
|
|
1278
1734
|
builtInMCPPlugin,
|
|
1279
1735
|
builtInSkillsPlugin,
|
|
1736
|
+
builtInPlanModePlugin,
|
|
1280
1737
|
new SubAgentPlugin()
|
|
1281
1738
|
];
|
|
1282
1739
|
var built_in_default = builtInPlugins;
|
|
1283
1740
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1284
1741
|
0 && (module.exports = {
|
|
1742
|
+
BuiltInPlanModeService,
|
|
1285
1743
|
BuiltInSkillRegistry,
|
|
1286
1744
|
SubAgentPlugin,
|
|
1287
1745
|
builtInMCPPlugin,
|
|
1746
|
+
builtInPlanModePlugin,
|
|
1288
1747
|
builtInPlugins,
|
|
1289
1748
|
builtInSkillsPlugin
|
|
1290
1749
|
});
|