Skip to content

Add agent teams, owner chat recovery and goal continuation improvements - #24

Open
LeZergan wants to merge 3 commits into
devnoname120:mainfrom
LeZergan:pr/agent-teams-runtime
Open

LeZergan wants to merge 3 commits into
devnoname120:mainfrom
LeZergan:pr/agent-teams-runtime

Conversation

@LeZergan

Copy link
Copy Markdown

Summary

Split out of #20, as requested. This PR has the native runtime work: agent teams, owner-chat recovery, goal continuation and the browser settings that use #22.

Stacked on #22 and #23. This branch contains their commits first, so GitHub shows a cumulative diff. Please review only the last commit, "Add agent teams, owner chat recovery and goal continuation improvements". After #22 and #23 merge I'll rebase, and this PR will show only its own changes. The pieces share supervisor.rs, store.rs, server.rs and owner_chat.rs too heavily to make an independent branch that compiles on its own.

New features are off by default unless noted.

Changes

Agent teams and AI agent control (agentChat.features.agentTeams, externalAgentControl)

  • Parent and worker chats, each worker with its own goal. New tools: agent_spawn, agent_status, agent_report, agent_control and agent_message.
  • Control is revision-checked (expectedRevision). A chat can only control its own recorded children, and workers can't control siblings or their parent.
  • Every worker goal and get_agent_brief includes a coordination agreement (docs/AGENT_COORDINATION.md).
  • One agent connection works over MCP, HTTP and a dependency-free JavaScript helper. The service publishes it in ~/.codexify/agents/ (connection.json, client.mjs). See docs/CODING_APP_AGENTS.md.
  • Optional auto mode and default delegation.

Owner chat

  • An Agents panel and agent folders (agentFolders).
  • A working-tree changes counter in the chat header. It is optional, rate-limited and never blocks chat.
  • A faster chat listing (owner_chat/listing.rs), with reads bounded in parallel.
  • Opt-in conversation recovery (conversationRecovery) replaces an inaccessible conversation without losing the task. It takes a recovery lease, then prepares the new chat and checks the real account before proceeding.

Goals and continuation

  • An infinite goal stops only when the same concrete blocker persists across three distinct goal turns spanning at least 60 seconds (goal_blocking.rs).
  • Offline detection counts native calls and running commands as activity, using upstream's configurable offline timeout.
  • Turn handoffs reset the previous owner's renewal clock.
  • When the browser observer fails late, an agent's acknowledgment of the exact message batch still settles the uncertain send, even while another page owns the scan.
  • Optional infinite retries (retryTimings.infiniteRetries).
  • Agent instructions changed: concurrent workspace edits no longer end the turn, and there's a new section on execution and tool speed.

