@positronic/cloudflare 0.0.74 → 0.0.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/src/api/brains.js +51 -78
  2. package/dist/src/api/secrets.js +1 -1
  3. package/dist/src/brain-runner-do.js +148 -45
  4. package/dist/src/dev-server.js +1 -1
  5. package/dist/src/event-loader.js +31 -0
  6. package/dist/src/governor-client-wrapper.js +6 -3
  7. package/dist/src/governor-do.js +1 -0
  8. package/dist/src/schedule-do.js +53 -13
  9. package/dist/src/token-estimator.js +105 -1
  10. package/dist/types/api/auth-middleware.d.ts.map +1 -1
  11. package/dist/types/api/brains.d.ts.map +1 -1
  12. package/dist/types/api/bundle.d.ts.map +1 -1
  13. package/dist/types/api/index.d.ts +1 -1
  14. package/dist/types/api/index.d.ts.map +1 -1
  15. package/dist/types/api/pages.d.ts.map +1 -1
  16. package/dist/types/api/secrets.d.ts.map +1 -1
  17. package/dist/types/api/store.d.ts.map +1 -1
  18. package/dist/types/api/types.d.ts +1 -0
  19. package/dist/types/api/types.d.ts.map +1 -1
  20. package/dist/types/api/webhooks/coordination.d.ts.map +1 -1
  21. package/dist/types/api/webhooks/index.d.ts.map +1 -1
  22. package/dist/types/api/webhooks/system.d.ts.map +1 -1
  23. package/dist/types/auth-do.d.ts.map +1 -1
  24. package/dist/types/brain-resolver.d.ts.map +1 -1
  25. package/dist/types/brain-runner-do.d.ts +6 -0
  26. package/dist/types/brain-runner-do.d.ts.map +1 -1
  27. package/dist/types/create-r2-store.d.ts.map +1 -1
  28. package/dist/types/dev-server.d.ts.map +1 -1
  29. package/dist/types/event-loader.d.ts +7 -0
  30. package/dist/types/event-loader.d.ts.map +1 -1
  31. package/dist/types/governor-client-wrapper.d.ts.map +1 -1
  32. package/dist/types/governor-do.d.ts.map +1 -1
  33. package/dist/types/manifest.d.ts.map +1 -1
  34. package/dist/types/monitor-do.d.ts.map +1 -1
  35. package/dist/types/node-index.d.ts +2 -2
  36. package/dist/types/node-index.d.ts.map +1 -1
  37. package/dist/types/pages-service.d.ts.map +1 -1
  38. package/dist/types/schedule-do.d.ts +3 -1
  39. package/dist/types/schedule-do.d.ts.map +1 -1
  40. package/dist/types/signal-provider.d.ts.map +1 -1
  41. package/dist/types/token-estimator.d.ts +21 -4
  42. package/dist/types/token-estimator.d.ts.map +1 -1
  43. package/dist/types/webhook-adapter.d.ts.map +1 -1
  44. package/package.json +6 -5
@@ -158,6 +158,7 @@ import { v4 as uuidv4 } from 'uuid';
158
158
  import { Cron } from 'croner';
159
159
  import Fuse from 'fuse.js';
160
160
  import { isSignalValid, brainMachineDefinition } from '@positronic/core';
161
+ import { zodToJsonSchema } from 'zod-to-json-schema';
161
162
  import { getManifest } from '../brain-runner-do.js';
162
163
  var brains = new Hono();
