From fcb2e119989d34064dfcebd65a191148c7d621fe Mon Sep 17 00:00:00 2001 From: mlogclub Date: Tue, 14 Apr 2026 12:13:33 +0800 Subject: [PATCH] feat: refactor runtime to use application runtime executor and update related types --- internal/ai/application/runtime/service.go | 5 +-- .../ai/application/runtime/summary_builder.go | 5 ++- internal/ai/infra/eino/service.go | 16 +++++----- internal/ai/infra/eino/types.go | 8 ----- internal/ai/runtime/debug_run.go | 11 ++++--- .../internal/impl/adapter/mcp_tool_adapter.go | 32 +++++++++---------- internal/ai/runtime/reply_helpers_test.go | 13 ++++---- .../ai/runtime/reply_interrupt_helpers.go | 9 +++--- .../ai/runtime/reply_interrupt_service.go | 7 ++-- internal/ai/runtime/reply_runlog_service.go | 31 +++++++++--------- internal/ai/runtime/reply_service.go | 3 +- internal/ai/runtime/reply_service_test.go | 14 ++++---- internal/ai/runtime/reply_trigger_service.go | 7 ++-- internal/ai/runtime/runtime_reply_executor.go | 15 +++++---- internal/ai/runtime/service.go | 4 +-- internal/ai/runtime/types.go | 8 ----- 16 files changed, 90 insertions(+), 98 deletions(-) delete mode 100644 internal/ai/infra/eino/types.go delete mode 100644 internal/ai/runtime/types.go diff --git a/internal/ai/application/runtime/service.go b/internal/ai/application/runtime/service.go index 35e058b..5636c2e 100644 --- a/internal/ai/application/runtime/service.go +++ b/internal/ai/application/runtime/service.go @@ -4,6 +4,7 @@ import ( "context" runtimeeino "cs-agent/internal/ai/infra/eino" + "cs-agent/internal/ai/runtime/executor" ) type Service struct { @@ -35,7 +36,7 @@ func (s *Service) Run(ctx context.Context, req Request) (*Summary, error) { if err := s.prepare.prepareToolsForRun(&req); err != nil { return nil, err } - summary, err := s.runtime.ExecuteRun(ctx, runtimeeino.RunInput{ + summary, err := s.runtime.ExecuteRun(ctx, executor.RunInput{ Conversation: req.Conversation, UserMessage: req.UserMessage, AIAgent: req.AIAgent, @@ -67,7 +68,7 @@ func (s *Service) Resume(ctx context.Context, req ResumeRequest) (*Summary, erro if err := s.prepare.prepareToolsForResume(&req); err != nil { return nil, err } - summary, err := s.runtime.ExecuteResume(ctx, runtimeeino.ResumeInput{ + summary, err := s.runtime.ExecuteResume(ctx, executor.ResumeInput{ Conversation: req.Conversation, AIAgent: req.AIAgent, AIConfig: req.AIConfig, diff --git a/internal/ai/application/runtime/summary_builder.go b/internal/ai/application/runtime/summary_builder.go index 14ee6dd..57f55ba 100644 --- a/internal/ai/application/runtime/summary_builder.go +++ b/internal/ai/application/runtime/summary_builder.go @@ -1,12 +1,11 @@ package runtime import ( + "cs-agent/internal/ai/runtime/executor" "strings" - - runtimeeino "cs-agent/internal/ai/infra/eino" ) -func toSummary(summary *runtimeeino.RunResult) *Summary { +func toSummary(summary *executor.RunResult) *Summary { if summary == nil { return nil } diff --git a/internal/ai/infra/eino/service.go b/internal/ai/infra/eino/service.go index 46d58fa..6848104 100644 --- a/internal/ai/infra/eino/service.go +++ b/internal/ai/infra/eino/service.go @@ -2,30 +2,30 @@ package eino import ( "context" - - runtimeexecutor "cs-agent/internal/ai/runtime/executor" + "cs-agent/internal/ai/runtime/executor" ) +// TODO 这个不要了,直接使用executor不行吗? type RuntimeExecutor struct { - inner *runtimeexecutor.Service + inner *executor.Service } func NewRuntimeExecutor() *RuntimeExecutor { return &RuntimeExecutor{ - inner: runtimeexecutor.NewService(), + inner: executor.NewService(), } } -func (s *RuntimeExecutor) ExecuteRun(ctx context.Context, req RunInput) (*RunResult, error) { +func (s *RuntimeExecutor) ExecuteRun(ctx context.Context, req executor.RunInput) (*executor.RunResult, error) { if s == nil || s.inner == nil { return nil, nil } - return s.inner.ExecuteRun(ctx, runtimeexecutor.RunInput(req)) + return s.inner.ExecuteRun(ctx, executor.RunInput(req)) } -func (s *RuntimeExecutor) ExecuteResume(ctx context.Context, req ResumeInput) (*RunResult, error) { +func (s *RuntimeExecutor) ExecuteResume(ctx context.Context, req executor.ResumeInput) (*executor.RunResult, error) { if s == nil || s.inner == nil { return nil, nil } - return s.inner.ExecuteResume(ctx, runtimeexecutor.ResumeInput(req)) + return s.inner.ExecuteResume(ctx, executor.ResumeInput(req)) } diff --git a/internal/ai/infra/eino/types.go b/internal/ai/infra/eino/types.go deleted file mode 100644 index 2d517e4..0000000 --- a/internal/ai/infra/eino/types.go +++ /dev/null @@ -1,8 +0,0 @@ -package eino - -import runtimeexecutor "cs-agent/internal/ai/runtime/executor" - -type RunInput = runtimeexecutor.RunInput -type ResumeInput = runtimeexecutor.ResumeInput -type InterruptContextSummary = runtimeexecutor.InterruptContextSummary -type RunResult = runtimeexecutor.RunResult diff --git a/internal/ai/runtime/debug_run.go b/internal/ai/runtime/debug_run.go index 44bdb58..5110691 100644 --- a/internal/ai/runtime/debug_run.go +++ b/internal/ai/runtime/debug_run.go @@ -4,6 +4,7 @@ import ( "context" "strings" + applicationruntime "cs-agent/internal/ai/application/runtime" "cs-agent/internal/ai/runtime/graphs" "cs-agent/internal/models" "cs-agent/internal/pkg/dto/request" @@ -40,7 +41,7 @@ func DebugRunSkill(ctx context.Context, req request.SkillDebugRunRequest) (*resp MessageType: enums.IMMessageTypeText, Content: strings.TrimSpace(req.UserMessage), } - summary, err := Service.Run(ctx, Request{ + summary, err := Service.Run(ctx, applicationruntime.Request{ Conversation: conversation, UserMessage: message, AIAgent: aiAgent, @@ -88,7 +89,7 @@ func DebugResumeSkill(ctx context.Context, req request.SkillDebugResumeRequest) return nil, errorsx.InvalidParam("会话与 AI Agent 不匹配") } resumeText := strings.TrimSpace(req.UserMessage) - summary, err := Service.Resume(ctx, ResumeRequest{ + summary, err := Service.Resume(ctx, applicationruntime.ResumeRequest{ Conversation: conversation, AIAgent: aiAgent, AIConfig: aiConfig, @@ -99,7 +100,7 @@ func DebugResumeSkill(ctx context.Context, req request.SkillDebugResumeRequest) }) if err != nil { if isCheckpointMissingError(err) { - summary = &Summary{ + summary = &applicationruntime.Summary{ Status: "expired", ReplyText: graphs.ConfirmationExpiredReply, } @@ -122,7 +123,7 @@ func DebugResumeSkill(ctx context.Context, req request.SkillDebugResumeRequest) return buildSkillDebugResumeResponse(req, summary, conversationID), nil } -func buildSkillDebugRunResponse(req request.SkillDebugRunRequest, summary *Summary, skill *models.SkillDefinition) *response.SkillDebugRunResponse { +func buildSkillDebugRunResponse(req request.SkillDebugRunRequest, summary *applicationruntime.Summary, skill *models.SkillDefinition) *response.SkillDebugRunResponse { resp := &response.SkillDebugRunResponse{ ConversationID: req.ConversationID, AIAgentID: req.AIAgentID, @@ -154,7 +155,7 @@ func buildSkillDebugRunResponse(req request.SkillDebugRunRequest, summary *Summa return resp } -func buildSkillDebugResumeResponse(req request.SkillDebugResumeRequest, summary *Summary, conversationID int64) *response.SkillDebugRunResponse { +func buildSkillDebugResumeResponse(req request.SkillDebugResumeRequest, summary *applicationruntime.Summary, conversationID int64) *response.SkillDebugRunResponse { resp := &response.SkillDebugRunResponse{ ConversationID: conversationID, AIAgentID: req.AIAgentID, diff --git a/internal/ai/runtime/internal/impl/adapter/mcp_tool_adapter.go b/internal/ai/runtime/internal/impl/adapter/mcp_tool_adapter.go index db0f81c..c0b631f 100644 --- a/internal/ai/runtime/internal/impl/adapter/mcp_tool_adapter.go +++ b/internal/ai/runtime/internal/impl/adapter/mcp_tool_adapter.go @@ -7,29 +7,27 @@ import ( "strings" "cs-agent/internal/ai/mcps" - runtimetooling "cs-agent/internal/ai/runtime/tooling" + "cs-agent/internal/ai/runtime/tooling" - einojsonschema "github.com/eino-contrib/jsonschema" + "github.com/eino-contrib/jsonschema" - einotool "github.com/cloudwego/eino/components/tool" + "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/schema" ) -type MCPToolDefinition = runtimetooling.MCPToolDefinition - type MCPTool struct { - definition MCPToolDefinition + definition tooling.MCPToolDefinition info *schema.ToolInfo } -func NewMCPTool(definition MCPToolDefinition, metadata *mcps.ToolInfo) *MCPTool { +func NewMCPTool(definition tooling.MCPToolDefinition, metadata *mcps.ToolInfo) *MCPTool { return &MCPTool{ definition: definition, info: buildToolInfo(definition, metadata), } } -var _ einotool.InvokableTool = (*MCPTool)(nil) +var _ tool.InvokableTool = (*MCPTool)(nil) func (t *MCPTool) Info(ctx context.Context) (*schema.ToolInfo, error) { if t == nil || t.info == nil { @@ -38,7 +36,7 @@ func (t *MCPTool) Info(ctx context.Context) (*schema.ToolInfo, error) { return t.info, nil } -func (t *MCPTool) InvokableRun(ctx context.Context, argumentsInJSON string, opts ...einotool.Option) (string, error) { +func (t *MCPTool) InvokableRun(ctx context.Context, argumentsInJSON string, opts ...tool.Option) (string, error) { if t == nil { return "", fmt.Errorf("mcp tool is nil") } @@ -54,7 +52,7 @@ func (t *MCPTool) InvokableRun(ctx context.Context, argumentsInJSON string, opts return BuildReducedToolResultSummary(result), nil } -func buildToolInfo(definition MCPToolDefinition, metadata *mcps.ToolInfo) *schema.ToolInfo { +func buildToolInfo(definition tooling.MCPToolDefinition, metadata *mcps.ToolInfo) *schema.ToolInfo { desc := strings.TrimSpace(definition.Description) if desc == "" && metadata != nil { desc = strings.TrimSpace(metadata.Description) @@ -72,7 +70,7 @@ func buildToolInfo(definition MCPToolDefinition, metadata *mcps.ToolInfo) *schem desc = "Call MCP tool " + strings.TrimSpace(definition.ToolCode) } info := &schema.ToolInfo{ - Name: runtimetooling.BuildModelToolName(definition), + Name: tooling.BuildModelToolName(definition), Desc: desc, Extra: map[string]any{ "toolCode": definition.ToolCode, @@ -86,7 +84,7 @@ func buildToolInfo(definition MCPToolDefinition, metadata *mcps.ToolInfo) *schem return info } -func buildParamsSchema(metadata *mcps.ToolInfo) *einojsonschema.Schema { +func buildParamsSchema(metadata *mcps.ToolInfo) *jsonschema.Schema { if metadata == nil || metadata.InputSchema == nil { return genericObjectSchema() } @@ -94,18 +92,18 @@ func buildParamsSchema(metadata *mcps.ToolInfo) *einojsonschema.Schema { if err != nil || len(raw) == 0 { return genericObjectSchema() } - js := &einojsonschema.Schema{} + js := &jsonschema.Schema{} if err := json.Unmarshal(raw, js); err != nil { return genericObjectSchema() } return js } -func genericObjectSchema() *einojsonschema.Schema { - return &einojsonschema.Schema{ - Version: einojsonschema.Version, +func genericObjectSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + Version: jsonschema.Version, Type: "object", - AdditionalProperties: &einojsonschema.Schema{}, + AdditionalProperties: &jsonschema.Schema{}, } } diff --git a/internal/ai/runtime/reply_helpers_test.go b/internal/ai/runtime/reply_helpers_test.go index ed1961e..f6a9ea6 100644 --- a/internal/ai/runtime/reply_helpers_test.go +++ b/internal/ai/runtime/reply_helpers_test.go @@ -4,11 +4,12 @@ import ( "strings" "testing" + applicationruntime "cs-agent/internal/ai/application/runtime" "cs-agent/internal/pkg/toolx" ) func TestSummaryPrimaryToolCodePrefersToolSearchTarget(t *testing.T) { - summary := &Summary{ + summary := &applicationruntime.Summary{ InvokedToolCodes: []string{toolx.BuiltinToolSearch.Code}, TraceData: `{ "toolSearch": { @@ -25,11 +26,11 @@ func TestSummaryPrimaryToolCodePrefersToolSearchTarget(t *testing.T) { } func TestToRunLogFinalAction(t *testing.T) { - if got := toRunLogFinalAction(&Summary{PlannedSkillCode: "refund", ReplyText: "ok"}); got != "skill" { + if got := toRunLogFinalAction(&applicationruntime.Summary{PlannedSkillCode: "refund", ReplyText: "ok"}); got != "skill" { t.Fatalf("expected skill final action, got %q", got) } - graphSummary := &Summary{ + graphSummary := &applicationruntime.Summary{ ReplyText: "ok", TraceData: `{ "graphTools": { @@ -43,7 +44,7 @@ func TestToRunLogFinalAction(t *testing.T) { t.Fatalf("expected graph final action, got %q", got) } - if got := toRunLogFinalAction(&Summary{Status: "fallback"}); got != "fallback" { + if got := toRunLogFinalAction(&applicationruntime.Summary{Status: "fallback"}); got != "fallback" { t.Fatalf("expected fallback final action, got %q", got) } } @@ -66,7 +67,7 @@ func TestExtractInterruptMessageAndCheckpointError(t *testing.T) { } func TestGraphPlanReason(t *testing.T) { - summary := &Summary{ + summary := &applicationruntime.Summary{ TraceData: `{ "graphTools": { "items": [ @@ -86,7 +87,7 @@ func TestGraphPlanReason(t *testing.T) { } func TestExtractHandoffReason(t *testing.T) { - summary := &Summary{ + summary := &applicationruntime.Summary{ TraceData: `{ "graphTools": { "items": [ diff --git a/internal/ai/runtime/reply_interrupt_helpers.go b/internal/ai/runtime/reply_interrupt_helpers.go index 15f659b..9ef4f35 100644 --- a/internal/ai/runtime/reply_interrupt_helpers.go +++ b/internal/ai/runtime/reply_interrupt_helpers.go @@ -5,6 +5,7 @@ import ( "strings" "time" + applicationruntime "cs-agent/internal/ai/application/runtime" "cs-agent/internal/models" svc "cs-agent/internal/services" ) @@ -13,7 +14,7 @@ type interruptMessagePreview struct { Message string `json:"message"` } -func buildConversationInterrupt(conversation models.Conversation, message models.Message, aiAgent models.AIAgent, summary *Summary) *models.ConversationInterrupt { +func buildConversationInterrupt(conversation models.Conversation, message models.Message, aiAgent models.AIAgent, summary *applicationruntime.Summary) *models.ConversationInterrupt { if summary == nil { return nil } @@ -36,7 +37,7 @@ func buildConversationInterrupt(conversation models.Conversation, message models return item } -func resolveInterruptPrompt(summary *Summary) string { +func resolveInterruptPrompt(summary *applicationruntime.Summary) string { if summary == nil || len(summary.Interrupts) == 0 { return "请继续补充信息后再试。" } @@ -61,14 +62,14 @@ func extractInterruptMessage(infoPreview string) string { return strings.TrimSpace(payload.Message) } -func firstInterruptID(summary *Summary) string { +func firstInterruptID(summary *applicationruntime.Summary) string { if summary == nil || len(summary.Interrupts) == 0 { return "" } return strings.TrimSpace(summary.Interrupts[0].ID) } -func firstInterruptType(summary *Summary) string { +func firstInterruptType(summary *applicationruntime.Summary) string { if summary == nil || len(summary.Interrupts) == 0 { return "" } diff --git a/internal/ai/runtime/reply_interrupt_service.go b/internal/ai/runtime/reply_interrupt_service.go index 0e81bf0..eea853e 100644 --- a/internal/ai/runtime/reply_interrupt_service.go +++ b/internal/ai/runtime/reply_interrupt_service.go @@ -4,6 +4,7 @@ import ( "context" "strings" + applicationruntime "cs-agent/internal/ai/application/runtime" "cs-agent/internal/ai/runtime/graphs" "cs-agent/internal/models" svc "cs-agent/internal/services" @@ -16,7 +17,7 @@ func newReplyInterruptService() *replyInterruptService { } func (s *replyInterruptService) ResumePendingInterrupt(ctx context.Context, owner *aiReplyService, conversation models.Conversation, message models.Message, aiAgent models.AIAgent, - pendingInterrupt *models.ConversationInterrupt, trace *aiReplyTraceData, summaryRef **Summary) error { + pendingInterrupt *models.ConversationInterrupt, trace *aiReplyTraceData, summaryRef **applicationruntime.Summary) error { if pendingInterrupt == nil || owner == nil || owner.executor == nil { return nil } @@ -64,7 +65,7 @@ func (s *replyInterruptService) ResumePendingInterrupt(ctx context.Context, owne } func (s *replyInterruptService) HandleInterruptedSummary(owner *aiReplyService, conversation models.Conversation, message models.Message, aiAgent models.AIAgent, - summary *Summary, trace *aiReplyTraceData) error { + summary *applicationruntime.Summary, trace *aiReplyTraceData) error { if owner == nil { return nil } @@ -85,7 +86,7 @@ func (s *replyInterruptService) HandleInterruptedSummary(owner *aiReplyService, } func (s *replyInterruptService) HandleInterruptedResume(owner *aiReplyService, conversation models.Conversation, message models.Message, aiAgent models.AIAgent, - pendingInterrupt *models.ConversationInterrupt, summary *Summary, trace *aiReplyTraceData) error { + pendingInterrupt *models.ConversationInterrupt, summary *applicationruntime.Summary, trace *aiReplyTraceData) error { if pendingInterrupt == nil || owner == nil { return nil } diff --git a/internal/ai/runtime/reply_runlog_service.go b/internal/ai/runtime/reply_runlog_service.go index 73cbbaf..8fd0588 100644 --- a/internal/ai/runtime/reply_runlog_service.go +++ b/internal/ai/runtime/reply_runlog_service.go @@ -6,6 +6,7 @@ import ( "strings" "time" + applicationruntime "cs-agent/internal/ai/application/runtime" "cs-agent/internal/models" "cs-agent/internal/pkg/toolx" svc "cs-agent/internal/services" @@ -18,7 +19,7 @@ func newReplyRunLogService() *replyRunLogService { type replyRunLogService struct{} func (s *replyRunLogService) Write(startedAt time.Time, message models.Message, conversation models.Conversation, aiAgent models.AIAgent, - question string, runErr error, trace *aiReplyTraceData, summary *Summary) { + question string, runErr error, trace *aiReplyTraceData, summary *applicationruntime.Summary) { errorMessage := "" if runErr != nil { errorMessage = runErr.Error() @@ -73,7 +74,7 @@ func buildAIReplyTraceData(trace *aiReplyTraceData) string { return string(data) } -func buildRunLogPlan(summary *Summary) (plannedAction, plannedToolCode, planReason string) { +func buildRunLogPlan(summary *applicationruntime.Summary) (plannedAction, plannedToolCode, planReason string) { if summary == nil { return "", "", "" } @@ -121,7 +122,7 @@ func buildRunLogPlan(summary *Summary) (plannedAction, plannedToolCode, planReas return "fallback", "", "runtime produced empty reply" } -func toRunLogFinalAction(summary *Summary) string { +func toRunLogFinalAction(summary *applicationruntime.Summary) string { if summary == nil { return "" } @@ -147,28 +148,28 @@ func toRunLogFinalAction(summary *Summary) string { } } -func buildRunLogReplyText(summary *Summary) string { +func buildRunLogReplyText(summary *applicationruntime.Summary) string { if summary == nil { return "" } return strings.TrimSpace(summary.ReplyText) } -func summaryPlannedSkillCode(summary *Summary) string { +func summaryPlannedSkillCode(summary *applicationruntime.Summary) string { if summary == nil { return "" } return strings.TrimSpace(summary.PlannedSkillCode) } -func summaryPlannedSkillName(summary *Summary) string { +func summaryPlannedSkillName(summary *applicationruntime.Summary) string { if summary == nil { return "" } return strings.TrimSpace(summary.PlannedSkillName) } -func summarySkillRouteTrace(summary *Summary) string { +func summarySkillRouteTrace(summary *applicationruntime.Summary) string { if summary == nil { return "" } @@ -182,14 +183,14 @@ func runLogResumeSource(trace *aiReplyTraceData) string { return strings.TrimSpace(trace.ResumeSource) } -func runLogFinalStatus(summary *Summary) string { +func runLogFinalStatus(summary *applicationruntime.Summary) string { if summary == nil { return "" } return strings.TrimSpace(summary.Status) } -func summaryPrimaryToolCode(summary *Summary) string { +func summaryPrimaryToolCode(summary *applicationruntime.Summary) string { if summary == nil { return "" } @@ -203,7 +204,7 @@ func summaryPrimaryToolCode(summary *Summary) string { return toolCode } -func extractToolSearchTrace(summary *Summary) string { +func extractToolSearchTrace(summary *applicationruntime.Summary) string { if summary == nil { return "" } @@ -218,7 +219,7 @@ func extractToolSearchTrace(summary *Summary) string { return string(buf) } -func extractGraphToolTrace(summary *Summary) string { +func extractGraphToolTrace(summary *applicationruntime.Summary) string { if summary == nil { return "" } @@ -233,7 +234,7 @@ func extractGraphToolTrace(summary *Summary) string { return string(buf) } -func firstToolSearchTargetToolCode(summary *Summary) string { +func firstToolSearchTargetToolCode(summary *applicationruntime.Summary) string { trace := parseRuntimeTraceData(summary.TraceData) for _, item := range trace.ToolSearch.Items { toolCode := strings.TrimSpace(item.TargetToolCode) @@ -250,7 +251,7 @@ func firstToolSearchTargetToolCode(summary *Summary) string { return "" } -func firstGraphToolCode(summary *Summary) string { +func firstGraphToolCode(summary *applicationruntime.Summary) string { trace := parseRuntimeTraceData(summary.TraceData) for _, item := range trace.GraphTools.Items { toolCode := strings.TrimSpace(item.ToolCode) @@ -261,7 +262,7 @@ func firstGraphToolCode(summary *Summary) string { return "" } -func extractHandoffReason(summary *Summary) string { +func extractHandoffReason(summary *applicationruntime.Summary) string { trace := parseRuntimeTraceData(summary.TraceData) for _, item := range trace.GraphTools.Items { if strings.TrimSpace(item.ToolCode) != toolx.GraphHandoffConversation.Code { @@ -279,7 +280,7 @@ func extractHandoffReason(summary *Summary) string { return "" } -func graphPlanReason(summary *Summary) string { +func graphPlanReason(summary *applicationruntime.Summary) string { trace := parseRuntimeTraceData(summary.TraceData) for _, item := range trace.GraphTools.Items { toolCode := strings.TrimSpace(item.ToolCode) diff --git a/internal/ai/runtime/reply_service.go b/internal/ai/runtime/reply_service.go index 033b3ee..a20ad4e 100644 --- a/internal/ai/runtime/reply_service.go +++ b/internal/ai/runtime/reply_service.go @@ -3,6 +3,7 @@ package runtime import ( "strings" + applicationruntime "cs-agent/internal/ai/application/runtime" svc "cs-agent/internal/services" ) @@ -30,7 +31,7 @@ type aiReplyService struct { runlog *replyRunLogService } -func firstInvokedToolCode(summary *Summary) string { +func firstInvokedToolCode(summary *applicationruntime.Summary) string { if summary == nil { return "" } diff --git a/internal/ai/runtime/reply_service_test.go b/internal/ai/runtime/reply_service_test.go index 0c8636b..dda584b 100644 --- a/internal/ai/runtime/reply_service_test.go +++ b/internal/ai/runtime/reply_service_test.go @@ -7,6 +7,8 @@ import ( "cs-agent/internal/models" "cs-agent/internal/pkg/enums" "cs-agent/internal/pkg/toolx" + + applicationruntime "cs-agent/internal/ai/application/runtime" ) func TestReplyEligibilityCanReply(t *testing.T) { @@ -69,7 +71,7 @@ func TestResolveReplyTimeout(t *testing.T) { } func TestBuildRunLogPlan(t *testing.T) { - summary := &Summary{ + summary := &applicationruntime.Summary{ PlannedSkillCode: "faq_router", PlanReason: "manual", } @@ -78,7 +80,7 @@ func TestBuildRunLogPlan(t *testing.T) { t.Fatalf("unexpected skill plan result: action=%q toolCode=%q reason=%q", action, toolCode, reason) } - summary = &Summary{ + summary = &applicationruntime.Summary{ Interrupted: true, TraceData: `{ "graphTools": { @@ -97,7 +99,7 @@ func TestBuildRunLogPlan(t *testing.T) { t.Fatalf("unexpected graph interrupt result: action=%q toolCode=%q reason=%q", action, toolCode, reason) } - summary = &Summary{ + summary = &applicationruntime.Summary{ InvokedToolCodes: []string{toolx.BuiltinToolSearch.Code}, TraceData: `{ "toolSearch": { @@ -114,7 +116,7 @@ func TestBuildRunLogPlan(t *testing.T) { t.Fatalf("unexpected dynamic tool result: action=%q toolCode=%q reason=%q", action, toolCode, reason) } - summary = &Summary{ReplyText: "done"} + summary = &applicationruntime.Summary{ReplyText: "done"} action, toolCode, reason = buildRunLogPlan(summary) if action != "reply" || toolCode != "" || reason != "agent replied directly" { t.Fatalf("unexpected reply result: action=%q toolCode=%q reason=%q", action, toolCode, reason) @@ -122,8 +124,8 @@ func TestBuildRunLogPlan(t *testing.T) { } func TestResolveInterruptPrompt(t *testing.T) { - summary := &Summary{ - Interrupts: []InterruptContextSummary{ + summary := &applicationruntime.Summary{ + Interrupts: []applicationruntime.InterruptContextSummary{ { ID: "interrupt-1", Type: "question", diff --git a/internal/ai/runtime/reply_trigger_service.go b/internal/ai/runtime/reply_trigger_service.go index 116c25c..74e8362 100644 --- a/internal/ai/runtime/reply_trigger_service.go +++ b/internal/ai/runtime/reply_trigger_service.go @@ -6,6 +6,7 @@ import ( "strings" "time" + applicationruntime "cs-agent/internal/ai/application/runtime" "cs-agent/internal/models" "cs-agent/internal/pkg/enums" svc "cs-agent/internal/services" @@ -44,7 +45,7 @@ func (s *aiReplyService) TriggerReplyAsync(conversation models.Conversation, mes func (s *aiReplyService) TriggerReply(ctx context.Context, conversation models.Conversation, message models.Message, aiAgent models.AIAgent) (retErr error) { startedAt := time.Now() trace := &aiReplyTraceData{Status: "started"} - var summary *Summary + var summary *applicationruntime.Summary if err := ctx.Err(); err != nil { return err } @@ -61,7 +62,7 @@ func (s *aiReplyService) TriggerReply(ctx context.Context, conversation models.C } func (s *aiReplyService) resumePendingInterrupt(ctx context.Context, conversation models.Conversation, message models.Message, aiAgent models.AIAgent, - pendingInterrupt *models.ConversationInterrupt, trace *aiReplyTraceData, summaryRef **Summary) error { + pendingInterrupt *models.ConversationInterrupt, trace *aiReplyTraceData, summaryRef **applicationruntime.Summary) error { if s == nil || s.interrupts == nil { return nil } @@ -69,7 +70,7 @@ func (s *aiReplyService) resumePendingInterrupt(ctx context.Context, conversatio } func (s *aiReplyService) executeReply(ctx context.Context, conversation models.Conversation, message models.Message, aiAgent models.AIAgent, - trace *aiReplyTraceData, summaryRef **Summary) error { + trace *aiReplyTraceData, summaryRef **applicationruntime.Summary) error { if s == nil || s.executor == nil { return nil } diff --git a/internal/ai/runtime/runtime_reply_executor.go b/internal/ai/runtime/runtime_reply_executor.go index 11c700e..ba9a5df 100644 --- a/internal/ai/runtime/runtime_reply_executor.go +++ b/internal/ai/runtime/runtime_reply_executor.go @@ -7,6 +7,7 @@ import ( "strings" "time" + applicationruntime "cs-agent/internal/ai/application/runtime" "cs-agent/internal/ai/runtime/graphs" "cs-agent/internal/models" svc "cs-agent/internal/services" @@ -18,13 +19,13 @@ func newRuntimeReplyExecutor() *runtimeReplyExecutor { return &runtimeReplyExecutor{} } -func (e *runtimeReplyExecutor) Run(ctx context.Context, conversation models.Conversation, message models.Message, aiAgent models.AIAgent, trace *aiReplyTraceData) (*Summary, error) { +func (e *runtimeReplyExecutor) Run(ctx context.Context, conversation models.Conversation, message models.Message, aiAgent models.AIAgent, trace *aiReplyTraceData) (*applicationruntime.Summary, error) { aiConfig := svc.AIConfigService.Get(aiAgent.AIConfigID) if aiConfig == nil { return nil, fmt.Errorf("ai config is nil") } runtimeStartedAt := time.Now() - summary, err := Service.Run(ctx, Request{ + summary, err := Service.Run(ctx, applicationruntime.Request{ Conversation: &conversation, UserMessage: &message, AIAgent: &aiAgent, @@ -37,7 +38,7 @@ func (e *runtimeReplyExecutor) Run(ctx context.Context, conversation models.Conv return summary, err } -func (e *runtimeReplyExecutor) ResumePendingInterrupt(ctx context.Context, conversation models.Conversation, message models.Message, aiAgent models.AIAgent, pendingInterrupt *models.ConversationInterrupt, trace *aiReplyTraceData) (*Summary, error) { +func (e *runtimeReplyExecutor) ResumePendingInterrupt(ctx context.Context, conversation models.Conversation, message models.Message, aiAgent models.AIAgent, pendingInterrupt *models.ConversationInterrupt, trace *aiReplyTraceData) (*applicationruntime.Summary, error) { if pendingInterrupt == nil { return nil, nil } @@ -49,7 +50,7 @@ func (e *runtimeReplyExecutor) ResumePendingInterrupt(ctx context.Context, conve if trace != nil { trace.ResumeSource = "pending_interrupt" } - summary, err := Service.Resume(ctx, ResumeRequest{ + summary, err := Service.Resume(ctx, applicationruntime.ResumeRequest{ Conversation: &conversation, AIAgent: &aiAgent, AIConfig: aiConfig, @@ -65,7 +66,7 @@ func (e *runtimeReplyExecutor) ResumePendingInterrupt(ctx context.Context, conve return summary, err } -func (e *runtimeReplyExecutor) fillTraceFromSummary(trace *aiReplyTraceData, summary *Summary, runErr error) { +func (e *runtimeReplyExecutor) fillTraceFromSummary(trace *aiReplyTraceData, summary *applicationruntime.Summary, runErr error) { if trace == nil { return } @@ -84,8 +85,8 @@ func (e *runtimeReplyExecutor) fillTraceFromSummary(trace *aiReplyTraceData, sum } } -func expiredInterruptSummary() *Summary { - return &Summary{ +func expiredInterruptSummary() *applicationruntime.Summary { + return &applicationruntime.Summary{ Status: "expired", ReplyText: graphs.ConfirmationExpiredReply, } diff --git a/internal/ai/runtime/service.go b/internal/ai/runtime/service.go index 6d8e847..d27fd24 100644 --- a/internal/ai/runtime/service.go +++ b/internal/ai/runtime/service.go @@ -18,14 +18,14 @@ type service struct { app *applicationruntime.Service } -func (s *service) Run(ctx context.Context, req Request) (*Summary, error) { +func (s *service) Run(ctx context.Context, req applicationruntime.Request) (*applicationruntime.Summary, error) { if s == nil || s.app == nil { return nil, nil } return s.app.Run(ctx, req) } -func (s *service) Resume(ctx context.Context, req ResumeRequest) (*Summary, error) { +func (s *service) Resume(ctx context.Context, req applicationruntime.ResumeRequest) (*applicationruntime.Summary, error) { if s == nil || s.app == nil { return nil, nil } diff --git a/internal/ai/runtime/types.go b/internal/ai/runtime/types.go deleted file mode 100644 index 8f4630d..0000000 --- a/internal/ai/runtime/types.go +++ /dev/null @@ -1,8 +0,0 @@ -package runtime - -import applicationruntime "cs-agent/internal/ai/application/runtime" - -type Request = applicationruntime.Request -type ResumeRequest = applicationruntime.ResumeRequest -type InterruptContextSummary = applicationruntime.InterruptContextSummary -type Summary = applicationruntime.Summary