Browser runtime settings (uses #22)

  • agentChat.automation.browserActionLanes (1–4) enables parallel action pages, with one action per conversation enforced natively.
  • Browser simplicity (Off / Simplified / Bones) and opt-in recovery enhancements, both passed to the companion at launch.
  • Fast setup applies the recommended preset in one save. It's available in Settings and as codexify config fast-setup. Quickstart fills it in only for missing fields.
  • Behaviour change: the healthy conversation-load interval now defaults to 1 second (was 180). HTTP 429 and Retry-After back-off still apply, and an explicitly saved interval is kept.

Tooling and docs

  • scripts/monitor-agent-performance.mjs, owner-chat UI smoke scripts, README and docs/REFERENCE.md updates.

Testing (Windows 11, full merged tree)

  • cargo test: 1658 passed. The failures that remain also fail on unmodified main on Windows, so they come from the environment:
    • doctor_cli (a Codexify service is installed on this machine)
    • existing_worktrees and workspace_resume (\\?\ path spelling)
    • chat_attachments
    • the exec_command output-budget test
  • The tests in agent_automation_supervisor, agent_automation_parallel and config all pass.
  • cargo fmt --check passes.
  • cargo clippy --all-targets -D warnings: no findings in the new code. The remaining warnings are Windows-only (unused variables in upstream's code behind cfg(unix)).
  • Browser companion: bun test 309 pass / 0 fail, and tsc --noEmit passes.

🤖 Generated with Claude Code

LeZergan and others added 3 commits November 13, 2026 01:25
Adds an optional pool of up to four fixed ChatGPT pages in one private Chrome
profile (one action per conversation; maintenance drains every page; shared
429 back-off and Send spacing), with optional health fields describing
capacity. The companion still defaults to one page.

Also recovers orphaned Windows Chrome, normalizes renderer priority, waits for
editor hydration instead of treating a missing editor as sign-out, journals
owned unsent drafts, bounds read-only DOM observations and passive health
polls, persists Retry-After across restarts, and adds optional Simplified and
Bones presentation levels. Upstream's admission, pairing-window reservation,
chat-mode, conversation-limit and transcript rate-limit handling are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
exec_command keeps a session addressable until its final output and exit code
are polled, retains final results until read, and lets an owner message end
only the output wait. Git checkpoints skip repeated legacy-namespace probes and
drain stderr under the command deadline. Paths drop the \?\ verbatim prefix
before reaching Git, the native server runs at Normal priority, and the
supervisor holds an OS lock for its lifetime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent teams (off by default): parent and worker chats with per-worker goals,
revision-checked agent_control, agent_message, agent_status and reports, plus
one agent connection over MCP, HTTP and a dependency-free JavaScript helper.

Owner chat: an Agents panel and folders, a working-tree changes counter, a
faster chat listing, and opt-in recovery that replaces an inaccessible
conversation. Goals: infinite goals stop only when the same concrete blocker
persists across three turns and 60 seconds; native offline detection counts
running native calls and commands; turn handoffs reset per-owner clocks.

Browser runtime: up to four parallel action pages (browserActionLanes),
Browser simplicity and recovery settings, Fast setup in Settings and
`codexify config fast-setup`, and a one-second healthy conversation-load
interval (HTTP 429 and Retry-After back-off still apply).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@devnoname120 devnoname120 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Reviewed the final commit 20be346 separately from its #22/#23 prerequisites, focusing on worker ownership/revision checks, durable controls, recovery leases, continuation fencing, native activity tracking, settings and the external agent client. Requesting changes; this stack is not ready to merge.

The Windows worktree path comparison is a functional blocker for the new agent client. The new native code also fails the non-Windows lint gate, and the split still omits a helper imported by its tests. Inline comments describe each issue.

Validation at this head:

  • Clean library run: 934 passed, 3 failed, 1 ignored. Both recovery-lease failures reproduce the macOS CI descriptor-directory permission error. The third failure is owner_api_lists_sends_and_reads_the_same_persisted_chat: its new agentTeam assertion expects metadata although the fixture leaves agentFolders disabled. Align the fixture/contract before treating the suite as passing.
  • Selected agent_connection, agent_automation_parallel, agent_automation_supervisor and turn_renewal integration suites: 182 passed, 1 ignored.
  • cargo fmt --all --check passed. cargo clippy --all-targets -- -D warnings failed with the new non-Windows loop/mutability diagnostics and the inherited unused PendingBuffer helper.
  • node --test scripts/test-agent-client.mjs fails before running tests because its imported helper is missing; the separate monitor tests passed all 9 cases.
  • Current CI fails browser packaging/native account-maintenance tests inherited from #22, the macOS owner-chat tests above, and the retry-settings UI assertion in both Chromium and WebKit (9 controls versus the expected 8). The Windows service job passes. These are not all Windows-environment failures.

The positive evidence is useful: the selected scheduling/continuation integration suites pass and the code contains explicit ownership checks, compare-and-set guards and tests for uncertain sends. However, the final commit adds roughly 16,000 lines across agent teams, recovery, settings and UI, beyond the prerequisite browser/execution changes. I would land the corrected prerequisites first, then rebase this PR and rerun its full native/browser/UI validation. The new client and recovery features need the inline defects and failing contracts resolved before approval.

.bindings
.selected_project_root(&self.config, &task)?
.ok_or("Coding-app team workspace is missing; retry setup")?;
if root != std::path::Path::new(&record.project_path) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Normalize the saved workspace before comparing it with the binding

With createWorktree=true on Windows, a new managed worktree is returned under the plain drive path produced by prepare_worktrees_root/strip_verbatim_prefix. Setup saves that spelling into record.project_path at line 395. client_task immediately reloads the binding through selected_project_root, whose canonical_binding_dir uses fs::canonicalize and returns the extended-length spelling. Path equality treats C:... and \?\C:... as different, so setup saves initialized=true and then fails with "Team workspace changed" even though the workspace has not moved; retries/status/control keep failing on the saved record. Store and compare canonical paths consistently, and cover setup plus reconnect with createWorktree=true on Windows. This follows from the two path-producing code paths; I did not execute the Windows runtime locally.

Comment thread src/owner_chat.rs
let mut temporary = prepare_runtime(parent, &info)?;
#[cfg(windows)]
let mut retry_delay_ms = 10;
loop {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Keep Windows-only retry loops out of non-Windows builds

The only continue in this loop is behind cfg(windows), so on macOS/Linux the loop always breaks or returns on its first iteration. cargo clippy --all-targets -- -D warnings fails with clippy::never_loop here and unused_mut for temporary above it. The new retry loop in agent_automation/store.rs:4212 has the same non-Windows problem. I reproduced both at this head on macOS. Use a platform-specific retry implementation or conditional loop/mutability so the ordinary non-Windows persist path remains warning-free. The inherited PendingBuffer::is_empty warning from #23 is separate.

import {pathToFileURL} from 'node:url';
import test from 'node:test';
import {setTimeout as delay} from 'node:timers/promises';
import {monitorTeams} from './windows-autowork-team-status.mjs';

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Include the helper required by the new agent-client tests

This imports windows-autowork-team-status.mjs, but that file is only added by #21. The declared #22/#23 stack in this branch does not contain it. Running node --test scripts/test-agent-client.mjs fails at module load with ERR_MODULE_NOT_FOUND, so none of the new JavaScript client tests execute. Put the shared helper with its consumers, remove the cross-PR test dependency, or explicitly include #21 in the stack/merge requirements and validate the resulting tree.

.unwrap();
config.memory.dir = Some(root.path().join("metadata").display().to_string());
config.markdown_chat.automation.descriptor_path =
root.path().join("descriptor.json").display().to_string();

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[P2] Make the recovery fixture satisfy the real Unix descriptor boundary

The fixture writes the descriptor directly under the temporary root and later sets only the file to 0600. Its parent is not established as a private directory before the real BrowserCompanionClient is used. Both recovery_lease_prepares_before_passive_health_and_waits_for_real_account_proof and recovery_lease_skips_its_task_while_unrelated_scans_continue fail with 409 "Browser companion descriptor directory must be private to the current user" in macOS CI and in my local run. Create/chmod a private fixture descriptor directory on Unix rather than weakening the production validator, so these tests actually reach and verify recovery commit/lease behavior.

This branch has not been deployed

No deployments
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.

2 participants