163
164
  /**
@@ -171,7 +172,7 @@ var brains = new Hono();
171
172
  }
172
173
  brains.post('/runs', function(context) {
173
174
  return _async_to_generator(function() {
174
- var requestBody, options, identifier, manifest, resolution, brain, brainRunId, namespace, doId, stub, auth, currentUser, initialData, brainTitle, response;
175
+ var requestBody, options, initialState, identifier, manifest, resolution, brain, brainRunId, namespace, doId, stub, auth, currentUser, initialData, brainTitle, response;
175
176
  return _ts_generator(this, function(_state) {
176
177
  switch(_state.label){
177
178
  case 0:
@@ -181,7 +182,7 @@ brains.post('/runs', function(context) {
181
182
  ];
182
183
  case 1:
183
184
  requestBody = _state.sent();
184
- options = requestBody.options;
185
+ options = requestBody.options, initialState = requestBody.initialState;
185
186
  // Support both identifier and brainTitle for backward compatibility
186
187
  identifier = requestBody.identifier || requestBody.brainTitle;
187
188
  if (!identifier) {
@@ -240,10 +241,12 @@ brains.post('/runs', function(context) {
240
241
  currentUser = {
241
242
  name: auth.userName || 'root'
242
243
  };
243
- // Pass options to the brain runner if provided
244
- initialData = options ? {
244
+ // Pass options and initialState to the brain runner if provided
245
+ initialData = options || initialState ? _object_spread({}, options && {
245
246
  options: options
246
- } : undefined;
247
+ }, initialState && {
248
+ initialState: initialState
249
+ }) : undefined;
247
250
  // Get the actual brain title from the resolved brain
248
251
  brainTitle = brain.title || identifier;
249
252
  return [
@@ -265,7 +268,7 @@ brains.post('/runs', function(context) {
265
268
  });
266
269
  brains.post('/runs/rerun', function(context) {
267
270
  return _async_to_generator(function() {
268
- var requestBody, runId, startsAt, stopsAfter, identifier, manifest, resolution, brain, monitorId, monitorStub, existingRun, auth, currentUser, newBrainRunId, namespace, doId, stub, rerunOptions, brainTitle, response;
271
+ var requestBody, runId, startsAt, userName, monitorId, monitorStub, existingRun, namespace, doId, stub, error;
269
272
  return _ts_generator(this, function(_state) {
270
273
  switch(_state.label){
271
274
  case 0:
@@ -275,57 +278,30 @@ brains.post('/runs/rerun', function(context) {
275
278
  ];
276
279
  case 1:
277
280
  requestBody = _state.sent();
278
- runId = requestBody.runId, startsAt = requestBody.startsAt, stopsAfter = requestBody.stopsAfter;
279
- // Support both identifier and brainTitle for backward compatibility
280
- identifier = requestBody.identifier || requestBody.brainTitle;
281
- if (!identifier) {
281
+ runId = requestBody.runId, startsAt = requestBody.startsAt;
282
+ if (!runId) {
282
283
  return [
283
284
  2,
284
285
  context.json({
285
- error: 'Missing identifier or brainTitle in request body'
286
+ error: 'Missing runId in request body'
286
287
  }, 400)
287
288
  ];
288
289
  }
289
- // Validate that the brain exists
290
- manifest = getManifest();
291
- if (!manifest) {
292
- return [
293
- 2,
294
- context.json({
295
- error: 'Manifest not initialized'
296
- }, 500)
297
- ];
298
- }
299
- // Resolve the identifier to find the brain
300
- resolution = manifest.resolve(identifier);
301
- if (resolution.matchType === 'none') {
302
- return [
303
- 2,
304
- context.json({
305
- error: "Brain '".concat(identifier, "' not found")
306
- }, 404)
307
- ];
308
- }
309
- if (resolution.matchType === 'multiple') {
290
+ if (startsAt === undefined || typeof startsAt !== 'number' || startsAt < 1) {
310
291
  return [
311
292
  2,
312
293
  context.json({
313
- error: 'Multiple brains match the identifier',
314
- matchType: 'multiple',
315
- candidates: resolution.candidates
316
- }, 409)
294
+ error: 'Missing or invalid startsAt in request body (must be >= 1)'
295
+ }, 400)
317
296
  ];
318
297
  }
319
- brain = resolution.brain;
320
- if (!runId) return [
321
- 3,
322
- 3
323
- ];
298
+ // Validate the run exists and the user owns it
299
+ userName = scopeUserName(context);
324
300
  monitorId = context.env.MONITOR_DO.idFromName('singleton');
325
301
  monitorStub = context.env.MONITOR_DO.get(monitorId);
326
302
  return [
327
303
  4,
328
- monitorStub.getLastEvent(runId)
304
+ monitorStub.getRun(runId, userName)
329
305
  ];
330
306
  case 2:
331
307
  existingRun = _state.sent();
@@ -337,48 +313,43 @@ brains.post('/runs/rerun', function(context) {
337
313
  }, 404)
338
314
  ];
339
315
  }
340
- _state.label = 3;
341
- case 3:
342
- // Read auth context for currentUser (every brain run must have an owner)
343
- auth = context.get('auth');
344
- if (!(auth === null || auth === void 0 ? void 0 : auth.userName) && !(auth === null || auth === void 0 ? void 0 : auth.isRoot)) {
345
- return [
346
- 2,
347
- context.json({
348
- error: 'Authentication required to run a brain'
349
- }, 401)
350
- ];
351
- }
352
- currentUser = {
353
- name: auth.userName || 'root'
354
- };
355
- // Create a new brain run with rerun parameters
356
- newBrainRunId = uuidv4();
316
+ // Get the existing DO and call rerun
357
317
  namespace = context.env.BRAIN_RUNNER_DO;
358
- doId = namespace.idFromName(newBrainRunId);
318
+ doId = namespace.idFromName(runId);
359
319
  stub = namespace.get(doId);
360
- // Start the brain with rerun options
361
- rerunOptions = _object_spread({}, runId && {
362
- originalRunId: runId
363
- }, startsAt !== undefined && {
364
- startsAt: startsAt
365
- }, stopsAfter !== undefined && {
366
- stopsAfter: stopsAfter
367
- });
368
- // Get the actual brain title from the resolved brain
369
- brainTitle = brain.title || identifier;
320
+ _state.label = 3;
321
+ case 3:
322
+ _state.trys.push([
323
+ 3,
324
+ 5,
325
+ ,
326
+ 6
327
+ ]);
370
328
  return [
371
329
  4,
372
- stub.start(brainTitle, newBrainRunId, currentUser, rerunOptions)
330
+ stub.rerun(startsAt)
373
331
  ];
374
332
  case 4:
375
333
  _state.sent();
376
- response = {
377
- brainRunId: newBrainRunId
378
- };
334
+ return [
335
+ 3,
336
+ 6
337
+ ];
338
+ case 5:
339
+ error = _state.sent();
379
340
  return [
380
341
  2,
381
- context.json(response, 201)
342
+ context.json({
343
+ error: error.message || 'Rerun failed'
344
+ }, 500)
345
+ ];
346
+ case 6:
347
+ return [
348
+ 2,
349
+ context.json({
350
+ brainRunId: runId,
351
+ brainTitle: existingRun.brainTitle
352
+ }, 200)
382
353
  ];
383
354
  }
384
355
  });
@@ -1081,7 +1052,7 @@ brains.post('/schedules', function(context) {
1081
1052
  }
1082
1053
  return [
1083
1054
  4,
1084
- scheduleStub.createSchedule(brainTitle, cronExpression, timezone, runAsUserName)
1055
+ scheduleStub.createSchedule(brainTitle, cronExpression, timezone, runAsUserName, body.options, body.initialState)
1085
1056
  ];
1086
1057
  case 4:
1087
1058
  schedule = _state.sent();
@@ -1307,11 +1278,13 @@ brains.get('/:identifier', function(context) {
1307
1278
  structure = brain.structure;
1308
1279
  return [
1309
1280
  2,
1310
- context.json({
1281
+ context.json(_object_spread({
1311
1282
  title: structure.title,
1312
1283
  description: structure.description || "".concat(structure.title, " brain"),
1313
1284
  steps: structure.steps
1314
- })
1285
+ }, brain.optionsSchema && {
1286
+ options: zodToJsonSchema(brain.optionsSchema)
1287
+ }))
1315
1288
  ];
1316
1289
  });
1317
1290
  })();
@@ -206,7 +206,7 @@ import { requireRoot } from './auth-middleware.js';
206
206
  2,
207
207
  fetch(url, _object_spread_props(_object_spread({}, options), {
208
208
  headers: _object_spread({
209
- 'Authorization': "Bearer ".concat(config.apiToken),
209
+ Authorization: "Bearer ".concat(config.apiToken),
210
210
  'Content-Type': 'application/json'
211
211
  }, options.headers)
212
212
  }))
@@ -443,21 +443,21 @@ var ScheduleAdapter = /*#__PURE__*/ function() {
443
443
  return ScheduleAdapter;
444
444
  }();
