@agen-ai/agent-runtime 0.4.0 → 0.4.2

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 (45) hide show
  1. package/README.md +200 -9
  2. package/dist/adapterValidation.d.ts +4 -2
  3. package/dist/adapterValidation.js +140 -51
  4. package/dist/artifacts.js +0 -1
  5. package/dist/contractErrors.d.ts +2 -2
  6. package/dist/contractErrors.js +11 -7
  7. package/dist/hostBindings/opening.d.ts +2 -0
  8. package/dist/hostBindings/opening.js +58 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.js +2 -0
  11. package/dist/nativeContinuations/admission.d.ts +17 -0
  12. package/dist/nativeContinuations/admission.js +250 -0
  13. package/dist/nativeContinuations/index.d.ts +2 -0
  14. package/dist/nativeContinuations/index.js +1 -0
  15. package/dist/nativeContinuations/types.d.ts +52 -0
  16. package/dist/nativeContinuations/types.js +0 -0
  17. package/dist/outputValidation.js +3 -2
  18. package/dist/providerCatalog.d.ts +1 -1
  19. package/dist/providerDriver.d.ts +4 -1
  20. package/dist/providerDriver.js +0 -1
  21. package/dist/providerInstanceRegistry.d.ts +4 -4
  22. package/dist/providerInstanceRegistry.js +2 -1
  23. package/dist/sessionAdmission.d.ts +12 -0
  24. package/dist/sessionAdmission.js +54 -0
  25. package/dist/sessionInteractions/index.d.ts +2 -0
  26. package/dist/sessionInteractions/index.js +1 -0
  27. package/dist/sessionInteractions/lifetime.d.ts +81 -0
  28. package/dist/sessionInteractions/lifetime.js +383 -0
  29. package/dist/sessionInteractions/request.d.ts +43 -0
  30. package/dist/sessionInteractions/request.js +381 -0
  31. package/dist/sessionInteractions/types.d.ts +110 -0
  32. package/dist/sessionInteractions/types.js +10 -0
  33. package/dist/sessionInteractions/validation.d.ts +25 -0
  34. package/dist/sessionInteractions/validation.js +180 -0
  35. package/dist/sessionValidation.d.ts +82 -3
  36. package/dist/sessionValidation.js +240 -181
  37. package/dist/sessions.d.ts +34 -0
  38. package/dist/testing/conformance.d.ts +3 -1
  39. package/dist/testing/conformance.js +180 -86
  40. package/dist/testing/fakeProvider.js +5 -6
  41. package/dist/turnExecution/execution.d.ts +23 -6
  42. package/dist/turnExecution/execution.js +136 -32
  43. package/dist/turnExecution/requests.d.ts +15 -3
  44. package/dist/turnExecution/requests.js +93 -28
  45. package/package.json +2 -2
@@ -1,8 +1,10 @@
1
1
  import type { AgentAuthenticationFlow, AgentCollaborationControlInput, AgentCollaborationNode, AgentCollaborationSpawnInput, AgentConfigurationCatalog, AgentConfigurationSelectionInput, AgentError, AgentGeneratedResourceDescriptor, AgentGeneratedResourceId, AgentManagedContentCatalog, AgentOperationCatalog, AgentOperationInvocation, AgentOperationResult, AgentRequestResolution, AgentSessionBinding, AgentSessionBranchSource, AgentSessionConfiguration, AgentSessionId, AgentTurnId, AgentTurnInputContent, AgentTurnInteractionMode, AgentTurnInputPart, AgentTurnInterruptionReason } from "@agen-ai/agent-protocol";
2
+ import type { AgentNativeContinuationContext, AgentNativeContinuationSupport } from "./nativeContinuations/types.js";
2
3
  import type { MaybePromise } from "./foundation.js";
3
4
  import type { AgentSessionHostBinding, AgentSessionHostBindingSupport } from "./hostBindings/types.js";
4
5
  import type { AgentProviderOutput } from "./outputs.js";
