micro--go-micro
888dbbca4a
goreleaser / goreleaser (push) Has been cancelled
* refactor(ai): rename ToolSet to Tools, simplify wiring with WithTools
Move tool discovery/execution fully into the ai package as ai.Tools
(formerly ai.ToolSet), and simplify the usage model:
- NewTools(reg, ai.ToolClient(c)) takes the execution client as an
option instead of threading it through Handler(c) per call
- New ai.WithTools(tools) option wires the tool handler into a model
in one call, replacing ai.WithToolHandler(set.Handler(c))
- ai.DiscoverTools(reg) for one-shot discovery
Before:
set := ai.NewToolSet(reg)
list, _ := set.Discover()
m := ai.New(p, ai.WithToolHandler(set.Handler(client)))
After:
tools := ai.NewTools(reg, ai.ToolClient(client))
list, _ := tools.Discover()
m := ai.New(p, ai.WithTools(tools))
Update ai/flow, micro chat, README, ai integration doc, Atlas Cloud
guide, and blog posts 3/8/9/10.
* feat(cli): add per-interface commands (registry, broker, store, config)
Map go-micro's core interfaces onto the CLI so the framework's
building blocks are inspectable and manipulable from the terminal:
micro registry list/get/watch service discovery
micro broker publish/subscribe pub/sub messaging
micro store read/write/delete/list persistence
micro config get/dump dynamic config (from env)
Structured pluggably in cmd/micro/resource: each interface is one
file exposing a Command() func, all wired through a commandFuncs
slice in resource.go. Adding a new resource command is a single
file plus one slice entry. Shared printJSON/fail helpers keep
output and errors consistent across commands.
Each command's verbs mirror the interface methods. Output is JSON
for structured data, raw for single values. Update README and
getting-started with an "inspecting the framework" section.
* docs: update CLI README with all new commands
Add documentation for commands that were missing from the CLI README:
- micro new --template (crud, pubsub, api)
- micro api (standalone HTTP gateway)
- micro registry list/get/watch
- micro broker publish/subscribe
- micro store read/write/delete/list
- micro config get/dump
- micro chat (interactive LLM agent)
- micro flow run/exec (event-driven orchestration)
- micro mcp serve/list/test
Organized into sections: API Gateway, Inspecting the Framework
(registry, broker, store, config), and AI & Agents (chat, flow, mcp).
* refactor(ai): move History from caller to Request field
History is now pure state (no Generate method). Instead, pass it
via Request.History and call ai.Generate(ctx, model, req):
Before:
hist := ai.NewHistory("system prompt", 50)
resp, _ := hist.Generate(ctx, model, prompt, tools)
After:
hist := ai.NewHistory(50)
resp, _ := ai.Generate(ctx, model, &ai.Request{
Prompt: prompt,
SystemPrompt: "system prompt",
Tools: tools,
History: hist,
})
The model is always the thing you call. History is context you
pass in. ai.Generate() handles the bookkeeping: prepends
accumulated messages before the call, records the exchange after.
NewHistory no longer takes a system prompt (it belongs on the
Request, where it always did).
Update micro chat, ai/flow, and all blog posts/docs.
* refactor(ai): make History a plain message accumulator
History no longer has Generate or touches the model. It's just
Add/Messages/Reset/Len with truncation — a helper for building
Request.Messages across turns.
Before:
hist := ai.NewHistory(50)
resp, _ := ai.Generate(ctx, m, &ai.Request{History: hist, ...})
After:
hist := ai.NewHistory(50)
hist.Add("user", prompt)
resp, _ := m.Generate(ctx, &ai.Request{Messages: hist.Messages(), ...})
hist.Add("assistant", resp.Reply)
Remove History field from Request. Remove package-level
ai.Generate(ctx, model, req) wrapper — users call m.Generate()
directly, which is the interface method. History is a convenience
for accumulating messages, not a participant in generation.
Update micro chat, ai/flow, blog posts 9 and 10.
---------
Co-authored-by: Claude <noreply@anthropic.com>
63 行
1.3 KiB
Go
63 行
1.3 KiB
Go
package ai
|
|
|
|
import "testing"
|
|
|
|
func TestHistory_Add(t *testing.T) {
|
|
h := NewHistory(0)
|
|
h.Add("user", "hello")
|
|
h.Add("assistant", "hi")
|
|
|
|
if h.Len() != 2 {
|
|
t.Errorf("len = %d, want 2", h.Len())
|
|
}
|
|
msgs := h.Messages()
|
|
if msgs[0].Role != "user" || msgs[0].Content != "hello" {
|
|
t.Errorf("first = %+v", msgs[0])
|
|
}
|
|
if msgs[1].Role != "assistant" || msgs[1].Content != "hi" {
|
|
t.Errorf("second = %+v", msgs[1])
|
|
}
|
|
}
|
|
|
|
func TestHistory_Truncation(t *testing.T) {
|
|
h := NewHistory(3)
|
|
for _, m := range []string{"a", "b", "c", "d", "e"} {
|
|
h.Add("user", m)
|
|
}
|
|
if h.Len() != 3 {
|
|
t.Errorf("len = %d, want 3", h.Len())
|
|
}
|
|
if h.Messages()[0].Content != "c" {
|
|
t.Errorf("first retained = %+v", h.Messages()[0])
|
|
}
|
|
}
|
|
|
|
func TestHistory_Reset(t *testing.T) {
|
|
h := NewHistory(0)
|
|
h.Add("user", "hello")
|
|
h.Reset()
|
|
if h.Len() != 0 {
|
|
t.Errorf("len after reset = %d", h.Len())
|
|
}
|
|
}
|
|
|
|
func TestHistory_SnapshotIsCopy(t *testing.T) {
|
|
h := NewHistory(0)
|
|
h.Add("user", "hello")
|
|
msgs := h.Messages()
|
|
msgs[0].Content = "mutated"
|
|
if h.Messages()[0].Content == "mutated" {
|
|
t.Error("snapshot returned reference, not copy")
|
|
}
|
|
}
|
|
|
|
func TestHistory_Unlimited(t *testing.T) {
|
|
h := NewHistory(0)
|
|
for i := 0; i < 100; i++ {
|
|
h.Add("user", "msg")
|
|
}
|
|
if h.Len() != 100 {
|
|
t.Errorf("len = %d, want 100", h.Len())
|
|
}
|
|
}
|