feat: foundations — canonical types, Parse grammar, env DSNs, health, chains
Phase 1 of the majordomo build: - llm/ canonical contract (messages, parts, tools, capabilities, streaming, Model/Provider, error classification) - health/ clock-injected tracker (threshold bench, exponential capped cooldown, reset-on-success) - root Registry + Parse (verbatim model ids, inline recursive alias expansion with cycle detection, chain dedup), LLM_* env-DSN providers (go-llm parity: lazy fallback + eager LoadEnv), health-aware chain executor behind the Model interface - provider/fake scriptable test provider; hermetic test suite incl. the trailing-thinking chain and foreman:// env loading - ADRs 0001-0008, CLAUDE.md, README (honest matrix), CI workflow, docs/phase-1-design.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
package llm
|
||||
|
||||
import "strings"
|
||||
|
||||
// FinishReason explains why generation stopped.
|
||||
type FinishReason string
|
||||
|
||||
const (
|
||||
// FinishStop: the model completed its answer (or hit a stop sequence).
|
||||
FinishStop FinishReason = "stop"
|
||||
// FinishLength: the MaxTokens (or context) limit was hit.
|
||||
FinishLength FinishReason = "length"
|
||||
// FinishToolCalls: the model stopped to request tool invocations.
|
||||
FinishToolCalls FinishReason = "tool_calls"
|
||||
// FinishContentFilter: the provider suppressed content.
|
||||
FinishContentFilter FinishReason = "content_filter"
|
||||
// FinishOther: any provider-specific reason not mapped above.
|
||||
FinishOther FinishReason = "other"
|
||||
)
|
||||
|
||||
// Usage reports token accounting for one request.
|
||||
type Usage struct {
|
||||
InputTokens int
|
||||
OutputTokens int
|
||||
}
|
||||
|
||||
// Total returns input plus output tokens.
|
||||
func (u Usage) Total() int { return u.InputTokens + u.OutputTokens }
|
||||
|
||||
// Add accumulates another usage record (used by agents summing steps).
|
||||
func (u *Usage) Add(o Usage) {
|
||||
u.InputTokens += o.InputTokens
|
||||
u.OutputTokens += o.OutputTokens
|
||||
}
|
||||
|
||||
// Response is the canonical generation result.
|
||||
type Response struct {
|
||||
// Parts is the response content (text, and for multimodal-output models,
|
||||
// other media).
|
||||
Parts []Part
|
||||
|
||||
// ToolCalls are the tool invocations the model requested, if any.
|
||||
ToolCalls []ToolCall
|
||||
|
||||
FinishReason FinishReason
|
||||
Usage Usage
|
||||
|
||||
// Model identifies the resolved target that produced this response as
|
||||
// "provider/model-id". With failover chains this names the element that
|
||||
// actually served the request.
|
||||
Model string
|
||||
|
||||
// Raw is the provider-native response object, an escape hatch for
|
||||
// provider-specific fields. May be nil; never required for normal use.
|
||||
Raw any
|
||||
}
|
||||
|
||||
// Text returns the concatenation of all text parts in the response.
|
||||
func (r *Response) Text() string {
|
||||
var b strings.Builder
|
||||
for _, p := range r.Parts {
|
||||
if t, ok := p.(TextPart); ok {
|
||||
b.WriteString(t.Text)
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Message converts the response into an assistant message suitable for
|
||||
// appending to a conversation history.
|
||||
func (r *Response) Message() Message {
|
||||
return Message{Role: RoleAssistant, Parts: r.Parts, ToolCalls: r.ToolCalls}
|
||||
}
|
||||
Reference in New Issue
Block a user