@rivet-dev/flue 2.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.
- package/LICENSE +203 -0
- package/README.md +26 -0
- package/dist/agent-coordinator.d.ts +88 -0
- package/dist/agent-coordinator.d.ts.map +1 -0
- package/dist/agent-coordinator.js +346 -0
- package/dist/agent-coordinator.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +2 -0
- package/dist/internal.js.map +1 -0
- package/dist/registry-ops-async.d.ts +7 -0
- package/dist/registry-ops-async.d.ts.map +1 -0
- package/dist/registry-ops-async.js +12 -0
- package/dist/registry-ops-async.js.map +1 -0
- package/dist/rivet-db.d.ts +7 -0
- package/dist/rivet-db.d.ts.map +1 -0
- package/dist/rivet-db.js +65 -0
- package/dist/rivet-db.js.map +1 -0
- package/dist/run-store-composite.d.ts +3 -0
- package/dist/run-store-composite.d.ts.map +1 -0
- package/dist/run-store-composite.js +43 -0
- package/dist/run-store-composite.js.map +1 -0
- package/dist/runtime.d.ts +8 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +7 -0
- package/dist/runtime.js.map +1 -0
- package/dist/stores/async-db.d.ts +10 -0
- package/dist/stores/async-db.d.ts.map +1 -0
- package/dist/stores/async-db.js +5 -0
- package/dist/stores/async-db.js.map +1 -0
- package/dist/stores/attachment-store.d.ts +4 -0
- package/dist/stores/attachment-store.d.ts.map +1 -0
- package/dist/stores/attachment-store.js +59 -0
- package/dist/stores/attachment-store.js.map +1 -0
- package/dist/stores/constants.d.ts +11 -0
- package/dist/stores/constants.d.ts.map +1 -0
- package/dist/stores/constants.js +11 -0
- package/dist/stores/constants.js.map +1 -0
- package/dist/stores/conversation-stream-store.d.ts +4 -0
- package/dist/stores/conversation-stream-store.d.ts.map +1 -0
- package/dist/stores/conversation-stream-store.js +16 -0
- package/dist/stores/conversation-stream-store.js.map +1 -0
- package/dist/stores/event-stream-store.d.ts +6 -0
- package/dist/stores/event-stream-store.d.ts.map +1 -0
- package/dist/stores/event-stream-store.js +171 -0
- package/dist/stores/event-stream-store.js.map +1 -0
- package/dist/stores/helpers.d.ts +2 -0
- package/dist/stores/helpers.d.ts.map +1 -0
- package/dist/stores/helpers.js +6 -0
- package/dist/stores/helpers.js.map +1 -0
- package/dist/stores/index.d.ts +11 -0
- package/dist/stores/index.d.ts.map +1 -0
- package/dist/stores/index.js +23 -0
- package/dist/stores/index.js.map +1 -0
- package/dist/stores/run-store.d.ts +4 -0
- package/dist/stores/run-store.d.ts.map +1 -0
- package/dist/stores/run-store.js +117 -0
- package/dist/stores/run-store.js.map +1 -0
- package/dist/stores/schema.d.ts +3 -0
- package/dist/stores/schema.d.ts.map +1 -0
- package/dist/stores/schema.js +228 -0
- package/dist/stores/schema.js.map +1 -0
- package/dist/stores/submission-store.d.ts +4 -0
- package/dist/stores/submission-store.d.ts.map +1 -0
- package/dist/stores/submission-store.js +261 -0
- package/dist/stores/submission-store.js.map +1 -0
- package/dist/target.d.ts +8 -0
- package/dist/target.d.ts.map +1 -0
- package/dist/target.js +408 -0
- package/dist/target.js.map +1 -0
- package/dist/workflow-coordinator.d.ts +71 -0
- package/dist/workflow-coordinator.d.ts.map +1 -0
- package/dist/workflow-coordinator.js +154 -0
- package/dist/workflow-coordinator.js.map +1 -0
- package/package.json +62 -0
package/dist/target.js
ADDED
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { defineTarget } from '@flue/cli';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
export function rivet(options = {}) {
|
|
4
|
+
const build = {
|
|
5
|
+
name: 'rivet',
|
|
6
|
+
bundle: 'vite',
|
|
7
|
+
external: [
|
|
8
|
+
'@rivet-dev/flue',
|
|
9
|
+
'rivetkit',
|
|
10
|
+
'rivetkit/client',
|
|
11
|
+
'rivetkit/db',
|
|
12
|
+
'node-liblzma',
|
|
13
|
+
'@mongodb-js/zstd',
|
|
14
|
+
],
|
|
15
|
+
generateEntryPoint(ctx) {
|
|
16
|
+
return generateEntryPoint(ctx, options);
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
return defineTarget({
|
|
20
|
+
name: 'rivet',
|
|
21
|
+
build,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const rivetTarget = rivet();
|
|
25
|
+
export default rivetTarget;
|
|
26
|
+
function generateEntryPoint(ctx, options) {
|
|
27
|
+
const agentImports = ctx.agents
|
|
28
|
+
.map((agent, index) => `import * as agent${index} from ${JSON.stringify(agent.filePath.replace(/\\/g, '/'))};`)
|
|
29
|
+
.join('\n');
|
|
30
|
+
const agentEntries = ctx.agents
|
|
31
|
+
.map((agent, index) => ` ${JSON.stringify(agent.name)}: agent${index},`)
|
|
32
|
+
.join('\n');
|
|
33
|
+
const workflowImports = ctx.workflows
|
|
34
|
+
.map((workflow, index) => `import * as workflow${index} from ${JSON.stringify(workflow.filePath.replace(/\\/g, '/'))};`)
|
|
35
|
+
.join('\n');
|
|
36
|
+
const workflowEntries = ctx.workflows
|
|
37
|
+
.map((workflow, index) => ` ${JSON.stringify(workflow.name)}: workflow${index},`)
|
|
38
|
+
.join('\n');
|
|
39
|
+
const agentNames = JSON.stringify(ctx.agents.map((agent) => agent.name).join(', '));
|
|
40
|
+
const workflowNames = JSON.stringify(ctx.workflows.map((workflow) => workflow.name).join(', '));
|
|
41
|
+
const userAppLoad = ctx.appEntry
|
|
42
|
+
? `const { default: userApp } = await import(${JSON.stringify(ctx.appEntry.replace(/\\/g, '/'))});`
|
|
43
|
+
: '';
|
|
44
|
+
const userRegistryImport = `import * as userRegistryModule from ${JSON.stringify(path.resolve(ctx.root, options.actors ?? './actors.ts').replace(/\\/g, '/'))};`;
|
|
45
|
+
return `// Auto-generated by flue (target: rivet)
|
|
46
|
+
import { actor } from 'rivetkit';
|
|
47
|
+
import { createClient } from 'rivetkit/client';
|
|
48
|
+
import { db } from 'rivetkit/db';
|
|
49
|
+
import {
|
|
50
|
+
createAsyncEventStreamStore,
|
|
51
|
+
createAsyncRegistryOps,
|
|
52
|
+
createRivetAsyncSqlDb,
|
|
53
|
+
createRivetAgentRuntime,
|
|
54
|
+
createRivetWorkflowRuntime,
|
|
55
|
+
} from '@rivet-dev/flue/runtime';
|
|
56
|
+
import {
|
|
57
|
+
Bash,
|
|
58
|
+
InMemoryFs,
|
|
59
|
+
bashFactoryToSessionEnv,
|
|
60
|
+
configureFlueRuntime,
|
|
61
|
+
createDefaultFlueApp,
|
|
62
|
+
createFlueContext,
|
|
63
|
+
generateWorkflowRunId,
|
|
64
|
+
resolveModel,
|
|
65
|
+
} from '@flue/runtime/adapter-kit';
|
|
66
|
+
${agentImports}
|
|
67
|
+
${workflowImports}
|
|
68
|
+
${userRegistryImport}
|
|
69
|
+
|
|
70
|
+
const agentModules = {
|
|
71
|
+
${agentEntries}
|
|
72
|
+
};
|
|
73
|
+
const workflowModules = {
|
|
74
|
+
${workflowEntries}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const agents = Object.entries(agentModules).map(([name, mod]) => {
|
|
78
|
+
if (!mod.default || mod.default.__flueAgentDefinition !== true) {
|
|
79
|
+
throw new Error('[flue] Agent "' + name + '" must default-export defineAgent(...).');
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
name,
|
|
83
|
+
definition: mod.default,
|
|
84
|
+
...(mod.description !== undefined ? { description: mod.description } : {}),
|
|
85
|
+
...(typeof mod.route === 'function' ? { route: mod.route } : {}),
|
|
86
|
+
...(typeof mod.attachments === 'function' ? { attachments: mod.attachments } : {}),
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
const workflows = Object.entries(workflowModules).map(([name, mod]) => {
|
|
90
|
+
if (!mod.default || mod.default.__flueWorkflowDefinition !== true) {
|
|
91
|
+
throw new Error('[flue] Workflow "' + name + '" must default-export defineWorkflow(...).');
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
name,
|
|
95
|
+
definition: mod.default,
|
|
96
|
+
...(typeof mod.route === 'function' ? { route: mod.route } : {}),
|
|
97
|
+
...(typeof mod.runs === 'function' ? { runs: mod.runs } : {}),
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
const FLUE_REGISTRY_ACTOR = 'flue-run-registry';
|
|
101
|
+
const FLUE_REGISTRY_KEY = process.env.FLUE_RIVET_REGISTRY_KEY || 'default';
|
|
102
|
+
const FLUE_AGENT_SUBMISSION_WAKE_ACTION = '__flueWakeAgentSubmissions';
|
|
103
|
+
const FLUE_AGENT_DISPATCH_ACTION = '__flueAdmitAgentDispatch';
|
|
104
|
+
const FLUE_WORKFLOW_ADMISSION_ACTION = '__flueAdmitWorkflow';
|
|
105
|
+
const actorAdapters = new WeakMap();
|
|
106
|
+
let flueClient;
|
|
107
|
+
|
|
108
|
+
function getFlueClient() {
|
|
109
|
+
flueClient ??= createClient();
|
|
110
|
+
return flueClient;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function getRegistryHandle() {
|
|
114
|
+
return getFlueClient().getOrCreate(FLUE_REGISTRY_ACTOR, [FLUE_REGISTRY_KEY]);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function forwardToFlueActor(handle, request) {
|
|
118
|
+
return handle.fetch(request);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const registryRunIndex = {
|
|
122
|
+
lookupRun: (runId) => getRegistryHandle().lookupRun(runId),
|
|
123
|
+
getRun: (runId) => getRegistryHandle().getRun(runId),
|
|
124
|
+
listRuns: (opts) => getRegistryHandle().listRuns(opts),
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
async function createDefaultEnv() {
|
|
128
|
+
const fs = new InMemoryFs();
|
|
129
|
+
return bashFactoryToSessionEnv(() => new Bash({
|
|
130
|
+
fs,
|
|
131
|
+
network: { dangerouslyAllowFullInternetAccess: true },
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function createContextForActor({ executionStore, actor, agentName, request, initialEventIndex, dispatchId }) {
|
|
136
|
+
return createFlueContext({
|
|
137
|
+
id: actor.key[0],
|
|
138
|
+
agentName,
|
|
139
|
+
dispatchId,
|
|
140
|
+
initialEventIndex,
|
|
141
|
+
env: process.env,
|
|
142
|
+
req: request,
|
|
143
|
+
agentConfig: { resolveModel },
|
|
144
|
+
createDefaultEnv,
|
|
145
|
+
submissionStore: executionStore.submissions,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function createContextForWorkflow({ actor, request, runId, initialEventIndex }) {
|
|
150
|
+
return createFlueContext({
|
|
151
|
+
id: runId,
|
|
152
|
+
runId,
|
|
153
|
+
initialEventIndex,
|
|
154
|
+
env: process.env,
|
|
155
|
+
req: request,
|
|
156
|
+
agentConfig: { resolveModel },
|
|
157
|
+
createDefaultEnv,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function adaptRivetActorContext(c) {
|
|
162
|
+
let adapter = actorAdapters.get(c);
|
|
163
|
+
if (adapter) return adapter;
|
|
164
|
+
adapter = {
|
|
165
|
+
get actorId() {
|
|
166
|
+
return c.actorId;
|
|
167
|
+
},
|
|
168
|
+
get name() {
|
|
169
|
+
return c.name;
|
|
170
|
+
},
|
|
171
|
+
get key() {
|
|
172
|
+
return c.key;
|
|
173
|
+
},
|
|
174
|
+
get region() {
|
|
175
|
+
return c.region;
|
|
176
|
+
},
|
|
177
|
+
get env() {
|
|
178
|
+
return process.env;
|
|
179
|
+
},
|
|
180
|
+
get request() {
|
|
181
|
+
return c.request;
|
|
182
|
+
},
|
|
183
|
+
get abortSignal() {
|
|
184
|
+
return c.abortSignal;
|
|
185
|
+
},
|
|
186
|
+
db: createRivetAsyncSqlDb(c.db),
|
|
187
|
+
schedule: c.schedule,
|
|
188
|
+
keepAwake: (promise) => c.keepAwake(promise),
|
|
189
|
+
};
|
|
190
|
+
actorAdapters.set(c, adapter);
|
|
191
|
+
return adapter;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const agentRuntime = createRivetAgentRuntime({
|
|
195
|
+
agents,
|
|
196
|
+
createContext: createContextForActor,
|
|
197
|
+
});
|
|
198
|
+
const workflowRuntime = createRivetWorkflowRuntime({
|
|
199
|
+
workflows,
|
|
200
|
+
createEventStreamStore: (ctx) => createAsyncEventStreamStore(ctx.db),
|
|
201
|
+
createRegistryRunStore: () => getRegistryHandle(),
|
|
202
|
+
createContext: createContextForWorkflow,
|
|
203
|
+
});
|
|
204
|
+
const preparedAgents = new WeakMap();
|
|
205
|
+
const preparedWorkflows = new WeakMap();
|
|
206
|
+
|
|
207
|
+
async function prepareAgent(c, agentName) {
|
|
208
|
+
const actorContext = adaptRivetActorContext(c);
|
|
209
|
+
let prepared = preparedAgents.get(actorContext);
|
|
210
|
+
if (!prepared) {
|
|
211
|
+
prepared = await agentRuntime.prepare({ db: actorContext.db, agentName });
|
|
212
|
+
agentRuntime.attach(actorContext, prepared);
|
|
213
|
+
preparedAgents.set(actorContext, prepared);
|
|
214
|
+
}
|
|
215
|
+
return actorContext;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async function prepareWorkflow(c, workflowName) {
|
|
219
|
+
const actorContext = adaptRivetActorContext(c);
|
|
220
|
+
let prepared = preparedWorkflows.get(actorContext);
|
|
221
|
+
if (!prepared) {
|
|
222
|
+
prepared = await workflowRuntime.prepare({ db: actorContext.db, workflowName, actor: actorContext });
|
|
223
|
+
workflowRuntime.attach(actorContext, prepared);
|
|
224
|
+
preparedWorkflows.set(actorContext, prepared);
|
|
225
|
+
}
|
|
226
|
+
return actorContext;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function defineFlueAgentActor(agentName) {
|
|
230
|
+
return actor({
|
|
231
|
+
db: db(),
|
|
232
|
+
actions: {
|
|
233
|
+
[FLUE_AGENT_SUBMISSION_WAKE_ACTION]: async (c) => {
|
|
234
|
+
const actorContext = await prepareAgent(c, agentName);
|
|
235
|
+
await agentRuntime.wakeSubmissions(actorContext);
|
|
236
|
+
},
|
|
237
|
+
[FLUE_AGENT_DISPATCH_ACTION]: async (c, input) => {
|
|
238
|
+
const actorContext = await prepareAgent(c, agentName);
|
|
239
|
+
return agentRuntime.admitDispatch(actorContext, input);
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
onWake: async (c) => {
|
|
243
|
+
const actorContext = await prepareAgent(c, agentName);
|
|
244
|
+
await agentRuntime.onWake(actorContext);
|
|
245
|
+
},
|
|
246
|
+
onRequest: async (c, request) => {
|
|
247
|
+
const actorContext = await prepareAgent(c, agentName);
|
|
248
|
+
const response = await agentRuntime.onRequest(actorContext, request);
|
|
249
|
+
if (response === null) return new Response(null, { status: 404 });
|
|
250
|
+
return response;
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function defineFlueWorkflowActor(workflowName) {
|
|
256
|
+
return actor({
|
|
257
|
+
db: db(),
|
|
258
|
+
// Public ?wait=result requests intentionally remain attached to the workflow.
|
|
259
|
+
options: { actionTimeout: 300000 },
|
|
260
|
+
actions: {
|
|
261
|
+
[FLUE_WORKFLOW_ADMISSION_ACTION]: async (c, input) => {
|
|
262
|
+
const actorContext = await prepareWorkflow(c, workflowName);
|
|
263
|
+
return workflowRuntime.admitWorkflow(actorContext, input);
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
onWake: async (c) => {
|
|
267
|
+
const actorContext = await prepareWorkflow(c, workflowName);
|
|
268
|
+
await workflowRuntime.onWake(actorContext);
|
|
269
|
+
},
|
|
270
|
+
onRequest: async (c, request) => {
|
|
271
|
+
const actorContext = await prepareWorkflow(c, workflowName);
|
|
272
|
+
const response = await workflowRuntime.onRequest(actorContext, request);
|
|
273
|
+
if (response === null) return new Response(null, { status: 404 });
|
|
274
|
+
return response;
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const runRegistryActor = actor({
|
|
280
|
+
db: db(),
|
|
281
|
+
actions: {
|
|
282
|
+
async createRun(c, input) {
|
|
283
|
+
return createAsyncRegistryOps(createRivetAsyncSqlDb(c.db)).then((ops) => ops.runStore.createRun(input));
|
|
284
|
+
},
|
|
285
|
+
async endRun(c, input) {
|
|
286
|
+
return createAsyncRegistryOps(createRivetAsyncSqlDb(c.db)).then((ops) => ops.runStore.endRun(input));
|
|
287
|
+
},
|
|
288
|
+
async getRun(c, runId) {
|
|
289
|
+
return createAsyncRegistryOps(createRivetAsyncSqlDb(c.db)).then((ops) => ops.runStore.getRun(runId));
|
|
290
|
+
},
|
|
291
|
+
async lookupRun(c, runId) {
|
|
292
|
+
return createAsyncRegistryOps(createRivetAsyncSqlDb(c.db)).then((ops) => ops.runStore.lookupRun(runId));
|
|
293
|
+
},
|
|
294
|
+
async listRuns(c, opts) {
|
|
295
|
+
return createAsyncRegistryOps(createRivetAsyncSqlDb(c.db)).then((ops) => ops.runStore.listRuns(opts));
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
export const registry = userRegistryModule.registry;
|
|
301
|
+
if (
|
|
302
|
+
!registry ||
|
|
303
|
+
typeof registry.startAndWait !== 'function' ||
|
|
304
|
+
typeof registry.parseConfig !== 'function' ||
|
|
305
|
+
!registry.config ||
|
|
306
|
+
typeof registry.config !== 'object'
|
|
307
|
+
) {
|
|
308
|
+
throw new TypeError('[flue] The Rivet actors module must export a registry created with setup(...).');
|
|
309
|
+
}
|
|
310
|
+
const userRivetActors = registry.config.use;
|
|
311
|
+
if (!userRivetActors || typeof userRivetActors !== 'object' || Array.isArray(userRivetActors)) {
|
|
312
|
+
throw new TypeError('[flue] The exported registry must configure an actor map with setup({ use: { ... } }).');
|
|
313
|
+
}
|
|
314
|
+
const internalRivetActors = {
|
|
315
|
+
[FLUE_REGISTRY_ACTOR]: runRegistryActor,
|
|
316
|
+
...Object.fromEntries(agents.map(({ name }) => [agentActorName(name), defineFlueAgentActor(name)])),
|
|
317
|
+
...Object.fromEntries(workflows.map(({ name }) => [workflowActorName(name), defineFlueWorkflowActor(name)])),
|
|
318
|
+
};
|
|
319
|
+
const actorNameCollisions = Object.keys(userRivetActors).filter((name) => name in internalRivetActors);
|
|
320
|
+
if (actorNameCollisions.length > 0) {
|
|
321
|
+
throw new Error('[flue] Rivet registry collides with generated actor names: ' + actorNameCollisions.join(', '));
|
|
322
|
+
}
|
|
323
|
+
registry.config.use = { ...userRivetActors, ...internalRivetActors };
|
|
324
|
+
|
|
325
|
+
function agentActorName(agentName) {
|
|
326
|
+
return 'flue-agent-' + agentName;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function workflowActorName(workflowName) {
|
|
330
|
+
return 'flue-workflow-' + workflowName;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function getAgentHandle(agentName, instanceId) {
|
|
334
|
+
if (!agents.some((record) => record.name === agentName)) return null;
|
|
335
|
+
return getFlueClient().getOrCreate(agentActorName(agentName), [instanceId]);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function getWorkflowHandle(workflowName, runId) {
|
|
339
|
+
if (!workflows.some((record) => record.name === workflowName)) return null;
|
|
340
|
+
return getFlueClient().getOrCreate(workflowActorName(workflowName), [runId]);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const rivetTarget = {
|
|
344
|
+
name: 'rivet',
|
|
345
|
+
routing: {
|
|
346
|
+
runIndex: registryRunIndex,
|
|
347
|
+
async forward(request, target) {
|
|
348
|
+
if (target.kind === 'agent') {
|
|
349
|
+
const handle = getAgentHandle(target.agentName, target.instanceId);
|
|
350
|
+
return handle ? forwardToFlueActor(handle, request) : null;
|
|
351
|
+
}
|
|
352
|
+
if (target.kind === 'workflow') {
|
|
353
|
+
const handle = getWorkflowHandle(target.workflowName, target.instanceId);
|
|
354
|
+
return handle ? forwardToFlueActor(handle, request) : null;
|
|
355
|
+
}
|
|
356
|
+
const handle = getWorkflowHandle(target.workflowName, target.runId);
|
|
357
|
+
return handle ? forwardToFlueActor(handle, request) : null;
|
|
358
|
+
},
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
const dispatchQueue = {
|
|
363
|
+
async enqueue(input) {
|
|
364
|
+
const handle = getAgentHandle(input.agent, input.id);
|
|
365
|
+
if (!handle) throw new Error('[flue] dispatch() target agent "' + input.agent + '" is unavailable.');
|
|
366
|
+
return handle.action({ name: FLUE_AGENT_DISPATCH_ACTION, args: [input] });
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
configureFlueRuntime({
|
|
371
|
+
target: rivetTarget,
|
|
372
|
+
devMode: process.env.FLUE_MODE === 'local',
|
|
373
|
+
agents,
|
|
374
|
+
workflows,
|
|
375
|
+
dispatchQueue,
|
|
376
|
+
channelHandlers: {},
|
|
377
|
+
async admitWorkflow({ workflowName, input }) {
|
|
378
|
+
const runId = generateWorkflowRunId();
|
|
379
|
+
const handle = getWorkflowHandle(workflowName, runId);
|
|
380
|
+
if (!handle) throw new Error('[flue] Workflow target "' + workflowName + '" is unavailable.');
|
|
381
|
+
return handle.action({
|
|
382
|
+
name: FLUE_WORKFLOW_ADMISSION_ACTION,
|
|
383
|
+
args: [{ runId, input }],
|
|
384
|
+
});
|
|
385
|
+
},
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
${userAppLoad}
|
|
389
|
+
export const flueApp = ${ctx.appEntry ? 'userApp' : 'createDefaultFlueApp()'};
|
|
390
|
+
if (!flueApp || typeof flueApp.fetch !== 'function') {
|
|
391
|
+
throw new Error('[flue] app.ts default export must expose fetch(request).');
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export function fetch(request, env) {
|
|
395
|
+
return flueApp.fetch(request, env);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
console.log('[flue] Agents: ' + ${agentNames});
|
|
399
|
+
console.log('[flue] Workflows: ' + ${workflowNames});
|
|
400
|
+
await registry.listen({
|
|
401
|
+
port: parseInt(process.env.PORT || '3000', 10),
|
|
402
|
+
application: {
|
|
403
|
+
fetch: (request) => flueApp.fetch(request),
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
`;
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=target.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"target.js","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { EventStreamStore, FlueContextInternal, RunStore } from '@flue/runtime/adapter-kit';
|
|
2
|
+
import type { WorkflowDefinition } from '@flue/runtime';
|
|
3
|
+
import { type AsyncSqlDb } from './stores/index.js';
|
|
4
|
+
export interface RivetWorkflowActorContext {
|
|
5
|
+
readonly actorId: string;
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly key: readonly string[];
|
|
8
|
+
readonly region: string;
|
|
9
|
+
readonly env?: Record<string, unknown>;
|
|
10
|
+
readonly request?: Request;
|
|
11
|
+
readonly abortSignal: AbortSignal;
|
|
12
|
+
readonly db: AsyncSqlDb;
|
|
13
|
+
keepAwake<T>(promise: Promise<T>): Promise<T>;
|
|
14
|
+
}
|
|
15
|
+
interface RivetWorkflowPreparedCoordinator {
|
|
16
|
+
readonly workflowName: string;
|
|
17
|
+
readonly runStore: RunStore;
|
|
18
|
+
}
|
|
19
|
+
export interface RivetWorkflowRuntimeOptions {
|
|
20
|
+
readonly workflows: ReadonlyArray<{
|
|
21
|
+
name: string;
|
|
22
|
+
definition: WorkflowDefinition;
|
|
23
|
+
}>;
|
|
24
|
+
readonly createContext: (options: {
|
|
25
|
+
readonly actor: RivetWorkflowActorContext;
|
|
26
|
+
readonly request?: Request;
|
|
27
|
+
readonly runId: string;
|
|
28
|
+
readonly initialEventIndex?: number;
|
|
29
|
+
readonly dispatchId?: string;
|
|
30
|
+
}) => FlueContextInternal;
|
|
31
|
+
readonly createEventStreamStore: (actor: RivetWorkflowActorContext) => EventStreamStore;
|
|
32
|
+
readonly createRegistryRunStore?: (actor: RivetWorkflowActorContext) => RunStore | undefined;
|
|
33
|
+
readonly resolveRunId?: (actor: RivetWorkflowActorContext) => string;
|
|
34
|
+
}
|
|
35
|
+
export interface RivetWorkflowRuntime {
|
|
36
|
+
prepare(options: {
|
|
37
|
+
readonly db: AsyncSqlDb;
|
|
38
|
+
readonly workflowName: string;
|
|
39
|
+
readonly actor: RivetWorkflowActorContext;
|
|
40
|
+
}): Promise<RivetWorkflowPreparedCoordinator>;
|
|
41
|
+
attach(actor: RivetWorkflowActorContext, prepared: RivetWorkflowPreparedCoordinator): RivetWorkflowCoordinator;
|
|
42
|
+
onWake(actor: RivetWorkflowActorContext, inherited?: () => Promise<unknown> | unknown): Promise<void>;
|
|
43
|
+
admitWorkflow(actor: RivetWorkflowActorContext, input: {
|
|
44
|
+
readonly runId: string;
|
|
45
|
+
readonly input: unknown;
|
|
46
|
+
}): Promise<{
|
|
47
|
+
runId: string;
|
|
48
|
+
}>;
|
|
49
|
+
onRequest(actor: RivetWorkflowActorContext, request: Request): Promise<Response | null>;
|
|
50
|
+
}
|
|
51
|
+
export declare function createRivetWorkflowRuntime(options: RivetWorkflowRuntimeOptions): RivetWorkflowRuntime;
|
|
52
|
+
export declare class RivetWorkflowCoordinator {
|
|
53
|
+
private readonly actor;
|
|
54
|
+
private readonly prepared;
|
|
55
|
+
private readonly options;
|
|
56
|
+
private readonly eventStreamStore;
|
|
57
|
+
constructor(actor: RivetWorkflowActorContext, prepared: RivetWorkflowPreparedCoordinator, options: RivetWorkflowRuntimeOptions, eventStreamStore: EventStreamStore);
|
|
58
|
+
onWake(inherited: () => Promise<unknown> | unknown): Promise<void>;
|
|
59
|
+
onRequest(request: Request): Promise<Response | null>;
|
|
60
|
+
admitWorkflow(options: {
|
|
61
|
+
readonly runId: string;
|
|
62
|
+
readonly input: unknown;
|
|
63
|
+
}): Promise<{
|
|
64
|
+
runId: string;
|
|
65
|
+
}>;
|
|
66
|
+
private get workflowName();
|
|
67
|
+
private get runId();
|
|
68
|
+
private createContext;
|
|
69
|
+
}
|
|
70
|
+
export {};
|
|
71
|
+
//# sourceMappingURL=workflow-coordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-coordinator.d.ts","sourceRoot":"","sources":["../src/workflow-coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { admitDetachedWorkflow, failRecoveredRun, handleRunRouteRequest, handleStreamHead, handleStreamRead, handleWorkflowRequest, } from '@flue/runtime/adapter-kit';
|
|
2
|
+
import { createRivetRunStore } from './run-store-composite.js';
|
|
3
|
+
import { createAsyncRunStore, ensureAsyncSqlSchema } from './stores/index.js';
|
|
4
|
+
export function createRivetWorkflowRuntime(options) {
|
|
5
|
+
const coordinators = new WeakMap();
|
|
6
|
+
const getCoordinator = (actor) => {
|
|
7
|
+
const coordinator = coordinators.get(actor);
|
|
8
|
+
if (!coordinator) {
|
|
9
|
+
throw new Error('[flue] Generated Rivet workflow coordinator was not initialized.');
|
|
10
|
+
}
|
|
11
|
+
return coordinator;
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
async prepare({ db, workflowName, actor }) {
|
|
15
|
+
await ensureAsyncSqlSchema(db);
|
|
16
|
+
const primary = createAsyncRunStore(db);
|
|
17
|
+
const mirror = options.createRegistryRunStore?.(actor);
|
|
18
|
+
return {
|
|
19
|
+
workflowName,
|
|
20
|
+
runStore: createRivetRunStore(primary, mirror),
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
attach(actor, prepared) {
|
|
24
|
+
const coordinator = new RivetWorkflowCoordinator(actor, prepared, options, options.createEventStreamStore(actor));
|
|
25
|
+
coordinators.set(actor, coordinator);
|
|
26
|
+
return coordinator;
|
|
27
|
+
},
|
|
28
|
+
onWake(actor, inherited = () => undefined) {
|
|
29
|
+
return getCoordinator(actor).onWake(inherited);
|
|
30
|
+
},
|
|
31
|
+
admitWorkflow(actor, input) {
|
|
32
|
+
return getCoordinator(actor).admitWorkflow(input);
|
|
33
|
+
},
|
|
34
|
+
onRequest(actor, request) {
|
|
35
|
+
return getCoordinator(actor).onRequest(request);
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export class RivetWorkflowCoordinator {
|
|
40
|
+
actor;
|
|
41
|
+
prepared;
|
|
42
|
+
options;
|
|
43
|
+
eventStreamStore;
|
|
44
|
+
constructor(actor, prepared, options, eventStreamStore) {
|
|
45
|
+
this.actor = actor;
|
|
46
|
+
this.prepared = prepared;
|
|
47
|
+
this.options = options;
|
|
48
|
+
this.eventStreamStore = eventStreamStore;
|
|
49
|
+
}
|
|
50
|
+
async onWake(inherited) {
|
|
51
|
+
await inherited();
|
|
52
|
+
const run = await this.prepared.runStore.getRun(this.runId);
|
|
53
|
+
if (run?.status !== 'active')
|
|
54
|
+
return;
|
|
55
|
+
await failRecoveredRun({
|
|
56
|
+
workflowName: this.workflowName,
|
|
57
|
+
runId: this.runId,
|
|
58
|
+
error: new Error('Flue workflow execution was interrupted. Start a new workflow run explicitly if retry is appropriate.'),
|
|
59
|
+
runStore: this.prepared.runStore,
|
|
60
|
+
eventStreamStore: this.eventStreamStore,
|
|
61
|
+
createContext: ({ runId, request, initialEventIndex }) => this.createContext(request, runId, initialEventIndex),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async onRequest(request) {
|
|
65
|
+
const runRoute = parseRunRoute(request);
|
|
66
|
+
if (runRoute) {
|
|
67
|
+
if (runRoute.action === 'ds-stream') {
|
|
68
|
+
const streamPath = runStreamPath(runRoute.runId);
|
|
69
|
+
if (request.method === 'HEAD')
|
|
70
|
+
return handleStreamHead(this.eventStreamStore, streamPath);
|
|
71
|
+
return handleStreamRead({ store: this.eventStreamStore, path: streamPath, request });
|
|
72
|
+
}
|
|
73
|
+
return handleRunRouteRequest({
|
|
74
|
+
workflowName: this.workflowName,
|
|
75
|
+
runId: runRoute.runId,
|
|
76
|
+
runStore: this.prepared.runStore,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (!parseWorkflowStart(request, this.workflowName))
|
|
80
|
+
return null;
|
|
81
|
+
const workflow = this.options.workflows.find((record) => record.name === this.workflowName)?.definition;
|
|
82
|
+
if (!workflow)
|
|
83
|
+
return null;
|
|
84
|
+
return handleWorkflowRequest({
|
|
85
|
+
request,
|
|
86
|
+
workflowName: this.workflowName,
|
|
87
|
+
runId: this.runId,
|
|
88
|
+
workflow,
|
|
89
|
+
runStore: this.prepared.runStore,
|
|
90
|
+
eventStreamStore: this.eventStreamStore,
|
|
91
|
+
createContext: ({ runId, request, initialEventIndex }) => this.createContext(request, runId, initialEventIndex),
|
|
92
|
+
startWorkflowAdmission: (_runId, run) => {
|
|
93
|
+
const completion = this.actor.keepAwake(Promise.resolve().then(run));
|
|
94
|
+
return { admitted: Promise.resolve(), completion };
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
async admitWorkflow(options) {
|
|
99
|
+
const workflow = this.options.workflows.find((record) => record.name === this.workflowName)?.definition;
|
|
100
|
+
if (!workflow) {
|
|
101
|
+
throw new Error(`[flue] Workflow target "${this.workflowName}" is unavailable.`);
|
|
102
|
+
}
|
|
103
|
+
return admitDetachedWorkflow({
|
|
104
|
+
workflowName: this.workflowName,
|
|
105
|
+
runId: options.runId,
|
|
106
|
+
workflow,
|
|
107
|
+
input: options.input,
|
|
108
|
+
runStore: this.prepared.runStore,
|
|
109
|
+
eventStreamStore: this.eventStreamStore,
|
|
110
|
+
createContext: ({ runId, request, initialEventIndex }) => this.createContext(request, runId, initialEventIndex),
|
|
111
|
+
startWorkflowAdmission: (_runId, run) => {
|
|
112
|
+
const completion = this.actor.keepAwake(Promise.resolve().then(run));
|
|
113
|
+
return { admitted: Promise.resolve(), completion };
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
get workflowName() {
|
|
118
|
+
return this.prepared.workflowName;
|
|
119
|
+
}
|
|
120
|
+
get runId() {
|
|
121
|
+
return this.options.resolveRunId?.(this.actor) ?? this.actor.key[0] ?? this.actor.actorId;
|
|
122
|
+
}
|
|
123
|
+
createContext(request, runId, initialEventIndex) {
|
|
124
|
+
return this.options.createContext({
|
|
125
|
+
actor: this.actor,
|
|
126
|
+
request,
|
|
127
|
+
runId,
|
|
128
|
+
initialEventIndex,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function parseWorkflowStart(request, workflowName) {
|
|
133
|
+
if (request.method !== 'POST')
|
|
134
|
+
return false;
|
|
135
|
+
const url = new URL(request.url);
|
|
136
|
+
const segments = url.pathname.split('/').filter(Boolean);
|
|
137
|
+
if (segments.length !== 2 || segments[0] !== 'workflows')
|
|
138
|
+
return false;
|
|
139
|
+
return decodeURIComponent(segments[1] ?? '') === workflowName;
|
|
140
|
+
}
|
|
141
|
+
function parseRunRoute(request) {
|
|
142
|
+
const url = new URL(request.url);
|
|
143
|
+
const segments = url.pathname.split('/').filter(Boolean);
|
|
144
|
+
if (segments.length !== 2 || segments[0] !== 'runs')
|
|
145
|
+
return null;
|
|
146
|
+
const runId = decodeURIComponent(segments[1] ?? '');
|
|
147
|
+
if (!runId)
|
|
148
|
+
return null;
|
|
149
|
+
return { action: request.method === 'GET' && url.searchParams.has('meta') ? 'meta' : 'ds-stream', runId };
|
|
150
|
+
}
|
|
151
|
+
function runStreamPath(runId) {
|
|
152
|
+
return `runs/${runId}`;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=workflow-coordinator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-coordinator.js","sourceRoot":"","sources":["../src/workflow-coordinator.ts"],"names":[],"mappings":"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"}
|