opencode-matrixx 2.6.7 → 2.6.8

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 (28) hide show
  1. package/dist/agents/seraph.d.ts +1 -1
  2. package/dist/cli.js +1 -1
  3. package/dist/config/schema/dcp.d.ts +1 -1
  4. package/dist/features/background-agent/constants.d.ts +2 -2
  5. package/dist/features/builtin-commands/templates/refactor.d.ts +1 -1
  6. package/dist/features/context-injector/collector.d.ts +2 -0
  7. package/dist/features/context-injector/index.d.ts +1 -1
  8. package/dist/hooks/agent-usage-reminder/constants.d.ts +1 -0
  9. package/dist/hooks/compaction-context-injector/hook.d.ts +1 -0
  10. package/dist/hooks/task-continuation-enforcer/constants.d.ts +4 -0
  11. package/dist/index.js +306 -603
  12. package/dist/matrixx.schema.json +1 -1
  13. package/dist/shared/poll-timeout-outcome.d.ts +21 -0
  14. package/dist/tools/dcp-switch-profile/tools.d.ts +6 -0
  15. package/dist/tools/delegate-task/constants.d.ts +1 -0
  16. package/dist/tools/delegate-task/poll-timeout-outcome.test.d.ts +1 -0
  17. package/dist/tools/index.d.ts +0 -1
  18. package/package.json +1 -1
  19. package/dist/tools/delegate-agent/background-executor.d.ts +0 -13
  20. package/dist/tools/delegate-agent/completion-poller.d.ts +0 -11
  21. package/dist/tools/delegate-agent/constants.d.ts +0 -2
  22. package/dist/tools/delegate-agent/index.d.ts +0 -3
  23. package/dist/tools/delegate-agent/message-dir.d.ts +0 -1
  24. package/dist/tools/delegate-agent/message-processor.d.ts +0 -2
  25. package/dist/tools/delegate-agent/session-creator.d.ts +0 -15
  26. package/dist/tools/delegate-agent/sync-executor.d.ts +0 -21
  27. package/dist/tools/delegate-agent/tools.d.ts +0 -3
  28. package/dist/tools/delegate-agent/types.d.ts +0 -19
