feat: import agents_and_robots platform as unibots (Matrix-out, unibus transport)

Reemplaza el scaffold del echobot por la plataforma completa de bots traida
desde ~/DataProyects/Github/agents_and_robots tras la operacion Matrix-out:
los bots ya no hablan por Matrix sino por el bus unibus (modelo todo-rooms +
E2E via shell/transportunibus sobre github.com/enmanuel/unibus/pkg/client).

- go.mod: replace de unibus -> ../unibus y de fn-registry -> ../../../.. (paths
  relativos reajustados a la nueva ubicacion dentro de fn_registry).
- app.md: bump a 0.2.0, descripcion + arquitectura + comandos + gotchas reales.
- modulo Go conservado como github.com/enmanuel/agents (sin reescribir imports).

agents_and_robots queda archivado como museo de la era Matrix.
This commit is contained in:
agent
2026-06-07 11:50:13 +02:00
parent bb5b0e09b1
commit fc644ecd6e
308 changed files with 38829 additions and 474 deletions
+27
View File
@@ -0,0 +1,27 @@
package llm
import "strings"
// Route maps a model string to its provider. Pure function.
func Route(model string) ProviderID {
switch {
case model == "claude-code" || strings.HasPrefix(model, "claude-code/"):
return ProviderClaudeCode
case strings.HasPrefix(model, "claude"):
return ProviderAnthropic
case strings.HasPrefix(model, "gpt"), strings.HasPrefix(model, "o1"), strings.HasPrefix(model, "o3"):
return ProviderOpenAI
case strings.HasPrefix(model, "ollama/"):
return ProviderOllama
default:
return ProviderOpenAI
}
}
// ModelName strips the provider prefix from a model string.
func ModelName(model string) string {
if after, ok := strings.CutPrefix(model, "ollama/"); ok {
return after
}
return model
}
+48
View File
@@ -0,0 +1,48 @@
package llm
import "testing"
func TestRoute(t *testing.T) {
tests := []struct {
model string
want ProviderID
}{
{"claude-code", ProviderClaudeCode},
{"claude-code/custom", ProviderClaudeCode},
{"claude-sonnet-4-5-20250929", ProviderAnthropic},
{"claude-opus-4", ProviderAnthropic},
{"gpt-4o", ProviderOpenAI},
{"o1-preview", ProviderOpenAI},
{"o3-mini", ProviderOpenAI},
{"ollama/mistral", ProviderOllama},
{"unknown-model", ProviderOpenAI}, // default
}
for _, tt := range tests {
t.Run(tt.model, func(t *testing.T) {
got := Route(tt.model)
if got != tt.want {
t.Errorf("Route(%q) = %q, want %q", tt.model, got, tt.want)
}
})
}
}
func TestModelName(t *testing.T) {
tests := []struct {
input, want string
}{
{"ollama/mistral", "mistral"},
{"gpt-4o", "gpt-4o"},
{"claude-sonnet-4-5-20250929", "claude-sonnet-4-5-20250929"},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
got := ModelName(tt.input)
if got != tt.want {
t.Errorf("ModelName(%q) = %q, want %q", tt.input, got, tt.want)
}
})
}
}
+69
View File
@@ -0,0 +1,69 @@
// Package llm defines pure types for LLM provider communication.
// No side effects — only data and transformations.
package llm
import "context"
type Role string
const (
RoleSystem Role = "system"
RoleUser Role = "user"
RoleAssistant Role = "assistant"
RoleTool Role = "tool"
)
type ProviderID string
const (
ProviderAnthropic ProviderID = "anthropic"
ProviderOpenAI ProviderID = "openai"
ProviderOllama ProviderID = "ollama"
ProviderClaudeCode ProviderID = "claude-code"
)
type Message struct {
Role Role
Content string
ToolCallID string
ToolCalls []ToolCall
}
type ToolCall struct {
ID string
Name string
Arguments string // JSON-encoded
}
type ToolSpec struct {
Name string
Description string
InputSchema map[string]any
}
type CompletionRequest struct {
Model string
Messages []Message
Tools []ToolSpec
MaxTokens int
Temperature float64
Stream bool
SystemPrompt string
}
type TokenUsage struct {
InputTokens int
OutputTokens int
TotalTokens int
}
type CompletionResponse struct {
Content string
ToolCalls []ToolCall
Usage TokenUsage
FinishReason string
}
// CompleteFunc is the single contract for LLM providers.
// Implementations live in shell/llm/.
type CompleteFunc func(ctx context.Context, req CompletionRequest) (CompletionResponse, error)