项目文件夹

文件
Asim Aslam 1bc886fa82 Introduce Agent abstraction and integrate with chat router (#2939)
* docs: Agent interface design sketch

Proposes Agent as a top-level abstraction alongside Service in the
micro package. Agent manages services — scoped tools, system prompt,
conversation memory, registry-discoverable.

Design only, no implementation.

https://claude.ai/code/session_01QTp4SshuVmLAvvEGJe4TJd

* feat: Agent as a first-class abstraction

Introduce micro.NewAgent() alongside micro.New() — Agent is to
intelligence what Service is to capability.

Agent interface:
- Chat(ctx, message) (*Response, error) — core interaction method
- Run() — registers in registry, subscribes to broker, blocks
- Stop() — graceful shutdown
- Scoped tools — only sees endpoints of its assigned services
- Persistent memory — conversation history stored in store
- Agent-to-agent — communication via broker topics

Top-level API:
  agent := micro.NewAgent("task-mgr",
      micro.AgentServices("task"),
      micro.AgentPrompt("You manage tasks."),
      micro.AgentProvider("anthropic"),
  )
  agent.Run()

https://claude.ai/code/session_01QTp4SshuVmLAvvEGJe4TJd

* feat: wire agents into chat router, add micro agent CLI, expose Flow

Three top-level abstractions:
  micro.New("task")              — Service (capability)
  micro.NewAgent("task-mgr")     — Agent (intelligence)
  micro.NewFlow("onboard-user")  — Flow (event-driven orchestration)

micro chat as router:
- Discovers agents from registry on startup
- Single agent: routes directly
- Multiple agents: LLM classifies intent, dispatches to right agent
  via route_to_agent tool
- No agents: falls back to current direct-service behaviour
- Banner shows discovered agents

micro agent CLI:
- micro agent list — shows registered agents and their services
- micro agent describe <name> — shows agent details from registry

https://claude.ai/code/session_01QTp4SshuVmLAvvEGJe4TJd

* feat: move flow to top level, update docs for three abstractions

Package structure now consistent:
  service/   — Service (capability)
  agent/     — Agent (intelligence)
  flow/      — Flow (event-driven orchestration)

ai/flow/ kept as backward-compatible re-export.

Updated across all surfaces:
- CLAUDE.md: added agent/ and flow/ to project structure
- README: added "Building Agents" section with NewAgent() examples,
  updated features table (Agents, Flows, Chat router), CLI table
  (agent list, agent describe), docs links
- Website: features grid shows Services, Agents, Flows as the three
  pillars alongside generation, MCP, and pluggable architecture
- micro.go: Flow imported from top-level flow/ package

https://claude.ai/code/session_01QTp4SshuVmLAvvEGJe4TJd

* docs: rewrite getting-started, fix ai-integration import paths

Getting started now covers all three abstractions:
- Service (write handlers, micro run, templates)
- Agent (micro.NewAgent, scoped tools, memory, CLI)
- Flow (event-driven LLM orchestration)
Leads with prompt-based generation, then manual service creation.

ai-integration.md: fixed flow import path from go-micro.dev/v5/ai/flow
to go-micro.dev/v5/flow, updated stack diagram to show agent/flow/chat.

https://claude.ai/code/session_01QTp4SshuVmLAvvEGJe4TJd

* blog: Introducing micro.NewAgent()

Post 16 — announces Agent as a first-class abstraction. Shows the
API (NewAgent, AgentServices, AgentPrompt, AgentProvider), scoped
tools, persistent memory, multi-service agents, multi-agent systems,
and the three-abstraction comparison table (Service/Agent/Flow).

https://claude.ai/code/session_01QTp4SshuVmLAvvEGJe4TJd

* feat: fix agent registration, blog post 16

Agent registration:
- Add node with address so mDNS can discover agents
- Store type and services in node metadata (mDNS requirement)
- Connect broker before subscribing, non-fatal if broker unavailable
- Print registration confirmation on Run()

Agent/chat discovery:
- Check both service-level and node-level metadata for type=agent
  (mDNS stores metadata on nodes, not services)

Blog post 16: "Introducing micro.NewAgent()" — announces the Agent
abstraction with code examples, comparison table, multi-agent patterns.

Tested end-to-end: micro run → micro agent list discovers the agent →
micro chat routes to it → agent calls service endpoints.

https://claude.ai/code/session_01QTp4SshuVmLAvvEGJe4TJd

* feat: agents are proper services with RPC Chat endpoint

Refactored agent to use server.Server instead of fake registry entries.
An agent now:
- Creates a real RPC server with server.Name(agentName)
- Registers an Agent.Chat handler callable via standard RPC
- Sets server metadata type=agent, services=x,y for discovery
- No more fake addresses or broker hacks

micro chat calls agents via RPC (client.Call) instead of creating
local agent instances. The registry stays clean — agents are real
services with real endpoints.

Removed broker dependency from agent options. Agent-to-agent
communication is just RPC like everything else.

https://claude.ai/code/session_01QTp4SshuVmLAvvEGJe4TJd

* feat: agent uses proto-defined RPC interface

Added agent/proto/agent.proto with Agent service definition:
  rpc Chat(ChatRequest) returns (ChatResponse)

Agent now implements the generated AgentHandler interface and
registers via pb.RegisterAgentHandler. The Chat endpoint is a
standard proto-based RPC callable by any go-micro client.

Renamed the programmatic API from Chat() to Ask() to avoid
collision with the proto handler method name.

micro chat calls agents via standard RPC with JSON-encoded
request/response — no special types needed on the caller side.

https://claude.ai/code/session_01QTp4SshuVmLAvvEGJe4TJd

* feat: generate agent alongside services, update all docs

micro run --prompt now generates an agent binary that manages all
the generated services. The agent reads MICRO_AI_PROVIDER and
MICRO_AI_API_KEY from the environment. micro run propagates these
when started with --prompt.

Run banner shows services and agents separately.

Updated README, getting-started guide, and landing page to show
the complete flow: generate → services + agent start → micro chat
routes to agent → agent orchestrates services.

https://claude.ai/code/session_01QTp4SshuVmLAvvEGJe4TJd

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-05 10:25:14 +01:00

86 行
1.7 KiB
Go

package flow
import (
"testing"
)
func TestNew(t *testing.T) {
f := New("test-flow",
Trigger("events.test"),
Prompt("Handle this: {{.Data}}"),
Provider("anthropic"),
APIKey("test-key"),
HistoryLimit(10),
)
if f.Name() != "test-flow" {
t.Errorf("name = %q, want test-flow", f.Name())
}
if f.opts.TriggerTopic != "events.test" {
t.Errorf("trigger = %q", f.opts.TriggerTopic)
}
if f.opts.Provider != "anthropic" {
t.Errorf("provider = %q", f.opts.Provider)
}
if f.opts.HistoryLimit != 10 {
t.Errorf("history limit = %d", f.opts.HistoryLimit)
}
if f.tmpl == nil {
t.Fatal("template not parsed")
}
}
func TestPromptTemplate(t *testing.T) {
f := New("tmpl-test",
Prompt("User created: {{.Data}}. Send welcome email."),
)
// Test that the template renders
if f.tmpl == nil {
t.Fatal("template not parsed")
}
}
func TestResultsEmpty(t *testing.T) {
f := New("empty")
results := f.Results()
if len(results) != 0 {
t.Errorf("expected 0 results, got %d", len(results))
}
}
func TestOnResultCallback(t *testing.T) {
var called bool
f := New("callback",
OnResult(func(r Result) {
called = true
if r.FlowName != "callback" {
t.Errorf("flow name = %q", r.FlowName)
}
}),
)
f.record(Result{FlowName: "callback"})
if !called {
t.Error("OnResult not called")
}
if len(f.Results()) != 1 {
t.Errorf("results = %d, want 1", len(f.Results()))
}
}
func TestDefaultOptions(t *testing.T) {
f := New("defaults")
if f.opts.Provider != "openai" {
t.Errorf("default provider = %q, want openai", f.opts.Provider)
}
if f.opts.HistoryLimit != 20 {
t.Errorf("default history limit = %d, want 20", f.opts.HistoryLimit)
}
if f.opts.SystemPrompt == "" {
t.Error("default system prompt is empty")
}
}