@positronic/cloudflare 0.0.77 → 0.0.78

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 (41) hide show
  1. package/dist/src/api/brains.js +90 -195
  2. package/dist/src/api/files.js +178 -0
  3. package/dist/src/api/index.js +9 -0
  4. package/dist/src/api/webhooks/coordination.js +0 -2
  5. package/dist/src/api/webhooks/index.js +43 -36
  6. package/dist/src/api/webhooks/system.js +23 -21
  7. package/dist/src/brain-runner-do.js +110 -170
  8. package/dist/src/content-type.js +6 -0
  9. package/dist/src/dev-server.js +128 -18
  10. package/dist/src/file-utils.js +7 -0
  11. package/dist/src/files-service.js +465 -0
  12. package/dist/src/manifest.js +13 -8
  13. package/dist/src/monitor-do.js +17 -0
  14. package/dist/src/schedule-do.js +5 -19
  15. package/dist/src/zip-builder.js +507 -0
  16. package/dist/types/api/brains.d.ts.map +1 -1
  17. package/dist/types/api/files.d.ts +7 -0
  18. package/dist/types/api/files.d.ts.map +1 -0
  19. package/dist/types/api/index.d.ts.map +1 -1
  20. package/dist/types/api/webhooks/coordination.d.ts +0 -1
  21. package/dist/types/api/webhooks/coordination.d.ts.map +1 -1
  22. package/dist/types/api/webhooks/index.d.ts.map +1 -1
  23. package/dist/types/api/webhooks/system.d.ts.map +1 -1
  24. package/dist/types/brain-runner-do.d.ts +13 -7
  25. package/dist/types/brain-runner-do.d.ts.map +1 -1
  26. package/dist/types/content-type.d.ts +2 -0
  27. package/dist/types/content-type.d.ts.map +1 -0
  28. package/dist/types/dev-server.d.ts +1 -0
  29. package/dist/types/dev-server.d.ts.map +1 -1
  30. package/dist/types/file-utils.d.ts +3 -0
  31. package/dist/types/file-utils.d.ts.map +1 -0
  32. package/dist/types/files-service.d.ts +4 -0
  33. package/dist/types/files-service.d.ts.map +1 -0
  34. package/dist/types/manifest.d.ts.map +1 -1
  35. package/dist/types/monitor-do.d.ts +6 -0
  36. package/dist/types/monitor-do.d.ts.map +1 -1
  37. package/dist/types/schedule-do.d.ts +0 -1
  38. package/dist/types/schedule-do.d.ts.map +1 -1
  39. package/dist/types/zip-builder.d.ts +4 -0
  40. package/dist/types/zip-builder.d.ts.map +1 -0
  41. package/package.json +5 -4
@@ -289,7 +289,7 @@ function _ts_generator(thisArg, body) {
289
289
  };
290
290
  }
291
291
  }
292
- import { STATUS, BRAIN_EVENTS, createBrainExecutionMachine, sendEvent } from '@positronic/core';
292
+ import { BrainRunner, STATUS, BRAIN_EVENTS, createBrainExecutionMachine, sendEvent } from '@positronic/core';
293
293
  import { DurableObject } from 'cloudflare:workers';
294
294
  import { CloudflareSignalProvider } from './signal-provider.js';
295
295
  import { BrainRunSQLiteAdapter } from './sqlite-adapter.js';
@@ -298,11 +298,13 @@ import { TimeoutAdapter } from './timeout-adapter.js';
298
298
  import { PageAdapter } from './page-adapter.js';
299
299
  import { EventLoader } from './event-loader.js';
300
300
  import { createPagesService } from './pages-service.js';
301
+ import { createFilesService } from './files-service.js';
301
302
  import { setGovernorBinding, rateGoverned } from './governor-client-wrapper.js';
302
303
  import { CloudflareR2Loader } from './r2-loader.js';
303
304
  import { createR2Backend } from './create-r2-store.js';
304
305
  import { createResources } from '@positronic/core';
305
306
  import { getOrigin } from './origin.js';
307
+ import { v4 as uuidv4 } from 'uuid';
306
308
  var manifest = null;