5
6
  import type { AgentArtifactCandidate } from "./artifacts.js";
7
+ import type { AgentProviderSessionInteractionContext, AgentSessionInteractionContext, AgentSessionInteractionSupport } from "./sessionInteractions/types.js";
6
8
  import type { AgentEnvironmentObservationPort } from "./environment/types.js";
7
9
  export interface AgentProviderSessionContext {
8
10
  readonly sessionId: AgentSessionId;
@@ -10,6 +12,7 @@ export interface AgentProviderSessionContext {
10
12
  readonly configuration: AgentSessionConfiguration;
11
13
  readonly signal?: AbortSignal;
12
14
  readonly hostBinding?: AgentSessionHostBinding;
15
+ readonly interactions?: AgentProviderSessionInteractionContext;
13
16
  }
14
17
  export type AgentSessionBindingCreatedObserver = (binding: AgentSessionBinding) => void;
15
18
  export interface AgentProviderCreateSessionInput extends AgentProviderSessionContext {
@@ -212,10 +215,41 @@ export type AgentProviderAuthentication = Readonly<{
212
215
  cancel: (input: AgentProviderAuthenticationCancelInput) => MaybePromise<AgentProviderOperationResult>;
213
216
  }>;
214
217
  export interface AgentProviderAdapter {
218
+ readonly sessionInteractions?: AgentSessionInteractionSupport;
215
219
  readonly hostBinding?: AgentSessionHostBindingSupport;
220
+ readonly nativeContinuations?: AgentNativeContinuationSupport;
216
221
  readonly createSession: (input: AgentProviderCreateSessionInput) => MaybePromise<AgentProviderSession>;
217
222
  readonly resumption: AgentSessionResumption;
218
223
  readonly branching: AgentSessionBranching;
219
224
  readonly authentication: AgentProviderAuthentication;
220
225
  }
226
+ export type AgentSessionOpenContext = Omit<AgentProviderSessionContext, "interactions"> & Readonly<{
227
+ interactions?: AgentSessionInteractionContext;
228
+ nativeContinuations?: AgentNativeContinuationContext;
229
+ }>;
230
+ export type AgentCreateSessionInput = AgentSessionOpenContext & Readonly<{
231
+ onBindingCreated: AgentSessionBindingCreatedObserver;
232
+ }>;
233
+ export type AgentResumeSessionInput = AgentSessionOpenContext & Readonly<{
234
+ binding: AgentSessionBinding;
235
+ }>;
236
+ export type AgentBranchSessionInput = AgentSessionOpenContext & Readonly<{
237
+ source: AgentSessionBranchSource;
238
+ onBindingCreated: AgentSessionBindingCreatedObserver;
239
+ }>;
240
+ export type AgentValidatedProviderAdapter = Omit<AgentProviderAdapter, "createSession" | "resumption" | "branching"> & Readonly<{
241
+ createSession: (input: AgentCreateSessionInput) => MaybePromise<AgentProviderSession>;
242
+ resumption: Readonly<{
243
+ kind: "unsupported";
244
+ }> | Readonly<{
245
+ kind: "supported";
246
+ resumeSession: (input: AgentResumeSessionInput) => MaybePromise<AgentProviderSession>;
247
+ }>;
248
+ branching: Readonly<{
249
+ kind: "unsupported";
250
+ }> | Readonly<{
251
+ kind: "through_turn";
252
+ branchSession: (input: AgentBranchSessionInput) => MaybePromise<AgentProviderSession>;
253
+ }>;
254
+ }>;
221
255
  //# sourceMappingURL=sessions.d.ts.map
@@ -18,7 +18,9 @@ export interface AgentProviderConformanceScenario {
18
18
  readonly interruptionSessionId: AgentSessionId;
19
19
  readonly turn: AgentProviderStartTurnInput;
20
20
  readonly interruptionTurn: AgentProviderStartTurnInput;
21
- readonly resolutionFor: (request: AgentRequest) => AgentRequestResolution;
21
+ readonly resolutionFor: (request: AgentRequest, context: Readonly<{
22
+ signal: AbortSignal;
23
+ }>) => AgentRequestResolution | undefined | Promise<AgentRequestResolution | undefined>;
22
24
  readonly branchSource?: (binding: AgentSessionBinding, turnId: AgentTurnId) => AgentSessionBranchSource;
23
25
  readonly steeringInput?: AgentTurnInputContent;
24
26
  }
@@ -15,7 +15,6 @@ class AgentProviderConformanceError extends Error {
15
15
  this.check = check;
16
16
  this.name = "AgentProviderConformanceError";
17
17
  }
18
- check;
19
18
  }
20
19
  function requireCheck(condition, check, message) {
21
20
  if (!condition) throw new AgentProviderConformanceError(check, message);
@@ -51,25 +50,104 @@ async function advanceToStartedTurn(session, input) {
51
50
  );
52
51
  outputs.push(next.value);
53
52
  if (next.value.kind === "event" && next.value.event.type === "turn.started") {
54
- return { execution, iterator, outputs };
53
+ return { session, execution, iterator, outputs };
55
54
  }
56
55
  }
57
56
  } catch (error) {
58
- await iterator.return?.();
57
+ const closing = session.close({ reason: "contract_rejected" });
58
+ const settled = await Promise.allSettled([closing, iterator.return?.()]);
59
+ const failures = settled.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
60
+ if (failures.length > 0) throw new AggregateError([error, ...failures], "Conformance opening and cleanup failed.", { cause: error });
59
61
  throw error;
60
62
  }
