refactor: streamline autonomous engine logic and introduce autonomousTurn context
This commit is contained in:
@@ -9,7 +9,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
ai "agent-desk/internal/ai"
|
ai "agent-desk/internal/ai"
|
||||||
"agent-desk/internal/ai/runtime/instruction"
|
|
||||||
"agent-desk/internal/ai/runtime/readtools"
|
"agent-desk/internal/ai/runtime/readtools"
|
||||||
"agent-desk/internal/ai/runtime/retrievers"
|
"agent-desk/internal/ai/runtime/retrievers"
|
||||||
runtimetooling "agent-desk/internal/ai/runtime/tooling"
|
runtimetooling "agent-desk/internal/ai/runtime/tooling"
|
||||||
@@ -66,81 +65,60 @@ func (e *AutonomousEngine) Run(ctx context.Context, req RunInput) (*RunResult, e
|
|||||||
}
|
}
|
||||||
req.AIAgent = snapshot.Agent
|
req.AIAgent = snapshot.Agent
|
||||||
req.AIConfig = snapshot.AIConfig
|
req.AIConfig = snapshot.AIConfig
|
||||||
skillContext := e.selectSkill(ctx, req)
|
turn := e.prepareTurn(ctx, req)
|
||||||
knowledgeContext, retrieverCount, retrieveErr := e.retrieveKnowledge(ctx, req.AIAgent, req.UserMessage.Content)
|
|
||||||
responsePolicy := evaluateAutonomousResponsePolicy(req.AIAgent, knowledgeContext, retrieveErr)
|
|
||||||
systemPrompt := buildAutonomousSystemPrompt(req.AIAgent, len(utils.SplitInt64s(req.AIAgent.KnowledgeIDs)) > 0, knowledgeContext, retrieveErr)
|
|
||||||
if skillInstruction := strings.TrimSpace(instruction.BuildSkillDocument(skillContext.Skill, nil)); skillInstruction != "" {
|
|
||||||
systemPrompt += "\n\nSkill instructions:\n" + skillInstruction
|
|
||||||
}
|
|
||||||
userPrompt, historyCount := e.buildUserPrompt(req)
|
|
||||||
if knowledgeContext != "" {
|
|
||||||
userPrompt += "\n\nKnowledge evidence:\n" + knowledgeContext
|
|
||||||
}
|
|
||||||
var toolCalls []svc.EngineToolCallInput
|
var toolCalls []svc.EngineToolCallInput
|
||||||
var result *ai.ChatCompletionResult
|
var result *ai.ChatCompletionResult
|
||||||
agentAllowedTools := autonomousAllowedMCPToolCodes(req.AIAgent.AllowedMCPTools)
|
if turn.ResponsePolicy.Enforced {
|
||||||
toolPolicy := parseAutonomousToolPolicy(req.AIAgent.ToolPolicy)
|
result = &ai.ChatCompletionResult{Content: turn.ResponsePolicy.ReplyText, ModelName: req.AIConfig.ModelName}
|
||||||
allowedTools := agentAllowedTools
|
} else if len(turn.AllowedTools) > 0 && e.toolChat != nil {
|
||||||
if skillContext.Skill != nil {
|
loopResult, loopErr := e.toolChat(ctx, req.AIConfig, turn.SystemPrompt, turn.UserPrompt, []ai.ToolDefinition{autonomousToolSearchDefinition()}, req.AIAgent.MaxSteps, e.toolSearchExecutor(req.Conversation, req.AIAgent, turn.AgentAllowedTools, turn.SkillContext.AllowedToolCodes, turn.ToolPolicy, &toolCalls))
|
||||||
allowedTools = intersectAutonomousToolCodes(agentAllowedTools, skillContext.AllowedToolCodes)
|
|
||||||
}
|
|
||||||
if req.Debug {
|
|
||||||
// Dashboard debug runs may inspect model and retrieval behavior but must
|
|
||||||
// not invoke direct MCP tools against production integrations.
|
|
||||||
allowedTools = nil
|
|
||||||
}
|
|
||||||
if responsePolicy.Enforced {
|
|
||||||
result = &ai.ChatCompletionResult{Content: responsePolicy.ReplyText, ModelName: req.AIConfig.ModelName}
|
|
||||||
} else if len(allowedTools) > 0 && e.toolChat != nil {
|
|
||||||
loopResult, loopErr := e.toolChat(ctx, req.AIConfig, systemPrompt, userPrompt, []ai.ToolDefinition{autonomousToolSearchDefinition()}, req.AIAgent.MaxSteps, e.toolSearchExecutor(req.Conversation, req.AIAgent, agentAllowedTools, skillContext.AllowedToolCodes, toolPolicy, &toolCalls))
|
|
||||||
if loopErr != nil {
|
if loopErr != nil {
|
||||||
if len(toolCalls) == 0 {
|
if len(toolCalls) == 0 {
|
||||||
err := loopErr
|
err := loopErr
|
||||||
_, _ = writeAutonomousRun(req, startedAt, nil, userPrompt, historyCount, retrieverCount, retrieveErr, skillContext, responsePolicy, toolCalls, err)
|
_, _ = writeAutonomousRun(req, startedAt, nil, turn.UserPrompt, turn.HistoryCount, turn.RetrieverCount, turn.RetrieveErr, turn.SkillContext, turn.ResponsePolicy, toolCalls, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
responsePolicy = autonomousToolFailurePolicy(req.AIAgent, "tool_loop_error")
|
turn.ResponsePolicy = autonomousToolFailurePolicy(req.AIAgent, "tool_loop_error")
|
||||||
result = &ai.ChatCompletionResult{Content: responsePolicy.ReplyText, ModelName: req.AIConfig.ModelName}
|
result = &ai.ChatCompletionResult{Content: turn.ResponsePolicy.ReplyText, ModelName: req.AIConfig.ModelName}
|
||||||
}
|
}
|
||||||
if result == nil && loopResult != nil {
|
if result == nil && loopResult != nil {
|
||||||
result = &loopResult.ChatCompletionResult
|
result = &loopResult.ChatCompletionResult
|
||||||
}
|
}
|
||||||
if autonomousHasConsecutiveToolFailures(toolCalls, 2) {
|
if autonomousHasConsecutiveToolFailures(toolCalls, 2) {
|
||||||
responsePolicy = autonomousToolFailurePolicy(req.AIAgent, "tool_consecutive_failures")
|
turn.ResponsePolicy = autonomousToolFailurePolicy(req.AIAgent, "tool_consecutive_failures")
|
||||||
result = &ai.ChatCompletionResult{Content: responsePolicy.ReplyText, ModelName: req.AIConfig.ModelName}
|
result = &ai.ChatCompletionResult{Content: turn.ResponsePolicy.ReplyText, ModelName: req.AIConfig.ModelName}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result, err = e.chat(ctx, req.AIConfig, systemPrompt, userPrompt)
|
result, err = e.chat(ctx, req.AIConfig, turn.SystemPrompt, turn.UserPrompt)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, _ = writeAutonomousRun(req, startedAt, nil, userPrompt, historyCount, retrieverCount, retrieveErr, skillContext, responsePolicy, toolCalls, err)
|
_, _ = writeAutonomousRun(req, startedAt, nil, turn.UserPrompt, turn.HistoryCount, turn.RetrieverCount, turn.RetrieveErr, turn.SkillContext, turn.ResponsePolicy, toolCalls, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if result == nil || strings.TrimSpace(result.Content) == "" {
|
if result == nil || strings.TrimSpace(result.Content) == "" {
|
||||||
err = errorsx.InvalidParam("autonomous engine returned an empty reply")
|
err = errorsx.InvalidParam("autonomous engine returned an empty reply")
|
||||||
_, _ = writeAutonomousRun(req, startedAt, nil, userPrompt, historyCount, retrieverCount, retrieveErr, skillContext, responsePolicy, toolCalls, err)
|
_, _ = writeAutonomousRun(req, startedAt, nil, turn.UserPrompt, turn.HistoryCount, turn.RetrieverCount, turn.RetrieveErr, turn.SkillContext, turn.ResponsePolicy, toolCalls, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result.Content, err = aitooling.NormalizeCustomerReply(result.Content)
|
result.Content, err = aitooling.NormalizeCustomerReply(result.Content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, _ = writeAutonomousRun(req, startedAt, nil, userPrompt, historyCount, retrieverCount, retrieveErr, skillContext, responsePolicy, toolCalls, err)
|
_, _ = writeAutonomousRun(req, startedAt, nil, turn.UserPrompt, turn.HistoryCount, turn.RetrieverCount, turn.RetrieveErr, turn.SkillContext, turn.ResponsePolicy, toolCalls, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
runID, recordErr := writeAutonomousRun(req, startedAt, result, userPrompt, historyCount, retrieverCount, retrieveErr, skillContext, responsePolicy, toolCalls, nil)
|
runID, recordErr := writeAutonomousRun(req, startedAt, result, turn.UserPrompt, turn.HistoryCount, turn.RetrieverCount, turn.RetrieveErr, turn.SkillContext, turn.ResponsePolicy, toolCalls, nil)
|
||||||
if recordErr != nil {
|
if recordErr != nil {
|
||||||
return nil, recordErr
|
return nil, recordErr
|
||||||
}
|
}
|
||||||
trace, _ := json.Marshal(map[string]any{
|
trace, _ := json.Marshal(map[string]any{
|
||||||
"engine": EngineCodeAutonomous,
|
"engine": EngineCodeAutonomous,
|
||||||
"mode": autonomousExecutionMode(allowedTools),
|
"mode": autonomousExecutionMode(turn.AllowedTools),
|
||||||
"historyMessageCount": historyCount,
|
"historyMessageCount": turn.HistoryCount,
|
||||||
"retrieverCount": retrieverCount,
|
"retrieverCount": turn.RetrieverCount,
|
||||||
"skillID": skillContext.SkillID(),
|
"skillID": turn.SkillContext.SkillID(),
|
||||||
"skillRouteError": skillContext.ErrorMessage,
|
"skillRouteError": turn.SkillContext.ErrorMessage,
|
||||||
"responsePolicyAction": responsePolicy.Action,
|
"responsePolicyAction": turn.ResponsePolicy.Action,
|
||||||
"responsePolicyReason": responsePolicy.Reason,
|
"responsePolicyReason": turn.ResponsePolicy.Reason,
|
||||||
"responsePolicyEnforced": responsePolicy.Enforced,
|
"responsePolicyEnforced": turn.ResponsePolicy.Enforced,
|
||||||
"debug": req.Debug,
|
"debug": req.Debug,
|
||||||
})
|
})
|
||||||
return &Summary{
|
return &Summary{
|
||||||
@@ -149,15 +127,15 @@ func (e *AutonomousEngine) Run(ctx context.Context, req RunInput) (*RunResult, e
|
|||||||
ModelName: result.ModelName,
|
ModelName: result.ModelName,
|
||||||
PromptTokens: result.PromptTokens,
|
PromptTokens: result.PromptTokens,
|
||||||
CompletionTokens: result.CompletionTokens,
|
CompletionTokens: result.CompletionTokens,
|
||||||
HistoryMessageCount: historyCount,
|
HistoryMessageCount: turn.HistoryCount,
|
||||||
RetrieverCount: retrieverCount,
|
RetrieverCount: turn.RetrieverCount,
|
||||||
PlannedSkillID: skillContext.SkillID(),
|
PlannedSkillID: turn.SkillContext.SkillID(),
|
||||||
PlannedSkillName: skillContext.SkillName(),
|
PlannedSkillName: turn.SkillContext.SkillName(),
|
||||||
PlanReason: skillContext.MatchReason,
|
PlanReason: turn.SkillContext.MatchReason,
|
||||||
SkillRouteTrace: skillContext.TraceData,
|
SkillRouteTrace: turn.SkillContext.TraceData,
|
||||||
SkillAllowedToolCodes: append([]string(nil), skillContext.AllowedToolCodes...),
|
SkillAllowedToolCodes: append([]string(nil), turn.SkillContext.AllowedToolCodes...),
|
||||||
AgentRunID: runID,
|
AgentRunID: runID,
|
||||||
HandoffRequested: responsePolicy.RequestHandoff && !req.Debug,
|
HandoffRequested: turn.ResponsePolicy.RequestHandoff && !req.Debug,
|
||||||
TraceData: string(trace),
|
TraceData: string(trace),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"agent-desk/internal/ai/runtime/instruction"
|
||||||
|
"agent-desk/internal/pkg/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
// autonomousTurn is the prepared context for an autonomous or hybrid model
|
||||||
|
// turn. It keeps context assembly separate from engine-specific execution and
|
||||||
|
// auditing.
|
||||||
|
type autonomousTurn struct {
|
||||||
|
SkillContext autonomousSkillContext
|
||||||
|
RetrieverCount int
|
||||||
|
RetrieveErr error
|
||||||
|
ResponsePolicy autonomousResponsePolicy
|
||||||
|
SystemPrompt string
|
||||||
|
UserPrompt string
|
||||||
|
HistoryCount int
|
||||||
|
AgentAllowedTools []string
|
||||||
|
AllowedTools []string
|
||||||
|
ToolPolicy autonomousToolPolicy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *AutonomousEngine) prepareTurn(ctx context.Context, req Request) autonomousTurn {
|
||||||
|
skillContext := e.selectSkill(ctx, req)
|
||||||
|
knowledgeContext, retrieverCount, retrieveErr := e.retrieveKnowledge(ctx, req.AIAgent, req.UserMessage.Content)
|
||||||
|
responsePolicy := evaluateAutonomousResponsePolicy(req.AIAgent, knowledgeContext, retrieveErr)
|
||||||
|
systemPrompt := buildAutonomousSystemPrompt(req.AIAgent, len(utils.SplitInt64s(req.AIAgent.KnowledgeIDs)) > 0, knowledgeContext, retrieveErr)
|
||||||
|
if skillInstruction := strings.TrimSpace(instruction.BuildSkillDocument(skillContext.Skill, nil)); skillInstruction != "" {
|
||||||
|
systemPrompt += "\n\nSkill instructions:\n" + skillInstruction
|
||||||
|
}
|
||||||
|
userPrompt, historyCount := e.buildUserPrompt(req)
|
||||||
|
if knowledgeContext != "" {
|
||||||
|
userPrompt += "\n\nKnowledge evidence:\n" + knowledgeContext
|
||||||
|
}
|
||||||
|
agentAllowedTools := autonomousAllowedMCPToolCodes(req.AIAgent.AllowedMCPTools)
|
||||||
|
allowedTools := agentAllowedTools
|
||||||
|
if skillContext.Skill != nil {
|
||||||
|
allowedTools = intersectAutonomousToolCodes(agentAllowedTools, skillContext.AllowedToolCodes)
|
||||||
|
}
|
||||||
|
if req.Debug {
|
||||||
|
// Dashboard debug runs may inspect model and retrieval behavior but must
|
||||||
|
// not invoke direct MCP tools against production integrations.
|
||||||
|
allowedTools = nil
|
||||||
|
}
|
||||||
|
return autonomousTurn{
|
||||||
|
SkillContext: skillContext,
|
||||||
|
RetrieverCount: retrieverCount,
|
||||||
|
RetrieveErr: retrieveErr,
|
||||||
|
ResponsePolicy: responsePolicy,
|
||||||
|
SystemPrompt: systemPrompt,
|
||||||
|
UserPrompt: userPrompt,
|
||||||
|
HistoryCount: historyCount,
|
||||||
|
AgentAllowedTools: agentAllowedTools,
|
||||||
|
AllowedTools: allowedTools,
|
||||||
|
ToolPolicy: parseAutonomousToolPolicy(req.AIAgent.ToolPolicy),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
ai "agent-desk/internal/ai"
|
ai "agent-desk/internal/ai"
|
||||||
aitooling "agent-desk/internal/ai/tooling"
|
aitooling "agent-desk/internal/ai/tooling"
|
||||||
"agent-desk/internal/ai/runtime/instruction"
|
|
||||||
workflowregistry "agent-desk/internal/ai/workflow/registry"
|
workflowregistry "agent-desk/internal/ai/workflow/registry"
|
||||||
workflowvalidator "agent-desk/internal/ai/workflow/validator"
|
workflowvalidator "agent-desk/internal/ai/workflow/validator"
|
||||||
"agent-desk/internal/models"
|
"agent-desk/internal/models"
|
||||||
@@ -61,26 +60,15 @@ func (e *HybridEngine) Run(ctx context.Context, req RunInput) (*RunResult, error
|
|||||||
return nil, errorsx.InvalidParam("hybrid agent playbook validation failed")
|
return nil, errorsx.InvalidParam("hybrid agent playbook validation failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
skillContext := e.autonomous.selectSkill(ctx, req)
|
turn := e.autonomous.prepareTurn(ctx, req)
|
||||||
knowledgeContext, retrieverCount, retrieveErr := e.autonomous.retrieveKnowledge(ctx, req.AIAgent, req.UserMessage.Content)
|
if turn.ResponsePolicy.Enforced {
|
||||||
responsePolicy := evaluateAutonomousResponsePolicy(req.AIAgent, knowledgeContext, retrieveErr)
|
return writeHybridResult(req, startedAt, &ai.ChatCompletionResult{Content: turn.ResponsePolicy.ReplyText, ModelName: req.AIConfig.ModelName}, "", 0, turn.RetrieverCount, turn.RetrieveErr, turn.SkillContext, nil, turn.ResponsePolicy, nil)
|
||||||
if responsePolicy.Enforced {
|
|
||||||
return writeHybridResult(req, startedAt, &ai.ChatCompletionResult{Content: responsePolicy.ReplyText, ModelName: req.AIConfig.ModelName}, "", 0, retrieverCount, skillContext, nil, responsePolicy, nil)
|
|
||||||
}
|
|
||||||
systemPrompt := buildAutonomousSystemPrompt(req.AIAgent, len(utils.SplitInt64s(req.AIAgent.KnowledgeIDs)) > 0, knowledgeContext, retrieveErr)
|
|
||||||
if skillInstruction := strings.TrimSpace(instruction.BuildSkillDocument(skillContext.Skill, nil)); skillInstruction != "" {
|
|
||||||
systemPrompt += "\n\nSkill instructions:\n" + skillInstruction
|
|
||||||
}
|
|
||||||
systemPrompt += "\n\nWhen a deterministic process is required, use run_playbook. Do not call it for ordinary factual questions."
|
|
||||||
userPrompt, historyCount := e.autonomous.buildUserPrompt(req)
|
|
||||||
if knowledgeContext != "" {
|
|
||||||
userPrompt += "\n\nKnowledge evidence:\n" + knowledgeContext
|
|
||||||
}
|
}
|
||||||
|
turn.SystemPrompt += "\n\nWhen a deterministic process is required, use run_playbook. Do not call it for ordinary factual questions."
|
||||||
|
|
||||||
var playbookSummary *Summary
|
var playbookSummary *Summary
|
||||||
toolCalls := make([]svc.EngineToolCallInput, 0, 1)
|
toolCalls := make([]svc.EngineToolCallInput, 0, 1)
|
||||||
toolPolicy := parseAutonomousToolPolicy(req.AIAgent.ToolPolicy)
|
loop, err := e.chatWithTools(ctx, req.AIConfig, turn.SystemPrompt, turn.UserPrompt, []ai.ToolDefinition{hybridPlaybookToolDefinition(req.AIAgent.WorkflowVersionID)}, req.AIAgent.MaxSteps, func(ctx context.Context, call ai.ToolCall) (string, error) {
|
||||||
loop, err := e.chatWithTools(ctx, req.AIConfig, systemPrompt, userPrompt, []ai.ToolDefinition{hybridPlaybookToolDefinition(req.AIAgent.WorkflowVersionID)}, req.AIAgent.MaxSteps, func(ctx context.Context, call ai.ToolCall) (string, error) {
|
|
||||||
if call.Name != "run_playbook" {
|
if call.Name != "run_playbook" {
|
||||||
return "", fmt.Errorf("unsupported hybrid tool: %s", call.Name)
|
return "", fmt.Errorf("unsupported hybrid tool: %s", call.Name)
|
||||||
}
|
}
|
||||||
@@ -96,7 +84,7 @@ func (e *HybridEngine) Run(ctx context.Context, req RunInput) (*RunResult, error
|
|||||||
}
|
}
|
||||||
playbookDefinition := aitooling.Definition{Code: hybridPlaybookToolCode, Name: "run_playbook", RiskLevel: aitooling.RiskLevelWrite, RequireConfirmation: true, MaxCallsPerRun: 1}
|
playbookDefinition := aitooling.Definition{Code: hybridPlaybookToolCode, Name: "run_playbook", RiskLevel: aitooling.RiskLevelWrite, RequireConfirmation: true, MaxCallsPerRun: 1}
|
||||||
if err := aitooling.DefaultRegistry.Authorize(playbookDefinition, aitooling.Policy{
|
if err := aitooling.DefaultRegistry.Authorize(playbookDefinition, aitooling.Policy{
|
||||||
AllowedRiskLevels: toolPolicy.AllowedRiskLevels,
|
AllowedRiskLevels: turn.ToolPolicy.AllowedRiskLevels,
|
||||||
CallCount: len(toolCalls),
|
CallCount: len(toolCalls),
|
||||||
TotalCallCount: len(toolCalls),
|
TotalCallCount: len(toolCalls),
|
||||||
MaxTotalCalls: 1,
|
MaxTotalCalls: 1,
|
||||||
@@ -119,11 +107,11 @@ func (e *HybridEngine) Run(ctx context.Context, req RunInput) (*RunResult, error
|
|||||||
return string(data), nil
|
return string(data), nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, _ = writeHybridAudit(req, startedAt, nil, userPrompt, historyCount, retrieverCount, skillContext, toolCalls, responsePolicy, false, err)
|
_, _ = writeHybridAudit(req, startedAt, nil, turn.UserPrompt, turn.HistoryCount, turn.RetrieverCount, turn.RetrieveErr, turn.SkillContext, toolCalls, turn.ResponsePolicy, false, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if playbookSummary != nil && playbookSummary.Interrupted {
|
if playbookSummary != nil && playbookSummary.Interrupted {
|
||||||
runID, auditErr := writeHybridAudit(req, startedAt, &ai.ChatCompletionResult{Content: playbookSummary.ReplyText, ModelName: playbookSummary.ModelName, PromptTokens: playbookSummary.PromptTokens, CompletionTokens: playbookSummary.CompletionTokens}, userPrompt, historyCount, retrieverCount, skillContext, toolCalls, responsePolicy, true, nil)
|
runID, auditErr := writeHybridAudit(req, startedAt, &ai.ChatCompletionResult{Content: playbookSummary.ReplyText, ModelName: playbookSummary.ModelName, PromptTokens: playbookSummary.PromptTokens, CompletionTokens: playbookSummary.CompletionTokens}, turn.UserPrompt, turn.HistoryCount, turn.RetrieverCount, turn.RetrieveErr, turn.SkillContext, toolCalls, turn.ResponsePolicy, true, nil)
|
||||||
if auditErr != nil {
|
if auditErr != nil {
|
||||||
return nil, auditErr
|
return nil, auditErr
|
||||||
}
|
}
|
||||||
@@ -132,10 +120,10 @@ func (e *HybridEngine) Run(ctx context.Context, req RunInput) (*RunResult, error
|
|||||||
}
|
}
|
||||||
if loop == nil || strings.TrimSpace(loop.Content) == "" {
|
if loop == nil || strings.TrimSpace(loop.Content) == "" {
|
||||||
err = errorsx.InvalidParam("hybrid engine returned an empty reply")
|
err = errorsx.InvalidParam("hybrid engine returned an empty reply")
|
||||||
_, _ = writeHybridAudit(req, startedAt, nil, userPrompt, historyCount, retrieverCount, skillContext, toolCalls, responsePolicy, false, err)
|
_, _ = writeHybridAudit(req, startedAt, nil, turn.UserPrompt, turn.HistoryCount, turn.RetrieverCount, turn.RetrieveErr, turn.SkillContext, toolCalls, turn.ResponsePolicy, false, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return writeHybridResult(req, startedAt, &loop.ChatCompletionResult, userPrompt, historyCount, retrieverCount, skillContext, playbookSummary, responsePolicy, toolCalls)
|
return writeHybridResult(req, startedAt, &loop.ChatCompletionResult, turn.UserPrompt, turn.HistoryCount, turn.RetrieverCount, turn.RetrieveErr, turn.SkillContext, playbookSummary, turn.ResponsePolicy, toolCalls)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *HybridEngine) Resume(ctx context.Context, req ResumeInput) (*RunResult, error) {
|
func (e *HybridEngine) Resume(ctx context.Context, req ResumeInput) (*RunResult, error) {
|
||||||
@@ -171,15 +159,15 @@ func parseHybridPlaybookCall(raw string) (int64, error) {
|
|||||||
return input.WorkflowVersionID, nil
|
return input.WorkflowVersionID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeHybridResult(req Request, startedAt time.Time, result *ai.ChatCompletionResult, inputPreview string, historyCount, retrieverCount int, skillContext autonomousSkillContext, playbook *Summary, responsePolicy autonomousResponsePolicy, toolCalls []svc.EngineToolCallInput) (*Summary, error) {
|
func writeHybridResult(req Request, startedAt time.Time, result *ai.ChatCompletionResult, inputPreview string, historyCount, retrieverCount int, retrieveErr error, skillContext autonomousSkillContext, playbook *Summary, responsePolicy autonomousResponsePolicy, toolCalls []svc.EngineToolCallInput) (*Summary, error) {
|
||||||
runID, err := writeHybridAudit(req, startedAt, result, inputPreview, historyCount, retrieverCount, skillContext, toolCalls, responsePolicy, false, nil)
|
runID, err := writeHybridAudit(req, startedAt, result, inputPreview, historyCount, retrieverCount, retrieveErr, skillContext, toolCalls, responsePolicy, false, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Summary{Status: "completed", ReplyText: strings.TrimSpace(result.Content), ModelName: result.ModelName, PromptTokens: result.PromptTokens, CompletionTokens: result.CompletionTokens, HistoryMessageCount: historyCount, RetrieverCount: retrieverCount, AgentRunID: runID, WorkflowRunID: workflowRunIDFromSummary(playbook)}, nil
|
return &Summary{Status: "completed", ReplyText: strings.TrimSpace(result.Content), ModelName: result.ModelName, PromptTokens: result.PromptTokens, CompletionTokens: result.CompletionTokens, HistoryMessageCount: historyCount, RetrieverCount: retrieverCount, AgentRunID: runID, WorkflowRunID: workflowRunIDFromSummary(playbook)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeHybridAudit(req Request, startedAt time.Time, result *ai.ChatCompletionResult, inputPreview string, historyCount, retrieverCount int, skillContext autonomousSkillContext, toolCalls []svc.EngineToolCallInput, responsePolicy autonomousResponsePolicy, interrupted bool, cause error) (int64, error) {
|
func writeHybridAudit(req Request, startedAt time.Time, result *ai.ChatCompletionResult, inputPreview string, historyCount, retrieverCount int, retrieveErr error, skillContext autonomousSkillContext, toolCalls []svc.EngineToolCallInput, responsePolicy autonomousResponsePolicy, interrupted bool, cause error) (int64, error) {
|
||||||
endedAt := time.Now()
|
endedAt := time.Now()
|
||||||
status, errorMessage, outputPreview := "completed", "", ""
|
status, errorMessage, outputPreview := "completed", "", ""
|
||||||
promptTokens, completionTokens := 0, 0
|
promptTokens, completionTokens := 0, 0
|
||||||
@@ -190,7 +178,7 @@ func writeHybridAudit(req Request, startedAt time.Time, result *ai.ChatCompletio
|
|||||||
} else if result != nil {
|
} else if result != nil {
|
||||||
outputPreview, promptTokens, completionTokens = strings.TrimSpace(result.Content), result.PromptTokens, result.CompletionTokens
|
outputPreview, promptTokens, completionTokens = strings.TrimSpace(result.Content), result.PromptTokens, result.CompletionTokens
|
||||||
}
|
}
|
||||||
steps := autonomousAdditionalSteps(req, retrieverCount, nil, skillContext, responsePolicy)
|
steps := autonomousAdditionalSteps(req, retrieverCount, retrieveErr, skillContext, responsePolicy)
|
||||||
for _, call := range toolCalls {
|
for _, call := range toolCalls {
|
||||||
if call.ToolCode == hybridPlaybookToolCode {
|
if call.ToolCode == hybridPlaybookToolCode {
|
||||||
steps = append(steps, svc.EngineStepInput{StepType: "playbook", StepCode: hybridPlaybookToolCode, WorkflowRunID: workflowRunIDFromToolResult(call.ResultPreview), Status: call.Status, InputPreview: call.ArgumentsPreview, OutputPreview: call.ResultPreview, ErrorMessage: call.ErrorMessage})
|
steps = append(steps, svc.EngineStepInput{StepType: "playbook", StepCode: hybridPlaybookToolCode, WorkflowRunID: workflowRunIDFromToolResult(call.ResultPreview), Status: call.Status, InputPreview: call.ArgumentsPreview, OutputPreview: call.ResultPreview, ErrorMessage: call.ErrorMessage})
|
||||||
|
|||||||
Reference in New Issue
Block a user