mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 10:45:59 -10:00
A child that shares the parent's provider starts on the depth in force now, and one that inherits the parent's model without an effort of its own is built for it, as a rebuild would have given. The status line reads the depth the session is on.
95 lines
3.3 KiB
Go
95 lines
3.3 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"reasonix/internal/runtime/langpref"
|
|
|
|
"reasonix/internal/contract/event"
|
|
"reasonix/internal/contract/provider"
|
|
"reasonix/internal/contract/tool"
|
|
"reasonix/internal/safety/evidence"
|
|
"reasonix/internal/safety/sandbox"
|
|
"reasonix/internal/state/instruction"
|
|
"reasonix/internal/state/memory"
|
|
"reasonix/internal/tools/jobs"
|
|
)
|
|
|
|
// toolCallContext assembles the context one tool call runs under: the host
|
|
// collaborators it may reach, the evidence scope it writes into, and the turn
|
|
// preferences it must honor. Every binding is optional, so a degraded
|
|
// assembly loses the capability rather than the call.
|
|
func (a *Agent) toolCallContext(ctx context.Context, plan *toolCallPlan) context.Context {
|
|
cctx, spawned := tool.WithProvenanceSink(ctx)
|
|
plan.spawned = spawned
|
|
cctx = tool.WithContextCompressor(WithCallContext(cctx, plan.call.ID, a.svc.sink, a.svc.asker, a.PlanningPhase()), a)
|
|
cctx = tool.WithContextRecaller(cctx, a)
|
|
cctx = tool.WithContextBudgetReporter(cctx, a)
|
|
cctx = tool.WithTranscriptReader(cctx, a)
|
|
cctx = WithSubagentDepth(cctx, a.subagentDepth)
|
|
cctx = WithRequestEffort(cctx, a.sess.effort.get())
|
|
if a.task.ledger != nil {
|
|
cctx = evidence.WithLedger(cctx, a.task.ledger)
|
|
cctx = evidence.WithSessionMessages(cctx, a.sess.conversation.Snapshot)
|
|
cctx = evidence.WithWorkspaceRoot(cctx, a.writeWorkspaceRoot)
|
|
if a.deliveryProfile {
|
|
cctx = evidence.WithDeliveryProfile(cctx)
|
|
}
|
|
}
|
|
if !a.PlanningPhase() {
|
|
cctx = a.withContractState(cctx)
|
|
}
|
|
if plan.planReplacementAuthorized {
|
|
cctx = tool.WithPlanReplacementAuthorization(cctx)
|
|
}
|
|
if len(a.projectChecks) > 0 {
|
|
cctx = instruction.WithChecks(cctx, a.projectChecks)
|
|
}
|
|
if a.svc.jobs != nil {
|
|
cctx = jobs.WithManager(cctx, a.svc.jobs)
|
|
session, manager := jobs.SessionFromContext(cctx), a.svc.jobs
|
|
cctx = tool.WithBackgroundStarter(cctx, func(kind, label string, run func(context.Context, io.Writer) (string, error)) string {
|
|
return manager.StartForSession(session, kind, label, run).ID
|
|
})
|
|
}
|
|
if a.svc.sandboxEscape != nil {
|
|
cctx = sandbox.WithEscapeApprover(cctx, a.svc.sandboxEscape)
|
|
}
|
|
if a.svc.configWrite != nil {
|
|
cctx = tool.WithConfigWriteApprover(cctx, a.svc.configWrite)
|
|
}
|
|
cctx = tool.WithNativeVideo(cctx, a.svc.nativeVideo)
|
|
cctx = tool.WithUserAddresses(cctx, a.userAddresses)
|
|
if a.svc.paidSearch != nil {
|
|
cctx = tool.WithPaidSearchApprover(cctx, a.svc.paidSearch)
|
|
}
|
|
// Whoever answers this run's questions also fills an external party's form.
|
|
if e, ok := a.svc.asker.(tool.Elicitor); ok {
|
|
cctx = tool.WithElicitor(cctx, e)
|
|
}
|
|
if v := a.responseLanguage.Load(); v != nil {
|
|
if lang, ok := v.(string); ok {
|
|
cctx = langpref.WithResponseLanguagePreference(cctx, lang)
|
|
}
|
|
}
|
|
if v := a.reasoningLanguage.Load(); v != nil {
|
|
if lang, ok := v.(string); ok {
|
|
cctx = langpref.WithReasoningLanguagePreference(cctx, lang)
|
|
}
|
|
}
|
|
if a.svc.memQueue != nil {
|
|
cctx = memory.WithQueue(cctx, a.svc.memQueue)
|
|
}
|
|
callID := plan.call.ID
|
|
cctx = tool.WithProgress(cctx, func(chunk string) {
|
|
a.svc.sink.Emit(event.Event{Kind: event.ToolProgress, Tool: event.Tool{ID: callID, Output: chunk}})
|
|
})
|
|
return cctx
|
|
}
|
|
|
|
// Transcript is a copy of this agent's conversation, for a tool that has to
|
|
// read all of it; see tool.TranscriptReader.
|
|
func (a *Agent) Transcript() []provider.Message {
|
|
return a.sess.conversation.Snapshot()
|
|
}
|