@relayfx/sdk 0.3.5 → 0.3.7

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.
@@ -16,7 +16,7 @@ import {
16
16
  exports_tool_executor,
17
17
  exports_tool_output,
18
18
  exports_turn_policy
19
- } from "./index-8fpd6kvj.js";
19
+ } from "./index-t5bbk8cp.js";
20
20
  import {
21
21
  ClientError,
22
22
  CommandReplyInvalid,
@@ -51,7 +51,7 @@ import {
51
51
  followExecutionFrom,
52
52
  inputSchemaRef,
53
53
  outputSchemaRef
54
- } from "./index-cyfx5y3r.js";
54
+ } from "./index-pw46cfne.js";
55
55
  import {
56
56
  __export
57
57
  } from "./index-nb39b5ae.js";
@@ -717,7 +717,7 @@ __export(exports_tool_runtime, {
717
717
  });
718
718
 
719
719
  // ../runtime/src/tool/tool-runtime-contract.ts
720
- import { Context as Context10, Layer as Layer10, Schema as Schema10 } from "effect";
720
+ import { Context as Context10, Effect as Effect10, Layer as Layer10, Schema as Schema10 } from "effect";
721
721
 
722
722
  class ToolNotRegistered extends Schema10.TaggedErrorClass()("ToolNotRegistered", {
723
723
  tool_name: exports_shared_schema.NonEmptyString
@@ -755,7 +755,7 @@ class ToolCallInfo extends Context10.Service()("@relayfx/runtime/tool/tool-runti
755
755
 
756
756
  class Service12 extends Context10.Service()("@relayfx/runtime/tool/tool-runtime-contract/Service") {
757
757
  }
758
- var testLayer8 = (implementation) => Layer10.succeed(Service12, Service12.of(implementation));
758
+ var testLayer8 = (implementation) => Layer10.succeed(Service12, Service12.of({ ...implementation, prepare: implementation.prepare ?? (() => Effect10.void) }));
759
759
  // ../store-sql/src/address/address-book-repository.ts
760
760
  var exports_address_book_repository = {};
761
761
  __export(exports_address_book_repository, {
@@ -3175,6 +3175,7 @@ __export(exports_execution_event_repository, {
3175
3175
  findByCursor: () => findByCursor,
3176
3176
  executionEventsChannel: () => executionEventsChannel,
3177
3177
  appendedSignals: () => appendedSignals,
3178
+ appendNext: () => appendNext,
3178
3179
  append: () => append,
3179
3180
  Service: () => Service25,
3180
3181
  ExecutionEventRow: () => ExecutionEventRow,
@@ -3183,7 +3184,7 @@ __export(exports_execution_event_repository, {
3183
3184
  ExecutionEventCursorNotFound: () => ExecutionEventCursorNotFound,
3184
3185
  DuplicateExecutionEvent: () => DuplicateExecutionEvent
3185
3186
  });
3186
- import { Context as Context23, Effect as Effect24, Filter, Layer as Layer23, Option as Option2, PubSub as PubSub2, Schema as Schema22, Stream as Stream2 } from "effect";
3187
+ import { Context as Context23, Effect as Effect24, Filter, Layer as Layer23, Option as Option2, PubSub as PubSub2, Schema as Schema22, Semaphore as Semaphore2, Stream as Stream2 } from "effect";
3187
3188
  import { SqlClient as SqlClient13 } from "effect/unstable/sql/SqlClient";
3188
3189
 
3189
3190
  // ../store-sql/src/database/notification-bus.ts
@@ -3319,6 +3320,7 @@ var duplicateError = (input) => DuplicateExecutionEvent.make({
3319
3320
  sequence: input.sequence,
3320
3321
  cursor: input.cursor
3321
3322
  });
3323
+ var hasSamePayload = (existing, input) => existing.id === input.id && existing.execution_id === input.execution_id && existing.child_execution_id === input.child_execution_id && existing.type === input.type && existing.cursor === input.cursor && exports_shared_schema.canonicalEquals(existing.content ?? null, input.content ?? null) && exports_shared_schema.canonicalEquals(existing.data ?? {}, input.data ?? {});
3322
3324
  var assertAppendable = (events, input) => {
3323
3325
  const duplicate = events.find((event) => event.sequence === input.sequence || event.cursor === input.cursor);
3324
3326
  if (duplicate !== undefined) {
@@ -3382,15 +3384,15 @@ var layer18 = Layer23.effect(Service25, Effect24.gen(function* () {
3382
3384
  ${timestampParam(sql, input.created_at)}
3383
3385
  )
3384
3386
  `;
3385
- const insertEvent = sql.onDialectOrElse({
3386
- mysql: () => (tenantId, input) => sql.withTransaction(Effect24.gen(function* () {
3387
- yield* insertStatement(tenantId, input);
3388
- return yield* selectByCursor(tenantId, input.cursor);
3389
- })),
3390
- orElse: () => (tenantId, input) => sql`
3391
- ${insertStatement(tenantId, input)}
3392
- RETURNING ${columns}
3393
- `
3387
+ const lockExecution = (tenantId, executionId) => sql.onDialectOrElse({
3388
+ mysql: () => sql`UPDATE relay_executions SET updated_at=updated_at WHERE tenant_id=${tenantId} AND id=${executionId}`.pipe(Effect24.andThen(sql`SELECT id FROM relay_executions WHERE tenant_id=${tenantId} AND id=${executionId}`)),
3389
+ orElse: () => sql`UPDATE relay_executions SET updated_at=updated_at WHERE tenant_id=${tenantId} AND id=${executionId} RETURNING id`
3390
+ });
3391
+ const lockExistingExecution = Effect24.fn("ExecutionEventRepository.lockExistingExecution")(function* (tenantId, executionId) {
3392
+ const rows = yield* lockExecution(tenantId, executionId);
3393
+ if (rows[0] === undefined) {
3394
+ return yield* ExecutionEventRepositoryError.make({ message: `Execution not found: ${executionId}` });
3395
+ }
3394
3396
  });
3395
3397
  const listConditions = (tenantId, input) => [
3396
3398
  sql`tenant_id = ${tenantId}`,
@@ -3407,28 +3409,68 @@ var layer18 = Layer23.effect(Service25, Effect24.gen(function* () {
3407
3409
  const decodeEvents = (rows) => Effect24.forEach(rows, decodeRow7).pipe(Effect24.map((decoded) => decoded.map(toEvent)));
3408
3410
  const append = Effect24.fn("ExecutionEventRepository.append")(function* (input) {
3409
3411
  const tenantId = yield* current();
3410
- const previousRows = yield* selectLatest(tenantId, input.execution_id).pipe(Effect24.mapError(toRepositoryError8));
3411
- const previous = previousRows[0] === undefined ? undefined : toEvent(yield* decodeRow7(previousRows[0]));
3412
- if (previous !== undefined && input.sequence === previous.sequence) {
3413
- return yield* duplicateError(input);
3414
- }
3415
- if (previous !== undefined && input.sequence < previous.sequence) {
3416
- return yield* ExecutionEventOrderViolation.make({
3417
- execution_id: input.execution_id,
3418
- sequence: input.sequence,
3419
- previous_sequence: previous.sequence
3420
- });
3421
- }
3422
- const duplicateCursorRows = yield* selectByCursor(tenantId, input.cursor).pipe(Effect24.mapError(toRepositoryError8));
3423
- if (duplicateCursorRows[0] !== undefined) {
3424
- return yield* duplicateError(input);
3425
- }
3426
- const rows = yield* insertEvent(tenantId, input).pipe(Effect24.mapError(toRepositoryError8));
3427
- const row = rows[0];
3428
- if (row === undefined) {
3429
- return yield* ExecutionEventRepositoryError.make({ message: "Execution event append returned no row" });
3430
- }
3431
- return toEvent(yield* decodeRow7(row));
3412
+ return yield* sql.withTransaction(Effect24.gen(function* () {
3413
+ yield* lockExistingExecution(tenantId, input.execution_id);
3414
+ const previousRows = yield* selectLatest(tenantId, input.execution_id);
3415
+ const previous = previousRows[0] === undefined ? undefined : toEvent(yield* decodeRow7(previousRows[0]));
3416
+ if (previous !== undefined && input.sequence === previous.sequence)
3417
+ return yield* duplicateError(input);
3418
+ if (previous !== undefined && input.sequence < previous.sequence) {
3419
+ return yield* ExecutionEventOrderViolation.make({
3420
+ execution_id: input.execution_id,
3421
+ sequence: input.sequence,
3422
+ previous_sequence: previous.sequence
3423
+ });
3424
+ }
3425
+ const duplicateCursorRows = yield* selectByCursor(tenantId, input.cursor);
3426
+ if (duplicateCursorRows[0] !== undefined)
3427
+ return yield* duplicateError(input);
3428
+ yield* insertStatement(tenantId, input);
3429
+ const rows = yield* selectByCursor(tenantId, input.cursor);
3430
+ const row = rows[0];
3431
+ if (row === undefined) {
3432
+ return yield* ExecutionEventRepositoryError.make({ message: "Execution event append returned no row" });
3433
+ }
3434
+ return toEvent(yield* decodeRow7(row));
3435
+ })).pipe(Effect24.mapError((error) => Schema22.is(DuplicateExecutionEvent)(error) || Schema22.is(ExecutionEventOrderViolation)(error) ? error : toRepositoryError8(error)));
3436
+ });
3437
+ const appendNext = Effect24.fn("ExecutionEventRepository.appendNext")(function* (input) {
3438
+ const tenantId = yield* current();
3439
+ return yield* sql.withTransaction(Effect24.gen(function* () {
3440
+ yield* lockExistingExecution(tenantId, input.execution_id);
3441
+ const existingRows = yield* selectByCursor(tenantId, input.cursor);
3442
+ const existingRow = existingRows[0];
3443
+ if (existingRow !== undefined) {
3444
+ const existing = toEvent(yield* decodeRow7(existingRow));
3445
+ if (hasSamePayload(existing, input))
3446
+ return { event: existing, inserted: false };
3447
+ return yield* duplicateError({ ...input, sequence: existing.sequence });
3448
+ }
3449
+ const sequenceRows = yield* sql`
3450
+ SELECT COALESCE(MAX(sequence), -1) + 1 AS value
3451
+ FROM relay_execution_events
3452
+ WHERE tenant_id = ${tenantId} AND execution_id = ${input.execution_id}
3453
+ `;
3454
+ const sequenceRow = sequenceRows[0];
3455
+ if (sequenceRow === undefined) {
3456
+ return yield* ExecutionEventRepositoryError.make({
3457
+ message: "Execution event sequence query returned no row"
3458
+ });
3459
+ }
3460
+ const decodedSequence = yield* decodeAggregate(sequenceRow);
3461
+ const { minimumSequence, ...eventInput } = input;
3462
+ const event = {
3463
+ ...eventInput,
3464
+ sequence: Math.max(Number(decodedSequence.value), minimumSequence ?? 0)
3465
+ };
3466
+ yield* insertStatement(tenantId, event);
3467
+ const rows = yield* selectByCursor(tenantId, input.cursor);
3468
+ const row = rows[0];
3469
+ if (row === undefined) {
3470
+ return yield* ExecutionEventRepositoryError.make({ message: "Execution event append returned no row" });
3471
+ }
3472
+ return { event: toEvent(yield* decodeRow7(row)), inserted: true };
3473
+ })).pipe(Effect24.mapError((error) => Schema22.is(DuplicateExecutionEvent)(error) ? error : toRepositoryError8(error)));
3432
3474
  });
3433
3475
  const list4 = Effect24.fn("ExecutionEventRepository.list")(function* (input) {
3434
3476
  const tenantId = yield* current();
@@ -3608,6 +3650,7 @@ var layer18 = Layer23.effect(Service25, Effect24.gen(function* () {
3608
3650
  return Service25.of({
3609
3651
  signalTransport: bus.transport,
3610
3652
  append,
3653
+ appendNext,
3611
3654
  list: list4,
3612
3655
  findBySequenceOrCursor,
3613
3656
  findByCursor,
@@ -3624,14 +3667,47 @@ var layer18 = Layer23.effect(Service25, Effect24.gen(function* () {
3624
3667
  var layerWithBus = layer18.pipe(Layer23.provide(layerFromDialect));
3625
3668
  var memoryLayer16 = Layer23.effect(Service25, Effect24.gen(function* () {
3626
3669
  const events = new Map;
3670
+ const locks = new Map;
3627
3671
  const signals = yield* PubSub2.unbounded();
3672
+ const lockFor = Effect24.fn("ExecutionEventRepository.memory.lockFor")(function* (executionId) {
3673
+ const candidate = yield* Semaphore2.make(1);
3674
+ return yield* Effect24.sync(() => {
3675
+ const existing = locks.get(executionId);
3676
+ if (existing !== undefined)
3677
+ return existing;
3678
+ locks.set(executionId, candidate);
3679
+ return candidate;
3680
+ });
3681
+ });
3628
3682
  return Service25.of({
3629
3683
  signalTransport: "in-process",
3630
3684
  append: Effect24.fn("ExecutionEventRepository.memory.append")(function* (input) {
3631
- const executionEvents = events.get(input.execution_id) ?? [];
3632
- yield* assertAppendable(executionEvents, input);
3633
- yield* Effect24.sync(() => events.set(input.execution_id, [...executionEvents, input]));
3634
- return input;
3685
+ const lock = yield* lockFor(input.execution_id);
3686
+ return yield* lock.withPermits(1)(Effect24.gen(function* () {
3687
+ const executionEvents = events.get(input.execution_id) ?? [];
3688
+ yield* assertAppendable(executionEvents, input);
3689
+ yield* Effect24.sync(() => events.set(input.execution_id, [...executionEvents, input]));
3690
+ return input;
3691
+ }));
3692
+ }),
3693
+ appendNext: Effect24.fn("ExecutionEventRepository.memory.appendNext")(function* (input) {
3694
+ const lock = yield* lockFor(input.execution_id);
3695
+ return yield* lock.withPermits(1)(Effect24.gen(function* () {
3696
+ const executionEvents = events.get(input.execution_id) ?? [];
3697
+ const existing = executionEvents.find((event2) => event2.cursor === input.cursor);
3698
+ if (existing !== undefined) {
3699
+ if (hasSamePayload(existing, input))
3700
+ return { event: existing, inserted: false };
3701
+ return yield* duplicateError({ ...input, sequence: existing.sequence });
3702
+ }
3703
+ const { minimumSequence, ...eventInput } = input;
3704
+ const event = {
3705
+ ...eventInput,
3706
+ sequence: Math.max(executionEvents.reduce((maximum, item) => Math.max(maximum, item.sequence), -1) + 1, minimumSequence ?? 0)
3707
+ };
3708
+ yield* Effect24.sync(() => events.set(input.execution_id, [...executionEvents, event]));
3709
+ return { event, inserted: true };
3710
+ }));
3635
3711
  }),
3636
3712
  list: Effect24.fn("ExecutionEventRepository.memory.list")(function* (input) {
3637
3713
  const executionEvents = events.get(input.executionId) ?? [];
@@ -3696,12 +3772,17 @@ var memoryLayer16 = Layer23.effect(Service25, Effect24.gen(function* () {
3696
3772
  }));
3697
3773
  var testLayer20 = (implementation) => Layer23.succeed(Service25, Service25.of({
3698
3774
  ...implementation,
3775
+ appendNext: implementation.appendNext ?? ((input) => implementation.append({ ...input, sequence: 0 }).pipe(Effect24.map((event) => ({ event, inserted: true })), Effect24.catchTag("ExecutionEventOrderViolation", (error) => ExecutionEventRepositoryError.make({ message: String(error) })))),
3699
3776
  page: implementation.page ?? (() => Effect24.succeed({ events: [], hasMore: false }))
3700
3777
  }));
3701
3778
  var append = Effect24.fn("ExecutionEventRepository.append.call")(function* (input) {
3702
3779
  const repository = yield* Service25;
3703
3780
  return yield* repository.append(input);
3704
3781
  });
3782
+ var appendNext = Effect24.fn("ExecutionEventRepository.appendNext.call")(function* (input) {
3783
+ const repository = yield* Service25;
3784
+ return yield* repository.appendNext(input);
3785
+ });
3705
3786
  var list4 = Effect24.fn("ExecutionEventRepository.list.call")(function* (input) {
3706
3787
  const repository = yield* Service25;
3707
3788
  return yield* repository.list(input);
@@ -4409,7 +4490,7 @@ var layer20 = Layer25.effect(Service27, Effect26.gen(function* () {
4409
4490
  }));
4410
4491
  var testLayer22 = (implementation) => Layer25.succeed(Service27, Service27.of(implementation));
4411
4492
  // ../store-sql/src/idempotency/idempotency-repository.ts
4412
- import { Context as Context26, Effect as Effect27, HashMap, Layer as Layer26, Option as Option5, Ref as Ref5, Schema as Schema25, Semaphore as Semaphore2 } from "effect";
4493
+ import { Context as Context26, Effect as Effect27, HashMap, Layer as Layer26, Option as Option5, Ref as Ref5, Schema as Schema25, Semaphore as Semaphore3 } from "effect";
4413
4494
  import { SqlClient as SqlClient16 } from "effect/unstable/sql/SqlClient";
4414
4495
  class IdempotencyRepositoryError extends Schema25.TaggedErrorClass()("IdempotencyRepositoryError", {
4415
4496
  message: Schema25.String
@@ -4528,7 +4609,7 @@ var layer21 = Layer26.effect(Service28, Effect27.gen(function* () {
4528
4609
  }));
4529
4610
  var memoryLayer19 = Layer26.effect(Service28, Effect27.gen(function* () {
4530
4611
  const records = yield* Ref5.make(HashMap.empty());
4531
- const semaphore = Semaphore2.makeUnsafe(1);
4612
+ const semaphore = Semaphore3.makeUnsafe(1);
4532
4613
  const runOnce = Effect27.fn("IdempotencyRepository.memory.runOnce")(function* (input, create4) {
4533
4614
  return yield* semaphore.withPermits(1)(Effect27.gen(function* () {
4534
4615
  const id = operationId(input);
@@ -4623,9 +4704,13 @@ var consumeMessage = (message, input) => Object.assign({}, message, { drain_id:
4623
4704
  var layer22 = Layer27.effect(Service29, Effect28.gen(function* () {
4624
4705
  const sql = yield* SqlClient17;
4625
4706
  const lockExecution = sql.onDialectOrElse({
4626
- pg: () => (tenant, executionId) => sql`SELECT pg_advisory_xact_lock(hashtext(${`${tenant}:${executionId}:inbox`}))`.pipe(Effect28.asVoid),
4627
- mysql: () => (tenant, executionId) => sql`SELECT id FROM relay_executions WHERE tenant_id=${tenant} AND id=${executionId} FOR UPDATE`.pipe(Effect28.asVoid),
4628
- orElse: () => () => Effect28.void
4707
+ mysql: () => (tenant, executionId) => sql`UPDATE relay_executions SET updated_at=updated_at WHERE tenant_id=${tenant} AND id=${executionId}`.pipe(Effect28.andThen(sql`SELECT id FROM relay_executions WHERE tenant_id=${tenant} AND id=${executionId}`)),
4708
+ orElse: () => (tenant, executionId) => sql`UPDATE relay_executions SET updated_at=updated_at WHERE tenant_id=${tenant} AND id=${executionId} RETURNING id`
4709
+ });
4710
+ const lockExistingExecution = Effect28.fn("InboxRepository.lockExistingExecution")(function* (tenant, executionId) {
4711
+ const rows = yield* lockExecution(tenant, executionId);
4712
+ if (rows[0] === undefined)
4713
+ return yield* InboxRepositoryError.make({ message: `Execution not found: ${executionId}` });
4629
4714
  });
4630
4715
  const appendEvent = (tenant, input, type, id, cursor, data) => Effect28.gen(function* () {
4631
4716
  const rows = yield* sql`SELECT COALESCE(MAX(sequence), -1) + 1 AS next_sequence FROM relay_execution_events WHERE tenant_id=${tenant} AND execution_id=${input.executionId}`;
@@ -4642,7 +4727,7 @@ var layer22 = Layer27.effect(Service29, Effect28.gen(function* () {
4642
4727
  const deliver = Effect28.fn("InboxRepository.deliver")(function* (input) {
4643
4728
  const tenant = yield* current();
4644
4729
  return yield* sql.withTransaction(Effect28.gen(function* () {
4645
- yield* lockExecution(tenant, input.executionId);
4730
+ yield* lockExistingExecution(tenant, input.executionId);
4646
4731
  if (input.idempotencyKey !== undefined) {
4647
4732
  const found = yield* sql`SELECT ${sql.literal(columns)} FROM relay_inbox_messages WHERE tenant_id=${tenant} AND execution_id=${input.executionId} AND idempotency_key=${input.idempotencyKey}`;
4648
4733
  if (found[0] !== undefined)
@@ -4671,7 +4756,7 @@ var layer22 = Layer27.effect(Service29, Effect28.gen(function* () {
4671
4756
  const drain = Effect28.fn("InboxRepository.drain")(function* (input) {
4672
4757
  const tenant = yield* current();
4673
4758
  return yield* sql.withTransaction(Effect28.gen(function* () {
4674
- yield* lockExecution(tenant, input.executionId);
4759
+ yield* lockExistingExecution(tenant, input.executionId);
4675
4760
  const old = yield* sql`SELECT message_sequences_json FROM relay_inbox_drains WHERE tenant_id=${tenant} AND execution_id=${input.executionId} AND drain_id=${input.drainId}`;
4676
4761
  let sequences;
4677
4762
  if (old[0] !== undefined)
@@ -6819,7 +6904,7 @@ __export(exports_skill_definition_repository, {
6819
6904
  Service: () => Service36,
6820
6905
  ExecutionSkillPinRow: () => ExecutionSkillPinRow
6821
6906
  });
6822
- import { Context as Context34, Effect as Effect35, HashSet, Layer as Layer34, Schema as Schema33, Semaphore as Semaphore3 } from "effect";
6907
+ import { Context as Context34, Effect as Effect35, HashSet, Layer as Layer34, Schema as Schema33, Semaphore as Semaphore4 } from "effect";
6823
6908
  import { SqlClient as SqlClient24 } from "effect/unstable/sql/SqlClient";
6824
6909
  class SkillDefinitionRepositoryError extends Schema33.TaggedErrorClass()("SkillDefinitionRepositoryError", {
6825
6910
  message: Schema33.String
@@ -7108,7 +7193,7 @@ var layer29 = Layer34.effect(Service36, Effect35.gen(function* () {
7108
7193
  return Service36.of({ put: put3, get: get10, getRevision: getRevision2, list: list11, listRevisions: listRevisions2, pinExecution, listPins, getPinned });
7109
7194
  }));
7110
7195
  var memoryLayer27 = Layer34.sync(Service36, () => {
7111
- const semaphore = Semaphore3.makeUnsafe(1);
7196
+ const semaphore = Semaphore4.makeUnsafe(1);
7112
7197
  const records = new Map;
7113
7198
  const revisions = new Map;
7114
7199
  const pins = new Map;
@@ -9622,7 +9707,8 @@ var afterSequence = (events, input) => {
9622
9707
  return Effect41.succeed(cursorEvent.sequence);
9623
9708
  };
9624
9709
  var replayAfter = (events, input, sequence) => events.filter((event) => event.execution_id === input.executionId).filter((event) => sequence === undefined || event.sequence > sequence).toSorted((left, right) => left.sequence - right.sequence).slice(0, limitOf(input));
9625
- var sameEvent = (left, right) => left.id === right.id && left.execution_id === right.execution_id && left.child_execution_id === right.child_execution_id && left.type === right.type && left.sequence === right.sequence && left.cursor === right.cursor && exports_shared_schema.canonicalEquals(left.content ?? null, right.content ?? null) && exports_shared_schema.canonicalEquals(left.data ?? {}, right.data ?? {});
9710
+ var sameEventPayload = (left, right) => left.id === right.id && left.execution_id === right.execution_id && left.child_execution_id === right.child_execution_id && left.type === right.type && left.cursor === right.cursor && exports_shared_schema.canonicalEquals(left.content ?? null, right.content ?? null) && exports_shared_schema.canonicalEquals(left.data ?? {}, right.data ?? {});
9711
+ var sameEvent = (left, right) => left.sequence === right.sequence && sameEventPayload(left, right);
9626
9712
  var findExisting = (events, input) => events.find((event) => event.cursor === input.cursor || event.sequence === input.sequence);
9627
9713
  var duplicateEventError = (input) => EventLogError.make({ message: `DuplicateExecutionEvent:${input.execution_id}:${input.sequence}` });
9628
9714
  var orderViolationError = (input, previous) => EventLogError.make({
@@ -9727,6 +9813,20 @@ var layerFromRepository = Layer39.effect(Service41, Effect41.gen(function* () {
9727
9813
  yield* recordEventAppended(event.type);
9728
9814
  return event;
9729
9815
  }),
9816
+ appendNext: Effect41.fn("EventLog.repository.appendNext")(function* (input) {
9817
+ yield* Effect41.annotateCurrentSpan({
9818
+ "relay.execution.id": input.execution_id,
9819
+ "relay.event.id": input.id,
9820
+ "relay.event.type": input.type
9821
+ });
9822
+ const result = yield* repository.appendNext(input).pipe(Effect41.mapError(mapRepositoryAppendError));
9823
+ if (result.inserted) {
9824
+ yield* PubSub5.publish(pubsub, result.event);
9825
+ yield* repository.notifyAppended(result.event).pipe(Effect41.catch((error5) => Effect41.logWarning("EventLog append notify failed", error5)));
9826
+ yield* recordEventAppended(result.event.type);
9827
+ }
9828
+ return result.event;
9829
+ }),
9730
9830
  replay: Effect41.fn("EventLog.repository.replay")(function* (input) {
9731
9831
  yield* Effect41.annotateCurrentSpan("relay.execution.id", input.executionId);
9732
9832
  const replay = yield* loadReplay(input);
@@ -9783,6 +9883,34 @@ var memoryLayer32 = Layer39.effect(Service41, Effect41.gen(function* () {
9783
9883
  yield* recordEventAppended(input.type);
9784
9884
  return input;
9785
9885
  }),
9886
+ appendNext: Effect41.fn("EventLog.memory.appendNext")(function* (input) {
9887
+ const result = yield* Ref10.modify((store) => {
9888
+ const existing = HashMap2.get(store, input.execution_id).pipe(Option6.getOrElse(() => []));
9889
+ const duplicate = existing.find((event2) => event2.cursor === input.cursor);
9890
+ if (duplicate !== undefined) {
9891
+ const candidate = { ...input, sequence: duplicate.sequence };
9892
+ if (!sameEvent(duplicate, candidate))
9893
+ return [{ _tag: "error", error: duplicateEventError(candidate) }, store];
9894
+ return [{ _tag: "event", event: duplicate, inserted: false }, store];
9895
+ }
9896
+ const { minimumSequence, ...eventInput } = input;
9897
+ const event = {
9898
+ ...eventInput,
9899
+ sequence: Math.max((existing.at(-1)?.sequence ?? -1) + 1, minimumSequence ?? 0)
9900
+ };
9901
+ return [
9902
+ { _tag: "event", event, inserted: true },
9903
+ HashMap2.set(store, input.execution_id, [...existing, event])
9904
+ ];
9905
+ })(events);
9906
+ if (result._tag === "error")
9907
+ return yield* result.error;
9908
+ if (result.inserted) {
9909
+ yield* PubSub5.publish(pubsub, result.event);
9910
+ yield* recordEventAppended(result.event.type);
9911
+ }
9912
+ return result.event;
9913
+ }),
9786
9914
  replay: Effect41.fn("EventLog.memory.replay")(function* (input) {
9787
9915
  yield* Effect41.annotateCurrentSpan("relay.execution.id", input.executionId);
9788
9916
  const replay = yield* loadReplay(input);
@@ -9827,18 +9955,28 @@ var memoryLayer32 = Layer39.effect(Service41, Effect41.gen(function* () {
9827
9955
  })
9828
9956
  });
9829
9957
  }));
9830
- var appendIdempotentTo = Function6.dual(2, (eventLog, input) => eventLog.append(input).pipe(Effect41.catchTag("EventLogError", (error5) => eventLog.findBySequenceOrCursor({
9831
- executionId: input.execution_id,
9832
- sequence: input.sequence,
9833
- cursor: input.cursor
9834
- }).pipe(Effect41.flatMap((existing) => Option6.match(existing, {
9958
+ var appendIdempotentTo = Function6.dual(2, (eventLog, input) => eventLog.appendNext({
9959
+ id: input.id,
9960
+ execution_id: input.execution_id,
9961
+ ...input.child_execution_id === undefined ? {} : { child_execution_id: input.child_execution_id },
9962
+ type: input.type,
9963
+ cursor: input.cursor,
9964
+ ...input.content === undefined ? {} : { content: input.content },
9965
+ ...input.data === undefined ? {} : { data: input.data },
9966
+ created_at: input.created_at,
9967
+ minimumSequence: input.sequence
9968
+ }).pipe(Effect41.catchTag("EventLogError", (error5) => eventLog.findByCursor({ executionId: input.execution_id, cursor: input.cursor }).pipe(Effect41.flatMap(Option6.match({
9835
9969
  onNone: () => Effect41.fail(error5),
9836
- onSome: (event) => sameEvent(event, input) ? Effect41.succeed(event) : Effect41.fail(error5)
9970
+ onSome: (event) => sameEventPayload(event, input) ? Effect41.succeed(event) : Effect41.fail(error5)
9837
9971
  })), Effect41.mapError(() => error5)))));
9838
9972
  var append3 = Effect41.fn("EventLog.append.call")(function* (input) {
9839
9973
  const service = yield* Service41;
9840
9974
  return yield* service.append(input);
9841
9975
  });
9976
+ var appendNext2 = Effect41.fn("EventLog.appendNext.call")(function* (input) {
9977
+ const service = yield* Service41;
9978
+ return yield* service.appendNext(input);
9979
+ });
9842
9980
  var appendIdempotent = Effect41.fn("EventLog.appendIdempotent.call")(function* (input) {
9843
9981
  const service = yield* Service41;
9844
9982
  return yield* appendIdempotentTo(service, input);
@@ -9978,7 +10116,7 @@ var createTimeoutSchedule = Effect42.fn("WaitService.createTimeoutSchedule")(fun
9978
10116
  var complete = Effect42.fn("WaitService.complete")(function* (repository, eventLog, input, event) {
9979
10117
  const result = yield* repository.completeWait(input).pipe(Effect42.mapError(mapRepositoryError2));
9980
10118
  if (result.transitioned) {
9981
- yield* eventLog.append(event(result.wait)).pipe(Effect42.mapError(mapEventLogError));
10119
+ yield* appendIdempotentTo(eventLog, event(result.wait)).pipe(Effect42.mapError(mapEventLogError));
9982
10120
  }
9983
10121
  return result;
9984
10122
  });
@@ -9998,7 +10136,7 @@ var layer34 = Layer40.effect(Service42, Effect42.gen(function* () {
9998
10136
  }
9999
10137
  yield* repository.acceptEnvelope({ envelope: input.envelope, waitId: input.waitId }).pipe(Effect42.mapError((error5) => WaitServiceError.make({ message: error5.message })));
10000
10138
  const wait = yield* repository.getWait(input.waitId).pipe(Effect42.mapError((error5) => WaitServiceError.make({ message: error5.message })), Effect42.flatMap((record2) => record2 === undefined ? Effect42.fail(WaitServiceError.make({ message: `Wait ${input.waitId} was not persisted` })) : Effect42.succeed(record2)));
10001
- yield* eventLog.append(waitCreatedEvent(input, wait)).pipe(Effect42.mapError(mapEventLogError));
10139
+ yield* appendIdempotentTo(eventLog, waitCreatedEvent(input, wait)).pipe(Effect42.mapError(mapEventLogError));
10002
10140
  if (input.envelope.wait.timeout !== undefined) {
10003
10141
  yield* createTimeoutSchedule(schedules, input.waitId, wait, input.envelope.wait.timeout);
10004
10142
  }
@@ -10018,7 +10156,7 @@ var layer34 = Layer40.effect(Service42, Effect42.gen(function* () {
10018
10156
  ...input.correlationKey === undefined ? {} : { correlationKey: input.correlationKey },
10019
10157
  ...input.metadata === undefined ? {} : { metadata: input.metadata }
10020
10158
  }).pipe(Effect42.mapError((error5) => WaitServiceError.make({ message: error5.message })));
10021
- yield* eventLog.append(waitCreatedEvent(input, wait)).pipe(Effect42.mapError(mapEventLogError));
10159
+ yield* appendIdempotentTo(eventLog, waitCreatedEvent(input, wait)).pipe(Effect42.mapError(mapEventLogError));
10022
10160
  if (input.timeout !== undefined) {
10023
10161
  yield* createTimeoutSchedule(schedules, input.waitId, wait, input.timeout);
10024
10162
  }
@@ -10083,6 +10221,13 @@ var cancel3 = Effect42.fn("WaitService.cancel.call")(function* (input) {
10083
10221
  const service = yield* Service42;
10084
10222
  return yield* service.cancel(input);
10085
10223
  });
10224
+ // ../runtime/src/tool/tool-runtime-identifiers.ts
10225
+ var scopedPart = (value) => encodeURIComponent(value);
10226
+ var toolScope = (executionId, toolCallId) => `${scopedPart(executionId)}:${scopedPart(toolCallId)}`;
10227
+ var eventId = (executionId, toolCallId, kind) => exports_ids_schema.EventId.make(`event:${toolScope(executionId, toolCallId)}:${kind}`);
10228
+ var waitId = (kind, executionId, toolCallId) => exports_ids_schema.WaitId.make(`wait:${kind}:${toolScope(executionId, toolCallId)}`);
10229
+ var Identifiers = { eventId, waitId };
10230
+
10086
10231
  // ../runtime/src/tool/tool-runtime-service.ts
10087
10232
  var permissionNames = (permissions) => HashSet3.fromIterable(permissions.map((permission) => permission.name));
10088
10233
  var requiredPermissionNames = (tool) => tool.requiredPermissions ?? tool.definition.permissions.map((permission) => permission.name);
@@ -10117,7 +10262,7 @@ var preserveToolError = (toolName, error5) => {
10117
10262
  };
10118
10263
  var preserveRecordResultError = (error5) => error5._tag === "ToolRuntimeError" ? error5 : mapRepositoryError3(error5);
10119
10264
  var requestedEvent = (input) => ({
10120
- id: exports_ids_schema.EventId.make(`event:${input.call.id}:tool-requested`),
10265
+ id: Identifiers.eventId(input.executionId, input.call.id, "tool-requested"),
10121
10266
  execution_id: input.executionId,
10122
10267
  type: "tool.call.requested",
10123
10268
  sequence: input.eventSequence,
@@ -10129,13 +10274,19 @@ var requestedEvent = (input) => ({
10129
10274
  },
10130
10275
  created_at: input.createdAt
10131
10276
  });
10132
- var sameToolEventPayload = (left, right) => left.id === right.id && left.execution_id === right.execution_id && left.child_execution_id === right.child_execution_id && left.type === right.type && left.cursor === right.cursor && left.created_at === right.created_at && exports_shared_schema.canonicalEquals(left.data ?? {}, right.data ?? {});
10133
- var ensureToolEvent = (eventLog, event) => eventLog.findByCursor({ executionId: event.execution_id, cursor: event.cursor }).pipe(Effect43.mapError(mapEventLogError2), Effect43.flatMap(Option8.match({
10134
- onNone: () => appendIdempotentTo(eventLog, event).pipe(Effect43.mapError(mapEventLogError2), Effect43.asVoid),
10135
- onSome: (existing) => sameToolEventPayload(existing, event) ? Effect43.void : Effect43.fail(ToolRuntimeError.make({ message: "EventLogError" }))
10136
- })));
10277
+ var ensureToolEvent = (eventLog, event) => eventLog.appendNext({
10278
+ id: event.id,
10279
+ execution_id: event.execution_id,
10280
+ ...event.child_execution_id === undefined ? {} : { child_execution_id: event.child_execution_id },
10281
+ type: event.type,
10282
+ cursor: event.cursor,
10283
+ ...event.content === undefined ? {} : { content: event.content },
10284
+ ...event.data === undefined ? {} : { data: event.data },
10285
+ created_at: event.created_at,
10286
+ minimumSequence: event.sequence
10287
+ }).pipe(Effect43.mapError(mapEventLogError2), Effect43.asVoid);
10137
10288
  var resultEvent = (input, result, sequence) => ({
10138
- id: exports_ids_schema.EventId.make(`event:${input.call.id}:tool-result`),
10289
+ id: Identifiers.eventId(input.executionId, input.call.id, "tool-result"),
10139
10290
  execution_id: input.executionId,
10140
10291
  type: "tool.result.received",
10141
10292
  sequence,
@@ -10204,11 +10355,11 @@ var finalToolResult = (tool, input, idempotencyKey) => Effect43.gen(function* ()
10204
10355
  output: jsonValue2(output)
10205
10356
  };
10206
10357
  });
10207
- var approvalWaitId = (input) => exports_ids_schema.WaitId.make(`wait:approval:${input.call.id}`);
10208
- var permissionWaitId = (input) => exports_ids_schema.WaitId.make(`wait:permission:${input.call.id}`);
10358
+ var approvalWaitId = (input) => Identifiers.waitId("approval", input.executionId, input.call.id);
10359
+ var permissionWaitId = (input) => Identifiers.waitId("permission", input.executionId, input.call.id);
10209
10360
  var mapWaitServiceError = (error5) => ToolRuntimeError.make({ message: error5.message });
10210
- var approvalRequestedEvent = (input, waitId) => ({
10211
- id: exports_ids_schema.EventId.make(`event:${input.call.id}:approval-requested`),
10361
+ var approvalRequestedEvent = (input, waitId2) => ({
10362
+ id: Identifiers.eventId(input.executionId, input.call.id, "approval-requested"),
10212
10363
  execution_id: input.executionId,
10213
10364
  type: "tool.approval.requested",
10214
10365
  sequence: input.eventSequence + 2,
@@ -10216,13 +10367,13 @@ var approvalRequestedEvent = (input, waitId) => ({
10216
10367
  data: {
10217
10368
  tool_call_id: input.call.id,
10218
10369
  tool_name: input.call.name,
10219
- wait_id: waitId,
10370
+ wait_id: waitId2,
10220
10371
  input: input.call.input
10221
10372
  },
10222
10373
  created_at: input.createdAt + 2
10223
10374
  });
10224
10375
  var approvalResolvedEvent = (input, wait, approved) => ({
10225
- id: exports_ids_schema.EventId.make(`event:${input.call.id}:approval-resolved`),
10376
+ id: Identifiers.eventId(input.executionId, input.call.id, "approval-resolved"),
10226
10377
  execution_id: input.executionId,
10227
10378
  type: "tool.approval.resolved",
10228
10379
  sequence: input.eventSequence + 1,
@@ -10237,14 +10388,14 @@ var approvalResolvedEvent = (input, wait, approved) => ({
10237
10388
  created_at: input.createdAt + 1
10238
10389
  });
10239
10390
  var deniedReason = (state) => state === "timed_out" ? "Tool approval timed out" : state === "cancelled" ? "Tool approval cancelled" : "Tool approval denied";
10240
- var waitRequested = (input, waitId) => Effect43.fail(ToolExecutionWaitRequested.make({ tool_name: input.call.name, wait_id: waitId }));
10391
+ var waitRequested = (input, waitId2) => Effect43.fail(ToolExecutionWaitRequested.make({ tool_name: input.call.name, wait_id: waitId2 }));
10241
10392
  var hasPermissionApprovalBypass = (waits, input) => waits.get(permissionWaitId(input)).pipe(Effect43.mapError(mapWaitServiceError), Effect43.map((wait) => wait !== undefined && wait.state === "resolved" && wait.metadata.kind === "tool-permission" && wait.metadata.tool_call_id === input.call.id && wait.metadata.tool_name === input.call.name && (wait.metadata.answer === "Approved" || wait.metadata.answer === "Always")));
10242
10393
  var resolveApproval = (waits, eventLog, input) => Effect43.gen(function* () {
10243
- const waitId = approvalWaitId(input);
10244
- const existing = yield* waits.get(waitId).pipe(Effect43.mapError(mapWaitServiceError));
10394
+ const waitId2 = approvalWaitId(input);
10395
+ const existing = yield* waits.get(waitId2).pipe(Effect43.mapError(mapWaitServiceError));
10245
10396
  if (existing === undefined) {
10246
10397
  yield* waits.createDetached({
10247
- waitId,
10398
+ waitId: waitId2,
10248
10399
  executionId: input.executionId,
10249
10400
  mode: "event",
10250
10401
  correlationKey: input.call.id,
@@ -10257,11 +10408,12 @@ var resolveApproval = (waits, eventLog, input) => Effect43.gen(function* () {
10257
10408
  eventSequence: input.eventSequence + 1,
10258
10409
  createdAt: input.createdAt
10259
10410
  }).pipe(Effect43.mapError(mapWaitServiceError));
10260
- yield* appendIdempotentTo(eventLog, approvalRequestedEvent(input, waitId)).pipe(Effect43.mapError(mapEventLogError2));
10261
- return yield* waitRequested(input, waitId);
10411
+ yield* appendIdempotentTo(eventLog, approvalRequestedEvent(input, waitId2)).pipe(Effect43.mapError(mapEventLogError2));
10412
+ return yield* waitRequested(input, waitId2);
10262
10413
  }
10263
10414
  if (existing.state === "open") {
10264
- return yield* waitRequested(input, waitId);
10415
+ yield* appendIdempotentTo(eventLog, approvalRequestedEvent({ ...input, createdAt: existing.createdAt }, waitId2)).pipe(Effect43.mapError(mapEventLogError2));
10416
+ return yield* waitRequested(input, waitId2);
10265
10417
  }
10266
10418
  const approved = existing.state === "resolved" && existing.metadata.approved === true;
10267
10419
  yield* appendIdempotentTo(eventLog, approvalResolvedEvent(input, existing, approved)).pipe(Effect43.mapError(mapEventLogError2));
@@ -10276,8 +10428,9 @@ var recordRequested = (repository, eventLog, input, tool) => repository.ensureCa
10276
10428
  placement: tool.placement ?? { kind: "local" },
10277
10429
  createdAt: input.createdAt
10278
10430
  }).pipe(Effect43.mapError(mapRepositoryError3), Effect43.tap((call) => ensureToolEvent(eventLog, requestedEvent({ ...input, createdAt: call.createdAt }))));
10279
- var repairResultEvent = (eventLog, input, record2) => eventLog.maxSequence(input.executionId).pipe(Effect43.mapError(mapEventLogError2), Effect43.flatMap((max) => ensureToolEvent(eventLog, resultEvent({ ...input, createdAt: record2.createdAt - 1 }, record2.result, (max ?? input.eventSequence) + 1))));
10280
- var recordReceived = (repository, eventLog, input, result) => repository.recordResult({ executionId: input.executionId, result, createdAt: input.createdAt + 1 }).pipe(Effect43.catchTag("DuplicateToolResult", () => repository.getResult(input.executionId, result.call_id).pipe(Effect43.mapError(mapRepositoryError3), Effect43.flatMap((existing) => existing === undefined ? Effect43.fail(ToolRuntimeError.make({ message: "DuplicateToolResult" })) : Effect43.succeed(existing)))), Effect43.mapError(preserveRecordResultError), Effect43.flatMap((record2) => eventLog.maxSequence(input.executionId).pipe(Effect43.mapError(mapEventLogError2), Effect43.flatMap((max) => appendIdempotentTo(eventLog, resultEvent(input, record2.result, (max ?? input.eventSequence) + 1)).pipe(Effect43.mapError(mapEventLogError2))), Effect43.as(record2.result))));
10431
+ var repairResultEvent = (eventLog, input, record2) => ensureToolEvent(eventLog, resultEvent({ ...input, createdAt: record2.createdAt - 1 }, record2.result, input.eventSequence + 1));
10432
+ var persistReceived = (repository, input, result) => repository.recordResult({ executionId: input.executionId, result, createdAt: input.createdAt + 1 }).pipe(Effect43.catchTag("DuplicateToolResult", () => repository.getResult(input.executionId, result.call_id).pipe(Effect43.mapError(mapRepositoryError3), Effect43.flatMap((existing) => existing === undefined ? Effect43.fail(ToolRuntimeError.make({ message: "DuplicateToolResult" })) : Effect43.succeed(existing)))), Effect43.mapError(preserveRecordResultError));
10433
+ var recordReceived = (eventLog, input, record2) => ensureToolEvent(eventLog, resultEvent({ ...input, createdAt: record2.createdAt - 1 }, record2.result, input.eventSequence + 1)).pipe(Effect43.as(record2.result));
10281
10434
  var nonEmptyName = (name) => Schema40.decodeUnknownSync(exports_shared_schema.NonEmptyString)(name);
10282
10435
  var needsApprovalFromEffectTool = (tool) => tool.needsApproval === undefined ? undefined : typeof tool.needsApproval === "boolean" ? tool.needsApproval : true;
10283
10436
  var definitionFromEffectTool = (modelTool, options) => ({
@@ -10356,7 +10509,7 @@ var placedTool = (modelTool, placement, options = {}) => ({
10356
10509
  });
10357
10510
  var clientTool = Function7.dual((args) => args.length > 1 || args.length === 1 && typeof args[0] === "object" && args[0] !== null && ("name" in args[0]), (modelTool, options = {}) => placedTool(modelTool, { kind: "client" }, options));
10358
10511
  var remoteTool = Function7.dual(2, (modelTool, options) => placedTool(modelTool, { kind: "remote", queue: options.queue }, options));
10359
- var placementWaitId = (input) => exports_ids_schema.WaitId.make(`wait:tool:${input.call.id}`);
10512
+ var placementWaitId = (input) => Identifiers.waitId("tool", input.executionId, input.call.id);
10360
10513
  var placementFailureResult = (input, message) => ({
10361
10514
  call_id: input.call.id,
10362
10515
  output: null,
@@ -10376,11 +10529,11 @@ var externalOutcomeResult = (call, input) => {
10376
10529
  return Schema40.decodeUnknownEffect(exports_tool_schema.resultSchema(call.definition.output_schema))(call.externalOutcome.output).pipe(Effect43.map((output) => ({ call_id: input.call.id, output: jsonValue2(output) })), Effect43.catch((error5) => Effect43.succeed(placementFailureResult(input, `invalid ${placement} result: ${error5.message}`))));
10377
10530
  };
10378
10531
  var runExternalTool = (repository, waits, call, input) => Effect43.gen(function* () {
10379
- const waitId = placementWaitId(input);
10380
- let wait = yield* waits.get(waitId).pipe(Effect43.mapError(mapWaitServiceError));
10532
+ const waitId2 = placementWaitId(input);
10533
+ let wait = yield* waits.get(waitId2).pipe(Effect43.mapError(mapWaitServiceError));
10381
10534
  if (wait === undefined) {
10382
10535
  wait = yield* waits.createDetached({
10383
- waitId,
10536
+ waitId: waitId2,
10384
10537
  executionId: input.executionId,
10385
10538
  mode: "event",
10386
10539
  correlationKey: input.call.id,
@@ -10397,12 +10550,12 @@ var runExternalTool = (repository, waits, call, input) => Effect43.gen(function*
10397
10550
  const waitingCall = call.state === "requested" ? yield* repository.prepareExternalWait({
10398
10551
  executionId: input.executionId,
10399
10552
  callId: input.call.id,
10400
- waitId,
10553
+ waitId: waitId2,
10401
10554
  availableAt: input.createdAt,
10402
10555
  updatedAt: input.createdAt
10403
10556
  }).pipe(Effect43.mapError(mapRepositoryError3)) : call;
10404
10557
  if (wait.state === "open")
10405
- return yield* waitRequested(input, waitId);
10558
+ return yield* waitRequested(input, waitId2);
10406
10559
  if (wait.state === "timed_out")
10407
10560
  return placementFailureResult(input, "Tool execution timed out");
10408
10561
  if (wait.state === "cancelled")
@@ -10424,7 +10577,25 @@ var makeService = (initialTools) => Effect43.gen(function* () {
10424
10577
  register: Effect43.fn("ToolRuntime.register")((registeredTool) => registerTool(tools, registeredTool)),
10425
10578
  definitions: Ref11.get(tools).pipe(Effect43.map((registry) => Chunk.toReadonlyArray(Chunk.map(registry, (registeredTool) => registeredTool.definition)))),
10426
10579
  registeredTools: Ref11.get(tools).pipe(Effect43.map(Chunk.toReadonlyArray)),
10580
+ prepare: Effect43.fn("ToolRuntime.prepare")(function* (input) {
10581
+ const stored = yield* Ref11.get(tools);
10582
+ const registry = (input.extraTools ?? []).reduce(upsertTool, stored);
10583
+ const registeredTool = Chunk.findFirst(registry, sameToolName(input.call.name)).pipe(Option8.getOrUndefined);
10584
+ if (registeredTool === undefined)
10585
+ return yield* ToolNotRegistered.make({ tool_name: input.call.name });
10586
+ yield* ensureAllowed(registeredTool, input);
10587
+ yield* validateInput(registeredTool, input);
10588
+ yield* recordRequested(repository, eventLog, input, registeredTool);
10589
+ if (input.onRequested !== undefined)
10590
+ yield* input.onRequested;
10591
+ }),
10427
10592
  run: Effect43.fn("ToolRuntime.run")(function* (input) {
10593
+ let settlementSequence;
10594
+ const beginSettlement = Effect43.suspend(() => {
10595
+ if (settlementSequence !== undefined)
10596
+ return Effect43.succeed(settlementSequence);
10597
+ return (input.beforeSettlement ?? Effect43.succeed(input.eventSequence)).pipe(Effect43.tap((sequence) => Effect43.sync(() => settlementSequence = sequence)));
10598
+ });
10428
10599
  const stored = yield* Ref11.get(tools);
10429
10600
  const registry = (input.extraTools ?? []).reduce(upsertTool, stored);
10430
10601
  const registeredTool = Chunk.findFirst(registry, sameToolName(input.call.name)).pipe(Option8.getOrUndefined);
@@ -10435,8 +10606,11 @@ var makeService = (initialTools) => Effect43.gen(function* () {
10435
10606
  yield* ensureAllowed(registeredTool, input);
10436
10607
  yield* validateInput(registeredTool, input);
10437
10608
  const call = yield* recordRequested(repository, eventLog, input, registeredTool);
10609
+ if (input.onRequested !== undefined)
10610
+ yield* input.onRequested;
10438
10611
  const existingResult = yield* repository.getResult(input.executionId, input.call.id).pipe(Effect43.mapError(mapRepositoryError3));
10439
10612
  if (existingResult !== undefined) {
10613
+ yield* beginSettlement;
10440
10614
  yield* repairResultEvent(eventLog, input, existingResult);
10441
10615
  return existingResult.result;
10442
10616
  }
@@ -10444,26 +10618,46 @@ var makeService = (initialTools) => Effect43.gen(function* () {
10444
10618
  if (registeredTool.definition.needs_approval === true) {
10445
10619
  const bypass = yield* hasPermissionApprovalBypass(waits, input);
10446
10620
  if (!bypass) {
10447
- const decision = yield* resolveApproval(waits, eventLog, input);
10448
- effectiveInput = { ...input, eventSequence: input.eventSequence + 2, createdAt: input.createdAt + 2 };
10621
+ const sequence = yield* beginSettlement;
10622
+ effectiveInput = {
10623
+ ...input,
10624
+ eventSequence: sequence,
10625
+ createdAt: input.createdAt + sequence - input.eventSequence
10626
+ };
10627
+ const decision = yield* resolveApproval(waits, eventLog, effectiveInput);
10628
+ effectiveInput = {
10629
+ ...effectiveInput,
10630
+ eventSequence: effectiveInput.eventSequence + 1,
10631
+ createdAt: effectiveInput.createdAt + 1
10632
+ };
10449
10633
  if (decision._tag === "denied") {
10450
- const denied = yield* recordReceived(repository, eventLog, effectiveInput, {
10634
+ const deniedRecord = yield* persistReceived(repository, effectiveInput, {
10451
10635
  call_id: input.call.id,
10452
10636
  output: null,
10453
10637
  error: decision.reason
10454
10638
  });
10639
+ const denied = yield* recordReceived(eventLog, effectiveInput, deniedRecord);
10455
10640
  yield* recordToolCall(input.call.name, "denied");
10456
10641
  return denied;
10457
10642
  }
10458
10643
  }
10459
10644
  }
10460
- const rawResult = call.placement.kind === "client" || call.placement.kind === "remote" ? yield* runExternalTool(repository, waits, call, effectiveInput) : yield* repository.beginAttempt({
10645
+ const executeHandler = call.placement.kind === "client" || call.placement.kind === "remote" ? runExternalTool(repository, waits, call, effectiveInput) : repository.beginAttempt({
10461
10646
  executionId: input.executionId,
10462
10647
  callId: input.call.id,
10463
10648
  startedAt: effectiveInput.createdAt
10464
10649
  }).pipe(Effect43.mapError(mapRepositoryError3), Effect43.flatMap(() => finalToolResult(registeredTool, effectiveInput, call.idempotencyKey)), Effect43.catchTag("ToolExecutionFailed", (error5) => Effect43.succeed(placementFailureResult(input, error5.message))));
10465
- const result = input.transformResult === undefined || rawResult.error !== undefined ? rawResult : yield* input.transformResult(rawResult);
10466
- const received = yield* recordReceived(repository, eventLog, effectiveInput, result);
10650
+ const record2 = yield* Effect43.uninterruptibleMask((restore) => restore(executeHandler).pipe(Effect43.flatMap((rawResult) => input.transformResult === undefined || rawResult.error !== undefined ? Effect43.succeed(rawResult) : input.transformResult(rawResult)), Effect43.flatMap((result2) => persistReceived(repository, effectiveInput, result2))));
10651
+ const result = record2.result;
10652
+ if (effectiveInput === input) {
10653
+ const sequence = yield* beginSettlement;
10654
+ effectiveInput = {
10655
+ ...input,
10656
+ eventSequence: sequence,
10657
+ createdAt: input.createdAt + sequence - input.eventSequence
10658
+ };
10659
+ }
10660
+ const received = yield* recordReceived(eventLog, effectiveInput, record2);
10467
10661
  yield* recordToolCall(input.call.name, result.error === undefined ? "success" : "failure");
10468
10662
  return received;
10469
10663
  }).pipe(Effect43.tapError((error5) => recordToolCall(input.call.name, error5._tag === "ToolExecutionWaitRequested" ? "wait" : error5._tag === "ToolPermissionDenied" ? "denied" : "failure")));
@@ -11462,10 +11656,10 @@ var presetMap = (agent) => new Map(Object.entries(agent.child_run_presets ?? {})
11462
11656
  ...preset.metadata === undefined ? {} : { metadata: preset.metadata }
11463
11657
  }
11464
11658
  ]));
11465
- var createJoinWait = Effect52.fn("SpawnChildRunTool.createJoinWait")(function* (config, input, id, waitId, createdAt) {
11659
+ var createJoinWait = Effect52.fn("SpawnChildRunTool.createJoinWait")(function* (config, input, id, waitId2, createdAt) {
11466
11660
  const eventSequence = yield* nextEventSequence(config.eventLog, input.execution_id);
11467
11661
  yield* config.waits.createDetached({
11468
- waitId,
11662
+ waitId: waitId2,
11469
11663
  executionId: input.execution_id,
11470
11664
  mode: "child",
11471
11665
  correlationKey: id,
@@ -11477,7 +11671,7 @@ var createJoinWait = Effect52.fn("SpawnChildRunTool.createJoinWait")(function* (
11477
11671
  createdAt
11478
11672
  }).pipe(Effect52.mapError(mapWaitError));
11479
11673
  });
11480
- var dispatchChild = Effect52.fn("SpawnChildRunTool.dispatchChild")(function* (config, input, id, definition, waitId) {
11674
+ var dispatchChild = Effect52.fn("SpawnChildRunTool.dispatchChild")(function* (config, input, id, definition, waitId2) {
11481
11675
  yield* config.dispatch({
11482
11676
  executionId: exports_ids_schema.ExecutionId.make(id),
11483
11677
  rootAddressId: input.address_id,
@@ -11493,7 +11687,7 @@ var dispatchChild = Effect52.fn("SpawnChildRunTool.dispatchChild")(function* (co
11493
11687
  metadata: {
11494
11688
  parent_execution_id: input.execution_id,
11495
11689
  child_execution_id: id,
11496
- parent_wait_id: waitId
11690
+ parent_wait_id: waitId2
11497
11691
  }
11498
11692
  }).pipe(Effect52.mapError((error5) => ToolRuntimeError.make({ message: String(error5) })));
11499
11693
  });
@@ -11517,10 +11711,10 @@ var run3 = Effect52.fn("SpawnChildRunTool.run")(function* (config, activeToolNam
11517
11711
  if (enforceStaticOrDynamic)
11518
11712
  yield* ensureStaticOrDynamic(input);
11519
11713
  const id = childExecutionId(context);
11520
- const waitId = childWaitId(id);
11521
- const existingWait = yield* config.waits.get(waitId).pipe(Effect52.mapError(mapWaitError));
11714
+ const waitId2 = childWaitId(id);
11715
+ const existingWait = yield* config.waits.get(waitId2).pipe(Effect52.mapError(mapWaitError));
11522
11716
  if (existingWait?.state === "open") {
11523
- return yield* ToolExecutionWaitRequested.make({ tool_name: activeToolName, wait_id: waitId });
11717
+ return yield* ToolExecutionWaitRequested.make({ tool_name: activeToolName, wait_id: waitId2 });
11524
11718
  }
11525
11719
  if (existingWait !== undefined)
11526
11720
  return yield* resultFromTerminal(config, id, existingWait);
@@ -11550,9 +11744,9 @@ var run3 = Effect52.fn("SpawnChildRunTool.run")(function* (config, activeToolNam
11550
11744
  createdAt: context.createdAt + 1
11551
11745
  }).pipe(Effect52.mapError((error5) => mapChildRunError(activeToolName, error5)));
11552
11746
  }
11553
- yield* createJoinWait(config, spawn, id, waitId, context.createdAt + 2);
11554
- yield* dispatchChild(config, spawn, id, definition, waitId);
11555
- return yield* ToolExecutionWaitRequested.make({ tool_name: activeToolName, wait_id: waitId });
11747
+ yield* createJoinWait(config, spawn, id, waitId2, context.createdAt + 2);
11748
+ yield* dispatchChild(config, spawn, id, definition, waitId2);
11749
+ return yield* ToolExecutionWaitRequested.make({ tool_name: activeToolName, wait_id: waitId2 });
11556
11750
  });
11557
11751
  var registeredTool = (config) => tool(toolName, {
11558
11752
  description: "Spawn a durable child run and wait for its terminal output.",
@@ -11904,7 +12098,7 @@ var registeredTools2 = (state) => [
11904
12098
  ];
11905
12099
 
11906
12100
  // ../runtime/src/session/session-store-service.ts
11907
- import { Clock as Clock9, Context as Context51, Effect as Effect57, Function as Function12, Layer as Layer52, Ref as Ref13, Semaphore as Semaphore4 } from "effect";
12101
+ import { Clock as Clock9, Context as Context51, Effect as Effect57, Function as Function12, Layer as Layer52, Ref as Ref13, Semaphore as Semaphore5 } from "effect";
11908
12102
 
11909
12103
  class Service51 extends Context51.Service()("@relayfx/runtime/session/session-store-service/Service") {
11910
12104
  }
@@ -12046,7 +12240,7 @@ var toAppendInput = (input) => {
12046
12240
  var make4 = Effect57.fn("RelaySessionStore.make")(function* (sessionId, entryScope = "default", makeOptions) {
12047
12241
  const repository = yield* exports_session_repository.Service;
12048
12242
  const state = yield* Ref13.make(undefined);
12049
- const lock = yield* Semaphore4.make(1);
12243
+ const lock = yield* Semaphore5.make(1);
12050
12244
  const entryPrefix = `${sessionId}:entry:${entryScope}:`;
12051
12245
  const initialState = Effect57.fn("RelaySessionStore.initialState")(function* (input) {
12052
12246
  const current2 = yield* Ref13.get(state);
@@ -13022,13 +13216,13 @@ var layer47 = Layer58.effect(Service57, Effect63.gen(function* () {
13022
13216
  }));
13023
13217
 
13024
13218
  // ../runtime/src/tool/tool-transition-coordinator.ts
13025
- import { Context as Context58, Effect as Effect64, Layer as Layer59, Semaphore as Semaphore5 } from "effect";
13219
+ import { Context as Context58, Effect as Effect64, Layer as Layer59, Semaphore as Semaphore6 } from "effect";
13026
13220
  import { SqlClient as SqlClient29 } from "effect/unstable/sql/SqlClient";
13027
13221
 
13028
13222
  class Service58 extends Context58.Service()("@relayfx/runtime/tool/tool-transition-coordinator/Service") {
13029
13223
  }
13030
13224
  var make6 = Effect64.gen(function* () {
13031
- const semaphore = yield* Semaphore5.make(1);
13225
+ const semaphore = yield* Semaphore6.make(1);
13032
13226
  return Service58.of({
13033
13227
  coordinate: (effect) => semaphore.withPermit(effect)
13034
13228
  });
@@ -13036,7 +13230,7 @@ var make6 = Effect64.gen(function* () {
13036
13230
  var memoryLayer41 = Layer59.effect(Service58, make6);
13037
13231
  var sqlLayer = Layer59.effect(Service58, Effect64.gen(function* () {
13038
13232
  const sql = yield* SqlClient29;
13039
- const semaphore = yield* Semaphore5.make(1);
13233
+ const semaphore = yield* Semaphore6.make(1);
13040
13234
  return Service58.of({
13041
13235
  coordinate: (effect) => semaphore.withPermit(sql.withTransaction(effect))
13042
13236
  });
@@ -13353,9 +13547,9 @@ var ActivityNames = {
13353
13547
  accept: `${StartExecutionWorkflowName}/Accept`,
13354
13548
  cancel: (turn) => `${StartExecutionWorkflowName}/Cancel/${turn}`,
13355
13549
  checkCancel: (turn) => `${StartExecutionWorkflowName}/CheckCancel/${turn}`,
13356
- loadWaitBeforeSleep: (waitId) => `${StartExecutionWorkflowName}/LoadWaitBeforeSleep/${waitId}`,
13357
- loadWaitAfterWake: (waitId) => `${StartExecutionWorkflowName}/LoadWaitAfterWake/${waitId}`,
13358
- markWaiting: (waitId) => `${StartExecutionWorkflowName}/MarkWaiting/${waitId}`,
13550
+ loadWaitBeforeSleep: (waitId2) => `${StartExecutionWorkflowName}/LoadWaitBeforeSleep/${waitId2}`,
13551
+ loadWaitAfterWake: (waitId2) => `${StartExecutionWorkflowName}/LoadWaitAfterWake/${waitId2}`,
13552
+ markWaiting: (waitId2) => `${StartExecutionWorkflowName}/MarkWaiting/${waitId2}`,
13359
13553
  ensureWorkspace: `${StartExecutionWorkflowName}/EnsureWorkspace`,
13360
13554
  suspendWorkspace: (key4) => `${StartExecutionWorkflowName}/SuspendWorkspace/${key4}`,
13361
13555
  resumeWorkspace: (key4) => `${StartExecutionWorkflowName}/ResumeWorkspace/${key4}`,
@@ -13410,7 +13604,7 @@ var mapChildExecutionRepositoryError = (error5) => ExecutionWorkflowFailed.make(
13410
13604
  var mapSkillRegistryError = (error5) => ExecutionWorkflowFailed.make({ message: error5.message });
13411
13605
  var mapEventLogError6 = (error5) => ExecutionWorkflowFailed.make({ message: error5._tag });
13412
13606
  var mapWorkspaceError = (error5) => ExecutionWorkflowFailed.make({ message: error5._tag });
13413
- var waitSignal = (waitId) => DurableDeferred.make(`Relay/Execution/Wait/${waitId}`, {
13607
+ var waitSignal = (waitId2) => DurableDeferred.make(`Relay/Execution/Wait/${waitId2}`, {
13414
13608
  success: WaitSignal,
13415
13609
  error: ExecutionWorkflowFailed
13416
13610
  });
@@ -13484,8 +13678,8 @@ var acceptExecution = (input) => Activity.make({
13484
13678
  });
13485
13679
  var terminalExecutionStatuses = new Set(["completed", "failed", "cancelled"]);
13486
13680
  var waitIdFromRecord = (record2) => {
13487
- const waitId = record2.metadata.wait_id;
13488
- return typeof waitId === "string" ? exports_ids_schema.WaitId.make(waitId) : undefined;
13681
+ const waitId2 = record2.metadata.wait_id;
13682
+ return typeof waitId2 === "string" ? exports_ids_schema.WaitId.make(waitId2) : undefined;
13489
13683
  };
13490
13684
  var prepareCancellation = Effect67.fn("ExecutionWorkflow.prepareCancellation")(function* (input) {
13491
13685
  const repository = yield* exports_execution_repository.Service;
@@ -13633,11 +13827,11 @@ var loadCancellationRequested = (input, turn) => Activity.make({
13633
13827
  return record2?.metadata?.cancellation_requested === true;
13634
13828
  })
13635
13829
  });
13636
- var loadWait = (name, waitId) => Activity.make({
13830
+ var loadWait = (name, waitId2) => Activity.make({
13637
13831
  name,
13638
13832
  success: Schema61.UndefinedOr(WaitSnapshot),
13639
13833
  error: ExecutionWorkflowFailed,
13640
- execute: get11(waitId).pipe(Effect67.map((record2) => record2 === undefined ? undefined : toWaitSnapshot(record2)), Effect67.mapError(mapWaitError2))
13834
+ execute: get11(waitId2).pipe(Effect67.map((record2) => record2 === undefined ? undefined : toWaitSnapshot(record2)), Effect67.mapError(mapWaitError2))
13641
13835
  });
13642
13836
  var markWaiting = (input, repository, wait) => Activity.make({
13643
13837
  name: ActivityNames.markWaiting(wait.id),
@@ -13757,7 +13951,7 @@ var failWorkspace = (input, error5) => fail({
13757
13951
  }).pipe(Effect67.catch(() => Effect67.void));
13758
13952
  var attachWorkspace = (input) => attach({ executionId: input.execution_id, now: input.started_at }).pipe(Effect67.mapError(mapWorkspaceError));
13759
13953
  var sessionEntryScope = Function13.dual(2, (input, turn) => `${input.execution_id}:${workflowGenerationForStart(input)}:complete:${turn}`);
13760
- var completeExecution = (input, waitId, waitState, workspaceRuntimeLayer, turn, pendingSuspension) => Activity.make({
13954
+ var completeExecution = (input, waitId2, waitState, workspaceRuntimeLayer, turn, pendingSuspension) => Activity.make({
13761
13955
  name: ActivityNames.complete(turn),
13762
13956
  success: exports_execution_schema.Execution,
13763
13957
  error: ExecutionWorkflowFailed,
@@ -13811,8 +14005,8 @@ var completeExecution = (input, waitId, waitState, workspaceRuntimeLayer, turn,
13811
14005
  const program = activeProgram.pipe(Effect67.map((result) => ({
13812
14006
  metadata: {
13813
14007
  ...result.metadata,
13814
- ...waitId === undefined ? {} : { wait_id: waitId },
13815
- ...waitId === undefined || waitState === undefined ? {} : { wait_state: waitState }
14008
+ ...waitId2 === undefined ? {} : { wait_id: waitId2 },
14009
+ ...waitId2 === undefined || waitState === undefined ? {} : { wait_state: waitState }
13816
14010
  },
13817
14011
  nextEventSequence: result.nextEventSequence
13818
14012
  })), Effect67.catchTag("AgentLoopWaitRequested", (wait) => Effect67.succeed({
@@ -13906,8 +14100,8 @@ var terminalOutput = (execution) => {
13906
14100
  const output = execution.metadata?.model_output;
13907
14101
  return typeof output === "string" ? [exports_content_schema.text(output)] : [];
13908
14102
  };
13909
- var missingWait = (waitId) => ExecutionWorkflowFailed.make({ message: `Wait not found: ${waitId}` });
13910
- var stillOpen = (waitId) => ExecutionWorkflowFailed.make({ message: `Wait remained open after wake: ${waitId}` });
14103
+ var missingWait = (waitId2) => ExecutionWorkflowFailed.make({ message: `Wait not found: ${waitId2}` });
14104
+ var stillOpen = (waitId2) => ExecutionWorkflowFailed.make({ message: `Wait remained open after wake: ${waitId2}` });
13911
14105
  var resolveWaitState = Effect67.fn("ExecutionWorkflow.resolveWaitState")(function* (input, repository) {
13912
14106
  if (input.wait_id === undefined)
13913
14107
  return;
@@ -13930,32 +14124,32 @@ var resolveWaitState = Effect67.fn("ExecutionWorkflow.resolveWaitState")(functio
13930
14124
  return afterTerminal;
13931
14125
  });
13932
14126
  var waitIdFromExecution = (execution) => {
13933
- const waitId = execution.metadata?.wait_id;
13934
- return typeof waitId === "string" ? exports_ids_schema.WaitId.make(waitId) : undefined;
14127
+ const waitId2 = execution.metadata?.wait_id;
14128
+ return typeof waitId2 === "string" ? exports_ids_schema.WaitId.make(waitId2) : undefined;
13935
14129
  };
13936
14130
  var pendingSuspensionFromExecution = (execution) => {
13937
14131
  const pending = execution.metadata?.pending_agent_suspension;
13938
14132
  return Schema61.decodeUnknownOption(exports_agent_event.AgentSuspended)(pending).pipe(Option15.getOrUndefined);
13939
14133
  };
13940
- var finishCancelledWait = Effect67.fn("ExecutionWorkflow.finishCancelledWait")(function* (startInput, turn, waitId) {
14134
+ var finishCancelledWait = Effect67.fn("ExecutionWorkflow.finishCancelledWait")(function* (startInput, turn, waitId2) {
13941
14135
  const cancelled = yield* cancelExecution(startInput, turn, "wait cancelled");
13942
14136
  yield* releaseWorkspace(startInput);
13943
14137
  yield* notifyParent(startInput, "cancelled", []);
13944
14138
  return {
13945
14139
  execution_id: cancelled.id,
13946
14140
  status: cancelled.status,
13947
- wait_id: waitId,
14141
+ wait_id: waitId2,
13948
14142
  wait_state: "cancelled",
13949
14143
  ...cancelled.metadata === undefined ? {} : { metadata: cancelled.metadata }
13950
14144
  };
13951
14145
  });
13952
- var continueAsNew = (startInput, turn, waitId, pendingSuspension) => Activity.make({
14146
+ var continueAsNew = (startInput, turn, waitId2, pendingSuspension) => Activity.make({
13953
14147
  name: ActivityNames.continueAsNew(turn),
13954
14148
  success: StartResult,
13955
14149
  error: ExecutionWorkflowError,
13956
14150
  execute: StartExecutionWorkflow.execute({
13957
14151
  ...startInput,
13958
- wait_id: waitId,
14152
+ wait_id: waitId2,
13959
14153
  resume_suspension: pendingSuspension,
13960
14154
  workflow_generation: workflowGenerationForStart(startInput) + 1
13961
14155
  })
@@ -14016,8 +14210,8 @@ var runWorkflow = Effect67.fn("ExecutionWorkflow.run")(function* (input) {
14016
14210
  break;
14017
14211
  if (turn >= maxWaitTurns)
14018
14212
  return yield* ExecutionWorkflowFailed.make({ message: "Agent wait turn limit exceeded" });
14019
- const waitId = waitIdFromExecution(execution);
14020
- if (waitId === undefined)
14213
+ const waitId2 = waitIdFromExecution(execution);
14214
+ if (waitId2 === undefined)
14021
14215
  return yield* ExecutionWorkflowFailed.make({ message: "Waiting execution missing wait id" });
14022
14216
  pendingSuspension = pendingSuspensionFromExecution(execution);
14023
14217
  if (pendingSuspension === undefined) {
@@ -14027,14 +14221,14 @@ var runWorkflow = Effect67.fn("ExecutionWorkflow.run")(function* (input) {
14027
14221
  yield* failIncompatibleCheckpoint(startInput, error5);
14028
14222
  return yield* error5;
14029
14223
  }
14030
- activeWaitId = waitId;
14031
- waitState = yield* resolveWaitState({ ...startInput, wait_id: waitId }, repository);
14224
+ activeWaitId = waitId2;
14225
+ waitState = yield* resolveWaitState({ ...startInput, wait_id: waitId2 }, repository);
14032
14226
  if (waitState === "cancelled") {
14033
- return yield* finishCancelledWait(startInput, turn + 1, waitId);
14227
+ return yield* finishCancelledWait(startInput, turn + 1, waitId2);
14034
14228
  }
14035
14229
  turn += 1;
14036
14230
  if (continueAsNewAfterTurns !== undefined && turn >= continueAsNewAfterTurns) {
14037
- return yield* continueAsNew(startInput, turn, waitId, pendingSuspension);
14231
+ return yield* continueAsNew(startInput, turn, waitId2, pendingSuspension);
14038
14232
  }
14039
14233
  }
14040
14234
  yield* releaseWorkspace(startInput);
@@ -14053,11 +14247,11 @@ var awaitCanonicalSettledResult = Effect67.fn("ExecutionWorkflow.awaitCanonicalS
14053
14247
  until: (record2) => record2?.status === "waiting" || record2 !== undefined && terminalExecutionStatuses.has(record2.status)
14054
14248
  }));
14055
14249
  const canonicalWaitId = execution?.metadata?.wait_id;
14056
- const waitId = typeof canonicalWaitId === "string" ? exports_ids_schema.WaitId.make(canonicalWaitId) : input.wait_id;
14250
+ const waitId2 = typeof canonicalWaitId === "string" ? exports_ids_schema.WaitId.make(canonicalWaitId) : input.wait_id;
14057
14251
  const result = {
14058
14252
  execution_id: input.execution_id,
14059
14253
  status: execution?.status ?? "waiting",
14060
- ...waitId === undefined ? {} : { wait_id: waitId },
14254
+ ...waitId2 === undefined ? {} : { wait_id: waitId2 },
14061
14255
  ...execution?.metadata === undefined ? {} : { metadata: execution.metadata }
14062
14256
  };
14063
14257
  return result;
@@ -14095,14 +14289,14 @@ var startRequest = Effect67.fn("ExecutionWorkflow.startRequest")(function* (inpu
14095
14289
  }
14096
14290
  const workflowExecutionId2 = yield* activeWorkflowExecutionIdForExecution(input.execution_id);
14097
14291
  const existingWaitId = existing.metadata?.wait_id;
14098
- const waitId = typeof existingWaitId === "string" ? exports_ids_schema.WaitId.make(existingWaitId) : undefined;
14099
- if (existing.status === "waiting" && waitId !== undefined) {
14100
- const wait = yield* get11(waitId).pipe(Effect67.mapError(mapWaitError2));
14292
+ const waitId2 = typeof existingWaitId === "string" ? exports_ids_schema.WaitId.make(existingWaitId) : undefined;
14293
+ if (existing.status === "waiting" && waitId2 !== undefined) {
14294
+ const wait = yield* get11(waitId2).pipe(Effect67.mapError(mapWaitError2));
14101
14295
  const state = wait === undefined ? undefined : terminalWaitState(toWaitSnapshot(wait));
14102
14296
  if (state !== undefined) {
14103
14297
  yield* signalWait({
14104
14298
  workflow_execution_id: workflowExecutionId2,
14105
- wait_id: waitId,
14299
+ wait_id: waitId2,
14106
14300
  state,
14107
14301
  signaled_at: wait?.resolvedAt ?? input.started_at
14108
14302
  });
@@ -14241,9 +14435,9 @@ var makeLayer = (signalDependencies) => Layer63.effect(Service62, Effect69.gen(f
14241
14435
  const findOpenByCorrelation = envelopes.findOpenByCorrelation;
14242
14436
  const wait = findOpenByCorrelation === undefined ? undefined : yield* findOpenByCorrelation(input.executionId, `inbox:${input.executionId}`).pipe(Effect69.mapError((error5) => InboxDeliveryError.make({ execution_id: input.executionId, message: error5.message })));
14243
14437
  if (wait?.state === "open") {
14244
- const waitId = wait.id;
14438
+ const waitId2 = wait.id;
14245
14439
  const sequence = yield* nextSequence(eventLog, input.executionId).pipe(Effect69.mapError((error5) => InboxDeliveryError.make({ execution_id: input.executionId, message: error5._tag })));
14246
- const transition3 = yield* waits.wake({ waitId, resolvedAt: input.createdAt, eventSequence: sequence }).pipe(Effect69.mapError((error5) => InboxDeliveryError.make({
14440
+ const transition3 = yield* waits.wake({ waitId: waitId2, resolvedAt: input.createdAt, eventSequence: sequence }).pipe(Effect69.mapError((error5) => InboxDeliveryError.make({
14247
14441
  execution_id: input.executionId,
14248
14442
  message: error5._tag === "WaitNotFound" ? error5.wait_id : error5.message
14249
14443
  })));
@@ -14269,14 +14463,14 @@ var makeLayer = (signalDependencies) => Layer63.effect(Service62, Effect69.gen(f
14269
14463
  }),
14270
14464
  undrainedCount: (id) => repository.countUndrained(id).pipe(Effect69.mapError((error5) => InboxServiceError.make({ message: error5.message }))),
14271
14465
  reply: Effect69.fn("InboxService.reply")(function* (input) {
14272
- const waitId = exports_ids_schema.WaitId.make(input.replyToken);
14273
- const wait = yield* waits.get(waitId).pipe(Effect69.mapError(() => InboxReplyTokenInvalid.make({ reply_token: input.replyToken })));
14466
+ const waitId2 = exports_ids_schema.WaitId.make(input.replyToken);
14467
+ const wait = yield* waits.get(waitId2).pipe(Effect69.mapError(() => InboxReplyTokenInvalid.make({ reply_token: input.replyToken })));
14274
14468
  if (wait === undefined || wait.state !== "open" || wait.envelopeId === undefined)
14275
14469
  return yield* InboxReplyTokenInvalid.make({ reply_token: input.replyToken });
14276
14470
  const original = yield* envelopes.getEnvelope(wait.envelopeId).pipe(Effect69.mapError(() => InboxReplyTokenInvalid.make({ reply_token: input.replyToken })));
14277
14471
  if (original === undefined)
14278
14472
  return yield* InboxReplyTokenInvalid.make({ reply_token: input.replyToken });
14279
- const envelopeId = exports_ids_schema.EnvelopeId.make(`envelope:reply:${waitId}`);
14473
+ const envelopeId = exports_ids_schema.EnvelopeId.make(`envelope:reply:${waitId2}`);
14280
14474
  yield* envelopes.acceptEnvelope({
14281
14475
  envelope: {
14282
14476
  id: envelopeId,
@@ -14289,7 +14483,7 @@ var makeLayer = (signalDependencies) => Layer63.effect(Service62, Effect69.gen(f
14289
14483
  }
14290
14484
  }).pipe(Effect69.mapError((error5) => InboxDeliveryError.make({ execution_id: wait.executionId, message: error5.message })));
14291
14485
  const sequence = yield* nextSequence(eventLog, wait.executionId).pipe(Effect69.mapError((error5) => InboxDeliveryError.make({ execution_id: wait.executionId, message: error5._tag })));
14292
- const transition3 = yield* waits.wake({ waitId, resolvedAt: input.createdAt, eventSequence: sequence }).pipe(Effect69.mapError(() => InboxReplyTokenInvalid.make({ reply_token: input.replyToken })));
14486
+ const transition3 = yield* waits.wake({ waitId: waitId2, resolvedAt: input.createdAt, eventSequence: sequence }).pipe(Effect69.mapError(() => InboxReplyTokenInvalid.make({ reply_token: input.replyToken })));
14293
14487
  if (!transition3.transitioned)
14294
14488
  return yield* InboxReplyTokenInvalid.make({ reply_token: input.replyToken });
14295
14489
  if (signalDependencies !== undefined) {
@@ -14301,7 +14495,7 @@ var makeLayer = (signalDependencies) => Layer63.effect(Service62, Effect69.gen(f
14301
14495
  signaledAt: input.createdAt
14302
14496
  }).pipe(Effect69.provideService(exports_execution_repository.Service, signalDependencies.executionRepository), Effect69.mapError((error5) => InboxDeliveryError.make({ execution_id: wait.executionId, message: String(error5) })));
14303
14497
  }
14304
- return { envelope_id: envelopeId, execution_id: wait.executionId, wait_id: waitId };
14498
+ return { envelope_id: envelopeId, execution_id: wait.executionId, wait_id: waitId2 };
14305
14499
  })
14306
14500
  });
14307
14501
  }));
@@ -14454,8 +14648,8 @@ var registeredTool4 = (config) => tool(toolName4, {
14454
14648
  requiredPermissions: [permissionName4],
14455
14649
  metadata: { relay_core_tool: true },
14456
14650
  run: (input, context) => Effect72.gen(function* () {
14457
- const waitId = exports_ids_schema.WaitId.make(`wait:inbox:${context.call.id}`);
14458
- const existing = yield* config.waits.get(waitId).pipe(Effect72.mapError((error5) => ToolRuntimeError.make({ message: error5.message })));
14651
+ const waitId2 = exports_ids_schema.WaitId.make(`wait:inbox:${context.call.id}`);
14652
+ const existing = yield* config.waits.get(waitId2).pipe(Effect72.mapError((error5) => ToolRuntimeError.make({ message: error5.message })));
14459
14653
  const drain2 = () => config.inbox.drain({ executionId: context.executionId, drainId: context.call.id }).pipe(Effect72.mapError((error5) => ToolRuntimeError.make({ message: error5.message })));
14460
14654
  if (existing?.state === "timed_out")
14461
14655
  return { status: "timed_out", messages: [] };
@@ -14464,7 +14658,7 @@ var registeredTool4 = (config) => tool(toolName4, {
14464
14658
  return { status: "messages", messages: drained.map(project) };
14465
14659
  }
14466
14660
  if (existing?.state === "open")
14467
- return yield* ToolExecutionWaitRequested.make({ tool_name: toolName4, wait_id: waitId });
14661
+ return yield* ToolExecutionWaitRequested.make({ tool_name: toolName4, wait_id: waitId2 });
14468
14662
  const count = yield* config.inbox.undrainedCount(context.executionId).pipe(Effect72.mapError((error5) => ToolRuntimeError.make({ message: error5.message })));
14469
14663
  if (count > 0) {
14470
14664
  const drained = yield* drain2();
@@ -14472,7 +14666,7 @@ var registeredTool4 = (config) => tool(toolName4, {
14472
14666
  }
14473
14667
  if (existing === undefined)
14474
14668
  yield* config.waits.createDetached({
14475
- waitId,
14669
+ waitId: waitId2,
14476
14670
  executionId: context.executionId,
14477
14671
  mode: "event",
14478
14672
  correlationKey: `inbox:${context.executionId}`,
@@ -14482,13 +14676,13 @@ var registeredTool4 = (config) => tool(toolName4, {
14482
14676
  }).pipe(Effect72.mapError((error5) => ToolRuntimeError.make({ message: error5.message })));
14483
14677
  if ((yield* config.inbox.undrainedCount(context.executionId).pipe(Effect72.mapError((error5) => ToolRuntimeError.make({ message: error5.message })))) > 0) {
14484
14678
  const sequence = yield* config.eventLog.maxSequence(context.executionId).pipe(Effect72.map((value) => (value ?? -1) + 1), Effect72.mapError((error5) => ToolRuntimeError.make({ message: error5._tag })));
14485
- const transition3 = yield* config.waits.wake({ waitId, resolvedAt: context.createdAt, eventSequence: sequence }).pipe(Effect72.mapError((error5) => ToolRuntimeError.make({ message: error5._tag })));
14679
+ const transition3 = yield* config.waits.wake({ waitId: waitId2, resolvedAt: context.createdAt, eventSequence: sequence }).pipe(Effect72.mapError((error5) => ToolRuntimeError.make({ message: error5._tag })));
14486
14680
  if (transition3.transitioned) {
14487
14681
  const drained = yield* drain2();
14488
14682
  return { status: "messages", messages: drained.map(project) };
14489
14683
  }
14490
14684
  }
14491
- return yield* ToolExecutionWaitRequested.make({ tool_name: toolName4, wait_id: waitId });
14685
+ return yield* ToolExecutionWaitRequested.make({ tool_name: toolName4, wait_id: waitId2 });
14492
14686
  })
14493
14687
  });
14494
14688
 
@@ -14669,18 +14863,18 @@ var layer52 = Layer65.effect(Service64, Effect74.gen(function* () {
14669
14863
  });
14670
14864
  const envelope = envelopeFrom(input);
14671
14865
  const ready = readyFor(input, route);
14672
- const waitId = waitIdFor(input);
14866
+ const waitId2 = waitIdFor(input);
14673
14867
  const replayed = yield* repository.getEnvelope(envelope.id).pipe(Effect74.mapError(mapRepositoryError11));
14674
14868
  if (replayed !== undefined) {
14675
14869
  if (route.kind === "local-execution" && inbox._tag === "Some" && input.input.idempotency_key !== undefined) {
14676
- if (waitId !== undefined) {
14677
- yield* inbox.value.ensureReplyWait({ envelope, waitId }).pipe(Effect74.mapError((error5) => EnvelopeServiceError.make({ message: error5.message })));
14870
+ if (waitId2 !== undefined) {
14871
+ yield* inbox.value.ensureReplyWait({ envelope, waitId: waitId2 }).pipe(Effect74.mapError((error5) => EnvelopeServiceError.make({ message: error5.message })));
14678
14872
  }
14679
14873
  yield* inbox.value.deliver({
14680
14874
  executionId: exports_ids_schema.ExecutionId.make(route.route_key),
14681
14875
  envelope,
14682
14876
  idempotencyKey: input.input.idempotency_key,
14683
- ...waitId === undefined ? {} : { replyWaitId: waitId },
14877
+ ...waitId2 === undefined ? {} : { replyWaitId: waitId2 },
14684
14878
  eventSequence: input.eventSequence,
14685
14879
  createdAt: input.createdAt
14686
14880
  }).pipe(Effect74.mapError((error5) => EnvelopeServiceError.make({ message: error5.message })));
@@ -14688,7 +14882,7 @@ var layer52 = Layer65.effect(Service64, Effect74.gen(function* () {
14688
14882
  const recorded = {
14689
14883
  envelope_id: envelope.id,
14690
14884
  execution_id: envelope.execution_id,
14691
- ...waitId === undefined ? {} : { wait_id: waitId }
14885
+ ...waitId2 === undefined ? {} : { wait_id: waitId2 }
14692
14886
  };
14693
14887
  return Object.defineProperty(recorded, "route_kind", { value: route.kind });
14694
14888
  }
@@ -14701,17 +14895,17 @@ var layer52 = Layer65.effect(Service64, Effect74.gen(function* () {
14701
14895
  envelope,
14702
14896
  acceptance: {
14703
14897
  envelope,
14704
- ...waitId === undefined ? {} : { waitId }
14898
+ ...waitId2 === undefined ? {} : { waitId: waitId2 }
14705
14899
  },
14706
14900
  ...input.input.idempotency_key === undefined ? {} : { idempotencyKey: input.input.idempotency_key },
14707
- ...waitId === undefined ? {} : { replyWaitId: waitId },
14901
+ ...waitId2 === undefined ? {} : { replyWaitId: waitId2 },
14708
14902
  eventSequence: input.eventSequence,
14709
14903
  createdAt: input.createdAt
14710
14904
  }).pipe(Effect74.mapError((error5) => EnvelopeServiceError.make({ message: error5.message })));
14711
14905
  accepted2 = {
14712
14906
  envelope_id: envelope.id,
14713
14907
  execution_id: envelope.execution_id,
14714
- ...waitId === undefined ? {} : { wait_id: waitId }
14908
+ ...waitId2 === undefined ? {} : { wait_id: waitId2 }
14715
14909
  };
14716
14910
  if (delivery.deduplicated) {
14717
14911
  return Object.defineProperty(accepted2, "route_kind", { value: route.kind });
@@ -14719,7 +14913,7 @@ var layer52 = Layer65.effect(Service64, Effect74.gen(function* () {
14719
14913
  } else {
14720
14914
  accepted2 = yield* repository.acceptEnvelope({
14721
14915
  envelope,
14722
- ...waitId === undefined ? {} : { waitId },
14916
+ ...waitId2 === undefined ? {} : { waitId: waitId2 },
14723
14917
  ...ready === undefined ? {} : { ready }
14724
14918
  }).pipe(Effect74.mapError(mapRepositoryError11));
14725
14919
  }
@@ -14728,8 +14922,8 @@ var layer52 = Layer65.effect(Service64, Effect74.gen(function* () {
14728
14922
  if (ready !== undefined) {
14729
14923
  yield* appendIdempotentTo(eventLog, readyEvent(input, ready)).pipe(Effect74.mapError(mapEventLogError7));
14730
14924
  }
14731
- if (route.kind === "local-execution" && inbox._tag === "Some" && waitId !== undefined) {
14732
- yield* inbox.value.ensureReplyWait({ envelope, waitId }).pipe(Effect74.mapError((error5) => EnvelopeServiceError.make({ message: error5.message })));
14925
+ if (route.kind === "local-execution" && inbox._tag === "Some" && waitId2 !== undefined) {
14926
+ yield* inbox.value.ensureReplyWait({ envelope, waitId: waitId2 }).pipe(Effect74.mapError((error5) => EnvelopeServiceError.make({ message: error5.message })));
14733
14927
  }
14734
14928
  yield* recordEnvelopeSent(route.kind);
14735
14929
  return Object.defineProperty(accepted2, "route_kind", { value: route.kind });
@@ -14795,9 +14989,9 @@ var layerFromEpoch = (epoch) => exports_instructions.layer(epoch.baseline.length
14795
14989
  // ../runtime/src/agent/relay-permissions.ts
14796
14990
  import { Clock as Clock15, Effect as Effect76, Layer as Layer67, Option as Option16, Schema as Schema69 } from "effect";
14797
14991
  var jsonValue3 = (value) => Schema69.decodeUnknownSync(exports_shared_schema.JsonValue)(value === undefined ? null : value);
14798
- var waitIdForToolCall = (toolCallId) => exports_ids_schema.WaitId.make(`wait:permission:${toolCallId}`);
14992
+ var waitIdForToolCall = (executionId, toolCallId) => Identifiers.waitId("permission", executionId, toolCallId);
14799
14993
  var fallbackToolCallId = (request) => `${request.agentName}:${request.turn}:${request.tool}`;
14800
- var tokenFor = (request) => waitIdForToolCall(request.toolCallId ?? fallbackToolCallId(request));
14994
+ var tokenFor = (executionId, request) => waitIdForToolCall(executionId, request.toolCallId ?? fallbackToolCallId(request));
14801
14995
  var matchingRule = (rules, tool3, params) => {
14802
14996
  let matched;
14803
14997
  for (const rule of rules) {
@@ -14806,7 +15000,7 @@ var matchingRule = (rules, tool3, params) => {
14806
15000
  }
14807
15001
  return matched;
14808
15002
  };
14809
- var staticDecision = (ruleset, request) => {
15003
+ var staticDecision = (executionId, ruleset, request) => {
14810
15004
  const rule = matchingRule(ruleset.rules, request.tool, request.params);
14811
15005
  const level = rule?.level ?? ruleset.fallback ?? "ask";
14812
15006
  switch (level) {
@@ -14818,7 +15012,7 @@ var staticDecision = (ruleset, request) => {
14818
15012
  ...rule?.reason === undefined ? {} : { reason: rule.reason }
14819
15013
  };
14820
15014
  case "ask":
14821
- return { _tag: "Ask", token: tokenFor(request) };
15015
+ return { _tag: "Ask", token: tokenFor(executionId, request) };
14822
15016
  }
14823
15017
  };
14824
15018
  var evaluateDecision = Effect76.fn("RelayPermissions.evaluateDecision")(function* (config, request) {
@@ -14834,10 +15028,10 @@ var evaluateDecision = Effect76.fn("RelayPermissions.evaluateDecision")(function
14834
15028
  ...rule.reason === undefined ? {} : { reason: rule.reason }
14835
15029
  };
14836
15030
  case "ask":
14837
- return { _tag: "Ask", token: tokenFor(request) };
15031
+ return { _tag: "Ask", token: tokenFor(config.executionId, request) };
14838
15032
  }
14839
15033
  }
14840
- return staticDecision(config.ruleset, request);
15034
+ return staticDecision(config.executionId, config.ruleset, request);
14841
15035
  });
14842
15036
  var permissionError = (message) => exports_permissions.PermissionError.make({ message });
14843
15037
  var createdAtForSequence = (config, sequence) => config.startedAt + sequence - config.eventSequence;
@@ -14849,18 +15043,18 @@ var allocateEventSequence = Effect76.fn("RelayPermissions.allocateEventSequence"
14849
15043
  return sequence;
14850
15044
  });
14851
15045
  var resetAllocatorToLog = (config) => config.allocator.current.pipe(Effect76.flatMap((current2) => nextLoggedSequence(config.eventLog, config.executionId, current2)), Effect76.flatMap(config.allocator.resetTo));
14852
- var permissionRequestedCursor = (config, pending, waitId) => `${config.executionId}:permission:${pending.toolCallId ?? waitId}:requested`;
15046
+ var permissionRequestedCursor = (config, pending, waitId2) => `${config.executionId}:permission:${pending.toolCallId ?? waitId2}:requested`;
14853
15047
  var permissionResolvedCursor = (config, pending, wait) => `${config.executionId}:permission:${pending.toolCallId ?? wait.id}:resolved`;
14854
- var permissionRequestedEvent = (config, pending, waitId, sequence) => ({
14855
- id: exports_ids_schema.EventId.make(`event:${pending.toolCallId ?? waitId}:permission-requested`),
15048
+ var permissionRequestedEvent = (config, pending, waitId2, sequence) => ({
15049
+ id: Identifiers.eventId(config.executionId, pending.toolCallId ?? waitId2, "permission-requested"),
14856
15050
  execution_id: config.executionId,
14857
15051
  type: "permission.ask.requested",
14858
15052
  sequence,
14859
- cursor: permissionRequestedCursor(config, pending, waitId),
15053
+ cursor: permissionRequestedCursor(config, pending, waitId2),
14860
15054
  data: {
14861
15055
  tool_call_id: pending.toolCallId ?? pending.token,
14862
15056
  tool_name: pending.tool,
14863
- wait_id: waitId,
15057
+ wait_id: waitId2,
14864
15058
  input: jsonValue3(pending.params),
14865
15059
  agent_name: pending.agentName,
14866
15060
  scope: config.scope
@@ -14887,7 +15081,7 @@ var answerForWait = (wait) => {
14887
15081
  return { _tag: "Denied", reason: "Permission denied" };
14888
15082
  };
14889
15083
  var permissionResolvedEvent = (config, pending, wait, answer, sequence) => ({
14890
- id: exports_ids_schema.EventId.make(`event:${pending.toolCallId ?? wait.id}:permission-resolved`),
15084
+ id: Identifiers.eventId(config.executionId, pending.toolCallId ?? wait.id, "permission-resolved"),
14891
15085
  execution_id: config.executionId,
14892
15086
  type: "permission.ask.resolved",
14893
15087
  sequence,
@@ -14907,19 +15101,19 @@ var appendPermissionEvent = (config, event) => appendIdempotentTo(config.eventLo
14907
15101
  onNone: () => Effect76.fail(permissionError(error5.message)),
14908
15102
  onSome: (prior) => samePermissionEvent(prior, event) ? Effect76.succeed(prior) : Effect76.fail(permissionError(error5.message))
14909
15103
  })))), Effect76.mapError((error5) => permissionError(error5.message)), Effect76.tap(() => resetAllocatorToLog(config)));
14910
- var ensurePermissionRequestedEvent = Effect76.fn("RelayPermissions.ensurePermissionRequestedEvent")(function* (config, pending, waitId) {
14911
- const cursor = permissionRequestedCursor(config, pending, waitId);
15104
+ var ensurePermissionRequestedEvent = Effect76.fn("RelayPermissions.ensurePermissionRequestedEvent")(function* (config, pending, waitId2) {
15105
+ const cursor = permissionRequestedCursor(config, pending, waitId2);
14912
15106
  const existing = yield* findEventByCursor(config, cursor);
14913
15107
  if (Option16.isSome(existing))
14914
15108
  return;
14915
15109
  const requestedSequence = yield* allocateEventSequence(config);
14916
- yield* appendPermissionEvent(config, permissionRequestedEvent(config, pending, waitId, requestedSequence));
15110
+ yield* appendPermissionEvent(config, permissionRequestedEvent(config, pending, waitId2, requestedSequence));
14917
15111
  });
14918
15112
  var createAsk = Effect76.fn("RelayPermissions.createAsk")(function* (config, pending) {
14919
- const waitId = exports_ids_schema.WaitId.make(pending.token);
15113
+ const waitId2 = exports_ids_schema.WaitId.make(pending.token);
14920
15114
  const waitSequence = yield* allocateEventSequence(config);
14921
15115
  yield* config.waits.createDetached({
14922
- waitId,
15116
+ waitId: waitId2,
14923
15117
  executionId: config.executionId,
14924
15118
  mode: "event",
14925
15119
  correlationKey: pending.toolCallId ?? pending.token,
@@ -14934,17 +15128,17 @@ var createAsk = Effect76.fn("RelayPermissions.createAsk")(function* (config, pen
14934
15128
  eventSequence: waitSequence,
14935
15129
  createdAt: createdAtForSequence(config, waitSequence)
14936
15130
  }).pipe(Effect76.mapError((error5) => permissionError(error5.message)));
14937
- yield* ensurePermissionRequestedEvent(config, pending, waitId);
15131
+ yield* ensurePermissionRequestedEvent(config, pending, waitId2);
14938
15132
  });
14939
15133
  var awaitAnswer = Effect76.fn("RelayPermissions.awaitAnswer")(function* (config, pending) {
14940
- const waitId = exports_ids_schema.WaitId.make(pending.token);
14941
- const existing = yield* config.waits.get(waitId).pipe(Effect76.mapError((error5) => permissionError(error5.message)));
15134
+ const waitId2 = exports_ids_schema.WaitId.make(pending.token);
15135
+ const existing = yield* config.waits.get(waitId2).pipe(Effect76.mapError((error5) => permissionError(error5.message)));
14942
15136
  if (existing === undefined) {
14943
15137
  yield* createAsk(config, pending);
14944
15138
  return Option16.none();
14945
15139
  }
14946
15140
  if (existing.state === "open") {
14947
- yield* ensurePermissionRequestedEvent(config, pending, waitId);
15141
+ yield* ensurePermissionRequestedEvent(config, pending, waitId2);
14948
15142
  return Option16.none();
14949
15143
  }
14950
15144
  const answer = answerForWait(existing);
@@ -15056,7 +15250,7 @@ var layer55 = (config) => Layer68.succeed(exports_steering.Steering, exports_ste
15056
15250
  }));
15057
15251
 
15058
15252
  // ../runtime/src/agent/relay-tool-executor.ts
15059
- import { Effect as Effect78, Layer as Layer69, Option as Option17, Schema as Schema71 } from "effect";
15253
+ import { Deferred as Deferred3, Effect as Effect78, Layer as Layer69, Option as Option17, Schema as Schema71 } from "effect";
15060
15254
  var jsonValue5 = (value) => Schema71.decodeUnknownSync(exports_shared_schema.JsonValue)(value);
15061
15255
  var errorDetail = (error5) => {
15062
15256
  switch (error5._tag) {
@@ -15084,47 +15278,103 @@ var boundResult = (config, result) => {
15084
15278
  return Effect78.succeed(result);
15085
15279
  return exports_tool_output.bound({ _tag: "Success", result: result.output, encodedResult: result.output }, { toolCallId: result.call_id, maxBytes: config.toolOutputMaxBytes }).pipe(Effect78.map((bounded) => ({ ...result, output: jsonValue5(bounded.encodedResult) })));
15086
15280
  };
15087
- var make8 = (config) => ({
15088
- execute: (request) => Effect78.gen(function* () {
15089
- const first = yield* config.allocator.current;
15090
- const call = {
15091
- id: exports_ids_schema.ToolCallId.make(request.call.id),
15092
- name: request.call.name,
15093
- input: jsonValue5(request.call.params)
15094
- };
15095
- const resumed = config.resumedToolCallId === call.id;
15096
- const existingRequest = resumed ? yield* hasRequestedEvent(config, call.id) : false;
15097
- const eventSequence = existingRequest ? first - 1 : first;
15098
- return yield* config.toolRuntime.run({
15099
- executionId: config.executionId,
15100
- call,
15101
- permissions: config.permissions,
15102
- eventSequence,
15103
- createdAt: config.startedAt + eventSequence - config.eventSequence,
15104
- ...config.extraTools === undefined ? {} : { extraTools: config.extraTools },
15105
- transformResult: (result) => boundResult(config, result)
15106
- }).pipe(Effect78.flatMap((result) => nextLoggedSequence2(config.eventLog, config.executionId, existingRequest ? first + 1 : first + 2).pipe(Effect78.flatMap(config.allocator.resetTo), Effect78.as(result.error === undefined ? { _tag: "Success", result: result.output, encodedResult: result.output } : {
15107
- _tag: "DomainFailure",
15108
- failure: result.error,
15109
- encodedFailure: result.error
15110
- }))), Effect78.catch((error5) => nextLoggedSequence2(config.eventLog, config.executionId, first).pipe(Effect78.flatMap(config.allocator.resetTo), Effect78.flatMap(() => {
15111
- if (error5._tag === "ToolExecutionWaitRequested") {
15112
- return Effect78.succeed({ _tag: "Suspend", token: error5.wait_id });
15113
- }
15114
- if (error5._tag === "ToolExecutionFailed") {
15115
- const failure2 = `${error5._tag}: ${errorDetail(error5)}`;
15116
- return Effect78.succeed({ _tag: "DomainFailure", failure: failure2, encodedFailure: failure2 });
15117
- }
15118
- const stage = error5._tag === "ToolPermissionDenied" ? "authorization" : error5._tag === "ToolInputInvalid" ? "decode-input" : error5._tag === "ToolNotRegistered" ? "missing-handler" : "handler";
15119
- return Effect78.fail(exports_tool_executor.FrameworkFailure.make({
15120
- stage,
15121
- tool: call.name,
15122
- message: `${error5._tag}: ${errorDetail(error5)}`
15123
- }));
15124
- }))));
15125
- })
15281
+ var batchKey = (request) => `${request.turn}:${request.toolCallBatch.calls.map((call) => call.id).join(":")}`;
15282
+ var gateKey = (turn, toolCallIndex) => `${turn}:${toolCallIndex}`;
15283
+ var gateFor = (gates, key4) => {
15284
+ const existing = gates.get(key4);
15285
+ if (existing !== undefined)
15286
+ return existing;
15287
+ const created = Deferred3.makeUnsafe();
15288
+ gates.set(key4, created);
15289
+ return created;
15290
+ };
15291
+ var callFrom = (call) => ({
15292
+ id: exports_ids_schema.ToolCallId.make(call.id),
15293
+ name: call.name,
15294
+ input: jsonValue5(call.params)
15295
+ });
15296
+ var frameworkFailure = (call, error5) => {
15297
+ const stage = error5._tag === "ToolPermissionDenied" ? "authorization" : error5._tag === "ToolInputInvalid" ? "decode-input" : error5._tag === "ToolNotRegistered" ? "missing-handler" : "handler";
15298
+ return exports_tool_executor.FrameworkFailure.make({
15299
+ stage,
15300
+ tool: call.name,
15301
+ message: `${error5._tag}: ${errorDetail(error5)}`
15302
+ });
15303
+ };
15304
+ var make8 = (config) => Effect78.sync(() => {
15305
+ const prepared = new Map;
15306
+ const settled = new Map;
15307
+ const awaitPrevious = (gates, request) => {
15308
+ if (request.toolCallIndex === 0 || config.resumedToolCallId === request.call.id)
15309
+ return Effect78.void;
15310
+ return Deferred3.await(gateFor(gates, gateKey(request.turn, request.toolCallIndex - 1)));
15311
+ };
15312
+ const completeSettlement = (request) => Deferred3.succeed(gateFor(settled, gateKey(request.turn, request.toolCallIndex)), undefined).pipe(Effect78.asVoid);
15313
+ return exports_tool_executor.ToolExecutor.of({
15314
+ execute: (request) => {
15315
+ const key4 = batchKey(request);
15316
+ const existingPreparation = prepared.get(key4);
15317
+ const preparation = existingPreparation ?? Deferred3.makeUnsafe();
15318
+ if (existingPreparation === undefined)
15319
+ prepared.set(key4, preparation);
15320
+ const prepareBatch = existingPreparation === undefined ? Effect78.gen(function* () {
15321
+ const first = yield* config.allocator.current;
15322
+ yield* Effect78.forEach(request.toolCallBatch.calls.entries(), ([toolCallIndex, batchCall]) => {
15323
+ const call = callFrom(batchCall);
15324
+ const eventSequence = first + toolCallIndex;
15325
+ return config.toolRuntime.prepare({
15326
+ executionId: config.executionId,
15327
+ call,
15328
+ permissions: config.permissions,
15329
+ eventSequence,
15330
+ createdAt: config.startedAt + eventSequence - config.eventSequence,
15331
+ ...config.extraTools === undefined ? {} : { extraTools: config.extraTools }
15332
+ }).pipe(Effect78.mapError((error5) => frameworkFailure(call, error5)));
15333
+ });
15334
+ const next = yield* nextLoggedSequence2(config.eventLog, config.executionId, first);
15335
+ yield* config.allocator.advanceTo(next);
15336
+ return next;
15337
+ }).pipe(Effect78.exit, Effect78.flatMap((exit) => Deferred3.done(preparation, exit)), Effect78.andThen(Deferred3.await(preparation)), Effect78.uninterruptible) : Deferred3.await(preparation);
15338
+ return Effect78.gen(function* () {
15339
+ yield* prepareBatch;
15340
+ let settlementSequence;
15341
+ const beginSettlement = Effect78.suspend(() => {
15342
+ if (settlementSequence !== undefined)
15343
+ return Effect78.succeed(settlementSequence);
15344
+ return awaitPrevious(settled, request).pipe(Effect78.andThen(config.allocator.current), Effect78.map((sequence) => sequence - 1), Effect78.tap((sequence) => Effect78.sync(() => settlementSequence = sequence)));
15345
+ });
15346
+ const first = yield* config.allocator.current;
15347
+ const call = callFrom(request.call);
15348
+ const existingRequest = yield* hasRequestedEvent(config, call.id);
15349
+ const eventSequence = existingRequest ? first - 1 : first;
15350
+ return yield* config.toolRuntime.run({
15351
+ executionId: config.executionId,
15352
+ call,
15353
+ permissions: config.permissions,
15354
+ eventSequence,
15355
+ createdAt: config.startedAt + eventSequence - config.eventSequence,
15356
+ ...config.extraTools === undefined ? {} : { extraTools: config.extraTools },
15357
+ beforeSettlement: beginSettlement,
15358
+ transformResult: (result) => boundResult(config, result)
15359
+ }).pipe(Effect78.flatMap((result) => nextLoggedSequence2(config.eventLog, config.executionId, existingRequest ? first + 1 : first + 2).pipe(Effect78.flatMap(config.allocator.advanceTo), Effect78.as(result.error === undefined ? { _tag: "Success", result: result.output, encodedResult: result.output } : {
15360
+ _tag: "DomainFailure",
15361
+ failure: result.error,
15362
+ encodedFailure: result.error
15363
+ }))), Effect78.catch((error5) => beginSettlement.pipe(Effect78.asVoid, Effect78.andThen(nextLoggedSequence2(config.eventLog, config.executionId, first)), Effect78.flatMap(config.allocator.advanceTo), Effect78.flatMap(() => {
15364
+ if (error5._tag === "ToolExecutionWaitRequested") {
15365
+ return Effect78.succeed({ _tag: "Suspend", token: error5.wait_id });
15366
+ }
15367
+ if (error5._tag === "ToolExecutionFailed") {
15368
+ const failure2 = `${error5._tag}: ${errorDetail(error5)}`;
15369
+ return Effect78.succeed({ _tag: "DomainFailure", failure: failure2, encodedFailure: failure2 });
15370
+ }
15371
+ return Effect78.fail(frameworkFailure(call, error5));
15372
+ }))), Effect78.tap((outcome) => outcome._tag === "Suspend" ? Effect78.void : completeSettlement(request)), Effect78.onInterrupt(() => completeSettlement(request)));
15373
+ });
15374
+ }
15375
+ });
15126
15376
  });
15127
- var layer56 = (config) => Layer69.succeed(exports_tool_executor.ToolExecutor, exports_tool_executor.ToolExecutor.of(make8(config)));
15377
+ var layer56 = (config) => Layer69.effect(exports_tool_executor.ToolExecutor, make8(config));
15128
15378
 
15129
15379
  // ../runtime/src/agent/relay-tool-output.ts
15130
15380
  import { Effect as Effect79, Function as Function14, Layer as Layer70, Option as Option18 } from "effect";
@@ -15175,6 +15425,7 @@ import { Effect as Effect80, Ref as Ref17 } from "effect";
15175
15425
  var make10 = (first) => Ref17.make(first).pipe(Effect80.map((ref) => ({
15176
15426
  allocate: (count) => Ref17.getAndUpdate(ref, (value) => value + count),
15177
15427
  current: Ref17.get(ref),
15428
+ advanceTo: (sequence) => Ref17.update(ref, (current2) => Math.max(current2, sequence)),
15178
15429
  resetTo: (sequence) => Ref17.set(ref, sequence)
15179
15430
  })));
15180
15431
 
@@ -15411,7 +15662,7 @@ var loopError = (error5, nextEventSequence5) => AgentLoopError.make({
15411
15662
  message: error5 instanceof Error ? `${error5.name}: ${error5.message}` : String(error5),
15412
15663
  next_event_sequence: nextEventSequence5
15413
15664
  });
15414
- var appendEvent = (eventLog, event, nextEventSequence5) => appendIdempotentTo(eventLog, event).pipe(Effect81.mapError((error5) => loopError(error5, nextEventSequence5)));
15665
+ var appendEvent = (eventLog, allocator, event, nextEventSequence5) => appendIdempotentTo(eventLog, event).pipe(Effect81.tap((appended) => allocator.advanceTo(appended.sequence + 1)), Effect81.mapError((error5) => loopError(error5, nextEventSequence5)));
15415
15666
  var compactionCommittedCursor = (executionId, checkpointId2) => `execution:${executionId}:agent-compaction:${checkpointId2}:committed`;
15416
15667
  var appendCompactionCommittedEvent = Effect81.fn("AgentLoop.appendCompactionCommittedEvent")(function* (eventLog, allocator, input, checkpoint) {
15417
15668
  if (input.sessionId === undefined)
@@ -15426,7 +15677,7 @@ var appendCompactionCommittedEvent = Effect81.fn("AgentLoop.appendCompactionComm
15426
15677
  session_id: input.sessionId,
15427
15678
  summary_present: checkpoint.summary !== undefined
15428
15679
  };
15429
- yield* appendEvent(eventLog, {
15680
+ yield* appendEvent(eventLog, allocator, {
15430
15681
  id: exports_ids_schema.EventId.make(`event:${input.executionId}:agent-compaction:${checkpoint.id}:committed`),
15431
15682
  execution_id: input.executionId,
15432
15683
  type: "agent.compaction.committed",
@@ -15712,7 +15963,10 @@ var make11 = (layerOptions) => Effect81.gen(function* () {
15712
15963
  const definitions2 = registered.map((tool3) => tool3.definition);
15713
15964
  yield* validateToolInputSchemaDigests(input, definitions2);
15714
15965
  const toolCallDecodeMaxRetries = yield* toolCallDecodeMaxRetriesConfig.pipe(Effect81.mapError((error5) => loopError(error5, input.eventSequence + 1)));
15715
- yield* appendEvent(eventLog, inputPreparedEvent(input, definitions2), input.eventSequence + 1);
15966
+ const durableMaxSequence = yield* eventLog.maxSequence(input.executionId).pipe(Effect81.mapError((error5) => loopError(error5, input.eventSequence + 1)));
15967
+ const nextEventSequence5 = Math.max(input.eventSequence + 1, (durableMaxSequence ?? -1) + 1);
15968
+ const allocator = yield* make10(nextEventSequence5);
15969
+ yield* appendEvent(eventLog, allocator, inputPreparedEvent(input, definitions2), input.eventSequence + 1);
15716
15970
  const toolOutputMaxBytes = yield* effectiveToolOutputMaxBytes(input);
15717
15971
  const compactionPolicy = input.agent.compaction_policy;
15718
15972
  const configuredCompactionOptions = compactionOptions(input.agent);
@@ -15736,9 +15990,6 @@ var make11 = (layerOptions) => Effect81.gen(function* () {
15736
15990
  input: jsonValue6(resumeSuspension.tool_params)
15737
15991
  };
15738
15992
  const storedHistory = resumeToolCall === undefined ? yield* loadStoredHistory(chats, input) : yield* restoreHistory(chats, input);
15739
- const durableMaxSequence = yield* eventLog.maxSequence(input.executionId).pipe(Effect81.mapError((error5) => loopError(error5, input.eventSequence + 1)));
15740
- const nextEventSequence5 = Math.max(input.eventSequence + 1, (durableMaxSequence ?? -1) + 1);
15741
- const allocator = yield* make10(nextEventSequence5);
15742
15993
  const onCheckpointCommitted = (result) => appendCompactionCommittedEvent(eventLog, allocator, input, result.checkpoint).pipe(Effect81.andThen(layerOptions?.onCheckpointCommitted?.(result) ?? Effect81.void));
15743
15994
  const durableHistory = Option19.isNone(sessionRepository) ? storedHistory : yield* reconcileCompactionCheckpoint(sessionRepository.value, chats, input, storedHistory, onCheckpointCommitted, resumeSuspension === undefined);
15744
15995
  const continuingDurableHistory = durableHistory !== undefined;
@@ -15798,7 +16049,8 @@ var make11 = (layerOptions) => Effect81.gen(function* () {
15798
16049
  const agent = exports_agent.make({
15799
16050
  name: input.agent.name,
15800
16051
  toolkit,
15801
- policy: turnPolicyFromDefinition(input.agent)
16052
+ policy: turnPolicyFromDefinition(input.agent),
16053
+ ...input.agent.tool_execution === undefined ? {} : { toolExecution: input.agent.tool_execution }
15802
16054
  });
15803
16055
  if (toolOutputMaxBytes !== undefined && Option19.isNone(blobStore)) {
15804
16056
  return yield* AgentLoopError.make({
@@ -15860,7 +16112,7 @@ var make11 = (layerOptions) => Effect81.gen(function* () {
15860
16112
  const tokenBudget = input.agent.token_budget;
15861
16113
  const enforceBudget = (state) => tokenBudget === undefined || state.tokensUsed < tokenBudget ? Effect81.void : Effect81.gen(function* () {
15862
16114
  const budgetSequence = yield* allocator.allocate(1);
15863
- yield* appendEvent(eventLog, budgetExceededEvent(input, state.tokensUsed, tokenBudget, budgetSequence), budgetSequence + 1);
16115
+ yield* appendEvent(eventLog, allocator, budgetExceededEvent(input, state.tokensUsed, tokenBudget, budgetSequence), budgetSequence + 1);
15864
16116
  return yield* AgentLoopBudgetExceeded.make({
15865
16117
  tokens_used: state.tokensUsed,
15866
16118
  token_budget: tokenBudget,
@@ -15874,13 +16126,13 @@ var make11 = (layerOptions) => Effect81.gen(function* () {
15874
16126
  if (part.type === "text-delta") {
15875
16127
  const sequence = yield* allocator.allocate(1);
15876
16128
  const deltaIndex = sequence - input.eventSequence - 1;
15877
- yield* appendEvent(eventLog, outputDeltaEvent(input, part, deltaIndex), sequence + 1);
16129
+ yield* appendEvent(eventLog, allocator, outputDeltaEvent(input, part, deltaIndex), sequence + 1);
15878
16130
  return { ...state, text: `${state.text}${part.delta}` };
15879
16131
  }
15880
16132
  if (part.type === "reasoning" || part.type === "reasoning-delta") {
15881
16133
  const sequence = yield* allocator.allocate(1);
15882
16134
  const deltaIndex = sequence - input.eventSequence - 1;
15883
- yield* appendEvent(eventLog, reasoningDeltaEvent(input, part, deltaIndex), sequence + 1);
16135
+ yield* appendEvent(eventLog, allocator, reasoningDeltaEvent(input, part, deltaIndex), sequence + 1);
15884
16136
  return state;
15885
16137
  }
15886
16138
  if (part.type === "tool-params-start") {
@@ -15889,7 +16141,7 @@ var make11 = (layerOptions) => Effect81.gen(function* () {
15889
16141
  if (part.type === "tool-params-delta") {
15890
16142
  const sequence = yield* allocator.allocate(1);
15891
16143
  const deltaIndex = state.toolCallDeltaIndexes[part.id] ?? 0;
15892
- yield* appendEvent(eventLog, toolCallDeltaEvent(input, part, state.toolCallNames[part.id], sequence, deltaIndex), sequence + 1);
16144
+ yield* appendEvent(eventLog, allocator, toolCallDeltaEvent(input, part, state.toolCallNames[part.id], sequence, deltaIndex), sequence + 1);
15893
16145
  return {
15894
16146
  ...state,
15895
16147
  toolCallDeltaIndexes: { ...state.toolCallDeltaIndexes, [part.id]: deltaIndex + 1 }
@@ -15898,7 +16150,7 @@ var make11 = (layerOptions) => Effect81.gen(function* () {
15898
16150
  if (part.type === "finish") {
15899
16151
  const finish = part;
15900
16152
  const sequence = yield* allocator.allocate(1);
15901
- yield* appendEvent(eventLog, usageReportedEvent(input, finish, sequence), sequence + 1);
16153
+ yield* appendEvent(eventLog, allocator, usageReportedEvent(input, finish, sequence), sequence + 1);
15902
16154
  yield* recordModelUsage({
15903
16155
  provider: input.agent.model.provider,
15904
16156
  model: input.agent.model.model,
@@ -15966,7 +16218,7 @@ var make11 = (layerOptions) => Effect81.gen(function* () {
15966
16218
  const schemaRef = input.agent.output_schema_ref;
15967
16219
  const structuredOutput = schemaRef === undefined || finalState.transcript === undefined ? undefined : yield* Chat.fromPrompt(finalState.transcript).pipe(Effect81.flatMap((chat) => runStructuredTurn(languageModels, schemas, chat, input, schemaRef, completedSequence + 1)));
15968
16220
  const structuredPart = structuredOutput === undefined || schemaRef === undefined ? [] : [{ type: "structured", value: structuredOutput, schema_ref: schemaRef }];
15969
- yield* appendEvent(eventLog, outputCompletedEvent(input, [...completedContent(finalState.text), ...structuredPart], finalState.text, completedSequence, structuredOutput), completedSequence + 1);
16221
+ yield* appendEvent(eventLog, allocator, outputCompletedEvent(input, [...completedContent(finalState.text), ...structuredPart], finalState.text, completedSequence, structuredOutput), completedSequence + 1);
15970
16222
  return {
15971
16223
  metadata: {
15972
16224
  model_output: finalState.text,
@@ -16344,16 +16596,16 @@ var make12 = Effect86.gen(function* () {
16344
16596
  }).pipe(Effect86.mapError(toSchedulerError));
16345
16597
  }).pipe(Effect86.withSpan("SchedulerService.dispatchStartExecution"));
16346
16598
  const dispatchWaitTransition = (schedule, now) => Effect86.gen(function* () {
16347
- const waitId = schedule.wait_id;
16348
- if (waitId === undefined) {
16599
+ const waitId2 = schedule.wait_id;
16600
+ if (waitId2 === undefined) {
16349
16601
  return yield* SchedulerError.make({ message: `Schedule ${schedule.id} is missing wait_id` });
16350
16602
  }
16351
- const wait = yield* waits.get(waitId).pipe(Effect86.mapError(toSchedulerError));
16603
+ const wait = yield* waits.get(waitId2).pipe(Effect86.mapError(toSchedulerError));
16352
16604
  if (wait === undefined || wait.state !== "open")
16353
16605
  return;
16354
16606
  const eventSequence = yield* nextEventSequence5(eventLog, wait.executionId);
16355
16607
  const metadata11 = dispatchMetadata(schedule);
16356
- const result = schedule.target_kind === "wake-wait" ? yield* waits.wake({ waitId, resolvedAt: now, eventSequence, metadata: metadata11 }).pipe(Effect86.mapError(toSchedulerError)) : yield* waits.timeout({ waitId, timedOutAt: now, eventSequence, metadata: metadata11 }).pipe(Effect86.mapError(toSchedulerError));
16608
+ const result = schedule.target_kind === "wake-wait" ? yield* waits.wake({ waitId: waitId2, resolvedAt: now, eventSequence, metadata: metadata11 }).pipe(Effect86.mapError(toSchedulerError)) : yield* waits.timeout({ waitId: waitId2, timedOutAt: now, eventSequence, metadata: metadata11 }).pipe(Effect86.mapError(toSchedulerError));
16357
16609
  if (!result.transitioned)
16358
16610
  return;
16359
16611
  yield* signalWorkflowWait({
@@ -17530,6 +17782,7 @@ var registerAgentPayload = Effect90.fn("Client.registerAgentPayload")(function*
17530
17782
  ...input.permission_rules === undefined ? {} : { permission_rules: input.permission_rules },
17531
17783
  ...input.compaction_policy === undefined ? {} : { compaction_policy: input.compaction_policy },
17532
17784
  ...turnPolicy,
17785
+ ...input.agent.toolExecution === undefined ? {} : { tool_execution: input.agent.toolExecution },
17533
17786
  ...input.max_wait_turns === undefined ? {} : { max_wait_turns: input.max_wait_turns },
17534
17787
  ...input.token_budget === undefined ? {} : { token_budget: input.token_budget },
17535
17788
  ...input.child_run_presets === undefined ? {} : { child_run_presets: input.child_run_presets },
@@ -17590,13 +17843,13 @@ var toToolWorkLease = (lease) => ({
17590
17843
  claim_expires_at: lease.claimExpiresAt,
17591
17844
  idempotency_key: lease.idempotencyKey
17592
17845
  });
17593
- var toolWaitId = (callId) => exports_ids_schema.WaitId.make(`wait:tool:${callId}`);
17846
+ var toolWaitId = (executionId, callId) => Identifiers.waitId("tool", executionId, callId);
17594
17847
  var acceptedWaitOutcome = (wait) => Schema83.decodeUnknownEffect(exports_tool_schema.ExternalOutcome)(wait.metadata.external_outcome).pipe(Effect90.mapError(toClientError));
17595
17848
  var resolveToolOutcomeWait = Effect90.fn("Client.resolveToolOutcomeWait")(function* (waits, eventLog, call, outcome, completedAt) {
17596
- const waitId = call.waitId ?? toolWaitId(call.call.id);
17597
- const wait = yield* waits.get(waitId).pipe(Effect90.mapError(toClientError));
17849
+ const waitId2 = call.waitId ?? toolWaitId(call.executionId, call.call.id);
17850
+ const wait = yield* waits.get(waitId2).pipe(Effect90.mapError(toClientError));
17598
17851
  if (wait === undefined)
17599
- return yield* ClientError.make({ message: `Tool wait not found: ${waitId}` });
17852
+ return yield* ClientError.make({ message: `Tool wait not found: ${waitId2}` });
17600
17853
  if (wait.executionId !== call.executionId) {
17601
17854
  return yield* ClientError.make({ message: `Tool wait does not match call: ${call.call.id}` });
17602
17855
  }
@@ -17612,7 +17865,7 @@ var resolveToolOutcomeWait = Effect90.fn("Client.resolveToolOutcomeWait")(functi
17612
17865
  }
17613
17866
  const eventSequence = yield* nextEventSequence6(eventLog, call.executionId);
17614
17867
  const resolved = yield* waits.wake({
17615
- waitId,
17868
+ waitId: waitId2,
17616
17869
  resolvedAt: completedAt,
17617
17870
  eventSequence,
17618
17871
  metadata: { kind: "tool-placement", external_outcome: outcome }
@@ -17757,10 +18010,10 @@ var childSpawnFingerprint = (record2) => {
17757
18010
  return typeof fingerprint === "string" ? fingerprint : undefined;
17758
18011
  };
17759
18012
  var createChildJoinWait = Effect90.fn("Client.createChildJoinWait")(function* (waits, eventLog, input, accepted2, createdAt) {
17760
- const waitId = childJoinWaitId(accepted2.child_execution_id);
18013
+ const waitId2 = childJoinWaitId(accepted2.child_execution_id);
17761
18014
  const eventSequence = yield* nextEventSequence6(eventLog, input.execution_id);
17762
18015
  yield* waits.createDetached({
17763
- waitId,
18016
+ waitId: waitId2,
17764
18017
  executionId: input.execution_id,
17765
18018
  mode: "child",
17766
18019
  correlationKey: accepted2.child_execution_id,
@@ -17771,7 +18024,7 @@ var createChildJoinWait = Effect90.fn("Client.createChildJoinWait")(function* (w
17771
18024
  eventSequence,
17772
18025
  createdAt
17773
18026
  }).pipe(Effect90.mapError(toClientError));
17774
- return waitId;
18027
+ return waitId2;
17775
18028
  });
17776
18029
  var reconcileExistingChildSpawn = Effect90.fn("Client.reconcileExistingChildSpawn")(function* (childExecutions, waits, eventLog, input) {
17777
18030
  const childExecutionId3 = childExecutionIdForSpawn(input);
@@ -17904,6 +18157,16 @@ var layerFromRuntime3 = Layer80.effect(Service, Effect90.gen(function* () {
17904
18157
  const executionId = exports_ids_schema.ExecutionId.make(input.correlation_key ?? `execution:send:${identity2}`);
17905
18158
  const envelopeId = exports_ids_schema.EnvelopeId.make(`${executionId}:envelope:${identity2}`);
17906
18159
  const createdAt = yield* Clock19.currentTimeMillis;
18160
+ const execution = yield* executionRepository.get(executionId).pipe(Effect90.mapError(toClientError));
18161
+ if (execution === undefined) {
18162
+ yield* executionRepository.create({
18163
+ id: executionId,
18164
+ rootAddressId: input.from,
18165
+ status: "queued",
18166
+ metadata: { operation: "envelope-send" },
18167
+ createdAt
18168
+ }).pipe(Effect90.catchIf(Schema83.is(exports_execution_repository.DuplicateExecution), () => Effect90.void), Effect90.mapError(toClientError));
18169
+ }
17907
18170
  const maxSequence3 = yield* eventLog.maxSequence(executionId).pipe(Effect90.mapError(toClientError));
17908
18171
  return yield* envelopes.send({
17909
18172
  envelopeId,