The /sandbox status can be 'ok' (with namespace isolation) or 'warn' (in
restricted environments like CI without unshare support). Update the test
to accept either value rather than hard-coding an expectation.
- Update client_integration.rs user-agent assertion to expect version 0.1.5
- Fix output_format_contract.rs /sandbox status expectation from 'warn' to 'ok'
The test explicit_model_provider_hint_controls_runtime_provider_dispatch
was failing when OPENAI_BASE_URL was set in the environment to a non-standard
URL (e.g., api.layofflabs.com). The test expects the OpenAI provider to use
the default base URL (api.openai.com) when no explicit base_url is provided
in the ProviderConfig.
This fix adds an EnvVarGuard struct to the tests module and uses it to
ensure OPENAI_BASE_URL is unset before running the test, preventing
environment pollution from affecting the test result.
Fixes: https://github.com/ultraworkers/claw-code/issues/3345
Co-authored-by: clawdbot <clawdbot@ultraworkers.dev>
- Add SkillOrigin::Bundled variant to support bundled skills registry
- Implement bundled_skill_root() function for discovering bundled skills
- Update skill discovery to include bundled skills from standard install paths
- Create example bundled skills (example-skill, chain-example)
- Add comprehensive tests for bundled skills discovery and metadata
- Bundled skills follow same directory structure as plugins
- Skills can now chain/invoke other skills using standard dispatch mechanisms
- Maintains backward compatibility with existing SkillsDir and LegacyCommandsDir
- Implement OperationRegistry with standard query, control, and event operations
- Add Schema struct for defining input/output schemas
- Add OperationMetadata for rich operation descriptions
- Add Frame methods to extract operation and input from broker requests
- Add comprehensive tests demonstrating the gap and the fix
- Operations can be discovered, validated, and customized
This addresses issue #3321 (Slice 1.2): SDK operation registry & schema validation.
The gap: The original SDK allowed any operation name with no validation.
The fix: A registry-based system that defines valid operations and their schemas.
- Mark SDK wire protocol (Slice 1.1) as implemented (PR #3330)
- Update tool catalog status with read selectors (PR #3332/#3334)
- Add slash commands progress: /tools, /info (PR #3339)
- Document as historical planning reference with current implementation status
- Add PR references and status summary
- All section status notes now reflect merged work as of 2026-10-13
- Resolve .gitignore conflict: include both nix entries and .claude/
- Update AnthropicRuntimeClient::new() test calls to match new signature
- Fix explicit_model_provider_hint test to unset OPENAI_BASE_URL env var
The PermissionMode enum intentionally does not implement PartialOrd
to prevent silent re-ranking of the privilege ladder. Use the explicit
covers() method for privilege comparisons instead of < and >=.
execute_batch already keyed results to original call slots; this makes
that airtight: panicking worker threads resolve to their own index via
a fallback tuple instead of colliding with slot 0, and results are
asserted to follow call order with a regression test that mixes a
workspace-escape read among valid reads at cap=2.
Adds the fan-out bound: parallel-safe calls run in waves of at most
maxParallelToolCalls (default 8, CLAWD_PARALLEL_TOOL_CALLS env, or the
new setting applied via with_max_parallel_tool_calls at runtime build).
Sequential behavior is preserved: allowed_tools checks still run
before dispatch, and ToolSearch stays off the parallel path.
TeamCreate resolves maxConcurrentAgents from the per-team input, then
the maxConcurrentAgents setting, then unlimited (pre-fix behavior).
The cap is persisted in the manifest and registered on a process-wide
gate; agent threads still spawn immediately but block on an RAII slot
before entering their run loop, so manifest/task-claim semantics are
unchanged. TeamDelete forgets the gate so queued agents drain and no
stale team entries accumulate. Includes a gate regression test.
Adds optional positive-integer parsing for the two new fan-out caps
next to subagentModel, in both camelCase and snake_case forms. Zero
parses as unset; non-numeric values are a named config error. Covered
by three regression tests mirroring the subagentModel test style.
Review fixes for PR #3250:
1. Restore workspace-level unsafe_code = "forbid" (was downgraded to
"warn" for TUI support). The per-crate [lints.rust] unsafe_code =
"allow" on rusty-claude-cli already overrides it where needed.
2. Fix TaskClaim TOCTOU race in claim_task(). Replace exists()-then-write
with OpenOptions::create_new(true) which atomically fails if the lock
file already exists, eliminating the race window between the check and
the write.
3. Remove TUI scaffolding deps (ratatui, tui-textarea, gag, crossbeam-channel,
libc, unicode-width) and the /tui slash command spec — these belong in
a future TUI PR and are unused in the current source.
Also updates the provider chain precedence test to reflect the new behavior
where the caller's resolved model is the chain primary.
Co-Authored-By: Claw <noreply@openclaw.ai>
Adds 3 unit tests covering the original silent-drop bug:
- camelCase 'subagentModel' key reads end-to-end
- snake_case 'subagent_model' key reads end-to-end
- blank value returns None (falls back to default model)
Requested by @1716775457damn in PR review.
Restores the fix from @Offwhite-Del that was lost during rebase.
Unknown models now return None so preflight skips the context-window
check and lets the API enforce its own limits.
Port the agent-team enhancement layer onto upstream/main so the model
can spin up coordinated sub-agent teams for parallel work.
subagentModel config wiring (fix):
- Add subagent_model field to RuntimeFeatureConfig + RuntimeConfig::subagent_model()
accessor so the subagentModel setting (already validated by config_validate.rs)
is now actually read and stored.
- Agent tool's resolve_agent_model falls back to subagentModel from config
when no explicit model is passed.
Provider namespace separation:
- New 'custom-openai' provider kind with dedicated env vars
(CLAWCUSTOMOPENAI_API_KEY / CLAWCUSTOMOPENAI_BASE_URL)
- /setup wizard saves kind: 'custom-openai' for option 5
- Bare model name normalized to 'custom/' prefix to avoid proxy 404s
- Sub-agents inherit /setup-saved provider config via inject_config_as_env_fallbacks
Parallel tool execution:
- Override execute_batch to classify read-only tools as parallel-safe
and run them concurrently via std::thread::scope
- Results return in original model order
Team coordination layer:
- AgentMessage, TaskClaim, TeamStatus tools + shared mailbox directory
- Mode presets (tiny/1x ... mega/6x) + enriched TeamCreate/Agent descriptions
- Background team watcher
- /team slash command: on/off/status/toggle
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Explain the provider compatibility behavior that now has executable coverage so future changes preserve routing, custom gateway slugs, diagnostics, and extra-body passthrough semantics.
Constraint: Task 2 requires docs/status evidence while leader owns Ultragoal checkpoints and .omx/ultragoal remains untouched.
Rejected: Add a new CLI status command | broader than the assigned provider compatibility documentation/status surface.
Confidence: high
Scope-risk: narrow
Directive: Keep docs aligned with provider_diagnostics_for_model, MessageRequest::extra_body, and OpenAI-compatible slash-model tests.
Tested: cargo test --manifest-path rust/Cargo.toml -p api custom_openai_gateway_preserves_slash_model_ids_and_extra_body_params; cargo test --manifest-path rust/Cargo.toml -p api provider_diagnostics_explain_openai_compatible_capabilities; cargo check --manifest-path rust/Cargo.toml -p api
Not-tested: Live provider calls requiring external credentials.
Co-authored-by: OmX <omx@local>
The follow-up docs gate needed the parity manifest reference string that the mock parity diff checker requires, so this records the verified map-only repair after leader integration.
Constraint: Task 11 scope allowed only PARITY.md, rust/MOCK_PARITY_HARNESS.md, and docs/g007-plugin-mcp-verification-map.md; only PARITY.md needed a change.
Rejected: Editing harness code or .omx/ultragoal | checks proved the remaining gap was docs-map text only and Ultragoal state is leader-owned.
Confidence: high
Scope-risk: narrow
Directive: Keep auto_compact_triggered parity_refs synchronized with PARITY.md when mock parity scenarios change.
Tested: cd rust && python3 scripts/run_mock_parity_diff.py; python3 scripts/validate_cc2_board.py --board .omx/cc2/board.json; rg -n auto_compact_triggered token_cost_reporting auto_compaction threshold from env G007 Plugin/MCP G007-plugin-mcp 12 scripted scenarios 21 captured PARITY.md rust/MOCK_PARITY_HARNESS.md docs/g007-plugin-mcp-verification-map.md; git diff --check
Not-tested: Full workspace suite; Task 11 was a docs/parity-map follow-up with focused executable map validation.
Co-authored-by: OmX <omx@oh-my-codex.dev>
The CHANGELOG incorrectly listed /status, /cost, and /version as new in v0.1.4.
These commands already existed in previous versions; PR #3333 only attempted to
add duplicate handlers (which was reverted in PR #3336). Remove the false claim.
- Add SlashCommand::Tools and SlashCommand::Info enum variants
- Add SLASH_COMMAND_SPECS entries for both commands
- Implement handlers in both REPL and CLI modes
- /tools lists available CLI tools with descriptions
- /info shows claw-code runtime information (version, git sha, rustc, target)
- Both commands return None from handle_slash_command, delegating to REPL/CLI layer
- Add test coverage for both commands in is_none test
- Implementations leverage existing tool specs and binary provenance infrastructure
The terminal check was removed during merge conflict resolution, causing
the spinner animation to be output to non-TTY streams (like pipes used
in tests), which corrupted the output format and broke the
text_prompt_mode_keeps_streamed_text_when_the_turn_fails test.
Restore the is_terminal() check to only animate when stdout is a real
terminal while keeping the interrupt feature.