445
445
  /**
446
- * Adapter that intercepts BATCH_CHUNK_COMPLETE events and triggers a
447
- * DO alarm-based restart to reclaim memory between chunks.
448
- * After each chunk, it queues a PAUSE signal and sets an immediate alarm.
446
+ * Adapter that intercepts ITERATE_ITEM_COMPLETE events and triggers a
447
+ * DO alarm-based restart to reclaim memory between items.
448
+ * After each item, it queues a PAUSE signal and sets an immediate alarm.
449
449
  * The alarm fires, calls wakeUp(), which replays events, reconstructs
450
- * batch progress, and resumes from the next chunk.
451
- */ var BatchChunkAdapter = /*#__PURE__*/ function() {
450
+ * iterate progress, and resumes from the next item.
451
+ */ var IterateItemAdapter = /*#__PURE__*/ function() {
452
452
  "use strict";
453
- function BatchChunkAdapter(doQueueSignal, doSetAlarm) {
454
- _class_call_check(this, BatchChunkAdapter);
453
+ function IterateItemAdapter(doQueueSignal, doSetAlarm) {
454
+ _class_call_check(this, IterateItemAdapter);
455
455
  _define_property(this, "doQueueSignal", void 0);
456
456
  _define_property(this, "doSetAlarm", void 0);
457
457
  this.doQueueSignal = doQueueSignal;
458
458
  this.doSetAlarm = doSetAlarm;
459
459
  }
460
- _create_class(BatchChunkAdapter, [
460
+ _create_class(IterateItemAdapter, [
461
461
  {
462
462
  key: "dispatch",
463
463
  value: function dispatch(event) {
@@ -466,13 +466,13 @@ var ScheduleAdapter = /*#__PURE__*/ function() {
466
466
  return _ts_generator(this, function(_state) {
467
467
  switch(_state.label){
468
468
  case 0:
469
- if (!(event.type === BRAIN_EVENTS.BATCH_CHUNK_COMPLETE)) return [
469
+ if (!(event.type === BRAIN_EVENTS.ITERATE_ITEM_COMPLETE)) return [
470
470
  3,
471
471
  3
472
472
  ];
473
- // Only pause and restart between chunks, not after the last chunk.
474
- // After the last chunk the brain continues to subsequent steps naturally.
475
- // A spurious alarm after the last chunk would call wakeUp() while the
473
+ // Only pause and restart between items, not after the last item.
474
+ // After the last item the brain continues to subsequent steps naturally.
475
+ // A spurious alarm after the last item would call wakeUp() while the
476
476
  // brain is still running, corrupting execution state.
477
477
  processedCount = event.processedCount, totalItems = event.totalItems;
478
478
  if (!(processedCount < totalItems)) return [
@@ -504,7 +504,7 @@ var ScheduleAdapter = /*#__PURE__*/ function() {
504
504
  }
505
505
  }
506
506
  ]);
507
- return BatchChunkAdapter;
507
+ return IterateItemAdapter;
508
508
  }();
509
509
  // SQL to initialize the run owner table (stores who started this brain run)
510
510
  var runOwnerTableSQL = "\nCREATE TABLE IF NOT EXISTS run_owner (\n user_name TEXT NOT NULL\n);\n";
@@ -1024,6 +1024,122 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1024
1024
  }).call(this);
1025
1025
  }
1026
1026
  },
1027
+ {
1028
+ key: "rerun",
1029
+ value: /**
1030
+ * Destructive rerun: truncate event history to just before step N,
1031
+ * then resume from there using the existing wakeUp() machinery.
1032
+ * startsAt is 1-indexed: --starts-at 3 keeps steps 1-2, re-executes from step 3.
1033
+ */ function rerun(startsAt) {
1034
+ return _async_to_generator(function() {
1035
+ var _this, eventLoader, eventsWithIds, startEntry, initialState, machine, stepsToKeep, topLevelStepCount, cutoffEventId, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step_value, eventId, event, r2Rows;
1036
+ return _ts_generator(this, function(_state) {
1037
+ switch(_state.label){
1038
+ case 0:
1039
+ _this = this;
1040
+ if (this.abortController) {
1041
+ throw new Error('Cannot rerun while brain is actively running');
1042
+ }
1043
+ eventLoader = new EventLoader(this.sql, this.env.RESOURCES_BUCKET);
1044
+ return [
1045
+ 4,
1046
+ eventLoader.loadAllEventsWithIds()
1047
+ ];
1048
+ case 1:
1049
+ eventsWithIds = _state.sent();
1050
+ if (eventsWithIds.length === 0) {
1051
+ throw new Error('No events found for this brain run');
1052
+ }
1053
+ // Find the START event to get initialState
1054
+ startEntry = eventsWithIds.find(function(e) {
1055
+ return e.event.type === BRAIN_EVENTS.START;
1056
+ });
1057
+ if (!startEntry) {
1058
+ throw new Error('No START event found');
1059
+ }
1060
+ initialState = startEntry.event.initialState || {};
1061
+ // Replay events through a state machine and count top-level STEP_COMPLETE events
1062
+ machine = createBrainExecutionMachine({
1063
+ initialState: initialState
1064
+ });
1065
+ stepsToKeep = startsAt - 1;
1066
+ topLevelStepCount = 0;
1067
+ cutoffEventId = startEntry.eventId; // Default: keep only START
1068
+ _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1069
+ try {
1070
+ for(_iterator = eventsWithIds[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1071
+ _step_value = _step.value, eventId = _step_value.eventId, event = _step_value.event;
1072
+ sendEvent(machine, event);
1073
+ if (event.type === BRAIN_EVENTS.STEP_COMPLETE && machine.context.isTopLevel) {
1074
+ topLevelStepCount++;
1075
+ if (topLevelStepCount === stepsToKeep) {
1076
+ cutoffEventId = eventId;
1077
+ break;
1078
+ }
1079
+ }
1080
+ }
1081
+ } catch (err) {
1082
+ _didIteratorError = true;
1083
+ _iteratorError = err;
1084
+ } finally{
1085
+ try {
1086
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1087
+ _iterator.return();
1088
+ }
1089
+ } finally{
1090
+ if (_didIteratorError) {
1091
+ throw _iteratorError;
1092
+ }
1093
+ }
1094
+ }
1095
+ // If startsAt is 1, cutoff stays at the START event's ID
1096
+ // Find R2 keys that need to be deleted (overflow events beyond the cutoff)
1097
+ r2Rows = this.sql.exec("SELECT r2_key FROM brain_events WHERE event_id > ? AND r2_key IS NOT NULL", cutoffEventId).toArray();
1098
+ if (!(r2Rows.length > 0)) return [
1099
+ 3,
1100
+ 3
1101
+ ];
1102
+ return [
1103
+ 4,
1104
+ Promise.all(r2Rows.map(function(row) {
1105
+ return _this.env.RESOURCES_BUCKET.delete(row.r2_key);
1106
+ }))
1107
+ ];
1108
+ case 2:
1109
+ _state.sent();
1110
+ _state.label = 3;
1111
+ case 3:
1112
+ // Truncate events beyond cutoff
1113
+ this.sql.exec("DELETE FROM brain_events WHERE event_id > ?", cutoffEventId);
1114
+ // Clear signals and wait timeouts
1115
+ // Use DROP + recreate pattern since tables may not exist if the brain
1116
+ // never used signals/wait (e.g. basic-brain with no wait steps)
1117
+ this.sql.exec("DROP TABLE IF EXISTS brain_signals");
1118
+ this.sql.exec("DROP TABLE IF EXISTS wait_timeout");
1119
+ this.signalsTableInitialized = false;
1120
+ this.waitTimeoutTableInitialized = false;
1121
+ // Cancel any pending alarm
1122
+ return [
1123
+ 4,
1124
+ this.ctx.storage.deleteAlarm()
1125
+ ];
1126
+ case 4:
1127
+ _state.sent();
1128
+ // Resume from the truncation point
1129
+ return [
1130
+ 4,
1131
+ this.wakeUp(this.brainRunId)
1132
+ ];
1133
+ case 5:
1134
+ _state.sent();
1135
+ return [
1136
+ 2
1137
+ ];
1138
+ }
1139
+ });
1140
+ }).call(this);
1141
+ }
1142
+ },
1027
1143
  {
1028
1144
  key: "alarm",
1029
1145
  value: function alarm() {
@@ -1066,7 +1182,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1066
1182
  key: "start",
1067
1183
  value: function start(brainTitle, brainRunId, currentUser, initialData) {
1068
1184
  return _async_to_generator(function() {
1069
- var _this, sql, resolution, brainToRun, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, env, pagesService, r2Resources, runnerWithResources, signalProvider, options, initialState, batchChunkAdapter, timeoutAdapter;
1185
+ var _this, sql, resolution, brainToRun, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, env, pagesService, r2Resources, runnerWithResources, signalProvider, options, _initialData_initialState, initialState, iterateItemAdapter, timeoutAdapter;
1070
1186
  return _ts_generator(this, function(_state) {
1071
1187
  switch(_state.label){
1072
1188
  case 0:
@@ -1130,14 +1246,14 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1130
1246
  runnerWithResources = runnerWithResources.withSignalProvider(signalProvider).withGovernor(function(c) {
1131
1247
  return rateGoverned(c);
1132
1248
  }).withStoreProvider(createR2Backend(this.env.RESOURCES_BUCKET));
1133
- // Extract options from initialData if present
1249
+ // Extract options and initialState from initialData if present
1134
1250
  options = initialData === null || initialData === void 0 ? void 0 : initialData.options;
1135
- initialState = initialData && !initialData.options ? initialData : {};
1251
+ initialState = (_initialData_initialState = initialData === null || initialData === void 0 ? void 0 : initialData.initialState) !== null && _initialData_initialState !== void 0 ? _initialData_initialState : initialData && !initialData.options && !initialData.initialState ? initialData : {};
1136
1252
  // Persist run owner durably (immutable, not derived from events)
1137
1253
  this.storeRunOwner(currentUser.name);
1138
1254
  // Create abort controller for this run
1139
1255
  this.abortController = new AbortController();
1140
- batchChunkAdapter = new BatchChunkAdapter(function(signal) {
1256
+ iterateItemAdapter = new IterateItemAdapter(function(signal) {
1141
1257
  return _this.queueSignal(signal);
1142
1258
  }, function(time) {
1143
1259
  return _this.ctx.storage.setAlarm(time);
@@ -1154,7 +1270,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1154
1270
  scheduleAdapter,
1155
1271
  webhookAdapter,
1156
1272
  this.pageAdapter,
1157
- batchChunkAdapter,
1273
+ iterateItemAdapter,
1158
1274
  timeoutAdapter
1159
1275
  ]).run(brainToRun, _object_spread_props(_object_spread({
1160
1276
  currentUser: currentUser,
@@ -1187,7 +1303,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1187
1303
  * This method reconstructs state and calls BrainRunner.resume().
1188
1304
  */ function wakeUp(brainRunId) {
1189
1305
  return _async_to_generator(function() {
1190
- var _this, sql, pendingTimeout, eventLoader, startEvent, brainTitle, initialState, ownerId, currentUser, originalBrainRunId, resolution, brainToRun, allEvents, machine, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, event, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, env, pagesService, r2Resources, runnerWithResources, signalProvider, batchChunkAdapter, timeoutAdapter;
1306
+ var _this, sql, pendingTimeout, eventLoader, startEvent, brainTitle, initialState, options, ownerId, currentUser, originalBrainRunId, resolution, brainToRun, allEvents, machine, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, event, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, env, pagesService, r2Resources, runnerWithResources, signalProvider, iterateItemAdapter, timeoutAdapter;
1191
1307
  return _ts_generator(this, function(_state) {
1192
1308
  switch(_state.label){
1193
1309
  case 0:
@@ -1195,7 +1311,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1195
1311
  sql = this.sql;
1196
1312
  // Clear any pending timeout and cancel the alarm to prevent spurious alarm
1197
1313
  // fires after explicit resume. Safe because wakeUp() is only called when a
1198
- // brain is suspended (waiting/paused), never during active batch execution.
1314
+ // brain is suspended (waiting/paused), never during active iterate execution.
1199
1315
  pendingTimeout = this.getWaitTimeout();
1200
1316
  if (!pendingTimeout) return [
1201
1317
  3,
@@ -1226,6 +1342,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1226
1342
  }
1227
1343
  brainTitle = startEvent.brainTitle;
1228
1344
  initialState = startEvent.initialState || {};
1345
+ options = startEvent.options || {};
1229
1346
  // Read run owner from durable storage (set once in start(), not from events)
1230
1347
  ownerId = this.getRunOwner();
1231
1348
  if (!ownerId) {
@@ -1327,7 +1444,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1327
1444
  }).withStoreProvider(createR2Backend(this.env.RESOURCES_BUCKET));
1328
1445
  // Create abort controller for this run
1329
1446
  this.abortController = new AbortController();
1330
- batchChunkAdapter = new BatchChunkAdapter(function(signal) {
1447
+ iterateItemAdapter = new IterateItemAdapter(function(signal) {
1331
1448
  return _this.queueSignal(signal);
1332
1449
  }, function(time) {
1333
1450
  return _this.ctx.storage.setAlarm(time);
@@ -1344,12 +1461,13 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1344
1461
  scheduleAdapter,
1345
1462
  webhookAdapter,
1346
1463
  this.pageAdapter,
1347
- batchChunkAdapter,
1464
+ iterateItemAdapter,
1348
1465
  timeoutAdapter
1349
1466
  ]).resume(brainToRun, {
1350
1467
  currentUser: currentUser,
1351
1468
  machine: machine,
1352
1469
  brainRunId: originalBrainRunId,
1470
+ options: options,
1353
1471
  signal: this.abortController.signal
1354
1472
  }).catch(function(err) {
1355
1473
  console.error("[DO ".concat(originalBrainRunId, "] BrainRunner wakeUp failed:"), err);
@@ -1385,7 +1503,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1385
1503
  stream = new ReadableStream({
1386
1504
  start: function(controller) {
1387
1505
  return _async_to_generator(function() {
1388
- var existingEvents, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, event, err1;
1506
+ var existingEvents, err;
1389
1507
  return _ts_generator(this, function(_state) {
1390
1508
  switch(_state.label){
1391
1509
  case 0:
@@ -1404,25 +1522,10 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1404
1522
  ];
1405
1523
  case 2:
1406
1524
  existingEvents = _state.sent();
1407
- _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1408
- try {
1409
- for(_iterator = existingEvents[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1410
- event = _step.value;
1411
- sendEvent(controller, event);
1412
- }
1413
- } catch (err) {
1414
- _didIteratorError = true;
1415
- _iteratorError = err;
1416
- } finally{
1417
- try {
1418
- if (!_iteratorNormalCompletion && _iterator.return != null) {
1419
- _iterator.return();
1420
- }
1421
- } finally{
1422
- if (_didIteratorError) {
1423
- throw _iteratorError;
1424
- }
1425
- }
1525
+ // Send all historical events as a single array message
1526
+ // so clients can process them in one batch instead of re-rendering per event
1527
+ if (existingEvents.length > 0) {
1528
+ sendEvent(controller, existingEvents);
1426
1529
  }
1427
1530
  eventStreamAdapter.subscribe(controller);
1428
1531
  return [
@@ -1430,13 +1533,13 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1430
1533
  4
1431
1534
  ];
1432
1535
  case 3:
1433
- err1 = _state.sent();
1434
- console.error("[DO ".concat(brainRunId, " WATCH] Error during stream start:"), err1);
1536
+ err = _state.sent();
1537
+ console.error("[DO ".concat(brainRunId, " WATCH] Error during stream start:"), err);
1435
1538
  controller.close();
1436
1539
  if (streamController) {
1437
1540
  eventStreamAdapter.unsubscribe(streamController);
1438
1541
  }
1439
- throw err1;
1542
+ throw err;
1440
1543
  case 4:
1441
1544
  return [
1442
1545
  2
@@ -1934,7 +1934,7 @@ export var CloudflareDevServer = /*#__PURE__*/ function() {
1934
1934
  fetch(url, {
1935
1935
  method: 'PUT',
1936
1936
  headers: {
1937
- 'Authorization': "Bearer ".concat(apiToken),
1937
+ Authorization: "Bearer ".concat(apiToken),
1938
1938
  'Content-Type': 'application/json'
1939
1939
  },
1940
1940
  body: JSON.stringify({
@@ -180,6 +180,37 @@ function _ts_generator(thisArg, body) {
180
180
  }).call(this);
181
181
  }
182
182
  },
183
+ {
184
+ key: "loadAllEventsWithIds",
185
+ value: /**
186
+ * Load all events with their SQL row IDs, for truncation operations.
187
+ */ function loadAllEventsWithIds() {
188
+ return _async_to_generator(function() {
189
+ var rows, events;
190
+ return _ts_generator(this, function(_state) {
191
+ switch(_state.label){
192
+ case 0:
193
+ rows = this.sql.exec("SELECT event_id, event_type, serialized_event, r2_key\n FROM brain_events\n ORDER BY event_id ASC").toArray();
194
+ return [
195
+ 4,
196
+ this.hydrateEvents(rows)
197
+ ];
198
+ case 1:
199
+ events = _state.sent();
200
+ return [
201
+ 2,
202
+ rows.map(function(row, i) {
203
+ return {
204
+ eventId: row.event_id,
205
+ event: events[i]
206
+ };
207
+ })
208
+ ];
209
+ }
210
+ });
211
+ }).call(this);
212
+ }
213
+ },
183
214
  {
184
215
  key: "loadEventByType",
185
216
  value: /**
@@ -263,7 +263,8 @@ export function rateGoverned(client) {
263
263
  estimated = estimateRequestTokens({
264
264
  prompt: params.prompt,
265
265
  messages: params.messages,
266
- system: params.system
266
+ system: params.system,
267
+ schema: params.schema
267
268
  });
268
269
  return [
269
270
  2,
@@ -302,7 +303,8 @@ export function rateGoverned(client) {
302
303
  estimated = estimateRequestTokens({
303
304
  prompt: params.prompt,
304
305
  messages: params.messages,
305
- system: params.system
306
+ system: params.system,
307
+ tools: params.tools
306
308
  });
307
309
  return [
308
310
  2,
@@ -339,7 +341,8 @@ export function rateGoverned(client) {
339
341
  governorStub = getGovernorStub(identity);
340
342
  estimated = estimateRequestTokens({
341
343
  messages: params.messages,
342
- system: params.system
344
+ system: params.system,
345
+ tools: params.tools
343
346
  });
344
347
  return [
345
348
  2,
@@ -258,6 +258,7 @@ export var GovernorDO = /*#__PURE__*/ function(DurableObject) {
258
258
  }
259
259
  }
260
260
  if (!this.limitsLoaded) {
261
+ console.warn("Governor: no rate limits known for model '".concat(modelId, "', requests will not be throttled"));
261
262
  return [
262
263
  2
263
264
  ];