Skip to content

feat(drive): control tool calls at runtime#32

Merged
kitlangton merged 3 commits into
mainfrom
multi-tool-interleavings
Jul 19, 2026
Merged

feat(drive): control tool calls at runtime#32
kitlangton merged 3 commits into
mainfrom
multi-tool-interleavings

Conversation

@kitlangton

@kitlangton kitlangton commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

What

Add Drive-owned runtime control for selected OpenCode tools. Scripts and library drivers can statically declare shell, webfetch, or websearch, accept concurrent invocations by stable call ID, stream progress, and settle each call independently.

tools: ["shell"],
run: ({ tools }) => Effect.gen(function* () {
  const shells = yield* tools.control("shell")
  const shell = yield* shells.take("call_build")
  yield* shell.progress("building\n")
  yield* shell.succeed({ output: "built\n", exit: 0 })
})

The existing callback-style tools(registry) API remains available for fixed handlers. Undeclared tools continue to use OpenCode's real implementations.

How

  • src/tool/controller.ts hosts declared adapters, routes exact-ID and FIFO waiters, serializes progress with terminal commitment, and owns interruption/shutdown cleanup.
  • Runtime calls expose typed id, input, index, progress, succeed, fail, and awaitInterrupted operations with structured ControlError failures.
  • One insertion-ordered owner map prevents duplicate IDs from releasing or stealing active calls. Effect callback cleanup safely returns a call when a suspended take is interrupted.
  • OpenCodeInstance owns the controller used to configure its plugin; prepared drivers and script contexts derive controls from that instance.
  • Background shells return their launch response immediately while the controlled call continues to drive retained completion state.
  • The multi-tool interleaving probe now uses the public runtime-control API as its first feature-level consumer.
  • README, API/architecture docs, agent skill guidance, compile contracts, and a minor changeset document the public surface.

Scope

  • This is Drive-only. It does not change OpenCode or add backend control to CLI command flags.
  • Runtime adapters are limited to shell, webfetch, and websearch.
  • Array declarations and callback registration remain intentionally exclusive.
  • Exactly-once settlement is a Drive-local acceptance guarantee, not a delivery guarantee after an HTTP transport disconnect.

Testing

  • bun run test: 153 Effect tests, 51 CLI integration tests, and 28 catalog tests passed.
  • bun run check: package/catalog lint, typecheck, generated catalog validation, tests, and builds passed.
  • cd packages/drive && bun run drive check test/manual/tui-regressions/multi-tool-interleavings.ts
  • cd packages/drive && bun pm pack --dry-run, followed by packed-artifact installation and Tool export validation in a clean consumer.
  • Live multi-tool probe passed against OpenCode v2 at bef6cfbffe, including permission-over-form priority, form-with-running-shell state, exact sibling settlement, interruption, and session recovery.

Demo

The question form exists, but read and glob permissions retain prompt priority while the runtime-controlled shell stays active:

Permission shown over pending form

After glob completes and read is rejected, the form appears while the controlled shell remains active:

Form shown with running controlled shell

Flow

sequenceDiagram
  participant Program as Drive program
  participant Controls as Tool controls
  participant Adapter as OpenCode tool adapter
  participant OpenCode

  Program->>Controls: control("shell")
  Program->>Controls: take("call_build")
  OpenCode->>Adapter: shell(input, call_build)
  Adapter->>Controls: offer call_build
  Controls-->>Program: typed controlled call
  Program->>Controls: progress("building")
  Controls-->>Adapter: progress event
  Adapter-->>OpenCode: streamed progress
  Program->>Controls: succeed(result)
  Controls-->>Adapter: terminal result
  Adapter-->>OpenCode: success event
Loading

@kitlangton kitlangton changed the title test(drive): probe concurrent tool interleavings feat(drive): control tool calls at runtime Jul 19, 2026
@kitlangton
kitlangton merged commit fad9f96 into main Jul 19, 2026
1 check passed
@kitlangton
kitlangton deleted the multi-tool-interleavings branch July 19, 2026 17:11
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