Skip to content

Conversation

@ThomasK33
Copy link
Member

@ThomasK33 ThomasK33 commented Dec 23, 2025

This PR reverts the recent “unify bash into task_*” approach and restores the CC-style split:

  • task: spawn sub-agent workspaces only
  • bash: execute shell commands only
  • task_await / task_list / task_terminate: remain the unified surface for waiting / rediscovering / terminating both agent tasks and background bash processes

Key changes

  • task schema + backend execution are agent-only again (no kind="bash").
  • bash(run_in_background=true) now returns taskId: "bash:<processId>" (in addition to backgroundProcessId) so callers can task_await / task_terminate without needing bash-specific wrappers.
  • Frontend tool rendering + token accounting treat bash as its own tool (no more task(kind="bash") special-casing).
  • Updated tests/fixtures to request/require bash instead of task(kind="bash").

Compatibility / behavior notes

  • task(kind="bash") is intentionally not supported anymore; it will be rejected by the tool schema and backend.
  • Existing history entries using task(kind="bash") will render as a generic tool call.

Verification

  • make static-check

📋 Implementation Plan

Plan: Revert to separate task + bash tools while keeping unified task_await

Goal

Restore the CC-style split:

  • task: spawn sub-agent workspaces only (subagent_type, prompt, title, run_in_background).
  • bash: execute shell commands only (script, timeout_secs, run_in_background, display_name).
  • task_await: remain the single “wait/output” tool for both agent tasks and background bash processes.

Recommended approach net LoC (product code only): ~-60 to -110 LoC (mostly deleting the task(kind="bash") branch + schema fields, plus a small additive tweak to bash background results).

Why this is needed (context)

We currently expose a unified task tool that accepts both agent-task args and kind="bash" args via a flattened Zod schema + superRefine (see src/common/utils/tools/toolDefinitions.ts and src/node/services/tools/task.ts). Even though it avoids anyOf/oneOf in the provider-facing schema, it’s still an undesirable UX/architecture: bash execution should be initiated via bash, while task_await provides the unified output surface.

Should we prefix agent task IDs as agent:<workspaceId>?

Recommendation: don’t (for now).

  • Agent task IDs are real workspace IDs used across the app. Prefixing would require pervasive parsing/rewiring (and it risks breaking persisted history).
  • We only need a prefix for bash tasks because they’re not workspace IDs (they’re process IDs), and task_await needs a cheap routing signal.
  • Adding taskId: "bash:<processId>" to bash background results gets us the consistency win (both task and bash return a taskId usable by task_await) without changing agent ID semantics.

If we ever want stronger typing, prefer adding an explicit kind: "agent" | "bash" field to task_list results (low-risk) rather than changing the agent task ID format.


Implementation Steps

1) Split tool input surface in TOOL_DEFINITIONS (agent-only task)

Files:

  • src/common/utils/tools/toolDefinitions.ts
  • src/common/utils/tools/tools.ts

Actions:

  1. Make task agent-only again:
    • Set TaskToolArgsSchema = TaskToolAgentArgsSchema.
    • Delete TaskToolBashArgsSchema and the superRefine union enforcement wrapper.
  2. Update tool descriptions to match the split:
    • TOOL_DEFINITIONS.task.description: remove “Unified … (bash)” wording and only document agent spawning.
    • TOOL_DEFINITIONS.bash.description: update background guidance to point at task_await / task_list / task_terminate (not bash_output / bash_background_*).
  3. Tighten TaskToolResultSchema to agent-only:
    • Remove bash-specific fields from TaskToolCompletedResultSchema (bashResult, exitCode, note, truncated).

Back-compat note: old chat history may still contain toolName="task" + input.kind="bash" and/or bashResult in the result. Preserve UI rendering via unknown-shape type guards (see step 4) rather than keeping task schema “wide”.

2) Remove bash dispatch from backend task tool

File: src/node/services/tools/task.ts

Actions:

  • Delete the task(kind="bash") execution branch.
  • Remove now-unused helpers/imports:
    • createBashTool, resolveBashDisplayName, toBashTaskId, BashToolResult, and formatBashReport().
  • Keep the agent-task logic + defensive input validation intact.

3) Return taskId from bash background results (directly awaitable)

Files:

  • src/common/utils/tools/toolDefinitions.ts (result schema)
  • src/node/services/tools/bash.ts
  • src/node/services/tools/taskId.ts (import-only)

Actions:

  1. Extend BashToolResultSchema:
    • Add taskId: z.string() to the background-success variant, where taskId is the prefixed form (bash:<processId>).
  2. Populate the new field in bash.ts:
    • When returning background spawn success (run_in_background=true), include taskId: toBashTaskId(spawnResult.processId).
    • When returning “sent to background” (migration path), include taskId: toBashTaskId(processId).

