Skip to content

[codex] Return tool timeouts without draining blocked bodies#976

Draft
mimeding wants to merge 9 commits into
osaurus-ai:mainfrom
mimeding:codex/tool-timeout-nonblocking-race
Draft

[codex] Return tool timeouts without draining blocked bodies#976
mimeding wants to merge 9 commits into
osaurus-ai:mainfrom
mimeding:codex/tool-timeout-nonblocking-race

Conversation

@mimeding
Copy link
Copy Markdown
Contributor

@mimeding mimeding commented Apr 29, 2026

Rebased onto current origin/main (fd2ffece, #1015). Reviewers should focus on the timeout race and PocketTTS compatibility updates; stale CI/cache commits remain only where they directly support this branch's test stability.

Business rationale

Tool calls are part of the local-agent harness, so a single blocked or cancellation-hostile tool body must not freeze the whole conversation. Returning a structured timeout envelope quickly lets the agent recover, explain what happened, and keep the user in control even when an individual tool misbehaves.

Coding rationale

ToolRegistry.runToolBody now races tool execution against a wall-clock timeout and returns the timeout envelope without waiting for the losing tool body to drain. The timeout tests use a blocking fixture that ignores cooperative cancellation without monopolizing the Swift concurrency executor, which better matches subprocess and blocking-I/O failure modes. The rebase keeps PocketTTS initialization compatible with the currently pinned FluidAudio API while preserving existing disk-detection behavior across both the repo-level and language-specific model cache layouts. CI cache changes stay scoped to the branch's test-core stability story.

What changed

  • Returned structured timeout envelopes without waiting for blocked tool bodies to finish.
  • Added timeout regression coverage for slow, blocking, and fast tool bodies.
  • Stabilized the timeout race test for loaded CI runners.
  • Kept PocketTTS initialization compatible with the currently resolved FluidAudio APIs.
  • Rebased the branch onto current main and resolved the timeout-test conflict against the newer fixture-relative timing assertion.

Validation

  • git fetch origin && git rebase origin/main - completed; conflict in ToolRegistryTimeoutTests.swift resolved by keeping the fixture-relative timeout assertion and applying the CI stabilization around it.
  • swift build --package-path Packages/OsaurusCore - passed.
  • swift build --package-path Packages/OsaurusCore -c release - passed.
  • swift test --package-path Packages/OsaurusCore - passed: 1,437 tests in 192 suites, with sandbox integration tests skipped by their normal environment gate.
  • xcrun swift-format lint --strict on every touched Swift file - passed.
  • swiftlint lint --strict on every touched Swift file - passed file-by-file.
  • git diff --check origin/main...HEAD - passed.
  • CLI gate skipped because this slice does not touch Packages/OsaurusCLI.
  • Workspace/Xcode build skipped because this slice does not touch Xcode targets or project settings.

Non-scope

  • No new tool schema or agent-loop behavior beyond timeout handling.
  • No changes to CLI behavior.
  • No broader TTS feature work beyond keeping PocketTTS initialization API-compatible with the current dependency graph.

Residual risks

The branch still carries CI cache-hardening commits because the timeout race was historically sensitive to the GitHub runner environment. If maintainers prefer separating CI-cache policy from timeout behavior, those commits can be split after this rebase is reviewed.

@mimeding
Copy link
Copy Markdown
Contributor Author

Follow-up from the live debug pass: the code change itself still verifies locally.

Local checks:

  • swift test --filter ToolRegistryTimeoutTests passed: 3/3 tests.
  • swiftlint --strict Packages/OsaurusCore/Tools/ToolRegistry.swift Packages/OsaurusCore/Tests/Tool/ToolRegistryTimeoutTests.swift passed.

GitHub test-core is failing before tests execute with the same EventSource module-resolution class (CAsyncHTTPClient, CNIOLLHTTP, CNIOExtrasZlib, CNIOPosix, _NumericsShims). PR #975 is the shared CI/DerivedData fix and is now fully green, so I would land #975 first, then rerun this PR rather than treating the timeout patch as the failing root cause.

@mimeding
Copy link
Copy Markdown
Contributor Author

Status update after adding the clean-PR rule: this PR is now draft because its attached GitHub checks are not clean yet. It should move back to ready only after #975 lands/rebases into the branch and scripts/ci/check-pr-clean.sh osaurus-ai/osaurus 976 passes.

@mimeding
Copy link
Copy Markdown
Contributor Author

Reran #976 after local verification. Local status is clean:

  • git diff --check origin/main...HEAD
  • strict SwiftLint on ToolRegistry.swift and ToolRegistryTimeoutTests.swift
  • cd Packages/OsaurusCore && swift test --filter ToolRegistryTimeoutTests (3 tests passed)
  • cd Packages/OsaurusCore && swift build

I could not rerun the failed GitHub job directly because GitHub requires repository admin rights for gh run rerun, so I pushed an empty rerun commit (ef9afe3e). The fresh GitHub run still fails only in test-core, with the same EventSource dependency-resolution class:

  • CAsyncHTTPClient
  • CNIOLLHTTP
  • CNIOExtrasZlib
  • CNIOPosix
  • _NumericsShims

No timeout-code regression is visible. Keeping this PR draft until #975 lands or the EventSource CI class is otherwise fixed.

@mimeding mimeding force-pushed the codex/tool-timeout-nonblocking-race branch from ef9afe3 to 9f315a0 Compare April 30, 2026 10:48
@mimeding mimeding marked this pull request as ready for review April 30, 2026 11:43
@mimeding mimeding force-pushed the codex/tool-timeout-nonblocking-race branch 3 times, most recently from d2e7169 to 1248480 Compare May 1, 2026 17:48
Michael Meding added 9 commits May 3, 2026 21:36
Business rationale: The timeout-race branch needs to stay reviewable and green after rebasing onto current main, because nonblocking tool failures are part of the local-agent harness users depend on when tools misbehave.

Coding rationale: This commit is a formatter-only cleanup in a file already touched by the branch. It preserves the PocketTTS compatibility behavior while satisfying the touched-file swift-format gate.
@mimeding mimeding force-pushed the codex/tool-timeout-nonblocking-race branch from 1248480 to 4f40ac5 Compare May 4, 2026 00:51
@mimeding mimeding marked this pull request as draft May 10, 2026 14:57
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