61
63
  }
62
- async function collectRemainingOutputs(started, resolutionFor) {
63
- for (; ; ) {
64
- const next = await started.iterator.next();
65
- if (next.done) return started.outputs;
66
- started.outputs.push(next.value);
67
- if (next.value.kind === "event" && next.value.event.type === "request.opened" && resolutionFor) {
68
- const request = next.value.event.payload.request;
69
- const receipt = await started.execution.resolveRequest({ resolution: parseAgentRequestResolutionFor(request, resolutionFor(request)) });
70
- requireCheck(receipt.status === "delivered", "request_resolution", "Matching request answer was not accepted by the provider handler.");
64
+ async function collectRemainingOutputs(started, resolutionFor, beforeClose) {
65
+ const requests = /* @__PURE__ */ new Map();
66
+ const tasks = [];
67
+ let acceptingRequests = true;
68
+ let deliveredRequests = 0;
69
+ let failTask;
70
+ const taskFailure = new Promise((_resolve, reject) => {
71
+ failTask = reject;
72
+ });
73
+ const abortRequests = () => {
74
+ for (const controller of requests.values()) {
75
+ controller.abort(new DOMException("Conformance request is no longer answerable.", "AbortError"));
76
+ }
77
+ };
78
+ const resolve = async (request, signal) => {
79
+ if (!resolutionFor) return;
80
+ let resolution;
81
+ try {
82
+ resolution = await resolutionFor(request, { signal });
83
+ } catch (error) {
84
+ if (signal.aborted && isAgentOperationAbortError(error)) return;
85
+ throw error;
71
86
  }
87
+ if (resolution === void 0 || signal.aborted) return;
88
+ const receipt = await started.execution.resolveRequest({
89
+ resolution: parseAgentRequestResolutionFor(request, resolution)
90
+ });
91
+ requireCheck(
92
+ receipt.status === "delivered",
93
+ "request_resolution",
94
+ "Matching request answer was not accepted by the provider handler."
95
+ );
96
+ deliveredRequests += 1;
97
+ };
98
+ const reader = (async () => {
99
+ for (; ; ) {
100
+ const next = await started.iterator.next();
101
+ if (next.done || !acceptingRequests) return;
102
+ started.outputs.push(next.value);
103
+ if (next.value.kind !== "event") continue;
104
+ const event = next.value.event;
105
+ if (event.type === "request.opened" && resolutionFor) {
106
+ const request = event.payload.request;
107
+ const controller = new AbortController();
108
+ requests.set(request.requestId, controller);
109
+ const task = resolve(request, controller.signal);
110
+ tasks.push(task);
111
+ void task.catch((error) => {
112
+ acceptingRequests = false;
113
+ failTask(error);
114
+ });
115
+ } else if (event.type === "request.unavailable") {
116
+ requests.get(event.payload.requestId)?.abort(
117
+ new DOMException("The provider retired this conformance request.", "AbortError")
118
+ );
119
+ requests.delete(event.payload.requestId);
120
+ } else if (event.type === "turn.completed") {
121
+ abortRequests();
122
+ return;
123
+ }
124
+ }
125
+ })();
126
+ const checked = reader.then(async () => {
127
+ if (acceptingRequests) await beforeClose?.();
128
+ });
129
+ const failures = /* @__PURE__ */ new Set();
130
+ try {
131
+ await Promise.race([checked, taskFailure]);
132
+ } catch (error) {
133
+ failures.add(error);
134
+ }
135
+ acceptingRequests = false;
136
+ abortRequests();
137
+ const closing = started.session.close({ reason: failures.size > 0 ? "contract_rejected" : "idle" });
138
+ const [closed, read, inspected, returned] = await Promise.allSettled([closing, reader, checked, started.iterator.return?.()]);
139
+ if (closed?.status === "rejected") failures.add(closed.reason);
140
+ for (const result of [read, inspected]) {
141
+ if (result?.status === "rejected" && !(failures.size > 0 && isAgentOperationAbortError(result.reason))) failures.add(result.reason);
72
142
  }
143
+ if (returned?.status === "rejected") failures.add(returned.reason);
144
+ const joined = await Promise.allSettled(tasks);
145
+ for (const result of joined) {
146
+ if (result.status === "rejected") failures.add(result.reason);
147
+ }
148
+ if (failures.size === 1) throw failures.values().next().value;
149
+ if (failures.size > 1) throw new AggregateError(failures, "Conformance and owned cleanup failed.", { cause: failures.values().next().value });
150
+ return { outputs: started.outputs, deliveredRequests };
73
151
  }
74
152
  function requireOperationStatus(result, statuses, check, message) {
75
153
  requireCheck(statuses.includes(result.status), check, message);
@@ -111,6 +189,7 @@ async function runAgentProviderConformance(scenario) {
111
189
  });
112
190
  let disposed = false;
113
191
  let createdSession = null;
192
+ let failure;
114
193
  try {
115
194
  const instance = registry.requireInstance(scenario.definition.instanceId);
116
195
  requireCheck(
@@ -277,55 +356,7 @@ async function runAgentProviderConformance(scenario) {
277
356
  );
278
357
  checks.push("abort");
279
358
  }
280
- const startedTurn = await advanceToStartedTurn(created, scenario.turn);
281
- let turnOutputs;
282
- try {
283
- if (instance.capabilities.turns.steer.kind === "supported") {
284
- requireCheck(
285
- created.steering.kind === "supported",
286
- "steering",
287
- "Steering capability has no handler."
288
- );
289
- const result = await created.steering.steerTurn({
290
- turnId: scenario.turn.turnId,
291
- ...scenario.steeringInput ?? {
292
- parts: [
293
- { type: "text", text: "Additional conformance input." }
294
- ]
295
- }
296
- });
297
- requireCheck(
298
- result.status === "delivered",
299
- "steering",
300
- "Steering did not deliver to the live turn."
301
- );
302
- } else {
303
- requireCheck(
304
- created.steering.kind === "unsupported",
305
- "steering",
306
- "Unsupported steering exposed a handler."
307
- );
308
- }
309
- turnOutputs = await collectRemainingOutputs(startedTurn, scenario.resolutionFor);
310
- } catch (error) {
311
- await startedTurn.iterator.return?.();
312
- await created.close({ reason: "contract_rejected" });
313
- throw error;
314
- }
315
- const events = semanticEvents(turnOutputs);
316
- requireCheck(
317
- events[0]?.type === "turn.started",
318
- "turn_order",
319
- "Turn did not start first."
320
- );
321
- requireCheck(
322
- hasStableTurnBoundary(events),
323
- "turn_order",
324
- "Turn did not terminate or enter a waiting state."
325
- );
326
- checks.push("turn_order");
327
- if (events.some((event) => event.type === "request.opened")) checks.push("request_resolution");
328
- checks.push("steering");
359
+ const turnChecksIndex = checks.length;
329
360
  if (instance.capabilities.turns.interrupt) {
330
361
  let interruptedBindingCount = 0;
331
362
  const interrupted = await instance.adapter.createSession({
@@ -363,15 +394,15 @@ async function runAgentProviderConformance(scenario) {
363
394
  "interruption",
364
395
  "Live turn interruption did not succeed."
365
396
  );
366
- const outputs = await collectRemainingOutputs(liveTurn);
397
+ const { outputs } = await collectRemainingOutputs(liveTurn);
367
398
  requireCheck(
368
399
  semanticEvents(outputs).some((event) => event.type === "turn.completed"),
369
400
  "interruption",
370
401
  "Interrupted turn did not produce native terminal output."
371
402
  );
372
403
  } finally {
373
- await liveTurn?.iterator.return?.();
374
- await interrupted.close({ reason: "other" });
404
+ const closing = interrupted.close({ reason: "other" });
405
+ await Promise.all([closing, liveTurn?.iterator.return?.()]);
375
406
  }
376
407
  } else {
377
408
  requireCheck(
@@ -527,28 +558,83 @@ async function runAgentProviderConformance(scenario) {
527
558
  );
528
559
  }
529
560
  checks.push("collaboration");
530
- if (instance.capabilities.generatedResources.kind === "supported") {
531
- requireCheck(
532
- created.generatedResources.kind === "supported" && scenario.generatedResourceId !== void 0,
533
- "generated_resources",
534
- "Supported generated resources require an access port and fixture."
535
- );
536
- const resource = await created.generatedResources.getGeneratedResource({
537
- resourceId: scenario.generatedResourceId
561
+ const turnChecks = [];
562
+ const startedTurn = await advanceToStartedTurn(created, scenario.turn);
563
+ let turnResult;
564
+ try {
565
+ if (instance.capabilities.turns.steer.kind === "supported") {
566
+ requireCheck(
567
+ created.steering.kind === "supported",
568
+ "steering",
569
+ "Steering capability has no handler."
570
+ );
571
+ const result = await created.steering.steerTurn({
572
+ turnId: scenario.turn.turnId,
573
+ ...scenario.steeringInput ?? {
574
+ parts: [
575
+ { type: "text", text: "Additional conformance input." }
576
+ ]
577
+ }
578
+ });
579
+ requireCheck(
580
+ result.status === "delivered",
581
+ "steering",
582
+ "Steering did not deliver to the live turn."
583
+ );
584
+ } else {
585
+ requireCheck(
586
+ created.steering.kind === "unsupported",
587
+ "steering",
588
+ "Unsupported steering exposed a handler."
589
+ );
590
+ }
591
+ turnResult = await collectRemainingOutputs(startedTurn, scenario.resolutionFor, async () => {
592
+ if (instance.capabilities.generatedResources.kind === "supported") {
593
+ requireCheck(
594
+ created.generatedResources.kind === "supported" && scenario.generatedResourceId !== void 0,
595
+ "generated_resources",
596
+ "Supported generated resources require an access port and fixture."
597
+ );
598
+ const resource = await created.generatedResources.getGeneratedResource({
599
+ resourceId: scenario.generatedResourceId
600
+ });
601
+ requireCheck(
602
+ resource.descriptor.resourceId === scenario.generatedResourceId,
603
+ "generated_resources",
604
+ "Generated resource access returned another resource."
605
+ );
606
+ } else {
607
+ requireCheck(
608
+ created.generatedResources.kind === "unsupported",
609
+ "generated_resources",
610
+ "Unsupported generated resources exposed an access port."
611
+ );
612
+ }
613
+ checks.push("generated_resources");
538
614
  });
539
- requireCheck(
540
- resource.descriptor.resourceId === scenario.generatedResourceId,
541
- "generated_resources",
542
- "Generated resource access returned another resource."
543
- );
544
- } else {
545
- requireCheck(
546
- created.generatedResources.kind === "unsupported",
547
- "generated_resources",
548
- "Unsupported generated resources exposed an access port."
549
- );
615
+ } catch (error) {
616
+ const closing = created.close({ reason: "contract_rejected" });
617
+ const settled = await Promise.allSettled([closing, startedTurn.iterator.return?.()]);
618
+ const failures = settled.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
619
+ if (failures.length > 0) throw new AggregateError([error, ...failures], "Conformance turn and cleanup failed.", { cause: error });
620
+ throw error;
550
621
  }
551
- checks.push("generated_resources");
622
+ const events = semanticEvents(turnResult.outputs);
623
+ requireCheck(
624
+ events[0]?.type === "turn.started",
625
+ "turn_order",
626
+ "Turn did not start first."
627
+ );
628
+ requireCheck(
629
+ hasStableTurnBoundary(events),
630
+ "turn_order",
631
+ "Turn did not terminate or enter a waiting state."
632
+ );
633
+ turnChecks.push("turn_order");
634
+ if (turnResult.deliveredRequests > 0) turnChecks.push("request_resolution");
635
+ if (events.some((event) => event.type === "request.unavailable")) turnChecks.push("request_unavailability");
636
+ turnChecks.push("steering");
637
+ checks.splice(turnChecksIndex, 0, ...turnChecks);
552
638
  await created.close({ reason: "idle" });
553
639
  await created.close({ reason: "idle" });
554
640
  checks.push("idempotent_session_close");
@@ -621,9 +707,17 @@ async function runAgentProviderConformance(scenario) {
621
707
  providerKey: scenario.definition.providerKey,
622
708
  checks: Object.freeze(checks)
623
709
  });
710
+ } catch (error) {
711
+ failure = { error };
712
+ throw error;
624
713
  } finally {
625
- await createdSession?.close({ reason: "contract_rejected" });
626
- if (!disposed) await registry.dispose();
714
+ try {
715
+ await createdSession?.close({ reason: "contract_rejected" });
716
+ if (!disposed) await registry.dispose();
717
+ } catch (error) {
718
+ if (failure) throw new AggregateError([failure.error, error], "Conformance and final cleanup failed.", { cause: failure.error });
719
+ throw error;
720
+ }
627
721
  }
628
722
  }
629
723
  export {
@@ -44,7 +44,7 @@ function defaultCapabilities(providerKey) {
44
44
  }
45
45
  };
46
46
  return parseAgentCapabilities({
47
- protocolVersion: 10,
47
+ protocolVersion: 12,
48
48
  providerKey,
49
49
  sessions: { create: true, resume: true, branch: { kind: "through_turn" } },
50
50
  turns: {
@@ -55,6 +55,7 @@ function defaultCapabilities(providerKey) {
55
55
  requests: {
56
56
  approval: {
57
57
  kind: "supported",
58
+ providerManagedRemembrance: false,
58
59
  modes: [{ persistence: "once", scopeKinds: ["exact_action"] }]
59
60
  },
60
61
  elicitation: {
@@ -165,7 +166,7 @@ function sessionBinding(state, sessionId) {
165
166
  };
166
167
  }
167
168
  function eventBase(sessionId, turnId, occurredAt) {
168
- return { protocolVersion: 10, sessionId, turnId, occurredAt };
169
+ return { protocolVersion: 12, sessionId, turnId, occurredAt };
169
170
  }
170
171
  function fakeEnvironmentSnapshot(environmentId) {
171
172
  return parseAgentEnvironmentSnapshot({
@@ -251,15 +252,13 @@ function requestForTurn(turnId) {
251
252
  optionId: parseAgentApprovalOptionId("approval:allow-once"),
252
253
  label: "Allow once",
253
254
  decision: "approved",
254
- persistence: "once",
255
- scope: { kind: "exact_action" }
255
+ consequence: { kind: "scoped", persistence: "once", scope: { kind: "exact_action" } }
256
256
  },
257
257
  {
258
258
  optionId: parseAgentApprovalOptionId("approval:deny-once"),
259
259
  label: "Deny",
260
260
  decision: "denied",
261
- persistence: "once",
262
- scope: { kind: "exact_action" }
261
+ consequence: { kind: "scoped", persistence: "once", scope: { kind: "exact_action" } }
263
262
  }
264
263
  ]
265
264
  };
@@ -1,26 +1,43 @@
1
- import { type AgentProviderKey } from "@agen-ai/agent-protocol";
1
+ import { type AgentProviderKey, type AgentTurnId } from "@agen-ai/agent-protocol";
2
2
  import type { AgentProviderOutput } from "../outputs.js";
3
+ import type { AgentSessionAdmission } from "../sessionAdmission.js";
3
4
  import type { AgentProviderStartTurnInput, AgentProviderTurnExecution } from "../sessions.js";
4
- import { type PendingAgentRequest, type SuspendedAgentTurnRequests } from "./requests.js";
5
+ import { type AgentTurnRequestAdmission, type PendingAgentRequest, type SuspendedAgentTurnRequests } from "./requests.js";
5
6
  export interface ValidatedAgentTurnExecution {
6
7
  readonly execution: AgentProviderTurnExecution;
7
8
  readonly hasEntered: () => boolean;
8
9
  readonly stop: (reason: Error) => void;
9
10
  readonly join: () => Promise<void>;
10
11
  readonly suspendRequests: () => SuspendedAgentTurnRequests;
12
+ readonly completed: Promise<void>;
11
13
  }
12
- export declare function createValidatedAgentTurnExecution(input: Readonly<{
14
+ type ExecutionOptions = Readonly<{
13
15
  providerKey: AgentProviderKey;
14
- turnInput: AgentProviderStartTurnInput;
15
16
  pendingRequests: Map<string, PendingAgentRequest>;
17
+ sessionAdmission: AgentSessionAdmission;
16
18
  inFlightOperations: Set<Promise<void>>;
17
- start: (input: AgentProviderStartTurnInput) => AgentProviderTurnExecution;
18
19
  requireUsable: () => void;
19
20
  isTerminal: () => boolean;
20
- observe: (output: AgentProviderOutput) => AgentProviderOutput;
21
+ canRestoreRequest: (pending: PendingAgentRequest) => boolean;
22
+ observe: (output: AgentProviderOutput, requests: AgentTurnRequestAdmission) => AgentProviderOutput;
21
23
  assertCompleted: () => void;
22
24
  release: () => void;
23
25
  retire: () => void;
24
26
  abandon: () => Promise<void>;
27
+ }>;
28
+ export declare function createValidatedAgentTurnExecution(input: ExecutionOptions & Readonly<{
29
+ turnInput: AgentProviderStartTurnInput;
30
+ start: (input: AgentProviderStartTurnInput) => AgentProviderTurnExecution;
25
31
  }>): ValidatedAgentTurnExecution;
32
+ export interface AdoptedAgentTurnExecution extends ValidatedAgentTurnExecution {
33
+ readonly readerReady: Promise<void>;
34
+ readonly admitDispatch: () => void;
35
+ readonly settleNoWork: () => void;
36
+ readonly markStarted: () => void;
37
+ }
38
+ export declare function adoptValidatedAgentTurnExecution(input: ExecutionOptions & Readonly<{
39
+ turnId: AgentTurnId;
40
+ createCandidate: (signal: AbortSignal) => AgentProviderTurnExecution;
41
+ }>): AdoptedAgentTurnExecution;
42
+ export {};
26
43
  //# sourceMappingURL=execution.d.ts.map