{"id":51244623,"url":"https://github.com/agentruntimecontrolprotocol/go-sdk","last_synced_at":"2026-06-29T03:03:13.599Z","repository":{"id":356978814,"uuid":"1234794482","full_name":"agentruntimecontrolprotocol/go-sdk","owner":"agentruntimecontrolprotocol","description":"Go reference SDK for ARCP (Agent Runtime Control Protocol).","archived":false,"fork":false,"pushed_at":"2026-06-22T10:25:38.000Z","size":629,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-22T12:18:17.168Z","etag":null,"topics":["agent-protocol","agent-runtime-control-protocol","agents","ai-agents","arcp","durable-execution","go","golang","llm","mcp","sdk","streaming"],"latest_commit_sha":null,"homepage":"https://github.com/agentruntimecontrolprotocol/spec","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/agentruntimecontrolprotocol.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-10T16:45:18.000Z","updated_at":"2026-06-16T21:28:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/agentruntimecontrolprotocol/go-sdk","commit_stats":null,"previous_names":["agentruntimecontrolprotocol/go-sdk"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/agentruntimecontrolprotocol/go-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agentruntimecontrolprotocol%2Fgo-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agentruntimecontrolprotocol%2Fgo-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agentruntimecontrolprotocol%2Fgo-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agentruntimecontrolprotocol%2Fgo-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/agentruntimecontrolprotocol","download_url":"https://codeload.github.com/agentruntimecontrolprotocol/go-sdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agentruntimecontrolprotocol%2Fgo-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34911135,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-protocol","agent-runtime-control-protocol","agents","ai-agents","arcp","durable-execution","go","golang","llm","mcp","sdk","streaming"],"created_at":"2026-06-29T03:03:11.062Z","updated_at":"2026-06-29T03:03:13.589Z","avatar_url":"https://github.com/agentruntimecontrolprotocol.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch3 align=\"center\"\u003eARCP Go SDK\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\u003cstrong\u003eGo SDK for the Agent Runtime Control Protocol (ARCP) — submit, observe, and control long-running agent jobs from Go.\u003c/strong\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/agentruntimecontrolprotocol/go-sdk\"\u003e\u003cimg alt=\"Go reference\" src=\"https://pkg.go.dev/badge/github.com/agentruntimecontrolprotocol/go-sdk.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/agentruntimecontrolprotocol/go-sdk/actions/workflows/test.yml\"\u003e\u003cimg alt=\"CI\" src=\"https://github.com/agentruntimecontrolprotocol/go-sdk/actions/workflows/test.yml/badge.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/agentruntimecontrolprotocol/go-sdk\"\u003e\u003cimg alt=\"codecov\" src=\"https://codecov.io/gh/agentruntimecontrolprotocol/go-sdk/graph/badge.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/agentruntimecontrolprotocol/go-sdk\"\u003e\u003cimg alt=\"Go report card\" src=\"https://goreportcard.com/badge/github.com/agentruntimecontrolprotocol/go-sdk\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/agentruntimecontrolprotocol/spec/blob/main/docs/draft-arcp-1.1.md\"\u003e\u003cimg alt=\"ARCP\" src=\"https://img.shields.io/badge/ARCP-v1.1%20draft-blue\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-Apache--2.0-lightgrey\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/agentruntimecontrolprotocol/spec/blob/main/docs/draft-arcp-1.1.md\"\u003eSpecification\u003c/a\u003e ·\n  \u003ca href=\"#concepts\"\u003eConcepts\u003c/a\u003e ·\n  \u003ca href=\"#installation\"\u003eInstall\u003c/a\u003e ·\n  \u003ca href=\"#quick-start\"\u003eQuick start\u003c/a\u003e ·\n  \u003ca href=\"docs/\"\u003eGuides\u003c/a\u003e ·\n  \u003ca href=\"https://pkg.go.dev/github.com/agentruntimecontrolprotocol/go-sdk\"\u003eAPI reference\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n`github.com/agentruntimecontrolprotocol/go-sdk` is the Go reference implementation of [ARCP](https://github.com/agentruntimecontrolprotocol/spec/blob/main/docs/draft-arcp-1.1.md), the Agent Runtime Control Protocol. It covers both sides of the wire — the `client` package for submitting and observing jobs, the `server` package for hosting agents — along with WebSocket, stdio, and in-memory transports, OTel and HTTP-router middleware, and the `arcp` CLI, so either side can talk to any conformant peer in any language without hand-rolling the envelope, sequencing, or lease handling.\n\nARCP itself is a transport-agnostic wire protocol for long-running AI agent jobs. It owns the parts of agent infrastructure that don't change between products — sessions, durable event streams, capability leases, budgets, resume — and stays out of the parts that do. ARCP wraps the agent function; it does not define how agents are built, how tools are exposed (that's MCP), or how telemetry is exported (that's OpenTelemetry).\n\n## Installation\n\nRequires Go 1.25 or newer (matching the `go` directive in `go.mod`). The module is fetched by the Go toolchain on first build; no separate install step is required.\n\n```sh\ngo get github.com/agentruntimecontrolprotocol/go-sdk@latest\n```\n\nThe CLI binary lives under `cmd/arcp` and is installable on its own with `go install github.com/agentruntimecontrolprotocol/go-sdk/cmd/arcp@latest`. Optional host integrations ship as sub-packages: `middleware/nethttp`, `middleware/chi`, and `middleware/otel`.\n\n## Quick start\n\nConnect to a runtime, submit a job, stream its events to completion:\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"encoding/json\"\n    \"fmt\"\n    \"log\"\n    \"os\"\n    \"time\"\n\n    \"github.com/agentruntimecontrolprotocol/go-sdk/client\"\n    \"github.com/agentruntimecontrolprotocol/go-sdk/transport\"\n)\n\nfunc main() {\n    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n    defer cancel()\n\n    t, err := transport.DialWebSocket(ctx, \"wss://runtime.example.com/arcp\", transport.WebSocketOptions{})\n    if err != nil {\n        log.Fatal(err)\n    }\n    cli, err := client.Connect(ctx, t, client.Options{Token: os.Getenv(\"ARCP_TOKEN\")})\n    if err != nil {\n        log.Fatal(err)\n    }\n    defer cli.Close(ctx)\n\n    h, err := cli.Submit(ctx, client.SubmitRequest{\n        Agent: \"data-analyzer\",\n        Input: map[string]any{\"dataset\": \"s3://example/sales.csv\"},\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n    go func() {\n        for ev := range h.Events() {\n            fmt.Printf(\"[%s] %s\\n\", ev.Kind, string(ev.Body))\n        }\n    }()\n    res, err := h.Wait(ctx)\n    if err != nil {\n        log.Fatal(err)\n    }\n    out, _ := json.Marshal(res.Output)\n    log.Println(\"final:\", res.FinalStatus, string(out))\n}\n```\n\nThis is the whole shape of the SDK: open a session, submit work, consume an ordered event stream, get a terminal result or error. Everything below is detail on those four moves.\n\n## Concepts\n\nARCP organizes everything around four concerns — **identity**, **durability**, **authority**, and **observability** — expressed through five core objects:\n\n- **Session** — a connection between a client and a runtime. A session carries identity (a bearer token), negotiates a feature set in a `hello`/`welcome` handshake, and is *resumable*: if the transport drops, you reconnect with a resume token and the runtime replays buffered events. Jobs outlive the session that started them. See [§6](https://github.com/agentruntimecontrolprotocol/spec/blob/main/docs/draft-arcp-1.1.md).\n- **Job** — one unit of agent work submitted into a session. A job has an identity, an optional idempotency key, a resolved agent version, and a lifecycle that ends in exactly one terminal state: `success`, `error`, `cancelled`, or `timed_out`. See [§7](https://github.com/agentruntimecontrolprotocol/spec/blob/main/docs/draft-arcp-1.1.md).\n- **Event** — the ordered, session-scoped stream a job emits: logs, thoughts, tool calls and results, status, metrics, artifact references, progress, and streamed result chunks. Events carry strictly monotonic sequence numbers so the stream survives reconnects gap-free. See [§8](https://github.com/agentruntimecontrolprotocol/spec/blob/main/docs/draft-arcp-1.1.md).\n- **Lease** — the authority a job runs under, expressed as capability grants (`fs.read`, `fs.write`, `net.fetch`, `tool.call`, `agent.delegate`, `cost.budget`, `model.use`). The runtime enforces the lease at every operation boundary; a job can never act outside it. Leases may carry a budget and an expiry, and may be subset and handed to sub-agents via delegation. See [§9](https://github.com/agentruntimecontrolprotocol/spec/blob/main/docs/draft-arcp-1.1.md).\n- **Subscription** — read-only attachment to a job started elsewhere (e.g. a dashboard watching a job a CLI submitted). A subscriber observes the live event stream but cannot cancel or mutate the job. Distinct from *resume*, which continues the original session and carries cancel authority. See [§7.6](https://github.com/agentruntimecontrolprotocol/spec/blob/main/docs/draft-arcp-1.1.md).\n\nThe SDK models each of these as first-class objects; the rest of this README shows how.\n\n## Guides\n\n### Sessions and resume\n\nOpen a session, negotiate features, and reconnect transparently after a transport drop using the resume token — jobs keep running server-side while you're gone.\n\n```go\nctx := context.Background()\nt, err := transport.DialWebSocket(ctx, \"wss://runtime.example.com/arcp\", transport.WebSocketOptions{})\nif err != nil {\n    log.Fatal(err)\n}\ncli, err := client.Connect(ctx, t, client.Options{\n    ClientName:    \"resumable\",\n    ClientVersion: \"1.0.0\",\n    Token:         os.Getenv(\"ARCP_TOKEN\"),\n})\nif err != nil {\n    log.Fatal(err)\n}\ndefer cli.Close(ctx)\n\n// The welcome payload carries the resume token, window, and effective\n// negotiated feature set.\nwelcome := cli.Welcome()\nfmt.Println(\"session:\", cli.SessionID())\nfmt.Println(\"resume window:\", welcome.ResumeWindowSec, \"s\")\nfmt.Println(\"features:\", cli.Features())\n\n// Subscriptions can re-anchor at a known sequence after a drop by setting\n// SubscribeOptions.FromEventSeq, replaying every event with seq greater\n// than that value.\n```\n\nAfter an unexpected drop, dial a fresh transport and present the welcome's resume block back. The runtime mints a new token, reuses the original session id, and replays buffered events with `event_seq \u003e LastEventSeq`:\n\n```go\nprior := messages.ResumeRequest{\n    SessionID:    cli.SessionID(),\n    ResumeToken:  cli.Welcome().ResumeToken,\n    LastEventSeq: cli.HighestSeq(),\n}\nt2, _ := transport.DialWebSocket(ctx, url, transport.WebSocketOptions{})\ncli2, err := client.Connect(ctx, t2, client.Options{\n    Token:  os.Getenv(\"ARCP_TOKEN\"),\n    Resume: \u0026prior,\n})\n```\n\nGraceful `Close` clears the resume state; only unexpected exits are resumable.\n\n### Submitting jobs\n\nSubmit a job with an agent (optionally version-pinned as `name@version`), an input, and an optional lease request, idempotency key, and runtime limit.\n\n```go\nexpires := time.Now().Add(time.Minute)\nh, err := cli.Submit(ctx, client.SubmitRequest{\n    Agent: \"weekly-report@2.1.0\",\n    Input: map[string]string{\"week\": \"2026-W19\"},\n    LeaseRequest: arcp.Lease{\n        arcp.CapNetFetch: {\"s3://reports/**\"},\n    },\n    LeaseConstraints: \u0026messages.LeaseConstraints{ExpiresAt: \u0026expires},\n    IdempotencyKey:   \"weekly-report-2026-W19\",\n    MaxRuntimeSec:    300,\n})\nif err != nil {\n    log.Fatal(err)\n}\n\nfmt.Println(\"job_id =\", h.ID())\nfmt.Println(\"effective lease =\", h.Accepted().Lease)\nfmt.Println(\"resolved agent =\", h.Accepted().Agent)\n```\n\n### Consuming events\n\nIterate the ordered event stream — `log`, `thought`, `tool_call`, `tool_result`, `status`, `metric`, `artifact_ref`, `progress`, `result_chunk` — and optionally acknowledge progress so the runtime can release buffered events early.\n\n```go\ncli, err := client.Connect(ctx, t, client.Options{\n    ClientName:      \"ack-demo\",\n    Token:           os.Getenv(\"ARCP_TOKEN\"),\n    AutoAckWindow:   32,                      // coalesced session.ack\n    AutoAckInterval: 250 * time.Millisecond,\n})\nif err != nil {\n    log.Fatal(err)\n}\ndefer cli.Close(ctx)\n\nh, err := cli.Submit(ctx, client.SubmitRequest{Agent: \"noisy\"})\nif err != nil {\n    log.Fatal(err)\n}\n\nfor ev := range h.Events() {\n    switch ev.Kind {\n    case messages.KindLog:\n        var b messages.LogBody\n        _ = json.Unmarshal(ev.Body, \u0026b)\n        fmt.Println(b.Level, b.Message)\n    case messages.KindToolCall:\n        fmt.Println(\"→ tool\", string(ev.Body))\n    case messages.KindMetric:\n        fmt.Println(\"metric\", string(ev.Body))\n    case messages.KindProgress:\n        fmt.Println(\"progress\", string(ev.Body))\n    }\n    // Or ack manually: _ = cli.Ack(ctx, lastSeq)\n}\n```\n\n### Leases and budgets\n\nRequest capabilities, a budget, and an expiry; read budget-remaining metrics as they arrive; handle the runtime's enforcement decisions.\n\n```go\nexpires := time.Now().Add(10 * time.Minute)\nh, err := cli.Submit(ctx, client.SubmitRequest{\n    Agent: \"web-research\",\n    Input: map[string]any{\"iterations\": 8, \"perCallUSD\": 0.3},\n    LeaseRequest: arcp.Lease{\n        arcp.CapToolCall:   {\"search.*\", \"fetch.*\"},\n        arcp.CapCostBudget: {\"USD:1.00\"},\n    },\n    LeaseConstraints: \u0026messages.LeaseConstraints{ExpiresAt: \u0026expires},\n})\nif err != nil {\n    log.Fatal(err)\n}\n\nfmt.Println(\"initial budget =\", h.Accepted().Budget)\n\ngo func() {\n    for ev := range h.Events() {\n        if ev.Kind != messages.KindMetric {\n            continue\n        }\n        var m messages.MetricBody\n        if err := json.Unmarshal(ev.Body, \u0026m); err != nil {\n            continue\n        }\n        if m.Name == \"cost.budget.remaining\" {\n            fmt.Printf(\"budget remaining: %.2f %s\\n\", m.Value, m.Unit)\n        }\n    }\n}()\n\nif _, err := h.Wait(ctx); err != nil {\n    // BUDGET_EXHAUSTED or LEASE_EXPIRED is never retryable.\n    log.Println(\"job ended:\", err)\n}\n```\n\n### Subscribing to jobs\n\nAttach read-only to a job submitted elsewhere and observe its live stream (with optional history replay) without cancel authority.\n\n```go\nobserver, err := client.Connect(ctx, t, client.Options{\n    ClientName: \"dashboard\",\n    Token:      os.Getenv(\"ARCP_TOKEN\"),\n})\nif err != nil {\n    log.Fatal(err)\n}\ndefer observer.Close(ctx)\n\nlist, err := observer.ListJobs(ctx, client.ListJobsRequest{\n    Filter: messages.ListJobsFilter{Status: []string{\"running\"}},\n})\nif err != nil {\n    log.Fatal(err)\n}\n\nsub, err := observer.Subscribe(ctx, list.Jobs[0].JobID, client.SubscribeOptions{History: true})\nif err != nil {\n    log.Fatal(err)\n}\nfmt.Printf(\"subscribed job=%s status=%s agent=%s\\n\", sub.JobID(), sub.CurrentStatus(), sub.Agent())\n\nfor ev := range sub.Events() {\n    fmt.Printf(\"[%s] %s\\n\", ev.Kind, string(ev.Body))\n}\n_ = sub.Close(ctx)\n```\n\n### Error handling\n\nCatch the typed error taxonomy and respect the `retryable` flag — `LEASE_EXPIRED` and `BUDGET_EXHAUSTED` are never retryable; a naive retry fails identically.\n\n```go\nh, err := cli.Submit(ctx, client.SubmitRequest{Agent: \"flaky\"})\nif err != nil {\n    log.Fatal(err)\n}\nif _, err := h.Wait(ctx); err != nil {\n    var arcpErr *arcp.Error\n    if errors.As(err, \u0026arcpErr) {\n        switch arcpErr.Code {\n        case arcp.CodeLeaseExpired, arcp.CodeBudgetExhausted:\n            // Resubmit with a fresh lease / budget; never retry as-is.\n            log.Fatalf(\"terminal: %s\", arcpErr.Code)\n        }\n        if arcp.IsRetryable(err) {\n            // Safe to retry with backoff (e.g. INTERNAL_ERROR, HEARTBEAT_LOST).\n        }\n    }\n    log.Fatal(err)\n}\n```\n\n## Feature support\n\nARCP features this SDK negotiates during the `hello`/`welcome` handshake:\n\n| Feature flag | Status |\n|---|---|\n| `heartbeat` | Supported |\n| `ack` | Supported |\n| `list_jobs` | Supported |\n| `subscribe` | Supported |\n| `lease_expires_at` | Supported |\n| `cost.budget` | Supported |\n| `model.use` | Supported |\n| `provisioned_credentials` | Supported |\n| `progress` | Supported |\n| `result_chunk` | Supported |\n| `agent_versions` | Supported |\n\n## Transport\n\nARCP is transport-agnostic. This SDK ships a WebSocket transport (default), an NDJSON-over-stdio transport for in-process child runtimes, and an in-memory transport for tests and same-process embedders. WebSocket is the default for networked runtimes; stdio is used for in-process child runtimes. Select one by constructing the corresponding `transport.Transport` (`transport.DialWebSocket(ctx, url, opts)`, `transport.NewStdioTransport(in, out)`, or `transport.NewMemoryPair()`) and passing it to `client.Connect(ctx, t, opts)`. Host integration: `middleware/nethttp.NewHandler(srv, opts)` builds an `http.Handler` you can mount on an `*http.Server` or `http.ServeMux`; `middleware/chi.Mount(router, srv, opts)` attaches the same handler to a `chi.Router`.\n\n## API reference\n\nFull API reference — every type, method, and event payload — is in [`docs/`](docs/) and at \u003chttps://pkg.go.dev/github.com/agentruntimecontrolprotocol/go-sdk\u003e.\n\n## Versioning and compatibility\n\nThis SDK speaks **ARCP v1.1 (draft)**. The SDK follows semantic versioning independently of the protocol; the protocol version it negotiates is shown above and in `session.hello`. A runtime advertising a different ARCP MAJOR is not guaranteed compatible. Feature mismatches degrade gracefully: the effective feature set is the intersection of what the client and runtime advertise, and the SDK will not use a feature outside it.\n\n## Contributing\n\nSee [`CONTRIBUTING.md`](CONTRIBUTING.md). Protocol questions and proposed changes belong in the [spec repository](https://github.com/agentruntimecontrolprotocol/spec); SDK bugs and feature requests belong here.\n\n## License\n\nApache-2.0 — see [`LICENSE`](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagentruntimecontrolprotocol%2Fgo-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fagentruntimecontrolprotocol%2Fgo-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagentruntimecontrolprotocol%2Fgo-sdk/lists"}