@shipfox/api-definitions 7.1.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 +4 -4
- package/CHANGELOG.md +14 -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 +4 -3
- package/dist/temporal/activities/sync-activities.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +4 -4
- 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 +14 -8
- package/src/temporal/activities/sync-activities.ts +10 -2
- package/test/agent-validation-catalog.ts +25 -0
- package/test/factories/definition.ts +2 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipfox/api-definitions",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "8.0.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"js-yaml": "^4.1.0",
|
|
31
31
|
"yaml": "^2.8.3",
|
|
32
32
|
"zod": "^4.4.3",
|
|
33
|
-
"@shipfox/api-agent-dto": "
|
|
33
|
+
"@shipfox/api-agent-dto": "8.0.0",
|
|
34
34
|
"@shipfox/api-auth-context": "7.1.0",
|
|
35
35
|
"@shipfox/api-definitions-dto": "6.0.0",
|
|
36
|
-
"@shipfox/api-integration-core-dto": "
|
|
37
|
-
"@shipfox/api-projects-dto": "
|
|
36
|
+
"@shipfox/api-integration-core-dto": "8.0.0",
|
|
37
|
+
"@shipfox/api-projects-dto": "8.0.0",
|
|
38
38
|
"@shipfox/api-secrets-dto": "6.0.0",
|
|
39
39
|
"@shipfox/config": "1.2.2",
|
|
40
40
|
"@shipfox/expression": "1.1.3",
|
package/src/config.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildHarnessToolDeploymentConfig,
|
|
3
|
-
type HarnessToolDeploymentConfig,
|
|
4
|
-
} from '@shipfox/api-agent-dto';
|
|
5
|
-
import {bool, createConfig, str} from '@shipfox/config';
|
|
1
|
+
import {createConfig, str} from '@shipfox/config';
|
|
6
2
|
import {findInvalidLabels, MAX_RUNNER_LABELS, parseLabelList} from '@shipfox/runner-labels';
|
|
7
3
|
|
|
8
4
|
export const config = createConfig({
|
|
@@ -10,14 +6,6 @@ export const config = createConfig({
|
|
|
10
6
|
desc: 'Default runner label(s) applied to workflow jobs that do not declare a "runner" at the job or workflow level. Set it to a comma-separated list, for example ubuntu-latest or ubuntu-latest,node-22. Leave it empty to require every workflow job to declare runner labels explicitly; with no value set, a job without a runner fails definition validation.',
|
|
11
7
|
default: '',
|
|
12
8
|
}),
|
|
13
|
-
AGENT_PI_ENABLED_TOOL_PACKAGES: str({
|
|
14
|
-
desc: 'Comma-separated optional Pi tool packages enabled for this deployment. Defaults to pi-web-access so Pi web access is available. Set it to an empty value to enable only Pi built-in tools. Accepted values: pi-web-access.',
|
|
15
|
-
default: 'pi-web-access',
|
|
16
|
-
}),
|
|
17
|
-
AGENT_PI_WEB_SEARCH_ENABLED: bool({
|
|
18
|
-
desc: 'Enables Pi web search tools when pi-web-access is enabled. Set it to false to disable web_search and get_search_content while keeping fetch_content available.',
|
|
19
|
-
default: true,
|
|
20
|
-
}),
|
|
21
9
|
});
|
|
22
10
|
|
|
23
11
|
export function parseDefinitionDefaultRunnerLabels(value: string): readonly string[] {
|
|
@@ -42,9 +30,3 @@ export function parseDefinitionDefaultRunnerLabels(value: string): readonly stri
|
|
|
42
30
|
export const definitionDefaultRunnerLabels = parseDefinitionDefaultRunnerLabels(
|
|
43
31
|
config.DEFINITION_DEFAULT_RUNNER_LABEL,
|
|
44
32
|
);
|
|
45
|
-
|
|
46
|
-
export const definitionHarnessToolDeploymentConfig: HarnessToolDeploymentConfig =
|
|
47
|
-
buildHarnessToolDeploymentConfig({
|
|
48
|
-
piEnabledToolPackages: config.AGENT_PI_ENABLED_TOOL_PACKAGES,
|
|
49
|
-
piWebSearchEnabled: config.AGENT_PI_WEB_SEARCH_ENABLED,
|
|
50
|
-
});
|
package/src/core/index.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export type * from './entities/index.js';
|
|
2
|
-
export {
|
|
2
|
+
export {
|
|
3
|
+
DefinitionParseError,
|
|
4
|
+
DefinitionSyncPermanentError,
|
|
5
|
+
} from './errors.js';
|
|
3
6
|
export {parseDefinition} from './parse-definition.js';
|
|
4
7
|
export {
|
|
5
8
|
classifySyncFailure,
|
package/src/core/integrations.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type IntegrationsModuleClient,
|
|
3
3
|
integrationsInterModuleContract,
|
|
4
|
-
} from '@shipfox/api-integration-core-dto';
|
|
4
|
+
} from '@shipfox/api-integration-core-dto/inter-module';
|
|
5
5
|
|
|
6
6
|
export type DefinitionsSourceControl = {
|
|
7
7
|
resolveRepository: IntegrationsModuleClient['resolveSourceRepository'];
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import {readFileSync} from 'node:fs';
|
|
2
2
|
import {dirname, resolve} from 'node:path';
|
|
3
3
|
import {fileURLToPath} from 'node:url';
|
|
4
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
4
5
|
import {DefinitionParseError} from './errors.js';
|
|
5
|
-
import {parseDefinition} from './parse-definition.js';
|
|
6
|
+
import {parseDefinition as parseDefinitionBase} from './parse-definition.js';
|
|
6
7
|
|
|
7
8
|
const fixturesDir = resolve(dirname(fileURLToPath(import.meta.url)), '../../test/fixtures');
|
|
8
9
|
|
|
10
|
+
function parseDefinition(yaml: string, options = {}) {
|
|
11
|
+
return parseDefinitionBase(yaml, {agentValidationCatalog, ...options});
|
|
12
|
+
}
|
|
13
|
+
|
|
9
14
|
function readFixture(name: string): string {
|
|
10
15
|
return readFileSync(resolve(fixturesDir, name), 'utf-8');
|
|
11
16
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {AgentValidationCatalog} from '@shipfox/api-agent-dto/inter-module';
|
|
2
2
|
import type {IntegrationValidationContext} from './entities/integration-context.js';
|
|
3
3
|
import type {WorkflowDefinitionPayload} from './entities/workflow-definition.js';
|
|
4
4
|
import {DefinitionParseError} from './errors.js';
|
|
@@ -6,9 +6,9 @@ import {validateDefinition} from './validate-definition.js';
|
|
|
6
6
|
|
|
7
7
|
export function parseDefinition(
|
|
8
8
|
yamlString: string,
|
|
9
|
-
options
|
|
9
|
+
options: {
|
|
10
10
|
defaultRunnerLabels?: readonly string[];
|
|
11
|
-
|
|
11
|
+
agentValidationCatalog: AgentValidationCatalog;
|
|
12
12
|
integrationValidationContext?: IntegrationValidationContext;
|
|
13
13
|
},
|
|
14
14
|
): WorkflowDefinitionPayload {
|
|
@@ -1,16 +1,23 @@
|
|
|
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
4
|
import {LOWERCASE_SHA256_HEX_RE} from '@shipfox/regex';
|
|
5
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
5
6
|
import type {IntegrationValidationContext} from './entities/integration-context.js';
|
|
6
7
|
import {DefinitionSyncPermanentError} from './errors.js';
|
|
7
8
|
import {
|
|
8
9
|
classifySyncFailure,
|
|
9
10
|
discoverWorkflowFiles,
|
|
10
|
-
fetchAndParseWorkflows,
|
|
11
|
+
fetchAndParseWorkflows as fetchAndParseWorkflowsBase,
|
|
11
12
|
resolveSyncSource,
|
|
12
13
|
} from './sync-definitions.js';
|
|
13
14
|
|
|
15
|
+
function fetchAndParseWorkflows(
|
|
16
|
+
params: Omit<Parameters<typeof fetchAndParseWorkflowsBase>[0], 'agentValidationCatalog'>,
|
|
17
|
+
) {
|
|
18
|
+
return fetchAndParseWorkflowsBase({...params, agentValidationCatalog});
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
const validYaml = `
|
|
15
22
|
name: CI
|
|
16
23
|
runner: ubuntu-latest
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {createHash} from 'node:crypto';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import type {AgentValidationCatalog} from '@shipfox/api-agent-dto/inter-module';
|
|
3
|
+
import {MAX_REPOSITORY_FILE_BYTES} from '@shipfox/api-integration-core-dto';
|
|
4
|
+
import {integrationsInterModuleContract} from '@shipfox/api-integration-core-dto/inter-module';
|
|
6
5
|
import {isInterModuleKnownError} from '@shipfox/inter-module';
|
|
7
6
|
import {boundedMap} from '@shipfox/node-module';
|
|
8
7
|
import type {IntegrationValidationContext} from './entities/integration-context.js';
|
|
@@ -84,6 +83,7 @@ export interface FetchAndParseWorkflowsParams extends SyncSourceContext {
|
|
|
84
83
|
ref: string;
|
|
85
84
|
paths: string[];
|
|
86
85
|
onProgress?: ((path: string) => void) | undefined;
|
|
86
|
+
agentValidationCatalog: AgentValidationCatalog;
|
|
87
87
|
loadIntegrationValidationContext?: (() => Promise<IntegrationValidationContext>) | undefined;
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -112,7 +112,11 @@ export async function fetchAndParseWorkflows(
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
return {
|
|
115
|
-
...parseWorkflowSnapshot({
|
|
115
|
+
...parseWorkflowSnapshot({
|
|
116
|
+
path: snapshot.path,
|
|
117
|
+
content: snapshot.content,
|
|
118
|
+
agentValidationCatalog: params.agentValidationCatalog,
|
|
119
|
+
}),
|
|
116
120
|
rawContent: snapshot.content,
|
|
117
121
|
};
|
|
118
122
|
},
|
|
@@ -131,6 +135,7 @@ export async function fetchAndParseWorkflows(
|
|
|
131
135
|
parseWorkflowSnapshot({
|
|
132
136
|
path: entry.path,
|
|
133
137
|
content: entry.rawContent,
|
|
138
|
+
agentValidationCatalog: params.agentValidationCatalog,
|
|
134
139
|
integrationValidationContext,
|
|
135
140
|
}),
|
|
136
141
|
);
|
|
@@ -140,12 +145,14 @@ function parseWorkflowSnapshot(params: {
|
|
|
140
145
|
path: string;
|
|
141
146
|
content: string;
|
|
142
147
|
integrationValidationContext?: IntegrationValidationContext | undefined;
|
|
148
|
+
agentValidationCatalog: AgentValidationCatalog;
|
|
143
149
|
}): ParsedWorkflow {
|
|
144
150
|
try {
|
|
145
151
|
const definition =
|
|
146
152
|
params.integrationValidationContext === undefined
|
|
147
|
-
? parseDefinition(params.content)
|
|
153
|
+
? parseDefinition(params.content, {agentValidationCatalog: params.agentValidationCatalog})
|
|
148
154
|
: parseDefinition(params.content, {
|
|
155
|
+
agentValidationCatalog: params.agentValidationCatalog,
|
|
149
156
|
integrationValidationContext: params.integrationValidationContext,
|
|
150
157
|
});
|
|
151
158
|
const contentHash = sha256Hex(params.content);
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
2
|
+
import {validateDefinition as validateDefinitionBase} from './validate-definition.js';
|
|
3
|
+
|
|
4
|
+
function validateDefinition(yaml: string, options = {}) {
|
|
5
|
+
return validateDefinitionBase(yaml, {agentValidationCatalog, ...options});
|
|
6
|
+
}
|
|
2
7
|
|
|
3
8
|
describe('validateDefinition', () => {
|
|
4
9
|
test('valid YAML returns { valid: true, definition }', () => {
|
|
@@ -129,9 +134,18 @@ jobs:
|
|
|
129
134
|
`;
|
|
130
135
|
|
|
131
136
|
const result = validateDefinition(yaml, {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
137
|
+
agentValidationCatalog: {
|
|
138
|
+
...agentValidationCatalog,
|
|
139
|
+
harnesses: agentValidationCatalog.harnesses.map((harness) => {
|
|
140
|
+
if (harness.id !== 'pi') return harness;
|
|
141
|
+
return {
|
|
142
|
+
...harness,
|
|
143
|
+
effective_tools: harness.effective_tools.filter(
|
|
144
|
+
(tool) =>
|
|
145
|
+
tool === 'fetch_content' || !['web_search', 'get_search_content'].includes(tool),
|
|
146
|
+
),
|
|
147
|
+
};
|
|
148
|
+
}),
|
|
135
149
|
},
|
|
136
150
|
});
|
|
137
151
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {AgentValidationCatalog} from '@shipfox/api-agent-dto/inter-module';
|
|
2
2
|
import {InvalidWorkflowDocumentError} from '@shipfox/workflow-document';
|
|
3
|
-
import {definitionDefaultRunnerLabels
|
|
3
|
+
import {definitionDefaultRunnerLabels} from '../config.js';
|
|
4
4
|
import type {IntegrationValidationContext} from './entities/integration-context.js';
|
|
5
5
|
import type {WorkflowDefinitionPayload} from './entities/workflow-definition.js';
|
|
6
6
|
import {InvalidWorkflowModelError, normalizeWorkflowDocument} from './workflow-model/index.js';
|
|
@@ -16,16 +16,15 @@ export function validateDefinition(
|
|
|
16
16
|
yamlContent: string,
|
|
17
17
|
options: {
|
|
18
18
|
defaultRunnerLabels?: readonly string[];
|
|
19
|
-
|
|
19
|
+
agentValidationCatalog: AgentValidationCatalog;
|
|
20
20
|
integrationValidationContext?: IntegrationValidationContext;
|
|
21
|
-
}
|
|
21
|
+
},
|
|
22
22
|
): ValidationResult {
|
|
23
23
|
try {
|
|
24
24
|
const {document, stepSourceLocations} = parseWorkflowYamlWithLocations(yamlContent);
|
|
25
25
|
const model = normalizeWorkflowDocument(document, {
|
|
26
26
|
defaultRunnerLabels: options.defaultRunnerLabels ?? definitionDefaultRunnerLabels,
|
|
27
|
-
|
|
28
|
-
options.harnessToolDeploymentConfig ?? definitionHarnessToolDeploymentConfig,
|
|
27
|
+
agentValidationCatalog: options.agentValidationCatalog,
|
|
29
28
|
integrationValidationContext: options.integrationValidationContext,
|
|
30
29
|
stepSourceLocations,
|
|
31
30
|
});
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
agentThinkingByHarness,
|
|
3
|
-
getHarnessDescriptor,
|
|
4
|
-
getModelProviderEntry,
|
|
5
|
-
type HarnessToolDeploymentConfig,
|
|
6
|
-
listEnabledHarnessTools,
|
|
7
|
-
} from '@shipfox/api-agent-dto';
|
|
1
|
+
import type {AgentValidationCatalog} from '@shipfox/api-agent-dto/inter-module';
|
|
8
2
|
import {
|
|
9
3
|
type AvailabilitySite,
|
|
10
4
|
buildTypedRootsEnvironment,
|
|
@@ -53,7 +47,7 @@ import {issue} from './validation-issue.js';
|
|
|
53
47
|
|
|
54
48
|
export interface NormalizeContext {
|
|
55
49
|
readonly defaultRunnerLabels: readonly string[];
|
|
56
|
-
readonly
|
|
50
|
+
readonly agentValidationCatalog: AgentValidationCatalog;
|
|
57
51
|
readonly integrationValidationContext?: IntegrationValidationContext | undefined;
|
|
58
52
|
}
|
|
59
53
|
|
|
@@ -719,7 +713,7 @@ function normalizeAgentStep(params: {
|
|
|
719
713
|
stepIndex: params.stepIndex,
|
|
720
714
|
issues: params.issues,
|
|
721
715
|
validateLiteralProvider: providerTemplate === undefined,
|
|
722
|
-
|
|
716
|
+
agentValidationCatalog: params.context.agentValidationCatalog,
|
|
723
717
|
});
|
|
724
718
|
const integrations = normalizeAgentIntegrations({
|
|
725
719
|
integrations: params.step.integrations,
|
|
@@ -755,7 +749,7 @@ function validateAgentStep(params: {
|
|
|
755
749
|
stepIndex: number;
|
|
756
750
|
issues: WorkflowModelValidationIssue[];
|
|
757
751
|
validateLiteralProvider: boolean;
|
|
758
|
-
|
|
752
|
+
agentValidationCatalog: AgentValidationCatalog;
|
|
759
753
|
}): void {
|
|
760
754
|
validateHarnessThinking(params);
|
|
761
755
|
validateHarnessTools(params);
|
|
@@ -764,7 +758,7 @@ function validateAgentStep(params: {
|
|
|
764
758
|
const providerId = params.step.provider;
|
|
765
759
|
if (providerId === undefined) return;
|
|
766
760
|
|
|
767
|
-
const provider =
|
|
761
|
+
const provider = params.agentValidationCatalog.providers.find((entry) => entry.id === providerId);
|
|
768
762
|
const harness = params.step.harness;
|
|
769
763
|
if (provider === undefined && harness === 'pi') return;
|
|
770
764
|
|
|
@@ -782,15 +776,19 @@ function validateAgentStep(params: {
|
|
|
782
776
|
|
|
783
777
|
if (harness === undefined) return;
|
|
784
778
|
|
|
785
|
-
const descriptor =
|
|
786
|
-
if (descriptor.
|
|
779
|
+
const descriptor = params.agentValidationCatalog.harnesses.find((entry) => entry.id === harness);
|
|
780
|
+
if (descriptor?.supported_provider_ids.includes(providerId)) return;
|
|
787
781
|
|
|
788
782
|
params.issues.push(
|
|
789
783
|
issue({
|
|
790
784
|
code: 'harness-provider-incompatible',
|
|
791
|
-
message: `Harness "${harness}" does not support provider: ${providerId}. Supported providers: ${descriptor.
|
|
785
|
+
message: `Harness "${harness}" does not support provider: ${providerId}. Supported providers: ${descriptor?.supported_provider_ids.join(', ') ?? ''}.`,
|
|
792
786
|
path: ['jobs', params.sourceName, 'steps', params.stepIndex, 'provider'],
|
|
793
|
-
details: {
|
|
787
|
+
details: {
|
|
788
|
+
harness,
|
|
789
|
+
provider: providerId,
|
|
790
|
+
supportedProviders: descriptor?.supported_provider_ids ?? [],
|
|
791
|
+
},
|
|
794
792
|
}),
|
|
795
793
|
);
|
|
796
794
|
}
|
|
@@ -800,7 +798,7 @@ function validateHarnessTools(params: {
|
|
|
800
798
|
sourceName: string;
|
|
801
799
|
stepIndex: number;
|
|
802
800
|
issues: WorkflowModelValidationIssue[];
|
|
803
|
-
|
|
801
|
+
agentValidationCatalog: AgentValidationCatalog;
|
|
804
802
|
}): void {
|
|
805
803
|
const {harness, tools} = params.step;
|
|
806
804
|
if (tools === undefined) return;
|
|
@@ -818,9 +816,9 @@ function validateHarnessTools(params: {
|
|
|
818
816
|
return;
|
|
819
817
|
}
|
|
820
818
|
|
|
821
|
-
const supportedTools =
|
|
822
|
-
(
|
|
823
|
-
|
|
819
|
+
const supportedTools =
|
|
820
|
+
params.agentValidationCatalog.harnesses.find((entry) => entry.id === harness)
|
|
821
|
+
?.effective_tools ?? [];
|
|
824
822
|
const supportedToolSet = new Set(supportedTools);
|
|
825
823
|
|
|
826
824
|
tools.forEach((tool, toolIndex) => {
|
|
@@ -842,14 +840,15 @@ function validateHarnessThinking(params: {
|
|
|
842
840
|
sourceName: string;
|
|
843
841
|
stepIndex: number;
|
|
844
842
|
issues: WorkflowModelValidationIssue[];
|
|
843
|
+
agentValidationCatalog: AgentValidationCatalog;
|
|
845
844
|
}): void {
|
|
846
845
|
const {harness, thinking} = params.step;
|
|
847
846
|
if (harness === undefined || thinking === undefined) return;
|
|
848
847
|
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
848
|
+
const supportedLevels =
|
|
849
|
+
params.agentValidationCatalog.harnesses.find((entry) => entry.id === harness)
|
|
850
|
+
?.thinking_levels ?? [];
|
|
851
|
+
if (supportedLevels.includes(thinking)) return;
|
|
853
852
|
params.issues.push(
|
|
854
853
|
issue({
|
|
855
854
|
code: 'harness-thinking-incompatible',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {WorkflowDocument} from '@shipfox/workflow-document';
|
|
2
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
2
3
|
import type {IntegrationValidationContext} from '../entities/integration-context.js';
|
|
3
4
|
import {InvalidWorkflowModelError} from './invalid-workflow-model-error.js';
|
|
4
5
|
import {DEFAULT_JOB_CHECKOUT} from './normalize-job-checkout.js';
|
|
@@ -6,14 +7,22 @@ import {normalizeWorkflowDocument as normalizeWorkflowDocumentBase} from './norm
|
|
|
6
7
|
|
|
7
8
|
function normalizeWorkflowDocument(
|
|
8
9
|
document: WorkflowDocument,
|
|
9
|
-
options?: Parameters<typeof normalizeWorkflowDocumentBase>[1],
|
|
10
|
+
options?: Omit<Parameters<typeof normalizeWorkflowDocumentBase>[1], 'agentValidationCatalog'> &
|
|
11
|
+
Partial<Pick<Parameters<typeof normalizeWorkflowDocumentBase>[1], 'agentValidationCatalog'>>,
|
|
10
12
|
) {
|
|
11
|
-
return normalizeWorkflowDocumentBase(
|
|
13
|
+
return normalizeWorkflowDocumentBase(
|
|
14
|
+
{runner: 'ubuntu-latest', ...document},
|
|
15
|
+
{
|
|
16
|
+
agentValidationCatalog: options?.agentValidationCatalog ?? agentValidationCatalog,
|
|
17
|
+
...options,
|
|
18
|
+
},
|
|
19
|
+
);
|
|
12
20
|
}
|
|
13
21
|
|
|
14
22
|
function expectInvalid(
|
|
15
23
|
document: WorkflowDocument,
|
|
16
|
-
options?: Parameters<typeof normalizeWorkflowDocumentBase>[1],
|
|
24
|
+
options?: Omit<Parameters<typeof normalizeWorkflowDocumentBase>[1], 'agentValidationCatalog'> &
|
|
25
|
+
Partial<Pick<Parameters<typeof normalizeWorkflowDocumentBase>[1], 'agentValidationCatalog'>>,
|
|
17
26
|
): InvalidWorkflowModelError {
|
|
18
27
|
try {
|
|
19
28
|
normalizeWorkflowDocument(document, options);
|
|
@@ -578,12 +587,7 @@ describe('normalizeWorkflowDocument', () => {
|
|
|
578
587
|
},
|
|
579
588
|
};
|
|
580
589
|
|
|
581
|
-
const error = expectInvalid(document
|
|
582
|
-
harnessToolDeploymentConfig: {
|
|
583
|
-
pi: {enabledToolPackages: ['pi-web-access'], webSearchEnabled: true},
|
|
584
|
-
claude: {enabledToolPackages: []},
|
|
585
|
-
},
|
|
586
|
-
});
|
|
590
|
+
const error = expectInvalid(document);
|
|
587
591
|
|
|
588
592
|
expect(error.issues).toEqual([
|
|
589
593
|
{
|
|
@@ -670,9 +674,20 @@ describe('normalizeWorkflowDocument', () => {
|
|
|
670
674
|
};
|
|
671
675
|
|
|
672
676
|
const error = expectInvalid(document, {
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
677
|
+
agentValidationCatalog: {
|
|
678
|
+
...agentValidationCatalog,
|
|
679
|
+
harnesses: agentValidationCatalog.harnesses.map((harness) =>
|
|
680
|
+
harness.id === 'pi'
|
|
681
|
+
? {
|
|
682
|
+
...harness,
|
|
683
|
+
effective_tools: harness.effective_tools.filter(
|
|
684
|
+
(tool) =>
|
|
685
|
+
tool === 'fetch_content' ||
|
|
686
|
+
!['web_search', 'get_search_content'].includes(tool),
|
|
687
|
+
),
|
|
688
|
+
}
|
|
689
|
+
: harness,
|
|
690
|
+
),
|
|
676
691
|
},
|
|
677
692
|
});
|
|
678
693
|
|
|
@@ -1169,7 +1184,7 @@ describe('normalizeWorkflowDocument', () => {
|
|
|
1169
1184
|
};
|
|
1170
1185
|
|
|
1171
1186
|
try {
|
|
1172
|
-
normalizeWorkflowDocumentBase(document);
|
|
1187
|
+
normalizeWorkflowDocumentBase(document, {agentValidationCatalog});
|
|
1173
1188
|
expect.fail('Expected InvalidWorkflowModelError');
|
|
1174
1189
|
} catch (error) {
|
|
1175
1190
|
expect(error).toBeInstanceOf(InvalidWorkflowModelError);
|
|
@@ -1193,6 +1208,7 @@ describe('normalizeWorkflowDocument', () => {
|
|
|
1193
1208
|
};
|
|
1194
1209
|
|
|
1195
1210
|
const model = normalizeWorkflowDocumentBase(document, {
|
|
1211
|
+
agentValidationCatalog,
|
|
1196
1212
|
defaultRunnerLabels: [' Ubuntu ', 'ubuntu'],
|
|
1197
1213
|
});
|
|
1198
1214
|
|
|
@@ -1211,7 +1227,10 @@ describe('normalizeWorkflowDocument', () => {
|
|
|
1211
1227
|
};
|
|
1212
1228
|
|
|
1213
1229
|
try {
|
|
1214
|
-
normalizeWorkflowDocumentBase(document, {
|
|
1230
|
+
normalizeWorkflowDocumentBase(document, {
|
|
1231
|
+
agentValidationCatalog,
|
|
1232
|
+
defaultRunnerLabels: ['ubuntu-latest'],
|
|
1233
|
+
});
|
|
1215
1234
|
expect.fail('Expected InvalidWorkflowModelError');
|
|
1216
1235
|
} catch (error) {
|
|
1217
1236
|
expect(error).toBeInstanceOf(InvalidWorkflowModelError);
|
|
@@ -1253,7 +1272,7 @@ describe('normalizeWorkflowDocument', () => {
|
|
|
1253
1272
|
};
|
|
1254
1273
|
|
|
1255
1274
|
try {
|
|
1256
|
-
normalizeWorkflowDocumentBase(document);
|
|
1275
|
+
normalizeWorkflowDocumentBase(document, {agentValidationCatalog});
|
|
1257
1276
|
expect.fail('Expected InvalidWorkflowModelError');
|
|
1258
1277
|
} catch (error) {
|
|
1259
1278
|
expect(error).toBeInstanceOf(InvalidWorkflowModelError);
|
|
@@ -1279,7 +1298,7 @@ describe('normalizeWorkflowDocument', () => {
|
|
|
1279
1298
|
};
|
|
1280
1299
|
|
|
1281
1300
|
try {
|
|
1282
|
-
normalizeWorkflowDocumentBase(document);
|
|
1301
|
+
normalizeWorkflowDocumentBase(document, {agentValidationCatalog});
|
|
1283
1302
|
expect.fail('Expected InvalidWorkflowModelError');
|
|
1284
1303
|
} catch (error) {
|
|
1285
1304
|
expect(error).toBeInstanceOf(InvalidWorkflowModelError);
|
|
@@ -1349,7 +1368,7 @@ describe('normalizeWorkflowDocument', () => {
|
|
|
1349
1368
|
};
|
|
1350
1369
|
|
|
1351
1370
|
try {
|
|
1352
|
-
normalizeWorkflowDocumentBase(document);
|
|
1371
|
+
normalizeWorkflowDocumentBase(document, {agentValidationCatalog});
|
|
1353
1372
|
expect.fail('Expected InvalidWorkflowModelError');
|
|
1354
1373
|
} catch (error) {
|
|
1355
1374
|
expect(error).toBeInstanceOf(InvalidWorkflowModelError);
|
|
@@ -1378,7 +1397,7 @@ describe('normalizeWorkflowDocument', () => {
|
|
|
1378
1397
|
},
|
|
1379
1398
|
};
|
|
1380
1399
|
|
|
1381
|
-
const model = normalizeWorkflowDocumentBase(document);
|
|
1400
|
+
const model = normalizeWorkflowDocumentBase(document, {agentValidationCatalog});
|
|
1382
1401
|
|
|
1383
1402
|
expect(model.jobs[0]?.runner).toHaveLength(20);
|
|
1384
1403
|
});
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DEFAULT_HARNESS_TOOL_DEPLOYMENT_CONFIG,
|
|
3
|
-
type HarnessToolDeploymentConfig,
|
|
4
|
-
} from '@shipfox/api-agent-dto';
|
|
1
|
+
import type {AgentValidationCatalog} from '@shipfox/api-agent-dto/inter-module';
|
|
5
2
|
import {canonicalizeLabels} from '@shipfox/runner-labels';
|
|
6
3
|
import type {WorkflowDocument} from '@shipfox/workflow-document';
|
|
7
4
|
import type {IntegrationValidationContext} from '../entities/integration-context.js';
|
|
@@ -20,18 +17,16 @@ export function normalizeWorkflowDocument(
|
|
|
20
17
|
document: WorkflowDocument,
|
|
21
18
|
options: {
|
|
22
19
|
defaultRunnerLabels?: readonly string[] | undefined;
|
|
23
|
-
|
|
20
|
+
agentValidationCatalog: AgentValidationCatalog;
|
|
24
21
|
integrationValidationContext?: IntegrationValidationContext | undefined;
|
|
25
22
|
stepSourceLocations?: WorkflowStepSourceLocationMap | undefined;
|
|
26
|
-
}
|
|
23
|
+
},
|
|
27
24
|
): WorkflowModel {
|
|
28
25
|
const issues: WorkflowModelValidationIssue[] = [];
|
|
29
26
|
const defaultRunnerLabels = canonicalizeLabels(options.defaultRunnerLabels);
|
|
30
|
-
const harnessToolDeploymentConfig =
|
|
31
|
-
options.harnessToolDeploymentConfig ?? DEFAULT_HARNESS_TOOL_DEPLOYMENT_CONFIG;
|
|
32
27
|
const context = {
|
|
33
28
|
defaultRunnerLabels,
|
|
34
|
-
|
|
29
|
+
agentValidationCatalog: options.agentValidationCatalog,
|
|
35
30
|
integrationValidationContext: options.integrationValidationContext,
|
|
36
31
|
};
|
|
37
32
|
const jobIdBySourceName = mapJobIds(document, issues);
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
import {sql} from 'drizzle-orm';
|
|
19
19
|
import type {WorkflowDefinitionPayload} from '#core/entities/workflow-definition.js';
|
|
20
20
|
import {normalizeWorkflowDocument} from '#core/workflow-model/index.js';
|
|
21
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
21
22
|
import {db} from './db.js';
|
|
22
23
|
import {
|
|
23
24
|
applyVcsDefinitionsBatch,
|
|
@@ -82,7 +83,7 @@ function definitionFields(name = 'Test Workflow'): WorkflowDefinitionPayload {
|
|
|
82
83
|
function definitionFieldsForDocument(
|
|
83
84
|
document: WorkflowDefinitionPayload['document'],
|
|
84
85
|
): WorkflowDefinitionPayload {
|
|
85
|
-
return {document, model: normalizeWorkflowDocument(document)};
|
|
86
|
+
return {document, model: normalizeWorkflowDocument(document, {agentValidationCatalog})};
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
async function listOutboxRowsForProject(projectId: string) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {normalizeWorkflowDocument} from '#core/workflow-model/index.js';
|
|
2
|
+
import {agentValidationCatalog} from '#test/agent-validation-catalog.js';
|
|
2
3
|
import type {DefinitionDb} from './definitions.js';
|
|
3
4
|
import {toDefinition} from './definitions.js';
|
|
4
5
|
|
|
@@ -21,7 +22,7 @@ describe('toDefinition', () => {
|
|
|
21
22
|
sha: null,
|
|
22
23
|
ref: null,
|
|
23
24
|
name: 'Manual workflow',
|
|
24
|
-
definition: {document, model: normalizeWorkflowDocument(document)},
|
|
25
|
+
definition: {document, model: normalizeWorkflowDocument(document, {agentValidationCatalog})},
|
|
25
26
|
contentHash: null,
|
|
26
27
|
fetchedAt: new Date('2026-06-09T10:00:00.000Z'),
|
|
27
28
|
createdAt: new Date('2026-06-09T10:00:01.000Z'),
|
package/src/index.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import {dirname, resolve} from 'node:path';
|
|
2
2
|
import {fileURLToPath} from 'node:url';
|
|
3
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
3
4
|
import {
|
|
4
5
|
DEFINITION_RESOLVED,
|
|
5
6
|
type DefinitionsEventMap,
|
|
6
7
|
definitionsEventSchemas,
|
|
7
8
|
} from '@shipfox/api-definitions-dto';
|
|
8
|
-
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto';
|
|
9
|
-
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
9
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto/inter-module';
|
|
10
10
|
import {
|
|
11
11
|
PROJECT_SOURCE_BOUND,
|
|
12
12
|
PROJECT_SOURCE_COMMIT_OBSERVED,
|
|
13
13
|
type ProjectsEventMap,
|
|
14
14
|
} from '@shipfox/api-projects-dto';
|
|
15
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module';
|
|
15
16
|
import {type ShipfoxModule, subscriberFactory} from '@shipfox/node-module';
|
|
16
17
|
import {logger} from '@shipfox/node-opentelemetry';
|
|
17
18
|
import {createDefinitionsSourceControl} from '#core/integrations.js';
|
|
@@ -48,11 +49,13 @@ const subscriber = subscriberFactory<DefinitionsEventMap & ProjectsEventMap>();
|
|
|
48
49
|
|
|
49
50
|
export interface CreateDefinitionsModuleOptions {
|
|
50
51
|
projects: ProjectsModuleClient;
|
|
52
|
+
agent: AgentInterModuleClient;
|
|
51
53
|
integrations: IntegrationsModuleClient;
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
export function createDefinitionsModule({
|
|
55
57
|
projects,
|
|
58
|
+
agent,
|
|
56
59
|
integrations,
|
|
57
60
|
}: CreateDefinitionsModuleOptions): ShipfoxModule {
|
|
58
61
|
const sourceControl = createDefinitionsSourceControl(integrations);
|
|
@@ -60,7 +63,7 @@ export function createDefinitionsModule({
|
|
|
60
63
|
return {
|
|
61
64
|
name: 'definitions',
|
|
62
65
|
database: {db, migrationsPath},
|
|
63
|
-
routes: createDefinitionRoutes({projects, integrations}),
|
|
66
|
+
routes: createDefinitionRoutes({projects, agent, integrations}),
|
|
64
67
|
publishers: [
|
|
65
68
|
{name: 'definitions', table: definitionsOutbox, db, eventSchemas: definitionsEventSchemas},
|
|
66
69
|
],
|
|
@@ -76,7 +79,7 @@ export function createDefinitionsModule({
|
|
|
76
79
|
{
|
|
77
80
|
taskQueue: DEFINITIONS_TASK_QUEUE,
|
|
78
81
|
workflowsPath,
|
|
79
|
-
activities: () => createDefinitionSyncActivities(sourceControl, integrations),
|
|
82
|
+
activities: () => createDefinitionSyncActivities(sourceControl, agent, integrations),
|
|
80
83
|
workflows: [],
|
|
81
84
|
},
|
|
82
85
|
],
|
|
@@ -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'),
|