@mastra/factory 0.23.0 → 0.24.0-alpha.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 +3 -3
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +15 -65
- package/dist/factory.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/integrations/github/session-subscriptions.js +1 -1
- package/dist/integrations/slack/slack.js +1 -1
- package/dist/routes/attention-providers.d.ts +0 -17
- package/dist/routes/attention-providers.d.ts.map +1 -1
- package/dist/routes/attention-providers.js +2 -128
- package/dist/routes/attention-providers.js.map +1 -1
- package/dist/routes/attention.d.ts.map +1 -1
- package/dist/routes/attention.js +1 -2
- package/dist/routes/attention.js.map +1 -1
- package/dist/routes/config.d.ts +0 -28
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +4 -78
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/contracts.d.ts +19 -35
- package/dist/routes/contracts.d.ts.map +1 -1
- package/dist/routes/contracts.js +4 -24
- package/dist/routes/contracts.js.map +1 -1
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +3 -2
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/surface.d.ts +0 -2
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +4 -5
- package/dist/routes/surface.js.map +1 -1
- package/dist/routes/work-items.d.ts.map +1 -1
- package/dist/routes/work-items.js +1 -7
- package/dist/routes/work-items.js.map +1 -1
- package/dist/rules/processor.d.ts +3 -0
- package/dist/rules/processor.d.ts.map +1 -1
- package/dist/rules/processor.js +3 -3
- package/dist/rules/processor.js.map +1 -1
- package/dist/session/credential-policy.d.ts.map +1 -1
- package/dist/session/credential-policy.js +0 -15
- package/dist/session/credential-policy.js.map +1 -1
- package/dist/session/factory-session.js +2 -2
- package/dist/session/thinking-default.d.ts +18 -0
- package/dist/session/thinking-default.d.ts.map +1 -0
- package/dist/session/thinking-default.js +42 -0
- package/dist/session/thinking-default.js.map +1 -0
- package/dist/storage/domains/audit/domain.d.ts +1 -1
- package/dist/storage/domains/audit/domain.d.ts.map +1 -1
- package/dist/storage/domains/audit/domain.js.map +1 -1
- package/dist/storage/domains/projects/base.d.ts +5 -0
- package/dist/storage/domains/projects/base.d.ts.map +1 -1
- package/dist/storage/domains/projects/base.js +9 -1
- package/dist/storage/domains/projects/base.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts +1 -36
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +2 -144
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/dist/telemetry-types.d.ts +1 -1
- package/dist/telemetry-types.d.ts.map +1 -1
- package/dist/telemetry-types.js +0 -1
- package/dist/telemetry-types.js.map +1 -1
- package/dist/workspace.d.ts +1 -1
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +1 -11
- package/dist/workspace.js.map +1 -1
- package/factory-skills/configure-factory-rules/SKILL.md +2 -2
- package/package.json +11 -11
- package/dist/routes/supervisor.d.ts +0 -25
- package/dist/routes/supervisor.d.ts.map +0 -1
- package/dist/routes/supervisor.js +0 -35
- package/dist/routes/supervisor.js.map +0 -1
- package/dist/supervisor/health-worker.d.ts +0 -19
- package/dist/supervisor/health-worker.d.ts.map +0 -1
- package/dist/supervisor/health-worker.js +0 -74
- package/dist/supervisor/health-worker.js.map +0 -1
- package/dist/supervisor/health.d.ts +0 -79
- package/dist/supervisor/health.d.ts.map +0 -1
- package/dist/supervisor/health.js +0 -228
- package/dist/supervisor/health.js.map +0 -1
- package/dist/supervisor/instructions.d.ts +0 -6
- package/dist/supervisor/instructions.d.ts.map +0 -1
- package/dist/supervisor/instructions.js +0 -66
- package/dist/supervisor/instructions.js.map +0 -1
- package/dist/supervisor/read-tools.d.ts +0 -43
- package/dist/supervisor/read-tools.d.ts.map +0 -1
- package/dist/supervisor/read-tools.js +0 -343
- package/dist/supervisor/read-tools.js.map +0 -1
- package/dist/supervisor/session-messaging.d.ts +0 -26
- package/dist/supervisor/session-messaging.d.ts.map +0 -1
- package/dist/supervisor/session-messaging.js +0 -21
- package/dist/supervisor/session-messaging.js.map +0 -1
- package/dist/supervisor/session.d.ts +0 -38
- package/dist/supervisor/session.d.ts.map +0 -1
- package/dist/supervisor/session.js +0 -79
- package/dist/supervisor/session.js.map +0 -1
- package/dist/supervisor/write-tools.d.ts +0 -30
- package/dist/supervisor/write-tools.d.ts.map +0 -1
- package/dist/supervisor/write-tools.js +0 -231
- package/dist/supervisor/write-tools.js.map +0 -1
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { getFactoryAuthOrgId, getFactoryAuthUserFromContext } from "../auth.js";
|
|
2
|
-
import { primeTenantCredentialsForTenant } from "../routes/tenant-credentials.js";
|
|
3
|
-
import { hydrateFactorySession, resolveFactorySessionModel } from "../session/factory-session.js";
|
|
4
|
-
//#region src/supervisor/session.ts
|
|
5
|
-
const RESOURCE_PREFIX = "factory-supervisor:";
|
|
6
|
-
function supervisorResourceId(factoryProjectId) {
|
|
7
|
-
return `${RESOURCE_PREFIX}${factoryProjectId}`;
|
|
8
|
-
}
|
|
9
|
-
/** The supervisor thread shares the session's id: one thread per factory. */
|
|
10
|
-
function supervisorThreadId(factoryProjectId) {
|
|
11
|
-
return supervisorResourceId(factoryProjectId);
|
|
12
|
-
}
|
|
13
|
-
function parseSupervisorResourceId(resourceId) {
|
|
14
|
-
if (!resourceId?.startsWith(RESOURCE_PREFIX)) return null;
|
|
15
|
-
const factoryProjectId = resourceId.slice(19);
|
|
16
|
-
return factoryProjectId.length > 0 ? factoryProjectId : null;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Scope a request to a supervisor session the caller is allowed to drive:
|
|
20
|
-
* the resourceId must name a project, and the caller's org must own it.
|
|
21
|
-
* Anything else yields null and the supervisor tools stay unregistered.
|
|
22
|
-
*/
|
|
23
|
-
async function resolveSupervisorScope(options) {
|
|
24
|
-
const { requestContext } = options;
|
|
25
|
-
if (!requestContext || typeof requestContext.get !== "function") return null;
|
|
26
|
-
const factoryProjectId = parseSupervisorResourceId(requestContext.get("controller")?.resourceId);
|
|
27
|
-
if (!factoryProjectId) return null;
|
|
28
|
-
const orgId = getFactoryAuthOrgId(getFactoryAuthUserFromContext(requestContext));
|
|
29
|
-
if (!orgId) return null;
|
|
30
|
-
if (!await options.projects.get({
|
|
31
|
-
orgId,
|
|
32
|
-
id: factoryProjectId
|
|
33
|
-
})) return null;
|
|
34
|
-
return {
|
|
35
|
-
orgId,
|
|
36
|
-
factoryProjectId
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Session-start hook: stamp the owning project onto a supervisor session and
|
|
41
|
-
* apply the factory's default model. Runs on every (re)creation so a restarted
|
|
42
|
-
* server heals the in-memory state. Sessions
|
|
43
|
-
* that are not supervisors are left untouched.
|
|
44
|
-
*/
|
|
45
|
-
async function hydrateSupervisorSession(session, deps) {
|
|
46
|
-
const factoryProjectId = parseSupervisorResourceId(session.identity.getResourceId());
|
|
47
|
-
if (!factoryProjectId) return;
|
|
48
|
-
const project = await deps.projects.getById({ id: factoryProjectId });
|
|
49
|
-
if (!project) return;
|
|
50
|
-
const sessionModel = await resolveFactorySessionModel({
|
|
51
|
-
projects: deps.projects,
|
|
52
|
-
modelDefaults: deps.modelDefaults,
|
|
53
|
-
factoryProjectId,
|
|
54
|
-
orgId: project.orgId,
|
|
55
|
-
ownerUserId: project.createdBy,
|
|
56
|
-
context: "run"
|
|
57
|
-
});
|
|
58
|
-
await session.state.set({
|
|
59
|
-
factoryProjectId,
|
|
60
|
-
factoryOrgId: project.orgId,
|
|
61
|
-
factoryModelScope: sessionModel.modelScope,
|
|
62
|
-
factoryOwnerUserId: project.createdBy
|
|
63
|
-
});
|
|
64
|
-
await primeTenantCredentialsForTenant({
|
|
65
|
-
orgId: project.orgId,
|
|
66
|
-
userId: project.createdBy,
|
|
67
|
-
credentialScope: sessionModel.modelScope
|
|
68
|
-
});
|
|
69
|
-
await hydrateFactorySession(session, {
|
|
70
|
-
orgId: project.orgId,
|
|
71
|
-
modelScope: sessionModel.modelScope,
|
|
72
|
-
ownerUserId: project.createdBy,
|
|
73
|
-
defaultModelId: sessionModel.modelId
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
//#endregion
|
|
77
|
-
export { hydrateSupervisorSession, parseSupervisorResourceId, resolveSupervisorScope, supervisorResourceId, supervisorThreadId };
|
|
78
|
-
|
|
79
|
-
//# sourceMappingURL=session.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","names":[],"sources":["../../src/supervisor/session.ts"],"sourcesContent":["/**\n * The supervisor session: one per factory, addressed by a self-describing\n * resourceId so a restarted server can recover its scope without a lookup\n * table. The session has no repository, no sandbox and no work-item seat —\n * its tools talk to storage directly.\n */\n\nimport type { MastraCodeState } from '@mastra/code-sdk/schema';\nimport type { AgentController, AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { RequestContext } from '@mastra/core/request-context';\n\nimport { getFactoryAuthOrgId, getFactoryAuthUserFromContext } from '../auth.js';\nimport { primeTenantCredentialsForTenant } from '../routes/tenant-credentials.js';\nimport { hydrateFactorySession, resolveFactorySessionModel } from '../session/factory-session.js';\nimport type { ModelDefaultsStorage } from '../storage/domains/model-defaults/base.js';\nimport type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';\nimport type { SupervisorScope } from './read-tools.js';\n\nconst RESOURCE_PREFIX = 'factory-supervisor:';\n\ntype FactorySession = Awaited<ReturnType<AgentController<MastraCodeState>['createSession']>>;\n\nexport function supervisorResourceId(factoryProjectId: string): string {\n return `${RESOURCE_PREFIX}${factoryProjectId}`;\n}\n\n/** The supervisor thread shares the session's id: one thread per factory. */\nexport function supervisorThreadId(factoryProjectId: string): string {\n return supervisorResourceId(factoryProjectId);\n}\n\nexport function parseSupervisorResourceId(resourceId: string | undefined | null): string | null {\n if (!resourceId?.startsWith(RESOURCE_PREFIX)) return null;\n const factoryProjectId = resourceId.slice(RESOURCE_PREFIX.length);\n return factoryProjectId.length > 0 ? factoryProjectId : null;\n}\n\n/**\n * Scope a request to a supervisor session the caller is allowed to drive:\n * the resourceId must name a project, and the caller's org must own it.\n * Anything else yields null and the supervisor tools stay unregistered.\n */\nexport async function resolveSupervisorScope(options: {\n requestContext: RequestContext | undefined;\n projects: Pick<FactoryProjectsStorage, 'get'>;\n}): Promise<SupervisorScope | null> {\n const { requestContext } = options;\n if (!requestContext || typeof requestContext.get !== 'function') return null;\n const context = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n const factoryProjectId = parseSupervisorResourceId(context?.resourceId);\n if (!factoryProjectId) return null;\n const orgId = getFactoryAuthOrgId(getFactoryAuthUserFromContext(requestContext));\n if (!orgId) return null;\n const project = await options.projects.get({ orgId, id: factoryProjectId });\n if (!project) return null;\n return { orgId, factoryProjectId };\n}\n\n/**\n * Session-start hook: stamp the owning project onto a supervisor session and\n * apply the factory's default model. Runs on every (re)creation so a restarted\n * server heals the in-memory state. Sessions\n * that are not supervisors are left untouched.\n */\nexport async function hydrateSupervisorSession(\n session: FactorySession,\n deps: {\n projects: FactoryProjectsStorage;\n modelDefaults: ModelDefaultsStorage;\n },\n): Promise<void> {\n const factoryProjectId = parseSupervisorResourceId(session.identity.getResourceId());\n if (!factoryProjectId) return;\n const project = await deps.projects.getById({ id: factoryProjectId });\n if (!project) return;\n const sessionModel = await resolveFactorySessionModel({\n projects: deps.projects,\n modelDefaults: deps.modelDefaults,\n factoryProjectId,\n orgId: project.orgId,\n ownerUserId: project.createdBy,\n context: 'run',\n });\n await session.state.set({\n factoryProjectId,\n factoryOrgId: project.orgId,\n factoryModelScope: sessionModel.modelScope,\n factoryOwnerUserId: project.createdBy,\n });\n await primeTenantCredentialsForTenant({\n orgId: project.orgId,\n userId: project.createdBy,\n credentialScope: sessionModel.modelScope,\n });\n await hydrateFactorySession(session, {\n orgId: project.orgId,\n modelScope: sessionModel.modelScope,\n ownerUserId: project.createdBy,\n defaultModelId: sessionModel.modelId,\n });\n}\n"],"mappings":";;;;AAkBA,MAAM,kBAAkB;AAIxB,SAAgB,qBAAqB,kBAAkC;CACrE,OAAO,GAAG,kBAAkB;AAC9B;;AAGA,SAAgB,mBAAmB,kBAAkC;CACnE,OAAO,qBAAqB,gBAAgB;AAC9C;AAEA,SAAgB,0BAA0B,YAAsD;CAC9F,IAAI,CAAC,YAAY,WAAW,eAAe,GAAG,OAAO;CACrD,MAAM,mBAAmB,WAAW,MAAM,EAAsB;CAChE,OAAO,iBAAiB,SAAS,IAAI,mBAAmB;AAC1D;;;;;;AAOA,eAAsB,uBAAuB,SAGT;CAClC,MAAM,EAAE,mBAAmB;CAC3B,IAAI,CAAC,kBAAkB,OAAO,eAAe,QAAQ,YAAY,OAAO;CAExE,MAAM,mBAAmB,0BADT,eAAe,IAAI,YACsB,CAAC,EAAE,UAAU;CACtE,IAAI,CAAC,kBAAkB,OAAO;CAC9B,MAAM,QAAQ,oBAAoB,8BAA8B,cAAc,CAAC;CAC/E,IAAI,CAAC,OAAO,OAAO;CAEnB,IAAI,CAAC,MADiB,QAAQ,SAAS,IAAI;EAAE;EAAO,IAAI;CAAiB,CAAC,GAC5D,OAAO;CACrB,OAAO;EAAE;EAAO;CAAiB;AACnC;;;;;;;AAQA,eAAsB,yBACpB,SACA,MAIe;CACf,MAAM,mBAAmB,0BAA0B,QAAQ,SAAS,cAAc,CAAC;CACnF,IAAI,CAAC,kBAAkB;CACvB,MAAM,UAAU,MAAM,KAAK,SAAS,QAAQ,EAAE,IAAI,iBAAiB,CAAC;CACpE,IAAI,CAAC,SAAS;CACd,MAAM,eAAe,MAAM,2BAA2B;EACpD,UAAU,KAAK;EACf,eAAe,KAAK;EACpB;EACA,OAAO,QAAQ;EACf,aAAa,QAAQ;EACrB,SAAS;CACX,CAAC;CACD,MAAM,QAAQ,MAAM,IAAI;EACtB;EACA,cAAc,QAAQ;EACtB,mBAAmB,aAAa;EAChC,oBAAoB,QAAQ;CAC9B,CAAC;CACD,MAAM,gCAAgC;EACpC,OAAO,QAAQ;EACf,QAAQ,QAAQ;EAChB,iBAAiB,aAAa;CAChC,CAAC;CACD,MAAM,sBAAsB,SAAS;EACnC,OAAO,QAAQ;EACf,YAAY,aAAa;EACzB,aAAa,QAAQ;EACrB,gBAAgB,aAAa;CAC/B,CAAC;AACH"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { BoardRegistry } from '../boards/index.js';
|
|
2
|
-
import type { IntegrationTools } from '../integrations/base.js';
|
|
3
|
-
import type { FactoryTransitionService } from '../rules/transition-service.js';
|
|
4
|
-
import type { AuditRecorder } from '../storage/domains/audit/domain.js';
|
|
5
|
-
import type { WorkItemRow, WorkItemsStorage } from '../storage/domains/work-items/base.js';
|
|
6
|
-
import type { SupervisorScope } from './read-tools.js';
|
|
7
|
-
import type { WorkerMessageResult } from './session-messaging.js';
|
|
8
|
-
interface SupervisorWriteDependencies {
|
|
9
|
-
scope: SupervisorScope;
|
|
10
|
-
userId: string;
|
|
11
|
-
workItems: WorkItemsStorage;
|
|
12
|
-
boards: BoardRegistry;
|
|
13
|
-
audit: AuditRecorder;
|
|
14
|
-
transitionService: FactoryTransitionService;
|
|
15
|
-
reconcileAcceptanceLabels?: (input: {
|
|
16
|
-
orgId: string;
|
|
17
|
-
factoryProjectId: string;
|
|
18
|
-
item: WorkItemRow;
|
|
19
|
-
}) => Promise<void>;
|
|
20
|
-
messageSession?: (input: {
|
|
21
|
-
sessionId: string;
|
|
22
|
-
message: string;
|
|
23
|
-
userId: string;
|
|
24
|
-
delivery: 'send' | 'queue';
|
|
25
|
-
}) => Promise<WorkerMessageResult>;
|
|
26
|
-
now?: () => Date;
|
|
27
|
-
}
|
|
28
|
-
export declare function createFactorySupervisorWriteTools(deps: SupervisorWriteDependencies): IntegrationTools;
|
|
29
|
-
export {};
|
|
30
|
-
//# sourceMappingURL=write-tools.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"write-tools.d.ts","sourceRoot":"","sources":["../../src/supervisor/write-tools.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAG/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAElE,UAAU,2BAA2B;IACnC,KAAK,EAAE,eAAe,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,gBAAgB,CAAC;IAC5B,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,aAAa,CAAC;IACrB,iBAAiB,EAAE,wBAAwB,CAAC;IAC5C,yBAAyB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;KAC5B,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACnC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,2BAA2B,GAAG,gBAAgB,CA6NrG"}
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import { BOARD_IDENTIFIER_RE } from "../rules/validation.js";
|
|
2
|
-
import { boardForWorkItem } from "../boards/semantics.js";
|
|
3
|
-
import "../boards/index.js";
|
|
4
|
-
import { factoryDispatchFailureMetadata } from "../rules/dispatch-errors.js";
|
|
5
|
-
import { overtakenDecisionIds } from "../rules/decision-applicability.js";
|
|
6
|
-
import { z } from "zod";
|
|
7
|
-
import { createTool } from "@mastra/core/tools";
|
|
8
|
-
//#region src/supervisor/write-tools.ts
|
|
9
|
-
function createFactorySupervisorWriteTools(deps) {
|
|
10
|
-
const now = deps.now ?? (() => /* @__PURE__ */ new Date());
|
|
11
|
-
const audit = async (action, target, metadata = {}) => deps.audit.record({
|
|
12
|
-
orgId: deps.scope.orgId,
|
|
13
|
-
actorId: deps.userId,
|
|
14
|
-
actorType: "human",
|
|
15
|
-
action,
|
|
16
|
-
targets: [target],
|
|
17
|
-
factoryProjectId: deps.scope.factoryProjectId,
|
|
18
|
-
metadata: {
|
|
19
|
-
...metadata,
|
|
20
|
-
cause: "supervisor"
|
|
21
|
-
},
|
|
22
|
-
occurredAt: now()
|
|
23
|
-
});
|
|
24
|
-
return {
|
|
25
|
-
factory_retry_decision: createTool({
|
|
26
|
-
id: "factory_retry_decision",
|
|
27
|
-
description: "Retry one failed Factory decision after the person confirms the repair.",
|
|
28
|
-
inputSchema: z.object({ decisionId: z.string().min(1) }),
|
|
29
|
-
requireApproval: true,
|
|
30
|
-
execute: async ({ decisionId }) => {
|
|
31
|
-
const current = await deps.workItems.getDeferredDecision(deps.scope.orgId, deps.scope.factoryProjectId, decisionId);
|
|
32
|
-
if (!current || current.status !== "failed") throw new Error("The decision is not failed, no longer exists, or belongs to another factory.");
|
|
33
|
-
const failure = factoryDispatchFailureMetadata(current.failureCode);
|
|
34
|
-
if (!failure.canRetry) throw new Error(`This failure (${failure.label}) cannot be fixed by a retry; repair the cause and start a new run instead.`);
|
|
35
|
-
if ((await overtakenDecisionIds(deps.workItems, deps.boards, deps.scope, [current])).size > 0) throw new Error("The work item has moved on from the phase this run was decided for; it cannot be retried.");
|
|
36
|
-
const decision = await deps.workItems.retryDeferredDecision(deps.scope.orgId, deps.scope.factoryProjectId, decisionId, now());
|
|
37
|
-
if (!decision) throw new Error("The decision is not failed, no longer exists, or belongs to another factory.");
|
|
38
|
-
await audit("factory.run.retry", {
|
|
39
|
-
type: "rule_decision",
|
|
40
|
-
id: decisionId
|
|
41
|
-
}, { workItemId: decision.workItemId });
|
|
42
|
-
return {
|
|
43
|
-
decisionId,
|
|
44
|
-
status: decision.status,
|
|
45
|
-
workItemId: decision.workItemId
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
}),
|
|
49
|
-
factory_dismiss_decision: createTool({
|
|
50
|
-
id: "factory_dismiss_decision",
|
|
51
|
-
description: "Dismiss one parked Factory proposal after the person confirms it is no longer wanted.",
|
|
52
|
-
inputSchema: z.object({ decisionId: z.string().min(1) }),
|
|
53
|
-
requireApproval: true,
|
|
54
|
-
execute: async ({ decisionId }) => {
|
|
55
|
-
const decision = await deps.workItems.dismissDeferredDecision(deps.scope.orgId, deps.scope.factoryProjectId, decisionId, now());
|
|
56
|
-
if (!decision) throw new Error("The decision is not proposed, no longer exists, or belongs to another factory.");
|
|
57
|
-
await audit("factory.run.dismissed", {
|
|
58
|
-
type: "rule_decision",
|
|
59
|
-
id: decisionId
|
|
60
|
-
}, { workItemId: decision.workItemId });
|
|
61
|
-
return {
|
|
62
|
-
decisionId,
|
|
63
|
-
status: decision.status,
|
|
64
|
-
workItemId: decision.workItemId
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
}),
|
|
68
|
-
factory_resolve_proposal: createTool({
|
|
69
|
-
id: "factory_resolve_proposal",
|
|
70
|
-
description: "Approve or dismiss one proposed Factory decision after the person confirms the choice.",
|
|
71
|
-
inputSchema: z.object({
|
|
72
|
-
decisionId: z.string().min(1),
|
|
73
|
-
resolution: z.enum(["approve", "dismiss"])
|
|
74
|
-
}),
|
|
75
|
-
requireApproval: true,
|
|
76
|
-
execute: async ({ decisionId, resolution }) => {
|
|
77
|
-
const decision = resolution === "approve" ? await deps.workItems.approveDeferredDecision(deps.scope.orgId, deps.scope.factoryProjectId, decisionId, now(), deps.userId) : await deps.workItems.dismissDeferredDecision(deps.scope.orgId, deps.scope.factoryProjectId, decisionId, now());
|
|
78
|
-
if (!decision) throw new Error("The proposal is no longer open or belongs to another factory.");
|
|
79
|
-
await audit(resolution === "approve" ? "factory.run.approved" : "factory.run.dismissed", {
|
|
80
|
-
type: "rule_decision",
|
|
81
|
-
id: decisionId
|
|
82
|
-
}, { workItemId: decision.workItemId });
|
|
83
|
-
return {
|
|
84
|
-
decisionId,
|
|
85
|
-
resolution,
|
|
86
|
-
status: decision.status,
|
|
87
|
-
workItemId: decision.workItemId
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
}),
|
|
91
|
-
factory_transition_work_item: createTool({
|
|
92
|
-
id: "factory_transition_work_item",
|
|
93
|
-
description: "Move or accept one Factory work item after the person confirms the destination stage.",
|
|
94
|
-
inputSchema: z.object({
|
|
95
|
-
workItemId: z.string().min(1),
|
|
96
|
-
stage: z.string().max(128).regex(BOARD_IDENTIFIER_RE)
|
|
97
|
-
}),
|
|
98
|
-
requireApproval: true,
|
|
99
|
-
execute: async ({ workItemId, stage }) => {
|
|
100
|
-
const item = await deps.workItems.get({
|
|
101
|
-
orgId: deps.scope.orgId,
|
|
102
|
-
id: workItemId
|
|
103
|
-
});
|
|
104
|
-
if (!item || item.factoryProjectId !== deps.scope.factoryProjectId) throw new Error("Work item not found.");
|
|
105
|
-
if (!(item.stages.length === 1 ? item.stages[0] : void 0)) throw new Error("The work item does not have one valid Factory stage.");
|
|
106
|
-
const result = await deps.transitionService.transition({
|
|
107
|
-
orgId: deps.scope.orgId,
|
|
108
|
-
factoryProjectId: deps.scope.factoryProjectId,
|
|
109
|
-
workItemId,
|
|
110
|
-
board: boardForWorkItem(item),
|
|
111
|
-
stage,
|
|
112
|
-
expectedRevision: item.revision,
|
|
113
|
-
actor: {
|
|
114
|
-
type: "human",
|
|
115
|
-
id: deps.userId
|
|
116
|
-
},
|
|
117
|
-
ingress: {
|
|
118
|
-
type: "human",
|
|
119
|
-
identity: `supervisor:${deps.userId}:${workItemId}:${item.revision}:${stage}`
|
|
120
|
-
},
|
|
121
|
-
cause: "supervisor"
|
|
122
|
-
});
|
|
123
|
-
if (result.status !== "accepted") throw new Error(`The transition was rejected (${result.code}): ${result.reason}`);
|
|
124
|
-
return result;
|
|
125
|
-
}
|
|
126
|
-
}),
|
|
127
|
-
factory_reconcile_labels: createTool({
|
|
128
|
-
id: "factory_reconcile_labels",
|
|
129
|
-
description: "Reconcile stale acceptance labels for one accepted work item after the person confirms the repair.",
|
|
130
|
-
inputSchema: z.object({ workItemId: z.string().min(1) }),
|
|
131
|
-
requireApproval: true,
|
|
132
|
-
execute: async ({ workItemId }) => {
|
|
133
|
-
if (!deps.reconcileAcceptanceLabels) throw new Error("Acceptance-label reconciliation is unavailable.");
|
|
134
|
-
const item = await deps.workItems.get({
|
|
135
|
-
orgId: deps.scope.orgId,
|
|
136
|
-
id: workItemId
|
|
137
|
-
});
|
|
138
|
-
if (!item || item.factoryProjectId !== deps.scope.factoryProjectId) throw new Error("Work item not found.");
|
|
139
|
-
if (!item.acceptedAt) throw new Error("The work item has not been accepted.");
|
|
140
|
-
await deps.reconcileAcceptanceLabels({
|
|
141
|
-
...deps.scope,
|
|
142
|
-
item
|
|
143
|
-
});
|
|
144
|
-
await audit("factory.work_item.labels_reconciled", {
|
|
145
|
-
type: "work_item",
|
|
146
|
-
id: workItemId
|
|
147
|
-
});
|
|
148
|
-
return {
|
|
149
|
-
workItemId,
|
|
150
|
-
reconciled: true
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
}),
|
|
154
|
-
factory_revoke_binding: createTool({
|
|
155
|
-
id: "factory_revoke_binding",
|
|
156
|
-
description: "Revoke an orphaned or stale run binding after a health finding and person confirmation.",
|
|
157
|
-
inputSchema: z.object({ bindingId: z.string().min(1) }),
|
|
158
|
-
requireApproval: true,
|
|
159
|
-
execute: async ({ bindingId }) => {
|
|
160
|
-
const binding = await deps.workItems.revokeRunBinding({
|
|
161
|
-
orgId: deps.scope.orgId,
|
|
162
|
-
factoryProjectId: deps.scope.factoryProjectId,
|
|
163
|
-
bindingId,
|
|
164
|
-
revokedAt: now()
|
|
165
|
-
});
|
|
166
|
-
if (!binding) throw new Error("The binding is not active, no longer exists, or belongs to another factory.");
|
|
167
|
-
await audit("factory.intake.binding_updated", {
|
|
168
|
-
type: "run_binding",
|
|
169
|
-
id: bindingId
|
|
170
|
-
}, {
|
|
171
|
-
workItemId: binding.workItemId,
|
|
172
|
-
role: binding.role,
|
|
173
|
-
status: "revoked"
|
|
174
|
-
});
|
|
175
|
-
return {
|
|
176
|
-
bindingId,
|
|
177
|
-
status: binding.status,
|
|
178
|
-
workItemId: binding.workItemId,
|
|
179
|
-
role: binding.role
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
}),
|
|
183
|
-
factory_signal_session: createTool({
|
|
184
|
-
id: "factory_signal_session",
|
|
185
|
-
description: "Send bounded guidance to a worker session after the person confirms the exact message. Use queue only when the guidance should wait for the current run to finish.",
|
|
186
|
-
inputSchema: z.object({
|
|
187
|
-
sessionId: z.string().min(1),
|
|
188
|
-
message: z.string().trim().min(1).max(2e3),
|
|
189
|
-
delivery: z.enum(["send", "queue"]).default("send")
|
|
190
|
-
}),
|
|
191
|
-
requireApproval: true,
|
|
192
|
-
execute: async ({ sessionId, message, delivery }) => {
|
|
193
|
-
if (!deps.messageSession) throw new Error("Worker session messaging is unavailable.");
|
|
194
|
-
const binding = (await deps.workItems.listRunBindings(deps.scope.orgId, deps.scope.factoryProjectId)).find((row) => row.sessionId === sessionId);
|
|
195
|
-
if (!binding) throw new Error("The session does not belong to this factory.");
|
|
196
|
-
if ((await deps.messageSession({
|
|
197
|
-
sessionId,
|
|
198
|
-
message,
|
|
199
|
-
userId: deps.userId,
|
|
200
|
-
delivery
|
|
201
|
-
}))?.status === "interrupted") return {
|
|
202
|
-
sessionId,
|
|
203
|
-
delivered: false,
|
|
204
|
-
status: "interrupted",
|
|
205
|
-
delivery,
|
|
206
|
-
workItemId: binding.workItemId,
|
|
207
|
-
role: binding.role
|
|
208
|
-
};
|
|
209
|
-
await audit("factory.agent.signaled", {
|
|
210
|
-
type: "factory_session",
|
|
211
|
-
id: sessionId
|
|
212
|
-
}, {
|
|
213
|
-
workItemId: binding.workItemId,
|
|
214
|
-
role: binding.role,
|
|
215
|
-
delivery
|
|
216
|
-
});
|
|
217
|
-
return {
|
|
218
|
-
sessionId,
|
|
219
|
-
delivered: true,
|
|
220
|
-
delivery,
|
|
221
|
-
workItemId: binding.workItemId,
|
|
222
|
-
role: binding.role
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
})
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
//#endregion
|
|
229
|
-
export { createFactorySupervisorWriteTools };
|
|
230
|
-
|
|
231
|
-
//# sourceMappingURL=write-tools.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"write-tools.js","names":[],"sources":["../../src/supervisor/write-tools.ts"],"sourcesContent":["import { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { boardForWorkItem } from '../boards/index.js';\nimport type { BoardRegistry } from '../boards/index.js';\nimport type { IntegrationTools } from '../integrations/base.js';\nimport { overtakenDecisionIds } from '../rules/decision-applicability.js';\nimport { factoryDispatchFailureMetadata } from '../rules/dispatch-errors.js';\nimport type { FactoryTransitionService } from '../rules/transition-service.js';\nimport { BOARD_IDENTIFIER_RE, MAX_BOARD_IDENTIFIER_LENGTH } from '../rules/validation.js';\nimport type { AuditAction } from '../storage/domains/audit/actions.js';\nimport type { AuditRecorder } from '../storage/domains/audit/domain.js';\nimport type { WorkItemRow, WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport type { SupervisorScope } from './read-tools.js';\nimport type { WorkerMessageResult } from './session-messaging.js';\n\ninterface SupervisorWriteDependencies {\n scope: SupervisorScope;\n userId: string;\n workItems: WorkItemsStorage;\n boards: BoardRegistry;\n audit: AuditRecorder;\n transitionService: FactoryTransitionService;\n reconcileAcceptanceLabels?: (input: { orgId: string; factoryProjectId: string; item: WorkItemRow }) => Promise<void>;\n messageSession?: (input: {\n sessionId: string;\n message: string;\n userId: string;\n delivery: 'send' | 'queue';\n }) => Promise<WorkerMessageResult>;\n now?: () => Date;\n}\n\nexport function createFactorySupervisorWriteTools(deps: SupervisorWriteDependencies): IntegrationTools {\n const now = deps.now ?? (() => new Date());\n const audit = async (\n action: AuditAction,\n target: { type: string; id: string },\n metadata: Record<string, unknown> = {},\n ) =>\n deps.audit.record({\n orgId: deps.scope.orgId,\n actorId: deps.userId,\n actorType: 'human',\n action,\n targets: [target],\n factoryProjectId: deps.scope.factoryProjectId,\n metadata: { ...metadata, cause: 'supervisor' },\n occurredAt: now(),\n });\n\n return {\n factory_retry_decision: createTool({\n id: 'factory_retry_decision',\n description: 'Retry one failed Factory decision after the person confirms the repair.',\n inputSchema: z.object({ decisionId: z.string().min(1) }),\n requireApproval: true,\n execute: async ({ decisionId }) => {\n const current = await deps.workItems.getDeferredDecision(\n deps.scope.orgId,\n deps.scope.factoryProjectId,\n decisionId,\n );\n if (!current || current.status !== 'failed') {\n throw new Error('The decision is not failed, no longer exists, or belongs to another factory.');\n }\n const failure = factoryDispatchFailureMetadata(current.failureCode);\n if (!failure.canRetry) {\n throw new Error(\n `This failure (${failure.label}) cannot be fixed by a retry; repair the cause and start a new run instead.`,\n );\n }\n if ((await overtakenDecisionIds(deps.workItems, deps.boards, deps.scope, [current])).size > 0) {\n throw new Error('The work item has moved on from the phase this run was decided for; it cannot be retried.');\n }\n const decision = await deps.workItems.retryDeferredDecision(\n deps.scope.orgId,\n deps.scope.factoryProjectId,\n decisionId,\n now(),\n );\n if (!decision) throw new Error('The decision is not failed, no longer exists, or belongs to another factory.');\n await audit(\n 'factory.run.retry',\n { type: 'rule_decision', id: decisionId },\n { workItemId: decision.workItemId },\n );\n return { decisionId, status: decision.status, workItemId: decision.workItemId };\n },\n }),\n factory_dismiss_decision: createTool({\n id: 'factory_dismiss_decision',\n description: 'Dismiss one parked Factory proposal after the person confirms it is no longer wanted.',\n inputSchema: z.object({ decisionId: z.string().min(1) }),\n requireApproval: true,\n execute: async ({ decisionId }) => {\n const decision = await deps.workItems.dismissDeferredDecision(\n deps.scope.orgId,\n deps.scope.factoryProjectId,\n decisionId,\n now(),\n );\n if (!decision)\n throw new Error('The decision is not proposed, no longer exists, or belongs to another factory.');\n await audit(\n 'factory.run.dismissed',\n { type: 'rule_decision', id: decisionId },\n { workItemId: decision.workItemId },\n );\n return { decisionId, status: decision.status, workItemId: decision.workItemId };\n },\n }),\n factory_resolve_proposal: createTool({\n id: 'factory_resolve_proposal',\n description: 'Approve or dismiss one proposed Factory decision after the person confirms the choice.',\n inputSchema: z.object({ decisionId: z.string().min(1), resolution: z.enum(['approve', 'dismiss']) }),\n requireApproval: true,\n execute: async ({ decisionId, resolution }) => {\n const decision =\n resolution === 'approve'\n ? await deps.workItems.approveDeferredDecision(\n deps.scope.orgId,\n deps.scope.factoryProjectId,\n decisionId,\n now(),\n deps.userId,\n )\n : await deps.workItems.dismissDeferredDecision(\n deps.scope.orgId,\n deps.scope.factoryProjectId,\n decisionId,\n now(),\n );\n if (!decision) throw new Error('The proposal is no longer open or belongs to another factory.');\n await audit(\n resolution === 'approve' ? 'factory.run.approved' : 'factory.run.dismissed',\n {\n type: 'rule_decision',\n id: decisionId,\n },\n { workItemId: decision.workItemId },\n );\n return { decisionId, resolution, status: decision.status, workItemId: decision.workItemId };\n },\n }),\n factory_transition_work_item: createTool({\n id: 'factory_transition_work_item',\n description: 'Move or accept one Factory work item after the person confirms the destination stage.',\n inputSchema: z.object({\n workItemId: z.string().min(1),\n stage: z.string().max(MAX_BOARD_IDENTIFIER_LENGTH).regex(BOARD_IDENTIFIER_RE),\n }),\n requireApproval: true,\n execute: async ({ workItemId, stage }) => {\n const item = await deps.workItems.get({ orgId: deps.scope.orgId, id: workItemId });\n if (!item || item.factoryProjectId !== deps.scope.factoryProjectId) throw new Error('Work item not found.');\n const from = item.stages.length === 1 ? item.stages[0] : undefined;\n if (!from) throw new Error('The work item does not have one valid Factory stage.');\n const result = await deps.transitionService.transition({\n orgId: deps.scope.orgId,\n factoryProjectId: deps.scope.factoryProjectId,\n workItemId,\n board: boardForWorkItem(item),\n stage,\n expectedRevision: item.revision,\n actor: { type: 'human', id: deps.userId },\n ingress: { type: 'human', identity: `supervisor:${deps.userId}:${workItemId}:${item.revision}:${stage}` },\n cause: 'supervisor',\n });\n if (result.status !== 'accepted') {\n throw new Error(`The transition was rejected (${result.code}): ${result.reason}`);\n }\n return result;\n },\n }),\n factory_reconcile_labels: createTool({\n id: 'factory_reconcile_labels',\n description: 'Reconcile stale acceptance labels for one accepted work item after the person confirms the repair.',\n inputSchema: z.object({ workItemId: z.string().min(1) }),\n requireApproval: true,\n execute: async ({ workItemId }) => {\n if (!deps.reconcileAcceptanceLabels) throw new Error('Acceptance-label reconciliation is unavailable.');\n const item = await deps.workItems.get({ orgId: deps.scope.orgId, id: workItemId });\n if (!item || item.factoryProjectId !== deps.scope.factoryProjectId) throw new Error('Work item not found.');\n if (!item.acceptedAt) throw new Error('The work item has not been accepted.');\n await deps.reconcileAcceptanceLabels({ ...deps.scope, item });\n await audit('factory.work_item.labels_reconciled', { type: 'work_item', id: workItemId });\n return { workItemId, reconciled: true };\n },\n }),\n factory_revoke_binding: createTool({\n id: 'factory_revoke_binding',\n description: 'Revoke an orphaned or stale run binding after a health finding and person confirmation.',\n inputSchema: z.object({ bindingId: z.string().min(1) }),\n requireApproval: true,\n execute: async ({ bindingId }) => {\n const binding = await deps.workItems.revokeRunBinding({\n orgId: deps.scope.orgId,\n factoryProjectId: deps.scope.factoryProjectId,\n bindingId,\n revokedAt: now(),\n });\n if (!binding) throw new Error('The binding is not active, no longer exists, or belongs to another factory.');\n await audit(\n 'factory.intake.binding_updated',\n { type: 'run_binding', id: bindingId },\n {\n workItemId: binding.workItemId,\n role: binding.role,\n status: 'revoked',\n },\n );\n return { bindingId, status: binding.status, workItemId: binding.workItemId, role: binding.role };\n },\n }),\n factory_signal_session: createTool({\n id: 'factory_signal_session',\n description:\n 'Send bounded guidance to a worker session after the person confirms the exact message. Use queue only when the guidance should wait for the current run to finish.',\n inputSchema: z.object({\n sessionId: z.string().min(1),\n message: z.string().trim().min(1).max(2000),\n delivery: z.enum(['send', 'queue']).default('send'),\n }),\n requireApproval: true,\n execute: async ({ sessionId, message, delivery }) => {\n if (!deps.messageSession) throw new Error('Worker session messaging is unavailable.');\n const bindings = await deps.workItems.listRunBindings(deps.scope.orgId, deps.scope.factoryProjectId);\n const binding = bindings.find(row => row.sessionId === sessionId);\n if (!binding) throw new Error('The session does not belong to this factory.');\n const result = await deps.messageSession({ sessionId, message, userId: deps.userId, delivery });\n if (result?.status === 'interrupted') {\n return {\n sessionId,\n delivered: false,\n status: 'interrupted',\n delivery,\n workItemId: binding.workItemId,\n role: binding.role,\n };\n }\n await audit(\n 'factory.agent.signaled',\n { type: 'factory_session', id: sessionId },\n {\n workItemId: binding.workItemId,\n role: binding.role,\n delivery,\n },\n );\n return { sessionId, delivered: true, delivery, workItemId: binding.workItemId, role: binding.role };\n },\n }),\n };\n}\n"],"mappings":"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"}
|