307
309
  export function setManifest(generatedManifest) {
308
310
  manifest = generatedManifest;
@@ -310,6 +312,32 @@ export function setManifest(generatedManifest) {
310
312
  export function getManifest() {
311
313
  return manifest;
312
314
  }
315
+ /**
316
+ * Start a new brain run on a fresh BrainRunnerDO.
317
+ * Shared by the API endpoint, ScheduleDO, and webhook triggers.
318
+ */ export function startBrainRun(namespace, brainTitle, currentUser, initialData) {
319
+ return _async_to_generator(function() {
320
+ var brainRunId, doId, stub;
321
+ return _ts_generator(this, function(_state) {
322
+ switch(_state.label){
323
+ case 0:
324
+ brainRunId = uuidv4();
325
+ doId = namespace.idFromName(brainRunId);
326
+ stub = namespace.get(doId);
327
+ return [
328
+ 4,
329
+ stub.start(brainTitle, brainRunId, currentUser, initialData)
330
+ ];
331
+ case 1:
332
+ _state.sent();
333
+ return [
334
+ 2,
335
+ brainRunId
336
+ ];
337
+ }
338
+ });
339
+ })();
340
+ }
313
341
  var brainRunner = null;
314
342
  export function setBrainRunner(runner) {
315
343
  brainRunner = runner;
@@ -521,73 +549,44 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
521
549
  _this = _call_super(this, BrainRunnerDO, [
522
550
  state,
523
551
  env
524
- ]), _define_property(_this, "sql", void 0), _define_property(_this, "brainRunId", void 0), _define_property(_this, "eventStreamAdapter", new EventStreamAdapter()), _define_property(_this, "abortController", null), _define_property(_this, "pageAdapter", null), _define_property(_this, "runOwnerTableInitialized", false), _define_property(_this, "signalsTableInitialized", false), _define_property(_this, "waitTimeoutTableInitialized", false);
552
+ ]), _define_property(_this, "sql", void 0), _define_property(_this, "brainRunId", void 0), _define_property(_this, "eventStreamAdapter", new EventStreamAdapter()), _define_property(_this, "abortController", null), _define_property(_this, "pageAdapter", null);
525
553
  _this.sql = state.storage.sql;
526
554
  _this.brainRunId = state.id.toString();
527
555
  _this.env = env;
556
+ _this.sql.exec(runOwnerTableSQL);
557
+ _this.sql.exec(signalsTableSQL);
558
+ _this.sql.exec(waitTimeoutTableSQL);
528
559
  return _this;
529
560
  }
