package core import ( "context" "ragflow/internal/harness/core/internal" ) // RunOption configures an agent run. type RunOption interface{ apply(*runOptions) } type runOptions struct { sessionValues map[string]any sharedParentSession bool checkPointID *string cancelCtx *cancelContext skipTransferMessages bool agentNames []string callbacks []any afterToolCallsHook func(ctx context.Context) error chatModelOptions []ModelOption toolOptions []ToolOption agentToolOptions map[string][]RunOption historyModifier func(context.Context, []Message) []Message } type runOptFn func(*runOptions) func (f runOptFn) apply(o *runOptions) { f(o) } func WrapImplSpecificOptFn(fn func(*runOptions)) RunOption { return runOptFn(fn) } func getCommonOptions(o *runOptions, opts ...RunOption) *runOptions { if o == nil { o = &runOptions{} } for _, opt := range opts { if opt != nil { opt.apply(o) } } return o } // WithSessionValues injects session-scoped key-value pairs into the run context. func WithSessionValues(vals map[string]any) RunOption { return runOptFn(func(o *runOptions) { o.sessionValues = vals }) } // WithCheckPointID sets the checkpoint ID for this run, enabling interrupt/resume. func WithCheckPointID(id string) RunOption { return runOptFn(func(o *runOptions) { o.checkPointID = &id }) } // WithSkipTransferMessages prevents the agent from receiving messages forwarded // from parent agents during a transfer. func WithSkipTransferMessages() RunOption { return runOptFn(func(o *runOptions) { o.skipTransferMessages = true }) } // WithCallbacks registers agent lifecycle callbacks (onStart/onEnd/onError/onInterrupt). func WithCallbacks(cbs ...any) RunOption { return runOptFn(func(o *runOptions) { o.callbacks = cbs }) } // WithAgentNames scopes the associated options to specific agent names. func WithAgentNames(names ...string) RunOption { return runOptFn(func(o *runOptions) { o.agentNames = names }) } // WithSharedParentSession gives sub-agents access to the parent's session values. func WithSharedParentSession() RunOption { return runOptFn(func(o *runOptions) { o.sharedParentSession = true }) } // ---- Model-agent-specific options ---- // WithChatModelOptions passes model-level options (e.g., temperature, retry) to the underlying Model. func WithChatModelOptions(opts []ModelOption) RunOption { return WrapImplSpecificOptFn(func(o *runOptions) { o.chatModelOptions = opts }) } // WithToolOptions passes tool-level options to tool invocations during this run. func WithToolOptions(opts []ToolOption) RunOption { return WrapImplSpecificOptFn(func(o *runOptions) { o.toolOptions = opts }) } // WithAgentToolOptions passes agent-level options to a specific sub-agent identified by name. func WithAgentToolOptions(agentName string, opts []RunOption) RunOption { return WrapImplSpecificOptFn(func(o *runOptions) { if o.agentToolOptions == nil { o.agentToolOptions = make(map[string][]RunOption) } o.agentToolOptions[agentName] = opts }) } // WithHistoryModifier sets a function that can trim or transform message history before // each model call. Useful for context-window management. func WithHistoryModifier(fn func(context.Context, []Message) []Message) RunOption { return WrapImplSpecificOptFn(func(o *runOptions) { o.historyModifier = fn }) } // WithAfterToolCallsHook registers a per-run hook that fires synchronously after // all tool calls in a react iteration complete, before the next Model call. // This is suitable for AgentLoop Push+Preempt patterns where the pushed item // must be visible to the next turn's GenInput. func WithAfterToolCallsHook(fn func(ctx context.Context) error) RunOption { return runOptFn(func(o *runOptions) { o.afterToolCallsHook = fn }) } // ---- Agent callbacks (scoped per agent name) ---- // WithAgentErrorCallback registers an error callback for the agent run. // It fires when an agent encounters a non-recoverable error during execution. func WithAgentErrorCallback(fn func(ctx context.Context, err error)) RunOption { return WrapImplSpecificOptFn(func(o *runOptions) { o.callbacks = append(o.callbacks, callbackHandler{onError: fn}) }) } // WithAgentInterruptCallback registers an interrupt callback for the agent run. // It fires when the agent execution is interrupted (e.g., for human-in-the-loop). func WithAgentInterruptCallback(fn func(ctx context.Context, info *InterruptInfo)) RunOption { return WrapImplSpecificOptFn(func(o *runOptions) { o.callbacks = append(o.callbacks, callbackHandler{onInterrupt: fn}) }) } // ---- Cancel option ---- func WithCancel() (RunOption, AgentCancelFunc) { cc := newCancelContext() opt := WrapImplSpecificOptFn(func(o *runOptions) { o.cancelCtx = cc }) return opt, cc.buildCancelFunc() } // ---- Configuration ---- // SetLanguage sets the language for agent prompts. func SetLanguage(lang internal.Language) { internal.SetLanguage(lang) } const ( LanguageEnglish = internal.LanguageEnglish LanguageChinese = internal.LanguageChinese )