mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-10 00:14:38 +00:00
Manifest-backed MCP tools, prompts, and resources with surface affordance contracts; agent capability manifest and governance projection; API contract tests and capability route projection; operations-loop and intelligence-funnel telemetry; release-control subsystem documentation, registry, and tooling; licensing and configuration.
75 lines
2.7 KiB
Go
75 lines
2.7 KiB
Go
package agentcapabilities
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
// ExecuteCapabilityToolHTTP projects one shared tool-call request onto the
|
|
// canonical agent capability manifest and wraps the upstream Pulse response in
|
|
// the shared tool result envelope.
|
|
func ExecuteCapabilityToolHTTP(ctx context.Context, client HTTPDoer, baseURL, token string, capabilities []Capability, params ToolCallParams) (ToolResult, error) {
|
|
params = NormalizeToolCallParams(params)
|
|
if err := ValidateToolCallParams(params); err != nil {
|
|
return ToolResult{}, err
|
|
}
|
|
resp, err := CallRequestResponseCapabilityHTTPByName(ctx, client, baseURL, token, capabilities, params.Name, params.Arguments)
|
|
if err != nil {
|
|
var lookupErr CapabilityLookupError
|
|
if errors.As(err, &lookupErr) {
|
|
return ToolResult{}, fmt.Errorf("unknown tool: %s", lookupErr.Name)
|
|
}
|
|
return ToolResult{}, fmt.Errorf("call Pulse: %w", err)
|
|
}
|
|
return NewCapabilityHTTPToolResult(resp), nil
|
|
}
|
|
|
|
// DirectToolExecutionOptions names the surface-specific error messages used
|
|
// when native Pulse code executes a shared tool result directly instead of
|
|
// feeding it back into a model turn.
|
|
type DirectToolExecutionOptions struct {
|
|
FailurePrefix string
|
|
ApprovalRequiredMessage string
|
|
PolicyBlockedMessage string
|
|
}
|
|
|
|
// DirectToolExecutionOutcome is the shared direct-execution projection of a
|
|
// tool result. OutputText is the text callers should expose as execution
|
|
// output; Interpretation keeps the full marker/result view available for
|
|
// diagnostics and future policy callers.
|
|
type DirectToolExecutionOutcome struct {
|
|
OutputText string
|
|
Interpretation ToolResultInterpretation
|
|
}
|
|
|
|
// InterpretDirectToolExecution maps a shared tool result into the output and
|
|
// error contract used by native Assistant direct execution paths.
|
|
// This keeps marker detection, isError handling, and direct-execution failure
|
|
// messages out of individual chat or adapter surfaces.
|
|
func InterpretDirectToolExecution(result ToolResult, opts DirectToolExecutionOptions) (DirectToolExecutionOutcome, error) {
|
|
interpreted := InterpretToolResult(result)
|
|
outcome := DirectToolExecutionOutcome{
|
|
OutputText: interpreted.Text,
|
|
Interpretation: interpreted,
|
|
}
|
|
|
|
if interpreted.IsError {
|
|
prefix := firstNonEmptyString(opts.FailurePrefix, "tool execution failed")
|
|
return outcome, fmt.Errorf("%s: %s", prefix, interpreted.Text)
|
|
}
|
|
|
|
if interpreted.ApprovalRequired {
|
|
outcome.OutputText = ""
|
|
message := firstNonEmptyString(opts.ApprovalRequiredMessage, "tool requires approval")
|
|
return outcome, errors.New(message)
|
|
}
|
|
|
|
if interpreted.PolicyBlocked {
|
|
outcome.OutputText = ""
|
|
message := firstNonEmptyString(opts.PolicyBlockedMessage, "tool blocked by security policy")
|
|
return outcome, errors.New(message)
|
|
}
|
|
|
|
return outcome, nil
|
|
}
|