Skip to content

feat: Ambient Code Platform session backend#63

Merged
jsell-rh merged 5 commits intojsell-rh:mainfrom
tiwillia:worktree-feature/sessionInterface-ambient
Mar 10, 2026
Merged

feat: Ambient Code Platform session backend#63
jsell-rh merged 5 commits intojsell-rh:mainfrom
tiwillia:worktree-feature/sessionInterface-ambient

Conversation

@tiwillia
Copy link

@tiwillia tiwillia commented Mar 10, 2026

Summary

  • Add AmbientSessionBackend implementing the SessionBackend interface for remote agent sessions via the ACP public API
  • Create ambient-workflow/ with adapted /boss.plan, /boss.check, /boss.ignite commands for ACP sessions (no tmux dependencies, uses BOSS_URL and AGENT_NAME env vars)
  • Wire workflow config into the backend so all spawned ambient sessions automatically get activeWorkflow and environmentVariables set on the K8s CR
  • Add Initial Prompt and Repos fields to the create agent dialog when ambient backend is selected
  • Cascade-delete the backing ACP session when an agent is removed
  • Preserve original agent name casing instead of lowercasing on creation
  • Hide tmux-specific controls (approval prompt, keystroke injection) for ambient-backed agents

Backend changes

File Change
session_backend.go AmbientCreateOpts with WorkflowRef, Repos, EnvVars fields
session_backend_ambient.go Full SessionBackend implementation against ACP public API; CreateSession includes activeWorkflow, environmentVariables, and repos in the request body
server.go Read AMBIENT_WORKFLOW_* and COORDINATOR_EXTERNAL_URL env vars
handlers_agent.go Add repos/task to create request; cascade-delete sessions on agent removal; preserve name casing
lifecycle.go Use resolveAgentName instead of ToLower for agent map keys
deploy/openshift/configmap.yaml Add workflow and coordinator URL env vars

Workflow files (ambient-workflow/)

File Description
.ambient/ambient.json Workflow manifest with system prompt (full protocol, API reference)
.claude/commands/boss.ignite.md Adapted for ACP: $BOSS_URL, $AGENT_NAME env vars, no tmux
.claude/commands/boss.check.md Adapted: $BOSS_URL env var, $AGENT_NAME fallback
.claude/commands/boss.plan.md Copied as-is (no tmux dependencies)
CLAUDE.md Behavioral guidelines for multi-agent coordination

Frontend changes

  • Create agent dialog shows "Initial Prompt" and "Repos" fields when ambient backend is selected (replacing "Working Directory" for tmux)
  • Hide tmux Controls section (approval, keystroke injection) for ambient agents

Test plan

  • go test -race ./internal/coordinator/ passes
  • npm run build succeeds
  • Manual: spawn ambient agent via API, verify activeWorkflow, environmentVariables, and repos appear on the K8s AgenticSession CR
  • Manual: delete agent, verify backing ACP session is also deleted
  • Manual: verify agent names preserve original casing

NOTE

This relies on the changes in ambient-code/platform#855

@tiwillia tiwillia changed the title WIP: Add Ambient Sessiong Backend support WIP: Add Ambient Session Backend support Mar 10, 2026
@tiwillia tiwillia force-pushed the worktree-feature/sessionInterface-ambient branch 3 times, most recently from f29ce33 to f9ffa07 Compare March 10, 2026 03:13
Implement the ambient backend, which manages agent sessions as remote
Kubernetes pods through the Ambient Code Platform public API instead of
local tmux sessions.

Backend implementation (13 SessionBackend methods):
- CreateSession via POST /v1/sessions with default task fallback
- KillSession via DELETE (accepts full 2xx range + 404)
- GetStatus maps ACP session + run status to SessionStatus
- IsIdle/CaptureOutput/SendInput/Interrupt via corresponding endpoints
- CheckApproval/Approve are no-ops (ambient has no terminal prompts)
- DiscoverSessions matches by display_name on running/pending sessions
- Available with 30s TTL cache, SkipTLSVerify for self-signed certs
- waitForRunning polls until async session creation completes

Integration changes:
- Per-agent backend dispatch in liveness, broadcast, check-in, and
  session status (no longer assumes single default backend)
