providers and integrations
why a provider needs both a herdr integration and an orcr integration, what each layer does, and how the driver contract is pinned to herdr's socket methods.
a provider is an agent CLI orcr can run: claude, codex, and more over time. supporting one takes two integration layers, one on each side. orcr requires both because a half-working provider would leave you with statuses stuck at unknown, waits that can never resolve, and logs without transcripts.
the two layers
- herdr's integration: installed with
herdr integration install <provider>. it hooks the provider so herdr can observe it: agent state (working,idle,blocked) and theagent_sessiontranscript pointer. herdr reports a blocked state, sometimes with a free-text message, but no structured reason. - orcr's integration: built into orcr (claude and codex ship first). it is how orcr drives the provider: launch argv (bypass-permissions flags, model and effort mapping), the startup recipe, completion tuning (the named parameters), the graceful-shutdown recipe, the transcript adapter, and
blocked_kindclassification.
a provider is supported only when both are present.
fail fast, no half-modes
agent run -a <provider> fails fast with integration_missing when either layer is absent. the details name which layer or layers are missing and the exact fix: herdr integration install <provider>, or a pointer that the provider is not yet supported by orcr. nothing is spawned.
unmanaged discovery only tracks supported providers; agents of a provider missing either layer are ignored. server status reports per-provider integration state (integrations: {claude: {orcr, herdr}, …}) so the gap is visible, and both server status and --help list the supported provider set. see managed vs unmanaged agents.
degraded no-integration modes are deliberately cut for simplicity. they are on the roadmap, not shipping.
supported set
| provider | orcr integration | herdr integration | supported |
|---|---|---|---|
| claude | built-in (first release) | herdr integration install claude | yes |
| codex | built-in (first release) | herdr integration install codex | yes |
| pi / opencode / … | planned (orcr integration add) | available in herdr | not yet; run fails with the message above |
a test-only mock provider exists for the e2e suite. it runs a scriptable fake agent TUI, writes a claude-format transcript into its own data dir, and is enabled only under ORCR_ALLOW_MOCK_PROVIDER=1. it is not for production use, but it is why every pattern in the cookbook has an end-to-end test.
transcript adapters
the orcr-integration piece behind logs locates and parses the provider's native session files into a common shape (ordered messages, roles, tool calls, token counts where available). two rules keep it honest:
- identity is a gate, not a guess. adapters select transcripts by the pane's
agent_sessionid and the agent'screated_at, never by cwd mtime alone. multiple candidates returntranscript_unavailablewith the candidates indetails, never a silent pick. - freshness. a final response is reported only once the transcript has advanced past the observed completion, bounded by
transcript_freshness_timeout_ms; otherwisetranscript_unavailable.
on each completion only the transcript locator and cursor are recorded. orcr keeps no response copies; reads always come from the native files. a documented limitation follows: if a provider later rotates or deletes its transcript files, historical --last-response fails with transcript_unavailable rather than returning a stale copy. see data and file conventions.
blocked_kind (question, limit, login, unknown) is best-effort classification from herdr's blocked message plus the transcript. detailed per-provider parsing of why an agent is blocked is future work.
the herdr driver contract
the driver's operation set is pinned to named herdr socket methods with fixed shapes, not reverse-engineered at implementation time. an in-code contract table maps every operation orcr uses, and its methods and result types are checked against the installed herdr's live api schema: version drift fails the conformance check. the pinned operations include:
agent.start {name, argv, cwd?, env?, workspace_id?, focus:false}: herdr creates the tab and pane; orcr does not pre-create tabs. the returned workspace, tab, pane, and terminal ids are authoritative and recorded.pane.move(destination forms for park and un-park),pane.close.pane.send-text/pane.send-keys(the two-call input delivery).pane.list/agent.list(status,agent_session,terminal_idreads).workspace.create.- session enumeration: sessions are per-socket, each with its own
socket_path; the driver discovers them viaherdr session list --jsonand fans out over each session's socket for cross-session reads. - notification, and the herdr integration-state read (which method reports whether a provider's integration is installed).
the minimum herdr protocol version is declared and handshake-checked. see architecture for where the driver sits, and durability and recovery for version negotiation.
managed vs unmanaged agents
what orcr creates and fully manages, what it merely tracks from your own herdr sessions, and the exact behavior contract that separates the two.
loops (scheduling model)
durable cron for any command. how a loop owns time, how runs get ids and process groups, and how overlap, timezones, and missed fires are handled.