@positronic/cloudflare 0.0.67 → 0.0.69
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.
- package/dist/src/api/auth-middleware.js +25 -0
- package/dist/src/api/brains.js +67 -16
- package/dist/src/api/secrets.js +3 -0
- package/dist/src/brain-runner-do.js +51 -5
- package/dist/src/create-r2-store.js +319 -0
- package/dist/src/dev-server.js +19 -1
- package/dist/src/governor-client-wrapper.js +364 -0
- package/dist/src/governor-do.js +387 -0
- package/dist/src/index.js +3 -0
- package/dist/src/monitor-do.js +25 -12
- package/dist/src/rate-limit-headers.js +199 -0
- package/dist/src/schedule-do.js +38 -22
- package/dist/src/token-estimator.js +39 -0
- package/dist/types/api/auth-middleware.d.ts +5 -0
- package/dist/types/api/auth-middleware.d.ts.map +1 -1
- package/dist/types/api/brains.d.ts.map +1 -1
- package/dist/types/api/secrets.d.ts.map +1 -1
- package/dist/types/brain-runner-do.d.ts +9 -1
- package/dist/types/brain-runner-do.d.ts.map +1 -1
- package/dist/types/create-r2-store.d.ts +14 -0
- package/dist/types/create-r2-store.d.ts.map +1 -0
- package/dist/types/dev-server.d.ts.map +1 -1
- package/dist/types/governor-client-wrapper.d.ts +15 -0
- package/dist/types/governor-client-wrapper.d.ts.map +1 -0
- package/dist/types/governor-do.d.ts +25 -0
- package/dist/types/governor-do.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/monitor-do.d.ts +13 -4
- package/dist/types/monitor-do.d.ts.map +1 -1
- package/dist/types/rate-limit-headers.d.ts +10 -0
- package/dist/types/rate-limit-headers.d.ts.map +1 -0
- package/dist/types/schedule-do.d.ts +11 -3
- package/dist/types/schedule-do.d.ts.map +1 -1
- package/dist/types/token-estimator.d.ts +9 -0
- package/dist/types/token-estimator.d.ts.map +1 -0
- package/package.json +5 -4
|
@@ -126,6 +126,31 @@ function _ts_generator(thisArg, body) {
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
import { jwtVerify, decodeJwt, importJWK } from 'jose';
|
|
129
|
+
/**
|
|
130
|
+
* Middleware that restricts access to root users only.
|
|
131
|
+
* Returns 403 if the authenticated user is not root.
|
|
132
|
+
*/ export function requireRoot() {
|
|
133
|
+
return function(c, next) {
|
|
134
|
+
return _async_to_generator(function() {
|
|
135
|
+
var auth;
|
|
136
|
+
return _ts_generator(this, function(_state) {
|
|
137
|
+
auth = c.get('auth');
|
|
138
|
+
if (!(auth === null || auth === void 0 ? void 0 : auth.isRoot)) {
|
|
139
|
+
return [
|
|
140
|
+
2,
|
|
141
|
+
c.json({
|
|
142
|
+
error: 'Root access required'
|
|
143
|
+
}, 403)
|
|
144
|
+
];
|
|
145
|
+
}
|
|
146
|
+
return [
|
|
147
|
+
2,
|
|
148
|
+
next()
|
|
149
|
+
];
|
|
150
|
+
});
|
|
151
|
+
})();
|
|
152
|
+
};
|
|
153
|
+
}
|
|
129
154
|
/**
|
|
130
155
|
* Get the JWT algorithm based on JWK key type
|
|
131
156
|
*/ function getAlgorithmForJwk(jwk) {
|
package/dist/src/api/brains.js
CHANGED
|
@@ -160,9 +160,18 @@ import Fuse from 'fuse.js';
|
|
|
160
160
|
import { isSignalValid, brainMachineDefinition } from '@positronic/core';
|
|
161
161
|
import { getManifest } from '../brain-runner-do.js';
|
|
162
162
|
var brains = new Hono();
|
|
163
|
+
/**
|
|
164
|
+
* Get the userId for ownership filtering from the auth context.
|
|
165
|
+
* Root users get null (no filter — sees everything).
|
|
166
|
+
* Non-root users get their userId (sees only their own).
|
|
167
|
+
*/ function scopeUserId(context) {
|
|
168
|
+
var auth = context.get('auth');
|
|
169
|
+
var _auth_userId;
|
|
170
|
+
return (auth === null || auth === void 0 ? void 0 : auth.isRoot) ? null : (_auth_userId = auth === null || auth === void 0 ? void 0 : auth.userId) !== null && _auth_userId !== void 0 ? _auth_userId : null;
|
|
171
|
+
}
|
|
163
172
|
brains.post('/runs', function(context) {
|
|
164
173
|
return _async_to_generator(function() {
|
|
165
|
-
var requestBody, options, identifier, manifest, resolution, brain, brainRunId, namespace, doId, stub, initialData, brainTitle, response;
|
|
174
|
+
var requestBody, options, identifier, manifest, resolution, brain, brainRunId, namespace, doId, stub, auth, currentUser, initialData, brainTitle, response;
|
|
166
175
|
return _ts_generator(this, function(_state) {
|
|
167
176
|
switch(_state.label){
|
|
168
177
|
case 0:
|
|
@@ -218,6 +227,19 @@ brains.post('/runs', function(context) {
|
|
|
218
227
|
namespace = context.env.BRAIN_RUNNER_DO;
|
|
219
228
|
doId = namespace.idFromName(brainRunId);
|
|
220
229
|
stub = namespace.get(doId);
|
|
230
|
+
// Read auth context for currentUser (every brain run must have an owner)
|
|
231
|
+
auth = context.get('auth');
|
|
232
|
+
if (!(auth === null || auth === void 0 ? void 0 : auth.userId) && !(auth === null || auth === void 0 ? void 0 : auth.isRoot)) {
|
|
233
|
+
return [
|
|
234
|
+
2,
|
|
235
|
+
context.json({
|
|
236
|
+
error: 'Authentication required to run a brain'
|
|
237
|
+
}, 401)
|
|
238
|
+
];
|
|
239
|
+
}
|
|
240
|
+
currentUser = {
|
|
241
|
+
id: auth.userId || 'root'
|
|
242
|
+
};
|
|
221
243
|
// Pass options to the brain runner if provided
|
|
222
244
|
initialData = options ? {
|
|
223
245
|
options: options
|
|
@@ -226,7 +248,7 @@ brains.post('/runs', function(context) {
|
|
|
226
248
|
brainTitle = brain.title || identifier;
|
|
227
249
|
return [
|
|
228
250
|
4,
|
|
229
|
-
stub.start(brainTitle, brainRunId, initialData)
|
|
251
|
+
stub.start(brainTitle, brainRunId, currentUser, initialData)
|
|
230
252
|
];
|
|
231
253
|
case 2:
|
|
232
254
|
_state.sent();
|
|
@@ -243,7 +265,7 @@ brains.post('/runs', function(context) {
|
|
|
243
265
|
});
|
|
244
266
|
brains.post('/runs/rerun', function(context) {
|
|
245
267
|
return _async_to_generator(function() {
|
|
246
|
-
var requestBody, runId, startsAt, stopsAfter, identifier, manifest, resolution, brain, monitorId, monitorStub, existingRun, newBrainRunId, namespace, doId, stub, rerunOptions, brainTitle, response;
|
|
268
|
+
var requestBody, runId, startsAt, stopsAfter, identifier, manifest, resolution, brain, monitorId, monitorStub, existingRun, auth, currentUser, newBrainRunId, namespace, doId, stub, rerunOptions, brainTitle, response;
|
|
247
269
|
return _ts_generator(this, function(_state) {
|
|
248
270
|
switch(_state.label){
|
|
249
271
|
case 0:
|
|
@@ -317,6 +339,19 @@ brains.post('/runs/rerun', function(context) {
|
|
|
317
339
|
}
|
|
318
340
|
_state.label = 3;
|
|
319
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.userId) && !(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
|
+
id: auth.userId || 'root'
|
|
354
|
+
};
|
|
320
355
|
// Create a new brain run with rerun parameters
|
|
321
356
|
newBrainRunId = uuidv4();
|
|
322
357
|
namespace = context.env.BRAIN_RUNNER_DO;
|
|
@@ -334,7 +369,7 @@ brains.post('/runs/rerun', function(context) {
|
|
|
334
369
|
brainTitle = brain.title || identifier;
|
|
335
370
|
return [
|
|
336
371
|
4,
|
|
337
|
-
stub.start(brainTitle, newBrainRunId, rerunOptions)
|
|
372
|
+
stub.start(brainTitle, newBrainRunId, currentUser, rerunOptions)
|
|
338
373
|
];
|
|
339
374
|
case 4:
|
|
340
375
|
_state.sent();
|
|
@@ -375,16 +410,17 @@ brains.get('/runs/:runId/watch', function(context) {
|
|
|
375
410
|
});
|
|
376
411
|
brains.get('/runs/:runId', function(context) {
|
|
377
412
|
return _async_to_generator(function() {
|
|
378
|
-
var runId, monitorId, monitorStub, run;
|
|
413
|
+
var runId, userId, monitorId, monitorStub, run;
|
|
379
414
|
return _ts_generator(this, function(_state) {
|
|
380
415
|
switch(_state.label){
|
|
381
416
|
case 0:
|
|
382
417
|
runId = context.req.param('runId');
|
|
418
|
+
userId = scopeUserId(context);
|
|
383
419
|
monitorId = context.env.MONITOR_DO.idFromName('singleton');
|
|
384
420
|
monitorStub = context.env.MONITOR_DO.get(monitorId);
|
|
385
421
|
return [
|
|
386
422
|
4,
|
|
387
|
-
monitorStub.getRun(runId)
|
|
423
|
+
monitorStub.getRun(runId, userId)
|
|
388
424
|
];
|
|
389
425
|
case 1:
|
|
390
426
|
run = _state.sent();
|
|
@@ -640,7 +676,7 @@ brains.post('/runs/:runId/resume', function(context) {
|
|
|
640
676
|
});
|
|
641
677
|
brains.get('/:identifier/history', function(context) {
|
|
642
678
|
return _async_to_generator(function() {
|
|
643
|
-
var identifier, limit, manifest, resolution, brain, brainTitle, monitorId, monitorStub, runs;
|
|
679
|
+
var identifier, limit, manifest, resolution, brain, brainTitle, monitorId, monitorStub, userId, runs;
|
|
644
680
|
return _ts_generator(this, function(_state) {
|
|
645
681
|
switch(_state.label){
|
|
646
682
|
case 0:
|
|
@@ -681,9 +717,10 @@ brains.get('/:identifier/history', function(context) {
|
|
|
681
717
|
// Get the monitor singleton instance
|
|
682
718
|
monitorId = context.env.MONITOR_DO.idFromName('singleton');
|
|
683
719
|
monitorStub = context.env.MONITOR_DO.get(monitorId);
|
|
720
|
+
userId = scopeUserId(context);
|
|
684
721
|
return [
|
|
685
722
|
4,
|
|
686
|
-
monitorStub.history(brainTitle, limit)
|
|
723
|
+
monitorStub.history(brainTitle, limit, userId)
|
|
687
724
|
];
|
|
688
725
|
case 1:
|
|
689
726
|
runs = _state.sent();
|
|
@@ -699,7 +736,7 @@ brains.get('/:identifier/history', function(context) {
|
|
|
699
736
|
});
|
|
700
737
|
brains.get('/:identifier/active-runs', function(context) {
|
|
701
738
|
return _async_to_generator(function() {
|
|
702
|
-
var identifier, manifest, resolution, brain, brainTitle, monitorId, monitorStub, runs;
|
|
739
|
+
var identifier, manifest, resolution, brain, brainTitle, monitorId, monitorStub, userId, runs;
|
|
703
740
|
return _ts_generator(this, function(_state) {
|
|
704
741
|
switch(_state.label){
|
|
705
742
|
case 0:
|
|
@@ -739,9 +776,10 @@ brains.get('/:identifier/active-runs', function(context) {
|
|
|
739
776
|
// Get the monitor singleton instance
|
|
740
777
|
monitorId = context.env.MONITOR_DO.idFromName('singleton');
|
|
741
778
|
monitorStub = context.env.MONITOR_DO.get(monitorId);
|
|
779
|
+
userId = scopeUserId(context);
|
|
742
780
|
return [
|
|
743
781
|
4,
|
|
744
|
-
monitorStub.activeRuns(brainTitle)
|
|
782
|
+
monitorStub.activeRuns(brainTitle, userId)
|
|
745
783
|
];
|
|
746
784
|
case 1:
|
|
747
785
|
runs = _state.sent();
|
|
@@ -922,7 +960,7 @@ brains.get('/', function(context) {
|
|
|
922
960
|
// Create a new schedule
|
|
923
961
|
brains.post('/schedules', function(context) {
|
|
924
962
|
return _async_to_generator(function() {
|
|
925
|
-
var body, cronExpression, identifier, manifest, resolution, brain, brainTitle, scheduleDoId, scheduleStub, timezone, schedule, error, errorMessage;
|
|
963
|
+
var body, cronExpression, identifier, manifest, resolution, brain, brainTitle, scheduleDoId, scheduleStub, auth, runAsUserId, timezone, schedule, error, errorMessage;
|
|
926
964
|
return _ts_generator(this, function(_state) {
|
|
927
965
|
switch(_state.label){
|
|
928
966
|
case 0:
|
|
@@ -1003,6 +1041,17 @@ brains.post('/schedules', function(context) {
|
|
|
1003
1041
|
// Get the schedule singleton instance
|
|
1004
1042
|
scheduleDoId = context.env.SCHEDULE_DO.idFromName('singleton');
|
|
1005
1043
|
scheduleStub = context.env.SCHEDULE_DO.get(scheduleDoId);
|
|
1044
|
+
// Require authentication — scheduled runs will execute as this user
|
|
1045
|
+
auth = context.get('auth');
|
|
1046
|
+
if (!(auth === null || auth === void 0 ? void 0 : auth.userId) && !(auth === null || auth === void 0 ? void 0 : auth.isRoot)) {
|
|
1047
|
+
return [
|
|
1048
|
+
2,
|
|
1049
|
+
context.json({
|
|
1050
|
+
error: 'Authentication required to create a schedule'
|
|
1051
|
+
}, 401)
|
|
1052
|
+
];
|
|
1053
|
+
}
|
|
1054
|
+
runAsUserId = auth.userId || 'root';
|
|
1006
1055
|
// Determine timezone: use provided value, fall back to project timezone
|
|
1007
1056
|
timezone = body.timezone;
|
|
1008
1057
|
if (!!timezone) return [
|
|
@@ -1032,7 +1081,7 @@ brains.post('/schedules', function(context) {
|
|
|
1032
1081
|
}
|
|
1033
1082
|
return [
|
|
1034
1083
|
4,
|
|
1035
|
-
scheduleStub.createSchedule(brainTitle, cronExpression, timezone)
|
|
1084
|
+
scheduleStub.createSchedule(brainTitle, cronExpression, timezone, runAsUserId)
|
|
1036
1085
|
];
|
|
1037
1086
|
case 4:
|
|
1038
1087
|
schedule = _state.sent();
|
|
@@ -1060,15 +1109,16 @@ brains.post('/schedules', function(context) {
|
|
|
1060
1109
|
// List all schedules
|
|
1061
1110
|
brains.get('/schedules', function(context) {
|
|
1062
1111
|
return _async_to_generator(function() {
|
|
1063
|
-
var scheduleId, scheduleStub, result;
|
|
1112
|
+
var scheduleId, scheduleStub, userId, result;
|
|
1064
1113
|
return _ts_generator(this, function(_state) {
|
|
1065
1114
|
switch(_state.label){
|
|
1066
1115
|
case 0:
|
|
1067
1116
|
scheduleId = context.env.SCHEDULE_DO.idFromName('singleton');
|
|
1068
1117
|
scheduleStub = context.env.SCHEDULE_DO.get(scheduleId);
|
|
1118
|
+
userId = scopeUserId(context);
|
|
1069
1119
|
return [
|
|
1070
1120
|
4,
|
|
1071
|
-
scheduleStub.listSchedules()
|
|
1121
|
+
scheduleStub.listSchedules(userId)
|
|
1072
1122
|
];
|
|
1073
1123
|
case 1:
|
|
1074
1124
|
result = _state.sent();
|
|
@@ -1083,7 +1133,7 @@ brains.get('/schedules', function(context) {
|
|
|
1083
1133
|
// Get scheduled run history - MUST be before :scheduleId route
|
|
1084
1134
|
brains.get('/schedules/runs', function(context) {
|
|
1085
1135
|
return _async_to_generator(function() {
|
|
1086
|
-
var scheduleIdParam, limit, scheduleDoId, scheduleStub, result;
|
|
1136
|
+
var scheduleIdParam, limit, scheduleDoId, scheduleStub, userId, result;
|
|
1087
1137
|
return _ts_generator(this, function(_state) {
|
|
1088
1138
|
switch(_state.label){
|
|
1089
1139
|
case 0:
|
|
@@ -1091,9 +1141,10 @@ brains.get('/schedules/runs', function(context) {
|
|
|
1091
1141
|
limit = Number(context.req.query('limit') || '100');
|
|
1092
1142
|
scheduleDoId = context.env.SCHEDULE_DO.idFromName('singleton');
|
|
1093
1143
|
scheduleStub = context.env.SCHEDULE_DO.get(scheduleDoId);
|
|
1144
|
+
userId = scopeUserId(context);
|
|
1094
1145
|
return [
|
|
1095
1146
|
4,
|
|
1096
|
-
scheduleStub.getAllRuns(scheduleIdParam, limit)
|
|
1147
|
+
scheduleStub.getAllRuns(scheduleIdParam, limit, userId)
|
|
1097
1148
|
];
|
|
1098
1149
|
case 1:
|
|
1099
1150
|
result = _state.sent();
|
package/dist/src/api/secrets.js
CHANGED
|
@@ -178,6 +178,7 @@ function _ts_generator(thisArg, body) {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
import { Hono } from 'hono';
|
|
181
|
+
import { requireRoot } from './auth-middleware.js';
|
|
181
182
|
/**
|
|
182
183
|
* Helper to check if Cloudflare API credentials are configured
|
|
183
184
|
*/ function getSecretsApiConfig(env) {
|
|
@@ -214,6 +215,8 @@ import { Hono } from 'hono';
|
|
|
214
215
|
}).apply(this, arguments);
|
|
215
216
|
}
|
|
216
217
|
var secrets = new Hono();
|
|
218
|
+
// Only root users can manage secrets
|
|
219
|
+
secrets.use('*', requireRoot());
|
|
217
220
|
// Protected secret name that cannot be managed via the API
|
|
218
221
|
var PROTECTED_SECRET = 'ROOT_PUBLIC_KEY';
|
|
219
222
|
// List all secrets (names only, not values)
|
|
@@ -298,7 +298,9 @@ 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 { setGovernorBinding, rateGoverned } from './governor-client-wrapper.js';
|
|
301
302
|
import { CloudflareR2Loader } from './r2-loader.js';
|
|
303
|
+
import { createR2Backend } from './create-r2-store.js';
|
|
302
304
|
import { createResources } from '@positronic/core';
|
|
303
305
|
var manifest = null;
|
|
304
306
|
export function setManifest(generatedManifest) {
|
|
@@ -503,6 +505,8 @@ var ScheduleAdapter = /*#__PURE__*/ function() {
|
|
|
503
505
|
]);
|
|
504
506
|
return BatchChunkAdapter;
|
|
505
507
|
}();
|
|
508
|
+
// SQL to initialize the run owner table (stores who started this brain run)
|
|
509
|
+
var runOwnerTableSQL = "\nCREATE TABLE IF NOT EXISTS run_owner (\n user_id TEXT NOT NULL\n);\n";
|
|
506
510
|
// SQL to initialize the signals table
|
|
507
511
|
var signalsTableSQL = "\nCREATE TABLE IF NOT EXISTS brain_signals (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n signal_type TEXT NOT NULL,\n content TEXT,\n queued_at INTEGER NOT NULL\n);\n";
|
|
508
512
|
// SQL to initialize the wait timeout table
|
|
@@ -516,13 +520,37 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
516
520
|
_this = _call_super(this, BrainRunnerDO, [
|
|
517
521
|
state,
|
|
518
522
|
env
|
|
519
|
-
]), _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, "signalsTableInitialized", false), _define_property(_this, "waitTimeoutTableInitialized", false);
|
|
523
|
+
]), _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);
|
|
520
524
|
_this.sql = state.storage.sql;
|
|
521
525
|
_this.brainRunId = state.id.toString();
|
|
522
526
|
_this.env = env;
|
|
523
527
|
return _this;
|
|
524
528
|
}
|
|
525
529
|
_create_class(BrainRunnerDO, [
|
|
530
|
+
{
|
|
531
|
+
key: "initializeRunOwnerTable",
|
|
532
|
+
value: function initializeRunOwnerTable() {
|
|
533
|
+
if (!this.runOwnerTableInitialized) {
|
|
534
|
+
this.sql.exec(runOwnerTableSQL);
|
|
535
|
+
this.runOwnerTableInitialized = true;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
key: "storeRunOwner",
|
|
541
|
+
value: function storeRunOwner(userId) {
|
|
542
|
+
this.initializeRunOwnerTable();
|
|
543
|
+
this.sql.exec("INSERT INTO run_owner (user_id) VALUES (?)", userId);
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
key: "getRunOwner",
|
|
548
|
+
value: function getRunOwner() {
|
|
549
|
+
this.initializeRunOwnerTable();
|
|
550
|
+
var results = this.sql.exec("SELECT user_id FROM run_owner LIMIT 1").toArray();
|
|
551
|
+
return results.length > 0 ? results[0].user_id : null;
|
|
552
|
+
}
|
|
553
|
+
},
|
|
526
554
|
{
|
|
527
555
|
key: "initializeSignalsTable",
|
|
528
556
|
value: function initializeSignalsTable() {
|
|
@@ -1018,7 +1046,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
1018
1046
|
},
|
|
1019
1047
|
{
|
|
1020
1048
|
key: "start",
|
|
1021
|
-
value: function start(brainTitle, brainRunId, initialData) {
|
|
1049
|
+
value: function start(brainTitle, brainRunId, currentUser, initialData) {
|
|
1022
1050
|
return _async_to_generator(function() {
|
|
1023
1051
|
var _this, sql, resolution, brainToRun, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, env, pagesService, r2Resources, runnerWithResources, signalProvider, options, initialState, batchChunkAdapter, timeoutAdapter;
|
|
1024
1052
|
return _ts_generator(this, function(_state) {
|
|
@@ -1055,6 +1083,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
1055
1083
|
env = this.buildRuntimeEnv();
|
|
1056
1084
|
// Create pages service for brain to use
|
|
1057
1085
|
pagesService = createPagesService(brainRunId, this.env.RESOURCES_BUCKET, monitorDOStub, env);
|
|
1086
|
+
setGovernorBinding(this.env.GOVERNOR_DO);
|
|
1058
1087
|
if (!brainRunner) {
|
|
1059
1088
|
throw new Error('BrainRunner not initialized');
|
|
1060
1089
|
}
|
|
@@ -1076,10 +1105,14 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
1076
1105
|
signalProvider = new CloudflareSignalProvider(function(filter) {
|
|
1077
1106
|
return _this.getAndConsumeSignals(filter);
|
|
1078
1107
|
});
|
|
1079
|
-
runnerWithResources = runnerWithResources.withSignalProvider(signalProvider)
|
|
1108
|
+
runnerWithResources = runnerWithResources.withSignalProvider(signalProvider).withGovernor(function(c) {
|
|
1109
|
+
return rateGoverned(c);
|
|
1110
|
+
}).withStoreProvider(createR2Backend(this.env.RESOURCES_BUCKET));
|
|
1080
1111
|
// Extract options from initialData if present
|
|
1081
1112
|
options = initialData === null || initialData === void 0 ? void 0 : initialData.options;
|
|
1082
1113
|
initialState = initialData && !initialData.options ? initialData : {};
|
|
1114
|
+
// Persist run owner durably (immutable, not derived from events)
|
|
1115
|
+
this.storeRunOwner(currentUser.id);
|
|
1083
1116
|
// Create abort controller for this run
|
|
1084
1117
|
this.abortController = new AbortController();
|
|
1085
1118
|
batchChunkAdapter = new BatchChunkAdapter(function(signal) {
|
|
@@ -1102,6 +1135,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
1102
1135
|
batchChunkAdapter,
|
|
1103
1136
|
timeoutAdapter
|
|
1104
1137
|
]).run(brainToRun, _object_spread_props(_object_spread({
|
|
1138
|
+
currentUser: currentUser,
|
|
1105
1139
|
initialState: initialState,
|
|
1106
1140
|
brainRunId: brainRunId
|
|
1107
1141
|
}, options && {
|
|
@@ -1131,7 +1165,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
1131
1165
|
* This method reconstructs state and calls BrainRunner.resume().
|
|
1132
1166
|
*/ function wakeUp(brainRunId) {
|
|
1133
1167
|
return _async_to_generator(function() {
|
|
1134
|
-
var _this, sql, pendingTimeout, eventLoader, startEvent, brainTitle, initialState, originalBrainRunId, resolution, brainToRun, allEvents, machine, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, event, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, env, pagesService, r2Resources, runnerWithResources, signalProvider, batchChunkAdapter, timeoutAdapter;
|
|
1168
|
+
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;
|
|
1135
1169
|
return _ts_generator(this, function(_state) {
|
|
1136
1170
|
switch(_state.label){
|
|
1137
1171
|
case 0:
|
|
@@ -1170,6 +1204,14 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
1170
1204
|
}
|
|
1171
1205
|
brainTitle = startEvent.brainTitle;
|
|
1172
1206
|
initialState = startEvent.initialState || {};
|
|
1207
|
+
// Read run owner from durable storage (set once in start(), not from events)
|
|
1208
|
+
ownerId = this.getRunOwner();
|
|
1209
|
+
if (!ownerId) {
|
|
1210
|
+
throw new Error("No run owner found for brain run ".concat(brainRunId));
|
|
1211
|
+
}
|
|
1212
|
+
currentUser = {
|
|
1213
|
+
id: ownerId
|
|
1214
|
+
};
|
|
1173
1215
|
// Use the brainRunId from the START event, not the parameter.
|
|
1174
1216
|
// alarm() passes state.id.toString() (the DO hex ID), but the brain was
|
|
1175
1217
|
// originally started with a UUID. Events must use the original UUID so
|
|
@@ -1233,6 +1275,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
1233
1275
|
env = this.buildRuntimeEnv();
|
|
1234
1276
|
// Create pages service for brain to use
|
|
1235
1277
|
pagesService = createPagesService(brainRunId, this.env.RESOURCES_BUCKET, monitorDOStub, env);
|
|
1278
|
+
setGovernorBinding(this.env.GOVERNOR_DO);
|
|
1236
1279
|
if (!brainRunner) {
|
|
1237
1280
|
throw new Error('BrainRunner not initialized');
|
|
1238
1281
|
}
|
|
@@ -1253,7 +1296,9 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
1253
1296
|
signalProvider = new CloudflareSignalProvider(function(filter) {
|
|
1254
1297
|
return _this.getAndConsumeSignals(filter);
|
|
1255
1298
|
});
|
|
1256
|
-
runnerWithResources = runnerWithResources.withSignalProvider(signalProvider)
|
|
1299
|
+
runnerWithResources = runnerWithResources.withSignalProvider(signalProvider).withGovernor(function(c) {
|
|
1300
|
+
return rateGoverned(c);
|
|
1301
|
+
}).withStoreProvider(createR2Backend(this.env.RESOURCES_BUCKET));
|
|
1257
1302
|
// Create abort controller for this run
|
|
1258
1303
|
this.abortController = new AbortController();
|
|
1259
1304
|
batchChunkAdapter = new BatchChunkAdapter(function(signal) {
|
|
@@ -1276,6 +1321,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
1276
1321
|
batchChunkAdapter,
|
|
1277
1322
|
timeoutAdapter
|
|
1278
1323
|
]).resume(brainToRun, {
|
|
1324
|
+
currentUser: currentUser,
|
|
1279
1325
|
machine: machine,
|
|
1280
1326
|
brainRunId: originalBrainRunId,
|
|
1281
1327
|
signal: this.abortController.signal
|