@mastra/factory 0.0.0-fix-thread-subscription-multi-instance-redis-streams-20260730204150
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/CHANGELOG.md +695 -0
- package/LICENSE.md +30 -0
- package/README.md +27 -0
- package/dist/auth.d.ts +181 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +505 -0
- package/dist/auth.js.map +1 -0
- package/dist/capabilities/connection.d.ts +9 -0
- package/dist/capabilities/connection.d.ts.map +1 -0
- package/dist/capabilities/connection.js +1 -0
- package/dist/capabilities/intake.d.ts +140 -0
- package/dist/capabilities/intake.d.ts.map +1 -0
- package/dist/capabilities/intake.js +1 -0
- package/dist/capabilities/version-control.d.ts +245 -0
- package/dist/capabilities/version-control.d.ts.map +1 -0
- package/dist/capabilities/version-control.js +1 -0
- package/dist/factory.d.ts +156 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +483 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/integrations/base.d.ts +210 -0
- package/dist/integrations/base.d.ts.map +1 -0
- package/dist/integrations/base.js +1 -0
- package/dist/integrations/github/config.d.ts +60 -0
- package/dist/integrations/github/config.d.ts.map +1 -0
- package/dist/integrations/github/config.js +42 -0
- package/dist/integrations/github/config.js.map +1 -0
- package/dist/integrations/github/factory-session.d.ts +12 -0
- package/dist/integrations/github/factory-session.d.ts.map +1 -0
- package/dist/integrations/github/factory-session.js +37 -0
- package/dist/integrations/github/factory-session.js.map +1 -0
- package/dist/integrations/github/integration.d.ts +191 -0
- package/dist/integrations/github/integration.d.ts.map +1 -0
- package/dist/integrations/github/integration.js +1077 -0
- package/dist/integrations/github/integration.js.map +1 -0
- package/dist/integrations/github/issue-triage.d.ts +27 -0
- package/dist/integrations/github/issue-triage.d.ts.map +1 -0
- package/dist/integrations/github/issue-triage.js +82 -0
- package/dist/integrations/github/issue-triage.js.map +1 -0
- package/dist/integrations/github/pat.d.ts +38 -0
- package/dist/integrations/github/pat.d.ts.map +1 -0
- package/dist/integrations/github/pat.js +59 -0
- package/dist/integrations/github/pat.js.map +1 -0
- package/dist/integrations/github/provenance.d.ts +27 -0
- package/dist/integrations/github/provenance.d.ts.map +1 -0
- package/dist/integrations/github/provenance.js +75 -0
- package/dist/integrations/github/provenance.js.map +1 -0
- package/dist/integrations/github/routes.d.ts +69 -0
- package/dist/integrations/github/routes.d.ts.map +1 -0
- package/dist/integrations/github/routes.js +1324 -0
- package/dist/integrations/github/routes.js.map +1 -0
- package/dist/integrations/github/rules.d.ts +78 -0
- package/dist/integrations/github/rules.d.ts.map +1 -0
- package/dist/integrations/github/rules.js +362 -0
- package/dist/integrations/github/rules.js.map +1 -0
- package/dist/integrations/github/sandbox-release.d.ts +38 -0
- package/dist/integrations/github/sandbox-release.d.ts.map +1 -0
- package/dist/integrations/github/sandbox-release.js +74 -0
- package/dist/integrations/github/sandbox-release.js.map +1 -0
- package/dist/integrations/github/sandbox.d.ts +281 -0
- package/dist/integrations/github/sandbox.d.ts.map +1 -0
- package/dist/integrations/github/sandbox.js +547 -0
- package/dist/integrations/github/sandbox.js.map +1 -0
- package/dist/integrations/github/session-subscriptions.d.ts +26 -0
- package/dist/integrations/github/session-subscriptions.d.ts.map +1 -0
- package/dist/integrations/github/session-subscriptions.js +192 -0
- package/dist/integrations/github/session-subscriptions.js.map +1 -0
- package/dist/integrations/github/subscriptions.d.ts +54 -0
- package/dist/integrations/github/subscriptions.d.ts.map +1 -0
- package/dist/integrations/github/subscriptions.js +62 -0
- package/dist/integrations/github/subscriptions.js.map +1 -0
- package/dist/integrations/github/token-refresh.d.ts +12 -0
- package/dist/integrations/github/token-refresh.d.ts.map +1 -0
- package/dist/integrations/github/token-refresh.js +24 -0
- package/dist/integrations/github/token-refresh.js.map +1 -0
- package/dist/integrations/github/webhook.d.ts +87 -0
- package/dist/integrations/github/webhook.d.ts.map +1 -0
- package/dist/integrations/github/webhook.js +397 -0
- package/dist/integrations/github/webhook.js.map +1 -0
- package/dist/integrations/linear/agent-tools.d.ts +34 -0
- package/dist/integrations/linear/agent-tools.d.ts.map +1 -0
- package/dist/integrations/linear/agent-tools.js +85 -0
- package/dist/integrations/linear/agent-tools.js.map +1 -0
- package/dist/integrations/linear/integration.d.ts +233 -0
- package/dist/integrations/linear/integration.d.ts.map +1 -0
- package/dist/integrations/linear/integration.js +672 -0
- package/dist/integrations/linear/integration.js.map +1 -0
- package/dist/integrations/linear/routes.d.ts +61 -0
- package/dist/integrations/linear/routes.d.ts.map +1 -0
- package/dist/integrations/linear/routes.js +239 -0
- package/dist/integrations/linear/routes.js.map +1 -0
- package/dist/integrations/linear/rules.d.ts +42 -0
- package/dist/integrations/linear/rules.d.ts.map +1 -0
- package/dist/integrations/linear/rules.js +133 -0
- package/dist/integrations/linear/rules.js.map +1 -0
- package/dist/integrations/linear/storage.d.ts +65 -0
- package/dist/integrations/linear/storage.d.ts.map +1 -0
- package/dist/integrations/linear/storage.js +1 -0
- package/dist/integrations/platform/api-client.d.ts +26 -0
- package/dist/integrations/platform/api-client.d.ts.map +1 -0
- package/dist/integrations/platform/api-client.js +156 -0
- package/dist/integrations/platform/api-client.js.map +1 -0
- package/dist/integrations/platform/github/event-worker.d.ts +49 -0
- package/dist/integrations/platform/github/event-worker.d.ts.map +1 -0
- package/dist/integrations/platform/github/event-worker.js +348 -0
- package/dist/integrations/platform/github/event-worker.js.map +1 -0
- package/dist/integrations/platform/github/integration.d.ts +50 -0
- package/dist/integrations/platform/github/integration.d.ts.map +1 -0
- package/dist/integrations/platform/github/integration.js +961 -0
- package/dist/integrations/platform/github/integration.js.map +1 -0
- package/dist/integrations/platform/linear/integration.d.ts +46 -0
- package/dist/integrations/platform/linear/integration.d.ts.map +1 -0
- package/dist/integrations/platform/linear/integration.js +483 -0
- package/dist/integrations/platform/linear/integration.js.map +1 -0
- package/dist/integrations/workos/integration.d.ts +39 -0
- package/dist/integrations/workos/integration.d.ts.map +1 -0
- package/dist/integrations/workos/integration.js +91 -0
- package/dist/integrations/workos/integration.js.map +1 -0
- package/dist/routes/config.d.ts +235 -0
- package/dist/routes/config.d.ts.map +1 -0
- package/dist/routes/config.js +972 -0
- package/dist/routes/config.js.map +1 -0
- package/dist/routes/custom-provider-source.d.ts +52 -0
- package/dist/routes/custom-provider-source.d.ts.map +1 -0
- package/dist/routes/custom-provider-source.js +124 -0
- package/dist/routes/custom-provider-source.js.map +1 -0
- package/dist/routes/fs.d.ts +151 -0
- package/dist/routes/fs.d.ts.map +1 -0
- package/dist/routes/fs.js +708 -0
- package/dist/routes/fs.js.map +1 -0
- package/dist/routes/intake.d.ts +23 -0
- package/dist/routes/intake.d.ts.map +1 -0
- package/dist/routes/intake.js +179 -0
- package/dist/routes/intake.js.map +1 -0
- package/dist/routes/oauth.d.ts +43 -0
- package/dist/routes/oauth.d.ts.map +1 -0
- package/dist/routes/oauth.js +463 -0
- package/dist/routes/oauth.js.map +1 -0
- package/dist/routes/projects.d.ts +19 -0
- package/dist/routes/projects.d.ts.map +1 -0
- package/dist/routes/projects.js +461 -0
- package/dist/routes/projects.js.map +1 -0
- package/dist/routes/provider-credentials.d.ts +81 -0
- package/dist/routes/provider-credentials.d.ts.map +1 -0
- package/dist/routes/provider-credentials.js +86 -0
- package/dist/routes/provider-credentials.js.map +1 -0
- package/dist/routes/route.d.ts +48 -0
- package/dist/routes/route.d.ts.map +1 -0
- package/dist/routes/route.js +15 -0
- package/dist/routes/route.js.map +1 -0
- package/dist/routes/skills.d.ts +30 -0
- package/dist/routes/skills.d.ts.map +1 -0
- package/dist/routes/skills.js +168 -0
- package/dist/routes/skills.js.map +1 -0
- package/dist/routes/surface.d.ts +91 -0
- package/dist/routes/surface.d.ts.map +1 -0
- package/dist/routes/surface.js +260 -0
- package/dist/routes/surface.js.map +1 -0
- package/dist/routes/tenant-credentials.d.ts +74 -0
- package/dist/routes/tenant-credentials.d.ts.map +1 -0
- package/dist/routes/tenant-credentials.js +156 -0
- package/dist/routes/tenant-credentials.js.map +1 -0
- package/dist/routes/work-items.d.ts +40 -0
- package/dist/routes/work-items.d.ts.map +1 -0
- package/dist/routes/work-items.js +695 -0
- package/dist/routes/work-items.js.map +1 -0
- package/dist/rules/binding-context.d.ts +5 -0
- package/dist/rules/binding-context.d.ts.map +1 -0
- package/dist/rules/binding-context.js +28 -0
- package/dist/rules/binding-context.js.map +1 -0
- package/dist/rules/defaults.d.ts +9 -0
- package/dist/rules/defaults.d.ts.map +1 -0
- package/dist/rules/defaults.js +260 -0
- package/dist/rules/defaults.js.map +1 -0
- package/dist/rules/dispatcher.d.ts +42 -0
- package/dist/rules/dispatcher.d.ts.map +1 -0
- package/dist/rules/dispatcher.js +518 -0
- package/dist/rules/dispatcher.js.map +1 -0
- package/dist/rules/index.d.ts +7 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +5 -0
- package/dist/rules/processor.d.ts +54 -0
- package/dist/rules/processor.d.ts.map +1 -0
- package/dist/rules/processor.js +378 -0
- package/dist/rules/processor.js.map +1 -0
- package/dist/rules/resolve.d.ts +17 -0
- package/dist/rules/resolve.d.ts.map +1 -0
- package/dist/rules/resolve.js +30 -0
- package/dist/rules/resolve.js.map +1 -0
- package/dist/rules/start-coordinator.d.ts +60 -0
- package/dist/rules/start-coordinator.d.ts.map +1 -0
- package/dist/rules/start-coordinator.js +194 -0
- package/dist/rules/start-coordinator.js.map +1 -0
- package/dist/rules/tools.d.ts +10 -0
- package/dist/rules/tools.d.ts.map +1 -0
- package/dist/rules/tools.js +58 -0
- package/dist/rules/tools.js.map +1 -0
- package/dist/rules/transition-service.d.ts +49 -0
- package/dist/rules/transition-service.d.ts.map +1 -0
- package/dist/rules/transition-service.js +232 -0
- package/dist/rules/transition-service.js.map +1 -0
- package/dist/rules/types.d.ts +234 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +38 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/rules/validation.d.ts +11 -0
- package/dist/rules/validation.d.ts.map +1 -0
- package/dist/rules/validation.js +308 -0
- package/dist/rules/validation.js.map +1 -0
- package/dist/sandbox/fleet.d.ts +222 -0
- package/dist/sandbox/fleet.d.ts.map +1 -0
- package/dist/sandbox/fleet.js +322 -0
- package/dist/sandbox/fleet.js.map +1 -0
- package/dist/sandbox/reattach.d.ts +3 -0
- package/dist/sandbox/reattach.d.ts.map +1 -0
- package/dist/sandbox/reattach.js +16 -0
- package/dist/sandbox/reattach.js.map +1 -0
- package/dist/server-error.d.ts +12 -0
- package/dist/server-error.d.ts.map +1 -0
- package/dist/server-error.js +16 -0
- package/dist/server-error.js.map +1 -0
- package/dist/skills/service.d.ts +48 -0
- package/dist/skills/service.d.ts.map +1 -0
- package/dist/skills/service.js +40 -0
- package/dist/skills/service.js.map +1 -0
- package/dist/spa-static.d.ts +33 -0
- package/dist/spa-static.d.ts.map +1 -0
- package/dist/spa-static.js +104 -0
- package/dist/spa-static.js.map +1 -0
- package/dist/state-signing.d.ts +59 -0
- package/dist/state-signing.d.ts.map +1 -0
- package/dist/state-signing.js +83 -0
- package/dist/state-signing.js.map +1 -0
- package/dist/storage/domains/audit/agent-audit.d.ts +27 -0
- package/dist/storage/domains/audit/agent-audit.d.ts.map +1 -0
- package/dist/storage/domains/audit/agent-audit.js +66 -0
- package/dist/storage/domains/audit/agent-audit.js.map +1 -0
- package/dist/storage/domains/audit/base.d.ts +140 -0
- package/dist/storage/domains/audit/base.d.ts.map +1 -0
- package/dist/storage/domains/audit/base.js +184 -0
- package/dist/storage/domains/audit/base.js.map +1 -0
- package/dist/storage/domains/audit/domain.d.ts +69 -0
- package/dist/storage/domains/audit/domain.d.ts.map +1 -0
- package/dist/storage/domains/audit/domain.js +167 -0
- package/dist/storage/domains/audit/domain.js.map +1 -0
- package/dist/storage/domains/channel-identity/base.d.ts +96 -0
- package/dist/storage/domains/channel-identity/base.d.ts.map +1 -0
- package/dist/storage/domains/channel-identity/base.js +149 -0
- package/dist/storage/domains/channel-identity/base.js.map +1 -0
- package/dist/storage/domains/credentials/base.d.ts +134 -0
- package/dist/storage/domains/credentials/base.d.ts.map +1 -0
- package/dist/storage/domains/credentials/base.js +273 -0
- package/dist/storage/domains/credentials/base.js.map +1 -0
- package/dist/storage/domains/custom-providers/base.d.ts +57 -0
- package/dist/storage/domains/custom-providers/base.d.ts.map +1 -0
- package/dist/storage/domains/custom-providers/base.js +145 -0
- package/dist/storage/domains/custom-providers/base.js.map +1 -0
- package/dist/storage/domains/intake/base.d.ts +38 -0
- package/dist/storage/domains/intake/base.d.ts.map +1 -0
- package/dist/storage/domains/intake/base.js +80 -0
- package/dist/storage/domains/intake/base.js.map +1 -0
- package/dist/storage/domains/integrations/base.d.ts +126 -0
- package/dist/storage/domains/integrations/base.d.ts.map +1 -0
- package/dist/storage/domains/integrations/base.js +317 -0
- package/dist/storage/domains/integrations/base.js.map +1 -0
- package/dist/storage/domains/memory-settings/base.d.ts +62 -0
- package/dist/storage/domains/memory-settings/base.d.ts.map +1 -0
- package/dist/storage/domains/memory-settings/base.js +126 -0
- package/dist/storage/domains/memory-settings/base.js.map +1 -0
- package/dist/storage/domains/model-packs/base.d.ts +49 -0
- package/dist/storage/domains/model-packs/base.d.ts.map +1 -0
- package/dist/storage/domains/model-packs/base.js +96 -0
- package/dist/storage/domains/model-packs/base.js.map +1 -0
- package/dist/storage/domains/projects/base.d.ts +58 -0
- package/dist/storage/domains/projects/base.d.ts.map +1 -0
- package/dist/storage/domains/projects/base.js +111 -0
- package/dist/storage/domains/projects/base.js.map +1 -0
- package/dist/storage/domains/queue-health/base.d.ts +52 -0
- package/dist/storage/domains/queue-health/base.d.ts.map +1 -0
- package/dist/storage/domains/queue-health/base.js +122 -0
- package/dist/storage/domains/queue-health/base.js.map +1 -0
- package/dist/storage/domains/source-control/base.d.ts +358 -0
- package/dist/storage/domains/source-control/base.d.ts.map +1 -0
- package/dist/storage/domains/source-control/base.js +908 -0
- package/dist/storage/domains/source-control/base.js.map +1 -0
- package/dist/storage/domains/source-control/inmemory.d.ts +175 -0
- package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -0
- package/dist/storage/domains/source-control/inmemory.js +377 -0
- package/dist/storage/domains/source-control/inmemory.js.map +1 -0
- package/dist/storage/domains/work-items/base.d.ts +412 -0
- package/dist/storage/domains/work-items/base.d.ts.map +1 -0
- package/dist/storage/domains/work-items/base.js +1309 -0
- package/dist/storage/domains/work-items/base.js.map +1 -0
- package/dist/storage/domains/work-items/metrics.d.ts +101 -0
- package/dist/storage/domains/work-items/metrics.d.ts.map +1 -0
- package/dist/storage/domains/work-items/metrics.js +221 -0
- package/dist/storage/domains/work-items/metrics.js.map +1 -0
- package/dist/timing.d.ts +15 -0
- package/dist/timing.d.ts.map +1 -0
- package/dist/timing.js +34 -0
- package/dist/timing.js.map +1 -0
- package/dist/workspace.d.ts +24 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +286 -0
- package/dist/workspace.js.map +1 -0
- package/factory-skills/configure-factory-rules/SKILL.md +67 -0
- package/factory-skills/factory-plan/SKILL.md +61 -0
- package/factory-skills/factory-review/SKILL.md +155 -0
- package/factory-skills/factory-triage/SKILL.md +77 -0
- package/package.json +81 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
import { FACTORY_RULE_STAGES } from "./types.js";
|
|
2
|
+
import { validateFactoryRuleDecision } from "./validation.js";
|
|
3
|
+
import { resolveSkillInvocation } from "../skills/service.js";
|
|
4
|
+
import { randomUUID } from "crypto";
|
|
5
|
+
import { RequestContext } from "@mastra/core/request-context";
|
|
6
|
+
//#region src/rules/dispatcher.ts
|
|
7
|
+
const LEASE_MS = 3e4;
|
|
8
|
+
const POLL_MS = 1e3;
|
|
9
|
+
const BATCH_SIZE = 10;
|
|
10
|
+
const MAX_ATTEMPTS = 5;
|
|
11
|
+
const MAX_ERROR_LENGTH = 512;
|
|
12
|
+
const MAX_BACKOFF_MS = 6e4;
|
|
13
|
+
const MAX_IN_FLIGHT = 25;
|
|
14
|
+
function sanitizeDispatchError(error) {
|
|
15
|
+
return (error instanceof Error ? error.message : String(error)).replace(/\b(?:bearer|token|api[-_ ]?key|authorization)\s*[:=]?\s*[^\s,;]+/gi, "[redacted]").slice(0, MAX_ERROR_LENGTH);
|
|
16
|
+
}
|
|
17
|
+
function retryAt(now, attempts) {
|
|
18
|
+
return new Date(now.getTime() + Math.min(1e3 * 2 ** Math.max(0, attempts - 1), MAX_BACKOFF_MS));
|
|
19
|
+
}
|
|
20
|
+
function externalSourceForDecision(decision) {
|
|
21
|
+
const [integrationId, type] = decision.source === "github-pr" ? ["github", "pull-request"] : decision.source === "github-issue" ? ["github", "issue"] : decision.source === "linear-issue" ? ["linear", "issue"] : ["factory", "manual"];
|
|
22
|
+
return {
|
|
23
|
+
integrationId,
|
|
24
|
+
type,
|
|
25
|
+
externalId: decision.sourceKey,
|
|
26
|
+
url: decision.url ?? void 0
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function deferredActor(record) {
|
|
30
|
+
const actor = record.actor;
|
|
31
|
+
if (actor?.type === "github" && typeof actor.login === "string" && typeof actor.trusted === "boolean" && typeof actor.factoryAuthored === "boolean") return {
|
|
32
|
+
type: "github",
|
|
33
|
+
login: actor.login,
|
|
34
|
+
trusted: actor.trusted,
|
|
35
|
+
factoryAuthored: actor.factoryAuthored
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
type: "system",
|
|
39
|
+
id: "factory-rule-dispatcher"
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function leaseIdentity(record, ownerId) {
|
|
43
|
+
return {
|
|
44
|
+
id: record.id,
|
|
45
|
+
orgId: record.orgId,
|
|
46
|
+
factoryProjectId: record.factoryProjectId,
|
|
47
|
+
ownerId
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async function awaitNotification(result, requireDelivery = false) {
|
|
51
|
+
await result.persisted;
|
|
52
|
+
if (!result.accepted) {
|
|
53
|
+
if (requireDelivery) throw new Error("Factory notification was persisted without agent delivery.");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const accepted = await result.accepted;
|
|
57
|
+
if (!requireDelivery) return;
|
|
58
|
+
if (accepted.action === "wake") {
|
|
59
|
+
await accepted.output.consumeStream();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (accepted.action !== "deliver") throw new Error(`Factory notification did not reach the agent (${String(accepted.action)}).`);
|
|
63
|
+
}
|
|
64
|
+
var FactoryDecisionDispatcher = class {
|
|
65
|
+
#controller;
|
|
66
|
+
#transitionService;
|
|
67
|
+
#storage;
|
|
68
|
+
#ownerId;
|
|
69
|
+
#reconcileToolResults;
|
|
70
|
+
#prepareBinding;
|
|
71
|
+
#primeCredentials;
|
|
72
|
+
#maxInFlight;
|
|
73
|
+
#timer;
|
|
74
|
+
#activeClaim;
|
|
75
|
+
#inFlight = /* @__PURE__ */ new Set();
|
|
76
|
+
constructor(options) {
|
|
77
|
+
this.#controller = options.controller;
|
|
78
|
+
this.#transitionService = options.transitionService;
|
|
79
|
+
this.#storage = options.storage;
|
|
80
|
+
this.#ownerId = options.ownerId ?? `factory-dispatcher:${randomUUID()}`;
|
|
81
|
+
this.#reconcileToolResults = options.reconcileToolResults;
|
|
82
|
+
this.#prepareBinding = options.prepareBinding;
|
|
83
|
+
this.#primeCredentials = options.primeCredentials;
|
|
84
|
+
const maxInFlight = options.maxInFlight ?? MAX_IN_FLIGHT;
|
|
85
|
+
this.#maxInFlight = Number.isFinite(maxInFlight) && maxInFlight > 0 ? Math.floor(maxInFlight) : MAX_IN_FLIGHT;
|
|
86
|
+
}
|
|
87
|
+
start() {
|
|
88
|
+
if (this.#timer) return;
|
|
89
|
+
this.#tick();
|
|
90
|
+
this.#timer = setInterval(() => void this.#tick(), POLL_MS);
|
|
91
|
+
this.#timer.unref?.();
|
|
92
|
+
}
|
|
93
|
+
async stop() {
|
|
94
|
+
if (this.#timer) clearInterval(this.#timer);
|
|
95
|
+
this.#timer = void 0;
|
|
96
|
+
await this.#activeClaim;
|
|
97
|
+
await Promise.allSettled([...this.#inFlight]);
|
|
98
|
+
}
|
|
99
|
+
async runOnce(now = /* @__PURE__ */ new Date()) {
|
|
100
|
+
await Promise.all(await this.#claimAndStart(now));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Claims a batch and starts dispatches without awaiting their completion.
|
|
104
|
+
* Dispatches can legitimately take minutes (skill kickoffs consume the
|
|
105
|
+
* agent's run stream; binding preparation provisions sandboxes), so awaiting
|
|
106
|
+
* them here would freeze the poll loop and starve every other queued
|
|
107
|
+
* decision. In-flight records stay protected from re-claim by lease renewal.
|
|
108
|
+
*/
|
|
109
|
+
async #claimAndStart(now) {
|
|
110
|
+
await this.#reconcileToolResults?.();
|
|
111
|
+
const capacity = this.#maxInFlight - this.#inFlight.size;
|
|
112
|
+
if (capacity <= 0) return [];
|
|
113
|
+
const limit = Math.min(BATCH_SIZE, capacity);
|
|
114
|
+
const leaseExpiresAt = new Date(now.getTime() + LEASE_MS);
|
|
115
|
+
const decisions = await this.#storage.claimDeferredDecisions({
|
|
116
|
+
ownerId: this.#ownerId,
|
|
117
|
+
now,
|
|
118
|
+
leaseExpiresAt,
|
|
119
|
+
limit
|
|
120
|
+
});
|
|
121
|
+
const startsLimit = limit - decisions.length;
|
|
122
|
+
const starts = startsLimit > 0 ? await this.#storage.claimPendingStarts({
|
|
123
|
+
ownerId: this.#ownerId,
|
|
124
|
+
now,
|
|
125
|
+
leaseExpiresAt,
|
|
126
|
+
limit: startsLimit
|
|
127
|
+
}) : [];
|
|
128
|
+
return [...decisions.map((decision) => this.#track(this.#dispatchDecision(decision, now))), ...starts.map((start) => this.#track(this.#dispatchPendingStart(start, now)))];
|
|
129
|
+
}
|
|
130
|
+
#track(dispatch) {
|
|
131
|
+
this.#inFlight.add(dispatch);
|
|
132
|
+
dispatch.catch(() => {}).then(() => this.#inFlight.delete(dispatch));
|
|
133
|
+
return dispatch;
|
|
134
|
+
}
|
|
135
|
+
async #tick() {
|
|
136
|
+
if (this.#activeClaim) return;
|
|
137
|
+
this.#activeClaim = this.#claimAndStart(/* @__PURE__ */ new Date()).then((dispatches) => {
|
|
138
|
+
for (const dispatch of dispatches) dispatch.catch((error) => {
|
|
139
|
+
console.error("Factory decision dispatch failed", sanitizeDispatchError(error));
|
|
140
|
+
});
|
|
141
|
+
}, (error) => {
|
|
142
|
+
console.error("Factory decision dispatch cycle failed", sanitizeDispatchError(error));
|
|
143
|
+
});
|
|
144
|
+
try {
|
|
145
|
+
await this.#activeClaim;
|
|
146
|
+
} finally {
|
|
147
|
+
this.#activeClaim = void 0;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async #dispatchDecision(record, now) {
|
|
151
|
+
try {
|
|
152
|
+
const decision = validateFactoryRuleDecision(record.decision, record.causalChain.length);
|
|
153
|
+
if (decision.type === "reject") throw new Error("Deferred Factory decisions cannot reject.");
|
|
154
|
+
await this.#withLease(async (leaseExpiresAt) => this.#storage.renewDeferredDecisionLease(leaseIdentity(record, this.#ownerId), leaseExpiresAt), async () => this.#executeDecision(record, decision));
|
|
155
|
+
if (!await this.#storage.completeDeferredDecision(leaseIdentity(record, this.#ownerId), /* @__PURE__ */ new Date())) throw new Error("Factory decision lease was lost before completion.");
|
|
156
|
+
} catch (error) {
|
|
157
|
+
const terminal = record.attempts >= MAX_ATTEMPTS;
|
|
158
|
+
await this.#storage.failDeferredDecision({
|
|
159
|
+
...leaseIdentity(record, this.#ownerId),
|
|
160
|
+
now: /* @__PURE__ */ new Date(),
|
|
161
|
+
availableAt: retryAt(now, record.attempts),
|
|
162
|
+
lastError: sanitizeDispatchError(error),
|
|
163
|
+
terminal
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async #executeDecision(record, decision) {
|
|
168
|
+
const nextChain = [...record.causalChain, {
|
|
169
|
+
ingressId: record.idempotencyKey,
|
|
170
|
+
decisionType: decision.type
|
|
171
|
+
}];
|
|
172
|
+
if (nextChain.length > 8) throw new Error("Factory rule causal depth exceeded.");
|
|
173
|
+
switch (decision.type) {
|
|
174
|
+
case "transition": {
|
|
175
|
+
const item = await this.#requireItem(record);
|
|
176
|
+
const result = await this.#transitionService.transition({
|
|
177
|
+
orgId: record.orgId,
|
|
178
|
+
factoryProjectId: record.factoryProjectId,
|
|
179
|
+
workItemId: item.id,
|
|
180
|
+
board: decision.board,
|
|
181
|
+
stage: decision.stage,
|
|
182
|
+
expectedRevision: item.revision,
|
|
183
|
+
actor: {
|
|
184
|
+
type: "system",
|
|
185
|
+
id: "factory-rule-dispatcher"
|
|
186
|
+
},
|
|
187
|
+
ingress: {
|
|
188
|
+
type: "rule",
|
|
189
|
+
identity: `decision:${record.idempotencyKey}`
|
|
190
|
+
},
|
|
191
|
+
cause: "rule_decision",
|
|
192
|
+
causalChain: nextChain
|
|
193
|
+
});
|
|
194
|
+
if (result.status === "rejected") throw new Error(`${result.code}: ${result.reason}`);
|
|
195
|
+
if (!decision.message) return;
|
|
196
|
+
const binding = await this.#findBinding(record, decision.message.role);
|
|
197
|
+
if (!binding) return;
|
|
198
|
+
const startedBy = item.sessions[binding.role]?.startedBy;
|
|
199
|
+
if (!startedBy) return;
|
|
200
|
+
await this.#primeCredentials?.({
|
|
201
|
+
orgId: record.orgId,
|
|
202
|
+
userId: startedBy
|
|
203
|
+
});
|
|
204
|
+
const requestContext = new RequestContext();
|
|
205
|
+
requestContext.set("user", {
|
|
206
|
+
workosId: startedBy,
|
|
207
|
+
organizationId: record.orgId
|
|
208
|
+
});
|
|
209
|
+
await awaitNotification(await (await this.#requireSession(binding)).sendNotificationSignal({
|
|
210
|
+
source: "factory",
|
|
211
|
+
kind: "rule-message",
|
|
212
|
+
summary: decision.message.text,
|
|
213
|
+
priority: "high",
|
|
214
|
+
payload: { message: decision.message.text },
|
|
215
|
+
sourceId: record.id,
|
|
216
|
+
dedupeKey: record.idempotencyKey
|
|
217
|
+
}, {
|
|
218
|
+
ifActive: { behavior: "deliver" },
|
|
219
|
+
ifIdle: { behavior: "wake" },
|
|
220
|
+
requestContext
|
|
221
|
+
}), true);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
case "upsertLinkedWorkItem":
|
|
225
|
+
await this.#upsertLinkedItem(record, decision, nextChain);
|
|
226
|
+
return;
|
|
227
|
+
case "invokeSkill": {
|
|
228
|
+
const binding = await this.#requireOrPrepareBinding(record, decision.role);
|
|
229
|
+
const startedBy = (record.workItemId ? await this.#storage.get({
|
|
230
|
+
orgId: record.orgId,
|
|
231
|
+
id: record.workItemId
|
|
232
|
+
}) : null)?.sessions[binding.role]?.startedBy;
|
|
233
|
+
if (!startedBy) throw new Error(`Factory binding ${binding.id} has no authenticated session owner.`);
|
|
234
|
+
await this.#primeCredentials?.({
|
|
235
|
+
orgId: record.orgId,
|
|
236
|
+
userId: startedBy
|
|
237
|
+
});
|
|
238
|
+
const requestContext = new RequestContext();
|
|
239
|
+
requestContext.set("user", {
|
|
240
|
+
workosId: startedBy,
|
|
241
|
+
organizationId: record.orgId
|
|
242
|
+
});
|
|
243
|
+
const resolved = await resolveSkillInvocation(this.#controller, {
|
|
244
|
+
resourceId: binding.resourceId,
|
|
245
|
+
name: decision.skillName,
|
|
246
|
+
arguments: decision.arguments
|
|
247
|
+
});
|
|
248
|
+
const session = resolved.session;
|
|
249
|
+
await this.#switchThread(session, binding);
|
|
250
|
+
if ((await session.thread.listActiveMessages()).some((message) => message.id === record.id)) return;
|
|
251
|
+
if (decision.precedingMessage) await awaitNotification(await session.sendNotificationSignal({
|
|
252
|
+
source: "factory",
|
|
253
|
+
kind: "stage-transition",
|
|
254
|
+
summary: decision.precedingMessage,
|
|
255
|
+
priority: "medium",
|
|
256
|
+
payload: { message: decision.precedingMessage },
|
|
257
|
+
sourceId: `${record.id}:stage-transition`,
|
|
258
|
+
dedupeKey: `${record.idempotencyKey}:stage-transition`
|
|
259
|
+
}, {
|
|
260
|
+
ifActive: { behavior: "deliver" },
|
|
261
|
+
ifIdle: { behavior: "persist" },
|
|
262
|
+
requestContext
|
|
263
|
+
}));
|
|
264
|
+
const settled = await session.sendSignal({
|
|
265
|
+
id: record.id,
|
|
266
|
+
type: "user",
|
|
267
|
+
tagName: "user",
|
|
268
|
+
contents: resolved.message
|
|
269
|
+
}, {
|
|
270
|
+
requestContext,
|
|
271
|
+
requireDelivery: true
|
|
272
|
+
}).accepted;
|
|
273
|
+
if (settled.action !== "wake" && settled.action !== "deliver") throw new Error(`Factory skill invocation signal did not reach the agent (${String(settled.action)}).`);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
case "sendMessage": {
|
|
277
|
+
const binding = decision.prepareBinding ? await this.#requireOrPrepareBinding(record, decision.role) : await this.#requireBinding(record, decision.role);
|
|
278
|
+
const startedBy = (record.workItemId ? await this.#storage.get({
|
|
279
|
+
orgId: record.orgId,
|
|
280
|
+
id: record.workItemId
|
|
281
|
+
}) : null)?.sessions[binding.role]?.startedBy;
|
|
282
|
+
if (!startedBy) throw new Error(`Factory binding ${binding.id} has no authenticated session owner.`);
|
|
283
|
+
await this.#primeCredentials?.({
|
|
284
|
+
orgId: record.orgId,
|
|
285
|
+
userId: startedBy
|
|
286
|
+
});
|
|
287
|
+
const requestContext = new RequestContext();
|
|
288
|
+
requestContext.set("user", {
|
|
289
|
+
workosId: startedBy,
|
|
290
|
+
organizationId: record.orgId
|
|
291
|
+
});
|
|
292
|
+
await awaitNotification(await (await this.#requireSession(binding)).sendNotificationSignal({
|
|
293
|
+
source: "factory",
|
|
294
|
+
kind: "rule-message",
|
|
295
|
+
summary: decision.message,
|
|
296
|
+
priority: decision.priority ?? "high",
|
|
297
|
+
payload: { message: decision.message },
|
|
298
|
+
sourceId: record.id,
|
|
299
|
+
dedupeKey: record.idempotencyKey
|
|
300
|
+
}, {
|
|
301
|
+
ifActive: { behavior: "deliver" },
|
|
302
|
+
ifIdle: { behavior: decision.idleBehavior ?? "wake" },
|
|
303
|
+
requestContext
|
|
304
|
+
}), true);
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
case "notify": {
|
|
308
|
+
const binding = await this.#requireBinding(record);
|
|
309
|
+
await awaitNotification(await (await this.#requireSession(binding)).sendNotificationSignal({
|
|
310
|
+
source: "factory",
|
|
311
|
+
kind: "rule-notification",
|
|
312
|
+
summary: decision.title,
|
|
313
|
+
payload: {
|
|
314
|
+
body: decision.body,
|
|
315
|
+
level: decision.level
|
|
316
|
+
},
|
|
317
|
+
sourceId: record.id,
|
|
318
|
+
dedupeKey: record.idempotencyKey
|
|
319
|
+
}));
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
async #upsertLinkedItem(record, decision, causalChain) {
|
|
324
|
+
const result = await this.#storage.upsert({
|
|
325
|
+
orgId: record.orgId,
|
|
326
|
+
userId: "factory-rule-dispatcher",
|
|
327
|
+
factoryProjectId: record.factoryProjectId,
|
|
328
|
+
input: {
|
|
329
|
+
externalSource: externalSourceForDecision(decision),
|
|
330
|
+
parentWorkItemId: record.workItemId,
|
|
331
|
+
title: decision.title,
|
|
332
|
+
stages: ["intake"],
|
|
333
|
+
sessions: {},
|
|
334
|
+
metadata: {
|
|
335
|
+
...decision.metadata,
|
|
336
|
+
factoryRuleMaterializationKey: record.idempotencyKey
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
reuseMode: "preserve"
|
|
340
|
+
});
|
|
341
|
+
const materializedByDecision = result.item.metadata?.factoryRuleMaterializationKey === record.idempotencyKey;
|
|
342
|
+
if (!materializedByDecision && (decision.stage === "intake" || !result.item.stages.includes("intake"))) return;
|
|
343
|
+
const board = decision.board;
|
|
344
|
+
let expectedRevision = result.item.revision;
|
|
345
|
+
if (materializedByDecision) {
|
|
346
|
+
const initial = await this.#transitionService.transition({
|
|
347
|
+
orgId: record.orgId,
|
|
348
|
+
factoryProjectId: record.factoryProjectId,
|
|
349
|
+
workItemId: result.item.id,
|
|
350
|
+
board,
|
|
351
|
+
stage: "intake",
|
|
352
|
+
expectedRevision,
|
|
353
|
+
actor: deferredActor(record),
|
|
354
|
+
ingress: {
|
|
355
|
+
type: "rule",
|
|
356
|
+
identity: `decision:${record.idempotencyKey}:${result.item.id}:initial-entry`
|
|
357
|
+
},
|
|
358
|
+
cause: "linked_item_materialized",
|
|
359
|
+
causalChain,
|
|
360
|
+
initialEntry: true
|
|
361
|
+
});
|
|
362
|
+
if (initial.status === "rejected") {
|
|
363
|
+
if (result.created) await this.#storage.delete({
|
|
364
|
+
orgId: record.orgId,
|
|
365
|
+
id: result.item.id
|
|
366
|
+
});
|
|
367
|
+
throw new Error(`${initial.code}: ${initial.reason}`);
|
|
368
|
+
}
|
|
369
|
+
expectedRevision = initial.revision;
|
|
370
|
+
}
|
|
371
|
+
if (decision.stage === "intake") return;
|
|
372
|
+
const moved = await this.#transitionService.transition({
|
|
373
|
+
orgId: record.orgId,
|
|
374
|
+
factoryProjectId: record.factoryProjectId,
|
|
375
|
+
workItemId: result.item.id,
|
|
376
|
+
board,
|
|
377
|
+
stage: decision.stage,
|
|
378
|
+
expectedRevision,
|
|
379
|
+
actor: {
|
|
380
|
+
type: "system",
|
|
381
|
+
id: "factory-rule-dispatcher"
|
|
382
|
+
},
|
|
383
|
+
ingress: {
|
|
384
|
+
type: "rule",
|
|
385
|
+
identity: `decision:${record.idempotencyKey}:${result.item.id}:destination`
|
|
386
|
+
},
|
|
387
|
+
cause: materializedByDecision ? "linked_item_materialized" : "linked_item_reconciled",
|
|
388
|
+
causalChain
|
|
389
|
+
});
|
|
390
|
+
if (moved.status === "rejected") throw new Error(`${moved.code}: ${moved.reason}`);
|
|
391
|
+
}
|
|
392
|
+
async #requireItem(record) {
|
|
393
|
+
if (!record.workItemId) throw new Error("Factory decision is not linked to a work item.");
|
|
394
|
+
const item = await this.#storage.get({
|
|
395
|
+
orgId: record.orgId,
|
|
396
|
+
id: record.workItemId
|
|
397
|
+
});
|
|
398
|
+
if (!item) throw new Error("Factory work item not found.");
|
|
399
|
+
return item;
|
|
400
|
+
}
|
|
401
|
+
async #findBinding(record, role) {
|
|
402
|
+
if (!record.workItemId) throw new Error("Factory decision is not linked to a work item.");
|
|
403
|
+
return (await this.#storage.listRunBindings(record.orgId, record.factoryProjectId, record.workItemId)).filter((candidate) => candidate.status === "active" && (role === void 0 || candidate.role === role)).sort((left, right) => {
|
|
404
|
+
if (role === void 0 && left.role === "work" && right.role !== "work") return -1;
|
|
405
|
+
if (role === void 0 && right.role === "work" && left.role !== "work") return 1;
|
|
406
|
+
return right.createdAt.getTime() - left.createdAt.getTime() || left.id.localeCompare(right.id);
|
|
407
|
+
})[0];
|
|
408
|
+
}
|
|
409
|
+
async #requireBinding(record, role) {
|
|
410
|
+
const binding = await this.#findBinding(record, role);
|
|
411
|
+
if (!binding) throw new Error(role ? `No active Factory binding for role ${role}.` : "No active Factory binding.");
|
|
412
|
+
return binding;
|
|
413
|
+
}
|
|
414
|
+
async #requireOrPrepareBinding(record, role) {
|
|
415
|
+
const binding = await this.#findBinding(record, role);
|
|
416
|
+
if (binding) {
|
|
417
|
+
if (await this.#controller.getSessionByResource(binding.resourceId)) return binding;
|
|
418
|
+
}
|
|
419
|
+
if (!this.#prepareBinding) throw new Error(binding ? "Bound Factory session not found." : `No active Factory binding for role ${role}.`);
|
|
420
|
+
const item = await this.#requireItem(record);
|
|
421
|
+
await this.#prepareBinding({
|
|
422
|
+
record,
|
|
423
|
+
item,
|
|
424
|
+
role
|
|
425
|
+
});
|
|
426
|
+
return this.#requireBinding(record, role);
|
|
427
|
+
}
|
|
428
|
+
async #requireSession(binding) {
|
|
429
|
+
const session = await this.#controller.getSessionByResource(binding.resourceId);
|
|
430
|
+
if (!session) throw new Error("Bound Factory session not found.");
|
|
431
|
+
await this.#switchThread(session, binding);
|
|
432
|
+
return session;
|
|
433
|
+
}
|
|
434
|
+
async #switchThread(session, binding) {
|
|
435
|
+
await session.thread.switch({ threadId: binding.threadId });
|
|
436
|
+
}
|
|
437
|
+
async #withLease(renew, effect) {
|
|
438
|
+
let renewalFailure;
|
|
439
|
+
let renewal = Promise.resolve();
|
|
440
|
+
const timer = setInterval(() => {
|
|
441
|
+
renewal = renewal.then(async () => {
|
|
442
|
+
try {
|
|
443
|
+
if (!await renew(new Date(Date.now() + LEASE_MS))) renewalFailure = /* @__PURE__ */ new Error("Factory dispatch lease was lost during execution.");
|
|
444
|
+
} catch (error) {
|
|
445
|
+
renewalFailure = error;
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
}, Math.floor(LEASE_MS / 3));
|
|
449
|
+
timer.unref?.();
|
|
450
|
+
try {
|
|
451
|
+
await effect();
|
|
452
|
+
await renewal;
|
|
453
|
+
if (renewalFailure) throw renewalFailure;
|
|
454
|
+
} finally {
|
|
455
|
+
clearInterval(timer);
|
|
456
|
+
await renewal;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
async #dispatchPendingStart(record, now) {
|
|
460
|
+
try {
|
|
461
|
+
await this.#withLease(async (leaseExpiresAt) => this.#storage.renewPendingStartLease(leaseIdentity(record, this.#ownerId), leaseExpiresAt), async () => {
|
|
462
|
+
if (record.message === null) return;
|
|
463
|
+
const binding = (await this.#storage.listRunBindings(record.orgId, record.factoryProjectId)).find((candidate) => candidate.id === record.bindingId && candidate.status === "active");
|
|
464
|
+
if (!binding) throw new Error("Prepared Factory binding is unavailable or revoked.");
|
|
465
|
+
const startedBy = (await this.#storage.get({
|
|
466
|
+
orgId: record.orgId,
|
|
467
|
+
id: binding.workItemId
|
|
468
|
+
}))?.sessions[binding.role]?.startedBy;
|
|
469
|
+
if (!startedBy) throw new Error(`Factory binding ${binding.id} has no authenticated session owner.`);
|
|
470
|
+
await this.#primeCredentials?.({
|
|
471
|
+
orgId: record.orgId,
|
|
472
|
+
userId: startedBy
|
|
473
|
+
});
|
|
474
|
+
const requestContext = new RequestContext();
|
|
475
|
+
requestContext.set("user", {
|
|
476
|
+
workosId: startedBy,
|
|
477
|
+
organizationId: record.orgId
|
|
478
|
+
});
|
|
479
|
+
await awaitNotification(await (await this.#requireSession(binding)).sendNotificationSignal({
|
|
480
|
+
source: "factory",
|
|
481
|
+
kind: "run-kickoff",
|
|
482
|
+
summary: record.message,
|
|
483
|
+
priority: "high",
|
|
484
|
+
payload: { message: record.message },
|
|
485
|
+
sourceId: record.id,
|
|
486
|
+
dedupeKey: `factory-kickoff:${record.kickoffKey}`
|
|
487
|
+
}, {
|
|
488
|
+
ifActive: { behavior: "deliver" },
|
|
489
|
+
ifIdle: { behavior: "wake" },
|
|
490
|
+
requestContext
|
|
491
|
+
}), true);
|
|
492
|
+
});
|
|
493
|
+
if (!await this.#storage.completePendingStart(leaseIdentity(record, this.#ownerId), /* @__PURE__ */ new Date())) throw new Error("Factory kickoff lease was lost before completion.");
|
|
494
|
+
} catch (error) {
|
|
495
|
+
await this.#storage.failPendingStart({
|
|
496
|
+
...leaseIdentity(record, this.#ownerId),
|
|
497
|
+
now: /* @__PURE__ */ new Date(),
|
|
498
|
+
availableAt: retryAt(now, record.attempts),
|
|
499
|
+
lastError: sanitizeDispatchError(error),
|
|
500
|
+
terminal: record.attempts >= MAX_ATTEMPTS
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
const FACTORY_DISPATCH_CONSTANTS = {
|
|
506
|
+
leaseMs: LEASE_MS,
|
|
507
|
+
pollMs: POLL_MS,
|
|
508
|
+
batchSize: BATCH_SIZE,
|
|
509
|
+
maxAttempts: MAX_ATTEMPTS,
|
|
510
|
+
maxErrorLength: MAX_ERROR_LENGTH,
|
|
511
|
+
maxBackoffMs: MAX_BACKOFF_MS,
|
|
512
|
+
maxInFlight: MAX_IN_FLIGHT,
|
|
513
|
+
stages: FACTORY_RULE_STAGES
|
|
514
|
+
};
|
|
515
|
+
//#endregion
|
|
516
|
+
export { FACTORY_DISPATCH_CONSTANTS, FactoryDecisionDispatcher };
|
|
517
|
+
|
|
518
|
+
//# sourceMappingURL=dispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.js","names":["#controller","#transitionService","#storage","#ownerId","#reconcileToolResults","#prepareBinding","#primeCredentials","#maxInFlight","#inFlight","#timer","#tick","#activeClaim","#claimAndStart","#track","#dispatchDecision","#dispatchPendingStart","#withLease","#executeDecision","#requireItem","#findBinding","#requireSession","#upsertLinkedItem","#requireOrPrepareBinding","#switchThread","#requireBinding"],"sources":["../../src/rules/dispatcher.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { MastraCodeState } from '@mastra/code-sdk/schema';\nimport type { AgentController } from '@mastra/core/agent-controller';\nimport { RequestContext } from '@mastra/core/request-context';\n\nimport { resolveSkillInvocation } from '../skills/service.js';\nimport type { SkillSession } from '../skills/service.js';\nimport type {\n FactoryDeferredDecisionRecord,\n FactoryPendingStartRecord,\n FactoryRunBindingRecord,\n WorkItemRow,\n WorkItemsStorage,\n} from '../storage/domains/work-items/base.js';\nimport type { FactoryTransitionService } from './transition-service.js';\nimport type { FactoryCommitDecision, FactoryRuleActor, FactoryRuleCausalEntry } from './types.js';\nimport { FACTORY_RULE_STAGES } from './types.js';\nimport { MAX_FACTORY_RULE_CAUSAL_DEPTH, validateFactoryRuleDecision } from './validation.js';\n\nconst LEASE_MS = 30_000;\nconst POLL_MS = 1_000;\nconst BATCH_SIZE = 10;\nconst MAX_ATTEMPTS = 5;\nconst MAX_ERROR_LENGTH = 512;\nconst MAX_BACKOFF_MS = 60_000;\n// Dispatches can legitimately run for minutes (skill kickoffs consume the\n// agent's run stream; binding preparation clones repositories), so they run\n// detached from the poll loop under this concurrency cap.\nconst MAX_IN_FLIGHT = 25;\n\ninterface DispatcherSession extends SkillSession {\n thread: {\n switch(input: { threadId: string }): Promise<unknown>;\n listActiveMessages(): Promise<Array<{ id: string }>>;\n };\n sendSignal(\n input: { id: string; type: 'user'; tagName: 'user'; contents: string },\n options: { requestContext: RequestContext; requireDelivery?: boolean },\n ): { accepted: Promise<{ accepted: true; runId?: string; action?: string }> };\n}\n\ntype FactoryController = Pick<AgentController<MastraCodeState>, 'getSessionByResource'>;\n\nexport interface FactoryBindingPreparationInput {\n record: FactoryDeferredDecisionRecord;\n item: WorkItemRow;\n role: string;\n}\n\nexport interface FactoryDecisionDispatcherOptions {\n controller: FactoryController;\n transitionService: Pick<FactoryTransitionService, 'transition'>;\n storage: WorkItemsStorage;\n ownerId?: string;\n reconcileToolResults?: () => Promise<void>;\n prepareBinding?: (input: FactoryBindingPreparationInput) => Promise<void>;\n primeCredentials?: (tenant: { orgId: string; userId: string }) => Promise<void>;\n maxInFlight?: number;\n}\n\nfunction sanitizeDispatchError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n return message\n .replace(/\\b(?:bearer|token|api[-_ ]?key|authorization)\\s*[:=]?\\s*[^\\s,;]+/gi, '[redacted]')\n .slice(0, MAX_ERROR_LENGTH);\n}\n\nfunction retryAt(now: Date, attempts: number): Date {\n return new Date(now.getTime() + Math.min(1_000 * 2 ** Math.max(0, attempts - 1), MAX_BACKOFF_MS));\n}\n\nfunction externalSourceForDecision(decision: Extract<FactoryCommitDecision, { type: 'upsertLinkedWorkItem' }>) {\n const [integrationId, type] =\n decision.source === 'github-pr'\n ? ['github', 'pull-request']\n : decision.source === 'github-issue'\n ? ['github', 'issue']\n : decision.source === 'linear-issue'\n ? ['linear', 'issue']\n : ['factory', 'manual'];\n return { integrationId, type, externalId: decision.sourceKey, url: decision.url ?? undefined };\n}\n\nfunction deferredActor(record: FactoryDeferredDecisionRecord): FactoryRuleActor {\n const actor = record.actor;\n if (\n actor?.type === 'github' &&\n typeof actor.login === 'string' &&\n typeof actor.trusted === 'boolean' &&\n typeof actor.factoryAuthored === 'boolean'\n ) {\n return {\n type: 'github',\n login: actor.login,\n trusted: actor.trusted,\n factoryAuthored: actor.factoryAuthored,\n };\n }\n return { type: 'system', id: 'factory-rule-dispatcher' };\n}\n\nfunction leaseIdentity(\n record: Pick<FactoryDeferredDecisionRecord | FactoryPendingStartRecord, 'id' | 'orgId' | 'factoryProjectId'>,\n ownerId: string,\n) {\n return { id: record.id, orgId: record.orgId, factoryProjectId: record.factoryProjectId, ownerId };\n}\n\nasync function awaitNotification(\n result: Awaited<ReturnType<SkillSession['sendNotificationSignal']>>,\n requireDelivery = false,\n): Promise<void> {\n await result.persisted;\n if (!result.accepted) {\n if (requireDelivery) throw new Error('Factory notification was persisted without agent delivery.');\n return;\n }\n const accepted = await result.accepted;\n if (!requireDelivery) return;\n if (accepted.action === 'wake') {\n await accepted.output.consumeStream();\n return;\n }\n if (accepted.action !== 'deliver') {\n throw new Error(`Factory notification did not reach the agent (${String(accepted.action)}).`);\n }\n}\n\nexport class FactoryDecisionDispatcher {\n readonly #controller: FactoryController;\n readonly #transitionService: Pick<FactoryTransitionService, 'transition'>;\n readonly #storage: WorkItemsStorage;\n readonly #ownerId: string;\n readonly #reconcileToolResults?: () => Promise<void>;\n readonly #prepareBinding?: (input: FactoryBindingPreparationInput) => Promise<void>;\n readonly #primeCredentials?: (tenant: { orgId: string; userId: string }) => Promise<void>;\n readonly #maxInFlight: number;\n #timer?: ReturnType<typeof setInterval>;\n #activeClaim?: Promise<void>;\n readonly #inFlight = new Set<Promise<void>>();\n\n constructor(options: FactoryDecisionDispatcherOptions) {\n this.#controller = options.controller;\n this.#transitionService = options.transitionService;\n this.#storage = options.storage;\n this.#ownerId = options.ownerId ?? `factory-dispatcher:${randomUUID()}`;\n this.#reconcileToolResults = options.reconcileToolResults;\n this.#prepareBinding = options.prepareBinding;\n this.#primeCredentials = options.primeCredentials;\n const maxInFlight = options.maxInFlight ?? MAX_IN_FLIGHT;\n this.#maxInFlight = Number.isFinite(maxInFlight) && maxInFlight > 0 ? Math.floor(maxInFlight) : MAX_IN_FLIGHT;\n }\n\n start(): void {\n if (this.#timer) return;\n void this.#tick();\n this.#timer = setInterval(() => void this.#tick(), POLL_MS);\n this.#timer.unref?.();\n }\n\n async stop(): Promise<void> {\n if (this.#timer) clearInterval(this.#timer);\n this.#timer = undefined;\n await this.#activeClaim;\n await Promise.allSettled([...this.#inFlight]);\n }\n\n async runOnce(now = new Date()): Promise<void> {\n await Promise.all(await this.#claimAndStart(now));\n }\n\n /**\n * Claims a batch and starts dispatches without awaiting their completion.\n * Dispatches can legitimately take minutes (skill kickoffs consume the\n * agent's run stream; binding preparation provisions sandboxes), so awaiting\n * them here would freeze the poll loop and starve every other queued\n * decision. In-flight records stay protected from re-claim by lease renewal.\n */\n async #claimAndStart(now: Date): Promise<Array<Promise<void>>> {\n await this.#reconcileToolResults?.();\n const capacity = this.#maxInFlight - this.#inFlight.size;\n if (capacity <= 0) return [];\n const limit = Math.min(BATCH_SIZE, capacity);\n const leaseExpiresAt = new Date(now.getTime() + LEASE_MS);\n const decisions = await this.#storage.claimDeferredDecisions({\n ownerId: this.#ownerId,\n now,\n leaseExpiresAt,\n limit,\n });\n const startsLimit = limit - decisions.length;\n const starts =\n startsLimit > 0\n ? await this.#storage.claimPendingStarts({\n ownerId: this.#ownerId,\n now,\n leaseExpiresAt,\n limit: startsLimit,\n })\n : [];\n return [\n ...decisions.map(decision => this.#track(this.#dispatchDecision(decision, now))),\n ...starts.map(start => this.#track(this.#dispatchPendingStart(start, now))),\n ];\n }\n\n #track(dispatch: Promise<void>): Promise<void> {\n this.#inFlight.add(dispatch);\n void dispatch.catch(() => {}).then(() => this.#inFlight.delete(dispatch));\n return dispatch;\n }\n\n async #tick(): Promise<void> {\n if (this.#activeClaim) return;\n this.#activeClaim = this.#claimAndStart(new Date()).then(\n dispatches => {\n for (const dispatch of dispatches) {\n dispatch.catch(error => {\n console.error('Factory decision dispatch failed', sanitizeDispatchError(error));\n });\n }\n },\n error => {\n console.error('Factory decision dispatch cycle failed', sanitizeDispatchError(error));\n },\n );\n try {\n await this.#activeClaim;\n } finally {\n this.#activeClaim = undefined;\n }\n }\n\n async #dispatchDecision(record: FactoryDeferredDecisionRecord, now: Date): Promise<void> {\n try {\n const decision = validateFactoryRuleDecision(record.decision, record.causalChain.length);\n if (decision.type === 'reject') throw new Error('Deferred Factory decisions cannot reject.');\n await this.#withLease(\n async leaseExpiresAt =>\n this.#storage.renewDeferredDecisionLease(leaseIdentity(record, this.#ownerId), leaseExpiresAt),\n async () => this.#executeDecision(record, decision),\n );\n const completed = await this.#storage.completeDeferredDecision(leaseIdentity(record, this.#ownerId), new Date());\n if (!completed) throw new Error('Factory decision lease was lost before completion.');\n } catch (error) {\n const terminal = record.attempts >= MAX_ATTEMPTS;\n await this.#storage.failDeferredDecision({\n ...leaseIdentity(record, this.#ownerId),\n now: new Date(),\n availableAt: retryAt(now, record.attempts),\n lastError: sanitizeDispatchError(error),\n terminal,\n });\n }\n }\n\n async #executeDecision(record: FactoryDeferredDecisionRecord, decision: FactoryCommitDecision): Promise<void> {\n const nextChain: FactoryRuleCausalEntry[] = [\n ...(record.causalChain as FactoryRuleCausalEntry[]),\n { ingressId: record.idempotencyKey, decisionType: decision.type },\n ];\n if (nextChain.length > MAX_FACTORY_RULE_CAUSAL_DEPTH) throw new Error('Factory rule causal depth exceeded.');\n\n switch (decision.type) {\n case 'transition': {\n const item = await this.#requireItem(record);\n const result = await this.#transitionService.transition({\n orgId: record.orgId,\n factoryProjectId: record.factoryProjectId,\n workItemId: item.id,\n board: decision.board,\n stage: decision.stage,\n expectedRevision: item.revision,\n actor: { type: 'system', id: 'factory-rule-dispatcher' },\n ingress: { type: 'rule', identity: `decision:${record.idempotencyKey}` },\n cause: 'rule_decision',\n causalChain: nextChain,\n });\n if (result.status === 'rejected') throw new Error(`${result.code}: ${result.reason}`);\n if (!decision.message) return;\n // Best-effort recipient lookup: no active binding (or no authenticated\n // session owner) means nobody is engaged with this item, so the\n // transition itself is the whole effect. A retry after a delivery\n // failure is safe because the transition replays by ingress identity.\n const binding = await this.#findBinding(record, decision.message.role);\n if (!binding) return;\n const startedBy = item.sessions[binding.role]?.startedBy;\n if (!startedBy) return;\n await this.#primeCredentials?.({ orgId: record.orgId, userId: startedBy });\n const requestContext = new RequestContext();\n requestContext.set('user', { workosId: startedBy, organizationId: record.orgId });\n const session = await this.#requireSession(binding);\n await awaitNotification(\n await session.sendNotificationSignal(\n {\n source: 'factory',\n kind: 'rule-message',\n summary: decision.message.text,\n priority: 'high',\n payload: { message: decision.message.text },\n sourceId: record.id,\n dedupeKey: record.idempotencyKey,\n },\n {\n ifActive: { behavior: 'deliver' },\n ifIdle: { behavior: 'wake' },\n requestContext,\n },\n ),\n true,\n );\n return;\n }\n case 'upsertLinkedWorkItem': {\n await this.#upsertLinkedItem(record, decision, nextChain);\n return;\n }\n case 'invokeSkill': {\n const binding = await this.#requireOrPrepareBinding(record, decision.role);\n const item = record.workItemId ? await this.#storage.get({ orgId: record.orgId, id: record.workItemId }) : null;\n const startedBy = item?.sessions[binding.role]?.startedBy;\n if (!startedBy) throw new Error(`Factory binding ${binding.id} has no authenticated session owner.`);\n await this.#primeCredentials?.({ orgId: record.orgId, userId: startedBy });\n const requestContext = new RequestContext();\n requestContext.set('user', { workosId: startedBy, organizationId: record.orgId });\n const resolved = await resolveSkillInvocation(this.#controller, {\n resourceId: binding.resourceId,\n name: decision.skillName,\n arguments: decision.arguments,\n });\n const session = resolved.session as DispatcherSession;\n await this.#switchThread(session, binding);\n const delivered = await session.thread.listActiveMessages();\n if (delivered.some(message => message.id === record.id)) return;\n if (decision.precedingMessage) {\n await awaitNotification(\n await session.sendNotificationSignal(\n {\n source: 'factory',\n kind: 'stage-transition',\n summary: decision.precedingMessage,\n priority: 'medium',\n payload: { message: decision.precedingMessage },\n sourceId: `${record.id}:stage-transition`,\n dedupeKey: `${record.idempotencyKey}:stage-transition`,\n },\n {\n ifActive: { behavior: 'deliver' },\n ifIdle: { behavior: 'persist' },\n requestContext,\n },\n ),\n );\n }\n const result = session.sendSignal(\n {\n id: record.id,\n type: 'user',\n tagName: 'user',\n contents: resolved.message,\n },\n // Without `requireDelivery` the session resolves `accepted` on the\n // next tick and swallows wake failures, so a kickoff that never\n // reached the agent would be marked succeeded and the thread would\n // stay empty forever.\n { requestContext, requireDelivery: true },\n );\n const settled = await result.accepted;\n if (settled.action !== 'wake' && settled.action !== 'deliver') {\n // An undefined action means the session did not verify delivery at\n // all — with `requireDelivery` set that is a contract violation, not\n // a success.\n throw new Error(`Factory skill invocation signal did not reach the agent (${String(settled.action)}).`);\n }\n return;\n }\n case 'sendMessage': {\n const binding = decision.prepareBinding\n ? await this.#requireOrPrepareBinding(record, decision.role)\n : await this.#requireBinding(record, decision.role);\n const item = record.workItemId ? await this.#storage.get({ orgId: record.orgId, id: record.workItemId }) : null;\n const startedBy = item?.sessions[binding.role]?.startedBy;\n if (!startedBy) throw new Error(`Factory binding ${binding.id} has no authenticated session owner.`);\n await this.#primeCredentials?.({ orgId: record.orgId, userId: startedBy });\n const requestContext = new RequestContext();\n requestContext.set('user', { workosId: startedBy, organizationId: record.orgId });\n const session = await this.#requireSession(binding);\n await awaitNotification(\n await session.sendNotificationSignal(\n {\n source: 'factory',\n kind: 'rule-message',\n summary: decision.message,\n priority: decision.priority ?? 'high',\n payload: { message: decision.message },\n sourceId: record.id,\n dedupeKey: record.idempotencyKey,\n },\n {\n ifActive: { behavior: 'deliver' },\n ifIdle: { behavior: decision.idleBehavior ?? 'wake' },\n requestContext,\n },\n ),\n true,\n );\n return;\n }\n case 'notify': {\n const binding = await this.#requireBinding(record);\n const session = await this.#requireSession(binding);\n await awaitNotification(\n await session.sendNotificationSignal({\n source: 'factory',\n kind: 'rule-notification',\n summary: decision.title,\n payload: { body: decision.body, level: decision.level },\n sourceId: record.id,\n dedupeKey: record.idempotencyKey,\n }),\n );\n }\n }\n }\n\n async #upsertLinkedItem(\n record: FactoryDeferredDecisionRecord,\n decision: Extract<FactoryCommitDecision, { type: 'upsertLinkedWorkItem' }>,\n causalChain: FactoryRuleCausalEntry[],\n ): Promise<void> {\n const result = await this.#storage.upsert({\n orgId: record.orgId,\n userId: 'factory-rule-dispatcher',\n factoryProjectId: record.factoryProjectId,\n input: {\n externalSource: externalSourceForDecision(decision),\n parentWorkItemId: record.workItemId,\n title: decision.title,\n stages: ['intake'],\n sessions: {},\n metadata: { ...decision.metadata, factoryRuleMaterializationKey: record.idempotencyKey },\n },\n reuseMode: 'preserve',\n });\n const materializedByDecision = result.item.metadata?.factoryRuleMaterializationKey === record.idempotencyKey;\n if (!materializedByDecision && (decision.stage === 'intake' || !result.item.stages.includes('intake'))) return;\n\n const board = decision.board;\n let expectedRevision = result.item.revision;\n if (materializedByDecision) {\n const initial = await this.#transitionService.transition({\n orgId: record.orgId,\n factoryProjectId: record.factoryProjectId,\n workItemId: result.item.id,\n board,\n stage: 'intake',\n expectedRevision,\n actor: deferredActor(record),\n ingress: { type: 'rule', identity: `decision:${record.idempotencyKey}:${result.item.id}:initial-entry` },\n cause: 'linked_item_materialized',\n causalChain,\n initialEntry: true,\n });\n if (initial.status === 'rejected') {\n if (result.created) await this.#storage.delete({ orgId: record.orgId, id: result.item.id });\n throw new Error(`${initial.code}: ${initial.reason}`);\n }\n expectedRevision = initial.revision;\n }\n if (decision.stage === 'intake') return;\n\n const moved = await this.#transitionService.transition({\n orgId: record.orgId,\n factoryProjectId: record.factoryProjectId,\n workItemId: result.item.id,\n board,\n stage: decision.stage,\n expectedRevision,\n actor: { type: 'system', id: 'factory-rule-dispatcher' },\n ingress: { type: 'rule', identity: `decision:${record.idempotencyKey}:${result.item.id}:destination` },\n cause: materializedByDecision ? 'linked_item_materialized' : 'linked_item_reconciled',\n causalChain,\n });\n if (moved.status === 'rejected') throw new Error(`${moved.code}: ${moved.reason}`);\n }\n\n async #requireItem(record: FactoryDeferredDecisionRecord) {\n if (!record.workItemId) throw new Error('Factory decision is not linked to a work item.');\n const item = await this.#storage.get({ orgId: record.orgId, id: record.workItemId });\n if (!item) throw new Error('Factory work item not found.');\n return item;\n }\n\n async #findBinding(\n record: FactoryDeferredDecisionRecord,\n role?: string,\n ): Promise<FactoryRunBindingRecord | undefined> {\n if (!record.workItemId) throw new Error('Factory decision is not linked to a work item.');\n const bindings = await this.#storage.listRunBindings(record.orgId, record.factoryProjectId, record.workItemId);\n return bindings\n .filter(candidate => candidate.status === 'active' && (role === undefined || candidate.role === role))\n .sort((left, right) => {\n if (role === undefined && left.role === 'work' && right.role !== 'work') return -1;\n if (role === undefined && right.role === 'work' && left.role !== 'work') return 1;\n return right.createdAt.getTime() - left.createdAt.getTime() || left.id.localeCompare(right.id);\n })[0];\n }\n\n async #requireBinding(record: FactoryDeferredDecisionRecord, role?: string): Promise<FactoryRunBindingRecord> {\n const binding = await this.#findBinding(record, role);\n if (!binding) throw new Error(role ? `No active Factory binding for role ${role}.` : 'No active Factory binding.');\n return binding;\n }\n\n async #requireOrPrepareBinding(\n record: FactoryDeferredDecisionRecord,\n role: string,\n ): Promise<FactoryRunBindingRecord> {\n const binding = await this.#findBinding(record, role);\n if (binding) {\n const session = await this.#controller.getSessionByResource(binding.resourceId);\n if (session) return binding;\n }\n if (!this.#prepareBinding) {\n throw new Error(binding ? 'Bound Factory session not found.' : `No active Factory binding for role ${role}.`);\n }\n const item = await this.#requireItem(record);\n await this.#prepareBinding({ record, item, role });\n return this.#requireBinding(record, role);\n }\n\n async #requireSession(binding: FactoryRunBindingRecord): Promise<DispatcherSession> {\n const session = (await this.#controller.getSessionByResource(binding.resourceId)) as DispatcherSession | undefined;\n if (!session) throw new Error('Bound Factory session not found.');\n await this.#switchThread(session, binding);\n return session;\n }\n\n async #switchThread(session: SkillSession, binding: FactoryRunBindingRecord): Promise<void> {\n await (session as DispatcherSession).thread.switch({ threadId: binding.threadId });\n }\n\n async #withLease(\n renew: (leaseExpiresAt: Date) => Promise<unknown | null>,\n effect: () => Promise<void>,\n ): Promise<void> {\n let renewalFailure: unknown;\n let renewal = Promise.resolve();\n const timer = setInterval(\n () => {\n renewal = renewal.then(async () => {\n try {\n const renewed = await renew(new Date(Date.now() + LEASE_MS));\n if (!renewed) renewalFailure = new Error('Factory dispatch lease was lost during execution.');\n } catch (error) {\n renewalFailure = error;\n }\n });\n },\n Math.floor(LEASE_MS / 3),\n );\n timer.unref?.();\n try {\n await effect();\n await renewal;\n if (renewalFailure) throw renewalFailure;\n } finally {\n clearInterval(timer);\n await renewal;\n }\n }\n\n async #dispatchPendingStart(record: FactoryPendingStartRecord, now: Date): Promise<void> {\n try {\n await this.#withLease(\n async leaseExpiresAt =>\n this.#storage.renewPendingStartLease(leaseIdentity(record, this.#ownerId), leaseExpiresAt),\n async () => {\n if (record.message === null) return;\n const bindings = await this.#storage.listRunBindings(record.orgId, record.factoryProjectId);\n const binding = bindings.find(\n candidate => candidate.id === record.bindingId && candidate.status === 'active',\n );\n if (!binding) throw new Error('Prepared Factory binding is unavailable or revoked.');\n // Wake runs build the Factory workspace, which requires the\n // authenticated session owner on the request context.\n const item = await this.#storage.get({ orgId: record.orgId, id: binding.workItemId });\n const startedBy = item?.sessions[binding.role]?.startedBy;\n if (!startedBy) throw new Error(`Factory binding ${binding.id} has no authenticated session owner.`);\n await this.#primeCredentials?.({ orgId: record.orgId, userId: startedBy });\n const requestContext = new RequestContext();\n requestContext.set('user', { workosId: startedBy, organizationId: record.orgId });\n const session = await this.#requireSession(binding);\n await awaitNotification(\n await session.sendNotificationSignal(\n {\n source: 'factory',\n kind: 'run-kickoff',\n summary: record.message!,\n priority: 'high',\n payload: { message: record.message },\n sourceId: record.id,\n dedupeKey: `factory-kickoff:${record.kickoffKey}`,\n },\n { ifActive: { behavior: 'deliver' }, ifIdle: { behavior: 'wake' }, requestContext },\n ),\n true,\n );\n },\n );\n const completed = await this.#storage.completePendingStart(leaseIdentity(record, this.#ownerId), new Date());\n if (!completed) throw new Error('Factory kickoff lease was lost before completion.');\n } catch (error) {\n await this.#storage.failPendingStart({\n ...leaseIdentity(record, this.#ownerId),\n now: new Date(),\n availableAt: retryAt(now, record.attempts),\n lastError: sanitizeDispatchError(error),\n terminal: record.attempts >= MAX_ATTEMPTS,\n });\n }\n }\n}\n\nexport const FACTORY_DISPATCH_CONSTANTS = {\n leaseMs: LEASE_MS,\n pollMs: POLL_MS,\n batchSize: BATCH_SIZE,\n maxAttempts: MAX_ATTEMPTS,\n maxErrorLength: MAX_ERROR_LENGTH,\n maxBackoffMs: MAX_BACKOFF_MS,\n maxInFlight: MAX_IN_FLIGHT,\n stages: FACTORY_RULE_STAGES,\n} as const;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { builtInFactoryRules, defaultFactoryRules, DEFAULT_FACTORY_RULE_VERSION } from './defaults.js';
|
|
2
|
+
export { resolveFactoryGithubRule, resolveFactoryLinearRule, resolveFactoryStageRules, resolveFactoryToolRule, } from './resolve.js';
|
|
3
|
+
export type { ResolvedFactoryStageRule, ResolvedFactoryToolRule } from './resolve.js';
|
|
4
|
+
export { FACTORY_GITHUB_EVENTS, FACTORY_LINEAR_EVENTS, FACTORY_RULE_BOARDS, FACTORY_RULE_SOURCES, FACTORY_RULE_STAGES, factoryRuleSourceForWorkItem, } from './types.js';
|
|
5
|
+
export type { FactoryBoardRuleLeaf, FactoryBoardRules, FactoryBoundRuleContext, FactoryCommitDecision, FactoryGithubEventName, FactoryGithubRuleContext, FactoryGithubRuleLeaf, FactoryLinearEventName, FactoryLinearRuleContext, FactoryLinearRuleLeaf, FactoryInvokeSkillDecision, FactoryNotifyDecision, FactoryRuleActor, FactoryRuleBoard, FactoryRuleCausalEntry, FactoryRuleContextBase, FactoryRuleDecision, FactoryRuleHandler, FactoryRuleIngressIdentity, FactoryRuleItemContext, FactoryRuleJsonValue, FactoryRuleRejectionCode, FactoryRuleRejectDecision, FactoryRuleSource, FactoryRules, FactoryRulesOverrides, FactoryRuleStage, FactorySendMessageDecision, FactoryStageRuleContext, FactoryToolResultRuleContext, FactoryToolRuleLeaf, FactoryTransitionDecision, FactoryTransitionResult, FactoryTransitionResultAccepted, FactoryTransitionResultRejected, FactoryUpsertLinkedWorkItemDecision, } from './types.js';
|
|
6
|
+
export { assertFactoryRules, FactoryRuleValidationError, MAX_FACTORY_RULE_CAUSAL_DEPTH, validateFactoryRuleDecision, validateFactoryRuleDecisions, } from './validation.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AACvG,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACtF,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,4BAA4B,GAC7B,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EACrB,0BAA0B,EAC1B,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC1B,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,EACzB,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,EAChB,0BAA0B,EAC1B,uBAAuB,EACvB,4BAA4B,EAC5B,mBAAmB,EACnB,yBAAyB,EACzB,uBAAuB,EACvB,+BAA+B,EAC/B,+BAA+B,EAC/B,mCAAmC,GACpC,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,6BAA6B,EAC7B,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { resolveFactoryGithubRule, resolveFactoryLinearRule, resolveFactoryStageRules, resolveFactoryToolRule } from "./resolve.js";
|
|
2
|
+
import { FACTORY_GITHUB_EVENTS, FACTORY_LINEAR_EVENTS, FACTORY_RULE_BOARDS, FACTORY_RULE_SOURCES, FACTORY_RULE_STAGES, factoryRuleSourceForWorkItem } from "./types.js";
|
|
3
|
+
import { FactoryRuleValidationError, MAX_FACTORY_RULE_CAUSAL_DEPTH, assertFactoryRules, validateFactoryRuleDecision, validateFactoryRuleDecisions } from "./validation.js";
|
|
4
|
+
import { DEFAULT_FACTORY_RULE_VERSION, builtInFactoryRules, defaultFactoryRules } from "./defaults.js";
|
|
5
|
+
export { DEFAULT_FACTORY_RULE_VERSION, FACTORY_GITHUB_EVENTS, FACTORY_LINEAR_EVENTS, FACTORY_RULE_BOARDS, FACTORY_RULE_SOURCES, FACTORY_RULE_STAGES, FactoryRuleValidationError, MAX_FACTORY_RULE_CAUSAL_DEPTH, assertFactoryRules, builtInFactoryRules, defaultFactoryRules, factoryRuleSourceForWorkItem, resolveFactoryGithubRule, resolveFactoryLinearRule, resolveFactoryStageRules, resolveFactoryToolRule, validateFactoryRuleDecision, validateFactoryRuleDecisions };
|