{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../../src/harness/runtime/harness.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Models, RetryPolicy } from \"@earendil-works/pi-ai\";\nimport type { QueueMode } from \"../../types.ts\";\nimport type {\n\tAcquireLaneOptions,\n\tAgentHarness,\n\tAgentHarnessOptions,\n\tAgentLane,\n\tGlobalConfigEventPayload,\n\tLaneInfo,\n\tOpenOperation,\n\tResources,\n} from \"../agent-harness.ts\";\nimport { type CompactionSettings, DEFAULT_COMPACTION_SETTINGS } from \"../compaction/compaction.ts\";\nimport { DEFAULT_RETRY_POLICY, validateCompactionSettings, validateRetryPolicy, validateToolNames } from \"../config.ts\";\nimport type { Context } from \"../context.ts\";\nimport { HarnessEventBus } from \"../events.ts\";\nimport { HookRegistry } from \"../hooks.ts\";\nimport { convertToLlm } from \"../messages.ts\";\nimport { HarnessClosed, HarnessFault, InvalidLane, UnknownTarget } from \"../result.ts\";\nimport { SessionInvariantError } from \"../session/session.ts\";\nimport type { LaneConfiguration, Session } from \"../session/types.ts\";\nimport { branchTip, deleteValue, entryLabel, laneConfig, laneState, sessionName, setValue } from \"../session/values.ts\";\nimport type { AgentHarnessStreamOptions, AgentHarnessTool } from \"../types.ts\";\nimport { Lane } from \"./lane.ts\";\nimport { readLaneStorage, restoreLaneState, restoreSession } from \"./restore.ts\";\nimport { type Config, type LaneState, SliceNotImplemented } from \"./types.ts\";\n\n/** Runtime implementation of AgentHarness. The harness manages lanes but is not itself a lane. */\nexport class Harness<TContext extends object | undefined> implements AgentHarness<TContext> {\n\treadonly session: Session;\n\treadonly models: Models;\n\treadonly hooks: HookRegistry;\n\treadonly events: HarnessEventBus;\n\treadonly lanesByName = new Map<string, Lane<TContext>>();\n\tprivate readonly seed: LaneConfiguration;\n\tprivate readonly configStore: { value: Config<TContext> };\n\tprivate closePromise: Promise<void> | undefined;\n\tprivate closedError: Error | undefined;\n\tprivate faultError: HarnessFault | undefined;\n\n\tconstructor(options: AgentHarnessOptions<TContext>, seed: LaneConfiguration, restored: Map<string, LaneState>) {\n\t\tthis.session = options.session;\n\t\tthis.models = options.models;\n\t\tthis.seed = seed;\n\t\tthis.events = new HarnessEventBus();\n\t\tthis.hooks = new HookRegistry((error, hook, lane, context) =>\n\t\t\tthis.events.emit(\n\t\t\t\t{\n\t\t\t\t\ttype: \"handler_error\",\n\t\t\t\t\tkind: \"hook\",\n\t\t\t\t\thook,\n\t\t\t\t\terror: error.message,\n\t\t\t\t\t...(error.stack === undefined ? {} : { stack: error.stack }),\n\t\t\t\t\tlane,\n\t\t\t\t},\n\t\t\t\tcontext,\n\t\t\t),\n\t\t);\n\t\tthis.configStore = {\n\t\t\tvalue: {\n\t\t\t\ttools: options.tools ?? [],\n\t\t\t\tresources: options.resources ?? {},\n\t\t\t\tstreamOptions: options.streamOptions ?? {},\n\t\t\t\tretryPolicy: options.retry ?? DEFAULT_RETRY_POLICY,\n\t\t\t\tcompaction: options.compaction ?? DEFAULT_COMPACTION_SETTINGS,\n\t\t\t\tsteeringMode: options.steeringMode ?? \"all\",\n\t\t\t\tfollowUpMode: options.followUpMode ?? \"all\",\n\t\t\t\ttoolExecution: options.toolExecution ?? \"parallel\",\n\t\t\t\ttoolContext: options.toolContext,\n\t\t\t\tsystemPrompt: options.systemPrompt,\n\t\t\t\ttoProviderMessages: options.toProviderMessages ?? ((messages) => convertToLlm(messages)),\n\t\t\t\tentryProjectors: options.entryProjectors ?? {},\n\t\t\t},\n\t\t};\n\t\tfor (const [name, state] of restored) this.lanesByName.set(name, this.buildLane(name, state));\n\t}\n\n\tlane(name: string, context: Context): Promise<AgentLane>;\n\tlane(name: string, options: AcquireLaneOptions, context: Context): Promise<AgentLane>;\n\tasync lane(\n\t\tname: string,\n\t\toptionsOrContext: AcquireLaneOptions | Context,\n\t\tmaybeContext?: Context,\n\t): Promise<AgentLane> {\n\t\tthis.assertOpen();\n\t\tif (name.length === 0 || name.includes(\"\\u0000\")) {\n\t\t\tconst reason = name.length === 0 ? \"lane name must not be empty\" : \"lane name must not contain \\\\u0000\";\n\t\t\tthrow new InvalidLane({\n\t\t\t\tlane: name,\n\t\t\t\treason,\n\t\t\t\tmessage: `Invalid lane ${JSON.stringify(name)}: ${reason}`,\n\t\t\t});\n\t\t}\n\t\tconst options = maybeContext === undefined ? {} : (optionsOrContext as AcquireLaneOptions);\n\t\tconst context = maybeContext ?? (optionsOrContext as Context);\n\t\tlet lane: Lane<TContext> | undefined;\n\t\tlet delivery: Promise<void> | undefined;\n\t\ttry {\n\t\t\tawait this.session.mutate(async (mutator) => {\n\t\t\t\tthis.assertOpen();\n\t\t\t\tlane = this.lanesByName.get(name);\n\t\t\t\tif (lane !== undefined) return;\n\n\t\t\t\tconst stored = await readLaneStorage(mutator, name, context);\n\t\t\t\tif (stored.kind === \"lane\") {\n\t\t\t\t\tconst restored = await restoreLaneState(mutator, name, stored, context);\n\t\t\t\t\tlane = this.buildLane(name, restored);\n\t\t\t\t\tthis.lanesByName.set(name, lane);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst tipId = stored.kind === \"branch\" ? stored.tip.value : (options.createAt ?? null);\n\t\t\t\tif (\n\t\t\t\t\tstored.kind === \"absent\" &&\n\t\t\t\t\ttipId !== null &&\n\t\t\t\t\t!(await mutator.getEntries([tipId], context)).has(tipId)\n\t\t\t\t) {\n\t\t\t\t\tthrow new UnknownTarget({\n\t\t\t\t\t\ttargetId: tipId,\n\t\t\t\t\t\tmessage: `Unknown target: ${tipId}`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst attachedConfiguration: LaneConfiguration = {\n\t\t\t\t\tmodel: { ...this.seed.model },\n\t\t\t\t\tthinkingLevel: this.seed.thinkingLevel,\n\t\t\t\t\tactiveToolNames: [...this.seed.activeToolNames],\n\t\t\t\t};\n\t\t\t\tconst state: LaneState = {\n\t\t\t\t\ttipId,\n\t\t\t\t\tconfiguration: attachedConfiguration,\n\t\t\t\t\tinbox: [],\n\t\t\t\t\tlastOperationId: null,\n\t\t\t\t\toperation: null,\n\t\t\t\t};\n\t\t\t\tconst writes = [\n\t\t\t\t\t...(stored.kind === \"absent\" ? [setValue(branchTip(name), tipId)] : []),\n\t\t\t\t\tsetValue(laneConfig(name), attachedConfiguration),\n\t\t\t\t\tsetValue(laneState(name), {\n\t\t\t\t\t\tcurrentOperationId: null,\n\t\t\t\t\t\tlastOperationId: null,\n\t\t\t\t\t\tinbox: [],\n\t\t\t\t\t}),\n\t\t\t\t];\n\t\t\t\tawait mutator.commit(writes, context);\n\t\t\t\tlane = this.buildLane(name, state);\n\t\t\t\tthis.lanesByName.set(name, lane);\n\t\t\t\tdelivery = this.events.emitBatch([{ type: \"lane_created\", lane: name, at: tipId }], context);\n\t\t\t}, context);\n\t\t} catch (error) {\n\t\t\tif (this.closedError !== undefined) throw this.closedError;\n\t\t\tif (error instanceof InvalidLane || error instanceof UnknownTarget) throw error;\n\t\t\tthrow this.fault(error, context);\n\t\t}\n\t\tawait delivery;\n\t\tif (lane === undefined)\n\t\t\tthrow this.fault(new SessionInvariantError(`Lane ${JSON.stringify(name)} was not published`), context);\n\t\treturn lane;\n\t}\n\n\tasync lanes(context: Context): Promise<LaneInfo[]> {\n\t\tthis.assertOpen();\n\t\tconst executions = await Promise.all(\n\t\t\t[...this.lanesByName.values()].map((lane) => lane.inspectExecution(context)),\n\t\t);\n\t\treturn executions.map((execution) => ({\n\t\t\tname: execution.lane,\n\t\t\ttipId: execution.tipId,\n\t\t\toperation: execution.current,\n\t\t}));\n\t}\n\n\tgetName(context: Context): Promise<string | undefined> {\n\t\tthis.assertOpen();\n\t\treturn this.session.getName(context);\n\t}\n\n\tasync setName(name: string | undefined, context: Context): Promise<void> {\n\t\tthis.assertOpen();\n\t\tlet delivery: Promise<void> | undefined;\n\t\ttry {\n\t\t\tawait this.session.mutate(async (mutator) => {\n\t\t\t\tthis.assertOpen();\n\t\t\t\tawait mutator.commit(\n\t\t\t\t\t[name === undefined ? deleteValue(sessionName) : setValue(sessionName, name)],\n\t\t\t\t\tcontext,\n\t\t\t\t);\n\t\t\t\tdelivery = this.events.emitBatch([{ type: \"value_update\", value: \"session_name\", name }], context);\n\t\t\t}, context);\n\t\t} catch (error) {\n\t\t\tif (this.closedError !== undefined) throw this.closedError;\n\t\t\tthrow this.fault(error, context);\n\t\t}\n\t\tawait delivery;\n\t}\n\n\tgetLabel(targetId: string, context: Context): Promise<string | undefined> {\n\t\tthis.assertOpen();\n\t\treturn this.session.getLabel(targetId, context);\n\t}\n\n\tasync setLabel(targetId: string, label: string | undefined, context: Context): Promise<void> {\n\t\tthis.assertOpen();\n\t\tlet delivery: Promise<void> | undefined;\n\t\ttry {\n\t\t\tawait this.session.mutate(async (mutator) => {\n\t\t\t\tthis.assertOpen();\n\t\t\t\tconst address = entryLabel(targetId);\n\t\t\t\tawait mutator.commit([label === undefined ? deleteValue(address) : setValue(address, label)], context);\n\t\t\t\tdelivery = this.events.emitBatch(\n\t\t\t\t\t[{ type: \"value_update\", value: \"entry_label\", targetId, label }],\n\t\t\t\t\tcontext,\n\t\t\t\t);\n\t\t\t}, context);\n\t\t} catch (error) {\n\t\t\tif (this.closedError !== undefined) throw this.closedError;\n\t\t\tthrow this.fault(error, context);\n\t\t}\n\t\tawait delivery;\n\t}\n\n\tgetTools(context: Context): Promise<AgentHarnessTool<TContext>[]> {\n\t\treturn this.getConfig(\"tools\", context);\n\t}\n\n\tsetTools(tools: AgentHarnessTool<TContext>[], context: Context): Promise<void> {\n\t\tvalidateToolNames(tools);\n\t\treturn this.setConfig(\"tools\", tools, () => ({ type: \"config_update\", property: \"tools\" }), context);\n\t}\n\n\tgetResources(context: Context): Promise<Resources> {\n\t\treturn this.getConfig(\"resources\", context);\n\t}\n\n\tsetResources(resources: Resources, context: Context): Promise<void> {\n\t\treturn this.setConfig(\"resources\", resources, () => ({ type: \"config_update\", property: \"resources\" }), context);\n\t}\n\n\tgetStreamOptions(context: Context): Promise<AgentHarnessStreamOptions> {\n\t\treturn this.getConfig(\"streamOptions\", context);\n\t}\n\n\tsetStreamOptions(options: AgentHarnessStreamOptions, context: Context): Promise<void> {\n\t\treturn this.setConfig(\n\t\t\t\"streamOptions\",\n\t\t\toptions,\n\t\t\t(previous, value) => ({ type: \"config_update\", property: \"streamOptions\", previous, value }),\n\t\t\tcontext,\n\t\t);\n\t}\n\n\tgetRetryPolicy(context: Context): Promise<RetryPolicy> {\n\t\treturn this.getConfig(\"retryPolicy\", context);\n\t}\n\n\tsetRetryPolicy(policy: RetryPolicy, context: Context): Promise<void> {\n\t\tvalidateRetryPolicy(policy);\n\t\treturn this.setConfig(\n\t\t\t\"retryPolicy\",\n\t\t\tpolicy,\n\t\t\t(previous, value) => ({ type: \"config_update\", property: \"retryPolicy\", previous, value }),\n\t\t\tcontext,\n\t\t);\n\t}\n\n\tgetCompactionSettings(context: Context): Promise<CompactionSettings> {\n\t\treturn this.getConfig(\"compaction\", context);\n\t}\n\n\tsetCompactionSettings(compaction: CompactionSettings, context: Context): Promise<void> {\n\t\tvalidateCompactionSettings(compaction);\n\t\treturn this.setConfig(\n\t\t\t\"compaction\",\n\t\t\tcompaction,\n\t\t\t(previous, value) => ({ type: \"config_update\", property: \"compactionSettings\", previous, value }),\n\t\t\tcontext,\n\t\t);\n\t}\n\n\tgetSteeringMode(context: Context): Promise<QueueMode> {\n\t\treturn this.getConfig(\"steeringMode\", context);\n\t}\n\n\tsetSteeringMode(steeringMode: QueueMode, context: Context): Promise<void> {\n\t\treturn this.setConfig(\n\t\t\t\"steeringMode\",\n\t\t\tsteeringMode,\n\t\t\t(previous, value) => ({ type: \"config_update\", property: \"steeringMode\", previous, value }),\n\t\t\tcontext,\n\t\t);\n\t}\n\n\tgetFollowUpMode(context: Context): Promise<QueueMode> {\n\t\treturn this.getConfig(\"followUpMode\", context);\n\t}\n\n\tsetFollowUpMode(followUpMode: QueueMode, context: Context): Promise<void> {\n\t\treturn this.setConfig(\n\t\t\t\"followUpMode\",\n\t\t\tfollowUpMode,\n\t\t\t(previous, value) => ({ type: \"config_update\", property: \"followUpMode\", previous, value }),\n\t\t\tcontext,\n\t\t);\n\t}\n\n\tasync watchSession(_context: Context): Promise<never> {\n\t\tthrow new SliceNotImplemented(\"watchSession\");\n\t}\n\n\tfault(cause: unknown, context: Context): Error {\n\t\tif (this.faultError !== undefined) return this.faultError;\n\t\tif (this.closedError !== undefined) return this.closedError;\n\t\tconst normalized = cause instanceof Error ? cause : new Error(String(cause));\n\t\tconst fault = new HarnessFault(\"AgentHarness storage or invariant fault\", normalized);\n\t\tthis.faultError = fault;\n\t\tfor (const lane of this.lanesByName.values()) lane.seal(fault);\n\t\tthis.hooks.close(fault);\n\t\tvoid this.events.emit({ type: \"fault\", code: \"harness_fault\", message: fault.message }, context);\n\t\tthis.events.close(fault);\n\t\treturn fault;\n\t}\n\n\tclose(context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tconst error = new HarnessClosed();\n\t\tthis.closedError = error;\n\t\tconst idleCallbacks = [...this.lanesByName.values()].map((lane) => lane.seal(error));\n\t\tthis.hooks.close(error);\n\t\tthis.events.close(error);\n\t\tconst sessionClose = this.session.close(context);\n\t\tthis.closePromise = Promise.all([sessionClose, ...idleCallbacks]).then(() => undefined);\n\t\treturn this.closePromise;\n\t}\n\n\tprivate buildLane(name: string, state: LaneState): Lane<TContext> {\n\t\treturn new Lane<TContext>(\n\t\t\tname,\n\t\t\tthis.session,\n\t\t\tthis.models,\n\t\t\tthis.hooks,\n\t\t\tstate,\n\t\t\t(cause, context) => this.fault(cause, context),\n\t\t\t(events, context) => this.events.emitBatch(events, context),\n\t\t\t(snapshot, filter, context, resnapshot) => this.events.watch(snapshot, filter, context, resnapshot),\n\t\t\t() => this.configStore.value,\n\t\t);\n\t}\n\n\tprivate async getConfig<TKey extends keyof Config<TContext>>(\n\t\tkey: TKey,\n\t\t_context: Context,\n\t): Promise<Config<TContext>[TKey]> {\n\t\tthis.assertOpen();\n\t\treturn this.configStore.value[key];\n\t}\n\n\tprivate async setConfig<TKey extends keyof Config<TContext>>(\n\t\tkey: TKey,\n\t\tvalue: Config<TContext>[TKey],\n\t\tevent: (previous: Config<TContext>[TKey], value: Config<TContext>[TKey]) => GlobalConfigEventPayload,\n\t\tcontext: Context,\n\t): Promise<void> {\n\t\tthis.assertOpen();\n\t\tconst previous = this.configStore.value[key];\n\t\tthis.configStore.value = { ...this.configStore.value, [key]: value };\n\t\tawait this.events.emit(event(previous, value), context);\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.faultError !== undefined) throw this.faultError;\n\t\tif (this.closedError !== undefined) throw this.closedError;\n\t}\n}\n\n/** Attach runtime without starting provider, tool, hook, or timer effects. */\nexport async function createAgentHarness<TContext extends object | undefined = object | undefined>(\n\toptions: AgentHarnessOptions<TContext>,\n\tcontext: Context,\n): Promise<{ harness: AgentHarness<TContext>; open: OpenOperation[] }> {\n\tconst tools = options.tools ?? [];\n\tvalidateToolNames(tools);\n\tvalidateRetryPolicy(options.retry ?? DEFAULT_RETRY_POLICY);\n\tvalidateCompactionSettings(options.compaction ?? DEFAULT_COMPACTION_SETTINGS);\n\tconst seed: LaneConfiguration = {\n\t\tmodel: { provider: options.model.provider, modelId: options.model.id },\n\t\tthinkingLevel: options.thinkingLevel ?? \"off\",\n\t\tactiveToolNames: [...(options.activeToolNames ?? tools.map((tool) => tool.name))],\n\t};\n\ttry {\n\t\tconst restored = await restoreSession(options.session, context);\n\t\tconst open = [...restored].flatMap(([lane, state]): OpenOperation[] => {\n\t\t\tconst operation = state.operation;\n\t\t\treturn operation === null\n\t\t\t\t? []\n\t\t\t\t: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlane,\n\t\t\t\t\t\t\toperationId: operation.meta.operationId,\n\t\t\t\t\t\t\tkind: operation.meta.intent.kind,\n\t\t\t\t\t\t\tstartedAt: operation.meta.startedAt,\n\t\t\t\t\t\t\t...(operation.state.control.status === \"cancel_requested\" ? { aborting: true as const } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t});\n\t\treturn { harness: new Harness(options, seed, restored), open };\n\t} catch (error) {\n\t\tthrow new HarnessFault(\"AgentHarness storage or invariant fault\", error);\n\t}\n}\n"]}