Spaces:
Running
Running
File size: 3,302 Bytes
d47b053 | 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 | import type {
StudioAssistantMessage,
StudioPermissionRequest,
StudioProcessorStreamEvent,
StudioRun,
StudioRuntimeTurnPlan,
StudioSession,
StudioSessionStore,
StudioTaskStore,
StudioWorkResultStore,
StudioWorkStore
} from '../../domain/types'
import type { StudioPermissionService } from '../../permissions/permission-service'
import type { StudioToolRegistry } from '../../tools/registry'
import { createStudioToolCallExecutionEvents } from '../tools/tool-call-adapter'
import type {
StudioResolvedSkill,
StudioRuntimeBackedToolContext,
StudioSubagentRunRequest,
StudioSubagentRunResult
} from '../tools/tool-runtime-context'
import type { CustomApiConfig } from '../../../types'
import { throwIfStudioRunCancelled } from './run-cancellation'
interface StudioTurnExecutionOptions {
projectId: string
session: StudioSession
run: StudioRun
assistantMessage: StudioAssistantMessage
plan: StudioRuntimeTurnPlan
registry: StudioToolRegistry
eventBus: StudioRuntimeBackedToolContext['eventBus']
permissionService?: StudioPermissionService
sessionStore?: StudioSessionStore
taskStore?: StudioTaskStore
workStore?: StudioWorkStore
workResultStore?: StudioWorkResultStore
askForConfirmation?: (request: StudioPermissionRequest) => Promise<'once' | 'always' | 'reject'>
runSubagent?: (input: StudioSubagentRunRequest) => Promise<StudioSubagentRunResult>
resolveSkill?: (name: string, session: StudioSession) => Promise<StudioResolvedSkill>
setToolMetadata: (callId: string, metadata: { title?: string; metadata?: Record<string, unknown> }) => void
customApiConfig?: CustomApiConfig
abortSignal?: AbortSignal
}
export async function* createStudioTurnExecutionStream(
input: StudioTurnExecutionOptions
): AsyncGenerator<StudioProcessorStreamEvent> {
const hasAssistantText = Boolean(input.plan.assistantText?.trim())
if (hasAssistantText) {
yield { type: 'text-start' }
yield { type: 'text-delta', text: input.plan.assistantText ?? '' }
yield { type: 'text-end' }
}
for (const toolCall of input.plan.toolCalls ?? []) {
throwIfStudioRunCancelled(input.abortSignal)
const toolInput = asToolInput(toolCall.input)
yield* createStudioToolCallExecutionEvents({
projectId: input.projectId,
session: input.session,
run: input.run,
assistantMessage: input.assistantMessage,
toolCallId: toolCall.callId,
toolName: toolCall.toolName,
toolInput,
registry: input.registry,
eventBus: input.eventBus,
permissionService: input.permissionService,
sessionStore: input.sessionStore,
taskStore: input.taskStore,
workStore: input.workStore,
workResultStore: input.workResultStore,
askForConfirmation: input.askForConfirmation,
runSubagent: input.runSubagent,
resolveSkill: input.resolveSkill,
setToolMetadata: input.setToolMetadata,
customApiConfig: input.customApiConfig,
abortSignal: input.abortSignal,
commentary: hasAssistantText ? null : undefined
})
}
yield { type: 'finish-step' }
}
function asToolInput(input: unknown): Record<string, unknown> {
if (input && typeof input === 'object' && !Array.isArray(input)) {
return input as Record<string, unknown>
}
return {}
}
|