- Skip model switching for non-tmux backends in runAgentCheckIn
- AutoDiscoverAll runs discovery across all available backends
- handleAgentSpawn/Restart/CreateAgents pass backend-specific opts,
  set BackendType on agent records, poll for ambient readiness
- isNonSessionAgent recognizes "ambient" as session-based

Frontend:
- Replace disabled "cloud (soon)" button with active "ambient" selector
- Conditionally show working directory field (tmux only)
- Backend-specific help text in create agent dialog

Deployment:
- AMBIENT_API_URL, AMBIENT_SKIP_TLS_VERIFY in ConfigMap
- AMBIENT_TOKEN via OpenShift Template (ambient-credentials.yaml)
- Deployment references secret; Makefile includes in deploy target
- Ambient auto-selected as default when tmux unavailable (distroless)

Tests: 22 new tests covering all methods, status mapping, caching,
discovery, transcript parsing, and polling via httptest mock server.
Create ambient-workflow/ with adapted boss commands (/boss.plan,
/boss.check, /boss.ignite) for ACP sessions — no tmux dependencies,
uses BOSS_URL and AGENT_NAME env vars. Wire workflow config into
AmbientSessionBackend so all spawned sessions automatically get the
workflow attached with activeWorkflow and environmentVariables in the
ACP API request body.
…sions

- Add Initial Prompt and Repos fields to the create agent dialog when
  ambient backend is selected (replacing Working Directory for tmux)
- Pass repos and task through to AmbientCreateOpts in the backend handler
- Cascade-delete the backing ACP session when an agent is deleted via
  the UI or API
The create agent and spawn handlers were lowercasing agent names before
storing them in the agents map, causing a mismatch with the ambient
backend which received the original cased name. Use resolveAgentName()
instead, which does case-insensitive lookup but preserves original
casing for new entries.
Hide the tmux-specific controls section (approval prompt, keystroke
injection) for agents with backend_type === 'ambient'.
@tiwillia tiwillia force-pushed the worktree-feature/sessionInterface-ambient branch from f9ffa07 to f193bf3 Compare March 10, 2026 12:43
@tiwillia tiwillia changed the title WIP: Add Ambient Session Backend support Add Ambient Session Backend support Mar 10, 2026
@tiwillia tiwillia changed the title Add Ambient Session Backend support feat: Ambient Code Platform session backend Mar 10, 2026
@jsell-rh jsell-rh merged commit 331f612 into jsell-rh:main Mar 10, 2026
1 check passed
@jsell-rh
Copy link
Owner

Review — TASK-052 AmbientSessionBackend (#63)

Overall: Solid implementation. The interface compliance is complete, error handling is consistent, and the 22 httptest-based tests give good coverage. PR is merged and all tests pass clean with -race.


Strengths

Interface implementation is complete and correct

Compile-time checks at the top (var _ SessionBackend = (*AmbientSessionBackend)(nil) etc.) catch any missing methods at build time — good practice.

doRequest helper is clean

Single place for auth headers, Content-Type, and request construction. All methods delegate through it correctly.

KillSession gracefully handles 404

Treating 404 as success is correct — the session is gone either way, which is the goal.

runningOrIdle fallback is safe

Falling back to SessionStatusRunning on any error means the liveness checker won't incorrectly mark a session as idle when we can't reach the runs endpoint.

waitForRunning select pattern is correct

Using time.After(2s) inside select{ctx.Done, ...} properly respects context cancellation during polling. No goroutine leak.

Available() caching is correct

30s TTL with mutex protects the cache correctly. Checking resp.StatusCode < 500 (accepting 4xx as available) is the right heuristic.


Observations (no change needed)

CaptureOutput truncates at 200 chars per message — reasonable payload guard but may complicate debugging. Consider extracting const maxMessageLen = 200 so it's easy to adjust.

DiscoverSessions only surfaces running/pending — correct for live session matching; completed/failed are intentionally excluded.

InsecureSkipVerify nolint comment — appropriate for OpenShift dev clusters with self-signed certs; opt-in via config is the right design.

Tests — 22 httptest mock server tests cover all methods including status mapping, TTL caching, discovery, and polling. Testing through the HTTP layer is the right approach.

Verdict: Approved. No required changes.

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