mirror of
https://github.com/coder/coder.git
synced 2026-10-31 02:43:21 +08:00
refactor(coderd/x/chatd): return PersistedStep directly from ExecuteLocalTools (#28359)
**Stack**: **#28359 (this PR)** → #28360 → #28361 → #28362 `chatloop.ToolExecutionOutcome` only wrapped a `PersistedStep`, so callers had to reach through `outcome.Step` for every field. `ExecuteLocalTools` now returns the `PersistedStep` directly and the wrapper type is deleted. No behavior change. First of a four-PR stack that makes local tool execution count toward Coder Agent runtime (splitting #28211). This refactor keeps the rename noise out of the feature PRs. Refs CODAGT-928 (https://linear.app/codercom/issue/CODAGT-928/track-local-tool-execution-for-agent-runtime).
This commit is contained in:
@@ -275,11 +275,6 @@ type ExecuteLocalToolsOptions struct {
|
||||
Clock quartz.Clock
|
||||
}
|
||||
|
||||
// ToolExecutionOutcome is the durable tool-result content from one batch.
|
||||
type ToolExecutionOutcome struct {
|
||||
Step PersistedStep
|
||||
}
|
||||
|
||||
// GenerateCompactionOptions configures one context compaction call.
|
||||
type GenerateCompactionOptions struct {
|
||||
Model fantasy.LanguageModel
|
||||
@@ -562,7 +557,7 @@ func contentFilterError(provider string, metadata fantasy.ProviderMetadata) erro
|
||||
|
||||
// ExecuteLocalTools runs local tool calls and returns durable tool results. It
|
||||
// does not retry or persist.
|
||||
func ExecuteLocalTools(ctx context.Context, opts ExecuteLocalToolsOptions) (ToolExecutionOutcome, error) {
|
||||
func ExecuteLocalTools(ctx context.Context, opts ExecuteLocalToolsOptions) (PersistedStep, error) {
|
||||
if opts.Metrics == nil {
|
||||
opts.Metrics = NopMetrics()
|
||||
}
|
||||
@@ -584,7 +579,7 @@ func ExecuteLocalTools(ctx context.Context, opts ExecuteLocalToolsOptions) (Tool
|
||||
// without capturing the publisher at construction time.
|
||||
ctx = WithMessagePartPublisher(ctx, opts.PublishMessagePart)
|
||||
if ctx.Err() != nil {
|
||||
return ToolExecutionOutcome{}, ctx.Err()
|
||||
return PersistedStep{}, ctx.Err()
|
||||
}
|
||||
|
||||
localCalls := make([]fantasy.ToolCallContent, 0, len(opts.ToolCalls))
|
||||
@@ -594,7 +589,7 @@ func ExecuteLocalTools(ctx context.Context, opts ExecuteLocalToolsOptions) (Tool
|
||||
}
|
||||
}
|
||||
if len(localCalls) == 0 {
|
||||
return ToolExecutionOutcome{}, nil
|
||||
return PersistedStep{}, nil
|
||||
}
|
||||
|
||||
var result stepResult
|
||||
@@ -616,12 +611,12 @@ func ExecuteLocalTools(ctx context.Context, opts ExecuteLocalToolsOptions) (Tool
|
||||
result.content = append(result.content, tr)
|
||||
}
|
||||
if ctx.Err() != nil {
|
||||
return ToolExecutionOutcome{}, ctx.Err()
|
||||
return PersistedStep{}, ctx.Err()
|
||||
}
|
||||
return ToolExecutionOutcome{Step: PersistedStep{
|
||||
return PersistedStep{
|
||||
Content: result.content,
|
||||
ToolResultCreatedAt: result.toolResultCreatedAt,
|
||||
}}, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
maxResultBytes := toolResultByteBudget(opts.ContextLimit)
|
||||
@@ -650,15 +645,15 @@ func ExecuteLocalTools(ctx context.Context, opts ExecuteLocalToolsOptions) (Tool
|
||||
},
|
||||
)
|
||||
if ctx.Err() != nil {
|
||||
return ToolExecutionOutcome{}, ctx.Err()
|
||||
return PersistedStep{}, ctx.Err()
|
||||
}
|
||||
for _, tr := range toolResults {
|
||||
result.content = append(result.content, tr)
|
||||
}
|
||||
return ToolExecutionOutcome{Step: PersistedStep{
|
||||
return PersistedStep{
|
||||
Content: result.content,
|
||||
ToolResultCreatedAt: result.toolResultCreatedAt,
|
||||
}}, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
// prepareMessagesForRequest applies the prompt preparation pipeline used
|
||||
|
||||
@@ -858,7 +858,7 @@ func (s *taskStarter) executeLocalTools(
|
||||
provider = prepared.Model.Provider()
|
||||
modelName = prepared.Model.ModelID()
|
||||
}
|
||||
var outcome chatloop.ToolExecutionOutcome
|
||||
var outcome chatloop.PersistedStep
|
||||
var spawnDispatchErr error
|
||||
if len(allowed) > 0 {
|
||||
outcome, err = chatloop.ExecuteLocalTools(ctx, chatloop.ExecuteLocalToolsOptions{
|
||||
@@ -886,18 +886,19 @@ func (s *taskStarter) executeLocalTools(
|
||||
// the tool run; its failure surfaces as a tool result error. The
|
||||
// step still commits so a sibling tool that already ran keeps its
|
||||
// result and is not re-executed, and the turn fails afterwards.
|
||||
if hookErr := chathooks.DispatchFailureFromResults(outcome.Step.Content); hookErr != nil {
|
||||
if hookErr := chathooks.DispatchFailureFromResults(outcome.Content); hookErr != nil {
|
||||
spawnDispatchErr = chathooks.GenerationDispatchError(agenthooks.EventUserPromptSubmit, hookErr)
|
||||
}
|
||||
}
|
||||
postResults, postDispatchErr := s.server.hooks.PostToolUseResults(ctx, chathooks.ChatFor(prepared.Chat, input.hookTurnID()), outcome.Step.Content)
|
||||
postResults, postDispatchErr := s.server.hooks.PostToolUseResults(ctx, chathooks.ChatFor(prepared.Chat, input.hookTurnID()), outcome.Content)
|
||||
for _, result := range denied {
|
||||
outcome.Step.Content = append(outcome.Step.Content, result)
|
||||
outcome.Content = append(outcome.Content, result)
|
||||
}
|
||||
chathooks.RestoreToolCallOrder(outcome.Step.Content, decision.localToolCalls)
|
||||
chathooks.RestoreToolCallOrder(outcome.Content, decision.localToolCalls)
|
||||
step := stepDataFromPersisted(outcome)
|
||||
messages, err := buildCommitStepMessages(buildCommitStepMessagesInput{
|
||||
modelConfigID: prepared.ModelConfigID,
|
||||
step: stepDataFromPersisted(outcome.Step),
|
||||
step: step,
|
||||
toolNameToConfigID: prepared.ToolNameToConfigID,
|
||||
logger: s.opts.Logger,
|
||||
contentVersion: chatprompt.CurrentContentVersion,
|
||||
|
||||
Reference in New Issue
Block a user