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>
143 行
4.0 KiB
Go
143 行
4.0 KiB
Go
// Package ai provides abstraction for AI model providers
|
|
package ai
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
)
|
|
|
|
// Model provides an interface for interacting with AI model providers
|
|
type Model interface {
|
|
// Init initializes the model with options
|
|
Init(...Option) error
|
|
// Options returns the model options
|
|
Options() Options
|
|
// Generate generates a response from the model
|
|
Generate(ctx context.Context, req *Request, opts ...GenerateOption) (*Response, error)
|
|
// Stream generates a streaming response (for future implementation)
|
|
Stream(ctx context.Context, req *Request, opts ...GenerateOption) (Stream, error)
|
|
// String returns the name of the provider
|
|
String() string
|
|
}
|
|
|
|
// Tool represents a tool/function that can be called by the model
|
|
type Tool struct {
|
|
Name string // LLM-safe name (e.g., "greeter_Greeter_Hello")
|
|
OriginalName string // Original name (e.g., "greeter.Greeter.Hello")
|
|
Description string
|
|
Properties map[string]any // JSON schema for tool parameters
|
|
}
|
|
|
|
// Request represents a request to generate content from a model
|
|
type Request struct {
|
|
// Prompt is the user's message/prompt
|
|
Prompt string
|
|
// SystemPrompt is the system instruction for the model
|
|
SystemPrompt string
|
|
// Tools available for the model to use
|
|
Tools []Tool
|
|
// Messages for continuing a conversation (optional).
|
|
// Use ai.History to accumulate these across turns.
|
|
Messages []Message
|
|
}
|
|
|
|
// Message represents a conversation message
|
|
type Message struct {
|
|
Role string // "user", "assistant", "system", "tool"
|
|
Content any // Can be string or structured content
|
|
}
|
|
|
|
// Response represents the response from a model
|
|
type Response struct {
|
|
// Reply is the text response from the model
|
|
Reply string
|
|
// ToolCalls are tool calls requested by the model
|
|
ToolCalls []ToolCall
|
|
// Answer is the final answer after tool execution (if tools were used)
|
|
Answer string
|
|
}
|
|
|
|
// ToolCall represents a request to call a tool
|
|
type ToolCall struct {
|
|
ID string // Tool call ID (for correlation)
|
|
Name string // Tool name
|
|
Input map[string]any // Tool input arguments
|
|
}
|
|
|
|
// ToolResult represents the result of a tool execution
|
|
type ToolResult struct {
|
|
ID string // Tool call ID (for correlation)
|
|
Content string // Tool execution result (JSON string)
|
|
}
|
|
|
|
// Stream is the interface for streaming responses (future implementation)
|
|
type Stream interface {
|
|
// Recv receives the next chunk of the response
|
|
Recv() (*Response, error)
|
|
// Close closes the stream
|
|
Close() error
|
|
}
|
|
|
|
// ToolHandler is a function that handles tool calls
|
|
type ToolHandler func(name string, input map[string]any) (result any, content string)
|
|
|
|
// NewFunc creates a new Model instance
|
|
type NewFunc func(...Option) Model
|
|
|
|
var providers = make(map[string]NewFunc)
|
|
|
|
// Register registers a model provider
|
|
func Register(name string, fn NewFunc) {
|
|
providers[name] = fn
|
|
}
|
|
|
|
// New creates a new Model instance based on the provider name
|
|
func New(provider string, opts ...Option) Model {
|
|
if fn, ok := providers[provider]; ok {
|
|
return fn(opts...)
|
|
}
|
|
|
|
// Default to first registered provider
|
|
if len(providers) > 0 {
|
|
for _, fn := range providers {
|
|
return fn(opts...)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AutoDetectProvider attempts to detect the provider from the base URL
|
|
func AutoDetectProvider(baseURL string) string {
|
|
if baseURL == "" {
|
|
return "openai"
|
|
}
|
|
switch {
|
|
case strings.Contains(baseURL, "anthropic"):
|
|
return "anthropic"
|
|
case strings.Contains(baseURL, "atlascloud"):
|
|
return "atlascloud"
|
|
case strings.Contains(baseURL, "googleapis.com"), strings.Contains(baseURL, "google"):
|
|
return "gemini"
|
|
case strings.Contains(baseURL, "groq"):
|
|
return "groq"
|
|
case strings.Contains(baseURL, "mistral"):
|
|
return "mistral"
|
|
case strings.Contains(baseURL, "together"):
|
|
return "together"
|
|
default:
|
|
return "openai"
|
|
}
|
|
}
|
|
|
|
// DefaultModel is a default model instance
|
|
var DefaultModel Model
|
|
|
|
// Generate generates a response using the default model.
|
|
func Generate(ctx context.Context, req *Request, opts ...GenerateOption) (*Response, error) {
|
|
if DefaultModel == nil {
|
|
return nil, nil
|
|
}
|
|
return DefaultModel.Generate(ctx, req, opts...)
|
|
}
|