@wopr-network/defcon 1.15.0 → 1.16.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/dist/src/api/wire-types.d.ts +3 -6
- package/dist/src/config/seed-loader.js +1 -0
- package/dist/src/config/zod-schemas.d.ts +2 -0
- package/dist/src/config/zod-schemas.js +2 -0
- package/dist/src/engine/engine.d.ts +2 -2
- package/dist/src/engine/engine.js +4 -10
- package/dist/src/execution/handlers/flow.js +13 -8
- package/dist/src/repositories/drizzle/flow.repo.js +5 -0
- package/dist/src/repositories/drizzle/schema.d.ts +17 -0
- package/dist/src/repositories/drizzle/schema.js +2 -0
- package/dist/src/repositories/interfaces.d.ts +3 -0
- package/drizzle/0019_same_rhodey.sql +1 -0
- package/drizzle/meta/0019_snapshot.json +1358 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
|
@@ -7,15 +7,12 @@ export type ClaimResponse = {
|
|
|
7
7
|
retry_after_ms: number;
|
|
8
8
|
message: string;
|
|
9
9
|
} | {
|
|
10
|
-
worker_id?: string;
|
|
11
10
|
entity_id: string;
|
|
12
11
|
invocation_id: string;
|
|
13
12
|
flow: string | null;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
context: Record<string, unknown> | null;
|
|
18
|
-
worker_notice?: string;
|
|
13
|
+
state: string;
|
|
14
|
+
refs: Record<string, unknown> | null;
|
|
15
|
+
artifacts: Record<string, unknown> | null;
|
|
19
16
|
};
|
|
20
17
|
export type ReportResponse = {
|
|
21
18
|
next_action: "continue";
|
|
@@ -45,6 +45,7 @@ export declare const StateDefinitionSchema: z.ZodObject<{
|
|
|
45
45
|
timeout_ms: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
46
46
|
}, z.core.$strip>>;
|
|
47
47
|
retryAfterMs: z.ZodOptional<z.ZodNumber>;
|
|
48
|
+
meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
48
49
|
}, z.core.$strip>;
|
|
49
50
|
export declare const CommandGateSchema: z.ZodObject<{
|
|
50
51
|
name: z.ZodString;
|
|
@@ -165,6 +166,7 @@ export declare const SeedFileSchema: z.ZodObject<{
|
|
|
165
166
|
timeout_ms: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
166
167
|
}, z.core.$strip>>;
|
|
167
168
|
retryAfterMs: z.ZodOptional<z.ZodNumber>;
|
|
169
|
+
meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
168
170
|
}, z.core.$strip>>;
|
|
169
171
|
gates: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
170
172
|
name: z.ZodString;
|
|
@@ -60,6 +60,8 @@ export const StateDefinitionSchema = z.object({
|
|
|
60
60
|
onEnter: OnEnterSchema.optional(),
|
|
61
61
|
onExit: OnExitSchema.optional(),
|
|
62
62
|
retryAfterMs: z.number().int().min(0).optional(),
|
|
63
|
+
/** Opaque metadata passed through to consumers (e.g. radar). Defcon stores but does not interpret. */
|
|
64
|
+
meta: z.record(z.string(), z.unknown()).optional(),
|
|
63
65
|
});
|
|
64
66
|
// Gate: discriminated union on `type`
|
|
65
67
|
const GateOutcomeSchema = z.object({
|
|
@@ -21,8 +21,8 @@ export interface ClaimWorkResult {
|
|
|
21
21
|
invocationId: string;
|
|
22
22
|
flowName: string;
|
|
23
23
|
stage: string;
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
refs: Record<string, unknown> | null;
|
|
25
|
+
artifacts: Record<string, unknown> | null;
|
|
26
26
|
}
|
|
27
27
|
export interface EngineStatus {
|
|
28
28
|
flows: Record<string, Record<string, number>>;
|
|
@@ -579,12 +579,6 @@ export class Engine {
|
|
|
579
579
|
this.logger.warn(`[engine] setAffinity failed for entity ${claimed.id} worker ${worker_id} — continuing:`, err);
|
|
580
580
|
}
|
|
581
581
|
}
|
|
582
|
-
const versionedFlow = await this.flowRepo.getAtVersion(claimed.flowId, claimed.flowVersion);
|
|
583
|
-
const effectiveFlow = versionedFlow ?? flow;
|
|
584
|
-
const state = effectiveFlow.states.find((s) => s.name === pending.stage);
|
|
585
|
-
const build = state
|
|
586
|
-
? await this.buildPromptForEntity(state, claimed, effectiveFlow)
|
|
587
|
-
: { prompt: pending.prompt, context: null };
|
|
588
582
|
await this.eventEmitter.emit({
|
|
589
583
|
type: "entity.claimed",
|
|
590
584
|
entityId: claimed.id,
|
|
@@ -597,8 +591,8 @@ export class Engine {
|
|
|
597
591
|
invocationId: claimedInvocation.id,
|
|
598
592
|
flowName: flow.name,
|
|
599
593
|
stage: pending.stage,
|
|
600
|
-
|
|
601
|
-
|
|
594
|
+
refs: claimed.refs ?? null,
|
|
595
|
+
artifacts: claimed.artifacts ?? null,
|
|
602
596
|
};
|
|
603
597
|
}
|
|
604
598
|
// 8. Fallback: no unclaimed invocations — claim entity directly and create invocation
|
|
@@ -676,8 +670,8 @@ export class Engine {
|
|
|
676
670
|
invocationId: claimedInvocation.id,
|
|
677
671
|
flowName: flow.name,
|
|
678
672
|
stage: state.name,
|
|
679
|
-
|
|
680
|
-
|
|
673
|
+
refs: claimed.refs ?? null,
|
|
674
|
+
artifacts: claimed.artifacts ?? null,
|
|
681
675
|
};
|
|
682
676
|
}
|
|
683
677
|
}
|
|
@@ -173,8 +173,15 @@ export async function handleFlowClaim(deps, args) {
|
|
|
173
173
|
continue;
|
|
174
174
|
}
|
|
175
175
|
const flow = entity ? flowById.get(entity.flowId) : undefined;
|
|
176
|
+
if (!flow) {
|
|
177
|
+
await deps.entities.release(entity.id, claimerId).catch(() => { });
|
|
178
|
+
await deps.invocations
|
|
179
|
+
.fail(claimed.id, `Flow not found for entity ${entity.id} (flowId: ${entity.flowId})`)
|
|
180
|
+
.catch(() => { });
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
176
183
|
// Record affinity for the claiming worker (best-effort; failure must not block the claim)
|
|
177
|
-
if (worker_id && entity
|
|
184
|
+
if (worker_id && entity) {
|
|
178
185
|
try {
|
|
179
186
|
const windowMs = flow.affinityWindowMs ?? 300000;
|
|
180
187
|
await deps.entities.setAffinity(claimed.entityId, worker_id, role, new Date(Date.now() + windowMs));
|
|
@@ -198,14 +205,12 @@ export async function handleFlowClaim(deps, args) {
|
|
|
198
205
|
});
|
|
199
206
|
}
|
|
200
207
|
return jsonResult({
|
|
201
|
-
|
|
202
|
-
entity_id: claimed.entityId,
|
|
208
|
+
entity_id: entity.id,
|
|
203
209
|
invocation_id: claimed.id,
|
|
204
|
-
flow: flow
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
context: claimed.context,
|
|
210
|
+
flow: flow.name,
|
|
211
|
+
state: claimed.stage,
|
|
212
|
+
refs: claimedEntity.refs ?? null,
|
|
213
|
+
artifacts: claimedEntity.artifacts ?? null,
|
|
209
214
|
});
|
|
210
215
|
}
|
|
211
216
|
return noWorkResult(RETRY_SHORT_MS, role);
|
|
@@ -17,6 +17,7 @@ function rowToState(r) {
|
|
|
17
17
|
onEnter: r.onEnter ?? null,
|
|
18
18
|
onExit: r.onExit ?? null,
|
|
19
19
|
retryAfterMs: r.retryAfterMs ?? null,
|
|
20
|
+
meta: r.meta,
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
function rowToTransition(r) {
|
|
@@ -161,6 +162,7 @@ export class DrizzleFlowRepository {
|
|
|
161
162
|
onEnter: s.onEnter ?? null,
|
|
162
163
|
onExit: s.onExit ?? null,
|
|
163
164
|
retryAfterMs: s.retryAfterMs ?? null,
|
|
165
|
+
meta: s.meta ?? null,
|
|
164
166
|
})),
|
|
165
167
|
transitions: (snap.transitions ?? []).map((t) => ({
|
|
166
168
|
id: t.id,
|
|
@@ -238,6 +240,7 @@ export class DrizzleFlowRepository {
|
|
|
238
240
|
onEnter: (state.onEnter ?? null),
|
|
239
241
|
onExit: (state.onExit ?? null),
|
|
240
242
|
retryAfterMs: state.retryAfterMs ?? null,
|
|
243
|
+
meta: (state.meta ?? null),
|
|
241
244
|
};
|
|
242
245
|
this.db.transaction((tx) => {
|
|
243
246
|
tx.insert(stateDefinitions).values(row).run();
|
|
@@ -268,6 +271,8 @@ export class DrizzleFlowRepository {
|
|
|
268
271
|
updateValues.onExit = changes.onExit;
|
|
269
272
|
if (changes.retryAfterMs !== undefined)
|
|
270
273
|
updateValues.retryAfterMs = changes.retryAfterMs;
|
|
274
|
+
if (changes.meta !== undefined)
|
|
275
|
+
updateValues.meta = changes.meta;
|
|
271
276
|
if (Object.keys(updateValues).length > 0) {
|
|
272
277
|
this.db.update(stateDefinitions).set(updateValues).where(eq(stateDefinitions.id, stateId)).run();
|
|
273
278
|
}
|
|
@@ -532,6 +532,23 @@ export declare const stateDefinitions: import("drizzle-orm/sqlite-core").SQLiteT
|
|
|
532
532
|
identity: undefined;
|
|
533
533
|
generated: undefined;
|
|
534
534
|
}, {}, {}>;
|
|
535
|
+
meta: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
536
|
+
name: "meta";
|
|
537
|
+
tableName: "state_definitions";
|
|
538
|
+
dataType: "json";
|
|
539
|
+
columnType: "SQLiteTextJson";
|
|
540
|
+
data: unknown;
|
|
541
|
+
driverParam: string;
|
|
542
|
+
notNull: false;
|
|
543
|
+
hasDefault: false;
|
|
544
|
+
isPrimaryKey: false;
|
|
545
|
+
isAutoincrement: false;
|
|
546
|
+
hasRuntimeDefault: false;
|
|
547
|
+
enumValues: undefined;
|
|
548
|
+
baseColumn: never;
|
|
549
|
+
identity: undefined;
|
|
550
|
+
generated: undefined;
|
|
551
|
+
}, {}, {}>;
|
|
535
552
|
};
|
|
536
553
|
dialect: "sqlite";
|
|
537
554
|
}>;
|
|
@@ -34,6 +34,8 @@ export const stateDefinitions = sqliteTable("state_definitions", {
|
|
|
34
34
|
onEnter: text("on_enter", { mode: "json" }),
|
|
35
35
|
onExit: text("on_exit", { mode: "json" }),
|
|
36
36
|
retryAfterMs: integer("retry_after_ms"),
|
|
37
|
+
/** Opaque metadata passed through to consumers. Defcon stores but does not interpret. */
|
|
38
|
+
meta: text("meta", { mode: "json" }),
|
|
37
39
|
}, (table) => ({
|
|
38
40
|
flowNameUnique: uniqueIndex("state_definitions_flow_name_unique").on(table.flowId, table.name),
|
|
39
41
|
}));
|
|
@@ -99,6 +99,8 @@ export interface State {
|
|
|
99
99
|
onExit: OnExitConfig | null;
|
|
100
100
|
/** Override check_back delay for workers claiming this state. Falls back to Flow.claimRetryAfterMs. */
|
|
101
101
|
retryAfterMs: number | null;
|
|
102
|
+
/** Opaque metadata passed through to consumers (e.g. radar). Defcon stores but does not interpret. */
|
|
103
|
+
meta: Record<string, unknown> | null;
|
|
102
104
|
}
|
|
103
105
|
/** A transition rule between two states */
|
|
104
106
|
export interface Transition {
|
|
@@ -195,6 +197,7 @@ export interface CreateStateInput {
|
|
|
195
197
|
onEnter?: OnEnterConfig;
|
|
196
198
|
onExit?: OnExitConfig;
|
|
197
199
|
retryAfterMs?: number;
|
|
200
|
+
meta?: Record<string, unknown>;
|
|
198
201
|
}
|
|
199
202
|
/** Input for adding a transition rule */
|
|
200
203
|
export interface CreateTransitionInput {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE `state_definitions` ADD `meta` text;
|