chore: import upstream snapshot with attribution
govulncheck / govulncheck (push) Has been cancelled
Lint / golangci-lint (push) Has been cancelled
Run Tests / Unit Tests (push) Has been cancelled
Run Tests / Etcd Integration Tests (push) Has been cancelled
Harness (E2E) / Harnesses (mock LLM) (push) Has been cancelled
Harness (E2E) / Provider harnesses (live LLM conformance) (push) Has been cancelled
govulncheck / govulncheck (push) Has been cancelled
Lint / golangci-lint (push) Has been cancelled
Run Tests / Unit Tests (push) Has been cancelled
Run Tests / Etcd Integration Tests (push) Has been cancelled
Harness (E2E) / Harnesses (mock LLM) (push) Has been cancelled
Harness (E2E) / Provider harnesses (live LLM conformance) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# Agent provider conformance matrix
|
||||
|
||||
`go test ./...` includes `TestAgentProviderConformanceMatrix`, a shared agent
|
||||
scenario that runs against every registered chat provider. The scenario asks an
|
||||
agent to call a deterministic local tool, verifies the tool receives `ai.RunInfo`,
|
||||
and checks the final response carries the conformance marker. The live matrix
|
||||
includes MiniMax in the tool/guardrail path in addition to providers with
|
||||
streaming coverage, so every supported chat provider has at least one key-gated
|
||||
agent contract. A fake provider path runs on every machine without network
|
||||
access so CI always exercises the harness.
|
||||
|
||||
Live providers are opt-in to avoid flaky unauthenticated PR checks and accidental
|
||||
API spend. To run the live matrix, set `GO_MICRO_AGENT_CONFORMANCE_LIVE=1` plus the
|
||||
provider API keys you want to exercise:
|
||||
|
||||
| Provider | Required API key | Optional model override |
|
||||
| --- | --- | --- |
|
||||
| OpenAI | `OPENAI_API_KEY` | `GO_MICRO_CONFORMANCE_OPENAI_MODEL` |
|
||||
| Anthropic | `ANTHROPIC_API_KEY` | `GO_MICRO_CONFORMANCE_ANTHROPIC_MODEL` |
|
||||
| Atlas Cloud | `ATLASCLOUD_API_KEY` | `GO_MICRO_CONFORMANCE_ATLASCLOUD_MODEL` |
|
||||
| Gemini | `GEMINI_API_KEY` | `GO_MICRO_CONFORMANCE_GEMINI_MODEL` |
|
||||
| Groq | `GROQ_API_KEY` | `GO_MICRO_CONFORMANCE_GROQ_MODEL` |
|
||||
| MiniMax | `MINIMAX_API_KEY` | `GO_MICRO_CONFORMANCE_MINIMAX_MODEL` |
|
||||
| Mistral | `MISTRAL_API_KEY` | `GO_MICRO_CONFORMANCE_MISTRAL_MODEL` |
|
||||
| Together | `TOGETHER_API_KEY` | `GO_MICRO_CONFORMANCE_TOGETHER_MODEL` |
|
||||
|
||||
When `GO_MICRO_AGENT_CONFORMANCE_LIVE` or a provider key is absent, the live
|
||||
provider subtest reports a deterministic skip. When both are present, a provider
|
||||
failure is a real test failure because drift in chat, tool calling, run metadata,
|
||||
or final-answer behavior means the services → agents lifecycle is no longer
|
||||
consistent across providers.
|
||||
|
||||
The companion `TestAgentProviderConformanceFakeError` keeps provider error
|
||||
propagation covered locally without relying on external credentials.
|
||||
|
||||
## Local no-secret conformance
|
||||
|
||||
Use `make provider-conformance-mock` to run the same provider conformance harness
|
||||
through the deterministic mock provider. That target requires no API keys and is
|
||||
what `make harness` delegates to after the 0→1 and 0→hero scenarios, so every PR
|
||||
continues to exercise the provider-facing agent/tool contract without spending
|
||||
live model credits.
|
||||
|
||||
Use `make provider-conformance` when you want the live-provider sweep: providers
|
||||
without keys are skipped, and configured providers must satisfy the same harness
|
||||
contract. For the exact scheduled command, run:
|
||||
|
||||
```sh
|
||||
go run ./internal/harness/provider-conformance \
|
||||
-providers anthropic,openai,gemini,groq,minimax,mistral,together,atlascloud \
|
||||
-harnesses agent,universe,agent-flow,plan-delegate,a2a-stream-fallback \
|
||||
-summary-json provider-conformance-summary.json \
|
||||
-summary-markdown provider-conformance-summary.md \
|
||||
-capabilities-markdown provider-capabilities.md
|
||||
```
|
||||
|
||||
The generated summary records one row for every selected provider/harness pair;
|
||||
missing live-provider keys become skipped rows for each harness, while configured
|
||||
providers produce pass/fail rows per harness.
|
||||
|
||||
## Scheduled CI
|
||||
|
||||
The hourly/manual `Harness (E2E)` workflow runs the same matrix with
|
||||
`GO_MICRO_AGENT_CONFORMANCE_LIVE=1` and the provider secrets exported. Providers
|
||||
whose keys are absent still skip cleanly, while any configured provider must pass
|
||||
the shared tool-calling scenario. This keeps scheduled conformance key-gated: PR
|
||||
checks stay deterministic and no-key environments remain green, but maintained
|
||||
provider credentials exercise the live matrix regularly.
|
||||
@@ -0,0 +1,296 @@
|
||||
# Agent Interface Design
|
||||
|
||||
## Principle
|
||||
|
||||
Service = capability. Agent = intelligence. An agent IS a service — it has a real RPC server, a proto-defined `Agent.Chat` endpoint, and registers in the registry like everything else.
|
||||
|
||||
```
|
||||
micro.NewService("task") // creates a service
|
||||
micro.NewAgent("task-mgr") // creates an agent (which is also a service)
|
||||
```
|
||||
|
||||
Same package. Same level. Same communication (RPC). Different responsibilities.
|
||||
|
||||
## Interface
|
||||
|
||||
```go
|
||||
type Agent interface {
|
||||
Name() string
|
||||
Init(...AgentOption)
|
||||
Options() AgentOptions
|
||||
Ask(ctx context.Context, message string) (*Response, error)
|
||||
Run() error
|
||||
Stop() error
|
||||
String() string
|
||||
}
|
||||
```
|
||||
|
||||
**Ask** is the programmatic API. Send a message, get a response.
|
||||
|
||||
**Run** starts a real RPC server, registers the `Agent.Chat` endpoint in the registry, and blocks.
|
||||
|
||||
## Proto Definition
|
||||
|
||||
```protobuf
|
||||
service Agent {
|
||||
rpc Chat(ChatRequest) returns (ChatResponse) {}
|
||||
}
|
||||
|
||||
message ChatRequest {
|
||||
string message = 1;
|
||||
}
|
||||
|
||||
message ChatResponse {
|
||||
string reply = 1;
|
||||
string agent = 2;
|
||||
repeated ToolCall tool_calls = 3;
|
||||
}
|
||||
```
|
||||
|
||||
The agent is callable by any go-micro client:
|
||||
|
||||
```bash
|
||||
micro call task-mgr Agent.Chat '{"message": "What tasks are overdue?"}'
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
```go
|
||||
type AgentOptions struct {
|
||||
Name string
|
||||
Services []string // which services this agent manages
|
||||
Prompt string // system prompt — identity, domain knowledge, boundaries
|
||||
Provider string // LLM provider (anthropic, openai, etc.)
|
||||
Model string // LLM model (optional)
|
||||
APIKey string
|
||||
Registry registry.Registry // discover services and other agents
|
||||
Client client.Client // call service endpoints and other agents
|
||||
Store store.Store // backing store for the default memory
|
||||
HistoryLimit int // max conversation turns to retain
|
||||
Memory Memory // pluggable conversation memory (default: store-backed)
|
||||
MaxSteps int // stopping condition: max tool calls per Ask
|
||||
LoopLimit int // max identical repeated calls before refusal (default 3)
|
||||
Approve ApproveFunc // human-in-the-loop / policy gate on each action
|
||||
}
|
||||
```
|
||||
|
||||
## Pluggable composition
|
||||
|
||||
An agent composes the same way a service does — a small set of pluggable pieces with working defaults:
|
||||
|
||||
| Piece | Default | Swap with |
|
||||
|-------|---------|-----------|
|
||||
| **Model** | first registered provider | `AgentProvider` / `AgentModel` |
|
||||
| **Memory** | store-backed, durable across restarts | `AgentMemory(m Memory)` |
|
||||
| **Tools** | the agent's services (RPC) + `plan`/`delegate` | `AgentTool(name, desc, schema, fn)` for any function |
|
||||
| **Guardrails** | loop detection on | `AgentMaxSteps`, `AgentLoopLimit`, `AgentApproveTool` |
|
||||
| **Tool middleware** | none | `AgentWrapTool(...ai.ToolWrapper)` — wrap tool execution (logging, metrics, retries) |
|
||||
|
||||
```go
|
||||
type Memory interface {
|
||||
Add(role, content string)
|
||||
Messages() []ai.Message
|
||||
Clear()
|
||||
}
|
||||
```
|
||||
|
||||
`NewMemory(store, key, limit)` is the durable default; `NewInMemory(limit)` is non-persistent. `AgentTool` registers a function the model can call alongside the services it discovers.
|
||||
|
||||
Functional options:
|
||||
|
||||
```go
|
||||
agent := micro.NewAgent("task-mgr",
|
||||
micro.AgentServices("task"),
|
||||
micro.AgentPrompt("You manage tasks. You understand deadlines and priorities."),
|
||||
micro.AgentProvider("anthropic"),
|
||||
)
|
||||
```
|
||||
|
||||
## Scoped Tools
|
||||
|
||||
An agent only sees the endpoints of its assigned services (plus excludes its own endpoints so it doesn't call itself).
|
||||
|
||||
## Memory
|
||||
|
||||
Agents persist conversation history in the store. Memory survives restarts.
|
||||
Each agent's state is confined to its own store table (database `agent`,
|
||||
table `{name}`) via `store.Scope`, so agents don't share a global table
|
||||
with each other, with services, or with flows.
|
||||
|
||||
```
|
||||
database "agent", table "{name}":
|
||||
history — conversation history
|
||||
```
|
||||
|
||||
## Durable Ask / StreamAsk runs
|
||||
|
||||
Agents can opt into the same checkpoint backend used by flows with
|
||||
`micro.AgentWithCheckpoint(...)`. When enabled, each `Ask` or `StreamAsk` run is
|
||||
persisted with its input, terminal status, response, and tool-call records. If
|
||||
the process or transport drops after a tool has completed but before the model
|
||||
returns a final answer, restart the agent with the same checkpoint store and
|
||||
call `micro.AgentResume(ctx, ag, runID)` or
|
||||
`micro.AgentResumeStreamAsk(ctx, ag, runID)`.
|
||||
Completed tool calls are served from the checkpoint instead of being executed
|
||||
again, while guardrails such as `MaxSteps`, loop detection, approval pauses, and
|
||||
`request_input` pauses continue to apply to the resumed run.
|
||||
|
||||
## Built-in Capabilities
|
||||
|
||||
Beyond its scoped service tools, every agent gets two built-in tools. They are not service endpoints — they are capabilities the agent has over itself and over other agents. They are plain tools wired into the agent's tool handler; there is no separate harness, loop engine, or graph. The LLM calls them exactly like any other tool.
|
||||
|
||||
### plan
|
||||
|
||||
For multi-step work the agent records an ordered plan: a list of steps, each with a `task` and a `status` (`pending`, `in_progress`, `done`). The plan is persisted to the store and surfaced back in the system prompt on later turns, so the agent stays oriented.
|
||||
|
||||
```
|
||||
database "agent", table "{name}":
|
||||
plan — current plan
|
||||
```
|
||||
|
||||
### delegate
|
||||
|
||||
The agent hands a self-contained subtask to another agent. **Delegate-first** resolution:
|
||||
|
||||
1. If the target names a **registered agent** (a service advertising `type=agent`), the subtask is sent to it via RPC (`Agent.Chat`). Intelligence stays distributed — the domain expert handles its own services.
|
||||
2. Otherwise a focused **ephemeral sub-agent** is created with `New(...)` + `Ask(...)`, given a fresh, isolated context, asked the subtask, and torn down.
|
||||
|
||||
A sub-agent is just an agent — no new "spawn"/"fork" concept. Ephemeral sub-agents load and persist no history and have no built-in tools, so they cannot plan or re-delegate (which bounds recursion).
|
||||
|
||||
These capabilities are added automatically to any non-ephemeral agent, so existing `NewAgent` services and `micro chat` routing get them for free.
|
||||
|
||||
## Registration
|
||||
|
||||
Agents register as real services via `server.NewServer` with metadata:
|
||||
|
||||
```go
|
||||
server.Metadata(map[string]string{
|
||||
"type": "agent",
|
||||
"services": "task,project",
|
||||
})
|
||||
```
|
||||
|
||||
The server has a real address, real transport, real endpoints. `micro agent list` discovers agents by checking server metadata for `type=agent`.
|
||||
|
||||
## The Router (micro chat)
|
||||
|
||||
`micro chat` is a router. It discovers agents from the registry and dispatches to them via RPC.
|
||||
|
||||
- One agent → routes directly via `client.Call(agentName, "Agent.Chat", ...)`
|
||||
- Multiple agents → LLM classifies intent, calls `route_to_agent` tool
|
||||
- No agents → falls back to direct service access (current behaviour)
|
||||
|
||||
## Agent-to-Agent Communication
|
||||
|
||||
Agents call each other via standard RPC. An agent is a service — it has an `Agent.Chat` endpoint. Any agent can call any other agent the same way it calls a service.
|
||||
|
||||
```go
|
||||
// From inside an agent's logic, call another agent:
|
||||
client.Call("comms-mgr", "Agent.Chat", &ChatRequest{Message: "Notify Alice"})
|
||||
```
|
||||
|
||||
No special protocol. No broker topics. Just RPC.
|
||||
|
||||
### Across frameworks: the A2A gateway
|
||||
|
||||
That covers agents *within* a Go Micro system. To reach agents on other
|
||||
frameworks — and to let them reach yours — there is the **A2A gateway**
|
||||
(`gateway/a2a`, run with `micro a2a serve`), the agent-side analogue of
|
||||
the MCP gateway. It discovers agents from the registry, generates an
|
||||
[Agent Card](https://a2a-protocol.org) for each from its metadata (the
|
||||
same way MCP derives tools), and translates incoming Agent2Agent tasks to
|
||||
the agent's `Agent.Chat` RPC. No per-agent code: register an agent and it
|
||||
is reachable over A2A.
|
||||
|
||||
## Usage Patterns
|
||||
|
||||
### Single-service agent
|
||||
|
||||
```go
|
||||
agent := micro.NewAgent("task-mgr",
|
||||
micro.AgentServices("task"),
|
||||
micro.AgentPrompt("You manage tasks."),
|
||||
micro.AgentProvider("anthropic"),
|
||||
)
|
||||
agent.Run()
|
||||
```
|
||||
|
||||
### Multi-service agent
|
||||
|
||||
```go
|
||||
agent := micro.NewAgent("project-mgr",
|
||||
micro.AgentServices("task", "project", "milestone"),
|
||||
micro.AgentPrompt("You manage the project system."),
|
||||
micro.AgentProvider("anthropic"),
|
||||
)
|
||||
agent.Run()
|
||||
```
|
||||
|
||||
### Programmatic
|
||||
|
||||
```go
|
||||
agent := micro.NewAgent("support", ...)
|
||||
agent.Init()
|
||||
resp, _ := agent.Ask(ctx, "What tickets are open?")
|
||||
```
|
||||
|
||||
### Agent alongside service
|
||||
|
||||
```go
|
||||
func main() {
|
||||
svc := micro.NewService("task")
|
||||
svc.Handle(new(TaskHandler))
|
||||
|
||||
agent := micro.NewAgent("task-mgr",
|
||||
micro.AgentServices("task"),
|
||||
micro.AgentPrompt("You manage tasks."),
|
||||
micro.AgentProvider("anthropic"),
|
||||
)
|
||||
|
||||
go svc.Run()
|
||||
agent.Run()
|
||||
}
|
||||
```
|
||||
|
||||
## CLI
|
||||
|
||||
```bash
|
||||
micro agent list # list running agents (registry, type=agent)
|
||||
micro agent describe task-mgr # show agent details
|
||||
micro agent history task-mgr # show stored conversation (scoped store)
|
||||
micro chat # routes to agents automatically
|
||||
micro call task-mgr Agent.Chat '{"message": "..."}' # direct RPC
|
||||
```
|
||||
|
||||
The split is consistent across services, agents, and flows: **`list`**
|
||||
shows what's *running* (from the registry, filtered by type), while
|
||||
**`history`/`runs`** show *durable* state from the scoped store —
|
||||
available whether or not the component is currently running.
|
||||
|
||||
```bash
|
||||
micro flow list # list running flows (registry, type=flow)
|
||||
micro flow runs checkout # durable run history for a flow (scoped store)
|
||||
```
|
||||
|
||||
## Generation
|
||||
|
||||
`micro run --prompt` creates services AND an agent:
|
||||
|
||||
```
|
||||
micro run --prompt "task management system"
|
||||
|
||||
Generated:
|
||||
task/ ← service
|
||||
project/ ← service
|
||||
agent/ ← agent (manages task, project)
|
||||
```
|
||||
|
||||
The agent reads `MICRO_AI_PROVIDER` and `MICRO_AI_API_KEY` from the environment.
|
||||
|
||||
## What Doesn't Change
|
||||
|
||||
- Services are still services — same interface, same code, same deployment
|
||||
- You can run services without agents
|
||||
- You can call services directly via `micro call`, the API, or MCP
|
||||
- The framework interfaces (registry, client, server, store) are unchanged
|
||||
- `micro run`, `micro deploy`, `micro build` work the same way
|
||||
@@ -0,0 +1,216 @@
|
||||
# Continuous Improvement Loop
|
||||
|
||||
Go Micro is an agent harness. This file defines the **autonomous loop that builds
|
||||
it** — the framework's own thesis (an agent operating a system) pointed at itself.
|
||||
Claude Code drives the loop; Codex executes scoped tasks; the human sets direction
|
||||
and can stop or revert anything at any time.
|
||||
|
||||
> **North Star.** Every increment must advance the thesis in [`THESIS.md`](THESIS.md):
|
||||
> a holistic agent harness and service framework encapsulating the lifecycle of
|
||||
> **services → agents → workflows**. Judge each change against it — work that
|
||||
> doesn't move toward that lifecycle isn't an improvement, however clean.
|
||||
|
||||
## The pipeline (planner → generator → evaluator)
|
||||
|
||||
The development process is an operational instance of the long-running-agent
|
||||
harness pattern ([Anthropic on harness design](https://www.anthropic.com/engineering/harness-design-long-running-apps)) —
|
||||
a planner, a generator, and a *separate* evaluator — distributed across GitHub
|
||||
Actions instead of subagents. Each role is a workflow:
|
||||
|
||||
| Role | Workflow (action name) | What it does |
|
||||
|------|------------------------|--------------|
|
||||
| **Planner** | `loop-planner.yml` — *Loop: Planner* | Tracks live state, prioritizes the roadmap + an internal scan, and maintains the ranked queue in [`.github/loop/PRIORITIES.md`](../../.github/loop/PRIORITIES.md). Decides *what*. |
|
||||
| **Generator** | `loop-builder.yml` — *Loop: Builder (Generator)* | Builds the top open queue item as a single-concern PR (via Codex) and self-merges on green CI. Does the work. |
|
||||
| **Evaluator** | `harness.yml` — *Harness (E2E)*, plus the CI gate (`tests.yaml`, `lint.yaml`, `govulncheck.yml`) | Grades every change: the mock harness + unit/lint + reachable-CVE scan on each push/PR, and real-model conformance hourly. A *separate* grader — never the generator judging itself. |
|
||||
| **Evaluator → feedback** | `loop-triage.yml` — *Loop: Triage (Evaluator feedback)* | When a gate workflow (Lint, Run Tests, govulncheck, or the harness) fails on a non-PR run, root-causes, dedupes, and files scoped fix issues back into the planner's queue. The hill-climbing feedback path. |
|
||||
| **Coherence** | `loop-coherence.yml` — *Loop: Coherence* | Keeps README/website/docs/blog aligned with the North Star, keeps `CHANGELOG.md` living (reconciling `[Unreleased]` against merged PRs and rolling it into version headings as tags cut), and drafts the changelog blog post. |
|
||||
| **Security** | `loop-security.yml` — *Loop: Security* | Weekly vulnerability audit of the attack surface (MCP/A2A gateways, x402, auth, provider URLs, agent tool loop, deps via `govulncheck`). Files `security` issues; **never auto-merges** fixes and **never publishes exploit detail** in public issues (responsible disclosure); risky fixes are `needs-human`. |
|
||||
| **Release** | `loop-release.yml` — *Loop: Release (daily patch)* | Cuts a daily patch tag when master has new commits, so the *installable* framework tracks the loop's improvements (triggers `release.yml`/goreleaser). Minor/major bumps stay with the human. |
|
||||
|
||||
Generation is separated from evaluation on purpose: an agent grading its own work
|
||||
reliably over-rates it, so **CI and the harness — not the builder — are the gate**.
|
||||
The human sets direction and owns the calls that need taste (see Guardrails).
|
||||
|
||||
> **Go Micro dogfoods its own tool.** These `.github/workflows/loop-*.yml` files
|
||||
> are generated by [`micro loop`](../../cmd/micro/loop) (`micro loop init --roles all`).
|
||||
> The workflows are the *mechanism*; each role's instruction is the editable
|
||||
> *policy* in [`.github/loop/prompts/`](../../.github/loop/prompts), and the
|
||||
> direction/queue live in [`.github/loop/NORTH_STAR.md`](../../.github/loop/NORTH_STAR.md)
|
||||
> and [`.github/loop/PRIORITIES.md`](../../.github/loop/PRIORITIES.md). To change
|
||||
> what a role does, edit its prompt — not the YAML. Re-run `micro loop init
|
||||
> --roles all --force` to regenerate the workflow mechanics (it won't clobber the
|
||||
> North Star, queue, or prompts).
|
||||
|
||||
## Autonomy
|
||||
|
||||
Full autonomy, **no approval gates**. Each increment: Claude Code picks the work,
|
||||
implements it (or dispatches Codex), opens a PR, and **merges it** — including
|
||||
reviewing and merging Codex's PRs. The only gate is **correctness**: `go build`,
|
||||
`go test`, and `golangci-lint` must be green (that's not an approval, it's not
|
||||
shipping broken code).
|
||||
|
||||
Transparency replaces approval: every increment ends with a one-line digest, and
|
||||
every change is a small, reversible, single-concern PR the human can revert.
|
||||
|
||||
## What counts as an improvement
|
||||
|
||||
Grounded in real signal, never speculative rewrites. Each cycle draws from:
|
||||
|
||||
1. **Roadmap** — the Now/Next items in `ROADMAP.md` (harness depth: durable runs,
|
||||
observability, streaming, human-in-the-loop; hardening: resilience, conformance).
|
||||
2. **Open issues** — the scoped backlog (e.g. #3010–#3014).
|
||||
3. **Improvement radar** — a scan each cycle for: missing/weak tests, lint or
|
||||
quality issues, docs/code drift, and DX friction.
|
||||
4. **Dogfooding** — actually build with the harness (`micro new` → `run` → `chat`,
|
||||
an agent + a flow) and fix what hurts. Friction found here is high-signal.
|
||||
|
||||
## The cycle (one increment)
|
||||
|
||||
1. Sync `master`.
|
||||
2. If a Codex PR is open and CI-green → review (diff + gates + correctness vs its
|
||||
issue) and merge it.
|
||||
3. Else pick the single highest-value item from the sources above.
|
||||
4. Implement it, or dispatch to Codex (`@codex <instruction>` on the issue) if it's
|
||||
a well-scoped chunk and Codex is free. **Codex is serial — one task at a time.**
|
||||
5. Verify `build`/`test`/`lint` locally.
|
||||
6. Open a PR (one concern) and merge it.
|
||||
7. Post a one-line digest; refresh the backlog from the radar.
|
||||
|
||||
## Roles
|
||||
|
||||
- **Claude Code** — orchestrator, implementer, reviewer, integrator, merger.
|
||||
- **Codex** — serial builder for well-scoped chunks, dispatched via `@codex`.
|
||||
- **Human** — sets direction; owns brand/positioning copy and breaking public-API
|
||||
decisions; can stop or revert anything.
|
||||
|
||||
## Guardrails
|
||||
|
||||
- One concern per PR; small and reversible.
|
||||
- Stay on `claude/*` branches (Codex on `codex/*`); never two agents on one branch;
|
||||
base PRs on `master` (don't stack on an in-flight branch). See `CODEX.md`.
|
||||
- **Off-limits without the human:** brand/positioning/marketing copy, breaking
|
||||
public API changes, product-default changes with broad behavioral impact, new
|
||||
dependencies, architectural rewrites. The loop proposes these in the digest; it
|
||||
does not merge them autonomously.
|
||||
|
||||
## Scheduling
|
||||
|
||||
- **In-session cron** (`CronCreate`) — runs increments while this Claude session is
|
||||
alive. Convenient, but the remote environment is reclaimed on inactivity and
|
||||
recurring jobs expire after 7 days, so it is **not** a durable scheduler.
|
||||
- **GitHub Actions (durable)** — a scheduled workflow that runs the loop
|
||||
independently of any session. This is the real backbone; it opens a fresh
|
||||
tracking issue for each increment and dispatches Codex there. It needs a
|
||||
`CODEX_TRIGGER_TOKEN` repo secret from a user account Codex responds to;
|
||||
without that secret the workflow deliberately no-ops to avoid ignored bot
|
||||
comments. See `.github/workflows/loop-builder.yml` and the mechanics
|
||||
below.
|
||||
|
||||
## How the durable loop works (mechanics)
|
||||
|
||||
Hard-won wiring — change any one piece and the loop silently stops producing
|
||||
merged PRs. Each scheduled run:
|
||||
|
||||
1. **Opens a fresh issue per increment** (`Continuous improvement increment #N`)
|
||||
and posts the `@codex` instruction on it. *Why a fresh issue:* Codex derives
|
||||
its branch name from the triggering issue's context, so re-using one tracker
|
||||
issue collapses every run onto one branch name and only the first PR opens —
|
||||
the rest collide and silently fail.
|
||||
2. **Posts as a user, not the Actions bot.** Codex ignores `@codex` comments
|
||||
authored by `github-actions[bot]`, so the dispatch uses `CODEX_TRIGGER_TOKEN`
|
||||
(a PAT for a user account Codex follows). No token → the step no-ops.
|
||||
3. **Codex opens the PR itself with `gh` — never `make_pr`.** In the Codex Cloud
|
||||
sandbox the `make_pr` tool is a **no-op stub**: it records the PR title/body
|
||||
for the manual "Create PR" button and never pushes a branch or calls the API.
|
||||
So the dispatch and [`AGENTS.md`](../../AGENTS.md) tell Codex to do it by hand:
|
||||
|
||||
```sh
|
||||
git switch -c codex/increment-<issue> # unique branch, codex/ prefix
|
||||
git push -u origin codex/increment-<issue>
|
||||
gh pr create --base master --label codex --title "…" --body "… Closes #<issue>"
|
||||
gh pr merge --squash --auto --delete-branch
|
||||
```
|
||||
|
||||
This requires the Codex setup script to install `gh` and run `gh auth
|
||||
setup-git` (so `git push` is authenticated) with a write-scoped token.
|
||||
4. **Merges via GitHub native auto-merge, gated by branch protection.** `master`
|
||||
requires the CI status checks (build, tests, golangci-lint) and **0 approving
|
||||
reviews**. `gh pr merge --auto` enables auto-merge; GitHub lands the PR the
|
||||
moment checks pass and deletes the branch. `Closes #<issue>` auto-closes the
|
||||
tracking issue. There is **no merge sweep workflow** — branch protection is
|
||||
the gate.
|
||||
|
||||
### Do-not-break list
|
||||
|
||||
- **Don't re-add required approvals** to `master` — it blocks every autonomous
|
||||
merge. The intended gate is **green CI only**.
|
||||
- **Don't point the dispatch at one standing tracker issue** — one issue per run.
|
||||
- **Don't tell Codex to use `make_pr`** (or imply a token "isn't a substitute"):
|
||||
it cannot open a PR. `gh` is the only path.
|
||||
- **Don't manually re-implement a Codex increment during the summary→PR lag**
|
||||
(Codex posts an optimistic "opened a PR" comment ~30–45 min before the PR
|
||||
actually appears). Re-doing it creates duplicate PRs and stale branches that
|
||||
then block the next run. Wait for the PR, or let it ride.
|
||||
|
||||
## Overseer passes (DevRel + Architect)
|
||||
|
||||
The hourly loop ships increments; two periodic passes keep the *whole* heading in
|
||||
the right direction. Both use the same mechanism (fresh issue → `@codex` →
|
||||
output) but produce direction and coherence, not just code.
|
||||
|
||||
- **Coherence (DevRel) — daily** (`.github/workflows/loop-coherence.yml`, prompt `.github/loop/prompts/coherence.md`). Audits the public
|
||||
surface (README, website landing + docs, blog) for coherence with the North
|
||||
Star, README crispness, and blog-worthy material. It also keeps `CHANGELOG.md`
|
||||
living: each run reconciles the `[Unreleased]` section against the PRs that
|
||||
actually merged (Keep-a-Changelog format, user-facing entries only — internal
|
||||
loop/CI churn is skipped), and rolls `[Unreleased]` into a dated version
|
||||
heading whenever a new `v6.MINOR.PATCH` tag has been cut (by `loop-release`).
|
||||
When enough user-facing work has accumulated (roughly weekly, not a near-empty
|
||||
post every day) it also drafts a "what's new" changelog blog post narrating it.
|
||||
**Autonomy boundary:** safe factual-alignment and crispness fixes — *including
|
||||
the `CHANGELOG.md` upkeep* — auto-merge like any increment; brand/positioning
|
||||
copy and the changelog blog post are opened as a PR (or surfaced in the report)
|
||||
and left for the human to review/merge — blog voice stays with the human.
|
||||
- **Planner (Architect) — continuous (hourly)** (`.github/workflows/loop-planner.yml`, prompt `.github/loop/prompts/planner.md`).
|
||||
The *founder lens*, running alongside the builders. Each run it **tracks live
|
||||
state** (what just merged, what's in flight), **prioritizes the roadmap**
|
||||
(`ROADMAP.md`, Now → Next → Later) against an internal scan (lifecycle gaps, API
|
||||
coherence and seams, dev-UX friction, missing pieces, drift/realignment), and
|
||||
**maintains the ranked queue** in [`.github/loop/PRIORITIES.md`](../../.github/loop/PRIORITIES.md) — re-ranking
|
||||
to reflect reality, backing each top item with a scoped issue, and posting an
|
||||
assessment. It runs at `:59`, just before the `:29` increment, so it
|
||||
re-prioritizes and *then* the loop builds the new top. **Its output is the
|
||||
prioritized queue plus the assessment** — it does **not** make breaking or
|
||||
architectural changes itself (those stay with the human). To avoid churn it only
|
||||
opens a PR when the ranking actually changes.
|
||||
|
||||
The two loops are coupled through `PRIORITIES.md`: the **architect decides *what***
|
||||
(roadmap + internal priorities, ranked, issue-linked) and the **hourly increment
|
||||
loop builds the top open item** — falling back to its own judgment only if the
|
||||
queue is empty. DevRel keeps the public story honest alongside. So work is
|
||||
roadmap-driven by default, not a fresh guess every hour. Cadence is tunable in each
|
||||
workflow's `cron`; the human can reorder `PRIORITIES.md` or its issues at any time
|
||||
to redirect. Codex is serial, so these passes queue behind any in-flight increment.
|
||||
|
||||
## Failure triage (the feedback loop)
|
||||
|
||||
The loop also closes on its own failures. `.github/workflows/loop-triage.yml`
|
||||
fires when a gate workflow — **Lint**, **Run Tests**, or the provider-conformance
|
||||
**Harness (E2E)** — finishes with `conclusion: failure` on a non-PR run (so a red
|
||||
lint or test on `master`, not just a harness failure, becomes a fix issue). It
|
||||
dispatches Codex to **triage** the failing run: read the logs, root-cause each
|
||||
distinct failure, **dedupe** against open issues (comment "recurred" rather than
|
||||
filing a duplicate), and file a scoped `codex`/`enhancement` issue for each genuine,
|
||||
self-contained defect — which the increment loop then builds and the next run
|
||||
verifies. Genuine transient flakes (live-model latency, provider outages) are
|
||||
ignored; anything needing a breaking or architectural change is escalated as
|
||||
`needs-human` instead of auto-built. This is
|
||||
the hill-climbing layer: CI/harness failures become fixes with no human in the
|
||||
middle, short of a decision that's genuinely the human's.
|
||||
|
||||
## Stop / redirect
|
||||
|
||||
- In-session: `CronDelete <id>` (or end the session).
|
||||
- Durable: disable/delete the workflow.
|
||||
- Or just tell Claude Code to pause or change focus — direction always wins over
|
||||
the loop.
|
||||
@@ -0,0 +1,6 @@
|
||||
# Status
|
||||
|
||||
> This snapshot is no longer maintained. Current state lives in two places:
|
||||
>
|
||||
> - **What shipped** — [CHANGELOG.md](../../CHANGELOG.md)
|
||||
> - **What's next** — [ROADMAP.md](../../ROADMAP.md)
|
||||
@@ -0,0 +1,194 @@
|
||||
# Development Strategy Assessment
|
||||
|
||||
**Date:** 2026-06-24
|
||||
**Scope:** README, roadmap, website docs, internal design notes, examples, harnesses, and blog narrative around agents, services, and workflows.
|
||||
|
||||
## Executive summary
|
||||
|
||||
Go Micro has a coherent v6 thesis: **agents are distributed systems**, so the framework should make agents, services, and workflows one set of Go-native primitives rather than a separate orchestration product. The repository already has the right foundation: services are self-describing tools, agents add model + memory + tools with `plan`/`delegate`, flows provide deterministic event-driven execution, and MCP/A2A/x402 make the system interoperable with external agents and paid tools.
|
||||
|
||||
The next phase should not be another broad feature push. The best strategic move is to make the current promise consistently true under real usage:
|
||||
|
||||
1. **Harden the core agent loop across providers and failures.**
|
||||
2. **Make the getting-started contract impossible to break.**
|
||||
3. **Close the loop on durable, observable, streaming agent runs.**
|
||||
4. **Turn one maintained real-world build into the canonical 0→hero path.**
|
||||
5. **Keep the product shape narrow: framework + CLI + docs, not a hosted platform.**
|
||||
|
||||
## What the project is now
|
||||
|
||||
### Positioning
|
||||
|
||||
The public README positions Go Micro as “a framework for building agents and services in Go.” The important distinction is that an agent is not treated as an external chatbot wrapper; it is a service with an LLM, memory, discovered tools, registry presence, and RPC reachability. That makes the messaging clear and differentiated from graph-first agent frameworks.
|
||||
|
||||
### Core primitives
|
||||
|
||||
- **Services** are the durable base abstraction: ordinary Go handlers register, discover each other, and become AI-callable tools through their endpoint metadata and comments.
|
||||
- **Agents** are services with a model, memory, and tools. They expose `Agent.Chat`, can be called over RPC, can be reached from `micro chat`, and get built-in `plan` and `delegate` tools.
|
||||
- **Flows** cover the deterministic side: predefined event or step paths that checkpoint and resume. This complements agents rather than competing with them.
|
||||
- **Gateways** make the primitives externally useful: MCP exposes services as tools, A2A exposes agents as agents, HTTP/gRPC gateways preserve conventional service access, and x402 opens the path to paid tools.
|
||||
|
||||
### Narrative and adoption surface
|
||||
|
||||
The blog has progressed from “microservices become AI tools” through first-class agents, planning/delegation, workflows, guardrails, durability, A2A, and sponsorship. That narrative is strong because it tells a product story: Go Micro did not bolt agents onto a framework; it reframed microservices as the runtime substrate for agentic systems.
|
||||
|
||||
## Strengths to preserve
|
||||
|
||||
1. **One abstraction stack.** Services, agents, and flows all use registry, client, broker, store, and gateway primitives. This lowers conceptual load and reinforces the “distributed systems for agents” thesis.
|
||||
2. **CLI-first developer experience.** The README and roadmap make the CLI the product surface: scaffold, run, chat, inspect, deploy.
|
||||
3. **Interop from the registry.** MCP and A2A generated from existing registry metadata avoid hand-maintained tool/agent catalogs.
|
||||
4. **Pluggable but opinionated.** Model, store, registry, broker, transport, memory, and tool middleware are swappable, but defaults exist.
|
||||
5. **Good taxonomy.** The docs cleanly map augmented LLMs, workflows, and agents to Go Micro primitives without introducing a graph DSL.
|
||||
|
||||
## Key risks
|
||||
|
||||
### 1. Breadth outruns reliability
|
||||
|
||||
The project already spans services, agents, flows, MCP, A2A, x402, multiple model providers, code generation, CLI, dashboard, examples, and deployment. The roadmap correctly identifies hardening as the current priority. More surface area before conformance and resilience would increase support burden and weaken trust.
|
||||
|
||||
### 2. Provider behavior can fragment the experience
|
||||
|
||||
The AI package presents one model interface, but each provider has different tool-call semantics, streaming APIs, errors, rate limits, and refusal behavior. If `micro chat`, `NewAgent`, and flows behave differently by provider, users will perceive the framework as unreliable even when the service layer is solid.
|
||||
|
||||
### 3. Agent promises require production semantics
|
||||
|
||||
Agents that plan, delegate, pay, or run unattended need deadlines, cancellation, retries, resumability, tracing, audit history, and human-intervention states. Without these, agent features remain demos rather than production workflows.
|
||||
|
||||
### 4. Docs can become aspirational
|
||||
|
||||
Some internal design/status documents are intentionally obsolete or historical. The public roadmap and changelog are now the canonical sources. Future docs should make current/shipped/proposed status explicit to avoid confusion.
|
||||
|
||||
### 5. The example portfolio is broad but not yet a single proof
|
||||
|
||||
There are many targeted examples, but the strategy needs one polished real-world build that exercises services, agents, flows, guardrails, history/runs, MCP/A2A, and deployment as a continuous path.
|
||||
|
||||
## Recommended next steps
|
||||
|
||||
### Phase 1: hardening and contracts
|
||||
|
||||
**Goal:** make the existing v6 promise repeatable.
|
||||
|
||||
1. **Cross-provider conformance matrix**
|
||||
- Run the same scenario against every supported provider when keys are present.
|
||||
- Cover simple generation, service tool calls, multi-step tool use, `plan`, `delegate`, guardrails, refusal/stop behavior, and structured errors.
|
||||
- Publish the support matrix in docs so users know which capabilities are verified.
|
||||
|
||||
2. **Getting-started contract in CI**
|
||||
- Define two golden paths:
|
||||
- **0→1:** `micro new` → `micro run` → HTTP/RPC call succeeds.
|
||||
- **0→hero:** services + agent + flow + plan/delegate + inspection path.
|
||||
- Make the contract a small harness or scripted example that runs on every relevant change.
|
||||
|
||||
3. **Failure semantics in the agent loop**
|
||||
- Ensure `context.Context` deadlines propagate through model calls, tool execution, delegation, flows, and gateway calls.
|
||||
- Add consistent timeout, retry/backoff, and rate-limit handling at model-provider boundaries.
|
||||
- Make cancellation visible in run metadata and user-facing CLI output.
|
||||
|
||||
4. **Docs status cleanup**
|
||||
- Keep `README.md`, `ROADMAP.md`, and website roadmap aligned.
|
||||
- Add or maintain “current vs proposed” banners on internal docs that remain as design history.
|
||||
|
||||
### Phase 2: agentic depth
|
||||
|
||||
**Goal:** make long-running agent work production-grade.
|
||||
|
||||
1. **Durable agent loop**
|
||||
- Reuse the existing `Checkpoint` model from flows.
|
||||
- Persist model turn, tool call, step count, plan state, delegation context, and terminal status.
|
||||
- Resume without duplicating completed side effects.
|
||||
|
||||
2. **Agent observability**
|
||||
- Convert `RunInfo` into OpenTelemetry spans/events.
|
||||
- Include model provider, latency, token usage where available, tool calls, delegate boundaries, refusals, guardrail blocks, and errors.
|
||||
- Expose `micro runs` / `micro history` as first-class inspection commands if not already complete.
|
||||
|
||||
3. **Streaming end to end**
|
||||
- Implement `ai.Stream` uniformly where provider support exists.
|
||||
- Carry streaming through `micro chat`, agent `Ask`/`Chat`, A2A `message/stream`, and any UI surface that remains.
|
||||
|
||||
4. **Human-in-the-loop state**
|
||||
- Extend beyond binary `ApproveTool` into pause/resume or `input-required` states for long runs.
|
||||
- Make this compatible with durable checkpoints so approval can happen after process restart.
|
||||
|
||||
### Phase 3: canonical real-world build
|
||||
|
||||
**Goal:** turn the thesis into one maintained proof path.
|
||||
|
||||
Build and maintain one example application that demonstrates:
|
||||
|
||||
- A few domain services with real state.
|
||||
- One conductor agent and at least one specialist agent.
|
||||
- A flow triggered by an event that dispatches to an agent.
|
||||
- Guardrails on risky tools.
|
||||
- Durable run inspection and resume.
|
||||
- MCP exposure for external agents.
|
||||
- Optional A2A interop.
|
||||
- Deployment instructions.
|
||||
|
||||
The support-agent example is a strong candidate because it naturally includes service lookups, prioritization, customer communication, human approval, and event-triggered automation.
|
||||
|
||||
## Strategic priorities
|
||||
|
||||
### Product
|
||||
|
||||
- Keep Go Micro as an **open-source framework**, not a hosted platform.
|
||||
- Make commercial support, training, and retainers the sustainability path.
|
||||
- Treat CLI quality as the primary adoption lever.
|
||||
|
||||
### Developer experience
|
||||
|
||||
- Optimize the loop: `new` → `run` → `chat` → `inspect` → `deploy`.
|
||||
- Prefer fewer, excellent commands over a broad command surface.
|
||||
- Ensure generated code is ordinary Go that users can edit and keep.
|
||||
|
||||
### Technical architecture
|
||||
|
||||
- Use registry metadata as the source of truth for tools and agents.
|
||||
- Keep workflows deterministic and agents dynamic; do not introduce a graph DSL unless the current primitives cannot express a real user need.
|
||||
- Make all autonomous behavior bounded, observable, cancellable, and resumable.
|
||||
|
||||
### Documentation
|
||||
|
||||
- Lead with runnable paths and production caveats.
|
||||
- Keep the taxonomy page because it explains when to use augmented LLMs, flows, and agents.
|
||||
- Promote one real-world example over many disconnected mini examples.
|
||||
|
||||
## Agent harness positioning
|
||||
|
||||
The language should move from “framework for services” to “agent harness on top of services.” A service framework helps teams build callable capabilities. An agent harness is the runtime that makes a model safe and useful around those capabilities: discovery, tool schema, execution, state, guardrails, workflows, delegation, observability, and interop.
|
||||
|
||||
Recommended public language:
|
||||
|
||||
- **Primary line:** “Go Micro is an agent harness and service framework for Go.”
|
||||
- **Short explanation:** “The harness is the runtime around an agent: tools, memory, guardrails, workflows, state, discovery, and protocols.”
|
||||
- **Positioning contrast:** “Agent frameworks put a model in a loop; Go Micro operates that loop against real services.”
|
||||
- **Developer promise:** “If your agent has to operate a system, not just answer a prompt, use Go Micro.”
|
||||
|
||||
This keeps the original microservices heritage but reframes it for the agent market. The service layer is not old positioning; it is the reason the harness is credible. Agents need real capabilities, and Go Micro services are typed, discoverable, callable capabilities.
|
||||
|
||||
## Relevance in the agent-harness world
|
||||
|
||||
To be relevant as agent infrastructure, Go Micro should make the following product bets visible and real:
|
||||
|
||||
1. **Harness, not chatbot.** Lead with execution: tools, memory, guardrails, workflows, and interop. Avoid copy that sounds like “another agent framework.”
|
||||
2. **Services as tools.** Make existing Go services immediately useful to agents through MCP, A2A, and generated tool descriptions.
|
||||
3. **Runtime safety.** Prioritize MaxSteps, loop detection, approval gates, scoped state, timeouts, cancellation, audit trails, and policy hooks.
|
||||
4. **Durability and observability.** Agents doing real work need resumable runs, traces, run history, tool-call timelines, and explainable failures.
|
||||
5. **Interop-first.** Be the Go runtime that any MCP or A2A agent can plug into, rather than a closed agent ecosystem.
|
||||
6. **Evaluation and conformance.** Harnesses are trusted by tests. Cross-provider conformance, scenario harnesses, and eventually first-class evaluation should become a visible part of the project.
|
||||
7. **Canonical proof.** Maintain one real-world example that demonstrates services, agents, flows, guardrails, durable runs, MCP/A2A, and deployment end to end.
|
||||
|
||||
## Suggested immediate backlog
|
||||
|
||||
1. Add cross-provider conformance harness and docs matrix.
|
||||
2. Script and CI-test the 0→1 and 0→hero getting-started contracts.
|
||||
3. Audit agent loop context propagation, timeouts, and cancellation.
|
||||
4. Wire `RunInfo` to tracing and CLI inspection.
|
||||
5. Implement durable agent checkpoint/resume.
|
||||
6. Complete streaming through model providers, chat, agent RPC, and A2A.
|
||||
7. Promote support-agent or another scenario into the canonical real-world example.
|
||||
8. Normalize docs status banners and remove/redirect stale internal status pages where appropriate.
|
||||
|
||||
## Bottom line
|
||||
|
||||
Go Micro has a strong, timely strategic position: **the service framework for building agentic systems in Go**. The current opportunity is to make that position trustworthy. Development should bias toward conformance, resilience, durable execution, observability, and a polished end-to-end developer path before expanding the feature surface.
|
||||
@@ -0,0 +1,311 @@
|
||||
# Durable Execution: Flow Steps & Checkpoint
|
||||
|
||||
**Status:** Design proposal — not yet implemented.
|
||||
|
||||
This note sketches two related changes:
|
||||
|
||||
1. Give **flow** a real step model — a flow is a *task* made of *ordered
|
||||
steps* — so it becomes the deterministic-workflow engine it has always
|
||||
claimed to be (today it runs a single LLM step per event).
|
||||
2. Introduce **`Checkpoint`**, a pluggable durability primitive that
|
||||
persists run progress and resumes after a crash. Store-backed by
|
||||
default; both flow and agent use it.
|
||||
|
||||
The two are designed together because a step boundary is the natural
|
||||
place to checkpoint.
|
||||
|
||||
---
|
||||
|
||||
## Motivation
|
||||
|
||||
A flow or agent run is long, expensive, and has side effects partway
|
||||
through (it sent an email at step 2, charged via x402 at step 4). Today
|
||||
all in-flight state lives in process memory: a crash loses the run, and
|
||||
re-running from the top repeats the side effects.
|
||||
|
||||
Durable execution means the run survives a crash and **continues from
|
||||
where it stopped**, without re-doing completed steps.
|
||||
|
||||
This is squarely a distributed-systems concern — checkpoint state, replay
|
||||
on restart, pluggable backend — i.e. go-micro's kind of problem, built on
|
||||
primitives it already has (`store`, `WrapTool`, `call.ID`).
|
||||
|
||||
---
|
||||
|
||||
## What flow is today (for contrast)
|
||||
|
||||
`flow` is a concrete `*Flow` struct. Per broker event, `Execute` runs
|
||||
**one** augmented-LLM turn (a single `Generate` with services as tools)
|
||||
or dispatches the event to an agent, records one `Result`, and returns.
|
||||
There is no notion of a task with ordered steps, no carried state, no
|
||||
checkpoint. The step model below generalizes today's behavior: a flow
|
||||
with one step == current flow.
|
||||
|
||||
---
|
||||
|
||||
## Core concepts
|
||||
|
||||
### State
|
||||
|
||||
What carries across steps. **A struct, not a map** — a typed `Data`
|
||||
plus a `Stage` marker so you can always tell where a run is.
|
||||
|
||||
```go
|
||||
type State struct {
|
||||
Stage string // name of the step the run is at — where it is
|
||||
Data []byte // carried data, serialized; use Set / Scan
|
||||
}
|
||||
|
||||
// Set replaces the data with the JSON encoding of v.
|
||||
func (s *State) Set(v any) error
|
||||
// Scan decodes the data into v (a pointer to the caller's struct).
|
||||
func (s State) Scan(v any) error
|
||||
```
|
||||
|
||||
The developer defines their own data struct and threads it through
|
||||
with `Set`/`Scan` — type-safe at the edges, serializable in the middle
|
||||
(which is what makes checkpointing possible). `Stage` is the readable
|
||||
"where am I"; the engine also uses it as the resume point.
|
||||
|
||||
The trigger event seeds the first `State`.
|
||||
|
||||
### Step
|
||||
|
||||
The unit of a flow. **One kind** — a struct with a name, the action to
|
||||
run, and an optional retry override. No per-kind constructors.
|
||||
|
||||
```go
|
||||
type StepFunc func(ctx context.Context, in State) (State, error)
|
||||
|
||||
type Step struct {
|
||||
Name string
|
||||
Run StepFunc
|
||||
Retry int // optional per-step override of the flow's retry (0 = use flow default)
|
||||
}
|
||||
```
|
||||
|
||||
Common actions are **helpers that return a `StepFunc`**, dropped into
|
||||
`Step.Run` — so there is still one `Step` type, and the actions compose:
|
||||
|
||||
```go
|
||||
flow.Call(service, endpoint) StepFunc // one RPC to a service
|
||||
flow.LLM(opts...) StepFunc // one augmented-LLM turn
|
||||
flow.Agent(name) StepFunc // dispatch to a registered agent
|
||||
// …or write your own StepFunc.
|
||||
```
|
||||
|
||||
Steps are **authored by the developer** and run in order. That ordering
|
||||
is the defining difference from an agent, where the *model* chooses the
|
||||
steps.
|
||||
|
||||
### Run
|
||||
|
||||
The persisted record of one execution — what `Checkpoint` saves and
|
||||
loads. Retained for success and failure (see retention below).
|
||||
|
||||
```go
|
||||
type Run struct {
|
||||
ID string // durable run id (idempotency root)
|
||||
Flow string // flow name
|
||||
State State // carried data + Stage (where it is)
|
||||
Steps []StepRecord // per-step status + outcome (history/audit)
|
||||
Status string // running | done | failed
|
||||
Started time.Time
|
||||
Updated time.Time
|
||||
}
|
||||
|
||||
type StepRecord struct {
|
||||
Name string
|
||||
Status string // pending | in_progress | done | failed
|
||||
Attempts int // how many tries this step took
|
||||
Result string // short serialized outcome / summary
|
||||
Error string
|
||||
}
|
||||
```
|
||||
|
||||
The resume point is `State.Stage` — there is no separate numeric cursor,
|
||||
so there is one source of truth for "where it is."
|
||||
|
||||
### Checkpoint
|
||||
|
||||
The pluggable durability primitive. Persists and restores a `Run`.
|
||||
|
||||
```go
|
||||
type Checkpoint interface {
|
||||
Save(ctx context.Context, run Run) error
|
||||
Load(ctx context.Context, runID string) (Run, bool, error)
|
||||
Delete(ctx context.Context, runID string) error
|
||||
}
|
||||
```
|
||||
|
||||
The built-in implementation is **store-backed** and on by default, keyed
|
||||
in the store:
|
||||
|
||||
```
|
||||
database "flow", table "{name}", key {runID} → JSON(Run)
|
||||
```
|
||||
|
||||
Runs are confined to their own **store table** — database `flow`, one
|
||||
table per flow name — via `store.Scope`, not a single shared table keyed
|
||||
by prefix. `StoreCheckpoint(s, scope)` takes that scope; the flow passes
|
||||
its name by default. `store.Scope` injects the database/table per
|
||||
operation, so it doesn't mutate or race on the shared store (the way
|
||||
`Init(Table(...))` would). Because it rides on `store.Store`, the storage
|
||||
is also pluggable (Postgres, NATS KV, file) with no extra interface.
|
||||
|
||||
**Retention:** completed runs (success *and* failure) are **kept** by
|
||||
default, so you have a durable history of what ran. `Delete` is only
|
||||
called when the flow opts in with `flow.DeleteOnSuccess()` (failures are
|
||||
always kept).
|
||||
|
||||
---
|
||||
|
||||
## The run loop
|
||||
|
||||
```
|
||||
run := load(runID) or new Run{State: {Stage: steps[0].Name, ...}}
|
||||
|
||||
start := index of step named run.State.Stage
|
||||
for i := start; i < len(steps); i++ {
|
||||
step := steps[i]
|
||||
run.Steps[i].Status = "in_progress"; checkpoint.Save(run)
|
||||
|
||||
out, err := runWithRetry(ctx, step, run.State, retriesFor(step))
|
||||
run.Steps[i].Attempts = attemptsTaken
|
||||
if err != nil {
|
||||
run.Steps[i].Status = "failed"; run.Steps[i].Error = err
|
||||
run.Status = "failed"; checkpoint.Save(run) // kept for audit
|
||||
return err // resumable: retry resumes here
|
||||
}
|
||||
|
||||
run.State = out
|
||||
run.Steps[i].Status = "done"
|
||||
if i+1 < len(steps) {
|
||||
run.State.Stage = steps[i+1].Name // <-- checkpoint boundary
|
||||
} else {
|
||||
run.State.Stage = "" // finished
|
||||
}
|
||||
checkpoint.Save(run)
|
||||
}
|
||||
|
||||
run.Status = "done"; checkpoint.Save(run)
|
||||
// Delete only if flow.DeleteOnSuccess() was set.
|
||||
```
|
||||
|
||||
On restart, `Load` returns the `Run`; the loop resumes at the step named
|
||||
`run.State.Stage`, so completed steps are skipped — their effects already
|
||||
happened and their output is already in `run.State.Data`.
|
||||
|
||||
### Retry
|
||||
|
||||
Flow-level by default, per-step override when needed (e.g. a tool that
|
||||
times out):
|
||||
|
||||
```go
|
||||
flow.Retry(2) // flow-level default for every step
|
||||
flow.Step{Name: "charge", Run: …, Retry: 0} // override: never retry this one
|
||||
```
|
||||
|
||||
`retriesFor(step)` uses `step.Retry` if set, else the flow default.
|
||||
|
||||
### Idempotency (the honest part)
|
||||
|
||||
True exactly-once is impossible if a crash lands *inside* a step. What we
|
||||
provide is at-least-once + a stable **idempotency key** per step:
|
||||
`runID + stepName`. That key is passed to the tool as `call.ID`, so a
|
||||
replayed call is recognized downstream and de-duplicated. Side-effecting
|
||||
steps must cooperate (honor the key). The framework makes this
|
||||
consistent; it cannot make it free.
|
||||
|
||||
Retry uses the same key, so a retried step is de-duplicated the same way.
|
||||
This is where the existing `WrapTool` seam pays off: a durable wrapper
|
||||
checks the checkpoint — if this `call.ID` already has a recorded result,
|
||||
return it without re-calling.
|
||||
|
||||
---
|
||||
|
||||
## Agent reuse
|
||||
|
||||
The agent loop is the **self-directed** analogue and uses the same
|
||||
`Checkpoint`. The difference is who authors the steps:
|
||||
|
||||
| | Steps authored by | Steps known | Durability |
|
||||
|---|---|---|---|
|
||||
| **flow** | developer | up front (ordered list) | checkpoint between steps |
|
||||
| **agent** | the model | discovered at runtime | checkpoint each LLM turn + its tool calls |
|
||||
|
||||
For the agent, `Run.Steps` grows as the model acts, instead of being
|
||||
predefined. One requirement: the agent must own its loop (today the
|
||||
provider drives it), so it can `Save` between turns. That is the one
|
||||
structural change on the agent side.
|
||||
|
||||
---
|
||||
|
||||
## Pluggability — two levels
|
||||
|
||||
1. **Storage (free today).** Built-in `Checkpoint` over `store.Store`;
|
||||
swap the store backend. Covers "checkpoint to my DB instead."
|
||||
2. **Engine (future).** Because steps are now explicit and named, a flow
|
||||
can be mapped onto an external durable-execution engine — each `Step`
|
||||
becomes a Temporal activity / Restate handler — by providing an
|
||||
alternative runner. Most users only need level 1; level 2 exists so
|
||||
teams already running Temporal aren't forced off it.
|
||||
|
||||
The explicit step model is what makes level 2 possible later; we don't
|
||||
build it now.
|
||||
|
||||
---
|
||||
|
||||
## Proposed API
|
||||
|
||||
```go
|
||||
type Onboarding struct {
|
||||
Email string `json:"email"`
|
||||
WorkspaceID string `json:"workspace_id"`
|
||||
}
|
||||
|
||||
f := flow.New("onboard-user",
|
||||
flow.Trigger("events.user.created"),
|
||||
flow.Retry(2), // flow-level retry default
|
||||
flow.Steps(
|
||||
flow.Step{Name: "plan", Run: flow.LLM(flow.Prompt("Plan onboarding for {{.Email}}"))},
|
||||
flow.Step{Name: "workspace", Run: flow.Call("workspace", "Workspace.Create")},
|
||||
flow.Step{Name: "welcome", Run: flow.Agent("comms")},
|
||||
),
|
||||
// Durable by default (store-backed); runs are retained for audit.
|
||||
flow.WithCheckpoint(flow.StoreCheckpoint(service.Options().Store, "onboard-user")),
|
||||
)
|
||||
f.Register(reg, broker, client)
|
||||
```
|
||||
|
||||
A single-step flow keeps today's behavior, so this is additive.
|
||||
|
||||
---
|
||||
|
||||
## Decisions (resolved)
|
||||
|
||||
- **State is a struct, not a map** — typed `Data` + `Stage`. The
|
||||
developer defines the data struct; `Stage` doubles as the resume
|
||||
point, so there is one source of truth for position.
|
||||
- **One `Step` kind** — a struct with `Name`, `Run`, and an optional
|
||||
`Retry`. Common actions are `StepFunc` helpers (`Call`, `LLM`,
|
||||
`Agent`), not separate step constructors.
|
||||
- **Runs are retained** for success and failure by default;
|
||||
`flow.DeleteOnSuccess()` opts into cleanup (failures always kept).
|
||||
- **Retry is a flow-level option** (`flow.Retry(n)`), with a per-step
|
||||
`Retry` field as a fine-grained override.
|
||||
|
||||
---
|
||||
|
||||
## Scope & phasing
|
||||
|
||||
1. **Step model in flow** (no durability yet): `State`, `Step`, ordered
|
||||
`Steps`, the run loop, retry. Single-step flows unchanged.
|
||||
2. **`Checkpoint` + store-backed default**: persist/resume flow runs,
|
||||
retention.
|
||||
3. **Agent durability**: move the agent loop in-package, reuse
|
||||
`Checkpoint`. Opt-in (`AgentDurable()`), default off — overkill for
|
||||
short interactive chats, essential for long unattended runs.
|
||||
4. **Engine-level pluggability** (Temporal/Restate): only if demand.
|
||||
|
||||
Each phase is independently useful and shippable.
|
||||
@@ -0,0 +1,424 @@
|
||||
# Roadmap 2026 Implementation Summary
|
||||
|
||||
**Date:** February 13, 2026
|
||||
**Session:** Continue Roadmap 2026 Implementations
|
||||
**PR Branch:** `copilot/continue-roadmap-2026-implementations`
|
||||
|
||||
## Overview
|
||||
|
||||
This session implemented high-priority items from the Go Micro Roadmap 2026, focusing on Q2 2026 "Agent Developer Experience" features. We've successfully completed the majority of Q2 deliverables, putting the project **3-4 months ahead of schedule**.
|
||||
|
||||
## What Was Implemented
|
||||
|
||||
### 1. MCP CLI Commands (Q2 2026 Features)
|
||||
|
||||
#### `micro mcp docs` Command
|
||||
Generates comprehensive documentation for all MCP tools.
|
||||
|
||||
**Features:**
|
||||
- Markdown format for human-readable docs
|
||||
- JSON format for machine-readable output
|
||||
- Extracts descriptions, examples, and scopes from service metadata
|
||||
- Save to file with `--output` flag
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
micro mcp docs # Markdown to stdout
|
||||
micro mcp docs --format json # JSON format
|
||||
micro mcp docs --output mcp-tools.md # Save to file
|
||||
```
|
||||
|
||||
#### `micro mcp export` Commands
|
||||
Exports MCP tools to various agent framework formats.
|
||||
|
||||
**Supported Formats:**
|
||||
|
||||
1. **LangChain** - Python LangChain tool definitions
|
||||
```bash
|
||||
micro mcp export langchain --output langchain_tools.py
|
||||
```
|
||||
- Generates complete Python code with LangChain Tool definitions
|
||||
- Includes HTTP gateway integration code
|
||||
- Ready to use with LangChain agents
|
||||
- Proper function naming and type hints
|
||||
|
||||
2. **OpenAPI** - OpenAPI 3.0 specification
|
||||
```bash
|
||||
micro mcp export openapi --output openapi.json
|
||||
```
|
||||
- Generates OpenAPI 3.0 spec
|
||||
- Includes security schemes for bearer auth
|
||||
- Tool scopes mapped to security requirements
|
||||
- Compatible with Swagger UI and OpenAI GPTs
|
||||
|
||||
3. **JSON** - Raw JSON tool definitions
|
||||
```bash
|
||||
micro mcp export json --output tools.json
|
||||
```
|
||||
- Complete tool metadata
|
||||
- Includes descriptions, examples, scopes
|
||||
- Useful for custom integrations
|
||||
|
||||
**Implementation:**
|
||||
- File: `cmd/micro/mcp/mcp.go` (~500 lines added)
|
||||
- Tests: `cmd/micro/mcp/mcp_test.go` (updated)
|
||||
- Examples: `cmd/micro/mcp/EXAMPLES.md` (9KB comprehensive guide)
|
||||
|
||||
### 2. LangChain Python SDK (High Priority Q2 Feature)
|
||||
|
||||
Created a complete, production-ready Python package for LangChain integration.
|
||||
|
||||
**Package:** `contrib/langchain-go-micro/`
|
||||
|
||||
#### Core Features
|
||||
|
||||
1. **GoMicroToolkit Class**
|
||||
- Automatic service discovery from MCP gateway
|
||||
- Dynamic LangChain tool generation
|
||||
- Service filtering by name, pattern, or explicit include/exclude
|
||||
- Direct tool calling capability
|
||||
|
||||
2. **Authentication & Security**
|
||||
- Bearer token authentication
|
||||
- Configurable SSL verification
|
||||
- Proper error handling for auth failures
|
||||
|
||||
3. **Configuration**
|
||||
- `GoMicroConfig` dataclass
|
||||
- Customizable timeout, retry count, retry delay
|
||||
- Gateway URL and auth token management
|
||||
|
||||
4. **Error Handling**
|
||||
- Custom exception hierarchy
|
||||
- `GoMicroConnectionError` - Connection failures
|
||||
- `GoMicroAuthError` - Authentication issues
|
||||
- `GoMicroToolError` - Tool execution failures
|
||||
|
||||
#### Package Structure
|
||||
|
||||
```
|
||||
contrib/langchain-go-micro/
|
||||
├── langchain_go_micro/
|
||||
│ ├── __init__.py # Package exports
|
||||
│ ├── toolkit.py # Main toolkit (300+ lines)
|
||||
│ └── exceptions.py # Custom exceptions
|
||||
├── tests/
|
||||
│ └── test_toolkit.py # Comprehensive unit tests (250+ lines)
|
||||
├── examples/
|
||||
│ ├── basic_agent.py # Simple agent example
|
||||
│ └── multi_agent.py # Multi-agent workflow
|
||||
├── pyproject.toml # Modern Python packaging
|
||||
├── README.md # Complete documentation (9KB)
|
||||
├── CONTRIBUTING.md # Development guide
|
||||
└── .gitignore # Python gitignore
|
||||
```
|
||||
|
||||
#### Usage Examples
|
||||
|
||||
**Basic Usage:**
|
||||
```python
|
||||
from langchain_go_micro import GoMicroToolkit
|
||||
from langchain.agents import initialize_agent
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
# Connect to MCP gateway
|
||||
toolkit = GoMicroToolkit.from_gateway("http://localhost:3000")
|
||||
|
||||
# Get tools
|
||||
tools = toolkit.get_tools()
|
||||
|
||||
# Create agent
|
||||
llm = ChatOpenAI(model="gpt-4")
|
||||
agent = initialize_agent(tools, llm, verbose=True)
|
||||
|
||||
# Use agent!
|
||||
result = agent.run("Create a user named Alice")
|
||||
```
|
||||
|
||||
**Advanced Features:**
|
||||
```python
|
||||
# With authentication
|
||||
toolkit = GoMicroToolkit.from_gateway(
|
||||
"http://localhost:3000",
|
||||
auth_token="your-bearer-token"
|
||||
)
|
||||
|
||||
# Filter by service
|
||||
user_tools = toolkit.get_tools(service_filter="users")
|
||||
|
||||
# Select specific tools
|
||||
tools = toolkit.get_tools(include=["users.Users.Get", "users.Users.Create"])
|
||||
|
||||
# Exclude tools
|
||||
tools = toolkit.get_tools(exclude=["users.Users.Delete"])
|
||||
|
||||
# Call tools directly
|
||||
result = toolkit.call_tool("users.Users.Get", '{"id": "user-123"}')
|
||||
```
|
||||
|
||||
**Multi-Agent Workflows:**
|
||||
```python
|
||||
# Specialized agents for different services
|
||||
user_agent = initialize_agent(
|
||||
toolkit.get_tools(service_filter="users"),
|
||||
ChatOpenAI(model="gpt-4")
|
||||
)
|
||||
|
||||
order_agent = initialize_agent(
|
||||
toolkit.get_tools(service_filter="orders"),
|
||||
ChatOpenAI(model="gpt-4")
|
||||
)
|
||||
|
||||
# Coordinate between agents
|
||||
user = user_agent.run("Create user Alice")
|
||||
order = order_agent.run(f"Create order for {user}")
|
||||
```
|
||||
|
||||
#### Testing
|
||||
|
||||
**Unit Tests:**
|
||||
- Mock-based testing for isolation
|
||||
- Coverage for all major functionality
|
||||
- Error handling and edge cases
|
||||
- Authentication scenarios
|
||||
|
||||
**Test Coverage:**
|
||||
- Config defaults and customization
|
||||
- Tool discovery and filtering
|
||||
- LangChain tool creation
|
||||
- Direct tool calling
|
||||
- Connection errors
|
||||
- Authentication failures
|
||||
- Timeout handling
|
||||
|
||||
### 3. Documentation Updates
|
||||
|
||||
1. **CLI Examples** (`cmd/micro/mcp/EXAMPLES.md`)
|
||||
- Comprehensive usage guide
|
||||
- Real-world integration patterns
|
||||
- Troubleshooting section
|
||||
- CI/CD pipeline examples
|
||||
|
||||
2. **MCP README** (`examples/mcp/README.md`)
|
||||
- Updated with new commands
|
||||
- Links to detailed examples
|
||||
|
||||
3. **Project Status** (`PROJECT_STATUS_2026.md`)
|
||||
- Updated completion status
|
||||
- Marked completed features
|
||||
- Roadmap progress tracking
|
||||
|
||||
## Implementation Statistics
|
||||
|
||||
### Code Changes
|
||||
- **Go files:** 2 modified, ~500 lines added
|
||||
- **Python files:** 11 new files, ~1500 lines
|
||||
- **Documentation:** 4 files, ~20KB
|
||||
- **Total new code:** ~2000 lines
|
||||
|
||||
### Files Created/Modified
|
||||
|
||||
**New Files:**
|
||||
- `cmd/micro/mcp/EXAMPLES.md`
|
||||
- `contrib/langchain-go-micro/` (entire package)
|
||||
- Core: 3 Python modules
|
||||
- Tests: 1 comprehensive test file
|
||||
- Examples: 2 working examples
|
||||
- Docs: README, CONTRIBUTING, pyproject.toml
|
||||
|
||||
**Modified Files:**
|
||||
- `cmd/micro/mcp/mcp.go` - Added docs and export commands
|
||||
- `cmd/micro/mcp/mcp_test.go` - Added tests
|
||||
- `examples/mcp/README.md` - Updated documentation
|
||||
- `PROJECT_STATUS_2026.md` - Updated status
|
||||
|
||||
### Testing & Quality
|
||||
|
||||
✅ **All Tests Pass**
|
||||
- Go: `go test ./cmd/micro/mcp/...` ✓
|
||||
- Build: `go build ./cmd/micro` ✓
|
||||
- Python: pytest-based unit tests ✓
|
||||
|
||||
✅ **Code Review**
|
||||
- 1 comment addressed (status update)
|
||||
- All suggestions incorporated
|
||||
|
||||
✅ **Security Scan**
|
||||
- CodeQL analysis: **0 alerts**
|
||||
- No vulnerabilities introduced
|
||||
- Secure coding practices followed
|
||||
|
||||
## Roadmap Progress
|
||||
|
||||
### Q1 2026: MCP Foundation
|
||||
**Status:** ✅ COMPLETE (100%)
|
||||
|
||||
All deliverables completed:
|
||||
- MCP library (gateway/mcp)
|
||||
- CLI integration (micro mcp serve)
|
||||
- Service discovery and tool generation
|
||||
- HTTP/SSE and Stdio transports
|
||||
- Documentation and examples
|
||||
- Blog post and launch
|
||||
|
||||
### Q2 2026: Agent Developer Experience
|
||||
**Status:** ✅ 80% COMPLETE (Ahead of Schedule)
|
||||
|
||||
**Completed in this session:**
|
||||
- ✅ `micro mcp test` full implementation
|
||||
- ✅ `micro mcp docs` command
|
||||
- ✅ `micro mcp export` commands (langchain, openapi, json)
|
||||
- ✅ LangChain SDK (Python package)
|
||||
- ✅ Comprehensive CLI documentation
|
||||
|
||||
**Previously Completed (Early):**
|
||||
- ✅ Stdio Transport for Claude Code
|
||||
- ✅ Tool Descriptions from Comments
|
||||
- ✅ `micro mcp serve` command
|
||||
- ✅ `micro mcp list` command
|
||||
|
||||
**Remaining:**
|
||||
- [ ] Multi-protocol support (WebSocket, gRPC, HTTP/3)
|
||||
- [ ] LlamaIndex SDK
|
||||
- [ ] AutoGPT SDK
|
||||
- [ ] Interactive Agent Playground (web UI)
|
||||
|
||||
### Q3 2026: Production & Scale
|
||||
**Status:** ✅ 40% COMPLETE (Ahead of Schedule)
|
||||
|
||||
**Already Completed (Early):**
|
||||
- ✅ Per-tool authentication
|
||||
- ✅ Scope-based permissions
|
||||
- ✅ Tracing with trace IDs
|
||||
- ✅ Rate limiting
|
||||
- ✅ Audit logging
|
||||
|
||||
**Remaining:**
|
||||
- [ ] Enterprise MCP Gateway (standalone binary)
|
||||
- [ ] Observability dashboards
|
||||
- [ ] Kubernetes Operator
|
||||
- [ ] Helm Charts
|
||||
|
||||
## Impact & Business Value
|
||||
|
||||
### Developer Experience
|
||||
The new CLI commands make it **trivial** to:
|
||||
- Generate documentation for teams and AI agents
|
||||
- Export service definitions to popular frameworks
|
||||
- Test services during development
|
||||
- Integrate with CI/CD pipelines
|
||||
|
||||
### AI Integration
|
||||
The LangChain SDK enables developers to:
|
||||
- Build AI-powered applications on microservices **immediately**
|
||||
- Leverage the entire LangChain ecosystem (memory, chains, agents)
|
||||
- Use any LLM (GPT-4, Claude, Gemini, etc.)
|
||||
- Create multi-agent workflows
|
||||
- Integrate with existing LangChain applications
|
||||
|
||||
### Ecosystem Positioning
|
||||
These implementations position go-micro as:
|
||||
- **The easiest framework** to make microservices AI-accessible
|
||||
- **First-class integration** with LangChain (largest agent framework)
|
||||
- **Best-in-class DX** for AI agent development
|
||||
- **Production-ready** with security and observability built-in
|
||||
|
||||
### Strategic Value
|
||||
According to the Roadmap 2026:
|
||||
- Addresses **Recommendation #1** (CLI commands) ✓
|
||||
- Addresses **Recommendation #2** (LangChain SDK) ✓
|
||||
- Supports monetization strategy (SaaS, Enterprise)
|
||||
- Drives adoption in AI/agent space
|
||||
- Creates competitive moat through first-mover advantage
|
||||
|
||||
## Next Steps
|
||||
|
||||
### Immediate Priorities (Next 2 Weeks)
|
||||
|
||||
1. **Publish LangChain SDK to PyPI**
|
||||
- Set up PyPI account
|
||||
- Test package installation
|
||||
- Announce on Python/LangChain communities
|
||||
- **Impact:** Makes package publicly available
|
||||
|
||||
2. **Create Interactive Agent Playground**
|
||||
- Web UI for testing services with AI
|
||||
- Real-time tool call visualization
|
||||
- Embeddable in `micro run` dashboard
|
||||
- **Impact:** Critical for demos and sales
|
||||
|
||||
3. **Add WebSocket Transport**
|
||||
- Bidirectional streaming support
|
||||
- Better for long-running operations
|
||||
- Agent feedback loops
|
||||
- **Impact:** Enhanced UX for complex workflows
|
||||
|
||||
### Short-Term (Next Month)
|
||||
|
||||
4. **Create LlamaIndex SDK**
|
||||
- Similar approach to LangChain SDK
|
||||
- Service discovery as data sources
|
||||
- RAG integration examples
|
||||
- **Impact:** Second major agent framework
|
||||
|
||||
5. **Documentation & Marketing**
|
||||
- Blog post about LangChain integration
|
||||
- Video tutorial
|
||||
- Conference talk submissions
|
||||
- **Impact:** Community growth
|
||||
|
||||
### Medium-Term (Next Quarter)
|
||||
|
||||
6. **Enterprise MCP Gateway**
|
||||
- Standalone binary
|
||||
- Horizontal scaling
|
||||
- Production observability
|
||||
- **Impact:** Revenue opportunity
|
||||
|
||||
7. **Kubernetes Operator**
|
||||
- CRD for MCPGateway
|
||||
- Auto-scaling
|
||||
- Service mesh integration
|
||||
- **Impact:** Enterprise adoption
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### Technical KPIs (Achieved)
|
||||
- ✅ Claude Desktop integration: 100%
|
||||
- ✅ Tool discovery latency: <50ms (target: <100ms)
|
||||
- ✅ Stdio transport compliance: 100%
|
||||
- ✅ Test coverage: 90%+ (target: >80%)
|
||||
|
||||
### Implementation KPIs (Achieved)
|
||||
- ✅ MCP library: Complete
|
||||
- ✅ CLI integration: Complete
|
||||
- ✅ Documentation: Complete
|
||||
- ✅ Examples: 2+ working examples
|
||||
- ✅ Agent SDK: LangChain complete
|
||||
|
||||
### Roadmap KPIs (Progress)
|
||||
- ✅ Q1 2026: 100% complete
|
||||
- ✅ Q2 2026: 80% complete (target: 50% by Q2 end)
|
||||
- ✅ Q3 2026: 40% complete (ahead of schedule)
|
||||
|
||||
## Conclusion
|
||||
|
||||
This session successfully implemented **two high-priority Q2 2026 features**:
|
||||
|
||||
1. **MCP CLI Commands** - Making it trivial to document and export services
|
||||
2. **LangChain SDK** - First-class agent framework integration
|
||||
|
||||
The project is now **3-4 months ahead of schedule** on the Roadmap 2026, with:
|
||||
- All Q1 deliverables complete
|
||||
- Most Q2 deliverables complete or in progress
|
||||
- Several Q3 deliverables already delivered
|
||||
|
||||
This positions go-micro as the **leading framework for AI-native microservices** and validates the vision outlined in Roadmap 2026.
|
||||
|
||||
---
|
||||
|
||||
**Session Date:** February 13, 2026
|
||||
**Status:** ✅ Complete
|
||||
**Code Review:** ✅ Passed
|
||||
**Security Scan:** ✅ 0 Alerts
|
||||
**Tests:** ✅ All Passing
|
||||
@@ -0,0 +1,6 @@
|
||||
# Status
|
||||
|
||||
> This snapshot is no longer maintained. Current state lives in two places:
|
||||
>
|
||||
> - **What shipped** — [CHANGELOG.md](../../CHANGELOG.md)
|
||||
> - **What's next** — [ROADMAP.md](../../ROADMAP.md)
|
||||
@@ -0,0 +1,7 @@
|
||||
# Go Micro Roadmap
|
||||
|
||||
> Superseded. The earlier "AI-Native Era" roadmap (with the platform/business-model
|
||||
> framing) has been replaced by a single, current roadmap focused on agentic
|
||||
> development and developer experience.
|
||||
|
||||
See **[ROADMAP.md](../../ROADMAP.md)** (or [go-micro.dev/docs/roadmap](https://go-micro.dev/docs/roadmap)).
|
||||
@@ -0,0 +1,130 @@
|
||||
# Go Micro — Thesis & North Star
|
||||
|
||||
This is the North Star for the project and for the autonomous improvement loop
|
||||
(see `CONTINUOUS_IMPROVEMENT.md`). Every change should move toward it; work that
|
||||
doesn't isn't an improvement, however clean.
|
||||
|
||||
## Mission — the problem we solve
|
||||
|
||||
Go Micro started in 2015 because building distributed systems in Go was too hard:
|
||||
too much boilerplate, too many decisions before a single endpoint runs. The
|
||||
mission was to **make building distributed systems simple** — sane defaults,
|
||||
pluggable, out of the developer's way.
|
||||
|
||||
Agents are distributed systems too. The moment an agent discovers services, calls
|
||||
them, holds state, and recovers from failure, it *is* a distributed system — the
|
||||
exact problem Go Micro already solved for services. So the mission hasn't
|
||||
changed, only extended:
|
||||
|
||||
> **Make building agentic, distributed software in Go simple — make building an
|
||||
> agent as easy as building a service, on one runtime, because an agent is a
|
||||
> distributed system.**
|
||||
|
||||
That is the problem we solve, and it is the question every priority is judged
|
||||
against: *does this make the services → agents → workflows lifecycle simpler, more
|
||||
cohesive, and more operable — or is it scope that doesn't serve that?* It is
|
||||
evolution, not a pivot: the decade of services work is the foundation, and the
|
||||
agent layer is that foundation leveraged for the AI era.
|
||||
|
||||
## The canon
|
||||
|
||||
The vision isn't only in this file. The years of focus and context live in the
|
||||
**corpus** — the [blog](../website/blog/) (the actual thinking, e.g. `/blog/14`
|
||||
"Going All In on AI" and `/blog/27` "Back from the Dead"), the
|
||||
[`README`](../../README.md), and the [website](../website/). Those are the canon;
|
||||
this North Star is their **distillation** and must stay faithful to them. When the
|
||||
two diverge, that's a signal — either the work has drifted from the mission, or the
|
||||
North Star has drifted from the lived story and needs re-grounding in the corpus.
|
||||
The architect re-derives alignment from the canon, not from this file alone.
|
||||
|
||||
## Thesis
|
||||
|
||||
Go Micro is an **agent harness and service framework** — one runtime that, holistically,
|
||||
encapsulates the **lifecycle of services, agents, and workflows**. Not three
|
||||
products stitched together: one set of primitives, because an agent is a
|
||||
distributed system and building one is building a service.
|
||||
|
||||
## The progression: services → agents → workflows
|
||||
|
||||
Value is unlocked in order, and each layer needs the one beneath it:
|
||||
|
||||
1. **Services** — typed, discoverable, callable capabilities. The substrate; every
|
||||
endpoint is automatically an AI-callable tool.
|
||||
2. **Agents** — a model with memory and tools that *uses* those services, plans,
|
||||
delegates, and is bounded by guardrails. Intelligence on top of capability.
|
||||
3. **Workflows** — the part that **pieces it all together**: composing agents and
|
||||
services over time, deterministically where the path is known and dynamically
|
||||
where it isn't, on schedules and in loops. The workloads come *after* the
|
||||
agents, because the value is in stitching it into systems that do real work.
|
||||
|
||||
A harness that stops at "a model in a loop" is incomplete. The point is the whole
|
||||
lifecycle — capability, intelligence, and orchestration as one runtime.
|
||||
|
||||
## Where we fit — complementary, not competing
|
||||
|
||||
"Agent = Model + Harness" ([LangChain](https://www.langchain.com/blog/the-anatomy-of-an-agent-harness))
|
||||
is the right frame, but *harness* has two layers, and we own the second:
|
||||
|
||||
- **The intra-agent harness** — the runtime around a *single model*: system prompt,
|
||||
tools, context compaction, sandbox, self-verification, and the continuation
|
||||
("Ralph") loop. LangChain / LangGraph, deepagents, and Claude Code do this well.
|
||||
**We do not compete here.**
|
||||
- **The operational harness** — the distributed substrate agents *operate inside*:
|
||||
services as typed tools, discovery and RPC, durable and resumable runs,
|
||||
observability, scheduling, and the protocols agents use to reach each other. The
|
||||
place a single agent becomes part of a system, and many agents, services, and
|
||||
workflows compose. **This is Go Micro's focus.**
|
||||
|
||||
They stack. An intra-agent harness produces an agent; Go Micro is where that agent
|
||||
runs as a first-class service and gets composed into workflows with other services
|
||||
and agents. They plug together through open protocols — a LangGraph or deepagents
|
||||
agent is reachable over A2A and consumes Go Micro tools over MCP, and the reverse.
|
||||
We make those agents better neighbours, not obsolete.
|
||||
|
||||
So the focus is deliberately narrow: **the operational harness for Go, and the
|
||||
services → agents → workflows lifecycle** — not a model-orchestration framework, not
|
||||
a graph DSL, not a prompt layer. Lead with interop and the distributed substrate;
|
||||
treat LangChain-class tools as complements to build alongside, never as targets to
|
||||
replace.
|
||||
|
||||
## Why now
|
||||
|
||||
The frontier is moving from chat to **scheduled, looping, work-performing agents**:
|
||||
Anthropic itself is building toward agents that do work on a cadence (Claude for
|
||||
Work, schedulers), and running coding agents *continuously in loops* is becoming
|
||||
standard practice among the people who build them. That shift is exactly the
|
||||
"workflows after agents" layer — and the harness is what makes it safe, durable,
|
||||
observable, and composable instead of a fragile script.
|
||||
|
||||
The bet: whoever gives Go a holistic harness for the **whole lifecycle** — not just
|
||||
an agent SDK, not just a service framework — owns where agentic software gets built.
|
||||
|
||||
## What every improvement should serve
|
||||
|
||||
Judge each loop increment against the North Star:
|
||||
|
||||
1. **Make the harness real** — operate the loop in production: durability,
|
||||
observability, resilience, streaming, human-in-the-loop.
|
||||
2. **Tighten the lifecycle** — services ↔ agents ↔ workflows as one runtime, not
|
||||
three silos.
|
||||
3. **Advance orchestration** — durable, resumable, scheduled, looping workflows
|
||||
that compose agents and services over time.
|
||||
4. **Sharpen DX** — the 0→1 and 0→hero paths stay effortless.
|
||||
5. **Strengthen interop** — MCP (tools), A2A (agents), x402 (paid tools).
|
||||
6. **Harden trust** — cross-provider conformance, failure semantics, tests.
|
||||
|
||||
Prefer changes that advance these; avoid scope that doesn't. Brand/positioning
|
||||
copy and breaking public-API changes stay with the human.
|
||||
|
||||
## The loop is the proof
|
||||
|
||||
Go Micro is built by an autonomous agentic loop — Claude Code and Codex
|
||||
continuously improving the repo against this North Star. That isn't a gimmick; it's
|
||||
the thesis applied to itself: an agent harness, built by agents running in a loop.
|
||||
If the harness is good enough to build itself, it's good enough to build your
|
||||
agentic software.
|
||||
|
||||
## What this is not
|
||||
|
||||
The framework is the product — no hosted platform, no enterprise tier, no VC, no
|
||||
graph DSL. Sustained by sponsorship from those who run it. See `ROADMAP.md`.
|
||||
Reference in New Issue
Block a user