@tomflow/proflow-agent-gateway 0.1.0
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/README.md +5 -0
- package/conformance.json +1 -0
- package/dist/deployment/adapter.d.ts +452 -0
- package/dist/deployment/adapter.js +240 -0
- package/dist/deployment/descriptor.d.ts +77 -0
- package/dist/deployment/descriptor.js +88 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +51 -0
- package/dist/src/index.d.ts +99 -0
- package/dist/src/index.js +430 -0
- package/dist/src/process.d.ts +70 -0
- package/dist/src/process.js +193 -0
- package/package.json +61 -0
- package/proflow.module.json +106 -0
package/README.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# @tomflow/proflow-agent-gateway
|
|
2
|
+
|
|
3
|
+
The sole Custom GPT Actions HTTP ingress and OpenAI transport anti-corruption layer.
|
|
4
|
+
|
|
5
|
+
It authenticates role-scoped credentials, validates typed body/path/query identity, routes business-purpose Actions to owner contracts, and normalizes File Bridge transport. It is stateless with respect to Worker Turns and owns no Task/Execution/Artifact/File business store. Product GPT-facing New Task `createTask/listRegisteredRoles/getRegisteredRole` is not part of the v1 main Action surface; New Task is Extension-first.
|
package/conformance.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "contract": "proflow.conformance.v1", "levels": ["C1", "C2", "C3"] }
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
type GatewayProcess = {
|
|
2
|
+
start(): Promise<{
|
|
3
|
+
host: string;
|
|
4
|
+
port: number;
|
|
5
|
+
}>;
|
|
6
|
+
stop(): Promise<void>;
|
|
7
|
+
restart(): Promise<{
|
|
8
|
+
host: string;
|
|
9
|
+
port: number;
|
|
10
|
+
}>;
|
|
11
|
+
readiness(): Promise<{
|
|
12
|
+
status: "READY" | "NOT_READY";
|
|
13
|
+
}>;
|
|
14
|
+
status(): unknown;
|
|
15
|
+
};
|
|
16
|
+
export declare function createBehaviorAdapter(service?: GatewayProcess): {
|
|
17
|
+
describe: () => {
|
|
18
|
+
result: {
|
|
19
|
+
readonly contract: "deployment.result.v1";
|
|
20
|
+
readonly ok: true;
|
|
21
|
+
readonly status: "SUCCEEDED";
|
|
22
|
+
readonly moduleRef: "agent-gateway";
|
|
23
|
+
readonly moduleVersion: "0.1.0";
|
|
24
|
+
};
|
|
25
|
+
observedEffects: never[];
|
|
26
|
+
};
|
|
27
|
+
preflight: () => {
|
|
28
|
+
result: {
|
|
29
|
+
readonly contract: "deployment.result.v1";
|
|
30
|
+
readonly ok: true;
|
|
31
|
+
readonly status: "SUCCEEDED";
|
|
32
|
+
readonly moduleRef: "agent-gateway";
|
|
33
|
+
readonly moduleVersion: "0.1.0";
|
|
34
|
+
};
|
|
35
|
+
observedEffects: never[];
|
|
36
|
+
};
|
|
37
|
+
status: () => Promise<{
|
|
38
|
+
result: {
|
|
39
|
+
readonly contract: "deployment.result.v1";
|
|
40
|
+
readonly moduleRef: "agent-gateway";
|
|
41
|
+
readonly moduleVersion: "0.1.0";
|
|
42
|
+
readonly ok: false;
|
|
43
|
+
readonly status: "ACTION_REQUIRED";
|
|
44
|
+
readonly actionRequired: {
|
|
45
|
+
readonly action: "compose-gateway";
|
|
46
|
+
readonly description: "Provide owner ports and process configuration";
|
|
47
|
+
};
|
|
48
|
+
} | {
|
|
49
|
+
contract: "deployment.result.v1";
|
|
50
|
+
ok: true;
|
|
51
|
+
status: "SUCCEEDED";
|
|
52
|
+
moduleRef: "agent-gateway";
|
|
53
|
+
moduleVersion: "0.1.0";
|
|
54
|
+
data: unknown;
|
|
55
|
+
checks: {
|
|
56
|
+
id: string;
|
|
57
|
+
status: "FAIL" | "PASS";
|
|
58
|
+
message: string;
|
|
59
|
+
}[];
|
|
60
|
+
} | {
|
|
61
|
+
contract: "deployment.result.v1";
|
|
62
|
+
moduleRef: "agent-gateway";
|
|
63
|
+
moduleVersion: "0.1.0";
|
|
64
|
+
ok: false;
|
|
65
|
+
status: "ACTION_REQUIRED";
|
|
66
|
+
actionRequired: {
|
|
67
|
+
action: string;
|
|
68
|
+
description: string;
|
|
69
|
+
};
|
|
70
|
+
data: unknown;
|
|
71
|
+
checks: {
|
|
72
|
+
id: string;
|
|
73
|
+
status: "FAIL" | "PASS";
|
|
74
|
+
message: string;
|
|
75
|
+
}[];
|
|
76
|
+
};
|
|
77
|
+
observedEffects: never[];
|
|
78
|
+
}>;
|
|
79
|
+
verify: () => Promise<{
|
|
80
|
+
result: {
|
|
81
|
+
contract: "deployment.result.v1";
|
|
82
|
+
ok: true;
|
|
83
|
+
status: "SUCCEEDED";
|
|
84
|
+
moduleRef: "agent-gateway";
|
|
85
|
+
moduleVersion: "0.1.0";
|
|
86
|
+
checks: {
|
|
87
|
+
id: string;
|
|
88
|
+
status: "FAIL" | "PASS";
|
|
89
|
+
message: string;
|
|
90
|
+
}[];
|
|
91
|
+
} | {
|
|
92
|
+
contract: "deployment.result.v1";
|
|
93
|
+
moduleRef: "agent-gateway";
|
|
94
|
+
moduleVersion: "0.1.0";
|
|
95
|
+
ok: false;
|
|
96
|
+
status: "ACTION_REQUIRED";
|
|
97
|
+
actionRequired: {
|
|
98
|
+
readonly action: "compose-gateway";
|
|
99
|
+
readonly description: "Provide owner ports and process configuration";
|
|
100
|
+
};
|
|
101
|
+
checks: {
|
|
102
|
+
id: string;
|
|
103
|
+
status: "FAIL" | "PASS";
|
|
104
|
+
message: string;
|
|
105
|
+
}[];
|
|
106
|
+
} | {
|
|
107
|
+
contract: "deployment.result.v1";
|
|
108
|
+
moduleRef: "agent-gateway";
|
|
109
|
+
moduleVersion: "0.1.0";
|
|
110
|
+
ok: false;
|
|
111
|
+
status: "ACTION_REQUIRED";
|
|
112
|
+
actionRequired: {
|
|
113
|
+
action: string;
|
|
114
|
+
description: string;
|
|
115
|
+
};
|
|
116
|
+
checks: {
|
|
117
|
+
id: string;
|
|
118
|
+
status: "FAIL" | "PASS";
|
|
119
|
+
message: string;
|
|
120
|
+
}[];
|
|
121
|
+
};
|
|
122
|
+
observedEffects: never[];
|
|
123
|
+
}>;
|
|
124
|
+
doctor: () => {
|
|
125
|
+
result: {
|
|
126
|
+
readonly contract: "deployment.result.v1";
|
|
127
|
+
readonly ok: true;
|
|
128
|
+
readonly status: "SUCCEEDED";
|
|
129
|
+
readonly moduleRef: "agent-gateway";
|
|
130
|
+
readonly moduleVersion: "0.1.0";
|
|
131
|
+
};
|
|
132
|
+
observedEffects: never[];
|
|
133
|
+
};
|
|
134
|
+
start: () => Promise<{
|
|
135
|
+
result: {
|
|
136
|
+
contract: "deployment.result.v1";
|
|
137
|
+
ok: true;
|
|
138
|
+
status: "SUCCEEDED";
|
|
139
|
+
moduleRef: "agent-gateway";
|
|
140
|
+
moduleVersion: "0.1.0";
|
|
141
|
+
data: {
|
|
142
|
+
host: string;
|
|
143
|
+
port: number;
|
|
144
|
+
};
|
|
145
|
+
} | {
|
|
146
|
+
contract: "deployment.result.v1";
|
|
147
|
+
moduleRef: "agent-gateway";
|
|
148
|
+
moduleVersion: "0.1.0";
|
|
149
|
+
status: "ACTION_REQUIRED";
|
|
150
|
+
ok: boolean;
|
|
151
|
+
actionRequired: {
|
|
152
|
+
action: string;
|
|
153
|
+
description: string;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
observedEffects: string[];
|
|
157
|
+
}>;
|
|
158
|
+
stop: () => Promise<{
|
|
159
|
+
result: {
|
|
160
|
+
readonly contract: "deployment.result.v1";
|
|
161
|
+
readonly ok: true;
|
|
162
|
+
readonly status: "SUCCEEDED";
|
|
163
|
+
readonly moduleRef: "agent-gateway";
|
|
164
|
+
readonly moduleVersion: "0.1.0";
|
|
165
|
+
} | {
|
|
166
|
+
readonly contract: "deployment.result.v1";
|
|
167
|
+
readonly moduleRef: "agent-gateway";
|
|
168
|
+
readonly moduleVersion: "0.1.0";
|
|
169
|
+
readonly ok: false;
|
|
170
|
+
readonly status: "ACTION_REQUIRED";
|
|
171
|
+
readonly actionRequired: {
|
|
172
|
+
readonly action: "compose-gateway";
|
|
173
|
+
readonly description: "Provide owner ports and process configuration";
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
observedEffects: string[];
|
|
177
|
+
}>;
|
|
178
|
+
uninstall: () => Promise<{
|
|
179
|
+
result: {
|
|
180
|
+
readonly contract: "deployment.result.v1";
|
|
181
|
+
readonly ok: true;
|
|
182
|
+
readonly status: "SUCCEEDED";
|
|
183
|
+
readonly moduleRef: "agent-gateway";
|
|
184
|
+
readonly moduleVersion: "0.1.0";
|
|
185
|
+
} | {
|
|
186
|
+
readonly contract: "deployment.result.v1";
|
|
187
|
+
readonly moduleRef: "agent-gateway";
|
|
188
|
+
readonly moduleVersion: "0.1.0";
|
|
189
|
+
readonly ok: false;
|
|
190
|
+
readonly status: "ACTION_REQUIRED";
|
|
191
|
+
readonly actionRequired: {
|
|
192
|
+
readonly action: "compose-gateway";
|
|
193
|
+
readonly description: "Provide owner ports and process configuration";
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
observedEffects: string[];
|
|
197
|
+
}>;
|
|
198
|
+
restart: () => Promise<{
|
|
199
|
+
result: {
|
|
200
|
+
contract: "deployment.result.v1";
|
|
201
|
+
ok: true;
|
|
202
|
+
status: "SUCCEEDED";
|
|
203
|
+
moduleRef: "agent-gateway";
|
|
204
|
+
moduleVersion: "0.1.0";
|
|
205
|
+
data: {
|
|
206
|
+
host: string;
|
|
207
|
+
port: number;
|
|
208
|
+
};
|
|
209
|
+
} | {
|
|
210
|
+
contract: "deployment.result.v1";
|
|
211
|
+
moduleRef: "agent-gateway";
|
|
212
|
+
moduleVersion: "0.1.0";
|
|
213
|
+
status: "ACTION_REQUIRED";
|
|
214
|
+
ok: boolean;
|
|
215
|
+
actionRequired: {
|
|
216
|
+
action: string;
|
|
217
|
+
description: string;
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
observedEffects: string[];
|
|
221
|
+
}>;
|
|
222
|
+
};
|
|
223
|
+
export declare const behaviorAdapter: {
|
|
224
|
+
describe: () => {
|
|
225
|
+
result: {
|
|
226
|
+
readonly contract: "deployment.result.v1";
|
|
227
|
+
readonly ok: true;
|
|
228
|
+
readonly status: "SUCCEEDED";
|
|
229
|
+
readonly moduleRef: "agent-gateway";
|
|
230
|
+
readonly moduleVersion: "0.1.0";
|
|
231
|
+
};
|
|
232
|
+
observedEffects: never[];
|
|
233
|
+
};
|
|
234
|
+
preflight: () => {
|
|
235
|
+
result: {
|
|
236
|
+
readonly contract: "deployment.result.v1";
|
|
237
|
+
readonly ok: true;
|
|
238
|
+
readonly status: "SUCCEEDED";
|
|
239
|
+
readonly moduleRef: "agent-gateway";
|
|
240
|
+
readonly moduleVersion: "0.1.0";
|
|
241
|
+
};
|
|
242
|
+
observedEffects: never[];
|
|
243
|
+
};
|
|
244
|
+
status: () => Promise<{
|
|
245
|
+
result: {
|
|
246
|
+
readonly contract: "deployment.result.v1";
|
|
247
|
+
readonly moduleRef: "agent-gateway";
|
|
248
|
+
readonly moduleVersion: "0.1.0";
|
|
249
|
+
readonly ok: false;
|
|
250
|
+
readonly status: "ACTION_REQUIRED";
|
|
251
|
+
readonly actionRequired: {
|
|
252
|
+
readonly action: "compose-gateway";
|
|
253
|
+
readonly description: "Provide owner ports and process configuration";
|
|
254
|
+
};
|
|
255
|
+
} | {
|
|
256
|
+
contract: "deployment.result.v1";
|
|
257
|
+
ok: true;
|
|
258
|
+
status: "SUCCEEDED";
|
|
259
|
+
moduleRef: "agent-gateway";
|
|
260
|
+
moduleVersion: "0.1.0";
|
|
261
|
+
data: unknown;
|
|
262
|
+
checks: {
|
|
263
|
+
id: string;
|
|
264
|
+
status: "FAIL" | "PASS";
|
|
265
|
+
message: string;
|
|
266
|
+
}[];
|
|
267
|
+
} | {
|
|
268
|
+
contract: "deployment.result.v1";
|
|
269
|
+
moduleRef: "agent-gateway";
|
|
270
|
+
moduleVersion: "0.1.0";
|
|
271
|
+
ok: false;
|
|
272
|
+
status: "ACTION_REQUIRED";
|
|
273
|
+
actionRequired: {
|
|
274
|
+
action: string;
|
|
275
|
+
description: string;
|
|
276
|
+
};
|
|
277
|
+
data: unknown;
|
|
278
|
+
checks: {
|
|
279
|
+
id: string;
|
|
280
|
+
status: "FAIL" | "PASS";
|
|
281
|
+
message: string;
|
|
282
|
+
}[];
|
|
283
|
+
};
|
|
284
|
+
observedEffects: never[];
|
|
285
|
+
}>;
|
|
286
|
+
verify: () => Promise<{
|
|
287
|
+
result: {
|
|
288
|
+
contract: "deployment.result.v1";
|
|
289
|
+
ok: true;
|
|
290
|
+
status: "SUCCEEDED";
|
|
291
|
+
moduleRef: "agent-gateway";
|
|
292
|
+
moduleVersion: "0.1.0";
|
|
293
|
+
checks: {
|
|
294
|
+
id: string;
|
|
295
|
+
status: "FAIL" | "PASS";
|
|
296
|
+
message: string;
|
|
297
|
+
}[];
|
|
298
|
+
} | {
|
|
299
|
+
contract: "deployment.result.v1";
|
|
300
|
+
moduleRef: "agent-gateway";
|
|
301
|
+
moduleVersion: "0.1.0";
|
|
302
|
+
ok: false;
|
|
303
|
+
status: "ACTION_REQUIRED";
|
|
304
|
+
actionRequired: {
|
|
305
|
+
readonly action: "compose-gateway";
|
|
306
|
+
readonly description: "Provide owner ports and process configuration";
|
|
307
|
+
};
|
|
308
|
+
checks: {
|
|
309
|
+
id: string;
|
|
310
|
+
status: "FAIL" | "PASS";
|
|
311
|
+
message: string;
|
|
312
|
+
}[];
|
|
313
|
+
} | {
|
|
314
|
+
contract: "deployment.result.v1";
|
|
315
|
+
moduleRef: "agent-gateway";
|
|
316
|
+
moduleVersion: "0.1.0";
|
|
317
|
+
ok: false;
|
|
318
|
+
status: "ACTION_REQUIRED";
|
|
319
|
+
actionRequired: {
|
|
320
|
+
action: string;
|
|
321
|
+
description: string;
|
|
322
|
+
};
|
|
323
|
+
checks: {
|
|
324
|
+
id: string;
|
|
325
|
+
status: "FAIL" | "PASS";
|
|
326
|
+
message: string;
|
|
327
|
+
}[];
|
|
328
|
+
};
|
|
329
|
+
observedEffects: never[];
|
|
330
|
+
}>;
|
|
331
|
+
doctor: () => {
|
|
332
|
+
result: {
|
|
333
|
+
readonly contract: "deployment.result.v1";
|
|
334
|
+
readonly ok: true;
|
|
335
|
+
readonly status: "SUCCEEDED";
|
|
336
|
+
readonly moduleRef: "agent-gateway";
|
|
337
|
+
readonly moduleVersion: "0.1.0";
|
|
338
|
+
};
|
|
339
|
+
observedEffects: never[];
|
|
340
|
+
};
|
|
341
|
+
start: () => Promise<{
|
|
342
|
+
result: {
|
|
343
|
+
contract: "deployment.result.v1";
|
|
344
|
+
ok: true;
|
|
345
|
+
status: "SUCCEEDED";
|
|
346
|
+
moduleRef: "agent-gateway";
|
|
347
|
+
moduleVersion: "0.1.0";
|
|
348
|
+
data: {
|
|
349
|
+
host: string;
|
|
350
|
+
port: number;
|
|
351
|
+
};
|
|
352
|
+
} | {
|
|
353
|
+
contract: "deployment.result.v1";
|
|
354
|
+
moduleRef: "agent-gateway";
|
|
355
|
+
moduleVersion: "0.1.0";
|
|
356
|
+
status: "ACTION_REQUIRED";
|
|
357
|
+
ok: boolean;
|
|
358
|
+
actionRequired: {
|
|
359
|
+
action: string;
|
|
360
|
+
description: string;
|
|
361
|
+
};
|
|
362
|
+
};
|
|
363
|
+
observedEffects: string[];
|
|
364
|
+
}>;
|
|
365
|
+
stop: () => Promise<{
|
|
366
|
+
result: {
|
|
367
|
+
readonly contract: "deployment.result.v1";
|
|
368
|
+
readonly ok: true;
|
|
369
|
+
readonly status: "SUCCEEDED";
|
|
370
|
+
readonly moduleRef: "agent-gateway";
|
|
371
|
+
readonly moduleVersion: "0.1.0";
|
|
372
|
+
} | {
|
|
373
|
+
readonly contract: "deployment.result.v1";
|
|
374
|
+
readonly moduleRef: "agent-gateway";
|
|
375
|
+
readonly moduleVersion: "0.1.0";
|
|
376
|
+
readonly ok: false;
|
|
377
|
+
readonly status: "ACTION_REQUIRED";
|
|
378
|
+
readonly actionRequired: {
|
|
379
|
+
readonly action: "compose-gateway";
|
|
380
|
+
readonly description: "Provide owner ports and process configuration";
|
|
381
|
+
};
|
|
382
|
+
};
|
|
383
|
+
observedEffects: string[];
|
|
384
|
+
}>;
|
|
385
|
+
uninstall: () => Promise<{
|
|
386
|
+
result: {
|
|
387
|
+
readonly contract: "deployment.result.v1";
|
|
388
|
+
readonly ok: true;
|
|
389
|
+
readonly status: "SUCCEEDED";
|
|
390
|
+
readonly moduleRef: "agent-gateway";
|
|
391
|
+
readonly moduleVersion: "0.1.0";
|
|
392
|
+
} | {
|
|
393
|
+
readonly contract: "deployment.result.v1";
|
|
394
|
+
readonly moduleRef: "agent-gateway";
|
|
395
|
+
readonly moduleVersion: "0.1.0";
|
|
396
|
+
readonly ok: false;
|
|
397
|
+
readonly status: "ACTION_REQUIRED";
|
|
398
|
+
readonly actionRequired: {
|
|
399
|
+
readonly action: "compose-gateway";
|
|
400
|
+
readonly description: "Provide owner ports and process configuration";
|
|
401
|
+
};
|
|
402
|
+
};
|
|
403
|
+
observedEffects: string[];
|
|
404
|
+
}>;
|
|
405
|
+
restart: () => Promise<{
|
|
406
|
+
result: {
|
|
407
|
+
contract: "deployment.result.v1";
|
|
408
|
+
ok: true;
|
|
409
|
+
status: "SUCCEEDED";
|
|
410
|
+
moduleRef: "agent-gateway";
|
|
411
|
+
moduleVersion: "0.1.0";
|
|
412
|
+
data: {
|
|
413
|
+
host: string;
|
|
414
|
+
port: number;
|
|
415
|
+
};
|
|
416
|
+
} | {
|
|
417
|
+
contract: "deployment.result.v1";
|
|
418
|
+
moduleRef: "agent-gateway";
|
|
419
|
+
moduleVersion: "0.1.0";
|
|
420
|
+
status: "ACTION_REQUIRED";
|
|
421
|
+
ok: boolean;
|
|
422
|
+
actionRequired: {
|
|
423
|
+
action: string;
|
|
424
|
+
description: string;
|
|
425
|
+
};
|
|
426
|
+
};
|
|
427
|
+
observedEffects: string[];
|
|
428
|
+
}>;
|
|
429
|
+
};
|
|
430
|
+
export declare function createServiceProcessBinding(input: {
|
|
431
|
+
moduleRef: string;
|
|
432
|
+
config: Record<string, string>;
|
|
433
|
+
workspaceRoot: string;
|
|
434
|
+
configByModuleRef: ReadonlyMap<string, Record<string, string>>;
|
|
435
|
+
}): Promise<{
|
|
436
|
+
serviceProcess: {
|
|
437
|
+
contract: "deployment.service-process.v1";
|
|
438
|
+
bin: "proflow-agent-gateway";
|
|
439
|
+
startCommand: "start";
|
|
440
|
+
config: Record<string, unknown>;
|
|
441
|
+
};
|
|
442
|
+
behaviorAdapter: Record<string, unknown>;
|
|
443
|
+
} | undefined>;
|
|
444
|
+
export declare function createProductionBinding(input: {
|
|
445
|
+
moduleRef: string;
|
|
446
|
+
config: Record<string, string>;
|
|
447
|
+
workspaceRoot: string;
|
|
448
|
+
configByModuleRef: ReadonlyMap<string, Record<string, string>>;
|
|
449
|
+
}): Promise<{
|
|
450
|
+
behaviorAdapter: Record<string, unknown>;
|
|
451
|
+
} | undefined>;
|
|
452
|
+
export {};
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { descriptor } from "./descriptor.js";
|
|
2
|
+
const base = {
|
|
3
|
+
contract: "deployment.result.v1",
|
|
4
|
+
ok: true,
|
|
5
|
+
status: "SUCCEEDED",
|
|
6
|
+
moduleRef: descriptor.moduleRef,
|
|
7
|
+
moduleVersion: descriptor.moduleVersion,
|
|
8
|
+
};
|
|
9
|
+
const unbound = {
|
|
10
|
+
...base,
|
|
11
|
+
ok: false,
|
|
12
|
+
status: "ACTION_REQUIRED",
|
|
13
|
+
actionRequired: {
|
|
14
|
+
action: "compose-gateway",
|
|
15
|
+
description: "Provide owner ports and process configuration",
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
export function createBehaviorAdapter(service) {
|
|
19
|
+
return {
|
|
20
|
+
describe: () => ({ result: base, observedEffects: [] }),
|
|
21
|
+
preflight: () => ({ result: base, observedEffects: [] }),
|
|
22
|
+
status: async () => {
|
|
23
|
+
const processStatus = service?.status();
|
|
24
|
+
const readiness = service ? await service.readiness() : undefined;
|
|
25
|
+
const ready = readiness?.status === "READY";
|
|
26
|
+
return {
|
|
27
|
+
result: service
|
|
28
|
+
? {
|
|
29
|
+
...(ready
|
|
30
|
+
? base
|
|
31
|
+
: {
|
|
32
|
+
...base,
|
|
33
|
+
ok: false,
|
|
34
|
+
status: "ACTION_REQUIRED",
|
|
35
|
+
actionRequired: {
|
|
36
|
+
action: "repair-gateway",
|
|
37
|
+
description: "Gateway is not READY",
|
|
38
|
+
},
|
|
39
|
+
}),
|
|
40
|
+
data: processStatus,
|
|
41
|
+
checks: [
|
|
42
|
+
{
|
|
43
|
+
id: "gateway-readiness",
|
|
44
|
+
status: ready ? "PASS" : "FAIL",
|
|
45
|
+
message: `Gateway readiness is ${readiness?.status ?? "NOT_READY"}`,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
}
|
|
49
|
+
: unbound,
|
|
50
|
+
observedEffects: [],
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
verify: async () => {
|
|
54
|
+
const readiness = service ? await service.readiness() : undefined;
|
|
55
|
+
const ready = readiness?.status === "READY";
|
|
56
|
+
return {
|
|
57
|
+
result: {
|
|
58
|
+
...(service && ready
|
|
59
|
+
? base
|
|
60
|
+
: service
|
|
61
|
+
? {
|
|
62
|
+
...base,
|
|
63
|
+
ok: false,
|
|
64
|
+
status: "ACTION_REQUIRED",
|
|
65
|
+
actionRequired: {
|
|
66
|
+
action: "repair-gateway",
|
|
67
|
+
description: "Gateway is not READY",
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
: unbound),
|
|
71
|
+
checks: [
|
|
72
|
+
{
|
|
73
|
+
id: "gateway-readiness",
|
|
74
|
+
status: ready ? "PASS" : "FAIL",
|
|
75
|
+
message: service
|
|
76
|
+
? `Gateway readiness is ${readiness?.status ?? "NOT_READY"}`
|
|
77
|
+
: "No configured Gateway process is bound",
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
observedEffects: [],
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
doctor: () => ({ result: base, observedEffects: [] }),
|
|
85
|
+
start: async () => ({
|
|
86
|
+
result: {
|
|
87
|
+
...base,
|
|
88
|
+
...(service
|
|
89
|
+
? { data: await service.start() }
|
|
90
|
+
: {
|
|
91
|
+
status: "ACTION_REQUIRED",
|
|
92
|
+
ok: false,
|
|
93
|
+
actionRequired: {
|
|
94
|
+
action: "compose-gateway",
|
|
95
|
+
description: "Provide owner ports before starting Gateway",
|
|
96
|
+
},
|
|
97
|
+
}),
|
|
98
|
+
},
|
|
99
|
+
observedEffects: service ? ["Manage the declared service process"] : [],
|
|
100
|
+
}),
|
|
101
|
+
stop: async () => {
|
|
102
|
+
if (service)
|
|
103
|
+
await service.stop();
|
|
104
|
+
return {
|
|
105
|
+
result: service ? base : unbound,
|
|
106
|
+
observedEffects: service ? ["Manage the declared service process"] : [],
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
uninstall: async () => {
|
|
110
|
+
if (service)
|
|
111
|
+
await service.stop();
|
|
112
|
+
return {
|
|
113
|
+
result: service ? base : unbound,
|
|
114
|
+
observedEffects: service ? ["Manage the declared service process"] : [],
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
restart: async () => ({
|
|
118
|
+
result: {
|
|
119
|
+
...base,
|
|
120
|
+
...(service
|
|
121
|
+
? { data: await service.restart() }
|
|
122
|
+
: {
|
|
123
|
+
status: "ACTION_REQUIRED",
|
|
124
|
+
ok: false,
|
|
125
|
+
actionRequired: {
|
|
126
|
+
action: "compose-gateway",
|
|
127
|
+
description: "Provide owner ports before restarting Gateway",
|
|
128
|
+
},
|
|
129
|
+
}),
|
|
130
|
+
},
|
|
131
|
+
observedEffects: service ? ["Manage the declared service process"] : [],
|
|
132
|
+
}),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
export const behaviorAdapter = createBehaviorAdapter();
|
|
136
|
+
export async function createServiceProcessBinding(input) {
|
|
137
|
+
const localBaseUrl = input.config.localBaseUrl;
|
|
138
|
+
const publicBaseUrl = input.config.publicBaseUrl;
|
|
139
|
+
const downstreamCredentialFile = input.config.downstreamCredentialFile;
|
|
140
|
+
const platformHost = input.configByModuleRef.get("platform-host");
|
|
141
|
+
const executionRuntime = input.configByModuleRef.get("execution-runtime");
|
|
142
|
+
const stateRoot = platformHost?.stateRoot;
|
|
143
|
+
const downstreamBaseUrl = executionRuntime?.["identity.endpoint"];
|
|
144
|
+
if (!localBaseUrl ||
|
|
145
|
+
!publicBaseUrl ||
|
|
146
|
+
!downstreamCredentialFile ||
|
|
147
|
+
!stateRoot ||
|
|
148
|
+
!downstreamBaseUrl) {
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
const listener = new URL(localBaseUrl);
|
|
152
|
+
if (listener.protocol !== "http:" ||
|
|
153
|
+
!new Set(["127.0.0.1", "localhost", "::1", "[::1]"]).has(listener.hostname) ||
|
|
154
|
+
listener.pathname !== "/")
|
|
155
|
+
return undefined;
|
|
156
|
+
const port = listener.port === "" ? 80 : Number(listener.port);
|
|
157
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65_535)
|
|
158
|
+
return undefined;
|
|
159
|
+
const [{ join }, { parseAgentGatewayProcessConfig }] = await Promise.all([
|
|
160
|
+
import("node:path"),
|
|
161
|
+
import("../src/process.js"),
|
|
162
|
+
]);
|
|
163
|
+
const processConfig = parseAgentGatewayProcessConfig({
|
|
164
|
+
host: listener.hostname,
|
|
165
|
+
port,
|
|
166
|
+
publicBaseUrl,
|
|
167
|
+
downstreamBaseUrl,
|
|
168
|
+
credentialFile: join(stateRoot, "agent", "secrets", "role-credentials.json"),
|
|
169
|
+
downstreamCredentialFile,
|
|
170
|
+
});
|
|
171
|
+
const probeService = {
|
|
172
|
+
async start() {
|
|
173
|
+
throw new Error("managed by Platform CLI service supervisor");
|
|
174
|
+
},
|
|
175
|
+
async stop() { },
|
|
176
|
+
async restart() {
|
|
177
|
+
throw new Error("managed by Platform CLI service supervisor");
|
|
178
|
+
},
|
|
179
|
+
async readiness() {
|
|
180
|
+
try {
|
|
181
|
+
const response = await fetch(new URL("/ready", listener));
|
|
182
|
+
return {
|
|
183
|
+
status: response.ok ? "READY" : "NOT_READY",
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return { status: "NOT_READY" };
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
status: () => ({
|
|
191
|
+
endpoint: listener.href.replace(/\/$/, ""),
|
|
192
|
+
managed: true,
|
|
193
|
+
}),
|
|
194
|
+
};
|
|
195
|
+
return {
|
|
196
|
+
serviceProcess: {
|
|
197
|
+
contract: "deployment.service-process.v1",
|
|
198
|
+
bin: "proflow-agent-gateway",
|
|
199
|
+
startCommand: "start",
|
|
200
|
+
config: processConfig,
|
|
201
|
+
},
|
|
202
|
+
behaviorAdapter: createBehaviorAdapter(probeService),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
export async function createProductionBinding(input) {
|
|
206
|
+
const localBaseUrl = input.config.localBaseUrl;
|
|
207
|
+
const publicBaseUrl = input.config.publicBaseUrl;
|
|
208
|
+
const downstreamCredentialFile = input.config.downstreamCredentialFile;
|
|
209
|
+
const platformHost = input.configByModuleRef.get("platform-host");
|
|
210
|
+
const executionRuntime = input.configByModuleRef.get("execution-runtime");
|
|
211
|
+
const stateRoot = platformHost?.stateRoot;
|
|
212
|
+
const downstreamBaseUrl = executionRuntime?.["identity.endpoint"];
|
|
213
|
+
if (!localBaseUrl ||
|
|
214
|
+
!publicBaseUrl ||
|
|
215
|
+
!downstreamCredentialFile ||
|
|
216
|
+
!stateRoot ||
|
|
217
|
+
!downstreamBaseUrl) {
|
|
218
|
+
return undefined;
|
|
219
|
+
}
|
|
220
|
+
const listener = new URL(localBaseUrl);
|
|
221
|
+
if (listener.protocol !== "http:" ||
|
|
222
|
+
!new Set(["127.0.0.1", "localhost", "::1", "[::1]"]).has(listener.hostname) ||
|
|
223
|
+
listener.pathname !== "/")
|
|
224
|
+
return undefined;
|
|
225
|
+
const port = listener.port === "" ? 80 : Number(listener.port);
|
|
226
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65_535)
|
|
227
|
+
return undefined;
|
|
228
|
+
const [{ join }, { createAgentGatewayProcess, parseAgentGatewayProcessConfig },] = await Promise.all([import("node:path"), import("../src/process.js")]);
|
|
229
|
+
const service = await createAgentGatewayProcess({
|
|
230
|
+
config: parseAgentGatewayProcessConfig({
|
|
231
|
+
host: listener.hostname,
|
|
232
|
+
port,
|
|
233
|
+
publicBaseUrl,
|
|
234
|
+
downstreamBaseUrl,
|
|
235
|
+
credentialFile: join(stateRoot, "agent", "secrets", "role-credentials.json"),
|
|
236
|
+
downstreamCredentialFile,
|
|
237
|
+
}),
|
|
238
|
+
});
|
|
239
|
+
return { behaviorAdapter: createBehaviorAdapter(service) };
|
|
240
|
+
}
|