Skip to content

Add configurable server timeouts and file-based Claude Code prompt delivery#318

Open
jitendrasinghsankhwar wants to merge 1 commit into
awslabs:mainfrom
jitendrasinghsankhwar:feature/configurable-server-settings
Open

Add configurable server timeouts and file-based Claude Code prompt delivery#318
jitendrasinghsankhwar wants to merge 1 commit into
awslabs:mainfrom
jitendrasinghsankhwar:feature/configurable-server-settings

Conversation

@jitendrasinghsankhwar

Copy link
Copy Markdown

Closes #317

Summary

Add configurable server tuning settings and fix Claude Code command-line length limit.

Changes

Configurable server settings via settings.json

New "server" key in ~/.aws/cli-agent-orchestrator/settings.json:

{
  "server": {
    "mcp_request_timeout": 120,
    "event_bus_max_queue_size": 8192,
    "provider_init_timeout": 90,
    "startup_prompt_handler_timeout": 5
  }
}
Setting Default Description
mcp_request_timeout 30 Seconds for HTTP calls between MCP sidecar and CAO API
event_bus_max_queue_size 1024 Max events buffered per subscriber queue
provider_init_timeout 60 Seconds for any CLI provider to reach IDLE after launch
startup_prompt_handler_timeout 20 Seconds for Claude Code workspace trust dialog handler

All values retain original defaults for backward compatibility.

File-based prompt delivery for Claude Code