530
561
  _create_class(BrainRunnerDO, [
531
- {
532
- key: "initializeRunOwnerTable",
533
- value: function initializeRunOwnerTable() {
534
- if (!this.runOwnerTableInitialized) {
535
- this.sql.exec(runOwnerTableSQL);
536
- this.runOwnerTableInitialized = true;
537
- }
538
- }
539
- },
540
562
  {
541
563
  key: "storeRunOwner",
542
564
  value: function storeRunOwner(userName) {
543
- this.initializeRunOwnerTable();
544
565
  this.sql.exec("INSERT INTO run_owner (user_name) VALUES (?)", userName);
545
566
  }
546
567
  },
547
568
  {
548
569
  key: "getRunOwner",
549
570
  value: function getRunOwner() {
550
- this.initializeRunOwnerTable();
551
571
  var results = this.sql.exec("SELECT user_name FROM run_owner LIMIT 1").toArray();
552
572
  return results.length > 0 ? results[0].user_name : null;
553
573
  }
554
574
  },
555
- {
556
- key: "initializeSignalsTable",
557
- value: function initializeSignalsTable() {
558
- if (!this.signalsTableInitialized) {
559
- this.sql.exec(signalsTableSQL);
560
- this.signalsTableInitialized = true;
561
- }
562
- }
563
- },
564
- {
565
- key: "initializeWaitTimeoutTable",
566
- value: function initializeWaitTimeoutTable() {
567
- if (!this.waitTimeoutTableInitialized) {
568
- this.sql.exec(waitTimeoutTableSQL);
569
- this.waitTimeoutTableInitialized = true;
570
- }
571
- }
572
- },
573
575
  {
574
576
  key: "storeWaitTimeout",
575
577
  value: function storeWaitTimeout(brainRunId, timeoutAt) {
576
- this.initializeWaitTimeoutTable();
577
578
  this.sql.exec("INSERT OR REPLACE INTO wait_timeout (brain_run_id, timeout_at) VALUES (?, ?)", brainRunId, timeoutAt);
578
579
  }
579
580
  },
580
581
  {
581
582
  key: "clearWaitTimeout",
582
583
  value: function clearWaitTimeout(brainRunId) {
583
- this.initializeWaitTimeoutTable();
584
584
  this.sql.exec("DELETE FROM wait_timeout WHERE brain_run_id = ?", brainRunId);
585
585
  }
586
586
  },
587
587
  {
588
588
  key: "getWaitTimeout",
589
589
  value: function getWaitTimeout() {
590
- this.initializeWaitTimeoutTable();
591
590
  var results = this.sql.exec("SELECT brain_run_id, timeout_at FROM wait_timeout LIMIT 1").toArray();
592
591
  if (results.length === 0) return null;
593
592
  return {
@@ -606,7 +605,6 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
606
605
  return _async_to_generator(function() {
607
606
  var _signal_content, content, queuedAt;
608
607
  return _ts_generator(this, function(_state) {
609
- this.initializeSignalsTable();
610
608
  // For WEBHOOK_RESPONSE, store the response as JSON in the content field
611
609
  content = signal.type === 'WEBHOOK_RESPONSE' && signal.response ? JSON.stringify(signal.response) : (_signal_content = signal.content) !== null && _signal_content !== void 0 ? _signal_content : null;
612
610
  queuedAt = Date.now();
@@ -625,11 +623,10 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
625
623
  {
626
624
  /**
627
625
  * Get and consume (delete) pending signals.
628
- * Signals are returned in priority order: KILL > PAUSE > WEBHOOK_RESPONSE > RESUME > USER_MESSAGE
626
+ * Signals are returned in priority order: KILL > PAUSE > WEBHOOK_RESPONSE > RESUME
629
627
  * @param filter 'CONTROL' returns only KILL/PAUSE, 'WEBHOOK' returns only WEBHOOK_RESPONSE, 'ALL' includes all signal types
630
628
  */ key: "getAndConsumeSignals",
631
629
  value: function getAndConsumeSignals(filter) {
632
- this.initializeSignalsTable();
633
630
  // Query signals ordered by priority
634
631
  var whereClause = '';
635
632
  if (filter === 'CONTROL') {
@@ -637,7 +634,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
637
634
  } else if (filter === 'WEBHOOK') {
638
635
  whereClause = "WHERE signal_type = 'WEBHOOK_RESPONSE'";
639
636
  }
640
- var results = this.sql.exec("SELECT id, signal_type, content FROM brain_signals ".concat(whereClause, "\n ORDER BY CASE signal_type\n WHEN 'KILL' THEN 1\n WHEN 'PAUSE' THEN 2\n WHEN 'WEBHOOK_RESPONSE' THEN 3\n WHEN 'RESUME' THEN 4\n WHEN 'USER_MESSAGE' THEN 5\n END")).toArray();
637
+ var results = this.sql.exec("SELECT id, signal_type, content FROM brain_signals ".concat(whereClause, "\n ORDER BY CASE signal_type\n WHEN 'KILL' THEN 1\n WHEN 'PAUSE' THEN 2\n WHEN 'WEBHOOK_RESPONSE' THEN 3\n WHEN 'RESUME' THEN 4\n END")).toArray();
641
638
  if (results.length === 0) {
642
639
  return [];
643
640
  }
@@ -648,18 +645,11 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
648
645
  this.sql.exec("DELETE FROM brain_signals WHERE id IN (".concat(ids.join(','), ")"));
649
646
  // Convert to BrainSignal format
650
647
  return results.map(function(r) {
651
- if (r.signal_type === 'USER_MESSAGE') {
652
- var _r_content;
653
- return {
654
- type: 'USER_MESSAGE',
655
- content: (_r_content = r.content) !== null && _r_content !== void 0 ? _r_content : ''
656
- };
657
- }
658
648
  if (r.signal_type === 'WEBHOOK_RESPONSE') {
659
- var _r_content1;
649
+ var _r_content;
660
650
  return {
661
651
  type: 'WEBHOOK_RESPONSE',
662
- response: JSON.parse((_r_content1 = r.content) !== null && _r_content1 !== void 0 ? _r_content1 : '{}')
652
+ response: JSON.parse((_r_content = r.content) !== null && _r_content !== void 0 ? _r_content : '{}')
663
653
  };
664
654
  }
665
655
  if (r.signal_type === 'RESUME') {
@@ -1112,12 +1102,8 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1112
1102
  // Truncate events beyond cutoff
1113
1103
  this.sql.exec("DELETE FROM brain_events WHERE event_id > ?", cutoffEventId);
1114
1104
  // 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;
1105
+ this.sql.exec("DELETE FROM brain_signals");
1106
+ this.sql.exec("DELETE FROM wait_timeout");
1121
1107
  // Cancel any pending alarm
1122
1108
  return [
1123
1109
  4,
@@ -1179,23 +1165,23 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1179
1165
  }
1180
1166
  },
1181
1167
  {
1182
- key: "start",
1183
- value: function start(brainTitle, brainRunId, currentUser, initialData) {
1168
+ key: "prepareRunner",
1169
+ value: /**
1170
+ * Resolve a brain from the manifest, create all adapters and the configured
1171
+ * BrainRunner. Shared setup for both start() and wakeUp().
1172
+ */ function prepareRunner(brainTitle, brainRunId, currentUser) {
1184
1173
  return _async_to_generator(function() {
1185
- var _this, sql, resolution, brainToRun, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, env, pagesService, r2Resources, runnerWithResources, signalProvider, options, _initialData_initialState, initialState, iterateItemAdapter, timeoutAdapter;
1174
+ var _this, resolution, brainToRun, sqliteAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, env, pagesService, filesService, r2Resources, signalProvider, bucket, storeBackend, iterateItemAdapter, timeoutAdapter, runner;
1186
1175
  return _ts_generator(this, function(_state) {
1187
1176
  switch(_state.label){
1188
1177
  case 0:
1189
1178
  _this = this;
1190
- sql = this.sql;
1191
1179
  if (!manifest) {
1192
1180
  throw new Error('Runtime manifest not initialized');
1193
1181
  }
1194
- // Resolve the brain using the title/identifier
1195
1182
  resolution = manifest.resolve(brainTitle);
1196
1183
  if (resolution.matchType === 'none') {
1197
1184
  console.error("[DO ".concat(brainRunId, "] Brain ").concat(brainTitle, " not found in manifest."));
1198
- console.error(JSON.stringify(manifest, null, 2));
1199
1185
  throw new Error("Brain ".concat(brainTitle, " not found"));
1200
1186
  }
1201
1187
  if (resolution.matchType === 'multiple') {
@@ -1206,8 +1192,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1206
1192
  if (!brainToRun) {
1207
1193
  throw new Error("Brain ".concat(brainTitle, " resolved but brain object is missing"));
1208
1194
  }
1209
- sqliteAdapter = new BrainRunSQLiteAdapter(sql, this.env.RESOURCES_BUCKET, brainRunId);
1210
- eventStreamAdapter = this.eventStreamAdapter;
1195
+ sqliteAdapter = new BrainRunSQLiteAdapter(this.sql, this.env.RESOURCES_BUCKET, brainRunId);
1211
1196
  monitorDOStub = this.env.MONITOR_DO.get(this.env.MONITOR_DO.idFromName('singleton'));
1212
1197
  monitorAdapter = new MonitorAdapter(monitorDOStub);
1213
1198
  scheduleAdapter = new ScheduleAdapter(this.env.SCHEDULE_DO.get(this.env.SCHEDULE_DO.idFromName('singleton')));
@@ -1219,8 +1204,8 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1219
1204
  ];
1220
1205
  case 1:
1221
1206
  env = _state.sent();
1222
- // Create pages service for brain to use
1223
1207
  pagesService = createPagesService(brainRunId, this.env.RESOURCES_BUCKET, monitorDOStub, env);
1208
+ filesService = createFilesService(this.env.RESOURCES_BUCKET, brainTitle, brainRunId, currentUser, env);
1224
1209
  setGovernorBinding(this.env.GOVERNOR_DO);
1225
1210
  if (!brainRunner) {
1226
1211
  throw new Error('BrainRunner not initialized');
@@ -1231,27 +1216,11 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1231
1216
  ];
1232
1217
  case 2:
1233
1218
  r2Resources = _state.sent();
1234
- // Create an enhanced runner with resources if available
1235
- runnerWithResources = brainRunner;
1236
- // Use R2 resources if available
1237
- if (r2Resources) {
1238
- runnerWithResources = brainRunner.withResources(r2Resources);
1239
- }
1240
- // Add pages service and runtime env
1241
- runnerWithResources = runnerWithResources.withPages(pagesService).withEnv(env);
1242
- // Add signal provider for signal handling
1243
1219
  signalProvider = new CloudflareSignalProvider(function(filter) {
1244
1220
  return _this.getAndConsumeSignals(filter);
1245
1221
  });
1246
- runnerWithResources = runnerWithResources.withSignalProvider(signalProvider).withGovernor(function(c) {
1247
- return rateGoverned(c);
1248
- }).withStoreProvider(createR2Backend(this.env.RESOURCES_BUCKET));
1249
- // Extract options and initialState from initialData if present
1250
- options = initialData === null || initialData === void 0 ? void 0 : initialData.options;
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 : {};
1252
- // Persist run owner durably (immutable, not derived from events)
1253
- this.storeRunOwner(currentUser.name);
1254
- // Create abort controller for this run
1222
+ bucket = this.env.RESOURCES_BUCKET;
1223
+ storeBackend = createR2Backend(bucket);
1255
1224
  this.abortController = new AbortController();
1256
1225
  iterateItemAdapter = new IterateItemAdapter(function(signal) {
1257
1226
  return _this.queueSignal(signal);
@@ -1263,16 +1232,61 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1263
1232
  }, function(time) {
1264
1233
  return _this.ctx.storage.setAlarm(time);
1265
1234
  });
1266
- runnerWithResources.withAdapters([
1267
- sqliteAdapter,
1268
- eventStreamAdapter,
1269
- monitorAdapter,
1270
- scheduleAdapter,
1271
- webhookAdapter,
1272
- this.pageAdapter,
1273
- iterateItemAdapter,
1274
- timeoutAdapter
1275
- ]).run(brainToRun, _object_spread_props(_object_spread({
1235
+ runner = new BrainRunner({
1236
+ client: brainRunner.client,
1237
+ adapters: [
1238
+ sqliteAdapter,
1239
+ this.eventStreamAdapter,
1240
+ monitorAdapter,
1241
+ scheduleAdapter,
1242
+ webhookAdapter,
1243
+ this.pageAdapter,
1244
+ iterateItemAdapter,
1245
+ timeoutAdapter
1246
+ ],
1247
+ env: env,
1248
+ resources: r2Resources !== null && r2Resources !== void 0 ? r2Resources : {},
1249
+ signalProvider: signalProvider,
1250
+ governor: function(c) {
1251
+ return rateGoverned(c);
1252
+ },
1253
+ files: filesService,
1254
+ pages: pagesService,
1255
+ storeProvider: storeBackend
1256
+ });
1257
+ return [
1258
+ 2,
1259
+ {
1260
+ brainToRun: brainToRun,
1261
+ runner: runner
1262
+ }
1263
+ ];
1264
+ }
1265
+ });
1266
+ }).call(this);
1267
+ }
1268
+ },
1269
+ {
1270
+ key: "start",
1271
+ value: function start(brainTitle, brainRunId, currentUser, initialData) {
1272
+ return _async_to_generator(function() {
1273
+ var _this, options, _initialData_initialState, initialState, _ref, brainToRun, runner;
1274
+ return _ts_generator(this, function(_state) {
1275
+ switch(_state.label){
1276
+ case 0:
1277
+ _this = this;
1278
+ // Extract options and initialState from initialData if present
1279
+ options = initialData === null || initialData === void 0 ? void 0 : initialData.options;
1280
+ 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 : {};
1281
+ // Persist run owner durably (immutable, not derived from events)
1282
+ this.storeRunOwner(currentUser.name);
1283
+ return [
1284
+ 4,
1285
+ this.prepareRunner(brainTitle, brainRunId, currentUser)
1286
+ ];
1287
+ case 1:
1288
+ _ref = _state.sent(), brainToRun = _ref.brainToRun, runner = _ref.runner;
1289
+ runner.run(brainToRun, _object_spread_props(_object_spread({
1276
1290
  currentUser: currentUser,
1277
1291
  initialState: initialState,
1278
1292
  brainRunId: brainRunId
@@ -1282,9 +1296,8 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1282
1296
  signal: this.abortController.signal
1283
1297
  })).catch(function(err) {
1284
1298
  console.error("[DO ".concat(brainRunId, "] BrainRunner run failed:"), err);
1285
- throw err; // Re-throw to ensure proper error propagation
1299
+ throw err;
1286
1300
  }).finally(function() {
1287
- // Clean up abort controller when run completes
1288
1301
  _this.abortController = null;
1289
1302
  });
1290
1303
  return [
@@ -1303,12 +1316,11 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1303
1316
  * This method reconstructs state and calls BrainRunner.resume().
1304
1317
  */ function wakeUp(brainRunId) {
1305
1318
  return _async_to_generator(function() {
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;
1319
+ var _this, pendingTimeout, eventLoader, startEvent, brainTitle, initialState, options, ownerId, currentUser, originalBrainRunId, allEvents, machine, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, event, _ref, brainToRun, runner;
1307
1320
  return _ts_generator(this, function(_state) {
1308
1321
  switch(_state.label){
1309
1322
  case 0:
1310
1323
  _this = this;
1311
- sql = this.sql;
1312
1324
  // Clear any pending timeout and cancel the alarm to prevent spurious alarm
1313
1325
  // fires after explicit resume. Safe because wakeUp() is only called when a
1314
1326
  // brain is suspended (waiting/paused), never during active iterate execution.
@@ -1326,11 +1338,8 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1326
1338
  _state.sent();
1327
1339
  _state.label = 2;
1328
1340
  case 2:
1329
- if (!manifest) {
1330
- throw new Error('Runtime manifest not initialized');
1331
- }
1332
1341
  // Use EventLoader to load events (handles R2 overflow transparently)
1333
- eventLoader = new EventLoader(sql, this.env.RESOURCES_BUCKET);
1342
+ eventLoader = new EventLoader(this.sql, this.env.RESOURCES_BUCKET);
1334
1343
  return [
1335
1344
  4,
1336
1345
  eventLoader.loadEventByType(BRAIN_EVENTS.START, 'ASC')
@@ -1359,27 +1368,12 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1359
1368
  if (!brainTitle) {
1360
1369
  throw new Error("Brain title not found in START event for brain run ".concat(brainRunId));
1361
1370
  }
1362
- // Resolve the brain using the title
1363
- resolution = manifest.resolve(brainTitle);
1364
- if (resolution.matchType === 'none') {
1365
- console.error("[DO ".concat(brainRunId, "] Brain ").concat(brainTitle, " not found in manifest."));
1366
- throw new Error("Brain ".concat(brainTitle, " not found"));
1367
- }
1368
- if (resolution.matchType === 'multiple') {
1369
- console.error("[DO ".concat(brainRunId, "] Multiple brains match identifier ").concat(brainTitle), resolution.candidates);
1370
- throw new Error("Multiple brains match identifier ".concat(brainTitle));
1371
- }
1372
- brainToRun = resolution.brain;
1373
- if (!brainToRun) {
1374
- throw new Error("Brain ".concat(brainTitle, " resolved but brain object is missing"));
1375
- }
1376
1371
  return [
1377
1372
  4,
1378
1373
  eventLoader.loadAllEvents()
1379
1374
  ];
1380
1375
  case 4:
1381
1376
  allEvents = _state.sent();
1382
- // Create state machine and feed all historical events to reconstruct execution state
1383
1377
  machine = createBrainExecutionMachine({
1384
1378
  initialState: initialState
1385
1379
  });
@@ -1403,67 +1397,13 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1403
1397
  }
1404
1398
  }
1405
1399
  }
1406
- sqliteAdapter = new BrainRunSQLiteAdapter(sql, this.env.RESOURCES_BUCKET, brainRunId);
1407
- eventStreamAdapter = this.eventStreamAdapter;
1408
- monitorDOStub = this.env.MONITOR_DO.get(this.env.MONITOR_DO.idFromName('singleton'));
1409
- monitorAdapter = new MonitorAdapter(monitorDOStub);
1410
- scheduleAdapter = new ScheduleAdapter(this.env.SCHEDULE_DO.get(this.env.SCHEDULE_DO.idFromName('singleton')));
1411
- webhookAdapter = new WebhookAdapter(monitorDOStub);
1412
- this.pageAdapter = new PageAdapter(monitorDOStub, this.env.RESOURCES_BUCKET);
1413
1400
  return [
1414
1401
  4,
1415
- this.buildRuntimeEnv()
1402
+ this.prepareRunner(brainTitle, brainRunId, currentUser)
1416
1403
  ];
1417
1404
  case 5:
1418
- env = _state.sent();
1419
- // Create pages service for brain to use
1420
- pagesService = createPagesService(brainRunId, this.env.RESOURCES_BUCKET, monitorDOStub, env);
1421
- setGovernorBinding(this.env.GOVERNOR_DO);
1422
- if (!brainRunner) {
1423
- throw new Error('BrainRunner not initialized');
1424
- }
1425
- return [
1426
- 4,
1427
- this.loadResourcesFromR2()
1428
- ];
1429
- case 6:
1430
- r2Resources = _state.sent();
1431
- runnerWithResources = brainRunner;
1432
- if (r2Resources) {
1433
- runnerWithResources = brainRunner.withResources(r2Resources);
1434
- }
1435
- // Add pages service and runtime env
1436
- runnerWithResources = runnerWithResources.withPages(pagesService).withEnv(env);
1437
- // Add signal provider for signal handling
1438
- // Webhook response comes from signals, consumed by the brain during execution
1439
- signalProvider = new CloudflareSignalProvider(function(filter) {
1440
- return _this.getAndConsumeSignals(filter);
1441
- });
1442
- runnerWithResources = runnerWithResources.withSignalProvider(signalProvider).withGovernor(function(c) {
1443
- return rateGoverned(c);
1444
- }).withStoreProvider(createR2Backend(this.env.RESOURCES_BUCKET));
1445
- // Create abort controller for this run
1446
- this.abortController = new AbortController();
1447
- iterateItemAdapter = new IterateItemAdapter(function(signal) {
1448
- return _this.queueSignal(signal);
1449
- }, function(time) {
1450
- return _this.ctx.storage.setAlarm(time);
1451
- });
1452
- timeoutAdapter = new TimeoutAdapter(function(brainRunId, timeoutAt) {
1453
- return _this.storeWaitTimeout(brainRunId, timeoutAt);
1454
- }, function(time) {
1455
- return _this.ctx.storage.setAlarm(time);
1456
- });
1457
- runnerWithResources.withAdapters([
1458
- sqliteAdapter,
1459
- eventStreamAdapter,
1460
- monitorAdapter,
1461
- scheduleAdapter,
1462
- webhookAdapter,
1463
- this.pageAdapter,
1464
- iterateItemAdapter,
1465
- timeoutAdapter
1466
- ]).resume(brainToRun, {
1405
+ _ref = _state.sent(), brainToRun = _ref.brainToRun, runner = _ref.runner;
1406
+ runner.resume(brainToRun, {
1467
1407
  currentUser: currentUser,
1468
1408
  machine: machine,
1469
1409
  brainRunId: originalBrainRunId,
@@ -0,0 +1,6 @@
1
+ import { guessMimeType } from '@positronic/core';
2
+ export function guessContentType(nameOrKey) {
3
+ var mime = guessMimeType(nameOrKey);
4
+ if (mime.startsWith('text/')) return "".concat(mime, "; charset=utf-8");
5
+ return mime;
6
+ }