package/dist/index.js CHANGED
@@ -29558,7 +29558,6 @@ var init_ulw_research = __esm(() => {
29558
29558
  "grep",
29559
29559
  "glob",
29560
29560
  "look_at",
29561
- "delegate_agent",
29562
29561
  "websearch_web_search_exa",
29563
29562
  "white_rabbit_searchGitHub",
29564
29563
  "context7_resolve-library-id",
@@ -30093,8 +30092,7 @@ import { join as join16 } from "path";
30093
30092
  var EXPLORATION_AGENT_DENYLIST = {
30094
30093
  write: false,
30095
30094
  edit: false,
30096
- task: false,
30097
- delegate_agent: false
30095
+ task: false
30098
30096
  };
30099
30097
  var AGENT_RESTRICTIONS = {
30100
30098
  trinity: EXPLORATION_AGENT_DENYLIST,
@@ -30102,8 +30100,7 @@ var AGENT_RESTRICTIONS = {
30102
30100
  merovingian: {
30103
30101
  write: false,
30104
30102
  edit: false,
30105
- task: false,
30106
- delegate_agent: false
30103
+ task: false
30107
30104
  },
30108
30105
  seraph: {
30109
30106
  write: false,
@@ -48173,10 +48170,9 @@ var TARGET_TOOLS = new Set([
48173
48170
  "white_rabbit_searchgithub"
48174
48171
  ]);
48175
48172
  var AGENT_TOOLS = new Set([
48176
- "task",
48177
- "delegate_agent",
48178
48173
  "task"
48179
48174
  ]);
48175
+ var MAX_AGENT_USAGE_REMINDERS = 3;
48180
48176
  var REMINDER_MESSAGE = `
48181
48177
  [Agent Usage Reminder]
48182
48178
 
@@ -48281,6 +48277,9 @@ function createAgentUsageReminderHook(_ctx) {
48281
48277
  if (state.agentUsed) {
48282
48278
  return;
48283
48279
  }
48280
+ if (state.reminderCount >= MAX_AGENT_USAGE_REMINDERS) {
48281
+ return;
48282
+ }
48284
48283
  output.output += REMINDER_MESSAGE;
48285
48284
  state.reminderCount++;
48286
48285
  state.updatedAt = Date.now();
@@ -50467,11 +50466,11 @@ TodoWrite([
50467
50466
 
50468
50467
  ## 1.1: Launch Parallel Explore Agents (BACKGROUND)
50469
50468
 
50470
- Fire ALL of these simultaneously using \`delegate_agent\`:
50469
+ Fire ALL of these simultaneously using \`task\`:
50471
50470
 
50472
50471
  \`\`\`
50473
50472
  // Agent 1: Find the refactoring target
50474
- delegate_agent(
50473
+ task(
50475
50474
  subagent_type="trinity",
50476
50475
  run_in_background=true,
50477
50476
  prompt="Find all occurrences and definitions of [TARGET].
@@ -50479,7 +50478,7 @@ delegate_agent(
50479
50478
  )
50480
50479
 
50481
50480
  // Agent 2: Find related code
50482
- delegate_agent(
50481
+ task(
50483
50482
  subagent_type="trinity",
50484
50483
  run_in_background=true,
50485
50484
  prompt="Find all code that imports, uses, or depends on [TARGET].
@@ -50487,7 +50486,7 @@ delegate_agent(
50487
50486
  )
50488
50487
 
50489
50488
  // Agent 3: Find similar patterns
50490
- delegate_agent(
50489
+ task(
50491
50490
  subagent_type="trinity",
50492
50491
  run_in_background=true,
50493
50492
  prompt="Find similar code patterns to [TARGET] in the codebase.
@@ -50495,7 +50494,7 @@ delegate_agent(
50495
50494
  )
50496
50495
 
50497
50496
  // Agent 4: Find tests
50498
- delegate_agent(
50497
+ task(
50499
50498
  subagent_type="trinity",
50500
50499
  run_in_background=true,
50501
50500
  prompt="Find all test files related to [TARGET].
@@ -50503,7 +50502,7 @@ delegate_agent(
50503
50502
  )
50504
50503
 
50505
50504
  // Agent 5: Architecture context
50506
- delegate_agent(
50505
+ task(
50507
50506
  subagent_type="trinity",
50508
50507
  run_in_background=true,
50509
50508
  prompt="Find architectural patterns and module organization around [TARGET].
@@ -50644,7 +50643,7 @@ ls -la *_test.go
50644
50643
 
50645
50644
  \`\`\`
50646
50645
  // Find all tests related to target
50647
- delegate_agent(
50646
+ task(
50648
50647
  subagent_type="trinity",
50649
50648
  run_in_background=false, // Need this synchronously
50650
50649
  prompt="Analyze test coverage for [TARGET]:
@@ -52798,8 +52797,7 @@ var DELEGATABLE_WORK_TOOLS = new Set([
52798
52797
  "glob"
52799
52798
  ]);
52800
52799
  var DELEGATION_TOOLS = new Set([
52801
- "task",
52802
- "delegate_agent"
52800
+ "task"
52803
52801
  ]);
52804
52802
  function createCategorySkillReminderHook(_ctx, availableSkills = []) {
52805
52803
  const sessionStates = new Map;
@@ -53382,56 +53380,28 @@ function createCommentCheckerHooks(config2) {
53382
53380
  };
53383
53381
  }
53384
53382
  // src/hooks/compaction-context-injector/hook.ts
53383
+ var MAX_TASK_HISTORY_CHARS = 1500;
53385
53384
  var COMPACTION_CONTEXT_PROMPT = `${createSystemDirective(SystemDirectiveTypes.COMPACTION_CONTEXT)}
53386
53385
 
53387
53386
  When summarizing this session, you MUST include the following sections in your summary:
53388
53387
 
53389
- ## 1. User Requests (As-Is)
53390
- - List all original user requests exactly as they were stated
53391
- - Preserve the user's exact wording and intent
53392
-
53393
- ## 2. Final Goal
53394
- - What the user ultimately wanted to achieve
53395
- - The end result or deliverable expected
53396
-
53397
- ## 3. Work Completed
53398
- - What has been done so far
53399
- - Files created/modified
53400
- - Features implemented
53401
- - Problems solved
53402
-
53403
- ## 4. Remaining Tasks
53404
- - What still needs to be done
53405
- - Pending items from the original request
53406
- - Follow-up tasks identified during the work
53407
-
53408
- ## 5. Active Working Context (For Seamless Continuation)
53409
- - **Files**: Paths of files currently being edited or frequently referenced
53410
- - **Code in Progress**: Key code snippets, function signatures, or data structures under active development
53411
- - **External References**: Documentation URLs, library APIs, or external resources being consulted
53412
- - **State & Variables**: Important variable names, configuration values, or runtime state relevant to ongoing work
53413
-
53414
- ## 6. Explicit Constraints (Verbatim Only)
53415
- - Include ONLY constraints explicitly stated by the user or in existing AGENTS.md context
53416
- - Quote constraints verbatim (do not paraphrase)
53417
- - Do NOT invent, add, or modify constraints
53418
- - If no explicit constraints exist, write "None"
53419
-
53420
- ## 7. Agent Verification State (Critical for Reviewers)
53421
- - **Current Agent**: What agent is running (momus, oracle, etc.)
53388
+ ## 1. Goal & Requests
53389
+ - Original user requests (as stated) and the final goal expected
53390
+
53391
+ ## 2. Progress & Remaining
53392
+ - Work completed (files, features, fixes) and what still remains
53393
+
53394
+ ## 3. Explicit Constraints (Verbatim Only)
53395
+ - Quote constraints verbatim. Do NOT invent or modify; write "None" if absent
53396
+
53397
+ ## 4. Agent Verification State (Critical for Reviewers)
53398
+ - **Current Agent**: What agent is running
53422
53399
  - **Verification Progress**: Files already verified/validated
53423
53400
  - **Pending Verifications**: Files still needing verification
53424
53401
  - **Previous Rejections**: If reviewer agent, what was rejected and why
53425
53402
  - **Acceptance Status**: Current state of review process
53426
53403
 
53427
- This section is CRITICAL for reviewer agents (momus, oracle) to maintain continuity.
53428
-
53429
- ## 8. Delegated Agent Sessions
53430
- - List ALL background agent tasks spawned during this session
53431
- - For each: agent name, category, status, description, and **session_id**
53432
- - **RESUME, DON'T RESTART.** Each listed session retains full context. After compaction, use \`session_id\` to continue existing agent sessions instead of spawning new ones. This saves tokens, preserves learned context, and prevents duplicate work.
53433
-
53434
- This context is critical for maintaining continuity after compaction.
53404
+ This section is CRITICAL for reviewer agents to maintain continuity.
53435
53405
  `;
53436
53406
  function createCompactionContextInjector(backgroundManager) {
53437
53407
  return (sessionID) => {
@@ -53439,9 +53409,11 @@ function createCompactionContextInjector(backgroundManager) {
53439
53409
  if (backgroundManager && sessionID) {
53440
53410
  const history = backgroundManager.taskHistory.formatForCompaction(sessionID);
53441
53411
  if (history) {
53412
+ const cappedHistory = history.length > MAX_TASK_HISTORY_CHARS ? `${history.slice(0, MAX_TASK_HISTORY_CHARS)}
53413
+ [... history truncated to 1500 chars]` : history;
53442
53414
  prompt += `
53443
53415
  ### Active/Recent Delegated Sessions
53444
- ${history}
53416
+ ${cappedHistory}
53445
53417
  `;
53446
53418
  }
53447
53419
  }
@@ -56457,7 +56429,7 @@ function createFailureCounterHook(_ctx) {
56457
56429
  return {
56458
56430
  "tool.execute.after": async (input, output) => {
56459
56431
  const tool = input.tool.toLowerCase();
56460
- if (tool !== "task" && tool !== "delegate_agent")
56432
+ if (tool !== "task")
56461
56433
  return;
56462
56434
  if (typeof output.output !== "string")
56463
56435
  return;
@@ -60109,7 +60081,7 @@ function isAllowedFile(filePath, workspaceRoot) {
60109
60081
  }
60110
60082
 
60111
60083
  // src/hooks/oracle-md-only/hook.ts
60112
- var TASK_TOOLS = ["task", "delegate_agent"];
60084
+ var TASK_TOOLS = ["task"];
60113
60085
  function createOracleMdOnlyHook(ctx) {
60114
60086
  return {
60115
60087
  "tool.execute.before": async (input, output) => {
@@ -64963,6 +64935,10 @@ init_logger();
64963
64935
  // src/hooks/task-continuation-enforcer/constants.ts
64964
64936
  var HOOK_NAME14 = "task-continuation-enforcer";
64965
64937
  var DEFAULT_SKIP_AGENTS = ["oracle", "compaction"];
64938
+ var EXPLORER_AGENTS = ["trinity", "operator"];
64939
+ function hasNonExplorerBgTasks(tasks) {
64940
+ return tasks.some((t) => !t.agent || !EXPLORER_AGENTS.includes(t.agent));
64941
+ }
64966
64942
  var CONTINUATION_PROMPT2 = `${createSystemDirective(SystemDirectiveTypes.TASK_CONTINUATION)}
64967
64943
 
64968
64944
  Incomplete Matrixx tasks remain. Continue working on the next pending task.
@@ -65121,6 +65097,19 @@ async function injectContinuation(args) {
65121
65097
  log(`[${HOOK_NAME14}] Skipped injection: background tasks running`, { sessionID });
65122
65098
  return;
65123
65099
  }
65100
+ const earlyInjectionState = sessionStateStore.getExistingState(sessionID);
65101
+ if (earlyInjectionState?.lastInjectedAt !== undefined) {
65102
+ const now = Date.now();
65103
+ const elapsedMs = now - earlyInjectionState.lastInjectedAt;
65104
+ if (elapsedMs < CONTINUATION_COOLDOWN_MS3) {
65105
+ log(`[${HOOK_NAME14}] Skipped injection: cooldown active`, {
65106
+ sessionID,
65107
+ cooldownMs: CONTINUATION_COOLDOWN_MS3,
65108
+ elapsedMs
65109
+ });
65110
+ return;
65111
+ }
65112
+ }
65124
65113
  const tasks = [];
65125
65114
  let filteredTasks = [];
65126
65115
  let total = 0;
@@ -65129,9 +65118,9 @@ async function injectContinuation(args) {
65129
65118
  try {
65130
65119
  taskDir = getTaskDir(config2, ctx.directory);
65131
65120
  if (!existsSync43(taskDir)) {
65132
- const hadBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).length > 0 : false;
65133
- if (hadBgTasks) {
65134
- log(`[${HOOK_NAME14}] Bootstrap injection: no task dir (hadBgTasks)`, { sessionID, taskDir });
65121
+ const hadNonExplorerBgTasks = backgroundManager ? hasNonExplorerBgTasks(backgroundManager.getTasksByParentSession(sessionID)) : false;
65122
+ if (hadNonExplorerBgTasks) {
65123
+ log(`[${HOOK_NAME14}] Bootstrap injection: no task dir (hadNonExplorerBgTasks)`, { sessionID, taskDir });
65135
65124
  isBootstrap = true;
65136
65125
  } else {
65137
65126
  log(`[${HOOK_NAME14}] Skipped injection: no task dir`, { sessionID, taskDir });
@@ -65152,9 +65141,9 @@ async function injectContinuation(args) {
65152
65141
  });
65153
65142
  total = filteredTasks.length;
65154
65143
  if (total === 0) {
65155
- const hadBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).length > 0 : false;
65156
- if (hadBgTasks) {
65157
- log(`[${HOOK_NAME14}] Bootstrap injection: no tasks (hadBgTasks)`, { sessionID });
65144
+ const hadNonExplorerBgTasks = backgroundManager ? hasNonExplorerBgTasks(backgroundManager.getTasksByParentSession(sessionID)) : false;
65145
+ if (hadNonExplorerBgTasks) {
65146
+ log(`[${HOOK_NAME14}] Bootstrap injection: no tasks (hadNonExplorerBgTasks)`, { sessionID });
65158
65147
  isBootstrap = true;
65159
65148
  } else {
65160
65149
  log(`[${HOOK_NAME14}] Skipped injection: no tasks`, { sessionID });
@@ -65232,6 +65221,9 @@ ${taskList}${staleNote}`;
65232
65221
  injectionState.inFlight = true;
65233
65222
  }
65234
65223
  if (isAwaitingUser(sessionStateStore.getExistingState(sessionID))) {
65224
+ if (injectionState) {
65225
+ injectionState.inFlight = false;
65226
+ }
65235
65227
  log(`[${HOOK_NAME14}] Skipped injection: awaiting user (race)`, { sessionID });
65236
65228
  return;
65237
65229
  }
@@ -65391,8 +65383,8 @@ async function handleSessionIdle(args) {
65391
65383
  try {
65392
65384
  taskDir = getTaskDir(config2, ctx.directory);
65393
65385
  if (!existsSync44(taskDir)) {
65394
- const hadBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).length > 0 : false;
65395
- if (hadBgTasks) {
65386
+ const hadNonExplorerBgTasks = backgroundManager ? hasNonExplorerBgTasks(backgroundManager.getTasksByParentSession(sessionID)) : false;
65387
+ if (hadNonExplorerBgTasks) {
65396
65388
  log(`[${HOOK_NAME14}] No task dir \u2014 bootstrap (hadBgTasks)`, { sessionID, taskDir });
65397
65389
  isBootstrap = true;
65398
65390
  total = 0;
@@ -65416,9 +65408,9 @@ async function handleSessionIdle(args) {
65416
65408
  });
65417
65409
  total = filteredTasks.length;
65418
65410
  if (total === 0) {
65419
- const hadBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).length > 0 : false;
65420
- if (hadBgTasks) {
65421
- log(`[${HOOK_NAME14}] No tasks \u2014 bootstrap (hadBgTasks)`, { sessionID });
65411
+ const hadNonExplorerBgTasks = backgroundManager ? hasNonExplorerBgTasks(backgroundManager.getTasksByParentSession(sessionID)) : false;
65412
+ if (hadNonExplorerBgTasks) {
65413
+ log(`[${HOOK_NAME14}] No tasks \u2014 bootstrap (hadNonExplorerBgTasks)`, { sessionID });
65422
65414
  isBootstrap = true;
65423
65415
  incompleteCount = 1;
65424
65416
  } else {
@@ -66014,7 +66006,7 @@ function renderNotepad(todo) {
66014
66006
  `;
66015
66007
  }
66016
66008
  // src/hooks/task-resume-info/hook.ts
66017
- var TARGET_TOOLS2 = ["task", "Task", "task_tool", "delegate_agent"];
66009
+ var TARGET_TOOLS2 = ["task", "Task", "task_tool"];
66018
66010
  var SESSION_ID_PATTERNS = [
66019
66011
  /Session ID: (ses_[a-zA-Z0-9_-]+)/,
66020
66012
  /session_id: (ses_[a-zA-Z0-9_-]+)/,
@@ -87919,25 +87911,15 @@ function loadedSkillToInfo(skill) {
87919
87911
  function formatSkillsXml(skills) {
87920
87912
  if (skills.length === 0)
87921
87913
  return "";
87922
- const skillsXml = skills.map((skill) => {
87923
- const lines = [
87924
- " <skill>",
87925
- ` <name>${skill.name}</name>`,
87926
- ` <description>${skill.description}</description>`
87927
- ];
87928
- if (skill.compatibility) {
87929
- lines.push(` <compatibility>${skill.compatibility}</compatibility>`);
87930
- }
87931
- lines.push(" </skill>");
87932
- return lines.join(`
87933
- `);
87934
- }).join(`
87914
+ const skillsXml = skills.map((skill) => ` <skill>${skill.name}</skill>`).join(`
87935
87915
  `);
87936
87916
  return `
87937
87917
 
87938
87918
  <available_skills>
87939
87919
  ${skillsXml}
87940
- </available_skills>`;
87920
+ </available_skills>
87921
+
87922
+ Call skill(name) for detail on a specific skill. Names only are listed to save context; descriptions load lazily.`;
87941
87923
  }
87942
87924
  function createSkillTool(options = {}) {
87943
87925
  let cachedSkills = null;
@@ -88864,6 +88846,7 @@ var DEFAULT_WALL_CLOCK_ABORT_GRACE_MS = 5000;
88864
88846
  var DEFAULT_NESTED_ADMISSION_ENABLED = true;
88865
88847
  var DEFAULT_NESTED_ADMISSION_MODE = "bypass";
88866
88848
  var DEFAULT_NESTED_MAX_DEPTH = 2;
88849
+ var DEFAULT_WAKE_SCHEDULER_ENABLED = false;
88867
88850
  var DEFAULT_WAKE_INTERVAL_MS = 300000;
88868
88851
  var MIN_WAKE_INTERVAL_MS = 60000;
88869
88852
  var RECONCILE_CONFIRMATION_GRACE_MS = 5000;
@@ -89550,7 +89533,7 @@ var BUILTIN_DCP_PROFILES = {
89550
89533
  brutal: {
89551
89534
  pruneNotification: "off",
89552
89535
  compress: {
89553
- maxContextLimit: "15%",
89536
+ maxContextLimit: "20%",
89554
89537
  minContextLimit: "10%",
89555
89538
  nudgeFrequency: 1,
89556
89539
  nudgeForce: "strong",
@@ -89793,367 +89776,6 @@ function createDcpSwitchProfileTool(options) {
89793
89776
  });
89794
89777
  return { dcp_switch_profile };
89795
89778
  }
89796
- // src/tools/delegate-agent/constants.ts
89797
- var ALLOWED_AGENTS = [
89798
- "trinity",
89799
- "operator",
89800
- "oracle",
89801
- "construct"
89802
- ];
89803
- var CALL_DELEGATE_AGENT_DESCRIPTION = `Spawn explore/librarian agent. run_in_background REQUIRED (true=async with task_id, false=sync).
89804
-
89805
- Available: {agents}
89806
-
89807
- Pass \`session_id=<id>\` to continue previous agent with full context. Prompts MUST be in English. Use \`background_output\` for async results.`;
89808
- // src/shared/saturated-outcome.ts
89809
- var LAUNCH_TERMINAL_STATUSES = [
89810
- "error",
89811
- "cancelled",
89812
- "interrupt",
89813
- "stopped",
89814
- "statusUncertain"
89815
- ];
89816
- function isLaunchTerminalStatus(status) {
89817
- return LAUNCH_TERMINAL_STATUSES.includes(status);
89818
- }
89819
- function isQueueSaturated(status, terminalReason) {
89820
- return status === "stopped" && terminalReason === "queue-saturated";
89821
- }
89822
- function formatSaturatedOutcome(taskId) {
89823
- const metadata = JSON.stringify({
89824
- task_id: taskId,
89825
- status: "stopped",
89826
- reason: "queue-saturated"
89827
- });
89828
- return `Background task NOT admitted (queue saturated).
89829
-
89830
- Task ID: ${taskId}
89831
- Status: stopped
89832
- Reason: queue-saturated
89833
-
89834
- <task_metadata>${metadata}</task_metadata>`;
89835
- }
89836
- function formatLaunchFailure(taskId, status) {
89837
- return `Task failed to start (status: ${status}).
89838
-
89839
- Task ID: ${taskId}`;
89840
- }
89841
- // src/tools/delegate-agent/background-executor.ts
89842
- async function executeBackground(args, toolContext, manager, client2) {
89843
- try {
89844
- const messageDir = getMessageDir(toolContext.sessionID);
89845
- const { prevMessage, firstMessageAgent } = await resolveMessageContext(toolContext.sessionID, client2, messageDir);
89846
- const sessionAgent = getSessionAgent(toolContext.sessionID);
89847
- const parentAgent = toolContext.agent ?? sessionAgent ?? firstMessageAgent ?? prevMessage?.agent;
89848
- log("[delegate_agent] parentAgent resolution", {
89849
- sessionID: toolContext.sessionID,
89850
- messageDir,
89851
- ctxAgent: toolContext.agent,
89852
- sessionAgent,
89853
- firstMessageAgent,
89854
- prevMessageAgent: prevMessage?.agent,
89855
- resolvedParentAgent: parentAgent
89856
- });
89857
- const task = await manager.launch({
89858
- description: args.description,
89859
- prompt: args.prompt,
89860
- agent: args.subagent_type,
89861
- parentSessionID: toolContext.sessionID,
89862
- parentMessageID: toolContext.messageID,
89863
- parentAgent,
89864
- parentTools: getSessionTools(toolContext.sessionID)
89865
- });
89866
- const WAIT_FOR_SESSION_INTERVAL_MS = 50;
89867
- const WAIT_FOR_SESSION_TIMEOUT_MS = 30000;
89868
- const waitStart = Date.now();
89869
- let sessionId = task.sessionID;
89870
- while (!sessionId && Date.now() - waitStart < WAIT_FOR_SESSION_TIMEOUT_MS) {
89871
- if (toolContext.abort?.aborted) {
89872
- return `Task aborted while waiting for session to start.
89873
-
89874
- Task ID: ${task.id}`;
89875
- }
89876
- const updated = manager.getTask(task.id);
89877
- if (updated && isLaunchTerminalStatus(updated.status)) {
89878
- if (isQueueSaturated(updated.status, updated.terminalReason)) {
89879
- return formatSaturatedOutcome(task.id);
89880
- }
89881
- return formatLaunchFailure(task.id, updated.status);
89882
- }
89883
- await new Promise((resolve10) => setTimeout(resolve10, WAIT_FOR_SESSION_INTERVAL_MS));
89884
- sessionId = manager.getTask(task.id)?.sessionID;
89885
- }
89886
- if (!sessionId) {
89887
- return formatDetailedError(new Error(`Task failed to start within timeout (30s). Task ID: ${task.id}, Status: ${task.status}`), {
89888
- operation: "Launch background agent task",
89889
- agent: task.agent
89890
- });
89891
- }
89892
- await toolContext.metadata?.({
89893
- title: args.description,
89894
- metadata: { sessionId }
89895
- });
89896
- return `Background agent task launched successfully.
89897
-
89898
- Task ID: ${task.id}
89899
- Session ID: ${sessionId ?? "(timed out)"}
89900
- Description: ${task.description}
89901
- Agent: ${task.agent} (subagent)
89902
- Status: ${task.status}
89903
-
89904
- The system will notify you when the task completes.
89905
- Use \`background_output\` tool with task_id="${task.id}" to check progress:
89906
- - block=false (default): Check status immediately - returns full status info
89907
- - block=true: Wait for completion (rarely needed since system notifies)`;
89908
- } catch (error95) {
89909
- const message = error95 instanceof Error ? error95.message : String(error95);
89910
- return `Failed to launch background agent task: ${message}`;
89911
- }
89912
- }
89913
-
89914
- // src/tools/delegate-agent/completion-poller.ts
89915
- async function waitForCompletion(sessionID, toolContext, ctx) {
89916
- log(`[delegate_agent] Polling for completion...`);
89917
- const POLL_INTERVAL_MS3 = 500;
89918
- const MAX_POLL_TIME_MS = 5 * 60 * 1000;
89919
- const pollStart = Date.now();
89920
- let lastMsgCount = 0;
89921
- let stablePolls = 0;
89922
- const STABILITY_REQUIRED = 3;
89923
- while (Date.now() - pollStart < MAX_POLL_TIME_MS) {
89924
- if (toolContext.abort?.aborted) {
89925
- log(`[delegate_agent] Aborted by user`);
89926
- throw new Error("Task aborted.");
89927
- }
89928
- await new Promise((resolve10) => setTimeout(resolve10, POLL_INTERVAL_MS3));
89929
- const statusResult = await ctx.client.session.status();
89930
- const allStatuses = normalizeSDKResponse(statusResult, {});
89931
- const sessionStatus = allStatuses[sessionID];
89932
- if (sessionStatus && sessionStatus.type !== "idle") {
89933
- stablePolls = 0;
89934
- lastMsgCount = 0;
89935
- continue;
89936
- }
89937
- const messagesCheck = await ctx.client.session.messages({ path: { id: sessionID } });
89938
- const msgs = normalizeSDKResponse(messagesCheck, [], {
89939
- preferResponseOnMissingData: true
89940
- });
89941
- const currentMsgCount = msgs.length;
89942
- if (currentMsgCount > 0 && currentMsgCount === lastMsgCount) {
89943
- stablePolls++;
89944
- if (stablePolls >= STABILITY_REQUIRED) {
89945
- log(`[delegate_agent] Session complete, ${currentMsgCount} messages`);
89946
- break;
89947
- }
89948
- } else {
89949
- stablePolls = 0;
89950
- lastMsgCount = currentMsgCount;
89951
- }
89952
- }
89953
- if (Date.now() - pollStart >= MAX_POLL_TIME_MS) {
89954
- log(`[delegate_agent] Timeout reached`);
89955
- throw new Error("Agent task timed out after 5 minutes.");
89956
- }
89957
- }
89958
-
89959
- // src/tools/delegate-agent/message-processor.ts
89960
- async function processMessages(sessionID, ctx) {
89961
- const messagesResult = await ctx.client.session.messages({
89962
- path: { id: sessionID }
89963
- });
89964
- if (messagesResult.error) {
89965
- log(`[delegate_agent] Messages error:`, messagesResult.error);
89966
- throw new Error(`Failed to get messages: ${messagesResult.error}`);
89967
- }
89968
- const messages2 = messagesResult.data;
89969
- log(`[delegate_agent] Got ${messages2.length} messages`);
89970
- const relevantMessages = messages2.filter((m) => m.info?.role === "assistant" || m.info?.role === "tool");
89971
- if (relevantMessages.length === 0) {
89972
- log(`[delegate_agent] No assistant or tool messages found`);
89973
- log(`[delegate_agent] All messages:`, JSON.stringify(messages2, null, 2));
89974
- throw new Error("No assistant or tool response found");
89975
- }
89976
- log(`[delegate_agent] Found ${relevantMessages.length} relevant messages`);
89977
- const sortedMessages = [...relevantMessages].sort((a, b) => {
89978
- const timeA = a.info?.time?.created ?? 0;
89979
- const timeB = b.info?.time?.created ?? 0;
89980
- return timeA - timeB;
89981
- });
89982
- const newMessages = consumeNewMessages(sessionID, sortedMessages);
89983
- if (newMessages.length === 0) {
89984
- return "No new output since last check.";
89985
- }
89986
- const extractedContent = [];
89987
- for (const message of newMessages) {
89988
- for (const part of message.parts ?? []) {
89989
- if ((part.type === "text" || part.type === "reasoning") && part.text) {
89990
- extractedContent.push(part.text);
89991
- } else if (part.type === "tool_result") {
89992
- const toolResult = part;
89993
- if (typeof toolResult.content === "string" && toolResult.content) {
89994
- extractedContent.push(toolResult.content);
89995
- } else if (Array.isArray(toolResult.content)) {
89996
- for (const block of toolResult.content) {
89997
- if ((block.type === "text" || block.type === "reasoning") && block.text) {
89998
- extractedContent.push(block.text);
89999
- }
90000
- }
90001
- }
90002
- }
90003
- }
90004
- }
90005
- const responseText = extractedContent.filter((text) => text.length > 0).join(`
90006
-
90007
- `);
90008
- log(`[delegate_agent] Got response, length: ${responseText.length}`);
90009
- return responseText;
90010
- }
90011
-
90012
- // src/tools/delegate-agent/session-creator.ts
90013
- async function createOrGetSession(args, toolContext, ctx) {
90014
- if (args.session_id) {
90015
- log(`[delegate_agent] Using existing session: ${args.session_id}`);
90016
- const sessionResult = await ctx.client.session.get({
90017
- path: { id: args.session_id }
90018
- });
90019
- if (sessionResult.error) {
90020
- log(`[delegate_agent] Session get error:`, sessionResult.error);
90021
- throw new Error(`Failed to get existing session: ${sessionResult.error}`);
90022
- }
90023
- return { sessionID: args.session_id, isNew: false };
90024
- } else {
90025
- log(`[delegate_agent] Creating new session with parent: ${toolContext.sessionID}`);
90026
- const parentSession = await ctx.client.session.get({
90027
- path: { id: toolContext.sessionID }
90028
- }).catch((err) => {
90029
- log(`[delegate_agent] Failed to get parent session:`, err);
90030
- return null;
90031
- });
90032
- log(`[delegate_agent] Parent session dir: ${parentSession?.data?.directory}, fallback: ${ctx.directory}`);
90033
- const parentDirectory = parentSession?.data?.directory ?? ctx.directory;
90034
- const createResult = await ctx.client.session.create({
90035
- body: {
90036
- parentID: toolContext.sessionID,
90037
- title: `${args.description} (@${args.subagent_type} subagent)`
90038
- },
90039
- query: {
90040
- directory: parentDirectory
90041
- }
90042
- });
90043
- if (createResult.error) {
90044
- log(`[delegate_agent] Session create error:`, createResult.error);
90045
- const errorStr = String(createResult.error);
90046
- if (errorStr.toLowerCase().includes("unauthorized")) {
90047
- throw new Error(`Failed to create session (Unauthorized). This may be due to:
90048
- 1. OAuth token restrictions (e.g., Claude Code credentials are restricted to Claude Code only)
90049
- 2. Provider authentication issues
90050
- 3. Session permission inheritance problems
90051
-
90052
- Try using a different provider or API key authentication.
90053
-
90054
- Original error: ${createResult.error}`);
90055
- }
90056
- throw new Error(`Failed to create session: ${createResult.error}`);
90057
- }
90058
- const sessionID = createResult.data.id;
90059
- log(`[delegate_agent] Created session: ${sessionID}`);
90060
- registerSubagentSession(sessionID, toolContext.sessionID);
90061
- return { sessionID, isNew: true };
90062
- }
90063
- }
90064
-
90065
- // src/tools/delegate-agent/sync-executor.ts
90066
- var defaultDeps = {
90067
- createOrGetSession,
90068
- waitForCompletion,
90069
- processMessages
90070
- };
90071
- async function executeSync(args, toolContext, ctx, deps = defaultDeps) {
90072
- const { sessionID } = await deps.createOrGetSession(args, toolContext, ctx);
90073
- await toolContext.metadata?.({
90074
- title: args.description,
90075
- metadata: { sessionId: sessionID }
90076
- });
90077
- log(`[delegate_agent] Sending prompt to session ${sessionID}`);
90078
- log(`[delegate_agent] Prompt text:`, args.prompt.substring(0, 100));
90079
- try {
90080
- await ctx.client.session.promptAsync({
90081
- path: { id: sessionID },
90082
- body: {
90083
- agent: args.subagent_type,
90084
- tools: {
90085
- ...getAgentToolRestrictions(args.subagent_type),
90086
- task: false,
90087
- question: false
90088
- },
90089
- parts: [{ type: "text", text: args.prompt }]
90090
- }
90091
- });
90092
- } catch (error95) {
90093
- const errorMessage = error95 instanceof Error ? error95.message : String(error95);
90094
- log(`[delegate_agent] Prompt error:`, errorMessage);
90095
- if (errorMessage.includes("agent.name") || errorMessage.includes("undefined")) {
90096
- return `Error: Agent "${args.subagent_type}" not found. Make sure the agent is registered in your opencode.json or provided by a plugin.
90097
-
90098
- <task_metadata>
90099
- session_id: ${sessionID}
90100
- </task_metadata>`;
90101
- }
90102
- return `Error: Failed to send prompt: ${errorMessage}
90103
-
90104
- <task_metadata>
90105
- session_id: ${sessionID}
90106
- </task_metadata>`;
90107
- }
90108
- await deps.waitForCompletion(sessionID, toolContext, ctx);
90109
- const responseText = await deps.processMessages(sessionID, ctx);
90110
- const output = `${responseText}
90111
-
90112
- ${["<task_metadata>", `session_id: ${sessionID}`, "</task_metadata>"].join(`
90113
- `)}`;
90114
- return output;
90115
- }
90116
-
90117
- // src/tools/delegate-agent/tools.ts
90118
- function createDelegateAgent(ctx, backgroundManager, disabledAgents = []) {
90119
- const agentDescriptions = ALLOWED_AGENTS.map((name) => `- ${name}: Specialized agent for ${name} tasks`).join(`
90120
- `);
90121
- const description = CALL_DELEGATE_AGENT_DESCRIPTION.replace("{agents}", agentDescriptions);
90122
- return tool({
90123
- description,
90124
- args: {
90125
- description: tool.schema.string().describe("A short (3-5 words) description of the task"),
90126
- prompt: tool.schema.string().describe("The task for the agent to perform"),
90127
- subagent_type: tool.schema.string().describe("The type of specialized agent to use for this task (explore or librarian only)"),
90128
- run_in_background: tool.schema.boolean().default(false).describe("true: run asynchronously (use background_output to get results), false: run synchronously and wait for completion. Default: false"),
90129
- session_id: tool.schema.string().describe("Existing Task session to continue").optional()
90130
- },
90131
- async execute(args, toolContext) {
90132
- const toolCtx = toolContext;
90133
- log(`[delegate_agent] Starting with agent: ${args.subagent_type}, background: ${args.run_in_background}`);
90134
- if (!ALLOWED_AGENTS.some((name) => name.toLowerCase() === args.subagent_type.toLowerCase())) {
90135
- return `Error: Invalid agent type "${args.subagent_type}". Only ${ALLOWED_AGENTS.join(", ")} are allowed.`;
90136
- }
90137
- const normalizedAgent = args.subagent_type.toLowerCase();
90138
- args = { ...args, subagent_type: normalizedAgent };
90139
- const callerAgent = (toolCtx.agent || "").toLowerCase();
90140
- const MOUSE_RESEARCH_ONLY = ["trinity", "operator"];
90141
- if (callerAgent === "mouse" && !MOUSE_RESEARCH_ONLY.includes(normalizedAgent)) {
90142
- return `Error: Mouse is a leaf executor. delegate_agent with subagent_type="${normalizedAgent}" is BLOCKED. Only trinity/operator allowed for research. Plan files (.matrixx/plans/*.md) must be created via task(subagent_type="oracle") from Morpheus, never via Mouse \u2192 Oracle. Route plan generation directly from Morpheus to oracle.`;
90143
- }
90144
- if (disabledAgents.some((disabled) => disabled.toLowerCase() === normalizedAgent)) {
90145
- return `Error: Agent "${normalizedAgent}" is disabled via disabled_agents configuration. Remove it from disabled_agents in your matrixx.json to use it.`;
90146
- }
90147
- if (args.run_in_background) {
90148
- if (args.session_id) {
90149
- return `Error: session_id is not supported in background mode. Use run_in_background=false to continue an existing session.`;
90150
- }
90151
- return await executeBackground(args, toolCtx, backgroundManager, ctx.client);
90152
- }
90153
- return await executeSync(args, toolCtx, ctx);
90154
- }
90155
- });
90156
- }
90157
89779
  // src/tools/delegate-task/complexity-types.ts
90158
89780
  function isDowngradable(level) {
90159
89781
  return level === 1 || level === 2;
@@ -90485,13 +90107,23 @@ var CATEGORY_DESCRIPTIONS = {
90485
90107
  "red-pill": "Tasks that don't fit other categories, high effort required",
90486
90108
  broadcast: "Documentation, prose, technical writing"
90487
90109
  };
90110
+ var SHORT_CATEGORY_HINTS = {
90111
+ construct: "frontend/UI",
90112
+ source: "hard logic",
90113
+ "deep-jack": "deep research",
90114
+ "matrix-bend": "creative",
90115
+ "bullet-time": "trivial 1-file",
90116
+ "blue-pill": "easy misc",
90117
+ "red-pill": "hard misc",
90118
+ broadcast: "docs"
90119
+ };
90488
90120
  var PLAN_AGENT_SYSTEM_PREPEND_STATIC_BEFORE_SKILLS = `<system>
90489
90121
  BEFORE you begin planning, you MUST first understand the user's request deeply.
90490
90122
 
90491
90123
  MANDATORY CONTEXT GATHERING PROTOCOL:
90492
90124
  1. Launch background agents to gather context:
90493
- - delegate_agent(description="Explore codebase patterns", subagent_type="trinity", run_in_background=true, prompt="<search for relevant patterns, files, and implementations in the codebase related to user's request>")
90494
- - delegate_agent(description="Research documentation", subagent_type="operator", run_in_background=true, prompt="<search for external documentation, examples, and best practices related to user's request>")
90125
+ - task(subagent_type="trinity", run_in_background=true, prompt="<search for relevant patterns, files, and implementations in the codebase related to user's request>")
90126
+ - task(subagent_type="operator", run_in_background=true, prompt="<search for external documentation, examples, and best practices related to user's request>")
90495
90127
 
90496
90128
  2. After gathering context, ALWAYS present:
90497
90129
  - **User Request Summary**: Concise restatement of what the user is asking for
@@ -90855,6 +90487,40 @@ ${task.agent ? `subagent: ${task.agent}
90855
90487
  });
90856
90488
  }
90857
90489
  }
90490
+ // src/shared/saturated-outcome.ts
90491
+ var LAUNCH_TERMINAL_STATUSES = [
90492
+ "error",
90493
+ "cancelled",
90494
+ "interrupt",
90495
+ "stopped",
90496
+ "statusUncertain"
90497
+ ];
90498
+ function isLaunchTerminalStatus(status) {
90499
+ return LAUNCH_TERMINAL_STATUSES.includes(status);
90500
+ }
90501
+ function isQueueSaturated(status, terminalReason) {
90502
+ return status === "stopped" && terminalReason === "queue-saturated";
90503
+ }
90504
+ function formatSaturatedOutcome(taskId) {
90505
+ const metadata = JSON.stringify({
90506
+ task_id: taskId,
90507
+ status: "stopped",
90508
+ reason: "queue-saturated"
90509
+ });
90510
+ return `Background task NOT admitted (queue saturated).
90511
+
90512
+ Task ID: ${taskId}
90513
+ Status: stopped
90514
+ Reason: queue-saturated
90515
+
90516
+ <task_metadata>${metadata}</task_metadata>`;
90517
+ }
90518
+ function formatLaunchFailure(taskId, status) {
90519
+ return `Task failed to start (status: ${status}).
90520
+
90521
+ Task ID: ${taskId}`;
90522
+ }
90523
+
90858
90524
  // src/tools/delegate-task/timing.ts
90859
90525
  var POLL_INTERVAL_MS3 = 1000;
90860
90526
  var MIN_STABILITY_TIME_MS2 = 1e4;
@@ -91743,6 +91409,46 @@ Session ID: ${sessionID}` };
91743
91409
 
91744
91410
  // src/tools/delegate-task/sync-session-poller.ts
91745
91411
  init_logger();
91412
+
91413
+ // src/shared/poll-timeout-outcome.ts
91414
+ var POLL_TIMEOUT_PREFIX = "Poll timeout reached";
91415
+ var LAST_ASSISTANT_TEXT_CAP = 2000;
91416
+ function truncateLastAssistantText(text) {
91417
+ if (!text)
91418
+ return "";
91419
+ if (text.length <= LAST_ASSISTANT_TEXT_CAP)
91420
+ return text;
91421
+ return `${text.slice(0, LAST_ASSISTANT_TEXT_CAP)}...[truncated]`;
91422
+ }
91423
+ function formatPollTimeoutOutcome(args) {
91424
+ const { sessionID, agentToUse, maxPollTimeMs } = args;
91425
+ const lastAssistantText = truncateLastAssistantText(args.lastAssistantText);
91426
+ const metadata = JSON.stringify({
91427
+ session_id: sessionID,
91428
+ status: "running",
91429
+ reason: "poll-timeout",
91430
+ agent: agentToUse,
91431
+ max_poll_time_ms: maxPollTimeMs,
91432
+ last_assistant_text: lastAssistantText
91433
+ });
91434
+ const partialOutput = lastAssistantText.length > 0 ? lastAssistantText : "(none)";
91435
+ return `${POLL_TIMEOUT_PREFIX} after ${maxPollTimeMs}ms for session ${sessionID}.
91436
+
91437
+ Session ID: ${sessionID}
91438
+ Status: running
91439
+ Reason: poll-timeout
91440
+ Agent: ${agentToUse}
91441
+ Resume: session ${sessionID} is still running; poll again or resume via session ${sessionID}.
91442
+ Last partial output:
91443
+ ${partialOutput}
91444
+
91445
+ <task_metadata>${metadata}</task_metadata>`;
91446
+ }
91447
+ function isPollTimeoutOutcome(text) {
91448
+ return text.startsWith(POLL_TIMEOUT_PREFIX);
91449
+ }
91450
+
91451
+ // src/tools/delegate-task/sync-session-poller.ts
91746
91452
  var NON_TERMINAL_FINISH_REASONS = new Set(["tool-calls", "unknown"]);
91747
91453
  var STALL_NO_RESPONSE_POLLS = 15;
91748
91454
  var STALL_TOOL_CALLS_POLLS = 10;
@@ -91960,7 +91666,32 @@ Session ID: ${input.sessionID}`;
91960
91666
  timedOut = true;
91961
91667
  log("[task] Poll timeout reached", { sessionID: input.sessionID, pollCount });
91962
91668
  }
91963
- return timedOut ? `Poll timeout reached after ${maxPollTimeMs}ms for session ${input.sessionID}` : null;
91669
+ if (!timedOut)
91670
+ return null;
91671
+ let lastAssistantText;
91672
+ try {
91673
+ const timeoutMessagesResult = await client2.session.messages({ path: { id: input.sessionID } }).catch(() => {
91674
+ return;
91675
+ });
91676
+ if (timeoutMessagesResult) {
91677
+ const timeoutMsgs = normalizeSDKResponse(timeoutMessagesResult, [], {
91678
+ preferResponseOnMissingData: true
91679
+ });
91680
+ const lastAssistant = [...timeoutMsgs].reverse().find((m) => m.info?.role === "assistant");
91681
+ const textParts = (lastAssistant?.parts ?? []).filter((p) => p.type === "text" && p.text).map((p) => p.text);
91682
+ if (textParts.length > 0)
91683
+ lastAssistantText = textParts.join(`
91684
+ `);
91685
+ }
91686
+ } catch {
91687
+ lastAssistantText = undefined;
91688
+ }
91689
+ return formatPollTimeoutOutcome({
91690
+ sessionID: input.sessionID,
91691
+ agentToUse: input.agentToUse,
91692
+ maxPollTimeMs,
91693
+ lastAssistantText
91694
+ });
91964
91695
  }
91965
91696
 
91966
91697
  // src/tools/delegate-task/sync-continuation-deps.ts
@@ -92032,7 +91763,6 @@ async function executeSyncContinuation(args, ctx, executorCtx, deps = syncContin
92032
91763
  const tools = {
92033
91764
  ...resumeAgent ? getAgentToolRestrictions(resumeAgent) : {},
92034
91765
  task: allowTask,
92035
- delegate_agent: true,
92036
91766
  question: false
92037
91767
  };
92038
91768
  setSessionTools(continuationID, tools);
@@ -92110,7 +91840,6 @@ async function sendSyncPrompt(client2, input, deps = sendSyncPromptDeps) {
92110
91840
  const allowTask = isPlanFamily(input.agentToUse);
92111
91841
  const tools = {
92112
91842
  task: allowTask,
92113
- delegate_agent: true,
92114
91843
  question: false,
92115
91844
  ...getAgentToolRestrictions(input.agentToUse)
92116
91845
  };
@@ -92281,7 +92010,7 @@ async function executeSyncTask(args, ctx, executorCtx, parentContext, agentToUse
92281
92010
  }
92282
92011
  });
92283
92012
  if (pollError) {
92284
- pollTimedOut = pollError.startsWith("Poll timeout reached");
92013
+ pollTimedOut = isPollTimeoutOutcome(pollError);
92285
92014
  return pollError;
92286
92015
  }
92287
92016
  const result = await deps.fetchSyncResult(client2, sessionID, undefined, {
@@ -92523,6 +92252,7 @@ function createDelegateTask(options) {
92523
92252
  const allCategories = mergeCategories(userCategories);
92524
92253
  const categoryNames = Object.keys(allCategories);
92525
92254
  const categoryExamples = categoryNames.join(", ");
92255
+ const categoryHints = categoryNames.map((name) => SHORT_CATEGORY_HINTS[name] ? `${name}(${SHORT_CATEGORY_HINTS[name]})` : name).join(", ");
92526
92256
  const availableCategories = options.availableCategories ?? Object.entries(allCategories).map(([name, categoryConfig]) => {
92527
92257
  const userDesc = userCategories?.[name]?.description;
92528
92258
  const builtinDesc = CATEGORY_DESCRIPTIONS[name];
@@ -92534,14 +92264,8 @@ function createDelegateTask(options) {
92534
92264
  };
92535
92265
  });
92536
92266
  const availableSkills = options.availableSkills ?? [];
92537
- const categoryList = categoryNames.map((name) => {
92538
- const userDesc = userCategories?.[name]?.description;
92539
- const builtinDesc = CATEGORY_DESCRIPTIONS[name];
92540
- const desc = userDesc || builtinDesc;
92541
- return desc ? ` - ${name}: ${desc}` : ` - ${name}`;
92542
- }).join(`
92543
- `);
92544
- const description = `Spawn agent task with category-based or direct agent selection.
92267
+ const description = `[DELEGATION \u2014 spawns a subagent that does work. Does NOT create a tracking record.]
92268
+ Spawn agent task with category-based or direct agent selection.
92545
92269
 
92546
92270
  REQUIRED: You MUST provide EITHER category OR subagent_type (one of them is REQUIRED, but not both).
92547
92271
  - If using a predefined category \u2192 provide category
@@ -92549,20 +92273,15 @@ REQUIRED: You MUST provide EITHER category OR subagent_type (one of them is REQU
92549
92273
  - Providing NEITHER is INVALID and will fail.
92550
92274
 
92551
92275
  - load_skills: ALWAYS REQUIRED. Pass at least one skill name (e.g., ["playwright"], ["git-master", "frontend-ui-ux"]).
92552
- - category: Use predefined category \u2192 Spawns Mouse with category config
92553
- Available categories:
92554
- ${categoryList}
92276
+ - category: Use predefined category \u2192 Spawns Mouse with category config. Available: ${categoryHints} (full per-category guidance is injected at execution time; see category arg).
92555
92277
  - subagent_type: Use specific agent directly (e.g., "oracle", "trinity")
92556
92278
  - run_in_background: true=async (returns task_id), false=sync (waits for result). Default: false. Use true for ANY parallel independent work (exploration, fan-out, multi-agent waves); false awaits the result inline.
92557
- - session_id: Existing Task session to continue (from previous task output). Continues agent with FULL CONTEXT PRESERVED - saves tokens, maintains continuity.
92279
+ - session_id: Existing Task session to continue (from previous task output). Continues agent with FULL CONTEXT PRESERVED - saves tokens, maintains continuity. See session_id arg for when to use it.
92558
92280
  - command: The command that triggered this task (optional, for slash command tracking).
92559
92281
 
92560
- **WHEN TO USE session_id:**
92561
- - Task failed/incomplete \u2192 session_id with "fix: [specific issue]"
92562
- - Need follow-up on previous result \u2192 session_id with additional question
92563
- - Multi-turn conversation with same agent \u2192 always session_id instead of new task
92282
+ Prompts MUST be in English.
92564
92283
 
92565
- Prompts MUST be in English.`;
92284
+ Do NOT confuse with task_create/task_update/task_list/task_get/task_cleanup (the [TRACKING] family): those only write local T-{uuid} progress records and execute nothing. To get work done by another agent, use THIS tool (task).`;
92566
92285
  return tool({
92567
92286
  description,
92568
92287
  args: {
@@ -92570,9 +92289,9 @@ Prompts MUST be in English.`;
92570
92289
  description: tool.schema.string().describe("Short task description (3-5 words)"),
92571
92290
  prompt: tool.schema.string().describe("Full detailed prompt for the agent"),
92572
92291
  run_in_background: tool.schema.boolean().default(false).describe("true=async (returns task_id), false=sync (waits). Default: false"),
92573
- category: tool.schema.string().optional().describe(`REQUIRED if subagent_type not provided. Do NOT provide both category and subagent_type.`),
92292
+ category: tool.schema.string().optional().describe(`REQUIRED if subagent_type not provided. Do NOT provide both category and subagent_type. Available: ${categoryExamples}. Per-category model/temperature/skills guidance is injected at execution time.`),
92574
92293
  subagent_type: tool.schema.string().optional().describe("REQUIRED if category not provided. Do NOT provide both category and subagent_type."),
92575
- session_id: tool.schema.string().optional().describe("Existing Task session to continue"),
92294
+ session_id: tool.schema.string().optional().describe("Existing Task session to continue (full context preserved). Use when: task failed/incomplete (fix: <issue>), follow-up on previous result, or multi-turn with same agent. NEVER start fresh for follow-ups."),
92576
92295
  command: tool.schema.string().optional().describe("The command that triggered this task"),
92577
92296
  complexity: tool.schema.union([
92578
92297
  tool.schema.literal(1),
@@ -93014,7 +92733,6 @@ Original error: ${createResult.error}`;
93014
92733
  agent: CONSTRUCT_AGENT,
93015
92734
  tools: {
93016
92735
  task: false,
93017
- delegate_agent: false,
93018
92736
  look_at: false,
93019
92737
  read: false
93020
92738
  },
@@ -93085,7 +92803,8 @@ function getTaskTimestamp(task) {
93085
92803
  }
93086
92804
  function createTaskCleanupTool(config4, ctx) {
93087
92805
  return tool({
93088
- description: `Delete completed task files from storage.
92806
+ description: `[TRACKING \u2014 local progress records only. Spawns nothing, executes nothing.]
92807
+ Delete completed task files from storage.
93089
92808
 
93090
92809
  Scans getTaskDir()/*.json, filters status==="completed" and optionally olderThan.
93091
92810
  olderThan supports "7d", "24h", "30m" format (regex ^(\\d+)(d|h|m)$).
@@ -93158,7 +92877,8 @@ import { join as join75 } from "path";
93158
92877
  init_logger();
93159
92878
  function createTaskCreateTool(config4, ctx) {
93160
92879
  return tool({
93161
- description: `Create a new task with auto-generated ID and threadID recording.
92880
+ description: `[TRACKING \u2014 local progress record only. Spawns nothing, executes nothing.]
92881
+ Create a new task with auto-generated ID and threadID recording.
93162
92882
 
93163
92883
  Auto-generates T-{uuid} ID, records threadID from context, sets status to "pending".
93164
92884
  Returns minimal response with task ID and subject.
@@ -93168,7 +92888,9 @@ Use \`blockedBy\` to specify task IDs that must complete before this task can st
93168
92888
  Calculate dependencies carefully to maximize parallel execution:
93169
92889
  - Tasks with no dependencies can run simultaneously
93170
92890
  - Only block a task if it truly depends on another's output
93171
- - Minimize dependency chains to reduce sequential bottlenecks`,
92891
+ - Minimize dependency chains to reduce sequential bottlenecks
92892
+
92893
+ Do NOT confuse with the task tool ([DELEGATION]): task_create only records a checklist item \u2014 it does NOT spawn an agent and no work gets done. To have another agent do work, use task (with category/subagent_type).`,
93172
92894
  args: {
93173
92895
  subject: tool.schema.string().describe("Task subject (required)"),
93174
92896
  description: tool.schema.string().optional().describe("Task description"),
@@ -93288,7 +93010,8 @@ function parseTaskId(id) {
93288
93010
  }
93289
93011
  function createTaskGetTool(config4, ctx) {
93290
93012
  return tool({
93291
- description: `Retrieve a task by ID.
93013
+ description: `[TRACKING \u2014 local progress record only. Spawns nothing, executes nothing.]
93014
+ Retrieve a task by ID.
93292
93015
 
93293
93016
  Returns the full task object including all fields: id, subject, description, status, activeForm, blocks, blockedBy, owner, metadata, repoURL, parentID, and threadID.
93294
93017
 
@@ -93322,7 +93045,8 @@ import { existsSync as existsSync75, readdirSync as readdirSync25 } from "fs";
93322
93045
  import { join as join77 } from "path";
93323
93046
  function createTaskList(config4, ctx) {
93324
93047
  return tool({
93325
- description: `List all active tasks with summary information.
93048
+ description: `[TRACKING \u2014 local progress records only. Spawns nothing, executes nothing.]
93049
+ List all active tasks with summary information.
93326
93050
 
93327
93051
  Returns tasks excluding completed and deleted statuses by default.
93328
93052
  For each task's blockedBy field, filters to only include unresolved (non-completed) blockers.
@@ -93383,7 +93107,8 @@ function parseTaskId2(id) {
93383
93107
  }
93384
93108
  function createTaskUpdateTool(config4, ctx) {
93385
93109
  return tool({
93386
- description: `Update an existing task with new values.
93110
+ description: `[TRACKING \u2014 local progress record only. Spawns nothing, executes nothing.]
93111
+ Update an existing task with new values.
93387
93112
 
93388
93113
  Supports updating: subject, description, status, activeForm, owner, metadata.
93389
93114
  For blocks/blockedBy: use addBlocks/addBlockedBy to append (additive, not replacement).
@@ -93637,6 +93362,11 @@ var CONTEXT_SEPARATOR = `
93637
93362
  ---
93638
93363
 
93639
93364
  `;
93365
+ var MAX_MERGED_CHARS = 6000;
93366
+ var MAX_PER_SOURCE_CHARS = 2000;
93367
+ function buildTruncationNotice(droppedEntries, omittedChars) {
93368
+ return `[context truncated: ${droppedEntries} entries dropped, ${omittedChars} chars omitted]`;
93369
+ }
93640
93370
 
93641
93371
  class ContextCollector {
93642
93372
  sessions = new Map;
@@ -93667,11 +93397,48 @@ class ContextCollector {
93667
93397
  };
93668
93398
  }
93669
93399
  const entries = this.sortEntries([...sessionMap.values()]);
93670
- const merged = entries.map((e) => e.content).join(CONTEXT_SEPARATOR);
93400
+ const originalJoinedLength = entries.map((e) => e.content).join(CONTEXT_SEPARATOR).length;
93401
+ let perSourceOmitted = 0;
93402
+ const capped = entries.map((entry) => {
93403
+ if (entry.content.length <= MAX_PER_SOURCE_CHARS)
93404
+ return entry;
93405
+ perSourceOmitted += entry.content.length - MAX_PER_SOURCE_CHARS;
93406
+ return { ...entry, content: entry.content.slice(0, MAX_PER_SOURCE_CHARS) };
93407
+ });
93408
+ const included = [];
93409
+ let used = 0;
93410
+ for (const entry of capped) {
93411
+ const add = included.length === 0 ? entry.content.length : CONTEXT_SEPARATOR.length + entry.content.length;
93412
+ if (used + add > MAX_MERGED_CHARS)
93413
+ break;
93414
+ included.push(entry);
93415
+ used += add;
93416
+ }
93417
+ const droppedEntries = capped.length - included.length;
93418
+ if (droppedEntries === 0 && perSourceOmitted === 0) {
93419
+ const merged2 = included.map((e) => e.content).join(CONTEXT_SEPARATOR);
93420
+ return {
93421
+ merged: merged2,
93422
+ entries: included,
93423
+ hasContent: included.length > 0
93424
+ };
93425
+ }
93426
+ let omittedChars = originalJoinedLength - used;
93427
+ let notice = buildTruncationNotice(droppedEntries, omittedChars);
93428
+ while (included.length > 0 && used + CONTEXT_SEPARATOR.length + notice.length > MAX_MERGED_CHARS) {
93429
+ const removed = included.pop();
93430
+ if (removed)
93431
+ used -= removed.content.length + CONTEXT_SEPARATOR.length;
93432
+ const dropped = capped.length - included.length;
93433
+ omittedChars = originalJoinedLength - used;
93434
+ notice = buildTruncationNotice(dropped, omittedChars);
93435
+ }
93436
+ const body = included.map((e) => e.content).join(CONTEXT_SEPARATOR);
93437
+ const merged = body.length === 0 ? notice : `${body}${CONTEXT_SEPARATOR}${notice}`;
93671
93438
  return {
93672
93439
  merged,
93673
- entries,
93674
- hasContent: entries.length > 0
93440
+ entries: included,
93441
+ hasContent: included.length > 0
93675
93442
  };
93676
93443
  }
93677
93444
  consume(sessionID) {
@@ -94228,7 +93995,13 @@ function statusToLabel(status) {
94228
93995
  }
94229
93996
  function buildCompletionNotification(task, allComplete, completedTasks, remainingCount, duration5, errorInfo) {
94230
93997
  if (allComplete) {
94231
- const completedTasksText = completedTasks.map((t) => `- \`${t.id}\`: ${t.description}`).join(`
93998
+ const MAX_COMPLETED_LISTED = 5;
93999
+ const visibleTasks = completedTasks.slice(-MAX_COMPLETED_LISTED);
94000
+ const hiddenCount = completedTasks.length - visibleTasks.length;
94001
+ const lines = visibleTasks.map((t) => `- \`${t.id}\`: ${t.description}`);
94002
+ if (hiddenCount > 0)
94003
+ lines.push(`- ... +${hiddenCount} more tasks`);
94004
+ const completedTasksText = lines.join(`
94232
94005
  `);
94233
94006
  return `<system-reminder>
94234
94007
  [ALL BACKGROUND TASKS COMPLETE]
@@ -94453,7 +94226,7 @@ function toReviveTask(handle, prompt) {
94453
94226
  }
94454
94227
 
94455
94228
  // src/features/background-agent/task-history.ts
94456
- var MAX_ENTRIES_PER_PARENT = 100;
94229
+ var MAX_ENTRIES_PER_PARENT = 50;
94457
94230
 
94458
94231
  class TaskHistory {
94459
94232
  entries = new Map;
@@ -94495,7 +94268,9 @@ class TaskHistory {
94495
94268
  const list = this.getByParentSession(parentSessionID);
94496
94269
  if (list.length === 0)
94497
94270
  return null;
94498
- const lines = list.map((e) => {
94271
+ const visible = list.slice(-MAX_JOB_BOARD_ENTRIES);
94272
+ const hiddenCount = list.length - visible.length;
94273
+ const lines = visible.map((e) => {
94499
94274
  const desc = e.description.replace(/[\n\r]+/g, " ").trim();
94500
94275
  const parts = [
94501
94276
  `- **${e.agent}**`,
@@ -94506,6 +94281,8 @@ class TaskHistory {
94506
94281
  ];
94507
94282
  return parts.filter(Boolean).join("");
94508
94283
  });
94284
+ if (hiddenCount > 0)
94285
+ lines.push(`- ... +${hiddenCount} more`);
94509
94286
  return lines.join(`
94510
94287
  `);
94511
94288
  }
@@ -94533,11 +94310,14 @@ class TaskHistory {
94533
94310
  }
94534
94311
  function clampMaxRetainedSnapshots(value) {
94535
94312
  if (value === undefined || !Number.isFinite(value))
94536
- return 20;
94313
+ return 10;
94537
94314
  return Math.min(100, Math.max(1, Math.floor(value)));
94538
94315
  }
94316
+ var MAX_JOB_BOARD_ENTRIES = 5;
94539
94317
  function formatJobBoardBlock(entries) {
94540
- const lines = entries.map((row) => {
94318
+ const visible = entries.slice(-MAX_JOB_BOARD_ENTRIES);
94319
+ const hiddenCount = entries.length - visible.length;
94320
+ const lines = visible.map((row) => {
94541
94321
  const parts = [
94542
94322
  `- **${row.agent}**`,
94543
94323
  row.category ? `[${row.category}]` : null,
@@ -94547,6 +94327,8 @@ function formatJobBoardBlock(entries) {
94547
94327
  ];
94548
94328
  return parts.filter(Boolean).join("");
94549
94329
  });
94330
+ if (hiddenCount > 0)
94331
+ lines.push(`- ... +${hiddenCount} more`);
94550
94332
  return `**Background task board (${entries.length} task${entries.length === 1 ? "" : "s"}):**
94551
94333
  ${lines.join(`
94552
94334
  `)}`;
@@ -94560,6 +94342,9 @@ One or more background tasks for this session are still running or have undelive
94560
94342
  Use background_output with the task ID to retrieve results when ready.
94561
94343
  Do NOT poll - continue productive work.
94562
94344
  </system-reminder>`;
94345
+ function isWakeSchedulerEnabled(cfg) {
94346
+ return cfg?.enabled ?? DEFAULT_WAKE_SCHEDULER_ENABLED;
94347
+ }
94563
94348
  function resolveWakeIntervalMs(cfg) {
94564
94349
  const raw = cfg?.intervalMs ?? DEFAULT_WAKE_INTERVAL_MS;
94565
94350
  return Math.max(MIN_WAKE_INTERVAL_MS, raw);
@@ -95207,8 +94992,7 @@ ${formatWallclockTimeout(task.id, elapsedMs, limitMs)}`;
95207
94992
  system: input.skillContent,
95208
94993
  tools: (() => {
95209
94994
  const tools = {
95210
- task: false,
95211
- delegate_agent: true,
94995
+ task: true,
95212
94996
  question: false,
95213
94997
  ...getAgentToolRestrictions(input.agent)
95214
94998
  };
@@ -95421,8 +95205,7 @@ ${formatWallclockTimeout(task.id, elapsedMs, limitMs)}`;
95421
95205
  ...resumeVariant ? { variant: resumeVariant } : {},
95422
95206
  tools: (() => {
95423
95207
  const tools = {
95424
- task: false,
95425
- delegate_agent: true,
95208
+ task: true,
95426
95209
  question: false,
95427
95210
  ...getAgentToolRestrictions(existingTask.agent)
95428
95211
  };
@@ -95558,7 +95341,7 @@ ${formatWallclockTimeout(task.id, elapsedMs, limitMs)}`;
95558
95341
  const toastManager = getTaskToastManager();
95559
95342
  if (toastManager)
95560
95343
  toastManager.addTask({ id: task.id, description: task.description, agent: task.agent, isBackground: true });
95561
- const tools = { task: false, delegate_agent: true, question: false, ...getAgentToolRestrictions(task.agent) };
95344
+ const tools = { task: true, question: false, ...getAgentToolRestrictions(task.agent) };
95562
95345
  setSessionTools(sessionID, tools);
95563
95346
  const reviveModel = task.model ? { providerID: task.model.providerID, modelID: task.model.modelID } : undefined;
95564
95347
  const reviveVariant = task.model?.variant;
@@ -95872,7 +95655,7 @@ ${formatWallclockTimeout(task.id, elapsedMs, limitMs)}`;
95872
95655
  }
95873
95656
  }
95874
95657
  refreshParentWake(parentSessionID) {
95875
- if (this.config?.wakeScheduler?.enabled === false)
95658
+ if (!isWakeSchedulerEnabled(this.config?.wakeScheduler))
95876
95659
  return;
95877
95660
  const readState2 = () => ({
95878
95661
  hasPendingChildren: (this.pendingByParent.get(parentSessionID)?.size ?? 0) > 0,
@@ -98593,8 +98376,7 @@ function buildDynamicOrchestratorPrompt(ctx) {
98593
98376
  }
98594
98377
  function createArchitectAgent(ctx) {
98595
98378
  const restrictions = createAgentToolRestrictions([
98596
- "task",
98597
- "delegate_agent"
98379
+ "task"
98598
98380
  ]);
98599
98381
  const baseConfig = {
98600
98382
  description: "Orchestrates work via task() to complete ALL tasks in a todo list until fully done. (Architect - Matrixx)",
@@ -99579,7 +99361,7 @@ function createKeymakerAgent(model, availableAgents, availableToolNames, availab
99579
99361
  maxTokens: 32000,
99580
99362
  prompt,
99581
99363
  color: "#D97706",
99582
- permission: { question: "allow", delegate_agent: "deny" },
99364
+ permission: { question: "allow" },
99583
99365
  reasoningEffort: "medium"
99584
99366
  };
99585
99367
  }
@@ -100125,7 +99907,7 @@ function createMorpheusAgent(model, availableAgents, availableToolNames, availab
100125
99907
  const skills = availableSkills ?? [];
100126
99908
  const categories = availableCategories ?? [];
100127
99909
  const prompt = availableAgents ? buildDynamicMorpheusPrompt(availableAgents, tools, skills, categories, useTaskSystem) : buildDynamicMorpheusPrompt([], tools, skills, categories, useTaskSystem);
100128
- const permission = { question: "allow", delegate_agent: "deny" };
99910
+ const permission = { question: "allow" };
100129
99911
  const base = {
100130
99912
  description: "Powerful AI orchestrator. Plans obsessively with todos, assesses search complexity before exploration, delegates strategically via category+skills combinations. Uses explore for internal code (parallel-friendly), librarian for external docs. (Morpheus - Matrixx)",
100131
99913
  mode: MODE4,
@@ -100322,9 +100104,7 @@ Your response goes directly to the user or calling agent. Make it self-contained
100322
100104
  Dense and useful beats long and thorough.
100323
100105
  </delivery>`;
100324
100106
  function createCipherAgent(model) {
100325
- const restrictions = createAgentToolRestrictions([
100326
- "delegate_agent"
100327
- ]);
100107
+ const restrictions = createAgentToolRestrictions([]);
100328
100108
  const base = {
100329
100109
  description: "DSL engineering specialist. Grammar design (BNF/EBNF/PEG), type systems, parsers, transpilers, code generators, metamodeling (textX/PyEcore/ANTLR4). (Cipher - Matrixx)",
100330
100110
  mode: MODE5,
@@ -100648,8 +100428,7 @@ function createOperatorAgent(model) {
100648
100428
  "write",
100649
100429
  "edit",
100650
100430
  "task",
100651
- "task",
100652
- "delegate_agent"
100431
+ "task"
100653
100432
  ]);
100654
100433
  return {
100655
100434
  description: "Specialized codebase understanding agent for multi-repository analysis, searching remote codebases, retrieving official documentation, and finding implementation examples using GitHub CLI, Context7, and Web Search. MUST BE USED when users ask to look up code in remote repositories, explain library internals, or find usage examples in open source. (Librarian - Matrixx)",
@@ -100967,7 +100746,7 @@ var SATI_SYSTEM_PROMPT = `You are Sati, a FRONTEND specialist with deep expertis
100967
100746
 
100968
100747
  <context>
100969
100748
  You are invoked when a task touches the user-facing web layer: components, pages, layouts, design systems, accessibility, runtime performance, or build configuration. You own the full FRONTEND surface end-to-end \u2014 from JSX/Svelte authoring through to visual verification in a real browser.
100970
- You are self-contained: no \`task\` and no \`delegate_agent\` \u2014 you execute the work yourself using your read/write/edit tools plus the skills attached to this agent.
100749
+ You are self-contained: no \`task\` \u2014 you execute the work yourself using your read/write/edit tools plus the skills attached to this agent.
100971
100750
  </context>
100972
100751
 
100973
100752
  ## BROWSER VERIFICATION LOOP
@@ -100997,7 +100776,7 @@ You have 8 skills attached. Use them as your primary reference, not as decoratio
100997
100776
 
100998
100777
  ## NO DELEGATION
100999
100778
 
101000
- You are explicitly invokable only (mode: subagent). Both \`task\` and \`delegate_agent\` are denied in your permission set. Do the work yourself \u2014 explore, edit, run, verify \u2014 and report a self-contained result.
100779
+ You are explicitly invokable only (mode: subagent). \`task\` is denied in your permission set. Do the work yourself \u2014 explore, edit, run, verify \u2014 and report a self-contained result.
101001
100780
 
101002
100781
  ## CODE QUALITY BAR
101003
100782
 
@@ -101030,8 +100809,7 @@ Your response goes directly to the calling agent or user. Make it self-contained
101030
100809
  </delivery>`;
101031
100810
  function createSatiAgent(model) {
101032
100811
  const restrictions = createAgentToolRestrictions([
101033
- "task",
101034
- "delegate_agent"
100812
+ "task"
101035
100813
  ]);
101036
100814
  const base = {
101037
100815
  description: "frontend specialist. React/Next.js, Svelte/SvelteKit, accessibility, performance, design tokens, component architecture, build tooling. Self-contained \u2014 no delegation. (Sati - Matrixx)",
@@ -101238,8 +101016,7 @@ function createSentinelAgent(model) {
101238
101016
  "write",
101239
101017
  "edit",
101240
101018
  "multiedit",
101241
- "task",
101242
- "delegate_agent"
101019
+ "task"
101243
101020
  ]);
101244
101021
  const base = {
101245
101022
  description: "Security auditing specialist. SAST/DAST scanning, secret detection, dependency auditing (CVE/SBOM), API security review, cryptographic analysis, infrastructure hardening, OWASP/CWE compliance, threat modeling (STRIDE). Read-only auditor \u2014 reports findings, never modifies code. (Sentinel - Matrixx)",
@@ -101324,9 +101101,9 @@ Confirm:
101324
101101
  \`\`\`
101325
101102
  // Launch these explore agents FIRST
101326
101103
  // Prompt structure: CONTEXT + GOAL + QUESTION + REQUEST
101327
- delegate_agent(subagent_type="trinity", prompt="I'm analyzing a new feature request and need to understand existing patterns before asking clarifying questions. Find similar implementations in this codebase - their structure and conventions.")
101328
- delegate_agent(subagent_type="trinity", prompt="I'm planning to build [feature type] and want to ensure consistency with the project. Find how similar features are organized - file structure, naming patterns, and architectural approach.")
101329
- delegate_agent(subagent_type="operator", prompt="I'm implementing [technology] and need to understand best practices before making recommendations. Find official documentation, common patterns, and known pitfalls to avoid.")
101104
+ task(subagent_type="trinity", run_in_background=true, prompt="I'm analyzing a new feature request and need to understand existing patterns before asking clarifying questions. Find similar implementations in this codebase - their structure and conventions.")
101105
+ task(subagent_type="trinity", run_in_background=true, prompt="I'm planning to build [feature type] and want to ensure consistency with the project. Find how similar features are organized - file structure, naming patterns, and architectural approach.")
101106
+ task(subagent_type="operator", run_in_background=true, prompt="I'm implementing [technology] and need to understand best practices before making recommendations. Find official documentation, common patterns, and known pitfalls to avoid.")
101330
101107
  \`\`\`
101331
101108
 
101332
101109
  **Questions to Ask** (AFTER exploration):
@@ -101439,9 +101216,9 @@ Task(
101439
101216
  **Investigation Structure**:
101440
101217
  \`\`\`
101441
101218
  // Parallel probes - Prompt structure: CONTEXT + GOAL + QUESTION + REQUEST
101442
- delegate_agent(subagent_type="trinity", prompt="I'm researching how to implement [feature] and need to understand the current approach. Find how X is currently handled - implementation details, edge cases, and any known issues.")
101443
- delegate_agent(subagent_type="operator", prompt="I'm implementing Y and need authoritative guidance. Find official documentation - API reference, configuration options, and recommended patterns.")
101444
- delegate_agent(subagent_type="operator", prompt="I'm looking for proven implementations of Z. Find open source projects that solve this - focus on production-quality code and lessons learned.")
101219
+ task(subagent_type="trinity", run_in_background=true, prompt="I'm researching how to implement [feature] and need to understand the current approach. Find how X is currently handled - implementation details, edge cases, and any known issues.")
101220
+ task(subagent_type="operator", run_in_background=true, prompt="I'm implementing Y and need authoritative guidance. Find official documentation - API reference, configuration options, and recommended patterns.")
101221
+ task(subagent_type="operator", run_in_background=true, prompt="I'm looking for proven implementations of Z. Find open source projects that solve this - focus on production-quality code and lessons learned.")
101445
101222
  \`\`\`
101446
101223
 
101447
101224
  **Directives for Oracle**:
@@ -101827,8 +101604,7 @@ function createTrinityAgent(model) {
101827
101604
  "write",
101828
101605
  "edit",
101829
101606
  "task",
101830
- "task",
101831
- "delegate_agent"
101607
+ "task"
101832
101608
  ]);
101833
101609
  return {
101834
101610
  description: 'Contextual grep for codebases. Answers "Where is X?", "Which file has Y?", "Find the code that does Z". Fire multiple in parallel for broad searches. Specify thoroughness: "quick" for basic, "medium" for moderate, "very thorough" for comprehensive analysis. (Explore - Matrixx)',
@@ -103533,11 +103309,9 @@ function buildConstraintsSection(useTaskSystem) {
103533
103309
  if (useTaskSystem) {
103534
103310
  return `<Critical_Constraints>
103535
103311
  BLOCKED ACTIONS (will fail if attempted):
103536
- - task (agent delegation tool): BLOCKED \u2014 you cannot delegate work to other agents
103537
- - delegate_agent with subagent_type=oracle/construct/merovingian/smith/sentinel/cipher: BLOCKED \u2014 Mouse is a leaf executor
103312
+ - task (agent delegation tool): BLOCKED \u2014 you cannot delegate work or spawn other agents, including for research
103538
103313
 
103539
103314
  ALLOWED tools:
103540
- - delegate_agent with subagent_type=trinity/operator ONLY: You MAY spawn explore/librarian agents for research
103541
103315
  - task_create, task_update, task_list, task_get: ALLOWED \u2014 use these for tracking your work
103542
103316
 
103543
103317
  You work ALONE for implementation. No delegation of implementation or planning tasks. Plan files (.matrixx/plans/*.md) are OWNED by oracle \u2014 never create them via Mouse.
@@ -103545,10 +103319,7 @@ You work ALONE for implementation. No delegation of implementation or planning t
103545
103319
  }
103546
103320
  return `<Critical_Constraints>
103547
103321
  BLOCKED ACTIONS (will fail if attempted):
103548
- - task (agent delegation tool): BLOCKED \u2014 you cannot delegate work to other agents
103549
- - delegate_agent with subagent_type=oracle/construct/merovingian/smith/sentinel/cipher: BLOCKED \u2014 Mouse is a leaf executor
103550
-
103551
- ALLOWED: delegate_agent with subagent_type=trinity/operator ONLY - You MAY spawn explore/librarian agents for research.
103322
+ - task (agent delegation tool): BLOCKED \u2014 you cannot delegate work or spawn other agents, including for research
103552
103323
  You work ALONE for implementation. No delegation of implementation or planning tasks. Plan files (.matrixx/plans/*.md) are OWNED by oracle \u2014 never create them via Mouse.
103553
103324
  </Critical_Constraints>`;
103554
103325
  }
@@ -103653,11 +103424,9 @@ function buildConstraintsSection2(useTaskSystem) {
103653
103424
  if (useTaskSystem) {
103654
103425
  return `<Critical_Constraints>
103655
103426
  BLOCKED ACTIONS (will fail if attempted):
103656
- - task (agent delegation tool): BLOCKED \u2014 you cannot delegate work to other agents
103657
- - delegate_agent with subagent_type=oracle/construct/merovingian/smith/sentinel/cipher: BLOCKED \u2014 Mouse is a leaf executor
103427
+ - task (agent delegation tool): BLOCKED \u2014 you cannot delegate work or spawn other agents, including for research
103658
103428
 
103659
103429
  ALLOWED tools:
103660
- - delegate_agent with subagent_type=trinity/operator ONLY: You MAY spawn explore/librarian agents for research
103661
103430
  - task_create, task_update, task_list, task_get: ALLOWED \u2014 use these for tracking your work
103662
103431
 
103663
103432
  You work ALONE for implementation. No delegation of implementation or planning tasks. Plan files (.matrixx/plans/*.md) are OWNED by oracle \u2014 never create them via Mouse.
@@ -103665,10 +103434,7 @@ You work ALONE for implementation. No delegation of implementation or planning t
103665
103434
  }
103666
103435
  return `<Critical_Constraints>
103667
103436
  BLOCKED ACTIONS (will fail if attempted):
103668
- - task (agent delegation tool): BLOCKED \u2014 you cannot delegate work to other agents
103669
- - delegate_agent with subagent_type=oracle/construct/merovingian/smith/sentinel/cipher: BLOCKED \u2014 Mouse is a leaf executor
103670
-
103671
- ALLOWED: delegate_agent with subagent_type=trinity/operator ONLY - You MAY spawn explore/librarian agents for research.
103437
+ - task (agent delegation tool): BLOCKED \u2014 you cannot delegate work or spawn other agents, including for research
103672
103438
  You work ALONE for implementation. No delegation of implementation or planning tasks. Plan files (.matrixx/plans/*.md) are OWNED by oracle \u2014 never create them via Mouse.
103673
103439
  </Critical_Constraints>`;
103674
103440
  }
@@ -103769,13 +103535,11 @@ function buildGptBlockedActionsSection(useTaskSystem) {
103769
103535
  BLOCKED (will fail if attempted):
103770
103536
  | Tool | Status | Description |
103771
103537
  |------|--------|-------------|
103772
- | task | BLOCKED | Agent delegation tool \u2014 you cannot spawn other agents |
103773
- | delegate_agent with oracle/construct/merovingian/smith/sentinel/cipher | BLOCKED | Mouse is leaf \u2014 only trinity/operator allowed |
103538
+ | task | BLOCKED | Agent delegation tool \u2014 you cannot delegate work or spawn other agents, including for research |
103774
103539
 
103775
103540
  ALLOWED:
103776
103541
  | Tool | Usage |
103777
103542
  |------|-------|
103778
- | delegate_agent with trinity/operator ONLY | Spawn explore/librarian for research ONLY |
103779
103543
  | task_create | Create tasks to track your work |
103780
103544
  | task_update | Update task status (in_progress, completed) |
103781
103545
  | task_list | List active tasks |
@@ -103788,13 +103552,12 @@ You work ALONE for implementation. No delegation. Plan files (.matrixx/plans/*.m
103788
103552
  BLOCKED (will fail if attempted):
103789
103553
  | Tool | Status | Description |
103790
103554
  |------|--------|-------------|
103791
- | task | BLOCKED | Agent delegation tool \u2014 you cannot spawn other agents |
103792
- | delegate_agent with oracle/construct/merovingian/smith/sentinel/cipher | BLOCKED | Mouse is leaf \u2014 only trinity/operator allowed |
103555
+ | task | BLOCKED | Agent delegation tool \u2014 you cannot delegate work or spawn other agents, including for research |
103793
103556
 
103794
103557
  ALLOWED:
103795
103558
  | Tool | Usage |
103796
103559
  |------|-------|
103797
- | delegate_agent with trinity/operator ONLY | Spawn explore/librarian for research ONLY |
103560
+ | task_create | Create tasks to track your work |
103798
103561
 
103799
103562
  You work ALONE for implementation. No delegation. Plan files (.matrixx/plans/*.md) are OWNED by oracle \u2014 never create them via Mouse.
103800
103563
  </blocked_actions>`;
@@ -103835,9 +103598,7 @@ Execute tasks directly. You NEVER delegate.
103835
103598
  </role>
103836
103599
 
103837
103600
  <rules>
103838
- - task tool: BLOCKED \u2014 cannot delegate to other agents
103839
- - delegate_agent with oracle/construct/merovingian/smith/sentinel/cipher: BLOCKED \u2014 Mouse is leaf, only trinity/operator allowed
103840
- - delegate_agent with trinity/operator ONLY: ALLOWED for research (explore/librarian)
103601
+ - task tool: BLOCKED \u2014 cannot delegate work or spawn other agents, including for research
103841
103602
  - ${useTaskSystem ? "task_create/task_update" : "todowrite/todoread"}: REQUIRED for tracking
103842
103603
  - Implement ONLY what is requested \u2014 no scope creep
103843
103604
  - Plan files (.matrixx/plans/*.md): OWNED by oracle \u2014 never create via Mouse
@@ -103932,9 +103693,7 @@ function buildQwenBlockedActions(useTaskSystem) {
103932
103693
  if (useTaskSystem) {
103933
103694
  return `| Tool | Status | Notes |
103934
103695
  |------|--------|-------|
103935
- | task | BLOCKED | Cannot delegate implementation |
103936
- | delegate_agent with oracle/construct/merovingian/smith/sentinel/cipher | BLOCKED | Mouse is leaf \u2014 only trinity/operator allowed |
103937
- | delegate_agent with trinity/operator ONLY | ALLOWED | Research only (explore/librarian) |
103696
+ | task | BLOCKED | Cannot delegate work or spawn other agents, including for research |
103938
103697
  | task_create | ALLOWED | Track your work |
103939
103698
  | task_update | ALLOWED | Update status |
103940
103699
  | task_list / task_get | ALLOWED | View tasks |
@@ -103943,9 +103702,7 @@ Plan files (.matrixx/plans/*.md) are OWNED by oracle \u2014 never create them vi
103943
103702
  }
103944
103703
  return `| Tool | Status | Notes |
103945
103704
  |------|--------|-------|
103946
- | task | BLOCKED | Cannot delegate implementation |
103947
- | delegate_agent with oracle/construct/merovingian/smith/sentinel/cipher | BLOCKED | Mouse is leaf \u2014 only trinity/operator allowed |
103948
- | delegate_agent with trinity/operator ONLY | ALLOWED | Research only (explore/librarian) |
103705
+ | task | BLOCKED | Cannot delegate work or spawn other agents, including for research |
103949
103706
 
103950
103707
  Plan files (.matrixx/plans/*.md) are OWNED by oracle \u2014 never create them via Mouse.`;
103951
103708
  }
@@ -104029,7 +103786,6 @@ function createMouseAgentWithOverrides(override, systemDefaultModel, useTaskSyst
104029
103786
  for (const tool3 of BLOCKED_TOOLS3) {
104030
103787
  merged[tool3] = "deny";
104031
103788
  }
104032
- merged.delegate_agent = "allow";
104033
103789
  const toolsConfig = { permission: { ...merged, ...basePermission } };
104034
103790
  const base = {
104035
103791
  description: override?.description ?? "Focused task executor. Same discipline, no delegation. (Mouse - Matrixx)",
@@ -104555,7 +104311,6 @@ function applyToolConfig(params) {
104555
104311
  if (architect) {
104556
104312
  architect.permission = {
104557
104313
  ...architect.permission,
104558
- delegate_agent: "deny",
104559
104314
  ...isTaskSystem ? { task: "allow", "task_*": "allow", teammate: "allow", ...denyTodoTools } : { todowrite: "allow", todoread: "allow", ...denyTaskTools }
104560
104315
  };
104561
104316
  }
@@ -104563,7 +104318,6 @@ function applyToolConfig(params) {
104563
104318
  if (morpheus) {
104564
104319
  morpheus.permission = {
104565
104320
  ...morpheus.permission,
104566
- delegate_agent: "deny",
104567
104321
  question: questionPermission,
104568
104322
  ...isTaskSystem ? { task: "allow", "task_*": "allow", teammate: "allow", ...denyTodoTools } : { todowrite: "allow", todoread: "allow", ...denyTaskTools }
104569
104323
  };
@@ -104572,7 +104326,6 @@ function applyToolConfig(params) {
104572
104326
  if (keymaker) {
104573
104327
  keymaker.permission = {
104574
104328
  ...keymaker.permission,
104575
- delegate_agent: "deny",
104576
104329
  question: questionPermission,
104577
104330
  ...isTaskSystem ? { task: "allow", ...denyTodoTools } : { todowrite: "allow", todoread: "allow", ...denyTaskTools }
104578
104331
  };
@@ -104581,7 +104334,6 @@ function applyToolConfig(params) {
104581
104334
  if (oracle) {
104582
104335
  oracle.permission = {
104583
104336
  ...oracle.permission,
104584
- delegate_agent: "deny",
104585
104337
  question: questionPermission,
104586
104338
  ...isTaskSystem ? { task: "allow", "task_*": "allow", teammate: "allow", ...denyTodoTools } : { todowrite: "allow", todoread: "allow", ...denyTaskTools }
104587
104339
  };
@@ -104727,7 +104479,6 @@ function filterDisabledTools(tools, disabledTools) {
104727
104479
  function createToolRegistry(args) {
104728
104480
  const { ctx, pluginConfig, managers, skillContext, availableCategories } = args;
104729
104481
  const backgroundTools = createBackgroundTools(managers.backgroundManager, ctx.client, ctx.directory);
104730
- const delegateAgent = createDelegateAgent(ctx, managers.backgroundManager, pluginConfig.disabled_agents ?? []);
104731
104482
  const isMultimodalLookerEnabled = !(pluginConfig.disabled_agents ?? []).some((agent) => agent.toLowerCase() === "construct");
104732
104483
  const lookAt = isMultimodalLookerEnabled ? createLookAt(ctx) : null;
104733
104484
  const delegateTask = createDelegateTask({
@@ -104807,7 +104558,6 @@ function createToolRegistry(args) {
104807
104558
  ...createDcpSwitchProfileTool({ pluginConfig }),
104808
104559
  ...createPresetTool({ pluginConfig, directory: ctx.directory }),
104809
104560
  ...backgroundTools,
104810
- delegate_agent: delegateAgent,
104811
104561
  ...lookAt ? { look_at: lookAt } : {},
104812
104562
  task: delegateTask,
104813
104563
  skill: skillTool,
@@ -106041,62 +105791,12 @@ function createEventHandler2(args) {
106041
105791
  }
106042
105792
 
106043
105793
  // src/plugin/messages-transform.ts
106044
- var MESSAGES_TRANSFORM_CACHE_MAX = 100;
106045
- var messagesTransformCache = new Map;
106046
- var messageHashCache = new WeakMap;
106047
- function hashMessages(messages2) {
106048
- const cached3 = messageHashCache.get(messages2);
106049
- if (cached3 !== undefined)
106050
- return cached3;
106051
- const fresh = JSON.stringify(messages2);
106052
- messageHashCache.set(messages2, fresh);
106053
- return fresh;
106054
- }
106055
- function extractSessionID(messages2) {
106056
- for (let i = messages2.length - 1;i >= 0; i--) {
106057
- const id = messages2[i].info.sessionID;
106058
- if (id)
106059
- return id;
106060
- }
106061
- return;
106062
- }
106063
- function getCachedTransform(sessionID, messagesHash) {
106064
- const key = `${sessionID}:${messagesHash}`;
106065
- const cached3 = messagesTransformCache.get(key);
106066
- if (cached3 === undefined)
106067
- return;
106068
- messagesTransformCache.delete(key);
106069
- messagesTransformCache.set(key, cached3);
106070
- return cached3;
106071
- }
106072
- function setCachedTransform(sessionID, messagesHash, messages2) {
106073
- const key = `${sessionID}:${messagesHash}`;
106074
- if (messagesTransformCache.size >= MESSAGES_TRANSFORM_CACHE_MAX) {
106075
- const oldest = messagesTransformCache.keys().next().value;
106076
- if (oldest !== undefined)
106077
- messagesTransformCache.delete(oldest);
106078
- }
106079
- messagesTransformCache.set(key, messages2);
106080
- }
106081
105794
  function createMessagesTransformHandler(args) {
106082
105795
  return async (input, output) => {
106083
- const sessionID = extractSessionID(output.messages);
106084
- if (!sessionID) {
106085
- await args.hooks.contextInjectorMessagesTransform?.["experimental.chat.messages.transform"]?.(input, output);
106086
- await args.hooks.envContextInjector?.["experimental.chat.messages.transform"]?.(input, output);
106087
- await args.hooks.thinkingBlockValidator?.["experimental.chat.messages.transform"]?.(input, output);
106088
- await args.hooks.evolutionHitl?.["experimental.chat.messages.transform"]?.(input, output);
106089
- return;
106090
- }
106091
- const messagesHash = hashMessages(output.messages);
106092
- const cached3 = getCachedTransform(sessionID, messagesHash);
106093
- if (cached3 !== undefined)
106094
- return;
106095
105796
  await args.hooks.contextInjectorMessagesTransform?.["experimental.chat.messages.transform"]?.(input, output);
106096
105797
  await args.hooks.envContextInjector?.["experimental.chat.messages.transform"]?.(input, output);
106097
105798
  await args.hooks.thinkingBlockValidator?.["experimental.chat.messages.transform"]?.(input, output);
106098
105799
  await args.hooks.evolutionHitl?.["experimental.chat.messages.transform"]?.(input, output);
106099
- setCachedTransform(sessionID, messagesHash, output.messages);
106100
105800
  };
106101
105801
  }
106102
105802
 
@@ -106403,6 +106103,9 @@ var MatrixxPlugin = async (ctx) => {
106403
106103
  startBackgroundCheck();
106404
106104
  const pluginConfig = await loadPluginConfig(ctx.directory, ctx);
106405
106105
  setContextModeForPrompts(pluginConfig.context_mode);
106106
+ if (pluginConfig.dcp?.default_profile) {
106107
+ switchProfile(pluginConfig.dcp.default_profile, { pluginConfig });
106108
+ }
106406
106109
  const disabledHooks = new Set(pluginConfig.disabled_hooks ?? []);
106407
106110
  const isHookEnabled = (hookName) => !disabledHooks.has(hookName);
106408
106111
  const safeHookEnabled = pluginConfig.experimental?.safe_hook_creation ?? true;