Replace inline --append-system-prompt and --mcp-config with file-based equivalents to avoid OS command-line length limits (ref: anthropics/claude-code#3411):

claude --append-system-prompt-file ~/.aws/cli-agent-orchestrator/tmp/{id}.prompt \
       --mcp-config ~/.aws/cli-agent-orchestrator/tmp/{id}.mcp.json

Files Changed

  • services/settings_service.py — new get_server_settings() function
  • cli/commands/launch.py — read MCP timeout from settings
  • services/event_bus.py — read queue size from settings
  • mcp_server/server.py — read MCP timeout from settings via _mcp_timeout()
  • providers/claude_code.py — file-based prompt/MCP config + configurable timeouts
  • providers/*.py (all 9) — use provider_init_timeout from settings
  • docs/settings.md — document new server tuning section
  • test/providers/test_claude_code_unit.py — updated for file-based behavior

Testing

  • Tested with Claude Code (Bedrock) as supervisor + Kiro CLI workers
  • Tested with Copilot CLI (BYOK/self-hosted) workers
  • Verified backward compatibility with no settings.json (uses defaults)
  • Verified file-based prompt delivery with 4KB+ system prompts

@codecov-commenter

codecov-commenter commented Jun 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.59091% with 3 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@5226318). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...rc/cli_agent_orchestrator/providers/copilot_cli.py 66.66% 2 Missing ⚠️
src/cli_agent_orchestrator/providers/kiro_cli.py 85.71% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #318   +/-   ##
=======================================
  Coverage        ?   87.47%           
=======================================
  Files           ?       92           
  Lines           ?    11134           
  Branches        ?        0           
=======================================
  Hits            ?     9739           
  Misses          ?     1395           
  Partials        ?        0           
Flag Coverage Δ
unittests 87.47% <96.59%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces configurable “server tuning” settings (timeouts and queue sizes) loaded from settings.json, and updates the Claude Code provider to avoid OS command-line length limits by writing the system prompt and MCP config to files.

Changes:

  • Add get_server_settings() with defaults and wire it into server/client timeouts and EventBus queue sizing.
  • Update CLI providers to use a configurable provider initialization timeout (replacing hardcoded values).
  • Switch Claude Code prompt/MCP config delivery from inline CLI args to file-based arguments; update unit tests and docs accordingly.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
test/providers/test_claude_code_unit.py Updates expectations/parsing to validate file-based --append-system-prompt-file and --mcp-config.
src/cli_agent_orchestrator/services/settings_service.py Adds get_server_settings() and default values for configurable server tuning.
src/cli_agent_orchestrator/services/event_bus.py Reads EventBus subscriber queue maxsize from server settings.
src/cli_agent_orchestrator/providers/q_cli.py Uses configurable provider init timeout instead of hardcoded shell init timeout.
src/cli_agent_orchestrator/providers/opencode_cli.py Uses configurable provider init timeout.
src/cli_agent_orchestrator/providers/kiro_cli.py Uses configurable provider init timeout (including recovery path).
src/cli_agent_orchestrator/providers/kimi_cli.py Uses configurable provider init timeout.
src/cli_agent_orchestrator/providers/hermes.py Uses configurable provider init timeout.
src/cli_agent_orchestrator/providers/gemini_cli.py Uses configurable provider init timeout.
src/cli_agent_orchestrator/providers/cursor_cli.py Uses configurable provider init timeout.
src/cli_agent_orchestrator/providers/copilot_cli.py Uses configurable provider init timeout for both async and sync shell readiness checks.
src/cli_agent_orchestrator/providers/codex.py Uses configurable provider init timeout.
src/cli_agent_orchestrator/providers/claude_code.py Writes system prompt + MCP config to files and makes startup prompt handler timeout configurable.
src/cli_agent_orchestrator/mcp_server/server.py Uses configurable MCP request timeout for requests to the CAO API.
src/cli_agent_orchestrator/cli/commands/launch.py Uses configurable MCP request timeout for launch-time requests.
docs/settings.md Documents the new server settings section in settings.json.
docs/CAO-LOCAL-GUIDE.html Adds a large HTML guide file (appears machine-local).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +102 to +106
settings = _load()
saved = settings.get("server", {})
result = dict(_SERVER_DEFAULTS)
result.update({k: v for k, v in saved.items() if k in _SERVER_DEFAULTS})
return result
Comment on lines +194 to +198
tmp_dir = Path.home() / ".aws" / "cli-agent-orchestrator" / "tmp"
tmp_dir.mkdir(parents=True, exist_ok=True)
prompt_file = tmp_dir / f"{self.terminal_id}.prompt"
prompt_file.write_text(system_prompt)
command_parts.extend(["--append-system-prompt-file", str(prompt_file)])
Comment on lines +218 to +222
tmp_dir = Path.home() / ".aws" / "cli-agent-orchestrator" / "tmp"
tmp_dir.mkdir(parents=True, exist_ok=True)
mcp_file = tmp_dir / f"{self.terminal_id}.mcp.json"
mcp_file.write_text(json.dumps({"mcpServers": mcp_config}))
command_parts.extend(["--mcp-config", str(mcp_file)])
# shlex.join wraps in single quotes; strip them
if mcp_file_path.startswith("'") and mcp_file_path.endswith("'"):
mcp_file_path = mcp_file_path[1:-1]
mcp_data = json.loads(Path(mcp_file_path).read_text())
mcp_file_path = parts[1].strip().split()[0]
if mcp_file_path.startswith("'") and mcp_file_path.endswith("'"):
mcp_file_path = mcp_file_path[1:-1]
mcp_data = json.loads(Path(mcp_file_path).read_text())
mcp_file_path = parts[1].strip().split()[0]
if mcp_file_path.startswith("'") and mcp_file_path.endswith("'"):
mcp_file_path = mcp_file_path[1:-1]
mcp_data = json.loads(Path(mcp_file_path).read_text())
Comment on lines +54 to +55
if not await wait_for_shell(self.terminal_id, timeout=get_server_settings()["provider_init_timeout"]):
raise TimeoutError("Shell initialization timed out")
Comment thread docs/CAO-LOCAL-GUIDE.html Outdated
Comment on lines +107 to +127
<h2 id="install">Installation (This Machine)</h2>
<pre><code># Installed from local patched clone
uv tool install /Users/JSR34/Repositories/cli-agent-orchestrator --upgrade

# Local clone location
/Users/JSR34/Repositories/cli-agent-orchestrator (branch: local/performance-patches)

# Installed binary location
/Users/JSR34/.local/bin/cao
/Users/JSR34/.local/bin/cao-server
/Users/JSR34/.local/bin/cao-mcp-server

# Data directory
~/.aws/cli-agent-orchestrator/
├── agent-context/ → installed agent profiles (cao install)
├── agent-store/ → custom agent profiles
├── db/ → SQLite database
├── fifos/ → Named pipes for terminal output streaming
├── logs/ → Server logs + terminal scrollback
├── memory/ → Agent memory wiki files
└── settings.json → Configuration</code></pre>
@jitendrasinghsankhwar jitendrasinghsankhwar force-pushed the feature/configurable-server-settings branch from 70cb3f5 to 99633e4 Compare June 20, 2026 02:27
@haofeif haofeif requested a review from Copilot June 20, 2026 13:48
@haofeif

haofeif commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

@call-me-ram mind reviewing this ticket if get a chance ?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 8 comments.

Comment on lines +102 to +106
settings = _load()
saved = settings.get("server", {})
result = dict(_SERVER_DEFAULTS)
result.update({k: v for k, v in saved.items() if k in _SERVER_DEFAULTS})
# Validate types and ranges
logger.info("Set skipDangerousModePermissionPrompt in ~/.claude/settings.json")

def _handle_startup_prompts(self, timeout: float = 20.0) -> None:
def _handle_startup_prompts(self, timeout: float = None) -> None:
Comment on lines 194 to +226
@@ -211,8 +216,14 @@ def _build_claude_command(self) -> str:
env["CAO_TERMINAL_ID"] = self.terminal_id
mcp_config[server_name]["env"] = env

mcp_json = json.dumps({"mcpServers": mcp_config})
command_parts.extend(["--mcp-config", mcp_json])
tmp_dir = Path.home() / ".aws" / "cli-agent-orchestrator" / "tmp"
tmp_dir.mkdir(parents=True, exist_ok=True)
mcp_file = tmp_dir / f"{self.terminal_id}.mcp.json"
mcp_file.write_text(
json.dumps({"mcpServers": mcp_config}), encoding="utf-8"
)
mcp_file.chmod(0o600)
command_parts.extend(["--mcp-config", str(mcp_file)])
Comment on lines 285 to +286
if not shell_ready:
raise TimeoutError("Shell initialization timed out after 30 seconds")
raise TimeoutError("Shell initialization timed out")
Comment on lines 50 to 52
"""Subscribe to a topic pattern (e.g., 'terminal.*.output'). Returns async queue."""
queue: asyncio.Queue = asyncio.Queue(maxsize=EVENT_BUS_MAX_QUEUE_SIZE)
queue: asyncio.Queue = asyncio.Queue(maxsize=get_server_settings()["event_bus_max_queue_size"])

Comment on lines 277 to +278
assert get_extra_skill_dirs() == ["/skills"]
class TestGetServerSettings:
Comment on lines +54 to +56
init_timeout = get_server_settings()["provider_init_timeout"]
if not await wait_for_shell(self.terminal_id, timeout=init_timeout):
raise TimeoutError(f"Shell initialization timed out after {init_timeout}s")
Comment on lines +28 to 33
def _mcp_timeout() -> int:
"""Get MCP request timeout from server settings."""
return get_server_settings()["mcp_request_timeout"]

# Environment variable to enable/disable working_directory parameter
ENABLE_WORKING_DIRECTORY = os.getenv("CAO_ENABLE_WORKING_DIRECTORY", "false").lower() == "true"
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.

Hardcoded timeouts and command-line length limit cause failures with Claude Code and heavy provider configurations

5 participants