@dxos/agent-runtime 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/lib/chunk-AgentService.mjs +189 -93
  2. package/dist/lib/chunk-AgentService.mjs.map +1 -1
  3. package/dist/lib/testing.mjs +3 -3
  4. package/dist/lib/testing.mjs.map +1 -1
  5. package/dist/types/src/agent-service/AgentService.d.ts +9 -0
  6. package/dist/types/src/agent-service/AgentService.d.ts.map +1 -1
  7. package/dist/types/src/agent-service/agent-process.d.ts +23 -5
  8. package/dist/types/src/agent-service/agent-process.d.ts.map +1 -1
  9. package/dist/types/src/agent-service/delegation-strategy.d.ts +5 -4
  10. package/dist/types/src/agent-service/delegation-strategy.d.ts.map +1 -1
  11. package/dist/types/src/agent-service/index.d.ts +1 -1
  12. package/dist/types/src/agent-service/index.d.ts.map +1 -1
  13. package/dist/types/src/agent-service/process-selection.test.d.ts +2 -0
  14. package/dist/types/src/agent-service/process-selection.test.d.ts.map +1 -0
  15. package/dist/types/src/agent-service/skill-hooks.test.d.ts +2 -0
  16. package/dist/types/src/agent-service/skill-hooks.test.d.ts.map +1 -0
  17. package/dist/types/src/testing/assistant-test-layer.d.ts +2 -2
  18. package/dist/types/src/testing/assistant-test-layer.d.ts.map +1 -1
  19. package/dist/types/tsconfig.tsbuildinfo +1 -1
  20. package/package.json +17 -17
  21. package/src/agent-service/AgentService.test.ts +4 -4
  22. package/src/agent-service/AgentService.ts +63 -24
  23. package/src/agent-service/README.md +10 -10
  24. package/src/agent-service/agent-process.ts +201 -100
  25. package/src/agent-service/delegation-scripted.test.ts +4 -4
  26. package/src/agent-service/delegation-strategy.ts +9 -4
  27. package/src/agent-service/index.ts +1 -0
  28. package/src/agent-service/process-selection.test.ts +135 -0
  29. package/src/agent-service/queue-scripted.test.ts +39 -0
  30. package/src/agent-service/redelivery.test.ts +23 -1
  31. package/src/agent-service/skill-hooks.test.ts +182 -0
  32. package/src/testing/assistant-test-layer.ts +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"testing.mjs","names":[],"sources":["../../src/testing/trace-pretty-print.ts","../../src/testing/assistant-test-layer.ts","../../src/testing/test-agent.ts","../../src/testing/ResearchService.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { ConsolePrinter } from '@dxos/ai';\nimport { FeedTraceSink } from '@dxos/compute-runtime';\nimport * as Process from '@dxos/compute/Process';\nimport * as Trace from '@dxos/compute/Trace';\nimport { Database, Filter, Query } from '@dxos/echo';\n\n/**\n * Pretty-prints assistant trace messages to stdout (Trace.CompleteBlock, process spawn/exit).\n */\nexport const prettyPrintTraceMessage = (message: Trace.Message): void => {\n for (const event of message.events) {\n if (Trace.isOfType(Trace.CompleteBlock, event)) {\n const tag = message.meta.processName ?? `${message.meta.pid ?? 'unknown'}`;\n console.log(`[${tag}] ${event.data.role.toUpperCase()}`);\n new ConsolePrinter({ tag }).printContentBlock(event.data.block);\n } else if (Trace.isOfType(Process.SpawnedEvent, event)) {\n console.log(`[${message.meta.pid}] Process spawned: ${message.meta.processName}`);\n } else if (Trace.isOfType(Process.ExitedEvent, event)) {\n console.log(`[${message.meta.pid}] Process exited: ${event.data.outcome}`);\n }\n }\n};\n\n/** {@link Trace.TraceSink} layer that mirrors {@link AssistantTestLayer}'s `tracing: 'pretty'` mode. */\nexport const traceSinkPrettyLayer = (): Layer.Layer<Trace.TraceSink> =>\n Layer.succeed(Trace.TraceSink, {\n write: prettyPrintTraceMessage,\n });\n\n/**\n * Subscribes to the space trace feed and pretty-prints newly appended messages.\n * Returns an unsubscribe function. Requires ambient {@link Database.Service}.\n */\nexport const traceFeedPrettyPrintSubscription = Effect.gen(function* () {\n const feed = yield* FeedTraceSink.getOrCreateTraceFeed();\n const queryResult = yield* Database.query(Query.select(Filter.type(Trace.Message)).from(feed));\n const seen = new Set((yield* Effect.promise(() => queryResult.run())).map((message) => message.id));\n\n return queryResult.subscribe((result) => {\n for (const message of result.results) {\n if (seen.has(message.id)) {\n continue;\n }\n seen.add(message.id);\n prettyPrintTraceMessage(message);\n }\n });\n});\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as LanguageModel from 'effect/ai/LanguageModel';\nimport * as Array from 'effect/Array';\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Match from 'effect/Match';\nimport * as KeyValueStore from 'effect/persistence/KeyValueStore';\nimport * as AtomRegistry from 'effect/reactivity/AtomRegistry';\n\nimport { AiService, OpaqueToolkit, Provider } from '@dxos/ai';\nimport { type AiServicePreset, TestAiService } from '@dxos/ai/testing';\nimport { Alarm, Harness } from '@dxos/assistant';\nimport * as Chat from '@dxos/assistant/Chat';\nimport {\n FeedTraceSink,\n ProcessManager,\n RemoteProcessManager,\n RemoteTraceMonitor,\n TriggerDispatcher,\n TriggerStateStore,\n UnifiedProcessManager,\n configuredCredentialsLayer,\n} from '@dxos/compute-runtime';\nimport { TestDatabaseLayer } from '@dxos/compute-runtime/testing';\nimport * as AgentService from '@dxos/compute/AgentService';\nimport * as Credential from '@dxos/compute/Credential';\nimport * as Instructions from '@dxos/compute/Instructions';\nimport * as Operation from '@dxos/compute/Operation';\nimport * as OperationHandlerSet from '@dxos/compute/OperationHandlerSet';\nimport * as Process from '@dxos/compute/Process';\nimport * as ServiceResolver from '@dxos/compute/ServiceResolver';\nimport * as Skill from '@dxos/compute/Skill';\nimport * as Trace from '@dxos/compute/Trace';\nimport * as Trigger from '@dxos/compute/Trigger';\nimport { Database, Feed, Hypergraph, Registry, Tag, Type } from '@dxos/echo';\nimport { registryLayer } from '@dxos/echo-client';\nimport { type TestContextService } from '@dxos/effect/testing';\nimport { DXN } from '@dxos/keys';\n\nimport { AgentService as AgentServiceRuntime } from '../agent-service/index.ts';\nimport { traceSinkPrettyLayer } from './trace-pretty-print.ts';\n\ninterface TestLayerOptions {\n aiServicePreset?: AiServicePreset;\n\n /**\n * Overrides the AI service entirely (e.g. a scripted model for deterministic e2e tests).\n * When set, `aiServicePreset` and `disableLlmMemoization` are ignored.\n */\n aiService?: Layer.Layer<AiService.AiService>;\n model?: DXN.DXN;\n /** Provider the model resolves through; defaults to `ollama` for the ollama preset, else `edge`. */\n provider?: DXN.DXN;\n operationHandlers?: OperationHandlerSet.OperationHandlerSet | OperationHandlerSet.OperationHandlerSet[];\n toolkits?: OpaqueToolkit.OpaqueToolkit[];\n types?: Type.AnyEntity[];\n skills?: Skill.Skill[];\n credentials?: Credential.ServiceCredential[];\n\n /**\n * Tracing configuration.\n * - `'feed'` persists trace events to a FeedTraceSink (queryable from the database).\n * @default 'noop'\n */\n tracing?: 'noop' | 'console' | 'pretty' | 'feed';\n\n disableLlmMemoization?: boolean;\n\n /**\n * Patterns matching run-specific values (e.g. timestamps derived from TestClock) that should be\n * canonicalized for memoized-conversation matching. Forwarded to `TestAiService`. Opt-in.\n */\n dynamicValuePatterns?: readonly RegExp[];\n\n /**\n * Options for the agent process (system prompt, tool backgrounding, delegation strategy, etc.).\n * The model defaults to the resolved test-layer model when not set here.\n */\n agent?: AgentServiceRuntime.Options;\n\n /**\n * Extra services to make available in the service resolver.\n * Operations can depend on those services. They may themselves require the {@link AgentService.AgentService}\n * (e.g. a service that wakes other conversations), which is served to them once it is built.\n */\n extraServices?: Layer.Layer<never, never, AgentService.AgentService>;\n}\n\nexport type AssistantTestServices =\n | LanguageModel.LanguageModel\n | Credential.CredentialsService\n | AgentService.AgentService\n | AiService.AiService\n | Database.Service\n | Registry.Service\n | OpaqueToolkit.OpaqueToolkitProvider\n | Operation.Service\n | ProcessManager.Service\n | RemoteProcessManager.Service\n | ProcessManager.ProcessOperationInvoker.Service\n | Process.ManagerService\n | AtomRegistry.AtomRegistry\n | OperationHandlerSet.OperationHandlerProvider\n | KeyValueStore.KeyValueStore\n | ServiceResolver.ServiceResolver\n | Trace.TraceService\n | Trace.TraceSink\n | FeedTraceSink.FeedTraceSink;\n\nexport const AssistantTestLayer = (\n options: TestLayerOptions = {},\n): Layer.Layer<AssistantTestServices, never, TestContextService> => {\n const resolvedModel: DXN.DXN =\n options.model ??\n (options.aiServicePreset === 'ollama'\n ? DXN.make('com.openai.model.gpt-oss-20b.default')\n : DXN.make('com.anthropic.model.claude-opus-5.default'));\n\n // The catalog's shared model ids need a provider to resolve; pair the resolved model with the\n // provider its preset registers a resolver for.\n const resolvedProvider: DXN.DXN =\n options.provider ?? (options.aiServicePreset === 'ollama' ? Provider.ollama.id : Provider.edge.id);\n\n const agentOptions: AgentServiceRuntime.Options = { ...options.agent };\n agentOptions.defaultModel ??= resolvedModel;\n agentOptions.provider ??= resolvedProvider;\n\n // The resolver materialises `HarnessService` (Tier B needs `ProcessManager.Service`), but\n // `ProcessManager.layer` requires the `ServiceResolver` — a construction cycle. Resolve it by\n // sharing a late-bound holder: the resolver reads the manager lazily (only at resolution time,\n // when the manager exists), and a downstream layer fills the holder once it is built.\n const processManagerHolder: ProcessManagerHolder = {};\n const agentServiceHolder: AgentServiceHolder = {};\n\n return Layer.empty.pipe(\n // Captures must sit above the layers they read (a provideMerge chain feeds upward).\n Layer.provideMerge(captureAgentService(agentServiceHolder)),\n Layer.provideMerge(ProcessManager.ProcessOperationInvoker.layer),\n Layer.provideMerge(AgentServiceRuntime.layer(agentOptions)),\n Layer.provideMerge(UnifiedProcessManager.layer),\n // A local test stack has no EDGE, so both the manager's remote half and `location: 'edge'` see\n // nothing.\n Layer.provideMerge(RemoteProcessManager.layerNoop),\n Layer.provideMerge(RemoteTraceMonitor.layerNoop),\n Layer.provideMerge(Trace.testTraceService({ meta: { processName: 'test' } })),\n // Order matters: in a `provideMerge` chain each layer's *requirements* are satisfied only by\n // layers added later (whose outputs feed it). `captureProcessManager` needs the manager, the\n // manager needs the `ServiceResolver`, and the resolver needs nothing (it reads the manager via\n // the holder), so they must appear in exactly this order.\n Layer.provideMerge(captureProcessManager(processManagerHolder)),\n Layer.provideMerge(ProcessManager.layer({ idGenerator: ProcessManager.SequentialIdGenerator })),\n Layer.provideMerge(AssistantTestServiceResolverLayer(options, processManagerHolder, agentServiceHolder)),\n Layer.provideMerge(AiService.languageModel(DXN.getName(resolvedModel), { provider: resolvedProvider })),\n Layer.provideMerge(AssistantTestTracingLayer(options.tracing ?? 'noop')),\n Layer.provideMerge(\n options.aiService ??\n TestAiService({\n preset: options.aiServicePreset,\n disableMemoization: options.disableLlmMemoization,\n dynamicValuePatterns: options.dynamicValuePatterns,\n }),\n ),\n Layer.provideMerge(AssistantTestBaseLayer(options)),\n Layer.orDie,\n );\n};\n\n/** Late-bound reference to the {@link ProcessManager.Service}, filled once the manager is built. */\ninterface ProcessManagerHolder {\n current?: Context.Service.Shape<typeof ProcessManager.Service>;\n}\n\n/** Late-bound reference to the {@link AgentService.AgentService}, filled once the service is built. */\ninterface AgentServiceHolder {\n current?: Context.Service.Shape<typeof AgentService.AgentService>;\n}\n\n/** An {@link AgentService.AgentService} that forwards to the holder's, so it can be handed out before that exists. */\nconst lateAgentService = (holder: AgentServiceHolder): Context.Service.Shape<typeof AgentService.AgentService> => ({\n getSession: (chat, options) =>\n Effect.suspend(() =>\n holder.current\n ? holder.current.getSession(chat, options)\n : Effect.die(new Error('AgentService is not built yet.')),\n ),\n hydrate: () =>\n Effect.suspend(() =>\n holder.current ? holder.current.hydrate() : Effect.die(new Error('AgentService is not built yet.')),\n ),\n});\n\n/** Fills the {@link AgentServiceHolder}, letting the resolver serve operations that relay into agent sessions. */\nconst captureAgentService = (holder: AgentServiceHolder): Layer.Layer<never, never, AgentService.AgentService> =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n holder.current = yield* AgentService.AgentService;\n }),\n );\n\n/** Fills the {@link ProcessManagerHolder} once the manager is available, breaking the build cycle. */\nconst captureProcessManager = (holder: ProcessManagerHolder): Layer.Layer<never, never, ProcessManager.Service> =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n holder.current = yield* ProcessManager.Service;\n }),\n );\n\n/**\n * Service resolver for testing.\n */\nexport const AssistantTestServiceResolverLayer = (\n { extraServices = Layer.empty }: Pick<TestLayerOptions, 'extraServices'>,\n processManagerHolder: ProcessManagerHolder,\n agentServiceHolder: AgentServiceHolder = {},\n) =>\n Layer.effect(\n ServiceResolver.ServiceResolver,\n Effect.gen(function* () {\n const services = yield* Effect.context<Database.Service>().pipe(\n Effect.map(Context.pick(Database.Service)),\n Effect.map(Layer.succeedContext),\n );\n\n const { db } = yield* Database.Service;\n\n // v4 dropped `Layer.toRuntime`; a built layer is its service context. The agent service is built\n // after the resolver (it needs it), so extra services reach it through the same late-bound holder.\n const extraServicesContext = yield* Layer.build(\n extraServices.pipe(\n Layer.provide(Layer.succeed(AgentService.AgentService, lateAgentService(agentServiceHolder))),\n ),\n );\n\n return ServiceResolver.compose(\n ServiceResolver.succeed(Harness.HarnessService, (context) =>\n Effect.gen(function* () {\n if (!context.conversation) {\n return yield* Effect.fail(new ServiceResolver.ServiceNotAvailableError(Harness.HarnessService.key));\n }\n // Read the manager lazily: the resolver is invoked at spawn time, by which point the\n // holder has been filled (see the construction-cycle note in `AssistantTestLayer`).\n const processManager = processManagerHolder.current;\n if (!processManager) {\n return yield* Effect.fail(new ServiceResolver.ServiceNotAvailableError(ProcessManager.Service.key));\n }\n const runtime = yield* Effect.context<Database.Service>();\n return yield* Harness.make({ conversation: context.conversation, processManager, runtime });\n }).pipe(Effect.provide(services)),\n ),\n // As the app's client contributes it: operations that look an object up across spaces need it.\n ServiceResolver.succeed(Hypergraph.Service, () => Effect.succeed(Hypergraph.makeService(db.graph))),\n ServiceResolver.succeed(AgentService.AgentService, () =>\n Effect.gen(function* () {\n // Read lazily (like the process manager): filled by `captureAgentService` before any\n // operation resolution runs.\n const agentService = agentServiceHolder.current;\n if (!agentService) {\n return yield* Effect.fail(new ServiceResolver.ServiceNotAvailableError(AgentService.key));\n }\n return agentService;\n }),\n ),\n yield* ServiceResolver.fromRequirements(\n Database.Service,\n OpaqueToolkit.OpaqueToolkitProvider,\n AiService.AiService,\n Registry.Service,\n Credential.CredentialsService,\n ),\n ServiceResolver.fromContext(extraServicesContext),\n );\n }),\n );\n\n/**\n * Only storage + registry.\n */\nexport const AssistantTestBaseLayer = ({\n operationHandlers = [],\n toolkits = [],\n types = [],\n credentials = [],\n skills = [],\n}: Pick<TestLayerOptions, 'operationHandlers' | 'toolkits' | 'types' | 'skills' | 'tracing' | 'credentials'>) => {\n const toolkit = OpaqueToolkit.merge(...toolkits);\n const operationHandlersSet = Array.isArray(operationHandlers)\n ? OperationHandlerSet.merge(...operationHandlers)\n : operationHandlers;\n types.push(\n Skill.Skill,\n Instructions.Instructions,\n Operation.PersistentOperation,\n Feed.Feed,\n // The agent process runs on a chat, so every session — bare ones included — persists one.\n Chat.Chat,\n Trigger.Trigger,\n Tag.Tag,\n Alarm.Alarm,\n );\n types = Array.dedupeWith(types, (a, b) => Type.getTypename(a) === Type.getTypename(b));\n\n return Layer.empty.pipe(\n // A skill referenced by its registry URI resolves through the DATABASE's registry (production\n // wires that up via plugin-instructions' `RegistrySync`), which is not the `Registry.Service`\n // seeded below — so a seeded skill has to land in both, or such a ref silently resolves to\n // nothing and the conversation loses the skill.\n Layer.provideMerge(seedDatabaseRegistry(skills)),\n Layer.provideMerge(\n TestDatabaseLayer({\n spaceKey: 'fixed',\n types,\n }),\n ),\n Layer.provideMerge(configuredCredentialsLayer(credentials)),\n Layer.provideMerge(\n Layer.effect(\n Registry.Service,\n Effect.gen(function* () {\n const handlerSet = yield* OperationHandlerSet.OperationHandlerProvider;\n const registry = yield* Registry.Service;\n const handlers = yield* handlerSet.handlers;\n registry.add(Operation.serializable(handlers));\n return registry;\n }),\n ),\n ),\n Layer.provideMerge(registryLayer({ initial: skills })),\n Layer.provideMerge(OpaqueToolkit.providerLayer(toolkit)),\n Layer.provideMerge(OperationHandlerSet.provide(operationHandlersSet)),\n Layer.provideMerge(KeyValueStore.layerMemory),\n Layer.provideMerge(AtomRegistry.layer),\n Layer.orDie,\n );\n};\n\n/** Registers the seeded skills with the database's registry, so their registry-URI refs resolve. */\nconst seedDatabaseRegistry = (skills: readonly Skill.Skill[]): Layer.Layer<never, never, Database.Service> =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n if (skills.length === 0) {\n return;\n }\n const { db } = yield* Database.Service;\n db.registry.add(skills);\n }),\n );\n\nconst AssistantTestTracingLayer = (\n mode: 'noop' | 'console' | 'pretty' | 'feed',\n): Layer.Layer<FeedTraceSink.FeedTraceSink | Trace.TraceSink, never, Database.Service> =>\n Match.value(mode).pipe(\n Match.when('noop', () => Layer.mergeAll(Trace.layerNoop, FeedTraceSink.layerNoop)),\n Match.when('console', () => Layer.mergeAll(Trace.layerConsole, FeedTraceSink.layerNoop)),\n Match.when('pretty', () => Layer.mergeAll(traceSinkPrettyLayer(), FeedTraceSink.layerNoop)),\n Match.when('feed', () => FeedTraceSink.layerLiveWithDirectSink),\n Match.exhaustive,\n );\n\ninterface TestLayerWithTriggersOptions extends TestLayerOptions {}\n\nexport type AssistantTestServicesWithTriggers = AssistantTestServices | TriggerDispatcher | TriggerStateStore;\n\nexport const AssistantTestLayerWithTriggers = (\n options: TestLayerWithTriggersOptions,\n): Layer.Layer<AssistantTestServicesWithTriggers, never, TestContextService> =>\n // `Layer.provideMerge` (not `Layer.mergeAll`) at each step: `mergeAll` unions requirements without\n // letting sibling layers discharge one another, so `TriggerDispatcher`'s own dependency on\n // `TriggerStateStore`/`ProcessManager.Service`/`Database.Service` needs threading explicitly.\n TriggerDispatcher.layer({ timeControl: 'manual', startingTime: new Date('2025-09-05T15:01:00.000Z') }).pipe(\n Layer.provide(AtomRegistry.layer),\n Layer.provideMerge(TriggerStateStore.layerMemory),\n Layer.provideMerge(AssistantTestLayer(options)),\n );\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport type * as Scope from 'effect/Scope';\nimport * as Stream from 'effect/Stream';\n\nimport type * as AgentService from '@dxos/compute/AgentService';\nimport * as Trace from '@dxos/compute/Trace';\nimport { Database, Feed, Filter, Obj } from '@dxos/echo';\nimport { BaseError, type BaseErrorOptions } from '@dxos/errors';\nimport { Message } from '@dxos/types';\n\n/**\n * Buffered view of a session's ephemeral block events — the headless equivalent of what the chat\n * UI renders while a request streams.\n */\nexport interface EphemeralCollector {\n /** Snapshot of `Trace.PartialBlock` payloads observed so far, in arrival order. */\n partialBlocks: () => readonly Trace.PayloadType<typeof Trace.PartialBlock>[];\n /** Snapshot of `Trace.CompleteBlock` payloads observed so far, in arrival order. */\n completeBlocks: () => readonly Trace.PayloadType<typeof Trace.CompleteBlock>[];\n}\n\n/**\n * Forks a collector over {@link AgentService.Session.subscribeEphemeral} so a test can assert the\n * streaming path (partial → complete blocks) without a UI. The fork is scoped: use with\n * `it.effect` (or an explicit scope) so the subscription is interrupted on test close.\n */\nexport const collectEphemeral = (\n session: AgentService.Session,\n): Effect.Effect<EphemeralCollector, never, Scope.Scope> =>\n Effect.gen(function* () {\n const partial: Trace.PayloadType<typeof Trace.PartialBlock>[] = [];\n const complete: Trace.PayloadType<typeof Trace.CompleteBlock>[] = [];\n yield* session.subscribeEphemeral().pipe(\n Stream.runForEach((message) =>\n Effect.sync(() => {\n for (const event of message.events) {\n if (Trace.isOfType(Trace.PartialBlock, event)) {\n partial.push(event.data);\n } else if (Trace.isOfType(Trace.CompleteBlock, event)) {\n complete.push(event.data);\n }\n }\n }),\n ),\n Effect.forkScoped,\n );\n\n return {\n partialBlocks: () => [...partial],\n completeBlocks: () => [...complete],\n };\n });\n\nexport class WaitForMessageTimeoutError extends BaseError.extend('WaitForMessageTimeoutError') {\n constructor(timeout: number, options?: Omit<BaseErrorOptions, 'context'>) {\n super({\n message: `Timed out after ${timeout}ms waiting for a matching feed message.`,\n context: { timeout },\n ...options,\n });\n }\n}\n\nexport interface WaitForMessageOptions {\n /** Overall deadline in milliseconds. @default 10_000 */\n timeout?: number;\n /** Poll interval in milliseconds. @default 100 */\n interval?: number;\n}\n\n/**\n * Polls the conversation feed until a message matches. Covers the gap left by\n * `Session.waitForCompletion`, which settles when the *turn* completes — background sub-agents\n * report back later, out of band. Polls on the real clock (not the Effect `TestClock`), so it works\n * under `it.effect` and `it.effect` alike.\n */\nexport const waitForMessage = (\n feed: Feed.Feed,\n predicate: (message: Message.Message) => boolean,\n { timeout = 10_000, interval = 100 }: WaitForMessageOptions = {},\n): Effect.Effect<Message.Message, WaitForMessageTimeoutError, Database.Service> =>\n Effect.gen(function* () {\n const deadline = Date.now() + timeout;\n do {\n const items = yield* Feed.query(feed, Filter.type(Message.Message)).run;\n const match = items.filter(Obj.instanceOf(Message.Message)).find(predicate);\n if (match) {\n return match;\n }\n yield* Effect.promise(() => new Promise((resolve) => setTimeout(resolve, interval)));\n } while (Date.now() < deadline);\n\n return yield* Effect.fail(new WaitForMessageTimeoutError(timeout));\n });\n\n/** Convenience predicate: any block's text content contains the substring. */\nexport const messageTextIncludes =\n (needle: string) =>\n (message: Message.Message): boolean =>\n Message.extractText(message).includes(needle);\n","//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Context from 'effect/Context';\nimport * as Deferred from 'effect/Deferred';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Queue from 'effect/Queue';\n\nimport { log } from '@dxos/log';\nimport { Organization } from '@dxos/types';\n\n//\n// Test data.\n//\n\nexport const getTestData = () => ({\n organizations: [\n Organization.make({\n name: 'Cyberdyne Systems',\n website: 'https://cyberdyne.com',\n }),\n Organization.make({\n name: 'Acme Robotics',\n website: 'https://acmerobotics.example',\n }),\n Organization.make({\n name: 'Globex Research',\n website: 'https://globex.example',\n }),\n ],\n research: {\n 'https://cyberdyne.com': `\n Cyberdyne Systems is a company that builds AI agents.\n They are based in San Francisco, California.\n They were founded in 1984.\n They are a public company.\n They are listed on the NASDAQ under the symbol CYBR.\n They are a member of the S&P 500 index.\n `,\n 'https://acmerobotics.example': `\n Acme Robotics designs industrial automation and collaborative robots.\n They are headquartered in Austin, Texas.\n They were founded in 2010.\n They serve manufacturing and logistics customers worldwide.\n `,\n 'https://globex.example': `\n Globex Research runs applied R&D labs focused on materials science and energy storage.\n They are based in Cambridge, Massachusetts.\n They partner with universities and government grants programs.\n Their flagship product line is solid-state battery prototypes for EVs.\n `,\n } as Record<string, string>,\n});\n\nexport interface Task {\n id: string;\n state: 'pending' | 'completed' | 'interrupted';\n website: string;\n deferred: Deferred.Deferred<string>;\n}\n\nexport interface Service {\n getTasks: () => readonly Task[];\n research: (website: string) => Effect.Effect<string>;\n waitForTaskToAppear: () => Effect.Effect<void>;\n completeOneTask: () => Effect.Effect<void>;\n completeAllTasks: () => Effect.Effect<void>;\n}\n\nexport class ResearchService extends Context.Service<ResearchService, Service>()(\n '@dxos/functions-runtime/testing/ResearchService',\n) {}\n\nexport const layer = Layer.effect(\n ResearchService,\n Effect.gen(function* () {\n const taskSignal = yield* Queue.unbounded<void>();\n const tasks: Task[] = [];\n const complete = (task: Task) =>\n Effect.gen(function* () {\n log.info('complete research', { id: task.id, website: task.website });\n task.state = 'completed';\n const result = getTestData().research[task.website];\n if (!result) {\n return yield* Effect.die(new Error(`No research found for ${task.website}`));\n }\n yield* Deferred.succeed(task.deferred, result);\n });\n\n return ResearchService.of({\n getTasks: () => tasks,\n research: (website: string) =>\n Effect.gen(function* () {\n const id = crypto.randomUUID();\n const task: Task = { id, state: 'pending', website, deferred: yield* Deferred.make<string>() };\n log.info('start research', { id, website });\n tasks.push(task);\n yield* Queue.offer(taskSignal, undefined);\n return yield* Deferred.await(task.deferred).pipe(\n Effect.onInterrupt(() =>\n Effect.sync(() => {\n log.info('interrupt research', { id, website: task.website });\n task.state = 'interrupted';\n }),\n ),\n );\n }),\n waitForTaskToAppear: () =>\n Effect.gen(function* () {\n while (true) {\n const task = tasks.find((t) => t.state === 'pending');\n if (task) {\n return;\n }\n yield* Queue.take(taskSignal);\n }\n }),\n completeOneTask: () =>\n Effect.gen(function* () {\n const task = tasks.find((t) => t.state === 'pending');\n if (!task) {\n return;\n }\n yield* complete(task);\n }),\n completeAllTasks: () =>\n Effect.gen(function* () {\n while (true) {\n const task = tasks.find((t) => t.state === 'pending');\n if (!task) {\n return;\n }\n yield* complete(task);\n }\n }),\n });\n }),\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"testing.mjs","names":[],"sources":["../../src/testing/trace-pretty-print.ts","../../src/testing/assistant-test-layer.ts","../../src/testing/test-agent.ts","../../src/testing/ResearchService.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { ConsolePrinter } from '@dxos/ai';\nimport { FeedTraceSink } from '@dxos/compute-runtime';\nimport * as Process from '@dxos/compute/Process';\nimport * as Trace from '@dxos/compute/Trace';\nimport { Database, Filter, Query } from '@dxos/echo';\n\n/**\n * Pretty-prints assistant trace messages to stdout (Trace.CompleteBlock, process spawn/exit).\n */\nexport const prettyPrintTraceMessage = (message: Trace.Message): void => {\n for (const event of message.events) {\n if (Trace.isOfType(Trace.CompleteBlock, event)) {\n const tag = message.meta.processName ?? `${message.meta.pid ?? 'unknown'}`;\n console.log(`[${tag}] ${event.data.role.toUpperCase()}`);\n new ConsolePrinter({ tag }).printContentBlock(event.data.block);\n } else if (Trace.isOfType(Process.SpawnedEvent, event)) {\n console.log(`[${message.meta.pid}] Process spawned: ${message.meta.processName}`);\n } else if (Trace.isOfType(Process.ExitedEvent, event)) {\n console.log(`[${message.meta.pid}] Process exited: ${event.data.outcome}`);\n }\n }\n};\n\n/** {@link Trace.TraceSink} layer that mirrors {@link AssistantTestLayer}'s `tracing: 'pretty'` mode. */\nexport const traceSinkPrettyLayer = (): Layer.Layer<Trace.TraceSink> =>\n Layer.succeed(Trace.TraceSink, {\n write: prettyPrintTraceMessage,\n });\n\n/**\n * Subscribes to the space trace feed and pretty-prints newly appended messages.\n * Returns an unsubscribe function. Requires ambient {@link Database.Service}.\n */\nexport const traceFeedPrettyPrintSubscription = Effect.gen(function* () {\n const feed = yield* FeedTraceSink.getOrCreateTraceFeed();\n const queryResult = yield* Database.query(Query.select(Filter.type(Trace.Message)).from(feed));\n const seen = new Set((yield* Effect.promise(() => queryResult.run())).map((message) => message.id));\n\n return queryResult.subscribe((result) => {\n for (const message of result.results) {\n if (seen.has(message.id)) {\n continue;\n }\n seen.add(message.id);\n prettyPrintTraceMessage(message);\n }\n });\n});\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as LanguageModel from 'effect/ai/LanguageModel';\nimport * as Array from 'effect/Array';\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Match from 'effect/Match';\nimport * as KeyValueStore from 'effect/persistence/KeyValueStore';\nimport * as AtomRegistry from 'effect/reactivity/AtomRegistry';\n\nimport { AiService, OpaqueToolkit, Provider } from '@dxos/ai';\nimport { type AiServicePreset, TestAiService } from '@dxos/ai/testing';\nimport { Alarm, Harness } from '@dxos/assistant';\nimport * as Chat from '@dxos/assistant/Chat';\nimport {\n FeedTraceSink,\n ProcessManager,\n ProcessOperationInvoker,\n RemoteProcessManager,\n RemoteTraceMonitor,\n TriggerDispatcher,\n TriggerStateStore,\n UnifiedProcessManager,\n configuredCredentialsLayer,\n} from '@dxos/compute-runtime';\nimport { TestDatabaseLayer } from '@dxos/compute-runtime/testing';\nimport * as AgentService from '@dxos/compute/AgentService';\nimport * as Credential from '@dxos/compute/Credential';\nimport * as Instructions from '@dxos/compute/Instructions';\nimport * as Operation from '@dxos/compute/Operation';\nimport * as OperationHandlerSet from '@dxos/compute/OperationHandlerSet';\nimport * as Process from '@dxos/compute/Process';\nimport * as ServiceResolver from '@dxos/compute/ServiceResolver';\nimport * as Skill from '@dxos/compute/Skill';\nimport * as Trace from '@dxos/compute/Trace';\nimport * as Trigger from '@dxos/compute/Trigger';\nimport { Database, Feed, Hypergraph, Registry, Tag, Type } from '@dxos/echo';\nimport { registryLayer } from '@dxos/echo-client';\nimport { type TestContextService } from '@dxos/effect/testing';\nimport { DXN } from '@dxos/keys';\n\nimport { AgentService as AgentServiceRuntime } from '../agent-service/index.ts';\nimport { traceSinkPrettyLayer } from './trace-pretty-print.ts';\n\ninterface TestLayerOptions {\n aiServicePreset?: AiServicePreset;\n\n /**\n * Overrides the AI service entirely (e.g. a scripted model for deterministic e2e tests).\n * When set, `aiServicePreset` and `disableLlmMemoization` are ignored.\n */\n aiService?: Layer.Layer<AiService.AiService>;\n model?: DXN.DXN;\n /** Provider the model resolves through; defaults to `ollama` for the ollama preset, else `edge`. */\n provider?: DXN.DXN;\n operationHandlers?: OperationHandlerSet.OperationHandlerSet | OperationHandlerSet.OperationHandlerSet[];\n toolkits?: OpaqueToolkit.OpaqueToolkit[];\n types?: Type.AnyEntity[];\n skills?: Skill.Skill[];\n credentials?: Credential.ServiceCredential[];\n\n /**\n * Tracing configuration.\n * - `'feed'` persists trace events to a FeedTraceSink (queryable from the database).\n * @default 'noop'\n */\n tracing?: 'noop' | 'console' | 'pretty' | 'feed';\n\n disableLlmMemoization?: boolean;\n\n /**\n * Patterns matching run-specific values (e.g. timestamps derived from TestClock) that should be\n * canonicalized for memoized-conversation matching. Forwarded to `TestAiService`. Opt-in.\n */\n dynamicValuePatterns?: readonly RegExp[];\n\n /**\n * Options for the agent process (system prompt, tool backgrounding, delegation strategy, etc.).\n * The model defaults to the resolved test-layer model when not set here.\n */\n agent?: AgentServiceRuntime.Options;\n\n /**\n * Extra services to make available in the service resolver.\n * Operations can depend on those services. They may themselves require the {@link AgentService.AgentService}\n * (e.g. a service that wakes other conversations), which is served to them once it is built.\n */\n extraServices?: Layer.Layer<never, never, AgentService.AgentService>;\n}\n\nexport type AssistantTestServices =\n | LanguageModel.LanguageModel\n | Credential.CredentialsService\n | AgentService.AgentService\n | AiService.AiService\n | Database.Service\n | Registry.Service\n | OpaqueToolkit.OpaqueToolkitProvider\n | Operation.Service\n | ProcessManager.Service\n | RemoteProcessManager.Service\n | ProcessOperationInvoker.Service\n | Process.ManagerService\n | AtomRegistry.AtomRegistry\n | OperationHandlerSet.OperationHandlerProvider\n | KeyValueStore.KeyValueStore\n | ServiceResolver.ServiceResolver\n | Trace.TraceService\n | Trace.TraceSink\n | FeedTraceSink.FeedTraceSink;\n\nexport const AssistantTestLayer = (\n options: TestLayerOptions = {},\n): Layer.Layer<AssistantTestServices, never, TestContextService> => {\n const resolvedModel: DXN.DXN =\n options.model ??\n (options.aiServicePreset === 'ollama'\n ? DXN.make('com.openai.model.gpt-oss-20b.default')\n : DXN.make('com.anthropic.model.claude-opus-5.default'));\n\n // The catalog's shared model ids need a provider to resolve; pair the resolved model with the\n // provider its preset registers a resolver for.\n const resolvedProvider: DXN.DXN =\n options.provider ?? (options.aiServicePreset === 'ollama' ? Provider.ollama.id : Provider.edge.id);\n\n const agentOptions: AgentServiceRuntime.Options = { ...options.agent };\n agentOptions.defaultModel ??= resolvedModel;\n agentOptions.provider ??= resolvedProvider;\n\n // The resolver materialises `HarnessService` (Tier B needs `ProcessManager.Service`), but\n // `ProcessManager.layer` requires the `ServiceResolver` — a construction cycle. Resolve it by\n // sharing a late-bound holder: the resolver reads the manager lazily (only at resolution time,\n // when the manager exists), and a downstream layer fills the holder once it is built.\n const processManagerHolder: ProcessManagerHolder = {};\n const agentServiceHolder: AgentServiceHolder = {};\n\n return Layer.empty.pipe(\n // Captures must sit above the layers they read (a provideMerge chain feeds upward).\n Layer.provideMerge(captureAgentService(agentServiceHolder)),\n Layer.provideMerge(ProcessOperationInvoker.layer),\n Layer.provideMerge(AgentServiceRuntime.layer(agentOptions)),\n Layer.provideMerge(UnifiedProcessManager.layer),\n // A local test stack has no EDGE, so both the manager's remote half and `location: 'edge'` see\n // nothing.\n Layer.provideMerge(RemoteProcessManager.layerNoop),\n Layer.provideMerge(RemoteTraceMonitor.layerNoop),\n Layer.provideMerge(Trace.testTraceService({ meta: { processName: 'test' } })),\n // Order matters: in a `provideMerge` chain each layer's *requirements* are satisfied only by\n // layers added later (whose outputs feed it). `captureProcessManager` needs the manager, the\n // manager needs the `ServiceResolver`, and the resolver needs nothing (it reads the manager via\n // the holder), so they must appear in exactly this order.\n Layer.provideMerge(captureProcessManager(processManagerHolder)),\n Layer.provideMerge(ProcessManager.layer({ idGenerator: ProcessManager.SequentialIdGenerator })),\n Layer.provideMerge(AssistantTestServiceResolverLayer(options, processManagerHolder, agentServiceHolder)),\n Layer.provideMerge(AiService.languageModel(DXN.getName(resolvedModel), { provider: resolvedProvider })),\n Layer.provideMerge(AssistantTestTracingLayer(options.tracing ?? 'noop')),\n Layer.provideMerge(\n options.aiService ??\n TestAiService({\n preset: options.aiServicePreset,\n disableMemoization: options.disableLlmMemoization,\n dynamicValuePatterns: options.dynamicValuePatterns,\n }),\n ),\n Layer.provideMerge(AssistantTestBaseLayer(options)),\n Layer.orDie,\n );\n};\n\n/** Late-bound reference to the {@link ProcessManager.Service}, filled once the manager is built. */\ninterface ProcessManagerHolder {\n current?: Context.Service.Shape<typeof ProcessManager.Service>;\n}\n\n/** Late-bound reference to the {@link AgentService.AgentService}, filled once the service is built. */\ninterface AgentServiceHolder {\n current?: Context.Service.Shape<typeof AgentService.AgentService>;\n}\n\n/** An {@link AgentService.AgentService} that forwards to the holder's, so it can be handed out before that exists. */\nconst lateAgentService = (holder: AgentServiceHolder): Context.Service.Shape<typeof AgentService.AgentService> => ({\n getSession: (chat, options) =>\n Effect.suspend(() =>\n holder.current\n ? holder.current.getSession(chat, options)\n : Effect.die(new Error('AgentService is not built yet.')),\n ),\n hydrate: () =>\n Effect.suspend(() =>\n holder.current ? holder.current.hydrate() : Effect.die(new Error('AgentService is not built yet.')),\n ),\n});\n\n/** Fills the {@link AgentServiceHolder}, letting the resolver serve operations that relay into agent sessions. */\nconst captureAgentService = (holder: AgentServiceHolder): Layer.Layer<never, never, AgentService.AgentService> =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n holder.current = yield* AgentService.AgentService;\n }),\n );\n\n/** Fills the {@link ProcessManagerHolder} once the manager is available, breaking the build cycle. */\nconst captureProcessManager = (holder: ProcessManagerHolder): Layer.Layer<never, never, ProcessManager.Service> =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n holder.current = yield* ProcessManager.Service;\n }),\n );\n\n/**\n * Service resolver for testing.\n */\nexport const AssistantTestServiceResolverLayer = (\n { extraServices = Layer.empty }: Pick<TestLayerOptions, 'extraServices'>,\n processManagerHolder: ProcessManagerHolder,\n agentServiceHolder: AgentServiceHolder = {},\n) =>\n Layer.effect(\n ServiceResolver.ServiceResolver,\n Effect.gen(function* () {\n const services = yield* Effect.context<Database.Service>().pipe(\n Effect.map(Context.pick(Database.Service)),\n Effect.map(Layer.succeedContext),\n );\n\n const { db } = yield* Database.Service;\n\n // v4 dropped `Layer.toRuntime`; a built layer is its service context. The agent service is built\n // after the resolver (it needs it), so extra services reach it through the same late-bound holder.\n const extraServicesContext = yield* Layer.build(\n extraServices.pipe(\n Layer.provide(Layer.succeed(AgentService.AgentService, lateAgentService(agentServiceHolder))),\n ),\n );\n\n return ServiceResolver.compose(\n ServiceResolver.succeed(Harness.HarnessService, (context) =>\n Effect.gen(function* () {\n if (!context.conversation) {\n return yield* Effect.fail(new ServiceResolver.ServiceNotAvailableError(Harness.HarnessService.key));\n }\n // Read the manager lazily: the resolver is invoked at spawn time, by which point the\n // holder has been filled (see the construction-cycle note in `AssistantTestLayer`).\n const processManager = processManagerHolder.current;\n if (!processManager) {\n return yield* Effect.fail(new ServiceResolver.ServiceNotAvailableError(ProcessManager.Service.key));\n }\n const runtime = yield* Effect.context<Database.Service>();\n return yield* Harness.make({ conversation: context.conversation, processManager, runtime });\n }).pipe(Effect.provide(services)),\n ),\n // As the app's client contributes it: operations that look an object up across spaces need it.\n ServiceResolver.succeed(Hypergraph.Service, () => Effect.succeed(Hypergraph.makeService(db.graph))),\n ServiceResolver.succeed(AgentService.AgentService, () =>\n Effect.gen(function* () {\n // Read lazily (like the process manager): filled by `captureAgentService` before any\n // operation resolution runs.\n const agentService = agentServiceHolder.current;\n if (!agentService) {\n return yield* Effect.fail(new ServiceResolver.ServiceNotAvailableError(AgentService.key));\n }\n return agentService;\n }),\n ),\n yield* ServiceResolver.fromRequirements(\n Database.Service,\n OpaqueToolkit.OpaqueToolkitProvider,\n AiService.AiService,\n Registry.Service,\n Credential.CredentialsService,\n ),\n ServiceResolver.fromContext(extraServicesContext),\n );\n }),\n );\n\n/**\n * Only storage + registry.\n */\nexport const AssistantTestBaseLayer = ({\n operationHandlers = [],\n toolkits = [],\n types = [],\n credentials = [],\n skills = [],\n}: Pick<TestLayerOptions, 'operationHandlers' | 'toolkits' | 'types' | 'skills' | 'tracing' | 'credentials'>) => {\n const toolkit = OpaqueToolkit.merge(...toolkits);\n const operationHandlersSet = Array.isArray(operationHandlers)\n ? OperationHandlerSet.merge(...operationHandlers)\n : operationHandlers;\n types.push(\n Skill.Skill,\n Instructions.Instructions,\n Operation.PersistentOperation,\n Feed.Feed,\n // The agent process runs on a chat, so every session — bare ones included — persists one.\n Chat.Chat,\n Trigger.Trigger,\n Tag.Tag,\n Alarm.Alarm,\n );\n types = Array.dedupeWith(types, (a, b) => Type.getTypename(a) === Type.getTypename(b));\n\n return Layer.empty.pipe(\n // A skill referenced by its registry URI resolves through the DATABASE's registry (production\n // wires that up via plugin-instructions' `RegistrySync`), which is not the `Registry.Service`\n // seeded below — so a seeded skill has to land in both, or such a ref silently resolves to\n // nothing and the conversation loses the skill.\n Layer.provideMerge(seedDatabaseRegistry(skills)),\n Layer.provideMerge(\n TestDatabaseLayer({\n spaceKey: 'fixed',\n types,\n }),\n ),\n Layer.provideMerge(configuredCredentialsLayer(credentials)),\n Layer.provideMerge(\n Layer.effect(\n Registry.Service,\n Effect.gen(function* () {\n const handlerSet = yield* OperationHandlerSet.OperationHandlerProvider;\n const registry = yield* Registry.Service;\n const handlers = yield* handlerSet.handlers;\n registry.add(Operation.serializable(handlers));\n return registry;\n }),\n ),\n ),\n Layer.provideMerge(registryLayer({ initial: skills })),\n Layer.provideMerge(OpaqueToolkit.providerLayer(toolkit)),\n Layer.provideMerge(OperationHandlerSet.provide(operationHandlersSet)),\n Layer.provideMerge(KeyValueStore.layerMemory),\n Layer.provideMerge(AtomRegistry.layer),\n Layer.orDie,\n );\n};\n\n/** Registers the seeded skills with the database's registry, so their registry-URI refs resolve. */\nconst seedDatabaseRegistry = (skills: readonly Skill.Skill[]): Layer.Layer<never, never, Database.Service> =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n if (skills.length === 0) {\n return;\n }\n const { db } = yield* Database.Service;\n db.registry.add(skills);\n }),\n );\n\nconst AssistantTestTracingLayer = (\n mode: 'noop' | 'console' | 'pretty' | 'feed',\n): Layer.Layer<FeedTraceSink.FeedTraceSink | Trace.TraceSink, never, Database.Service> =>\n Match.value(mode).pipe(\n Match.when('noop', () => Layer.mergeAll(Trace.layerNoop, FeedTraceSink.layerNoop)),\n Match.when('console', () => Layer.mergeAll(Trace.layerConsole, FeedTraceSink.layerNoop)),\n Match.when('pretty', () => Layer.mergeAll(traceSinkPrettyLayer(), FeedTraceSink.layerNoop)),\n Match.when('feed', () => FeedTraceSink.layerLiveWithDirectSink),\n Match.exhaustive,\n );\n\ninterface TestLayerWithTriggersOptions extends TestLayerOptions {}\n\nexport type AssistantTestServicesWithTriggers = AssistantTestServices | TriggerDispatcher | TriggerStateStore;\n\nexport const AssistantTestLayerWithTriggers = (\n options: TestLayerWithTriggersOptions,\n): Layer.Layer<AssistantTestServicesWithTriggers, never, TestContextService> =>\n // `Layer.provideMerge` (not `Layer.mergeAll`) at each step: `mergeAll` unions requirements without\n // letting sibling layers discharge one another, so `TriggerDispatcher`'s own dependency on\n // `TriggerStateStore`/`ProcessManager.Service`/`Database.Service` needs threading explicitly.\n TriggerDispatcher.layer({ timeControl: 'manual', startingTime: new Date('2025-09-05T15:01:00.000Z') }).pipe(\n Layer.provide(AtomRegistry.layer),\n Layer.provideMerge(TriggerStateStore.layerMemory),\n Layer.provideMerge(AssistantTestLayer(options)),\n );\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport type * as Scope from 'effect/Scope';\nimport * as Stream from 'effect/Stream';\n\nimport type * as AgentService from '@dxos/compute/AgentService';\nimport * as Trace from '@dxos/compute/Trace';\nimport { Database, Feed, Filter, Obj } from '@dxos/echo';\nimport { BaseError, type BaseErrorOptions } from '@dxos/errors';\nimport { Message } from '@dxos/types';\n\n/**\n * Buffered view of a session's ephemeral block events — the headless equivalent of what the chat\n * UI renders while a request streams.\n */\nexport interface EphemeralCollector {\n /** Snapshot of `Trace.PartialBlock` payloads observed so far, in arrival order. */\n partialBlocks: () => readonly Trace.PayloadType<typeof Trace.PartialBlock>[];\n /** Snapshot of `Trace.CompleteBlock` payloads observed so far, in arrival order. */\n completeBlocks: () => readonly Trace.PayloadType<typeof Trace.CompleteBlock>[];\n}\n\n/**\n * Forks a collector over {@link AgentService.Session.subscribeEphemeral} so a test can assert the\n * streaming path (partial → complete blocks) without a UI. The fork is scoped: use with\n * `it.effect` (or an explicit scope) so the subscription is interrupted on test close.\n */\nexport const collectEphemeral = (\n session: AgentService.Session,\n): Effect.Effect<EphemeralCollector, never, Scope.Scope> =>\n Effect.gen(function* () {\n const partial: Trace.PayloadType<typeof Trace.PartialBlock>[] = [];\n const complete: Trace.PayloadType<typeof Trace.CompleteBlock>[] = [];\n yield* session.subscribeEphemeral().pipe(\n Stream.runForEach((message) =>\n Effect.sync(() => {\n for (const event of message.events) {\n if (Trace.isOfType(Trace.PartialBlock, event)) {\n partial.push(event.data);\n } else if (Trace.isOfType(Trace.CompleteBlock, event)) {\n complete.push(event.data);\n }\n }\n }),\n ),\n Effect.forkScoped,\n );\n\n return {\n partialBlocks: () => [...partial],\n completeBlocks: () => [...complete],\n };\n });\n\nexport class WaitForMessageTimeoutError extends BaseError.extend('WaitForMessageTimeoutError') {\n constructor(timeout: number, options?: Omit<BaseErrorOptions, 'context'>) {\n super({\n message: `Timed out after ${timeout}ms waiting for a matching feed message.`,\n context: { timeout },\n ...options,\n });\n }\n}\n\nexport interface WaitForMessageOptions {\n /** Overall deadline in milliseconds. @default 10_000 */\n timeout?: number;\n /** Poll interval in milliseconds. @default 100 */\n interval?: number;\n}\n\n/**\n * Polls the conversation feed until a message matches. Covers the gap left by\n * `Session.waitForCompletion`, which settles when the *turn* completes — background sub-agents\n * report back later, out of band. Polls on the real clock (not the Effect `TestClock`), so it works\n * under `it.effect` and `it.effect` alike.\n */\nexport const waitForMessage = (\n feed: Feed.Feed,\n predicate: (message: Message.Message) => boolean,\n { timeout = 10_000, interval = 100 }: WaitForMessageOptions = {},\n): Effect.Effect<Message.Message, WaitForMessageTimeoutError, Database.Service> =>\n Effect.gen(function* () {\n const deadline = Date.now() + timeout;\n do {\n const items = yield* Feed.query(feed, Filter.type(Message.Message)).run;\n const match = items.filter(Obj.instanceOf(Message.Message)).find(predicate);\n if (match) {\n return match;\n }\n yield* Effect.promise(() => new Promise((resolve) => setTimeout(resolve, interval)));\n } while (Date.now() < deadline);\n\n return yield* Effect.fail(new WaitForMessageTimeoutError(timeout));\n });\n\n/** Convenience predicate: any block's text content contains the substring. */\nexport const messageTextIncludes =\n (needle: string) =>\n (message: Message.Message): boolean =>\n Message.extractText(message).includes(needle);\n","//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Context from 'effect/Context';\nimport * as Deferred from 'effect/Deferred';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Queue from 'effect/Queue';\n\nimport { log } from '@dxos/log';\nimport { Organization } from '@dxos/types';\n\n//\n// Test data.\n//\n\nexport const getTestData = () => ({\n organizations: [\n Organization.make({\n name: 'Cyberdyne Systems',\n website: 'https://cyberdyne.com',\n }),\n Organization.make({\n name: 'Acme Robotics',\n website: 'https://acmerobotics.example',\n }),\n Organization.make({\n name: 'Globex Research',\n website: 'https://globex.example',\n }),\n ],\n research: {\n 'https://cyberdyne.com': `\n Cyberdyne Systems is a company that builds AI agents.\n They are based in San Francisco, California.\n They were founded in 1984.\n They are a public company.\n They are listed on the NASDAQ under the symbol CYBR.\n They are a member of the S&P 500 index.\n `,\n 'https://acmerobotics.example': `\n Acme Robotics designs industrial automation and collaborative robots.\n They are headquartered in Austin, Texas.\n They were founded in 2010.\n They serve manufacturing and logistics customers worldwide.\n `,\n 'https://globex.example': `\n Globex Research runs applied R&D labs focused on materials science and energy storage.\n They are based in Cambridge, Massachusetts.\n They partner with universities and government grants programs.\n Their flagship product line is solid-state battery prototypes for EVs.\n `,\n } as Record<string, string>,\n});\n\nexport interface Task {\n id: string;\n state: 'pending' | 'completed' | 'interrupted';\n website: string;\n deferred: Deferred.Deferred<string>;\n}\n\nexport interface Service {\n getTasks: () => readonly Task[];\n research: (website: string) => Effect.Effect<string>;\n waitForTaskToAppear: () => Effect.Effect<void>;\n completeOneTask: () => Effect.Effect<void>;\n completeAllTasks: () => Effect.Effect<void>;\n}\n\nexport class ResearchService extends Context.Service<ResearchService, Service>()(\n '@dxos/functions-runtime/testing/ResearchService',\n) {}\n\nexport const layer = Layer.effect(\n ResearchService,\n Effect.gen(function* () {\n const taskSignal = yield* Queue.unbounded<void>();\n const tasks: Task[] = [];\n const complete = (task: Task) =>\n Effect.gen(function* () {\n log.info('complete research', { id: task.id, website: task.website });\n task.state = 'completed';\n const result = getTestData().research[task.website];\n if (!result) {\n return yield* Effect.die(new Error(`No research found for ${task.website}`));\n }\n yield* Deferred.succeed(task.deferred, result);\n });\n\n return ResearchService.of({\n getTasks: () => tasks,\n research: (website: string) =>\n Effect.gen(function* () {\n const id = crypto.randomUUID();\n const task: Task = { id, state: 'pending', website, deferred: yield* Deferred.make<string>() };\n log.info('start research', { id, website });\n tasks.push(task);\n yield* Queue.offer(taskSignal, undefined);\n return yield* Deferred.await(task.deferred).pipe(\n Effect.onInterrupt(() =>\n Effect.sync(() => {\n log.info('interrupt research', { id, website: task.website });\n task.state = 'interrupted';\n }),\n ),\n );\n }),\n waitForTaskToAppear: () =>\n Effect.gen(function* () {\n while (true) {\n const task = tasks.find((t) => t.state === 'pending');\n if (task) {\n return;\n }\n yield* Queue.take(taskSignal);\n }\n }),\n completeOneTask: () =>\n Effect.gen(function* () {\n const task = tasks.find((t) => t.state === 'pending');\n if (!task) {\n return;\n }\n yield* complete(task);\n }),\n completeAllTasks: () =>\n Effect.gen(function* () {\n while (true) {\n const task = tasks.find((t) => t.state === 'pending');\n if (!task) {\n return;\n }\n yield* complete(task);\n }\n }),\n });\n }),\n);\n"],"mappings":"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"}
@@ -5,6 +5,7 @@ import * as Process from '@dxos/compute/Process';
5
5
  import * as Skill from '@dxos/compute/Skill';
6
6
  import { Database, Obj, Ref, Registry } from '@dxos/echo';
7
7
  import { DXN } from '@dxos/keys';
8
+ import { type AgentProcessDefinition } from './agent-process.ts';
8
9
  import { type DelegationStrategy } from './delegation-strategy.ts';
9
10
  import { type MakeTurnProducer } from './turn-producer.ts';
10
11
  export interface CreateSessionOptions {
@@ -45,6 +46,14 @@ export interface Options {
45
46
  * child processes and folds their results back into the conversation. Absent — a plain agent.
46
47
  */
47
48
  delegationStrategy?: DelegationStrategy;
49
+ /**
50
+ * Process definitions a chat can name in `chat.session.process` to run on instead of
51
+ * {@link AgentProcess}. Read per session, so a definition contributed after the layer was built
52
+ * is still found.
53
+ */
54
+ processes?: () => readonly AgentProcessDefinition[];
55
+ /** Keep each session's process resident between turns (see `AgentProcessOptions.resident`). */
56
+ resident?: boolean;
48
57
  }
49
58
  /**
50
59
  * The `AgentService` layer.
@@ -1 +1 @@
1
- {"version":3,"file":"AgentService.d.ts","sourceRoot":"","sources":["../../../../src/agent-service/AgentService.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAMtC,OAAO,KAAK,YAAY,MAAM,4BAA4B,CAAC;AAE3D,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAc,QAAQ,EAAQ,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE5E,OAAO,EAAE,GAAG,EAAqB,MAAM,YAAY,CAAC;AAKpD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAkB3D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,CAC1B,IAAI,CAAC,EAAE,oBAAoB,KACxB,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,YAAY,CAsB5F,CAAC;AAEpB,MAAM,WAAW,OAAO;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAEpC;;OAEG;IACH,YAAY,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAEnB;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,UAAW,OAAO,KAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,CAAC,cAAc,CA2NxG,CAAC"}
1
+ {"version":3,"file":"AgentService.d.ts","sourceRoot":"","sources":["../../../../src/agent-service/AgentService.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAMtC,OAAO,KAAK,YAAY,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAc,QAAQ,EAAQ,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE5E,OAAO,EAAE,GAAG,EAAqB,MAAM,YAAY,CAAC;AAIpD,OAAO,EAAoD,KAAK,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACnH,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAM3D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,CAC1B,IAAI,CAAC,EAAE,oBAAoB,KACxB,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,YAAY,CAsB5F,CAAC;AAEpB,MAAM,WAAW,OAAO;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAEpC;;OAEG;IACH,YAAY,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAEnB;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IAExC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,SAAS,sBAAsB,EAAE,CAAC;IACpD,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,UAAW,OAAO,KAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,CAAC,cAAc,CAsQxG,CAAC"}
@@ -1,10 +1,10 @@
1
1
  import * as Effect from 'effect/Effect';
2
2
  import * as Schema from 'effect/Schema';
3
3
  import { AiService, OpaqueToolkit } from '@dxos/ai';
4
- import { Alarm } from '@dxos/assistant';
5
- import { ProcessManager } from '@dxos/compute-runtime';
4
+ import { Alarm, type HarnessControlRpcs } from '@dxos/assistant';
6
5
  import * as Credential from '@dxos/compute/Credential';
7
6
  import * as Operation from '@dxos/compute/Operation';
7
+ import * as OperationHandlerSet from '@dxos/compute/OperationHandlerSet';
8
8
  import * as Process from '@dxos/compute/Process';
9
9
  import * as StorageService from '@dxos/compute/StorageService';
10
10
  import { Database, Obj, Ref, Registry } from '@dxos/echo';
@@ -22,6 +22,13 @@ export interface AgentProcessOptions {
22
22
  makeTurnProducer?: MakeTurnProducer;
23
23
  /** Model used when the chat the process is bound to has not selected one. */
24
24
  defaultModel?: DXN.DXN;
25
+ /**
26
+ * Stay resident (IDLE) once the work is done rather than succeeding, so the next prompt lands on this
27
+ * process instead of a new one. For a host where a spawn is expensive — on EDGE it is a fresh Durable
28
+ * Object that opens the space and loads the toolkit before the turn can start.
29
+ * @default false
30
+ */
31
+ resident?: boolean;
25
32
  /**
26
33
  * The catalog's shared model ids are served by several providers, so resolution needs the provider
27
34
  * alongside the id; without it a local model id cannot be claimed by any resolver.
@@ -355,11 +362,17 @@ export declare const AgentInput: Schema.Union<readonly [Schema.Union<readonly [S
355
362
  export type AgentInput = Schema.Schema.Type<typeof AgentInput>;
356
363
  /** Builds the feed message for an input; the sender defaults to the plain user role. */
357
364
  export declare const makeInputMessage: (input: AgentInput) => Message.Message;
365
+ /**
366
+ * A process that can run a chat in place of {@link AgentProcess}: it takes the same input and serves
367
+ * the same `HarnessControl` RPCs, so a session drives it without knowing which one it is. Its
368
+ * requirements are its own; the host resolves them when it spawns the process.
369
+ */
370
+ export type AgentProcessDefinition = Operation.Durable<AgentInput, void, any, HarnessControlRpcs>;
358
371
  /**
359
372
  * Hosts a persistent, suspendible AiAgent that can process a number of prompts.
360
373
  * The process target is a queue DXN string.
361
374
  */
362
- export declare const AgentProcess: (options: AgentProcessOptions) => Operation.Durable<string | readonly ({
375
+ export declare const AgentProcess: (options: AgentProcessOptions) => Operation.DurableDefinition.WithHandler<Operation.DurableDefinition<string | readonly ({
363
376
  readonly _tag: "anchor";
364
377
  readonly pending?: boolean | undefined;
365
378
  readonly objectId: string;
@@ -716,7 +729,7 @@ export declare const AgentProcess: (options: AgentProcessOptions) => Operation.D
716
729
  readonly properties?: {
717
730
  readonly [x: string]: any;
718
731
  } | undefined;
719
- }, void, AiService.AiService | Credential.CredentialsService | OpaqueToolkit.OpaqueToolkitProvider | Registry.Service | Database.Service | Operation.Service | ProcessManager.ProcessOperationInvoker.Service | StorageService.StorageService, import("effect/rpc/Rpc").Rpc<"enqueueMessage", Schema.Struct<{
732
+ }, void, AiService.AiService | Credential.CredentialsService | Process.ManagerService | OpaqueToolkit.OpaqueToolkitProvider | OperationHandlerSet.OperationHandlerProvider | Registry.Service | Database.Service | Operation.Service | StorageService.StorageService, import("effect/rpc/Rpc").Rpc<"enqueueMessage", Schema.Struct<{
720
733
  readonly content: Schema.$Array<Schema.Union<readonly [Schema.TaggedStruct<"anchor", {
721
734
  readonly pending: Schema.optional<Schema.Boolean>;
722
735
  readonly objectId: import("@dxos/keys").EntityIdClass;
@@ -868,7 +881,7 @@ export declare const AgentProcess: (options: AgentProcessOptions) => Operation.D
868
881
  }>, Schema.Void, Schema.Never, never, never> | import("effect/rpc/Rpc").Rpc<"setAlarm", Schema.Struct<{
869
882
  readonly at: Schema.DateTimeUtc;
870
883
  readonly message: Schema.NullOr<Schema.String>;
871
- }>, Schema.Void, Schema.Never, never, never>>;
884
+ }>, Schema.Void, Schema.Never, never, never>>>;
872
885
  declare const ToolResultEvent: Schema.TaggedStruct<"tool_result", {
873
886
  readonly pid: Schema.brand<Schema.String, "ProcessId">;
874
887
  readonly result: Schema.Unknown;
@@ -910,6 +923,11 @@ export type AgentIdleSnapshot = {
910
923
  };
911
924
  /** True while the agent still has queued work, a pending alarm, subprocesses, or undelivered tool results. */
912
925
  export declare const isAgentWorkPending: ({ toolResults, pendingMessages, pendingAlarms, delegations, toolCallManager, }: AgentIdleSnapshot) => boolean;
926
+ /**
927
+ * Whether a tool call's result is already accounted for — queued for the next turn or delivered to the
928
+ * agent — so a finished child that can no longer be reattached needs no answer of its own.
929
+ */
930
+ export declare const isToolResultHandled: (queue: readonly ToolResultEvent[], pid: Process.ID, isReported: (pid: Process.ID) => boolean) => boolean;
913
931
  /**
914
932
  * Discards tool results at the head of the queue whose values already reached the agent.
915
933
  *
@@ -1 +1 @@
1
- {"version":3,"file":"agent-process.d.ts","sourceRoot":"","sources":["../../../../src/agent-service/agent-process.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-process.d.ts","sourceRoot":"","sources":["../../../../src/agent-service/agent-process.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,12 @@ import type * as Cause from 'effect/Cause';
2
2
  import type * as Effect from 'effect/Effect';
3
3
  import type * as Exit from 'effect/Exit';
4
4
  import type * as Chat from '@dxos/assistant/Chat';
5
- import { type ProcessManager } from '@dxos/compute-runtime';
5
+ import type * as OperationHandlerSet from '@dxos/compute/OperationHandlerSet';
6
6
  import type * as Process from '@dxos/compute/Process';
7
7
  import { type Database } from '@dxos/echo';
8
8
  /**
9
9
  * A unit of work the supervisor delegates to a linked child process. `spawn` is an existential over
10
- * the child operation's input/output types: the strategy constructs it (e.g. via `invokeFiber`)
10
+ * the child operation's input/output types: the strategy constructs it (e.g. via `Process.spawn`)
11
11
  * so {@link AgentProcess} can remain agnostic to the operation type and just track the returned pid.
12
12
  */
13
13
  export interface Delegation {
@@ -17,9 +17,10 @@ export interface Delegation {
17
17
  readonly id: string;
18
18
  /**
19
19
  * Spawns the child for this delegation and returns its process id. Must be linked (non-blocking)
20
- * so the child's exit wakes the supervisor's `onChildEvent` — i.e. `ProcessOperationInvoker.invokeFiber`.
20
+ * so the child's exit wakes the supervisor's `onChildEvent` — i.e. spawned through the supervisor's own
21
+ * {@link Process.ManagerService}, which links its children by default.
21
22
  */
22
- readonly spawn: Effect.Effect<Process.ID, never, ProcessManager.ProcessOperationInvoker.Service>;
23
+ readonly spawn: Effect.Effect<Process.ID, never, Process.ManagerService | OperationHandlerSet.OperationHandlerProvider>;
23
24
  }
24
25
  /**
25
26
  * Services the strategy callbacks may use. The hosting {@link AgentProcess} provides these.
@@ -1 +1 @@
1
- {"version":3,"file":"delegation-strategy.d.ts","sourceRoot":"","sources":["../../../../src/agent-service/delegation-strategy.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,KAAK,IAAI,MAAM,aAAa,CAAC;AAEzC,OAAO,KAAK,KAAK,IAAI,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,KAAK,OAAO,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;CAClG;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,CAClB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,SAAS,UAAU,EAAE,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAEnE;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,CACnB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KACrB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAElD;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CACtB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KACxB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;CACnD"}
1
+ {"version":3,"file":"delegation-strategy.d.ts","sourceRoot":"","sources":["../../../../src/agent-service/delegation-strategy.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,KAAK,IAAI,MAAM,aAAa,CAAC;AAEzC,OAAO,KAAK,KAAK,IAAI,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,KAAK,mBAAmB,MAAM,mCAAmC,CAAC;AAC9E,OAAO,KAAK,KAAK,OAAO,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAC3B,OAAO,CAAC,EAAE,EACV,KAAK,EACL,OAAO,CAAC,cAAc,GAAG,mBAAmB,CAAC,wBAAwB,CACtE,CAAC;CACH;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,CAClB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,SAAS,UAAU,EAAE,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAEnE;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,CACnB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KACrB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAElD;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CACtB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KACxB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;CACnD"}
@@ -1,5 +1,5 @@
1
1
  export * as AgentService from './AgentService.ts';
2
- export { AGENT_PROCESS_KEY, AgentInput, AgentProcess, type AgentProcessOptions, makeInputMessage, } from './agent-process.ts';
2
+ export { AGENT_PROCESS_KEY, AgentInput, AgentProcess, type AgentProcessDefinition, type AgentProcessOptions, makeInputMessage, } from './agent-process.ts';
3
3
  export { type Delegation, type DelegationStrategy } from './delegation-strategy.ts';
4
4
  export * from './turn-producer.ts';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/agent-service/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAGlD,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,KAAK,mBAAmB,EACxB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACpF,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/agent-service/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAGlD,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACpF,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=process-selection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-selection.test.d.ts","sourceRoot":"","sources":["../../../../src/agent-service/process-selection.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=skill-hooks.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-hooks.test.d.ts","sourceRoot":"","sources":["../../../../src/agent-service/skill-hooks.test.ts"],"names":[],"mappings":""}
@@ -5,7 +5,7 @@ import * as KeyValueStore from 'effect/persistence/KeyValueStore';
5
5
  import * as AtomRegistry from 'effect/reactivity/AtomRegistry';
6
6
  import { AiService, OpaqueToolkit } from '@dxos/ai';
7
7
  import { type AiServicePreset } from '@dxos/ai/testing';
8
- import { FeedTraceSink, ProcessManager, RemoteProcessManager, TriggerDispatcher, TriggerStateStore } from '@dxos/compute-runtime';
8
+ import { FeedTraceSink, ProcessManager, ProcessOperationInvoker, RemoteProcessManager, TriggerDispatcher, TriggerStateStore } from '@dxos/compute-runtime';
9
9
  import * as AgentService from '@dxos/compute/AgentService';
10
10
  import * as Credential from '@dxos/compute/Credential';
11
11
  import * as Operation from '@dxos/compute/Operation';
@@ -57,7 +57,7 @@ interface TestLayerOptions {
57
57
  */
58
58
  extraServices?: Layer.Layer<never, never, AgentService.AgentService>;
59
59
  }
60
- export type AssistantTestServices = LanguageModel.LanguageModel | Credential.CredentialsService | AgentService.AgentService | AiService.AiService | Database.Service | Registry.Service | OpaqueToolkit.OpaqueToolkitProvider | Operation.Service | ProcessManager.Service | RemoteProcessManager.Service | ProcessManager.ProcessOperationInvoker.Service | Process.ManagerService | AtomRegistry.AtomRegistry | OperationHandlerSet.OperationHandlerProvider | KeyValueStore.KeyValueStore | ServiceResolver.ServiceResolver | Trace.TraceService | Trace.TraceSink | FeedTraceSink.FeedTraceSink;
60
+ export type AssistantTestServices = LanguageModel.LanguageModel | Credential.CredentialsService | AgentService.AgentService | AiService.AiService | Database.Service | Registry.Service | OpaqueToolkit.OpaqueToolkitProvider | Operation.Service | ProcessManager.Service | RemoteProcessManager.Service | ProcessOperationInvoker.Service | Process.ManagerService | AtomRegistry.AtomRegistry | OperationHandlerSet.OperationHandlerProvider | KeyValueStore.KeyValueStore | ServiceResolver.ServiceResolver | Trace.TraceService | Trace.TraceSink | FeedTraceSink.FeedTraceSink;
61
61
  export declare const AssistantTestLayer: (options?: TestLayerOptions) => Layer.Layer<AssistantTestServices, never, TestContextService>;
62
62
  /** Late-bound reference to the {@link ProcessManager.Service}, filled once the manager is built. */
63
63
  interface ProcessManagerHolder {
@@ -1 +1 @@
1
- {"version":3,"file":"assistant-test-layer.d.ts","sourceRoot":"","sources":["../../../../src/testing/assistant-test-layer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"assistant-test-layer.d.ts","sourceRoot":"","sources":["../../../../src/testing/assistant-test-layer.ts"],"names":[],"mappings":"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"}