4) Keep task_await unified (no behavior change), but fix UX affordances

Files:

  • src/node/services/tools/task_await.ts (likely no code changes)
  • src/common/utils/tools/taskToolTypeGuards.ts
  • src/browser/stores/WorkspaceStore.ts
  • (possible) src/browser/components/tools/* where task(kind="bash") is special-cased

Actions:

  1. Maintain unified waiting semantics:
    • Keep routing on taskId prefix (bash: → backgroundProcessManager; else agent task).
  2. Update/rename type guards for legacy task(kind="bash"):
    • Stop depending on TaskToolArgs having kind.
    • Prefer an unknown → LegacyTaskBashArgs guard for rendering old history.
  3. Simplify WorkspaceStore bash detection:
    • Replace isTaskKindBashToolCall() with isBashLikeToolCall():
      • toolName === "bash" → bash
      • toolName === "task" && input.kind === "bash" → legacy bash-in-task
      • toolName === "task" && result.taskId startsWith("bash:") / bashResult → legacy fallback
    • Remove the special “task uses bash tool under the hood” live-output cleanup path for new flows; keep a minimal legacy fallback only for old sessions.

5) Update token accounting buckets

Files:

  • src/common/utils/tokens/tokenStatsCalculator.ts
  • src/common/utils/tokens/tokenStatsCalculator.test.ts

Actions:

  • Update getConsumerInfoForToolCall():
    • New behavior: toolName === "bash" is its own consumer bucket.
    • Legacy behavior: if toolName === "task" and input.kind === "bash", label as task (bash legacy).

6) Update tests and fixtures to use bash, not task(kind="bash")

Targeted updates (non-exhaustive but high-signal):

  • src/common/utils/tools/toolDefinitions.test.ts

    • Remove/replace the assertion that task accepts { kind: "bash" … }.
    • Add an assertion that task rejects bash-shaped input.
  • src/node/services/tools/task.bash.test.ts

    • Remove the tests that call createTaskTool() with kind:"bash".
    • Keep (or move) the tests that ensure task_await, task_list, and task_terminate work with taskId="bash:<processId>".
  • tests/ipc/runtimeExecuteBash.test.ts

    • Tool policy: require bash (instead of task).
    • Prompt strings + event assertions: verify toolName === "bash" (no args.kind).
  • tests/ipc/sendMessage.context.test.ts, tests/ipc/ollama.test.ts

    • Update prompts from “Use task(kind="bash") …” to “Use bash() …”.
  • src/node/services/taskService.test.ts

    • Replace parent message part toolName:"task" input:{kind:"bash",…} with toolName:"bash" input:{script,…}.
  • Update any strict equality assertions for background bash results to allow / expect the new taskId field.

7) Verification

Run a tight set of checks after changes:

  • Unit: bun test src/node/services/tools/task.test.ts
  • Unit: bun test src/node/services/tools/task.bash.test.ts
  • Unit: bun test src/common/utils/tools/toolDefinitions.test.ts
  • Unit: bun test src/common/utils/tokens/tokenStatsCalculator.test.ts
  • IPC integration: TEST_INTEGRATION=1 bun x jest tests/ipc/runtimeExecuteBash.test.ts -t "execute simple bash commands"

Generated with mux • Model: openai:gpt-5.2 • Thinking: xhigh

@ThomasK33 ThomasK33 force-pushed the task-bash-abstraction branch from 7860d42 to 986955f Compare December 23, 2025 19:33
@ThomasK33
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ThomasK33 ThomasK33 force-pushed the task-bash-abstraction branch from 215bd13 to db76e83 Compare December 24, 2025 09:32
@ThomasK33
Copy link
Member Author

Fixed in db76e83 - coerceTimeoutMs now accepts 0 and only rejects negative values, so timeout_secs: 0 correctly translates to an immediate non-blocking check for both agent and bash tasks.

@ThomasK33
Copy link
Member Author

@codex review

Follow-up: fixed static-check by aligning RefreshController unit tests with the current (post-revert) RefreshController API.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

try {
const report = await taskService.waitForAgentReport(taskId, {
timeoutMs,

P2 Badge Handle timeout_secs=0 for agent tasks

task_await now allows timeout_secs=0 (per schema/docs for non‑blocking bash), but createTaskAwaitTool forwards timeoutMs directly into taskService.waitForAgentReport. When timeout_secs is 0 and any agent task is included (explicitly or via the default “all active tasks”), waitForAgentReport asserts timeoutMs > 0 and throws, so those agent results come back as error instead of queued|running|awaiting_report. Consider treating 0 as “no wait” for agent tasks (return current status) or defaulting to the 10‑minute wait when timeout_secs is 0.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ThomasK33
Copy link
Member Author

Fixed in cac38ca.

  • task_await now treats timeout_secs: 0 (or values that round down to 0ms) as non-blocking for agent tasks.
  • We validate scope first, then return the current task status (queued/running/awaiting_report) instead of calling waitForAgentReport (which asserts timeoutMs > 0).
  • Added a regression test covering timeout_secs=0.

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ThomasK33
Copy link
Member Author

@codex review

Addressed the truncation metadata issue for task(kind="bash") by:

  • adding truncated?: { reason; totalLines } to the task completed result schema
  • including a truncation warning + metadata in reportMarkdown when present
  • making bash tool init lazy so agent-only task tests don't require bash deps

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ThomasK33
Copy link
Member Author

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Another round soon, please!

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ThomasK33 ThomasK33 force-pushed the task-bash-abstraction branch 2 times, most recently from 84a1d42 to ee8d4c4 Compare December 26, 2025 20:47
@ThomasK33
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ThomasK33 ThomasK33 force-pushed the task-bash-abstraction branch from 0523720 to a5fc33c Compare December 26, 2025 22:35
@ThomasK33
Copy link
Member Author

@codex review

Fixed pending task finalization to skip task(kind="bash") (and added a unit test).

Also extended workspace activity snapshots to include the last thinking level for the VS Code extension.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ThomasK33 ThomasK33 force-pushed the task-bash-abstraction branch from bbe9ddd to 853b615 Compare December 28, 2025 10:53
@ThomasK33
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ThomasK33 ThomasK33 force-pushed the task-bash-abstraction branch from dc653d6 to 81cd629 Compare December 28, 2025 20:09
@ThomasK33
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ThomasK33 ThomasK33 force-pushed the task-bash-abstraction branch from 10b63d2 to 4a2ea12 Compare December 28, 2025 21:39
@ThomasK33
Copy link
Member Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ThomasK33 ThomasK33 force-pushed the task-bash-abstraction branch from 4a2ea12 to ec44579 Compare December 29, 2025 08:26
Change-Id: I93d9236d1160456b3f4f3c05815b70f84e812012
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Ifa45aefee1298bd27137a4d1ffc6bf95517689b8
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I002ab1584a1c9e73ebdd06a126d5bf01acdd9756
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I1a869f9aea822126fdf7098161d5f5198fe12ee2
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Previously, timeout_secs=0 was treated as 'unset' and fell back to
the default 10-minute timeout for agent tasks (while bash tasks
correctly supported non-blocking 0-second waits). Now timeout_secs=0
is respected for both agent and bash tasks, enabling immediate
non-blocking checks when needed.

Addresses Codex review feedback.

Change-Id: Iad7d72a342c9ae6c86ffcade4f7bc34e846376c5
Signed-off-by: Thomas Kosiewski <tk@coder.com>
When timeout_secs=0, task_await should return the current agent task status (queued/running/awaiting_report) rather than erroring due to waitForAgentReport's timeoutMs>0 invariant. Add a regression test.

Change-Id: I6114dece5254064298bfe523339b17b1579abe48
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I8721464eef644e87bd4aebd60c0231b99af432e7
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Ic45bb48c897b0bab9a0460908e7167f07c43bf6f
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I0405e87882b040e05611ed899c1590293d15deb1
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Iae7e5a1f29002e2ccbc5bf1e5f82c2e72c975400
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Ia3295b2a2f720c18253f36f129edf853dd0b44c1
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I6a731b8665141f37c4fa4bbdf80302db201d1171
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I057eac2e131fd9e8a00281c028ae3aee6c49b3e9
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Ib254ceb7cadcc2632bcd9f249767c0d1004b1167
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I5f986c0596dee69aa17c901ffb94322fa390fb69
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Ib563d7fe7a5882aed0a61f338147e43e747bb5a2
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I44d0d38c54c9136a4f2459abe21b87d8c30bb45f
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I64827f3a8e4305fbe3a46978fa49ad78523e4662
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Ibb874d6bbb7d38a458024deb1ed710d58c87d975
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I836b13fa243fd999eac70ae006d47501f57e30a6
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I3129f859e0f44bf6eaed3855a6a8222ed107dc4a
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I3dc061b4728cc6cf70f680628401eb02c540d876
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I5145c268728aa0476723eb1753e56e687d9e81af
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Ica79dd1f0b0f528331922bb4bdeabb9da1222395
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I470711377e0d439be2724d4ed909e18ef76bd0cc
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I4fe6af0fe450b12528335bbb04310dbe37d866cf
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Ib1a91a17f9d88b5b02314d1e608135887e835d90
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33 ThomasK33 force-pushed the task-bash-abstraction branch from d2bf219 to 3542154 Compare December 29, 2025 09:04
@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Delightful!

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ThomasK33 ThomasK33 changed the title 🤖 feat: unify bash into task_* tools 🤖 refactor: restore separate task + bash tools Dec 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant