File size: 3,892 Bytes
abcf568 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | import { StudioRunProcessor } from '../run-processor'
import type {
StudioAssistantMessage,
StudioRun,
StudioSession,
StudioRuntimeTurnPlan,
StudioToolChoice,
} from '../../../domain/types'
import type { CustomApiConfig } from '../../../../types'
import type { StudioSubagentRunRequest, StudioSubagentRunResult } from '../../tools/tool-runtime-context'
import type {
StudioBackgroundRunHandle,
StudioPreparedRunContext,
StudioRunRequestInput,
StudioSessionRunnerDependencies,
StudioSessionRunnerOptions
} from './dependency-center'
import { createAssistantMessage, createRun } from './factory'
import { buildWorkContext, prepareRun } from './preparer'
import { routePreparedRun } from './router'
import { createResolvedPlanExecution } from './execution-factories'
import { executePreparedStream } from './execution-manager'
import { createDependencyCenter } from './dependency-center'
import { runSubagent as executeSubagent } from './subagent-manager'
export class StudioSessionRunner {
private readonly deps: StudioSessionRunnerDependencies
constructor(options: StudioSessionRunnerOptions) {
const processor = new StudioRunProcessor({
messageStore: options.messageStore,
partStore: options.partStore
})
this.deps = createDependencyCenter(options, {
processor,
createRun: (session, inputText, metadata) => createRun(session, inputText, metadata),
createAssistantMessage: (session) => createAssistantMessage({ messageStore: options.messageStore }, session),
buildWorkContext: (input) => buildWorkContext({
workStore: options.workStore,
workResultStore: options.workResultStore,
taskStore: options.taskStore,
sessionEventStore: options.sessionEventStore
}, input),
runSubagent: (input) => this.runSubagent(input)
})
}
async createAssistantMessage(session: StudioSession): Promise<StudioAssistantMessage> {
return createAssistantMessage(this.deps, session)
}
createRun(session: StudioSession, inputText: string, metadata?: Record<string, unknown>): StudioRun {
return createRun(session, inputText, metadata)
}
async run(input: StudioRunRequestInput): Promise<StudioSubagentRunResult & { run: StudioRun; assistantMessage: StudioAssistantMessage }> {
const handle = await this.startBackgroundRun(input)
return handle.completion
}
async startBackgroundRun(input: StudioRunRequestInput): Promise<StudioBackgroundRunHandle> {
const prepared = await prepareRun(this.deps, input)
const abortController = new AbortController()
return {
run: prepared.run,
assistantMessage: prepared.assistantMessage,
abort: (reason?: string) => abortController.abort(reason ?? 'Run cancelled'),
completion: this.executePreparedRun(prepared, abortController.signal)
}
}
async runWithPlan(input: {
projectId: string
session: StudioSession
inputText: string
plan: StudioRuntimeTurnPlan
customApiConfig?: CustomApiConfig
toolChoice?: StudioToolChoice
}): Promise<StudioSubagentRunResult & { run: StudioRun; assistantMessage: StudioAssistantMessage }> {
const prepared = await prepareRun(this.deps, input)
const abortController = new AbortController()
return executePreparedStream(this.deps, prepared, createResolvedPlanExecution(this.deps, {
prepared,
plan: input.plan,
customApiConfig: input.customApiConfig,
toolChoice: input.toolChoice,
abortSignal: abortController.signal,
}), abortController.signal)
}
async runSubagent(input: StudioSubagentRunRequest): Promise<StudioSubagentRunResult> {
return executeSubagent(this.deps, input, (request) => this.run(request))
}
private async executePreparedRun(prepared: StudioPreparedRunContext, abortSignal: AbortSignal) {
return routePreparedRun(this.deps, prepared, abortSignal)
}
}
|