feat: golem15.golem plugin with the OpenAI-compatible adapter and AIService.Send
- Prompt, Payload and AIResponse value objects ported from Golem15.Golem - OpenAIAdapter: chat completions mapping with PHP's response_format, max_completion_tokens and reasoning_effort rules - AIService.Send through fetchguard (TrustedMode for operator models, PublicOnlyMode otherwise) with PHP's failure messages - config defaults for the SSRF allowlist and the AI timeout, lang, README
This commit is contained in:
56
classes/valueobjects/response.go
Normal file
56
classes/valueobjects/response.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package valueobjects
|
||||
|
||||
// AIResponse is the outcome of an AI call. A success carries Content,
|
||||
// Usage and the provider's decoded answer in Raw; a failure carries Error,
|
||||
// PHP's message for the caller, and sometimes Raw (the provider's error
|
||||
// body, or {"raw": body} when the answer was not JSON). Err is the Go
|
||||
// error behind a failure, for logs and tests; it is never shown to a user
|
||||
// and may be nil.
|
||||
type AIResponse struct {
|
||||
Success bool
|
||||
Content string
|
||||
Error string
|
||||
Usage map[string]any
|
||||
Raw map[string]any
|
||||
Err error
|
||||
}
|
||||
|
||||
// Success builds a successful response.
|
||||
func Success(content string, usage, raw map[string]any) AIResponse {
|
||||
if usage == nil {
|
||||
usage = map[string]any{}
|
||||
}
|
||||
if raw == nil {
|
||||
raw = map[string]any{}
|
||||
}
|
||||
return AIResponse{Success: true, Content: content, Usage: usage, Raw: raw}
|
||||
}
|
||||
|
||||
// Failure builds a failed response.
|
||||
func Failure(message string, raw map[string]any) AIResponse {
|
||||
if raw == nil {
|
||||
raw = map[string]any{}
|
||||
}
|
||||
return AIResponse{Error: message, Usage: map[string]any{}, Raw: raw}
|
||||
}
|
||||
|
||||
// TotalTokens is usage.total_tokens, 0 when absent.
|
||||
func (r AIResponse) TotalTokens() int { return usageInt(r.Usage, "total_tokens") }
|
||||
|
||||
// PromptTokens is usage.prompt_tokens, 0 when absent.
|
||||
func (r AIResponse) PromptTokens() int { return usageInt(r.Usage, "prompt_tokens") }
|
||||
|
||||
// CompletionTokens is usage.completion_tokens, 0 when absent.
|
||||
func (r AIResponse) CompletionTokens() int { return usageInt(r.Usage, "completion_tokens") }
|
||||
|
||||
func usageInt(m map[string]any, k string) int {
|
||||
switch n := m[k].(type) {
|
||||
case int:
|
||||
return n
|
||||
case int64:
|
||||
return int(n)
|
||||
case float64:
|
||||
return int(n)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user