@shipfox/api-definitions 6.0.0 → 8.0.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/.turbo/turbo-build.log +11 -13
- package/CHANGELOG.md +27 -0
- package/dist/config.d.ts +0 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -14
- package/dist/config.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/integrations.d.ts +1 -1
- package/dist/core/integrations.d.ts.map +1 -1
- package/dist/core/integrations.js +1 -1
- package/dist/core/integrations.js.map +1 -1
- package/dist/core/parse-definition.d.ts +3 -3
- package/dist/core/parse-definition.d.ts.map +1 -1
- package/dist/core/parse-definition.js.map +1 -1
- package/dist/core/sync-definitions.d.ts +2 -0
- package/dist/core/sync-definitions.d.ts.map +1 -1
- package/dist/core/sync-definitions.js +9 -3
- package/dist/core/sync-definitions.js.map +1 -1
- package/dist/core/validate-definition.d.ts +3 -3
- package/dist/core/validate-definition.d.ts.map +1 -1
- package/dist/core/validate-definition.js +3 -3
- package/dist/core/validate-definition.js.map +1 -1
- package/dist/core/workflow-model/normalize-jobs.d.ts +2 -2
- package/dist/core/workflow-model/normalize-jobs.d.ts.map +1 -1
- package/dist/core/workflow-model/normalize-jobs.js +9 -11
- package/dist/core/workflow-model/normalize-jobs.js.map +1 -1
- package/dist/core/workflow-model/normalize-workflow-document.d.ts +3 -3
- package/dist/core/workflow-model/normalize-workflow-document.d.ts.map +1 -1
- package/dist/core/workflow-model/normalize-workflow-document.js +2 -4
- package/dist/core/workflow-model/normalize-workflow-document.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/presentation/routes/create-definition.d.ts +4 -2
- package/dist/presentation/routes/create-definition.d.ts.map +1 -1
- package/dist/presentation/routes/create-definition.js +5 -1
- package/dist/presentation/routes/create-definition.js.map +1 -1
- package/dist/presentation/routes/get-definition.d.ts +1 -1
- package/dist/presentation/routes/get-definition.d.ts.map +1 -1
- package/dist/presentation/routes/get-definition.js.map +1 -1
- package/dist/presentation/routes/index.js +2 -2
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/presentation/routes/list-definitions.d.ts +1 -1
- package/dist/presentation/routes/list-definitions.d.ts.map +1 -1
- package/dist/presentation/routes/list-definitions.js.map +1 -1
- package/dist/presentation/routes/project-access.d.ts +1 -1
- package/dist/presentation/routes/project-access.d.ts.map +1 -1
- package/dist/presentation/routes/project-access.js.map +1 -1
- package/dist/presentation/routes/validate-definition.d.ts +2 -1
- package/dist/presentation/routes/validate-definition.d.ts.map +1 -1
- package/dist/presentation/routes/validate-definition.js +26 -22
- package/dist/presentation/routes/validate-definition.js.map +1 -1
- package/dist/temporal/activities/sync-activities.d.ts +3 -2
- package/dist/temporal/activities/sync-activities.d.ts.map +1 -1
- package/dist/temporal/activities/sync-activities.js +8 -7
- package/dist/temporal/activities/sync-activities.js.map +1 -1
- package/dist/temporal/workflows/index.bundle.js +17195 -3337
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +10 -28
- package/src/config.ts +1 -19
- package/src/core/index.ts +4 -1
- package/src/core/integrations.ts +1 -1
- package/src/core/parse-definition.test.ts +6 -1
- package/src/core/parse-definition.ts +3 -3
- package/src/core/sync-definitions.test.ts +9 -2
- package/src/core/sync-definitions.ts +13 -6
- package/src/core/validate-definition.test.ts +18 -4
- package/src/core/validate-definition.ts +5 -6
- package/src/core/workflow-model/normalize-jobs.ts +22 -23
- package/src/core/workflow-model/normalize-workflow-document.test.ts +37 -18
- package/src/core/workflow-model/normalize-workflow-document.ts +4 -9
- package/src/db/definitions.test.ts +2 -1
- package/src/db/schema/definitions.test.ts +2 -1
- package/src/index.ts +7 -4
- package/src/presentation/dto/definition.test.ts +2 -1
- package/src/presentation/routes/create-definition.test.ts +10 -3
- package/src/presentation/routes/create-definition.ts +7 -3
- package/src/presentation/routes/get-definition.test.ts +1 -1
- package/src/presentation/routes/get-definition.ts +1 -1
- package/src/presentation/routes/index.test.ts +6 -2
- package/src/presentation/routes/index.ts +2 -2
- package/src/presentation/routes/list-definitions.test.ts +1 -1
- package/src/presentation/routes/list-definitions.ts +1 -1
- package/src/presentation/routes/project-access.ts +1 -1
- package/src/presentation/routes/validate-definition.test.ts +8 -2
- package/src/presentation/routes/validate-definition.ts +27 -22
- package/src/temporal/activities/sync-activities.test.ts +19 -8
- package/src/temporal/activities/sync-activities.ts +16 -6
- package/test/agent-validation-catalog.ts +25 -0
- package/test/factories/definition.ts +2 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {WorkflowDefinition} from '#core/entities/workflow-definition.js';
|
|
2
2
|
import {normalizeWorkflowDocument} from '#core/workflow-model/index.js';
|
|
3
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
3
4
|
import {toDefinitionDto} from './definition.js';
|
|
4
5
|
|
|
5
6
|
describe('toDefinitionDto', () => {
|
|
@@ -29,7 +30,7 @@ describe('toDefinitionDto', () => {
|
|
|
29
30
|
name: document.name,
|
|
30
31
|
definition: document,
|
|
31
32
|
document,
|
|
32
|
-
model: normalizeWorkflowDocument(document),
|
|
33
|
+
model: normalizeWorkflowDocument(document, {agentValidationCatalog}),
|
|
33
34
|
sourceSnapshot: null,
|
|
34
35
|
contentHash: null,
|
|
35
36
|
fetchedAt: new Date('2026-06-09T10:00:00.000Z'),
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import {buildUserContext, setUserContext} from '@shipfox/api-auth-context';
|
|
2
|
-
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto';
|
|
3
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';
|
|
3
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
4
4
|
import type {FastifyInstance} from 'fastify';
|
|
5
5
|
import Fastify from 'fastify';
|
|
6
6
|
import {serializerCompiler, validatorCompiler} from 'fastify-type-provider-zod';
|
|
7
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
7
8
|
import {buildCreateDefinitionRoute} from './create-definition.js';
|
|
8
9
|
|
|
9
10
|
const getProjectById = vi.fn();
|
|
10
11
|
const projects = {getProjectById} as Pick<ProjectsModuleClient, 'getProjectById'>;
|
|
12
|
+
const agent = {getValidationCatalog: vi.fn(() => agentValidationCatalog)};
|
|
11
13
|
|
|
12
14
|
describe('POST /api/definitions', () => {
|
|
13
15
|
let app: FastifyInstance;
|
|
@@ -32,7 +34,10 @@ describe('POST /api/definitions', () => {
|
|
|
32
34
|
});
|
|
33
35
|
app.post(
|
|
34
36
|
'/api/definitions',
|
|
35
|
-
buildCreateDefinitionRoute({
|
|
37
|
+
buildCreateDefinitionRoute({
|
|
38
|
+
projects: projects as ProjectsModuleClient,
|
|
39
|
+
agent: agent as never,
|
|
40
|
+
}),
|
|
36
41
|
);
|
|
37
42
|
await app.ready();
|
|
38
43
|
});
|
|
@@ -96,6 +101,7 @@ jobs:
|
|
|
96
101
|
'/api/definitions',
|
|
97
102
|
buildCreateDefinitionRoute({
|
|
98
103
|
projects: projects as ProjectsModuleClient,
|
|
104
|
+
agent: agent as never,
|
|
99
105
|
integrations: {getAgentToolsContext} as Pick<
|
|
100
106
|
IntegrationsModuleClient,
|
|
101
107
|
'getAgentToolsContext'
|
|
@@ -168,6 +174,7 @@ jobs:
|
|
|
168
174
|
'/api/definitions',
|
|
169
175
|
buildCreateDefinitionRoute({
|
|
170
176
|
projects: projects as ProjectsModuleClient,
|
|
177
|
+
agent: agent as never,
|
|
171
178
|
integrations: {getAgentToolsContext} as Pick<
|
|
172
179
|
IntegrationsModuleClient,
|
|
173
180
|
'getAgentToolsContext'
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
1
2
|
import {
|
|
2
3
|
createDefinitionBodySchema,
|
|
3
4
|
definitionResponseSchema,
|
|
4
5
|
definitionValidationErrorSchema,
|
|
5
6
|
} from '@shipfox/api-definitions-dto';
|
|
6
|
-
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto';
|
|
7
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
7
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';
|
|
8
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
8
9
|
import {ClientError, defineRoute} from '@shipfox/node-fastify';
|
|
9
10
|
import {z} from 'zod';
|
|
10
11
|
import {DefinitionParseError} from '#core/errors.js';
|
|
@@ -17,6 +18,7 @@ import {requireProjectAccess} from './project-access.js';
|
|
|
17
18
|
|
|
18
19
|
export interface CreateDefinitionRouteOptions {
|
|
19
20
|
projects: ProjectsModuleClient;
|
|
21
|
+
agent: AgentInterModuleClient;
|
|
20
22
|
integrations?: IntegrationsModuleClient;
|
|
21
23
|
}
|
|
22
24
|
|
|
@@ -50,11 +52,13 @@ export function buildCreateDefinitionRoute(options: CreateDefinitionRouteOptions
|
|
|
50
52
|
const {project_id: projectId, config_path, source, yaml: yamlString, sha, ref} = request.body;
|
|
51
53
|
const project = await requireProjectAccess(request, projectId, options.projects);
|
|
52
54
|
|
|
53
|
-
const
|
|
55
|
+
const agentValidationCatalog = await options.agent.getValidationCatalog({});
|
|
56
|
+
const structurallyParsed = parseDefinition(yamlString, {agentValidationCatalog});
|
|
54
57
|
const {integrations} = options;
|
|
55
58
|
const parsed =
|
|
56
59
|
integrations !== undefined && hasAgentStepIntegrations(structurallyParsed.document)
|
|
57
60
|
? parseDefinition(yamlString, {
|
|
61
|
+
agentValidationCatalog,
|
|
58
62
|
integrationValidationContext: await loadIntegrationValidationContext(
|
|
59
63
|
integrations,
|
|
60
64
|
project.workspaceId,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {buildUserContext, setUserContext} from '@shipfox/api-auth-context';
|
|
2
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
3
3
|
import type {FastifyInstance} from 'fastify';
|
|
4
4
|
import Fastify from 'fastify';
|
|
5
5
|
import {serializerCompiler, validatorCompiler} from 'fastify-type-provider-zod';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {definitionResponseSchema} from '@shipfox/api-definitions-dto';
|
|
2
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
3
3
|
import {ClientError, defineRoute} from '@shipfox/node-fastify';
|
|
4
4
|
import {z} from 'zod';
|
|
5
5
|
import {getDefinitionById} from '#db/definitions.js';
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import {AUTH_USER, buildUserContext, setUserContext} from '@shipfox/api-auth-context';
|
|
2
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
3
3
|
import {type AuthMethod, ClientError, closeApp, createApp} from '@shipfox/node-fastify';
|
|
4
4
|
import type {FastifyRequest} from 'fastify';
|
|
5
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
5
6
|
import {createDefinitionRoutes} from './index.js';
|
|
6
7
|
|
|
7
8
|
const projects = {
|
|
8
9
|
getProjectById: vi.fn(),
|
|
9
10
|
requireProjectForWorkspace: vi.fn(),
|
|
10
11
|
} as unknown as ProjectsModuleClient;
|
|
11
|
-
const definitionRoutes = createDefinitionRoutes({
|
|
12
|
+
const definitionRoutes = createDefinitionRoutes({
|
|
13
|
+
projects,
|
|
14
|
+
agent: {getValidationCatalog: vi.fn(() => agentValidationCatalog)} as never,
|
|
15
|
+
});
|
|
12
16
|
|
|
13
17
|
const fakeUserAuth: AuthMethod = {
|
|
14
18
|
name: AUTH_USER,
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from './create-definition.js';
|
|
7
7
|
import {buildGetDefinitionRoute} from './get-definition.js';
|
|
8
8
|
import {buildListDefinitionsRoute} from './list-definitions.js';
|
|
9
|
-
import {
|
|
9
|
+
import {buildValidateDefinitionRoute} from './validate-definition.js';
|
|
10
10
|
|
|
11
11
|
export interface DefinitionRouteOptions extends CreateDefinitionRouteOptions {}
|
|
12
12
|
|
|
@@ -19,7 +19,7 @@ export function createDefinitionRoutes(options: DefinitionRouteOptions): RouteGr
|
|
|
19
19
|
buildCreateDefinitionRoute(options),
|
|
20
20
|
buildListDefinitionsRoute(options.projects),
|
|
21
21
|
buildGetDefinitionRoute(options.projects),
|
|
22
|
-
|
|
22
|
+
buildValidateDefinitionRoute(options.agent),
|
|
23
23
|
],
|
|
24
24
|
},
|
|
25
25
|
];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {buildUserContext, setUserContext} from '@shipfox/api-auth-context';
|
|
2
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
3
3
|
import {encodeStringIdCursor} from '@shipfox/node-drizzle';
|
|
4
4
|
import type {FastifyInstance} from 'fastify';
|
|
5
5
|
import Fastify from 'fastify';
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
definitionListQuerySchema,
|
|
3
3
|
definitionListResponseSchema,
|
|
4
4
|
} from '@shipfox/api-definitions-dto';
|
|
5
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
5
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
6
6
|
import {decodeStringIdCursor, encodeStringIdCursor} from '@shipfox/node-drizzle';
|
|
7
7
|
import {ClientError, defineRoute} from '@shipfox/node-fastify';
|
|
8
8
|
import {listDefinitions} from '#db/definitions.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {requireWorkspaceAccess} from '@shipfox/api-auth-context';
|
|
2
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
3
3
|
import {ClientError} from '@shipfox/node-fastify';
|
|
4
4
|
import type {FastifyRequest} from 'fastify';
|
|
5
5
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type {FastifyInstance} from 'fastify';
|
|
2
2
|
import Fastify from 'fastify';
|
|
3
3
|
import {serializerCompiler, validatorCompiler} from 'fastify-type-provider-zod';
|
|
4
|
-
import {
|
|
4
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
5
|
+
import {buildValidateDefinitionRoute} from './validate-definition.js';
|
|
5
6
|
|
|
6
7
|
describe('POST /definitions/validate', () => {
|
|
7
8
|
let app: FastifyInstance;
|
|
@@ -10,7 +11,12 @@ describe('POST /definitions/validate', () => {
|
|
|
10
11
|
app = Fastify();
|
|
11
12
|
app.setValidatorCompiler(validatorCompiler);
|
|
12
13
|
app.setSerializerCompiler(serializerCompiler);
|
|
13
|
-
app.post(
|
|
14
|
+
app.post(
|
|
15
|
+
'/definitions/validate',
|
|
16
|
+
buildValidateDefinitionRoute({
|
|
17
|
+
getValidationCatalog: vi.fn(() => agentValidationCatalog),
|
|
18
|
+
} as never),
|
|
19
|
+
);
|
|
14
20
|
await app.ready();
|
|
15
21
|
});
|
|
16
22
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
1
2
|
import {definitionDtoSchema, definitionValidationErrorSchema} from '@shipfox/api-definitions-dto';
|
|
2
3
|
import {defineRoute} from '@shipfox/node-fastify';
|
|
3
4
|
import {z} from 'zod';
|
|
@@ -19,28 +20,32 @@ const validationResultSchema = z.union([
|
|
|
19
20
|
}),
|
|
20
21
|
]);
|
|
21
22
|
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
export function buildValidateDefinitionRoute(agent: AgentInterModuleClient) {
|
|
24
|
+
return defineRoute({
|
|
25
|
+
method: 'POST',
|
|
26
|
+
path: '/validate',
|
|
27
|
+
description: 'Validate a workflow definition without persisting',
|
|
28
|
+
schema: {
|
|
29
|
+
body: validateBodySchema,
|
|
30
|
+
response: {
|
|
31
|
+
200: validationResultSchema,
|
|
32
|
+
},
|
|
30
33
|
},
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
handler: async (request) => {
|
|
35
|
+
const {yaml} = request.body;
|
|
36
|
+
const result = validateDefinition(yaml, {
|
|
37
|
+
agentValidationCatalog: await agent.getValidationCatalog({}),
|
|
38
|
+
});
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
if (result.valid) {
|
|
41
|
+
return {
|
|
42
|
+
valid: true as const,
|
|
43
|
+
workflow_document: result.definition.document,
|
|
44
|
+
workflow_model: result.definition.model,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
});
|
|
48
|
+
return result;
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type {IntegrationSourceControlService} from '@shipfox/api-integration-core';
|
|
2
|
-
import {integrationsInterModuleContract} from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import {integrationsInterModuleContract} from '@shipfox/api-integration-core-dto/inter-module';
|
|
3
3
|
import {createInterModuleKnownError} from '@shipfox/inter-module';
|
|
4
|
+
import {isErrorReported} from '@shipfox/node-error-monitoring';
|
|
4
5
|
import {ApplicationFailure} from '@temporalio/common';
|
|
5
6
|
import {sql} from 'drizzle-orm';
|
|
6
7
|
import {db, definitionSyncStates} from '#db/index.js';
|
|
7
8
|
import {workflowDefinitions} from '#db/schema/definitions.js';
|
|
9
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
8
10
|
import {createDefinitionSyncActivities} from './sync-activities.js';
|
|
9
11
|
|
|
12
|
+
const agent = {getValidationCatalog: vi.fn(() => agentValidationCatalog)} as never;
|
|
13
|
+
|
|
10
14
|
vi.mock('@temporalio/activity', () => ({
|
|
11
15
|
Context: {
|
|
12
16
|
current: () => ({heartbeat: vi.fn()}),
|
|
@@ -78,7 +82,7 @@ describe('definition sync activities', () => {
|
|
|
78
82
|
|
|
79
83
|
describe('prepareDefinitionSync', () => {
|
|
80
84
|
it('marks the sync state as syncing and returns the resolved ref', async () => {
|
|
81
|
-
const activities = createDefinitionSyncActivities(sourceControl());
|
|
85
|
+
const activities = createDefinitionSyncActivities(sourceControl(), agent);
|
|
82
86
|
|
|
83
87
|
const result = await activities.prepareDefinitionSync({
|
|
84
88
|
projectId,
|
|
@@ -99,7 +103,7 @@ describe('definition sync activities', () => {
|
|
|
99
103
|
|
|
100
104
|
it('keeps source ref and source commit sha separate for commit-triggered sync', async () => {
|
|
101
105
|
const source = sourceControl();
|
|
102
|
-
const activities = createDefinitionSyncActivities(source);
|
|
106
|
+
const activities = createDefinitionSyncActivities(source, agent);
|
|
103
107
|
|
|
104
108
|
const result = await activities.prepareDefinitionSync({
|
|
105
109
|
projectId,
|
|
@@ -126,6 +130,7 @@ describe('definition sync activities', () => {
|
|
|
126
130
|
return Promise.reject(new Error('temporary outage'));
|
|
127
131
|
}),
|
|
128
132
|
}),
|
|
133
|
+
agent,
|
|
129
134
|
);
|
|
130
135
|
|
|
131
136
|
const result = activities.prepareDefinitionSync({
|
|
@@ -141,6 +146,8 @@ describe('definition sync activities', () => {
|
|
|
141
146
|
type: 'unknown',
|
|
142
147
|
message: 'temporary outage',
|
|
143
148
|
});
|
|
149
|
+
const error = await result.catch((error: unknown) => error);
|
|
150
|
+
expect(isErrorReported(error)).toBe(false);
|
|
144
151
|
});
|
|
145
152
|
|
|
146
153
|
it('preserves retryable provider error codes for workflow-level failure persistence', async () => {
|
|
@@ -156,6 +163,7 @@ describe('definition sync activities', () => {
|
|
|
156
163
|
);
|
|
157
164
|
}),
|
|
158
165
|
}),
|
|
166
|
+
agent,
|
|
159
167
|
);
|
|
160
168
|
|
|
161
169
|
const result = activities.prepareDefinitionSync({
|
|
@@ -170,12 +178,14 @@ describe('definition sync activities', () => {
|
|
|
170
178
|
type: 'provider-timeout',
|
|
171
179
|
message: 'integrations.resolveSourceRepository: provider-failure',
|
|
172
180
|
});
|
|
181
|
+
const error = await result.catch((error: unknown) => error);
|
|
182
|
+
expect(isErrorReported(error)).toBe(true);
|
|
173
183
|
});
|
|
174
184
|
});
|
|
175
185
|
|
|
176
186
|
describe('fetchAndApplyDefinitionWorkflows', () => {
|
|
177
187
|
it('upserts workflow definitions and soft-deletes orphans', async () => {
|
|
178
|
-
const activities = createDefinitionSyncActivities(sourceControl());
|
|
188
|
+
const activities = createDefinitionSyncActivities(sourceControl(), agent);
|
|
179
189
|
|
|
180
190
|
const result = await activities.fetchAndApplyDefinitionWorkflows({
|
|
181
191
|
projectId,
|
|
@@ -201,6 +211,7 @@ describe('definition sync activities', () => {
|
|
|
201
211
|
}),
|
|
202
212
|
),
|
|
203
213
|
}),
|
|
214
|
+
agent,
|
|
204
215
|
);
|
|
205
216
|
|
|
206
217
|
const result = activities.fetchAndApplyDefinitionWorkflows({
|
|
@@ -219,7 +230,7 @@ describe('definition sync activities', () => {
|
|
|
219
230
|
|
|
220
231
|
it('fetches from source commit sha while persisting under source ref', async () => {
|
|
221
232
|
const source = sourceControl();
|
|
222
|
-
const activities = createDefinitionSyncActivities(source);
|
|
233
|
+
const activities = createDefinitionSyncActivities(source, agent);
|
|
223
234
|
|
|
224
235
|
const result = await activities.fetchAndApplyDefinitionWorkflows({
|
|
225
236
|
projectId,
|
|
@@ -245,7 +256,7 @@ describe('definition sync activities', () => {
|
|
|
245
256
|
|
|
246
257
|
describe('markDefinitionSyncFailed', () => {
|
|
247
258
|
it('persists last_error_code and last_error_message verbatim', async () => {
|
|
248
|
-
const activities = createDefinitionSyncActivities(sourceControl());
|
|
259
|
+
const activities = createDefinitionSyncActivities(sourceControl(), agent);
|
|
249
260
|
await activities.prepareDefinitionSync({
|
|
250
261
|
projectId,
|
|
251
262
|
workspaceId: crypto.randomUUID(),
|
|
@@ -275,7 +286,7 @@ describe('definition sync activities', () => {
|
|
|
275
286
|
});
|
|
276
287
|
|
|
277
288
|
it('persists failures with the unresolved sentinel ref when no ref was produced', async () => {
|
|
278
|
-
const activities = createDefinitionSyncActivities(sourceControl());
|
|
289
|
+
const activities = createDefinitionSyncActivities(sourceControl(), agent);
|
|
279
290
|
|
|
280
291
|
const result = activities.markDefinitionSyncFailed({
|
|
281
292
|
projectId,
|
|
@@ -302,7 +313,7 @@ describe('definition sync activities', () => {
|
|
|
302
313
|
|
|
303
314
|
describe('markDefinitionSyncSucceeded', () => {
|
|
304
315
|
it('clears stale error fields when transitioning to succeeded', async () => {
|
|
305
|
-
const activities = createDefinitionSyncActivities(sourceControl());
|
|
316
|
+
const activities = createDefinitionSyncActivities(sourceControl(), agent);
|
|
306
317
|
await activities.prepareDefinitionSync({
|
|
307
318
|
projectId,
|
|
308
319
|
workspaceId: crypto.randomUUID(),
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
2
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';
|
|
3
|
+
import {markErrorReported} from '@shipfox/node-error-monitoring';
|
|
2
4
|
import {Context} from '@temporalio/activity';
|
|
3
5
|
import {ApplicationFailure} from '@temporalio/common';
|
|
4
6
|
import type {DefinitionSyncErrorCode} from '#core/entities/sync-state.js';
|
|
@@ -52,12 +54,17 @@ export interface FetchAndApplyActivityResult {
|
|
|
52
54
|
|
|
53
55
|
export function createDefinitionSyncActivities(
|
|
54
56
|
sourceControl: DefinitionsSourceControl,
|
|
57
|
+
agent: AgentInterModuleClient,
|
|
55
58
|
integrations?: IntegrationsModuleClient | undefined,
|
|
56
59
|
) {
|
|
57
60
|
return {
|
|
58
61
|
prepareDefinitionSync: createPrepareDefinitionSyncActivity(sourceControl),
|
|
59
62
|
discoverDefinitionWorkflows: createDiscoverDefinitionWorkflowsActivity(sourceControl),
|
|
60
|
-
fetchAndApplyDefinitionWorkflows: createFetchAndApplyActivity(
|
|
63
|
+
fetchAndApplyDefinitionWorkflows: createFetchAndApplyActivity(
|
|
64
|
+
sourceControl,
|
|
65
|
+
agent,
|
|
66
|
+
integrations,
|
|
67
|
+
),
|
|
61
68
|
markDefinitionSyncSucceeded: createMarkSyncSucceededActivity(),
|
|
62
69
|
markDefinitionSyncFailed: createMarkSyncFailedActivity(),
|
|
63
70
|
};
|
|
@@ -103,6 +110,7 @@ function createDiscoverDefinitionWorkflowsActivity(sourceControl: DefinitionsSou
|
|
|
103
110
|
|
|
104
111
|
function createFetchAndApplyActivity(
|
|
105
112
|
sourceControl: DefinitionsSourceControl,
|
|
113
|
+
agent: AgentInterModuleClient,
|
|
106
114
|
integrations?: IntegrationsModuleClient | undefined,
|
|
107
115
|
) {
|
|
108
116
|
return async function fetchAndApplyDefinitionWorkflows(
|
|
@@ -113,6 +121,7 @@ function createFetchAndApplyActivity(
|
|
|
113
121
|
...input,
|
|
114
122
|
ref: input.sourceCommitSha ?? input.sourceRef,
|
|
115
123
|
sourceControl,
|
|
124
|
+
agentValidationCatalog: await agent.getValidationCatalog({}),
|
|
116
125
|
onProgress: (path) => Context.current().heartbeat({path}),
|
|
117
126
|
loadIntegrationValidationContext:
|
|
118
127
|
integrations === undefined
|
|
@@ -183,9 +192,10 @@ async function runWithPermanentTranslation<T>(operation: () => Promise<T>): Prom
|
|
|
183
192
|
throw error;
|
|
184
193
|
}
|
|
185
194
|
const failure = classifySyncFailure(error);
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
195
|
+
const translatedError = failure.retryable
|
|
196
|
+
? ApplicationFailure.retryable(failure.message, failure.code)
|
|
197
|
+
: ApplicationFailure.nonRetryable(failure.message, failure.code);
|
|
198
|
+
if (failure.code !== 'unknown') markErrorReported(translatedError);
|
|
199
|
+
throw translatedError;
|
|
190
200
|
}
|
|
191
201
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_HARNESS_TOOL_DEPLOYMENT_CONFIG,
|
|
3
|
+
getModelProviderEntry,
|
|
4
|
+
listEnabledHarnessTools,
|
|
5
|
+
listHarnessDescriptors,
|
|
6
|
+
MODEL_PROVIDER_IDS,
|
|
7
|
+
} from '@shipfox/api-agent-dto';
|
|
8
|
+
import type {AgentValidationCatalog} from '@shipfox/api-agent-dto/inter-module';
|
|
9
|
+
|
|
10
|
+
export const agentValidationCatalog: AgentValidationCatalog = {
|
|
11
|
+
version: 1,
|
|
12
|
+
providers: MODEL_PROVIDER_IDS.map((id) => ({
|
|
13
|
+
id,
|
|
14
|
+
support_status: getModelProviderEntry(id)?.support_status ?? 'unsupported',
|
|
15
|
+
})),
|
|
16
|
+
harnesses: listHarnessDescriptors().map((harness) => ({
|
|
17
|
+
id: harness.id,
|
|
18
|
+
supported_provider_ids: [...harness.supportedProviderIds],
|
|
19
|
+
thinking_levels: [...harness.thinkingLevels],
|
|
20
|
+
effective_tools: listEnabledHarnessTools(
|
|
21
|
+
harness.id,
|
|
22
|
+
DEFAULT_HARNESS_TOOL_DEPLOYMENT_CONFIG,
|
|
23
|
+
).map((tool) => tool.name),
|
|
24
|
+
})),
|
|
25
|
+
};
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
} from '#core/entities/workflow-definition.js';
|
|
6
6
|
import {normalizeWorkflowDocument} from '#core/workflow-model/index.js';
|
|
7
7
|
import {upsertDefinition} from '#db/definitions.js';
|
|
8
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
8
9
|
|
|
9
10
|
function defaultDefinition(): WorkflowDefinitionPayload {
|
|
10
11
|
const document = {
|
|
@@ -16,7 +17,7 @@ function defaultDefinition(): WorkflowDefinitionPayload {
|
|
|
16
17
|
},
|
|
17
18
|
},
|
|
18
19
|
};
|
|
19
|
-
return {document, model: normalizeWorkflowDocument(document)};
|
|
20
|
+
return {document, model: normalizeWorkflowDocument(document, {agentValidationCatalog})};
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
interface DefinitionTransients {
|