@shipfox/api-workflows 4.0.0 → 6.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 +104 -0
- package/dist/core/agent-defaults.d.ts +17 -0
- package/dist/core/agent-defaults.d.ts.map +1 -0
- package/dist/core/agent-defaults.js +21 -0
- package/dist/core/agent-defaults.js.map +1 -0
- package/dist/core/agent-tool-capability-warning.d.ts +4 -0
- package/dist/core/agent-tool-capability-warning.d.ts.map +1 -1
- package/dist/core/agent-tool-capability-warning.js +15 -17
- package/dist/core/agent-tool-capability-warning.js.map +1 -1
- package/dist/core/agent-tools.d.ts +11 -9
- package/dist/core/agent-tools.d.ts.map +1 -1
- package/dist/core/agent-tools.js +23 -18
- package/dist/core/agent-tools.js.map +1 -1
- package/dist/core/checkout.d.ts +21 -7
- package/dist/core/checkout.d.ts.map +1 -1
- package/dist/core/checkout.js +23 -11
- package/dist/core/checkout.js.map +1 -1
- package/dist/core/entities/workflow-run-attempt.d.ts +1 -1
- package/dist/core/entities/workflow-run-attempt.d.ts.map +1 -1
- package/dist/core/entities/workflow-run-attempt.js.map +1 -1
- package/dist/core/job-execution.d.ts +3 -1
- package/dist/core/job-execution.d.ts.map +1 -1
- package/dist/core/job-execution.js +14 -12
- package/dist/core/job-execution.js.map +1 -1
- package/dist/core/job-transition/derive-job-execution-outputs.d.ts +1 -1
- package/dist/core/job-transition/derive-job-execution-outputs.d.ts.map +1 -1
- package/dist/core/job-transition/derive-job-execution-outputs.js.map +1 -1
- package/dist/core/job-transition/derive-job-success.js +1 -1
- package/dist/core/job-transition/derive-job-success.js.map +1 -1
- package/dist/core/listener-execution-materialization.d.ts +3 -3
- package/dist/core/listener-execution-materialization.d.ts.map +1 -1
- package/dist/core/listener-execution-materialization.js +3 -4
- package/dist/core/listener-execution-materialization.js.map +1 -1
- package/dist/core/run-workflow.d.ts +12 -1
- package/dist/core/run-workflow.d.ts.map +1 -1
- package/dist/core/run-workflow.js +13 -8
- package/dist/core/run-workflow.js.map +1 -1
- package/dist/core/step-config/agent.d.ts +8 -8
- package/dist/core/step-config/agent.d.ts.map +1 -1
- package/dist/core/step-config/agent.js +12 -10
- package/dist/core/step-config/agent.js.map +1 -1
- package/dist/core/step-config/complete-step-dispatch-config.d.ts +4 -4
- package/dist/core/step-config/complete-step-dispatch-config.d.ts.map +1 -1
- package/dist/core/step-config/complete-step-dispatch-config.js +2 -2
- package/dist/core/step-config/complete-step-dispatch-config.js.map +1 -1
- package/dist/core/step-config/materialize-job-execution-steps.d.ts +3 -3
- package/dist/core/step-config/materialize-job-execution-steps.d.ts.map +1 -1
- package/dist/core/step-config/materialize-job-execution-steps.js +5 -6
- package/dist/core/step-config/materialize-job-execution-steps.js.map +1 -1
- package/dist/core/step-config/materialize-workflow-model.d.ts +3 -3
- package/dist/core/step-config/materialize-workflow-model.d.ts.map +1 -1
- package/dist/core/step-config/materialize-workflow-model.js +4 -4
- package/dist/core/step-config/materialize-workflow-model.js.map +1 -1
- package/dist/core/step-config/resolve-job-execution-name.d.ts +1 -1
- package/dist/core/step-config/resolve-job-execution-name.d.ts.map +1 -1
- package/dist/core/step-config/resolve-job-execution-name.js.map +1 -1
- package/dist/core/step-config/resolve-step-config.d.ts +4 -4
- package/dist/core/step-config/resolve-step-config.d.ts.map +1 -1
- package/dist/core/step-config/resolve-step-config.js +6 -6
- package/dist/core/step-config/resolve-step-config.js.map +1 -1
- package/dist/core/step-config/run.d.ts +1 -1
- package/dist/core/step-config/run.d.ts.map +1 -1
- package/dist/core/step-config/run.js.map +1 -1
- package/dist/core/workflow-run-creation.d.ts +3 -3
- package/dist/core/workflow-run-creation.d.ts.map +1 -1
- package/dist/core/workflow-run-creation.js +3 -4
- package/dist/core/workflow-run-creation.js.map +1 -1
- package/dist/db/db.d.ts +16 -4
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/job-listeners.d.ts +7 -1
- package/dist/db/job-listeners.d.ts.map +1 -1
- package/dist/db/job-listeners.js +10 -5
- package/dist/db/job-listeners.js.map +1 -1
- package/dist/db/runner-lease-table.d.ts +5 -5
- package/dist/db/runner-lease-table.d.ts.map +1 -1
- package/dist/db/runner-lease-table.js +3 -2
- package/dist/db/runner-lease-table.js.map +1 -1
- package/dist/db/schema/workflow-run-attempts.d.ts +9 -3
- package/dist/db/schema/workflow-run-attempts.d.ts.map +1 -1
- package/dist/db/schema/workflow-run-attempts.js +2 -1
- package/dist/db/schema/workflow-run-attempts.js.map +1 -1
- package/dist/db/schema/workflow-runs.js +1 -1
- package/dist/db/schema/workflow-runs.js.map +1 -1
- package/dist/db/workflow-runs/job-executions.d.ts +5 -0
- package/dist/db/workflow-runs/job-executions.d.ts.map +1 -1
- package/dist/db/workflow-runs/job-executions.js +14 -7
- package/dist/db/workflow-runs/job-executions.js.map +1 -1
- package/dist/db/workflow-runs/jobs.d.ts.map +1 -1
- package/dist/db/workflow-runs/jobs.js +3 -1
- package/dist/db/workflow-runs/jobs.js.map +1 -1
- package/dist/db/workflow-runs/run-create.d.ts +9 -2
- package/dist/db/workflow-runs/run-create.d.ts.map +1 -1
- package/dist/db/workflow-runs/run-create.js +12 -9
- package/dist/db/workflow-runs/run-create.js.map +1 -1
- package/dist/db/workflow-runs/run-rerun.d.ts.map +1 -1
- package/dist/db/workflow-runs/run-rerun.js +3 -1
- package/dist/db/workflow-runs/run-rerun.js.map +1 -1
- package/dist/index.d.ts +18 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +61 -37
- package/dist/index.js.map +1 -1
- package/dist/presentation/dto/checkout-token.d.ts +14 -1
- package/dist/presentation/dto/checkout-token.d.ts.map +1 -1
- package/dist/presentation/dto/checkout-token.js.map +1 -1
- package/dist/presentation/index.d.ts +1 -1
- package/dist/presentation/index.d.ts.map +1 -1
- package/dist/presentation/index.js +1 -1
- package/dist/presentation/index.js.map +1 -1
- package/dist/presentation/inter-module.d.ts +18 -0
- package/dist/presentation/inter-module.d.ts.map +1 -0
- package/dist/presentation/inter-module.js +113 -0
- package/dist/presentation/inter-module.js.map +1 -0
- package/dist/presentation/routes/agent-runtime-config.d.ts +6 -1
- package/dist/presentation/routes/agent-runtime-config.d.ts.map +1 -1
- package/dist/presentation/routes/agent-runtime-config.js +59 -57
- package/dist/presentation/routes/agent-runtime-config.js.map +1 -1
- package/dist/presentation/routes/cancel-run.d.ts +2 -1
- package/dist/presentation/routes/cancel-run.d.ts.map +1 -1
- package/dist/presentation/routes/cancel-run.js +37 -34
- package/dist/presentation/routes/cancel-run.js.map +1 -1
- package/dist/presentation/routes/checkout-token.d.ts +8 -1
- package/dist/presentation/routes/checkout-token.d.ts.map +1 -1
- package/dist/presentation/routes/checkout-token.js +65 -47
- package/dist/presentation/routes/checkout-token.js.map +1 -1
- package/dist/presentation/routes/get-run-aggregates.d.ts +2 -1
- package/dist/presentation/routes/get-run-aggregates.d.ts.map +1 -1
- package/dist/presentation/routes/get-run-aggregates.js +44 -53
- package/dist/presentation/routes/get-run-aggregates.js.map +1 -1
- package/dist/presentation/routes/get-run.d.ts +2 -1
- package/dist/presentation/routes/get-run.d.ts.map +1 -1
- package/dist/presentation/routes/get-run.js +53 -50
- package/dist/presentation/routes/get-run.js.map +1 -1
- package/dist/presentation/routes/get-step-secrets.d.ts +3 -1
- package/dist/presentation/routes/get-step-secrets.d.ts.map +1 -1
- package/dist/presentation/routes/get-step-secrets.js +72 -68
- package/dist/presentation/routes/get-step-secrets.js.map +1 -1
- package/dist/presentation/routes/index.d.ts +19 -2
- package/dist/presentation/routes/index.d.ts.map +1 -1
- package/dist/presentation/routes/index.js +38 -30
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/presentation/routes/leased-step.d.ts +2 -0
- package/dist/presentation/routes/leased-step.d.ts.map +1 -1
- package/dist/presentation/routes/leased-step.js +1 -2
- package/dist/presentation/routes/leased-step.js.map +1 -1
- package/dist/presentation/routes/list-run-attempts.d.ts +2 -1
- package/dist/presentation/routes/list-run-attempts.d.ts.map +1 -1
- package/dist/presentation/routes/list-run-attempts.js +29 -26
- package/dist/presentation/routes/list-run-attempts.js.map +1 -1
- package/dist/presentation/routes/list-runs.d.ts +2 -1
- package/dist/presentation/routes/list-runs.d.ts.map +1 -1
- package/dist/presentation/routes/list-runs.js +51 -60
- package/dist/presentation/routes/list-runs.js.map +1 -1
- package/dist/presentation/routes/next-step.d.ts +10 -1
- package/dist/presentation/routes/next-step.d.ts.map +1 -1
- package/dist/presentation/routes/next-step.js +64 -50
- package/dist/presentation/routes/next-step.js.map +1 -1
- package/dist/presentation/routes/project-access.d.ts +10 -0
- package/dist/presentation/routes/project-access.d.ts.map +1 -0
- package/dist/presentation/routes/project-access.js +17 -0
- package/dist/presentation/routes/project-access.js.map +1 -0
- package/dist/presentation/routes/report-step.d.ts +2 -1
- package/dist/presentation/routes/report-step.d.ts.map +1 -1
- package/dist/presentation/routes/report-step.js +62 -61
- package/dist/presentation/routes/report-step.js.map +1 -1
- package/dist/presentation/routes/require-accessible-run.d.ts +3 -1
- package/dist/presentation/routes/require-accessible-run.d.ts.map +1 -1
- package/dist/presentation/routes/require-accessible-run.js +3 -6
- package/dist/presentation/routes/require-accessible-run.js.map +1 -1
- package/dist/presentation/routes/rerun-run.d.ts +2 -1
- package/dist/presentation/routes/rerun-run.d.ts.map +1 -1
- package/dist/presentation/routes/rerun-run.js +46 -43
- package/dist/presentation/routes/rerun-run.js.map +1 -1
- package/dist/temporal/activities/index.d.ts +44 -9
- package/dist/temporal/activities/index.d.ts.map +1 -1
- package/dist/temporal/activities/index.js +13 -9
- package/dist/temporal/activities/index.js.map +1 -1
- package/dist/temporal/activities/orchestration-activities.d.ts +20 -11
- package/dist/temporal/activities/orchestration-activities.d.ts.map +1 -1
- package/dist/temporal/activities/orchestration-activities.js +48 -33
- package/dist/temporal/activities/orchestration-activities.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +41 -44
- package/src/core/agent-defaults.test.ts +28 -0
- package/src/core/agent-defaults.ts +36 -0
- package/src/core/agent-tool-capability-warning.test.ts +36 -11
- package/src/core/agent-tool-capability-warning.ts +27 -25
- package/src/core/agent-tools.ts +33 -36
- package/src/core/checkout.test.ts +38 -25
- package/src/core/checkout.ts +41 -14
- package/src/core/entities/workflow-run-attempt.ts +1 -1
- package/src/core/job-execution.ts +19 -9
- package/src/core/job-transition/derive-job-execution-outputs.ts +1 -1
- package/src/core/job-transition/derive-job-success.ts +1 -1
- package/src/core/listener-execution-materialization.test.ts +4 -2
- package/src/core/listener-execution-materialization.ts +6 -9
- package/src/core/run-workflow.test.ts +43 -38
- package/src/core/run-workflow.ts +26 -9
- package/src/core/step-config/agent.ts +24 -26
- package/src/core/step-config/complete-step-dispatch-config.test.ts +22 -23
- package/src/core/step-config/complete-step-dispatch-config.ts +6 -6
- package/src/core/step-config/materialize-job-execution-steps.test.ts +34 -23
- package/src/core/step-config/materialize-job-execution-steps.ts +38 -39
- package/src/core/step-config/materialize-workflow-model.test.ts +94 -82
- package/src/core/step-config/materialize-workflow-model.ts +31 -29
- package/src/core/step-config/resolve-job-execution-name.ts +1 -1
- package/src/core/step-config/resolve-step-config.ts +11 -9
- package/src/core/step-config/run.ts +1 -1
- package/src/core/workflow-run-creation.test.ts +14 -10
- package/src/core/workflow-run-creation.ts +6 -9
- package/src/db/job-listeners.ts +20 -5
- package/src/db/runner-lease-table.ts +2 -2
- package/src/db/schema/workflow-run-attempts.ts +7 -3
- package/src/db/schema/workflow-runs.ts +1 -1
- package/src/db/workflow-runs/job-executions.ts +15 -1
- package/src/db/workflow-runs/jobs.ts +4 -1
- package/src/db/workflow-runs/run-create.test.ts +7 -1
- package/src/db/workflow-runs/run-create.ts +25 -15
- package/src/db/workflow-runs/run-rerun.test.ts +1 -1
- package/src/db/workflow-runs/run-rerun.ts +6 -3
- package/src/index.ts +75 -33
- package/src/presentation/dto/checkout-token.ts +7 -1
- package/src/presentation/index.ts +1 -1
- package/src/presentation/inter-module.test.ts +149 -0
- package/src/presentation/inter-module.ts +132 -0
- package/src/presentation/routes/agent-runtime-config.test.ts +53 -10
- package/src/presentation/routes/agent-runtime-config.ts +89 -64
- package/src/presentation/routes/cancel-run.test.ts +10 -20
- package/src/presentation/routes/cancel-run.ts +30 -27
- package/src/presentation/routes/checkout-token.test.ts +52 -33
- package/src/presentation/routes/checkout-token.ts +109 -49
- package/src/presentation/routes/get-run-aggregates.test.ts +13 -7
- package/src/presentation/routes/get-run-aggregates.ts +54 -57
- package/src/presentation/routes/get-run.test.ts +10 -18
- package/src/presentation/routes/get-run.ts +51 -48
- package/src/presentation/routes/get-step-secrets.test.ts +29 -7
- package/src/presentation/routes/get-step-secrets.ts +72 -61
- package/src/presentation/routes/index.test.ts +16 -1
- package/src/presentation/routes/index.ts +54 -29
- package/src/presentation/routes/leased-step.ts +3 -2
- package/src/presentation/routes/list-run-attempts.test.ts +9 -19
- package/src/presentation/routes/list-run-attempts.ts +21 -18
- package/src/presentation/routes/list-runs.test.ts +13 -7
- package/src/presentation/routes/list-runs.ts +64 -67
- package/src/presentation/routes/next-step.test.ts +30 -11
- package/src/presentation/routes/next-step.ts +68 -48
- package/src/presentation/routes/project-access.ts +16 -0
- package/src/presentation/routes/report-step.test.ts +18 -2
- package/src/presentation/routes/report-step.ts +51 -49
- package/src/presentation/routes/require-accessible-run.ts +5 -2
- package/src/presentation/routes/rerun-run.test.ts +9 -19
- package/src/presentation/routes/rerun-run.ts +39 -36
- package/src/temporal/activities/index.ts +32 -12
- package/src/temporal/activities/orchestration-activities.test.ts +10 -8
- package/src/temporal/activities/orchestration-activities.ts +74 -50
- package/src/temporal/workflows/job-execution-orchestration.test.ts +47 -2
- package/test/env.ts +1 -3
- package/test/factories/project.ts +10 -5
- package/test/factories/workflow-model.test.ts +5 -1
- package/test/factories/workflow-model.ts +1 -1
- package/test/factories/workflow-run.ts +1 -1
- package/test/fixtures/agent-inter-module.ts +27 -0
- package/test/fixtures/annotations-inter-module.ts +5 -0
- package/test/fixtures/auth-inter-module.ts +22 -0
- package/test/fixtures/lease-token.ts +2 -1
- package/test/fixtures/projects-inter-module.ts +8 -0
- package/test/fixtures/runners-inter-module.ts +52 -0
- package/test/fixtures/secrets-inter-module.ts +61 -0
- package/test/globalSetup.ts +11 -11
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/core/source-control.d.ts +0 -5
- package/dist/core/source-control.d.ts.map +0 -1
- package/dist/core/source-control.js +0 -19
- package/dist/core/source-control.js.map +0 -1
- package/src/core/source-control.test.ts +0 -17
- package/src/core/source-control.ts +0 -22
- package/src/temporal/workflows/job-execution-orchestration-timeout.test.ts +0 -165
package/src/core/checkout.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
1
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
3
3
|
import {getJobById, getWorkflowRunByAttemptId} from '#db/workflow-runs.js';
|
|
4
4
|
import {
|
|
5
5
|
CheckoutIntentUnresolvedError,
|
|
@@ -20,15 +20,18 @@ export interface CheckoutIntent {
|
|
|
20
20
|
* (`workflowRunId`/`workflowRunAttemptId`/`workspaceId` in the lease claim are informational).
|
|
21
21
|
* Chain: job → attempt → run → project source metadata. Credential-free.
|
|
22
22
|
*/
|
|
23
|
-
export async function resolveCheckoutIntent(
|
|
23
|
+
export async function resolveCheckoutIntent(
|
|
24
|
+
jobId: string,
|
|
25
|
+
projects: ProjectsModuleClient,
|
|
26
|
+
): Promise<CheckoutIntent> {
|
|
24
27
|
const job = await getJobById(jobId);
|
|
25
28
|
if (!job) throw new JobNotFoundError(jobId);
|
|
26
29
|
|
|
27
30
|
const run = await getWorkflowRunByAttemptId(job.workflowRunAttemptId);
|
|
28
31
|
if (!run) throw new WorkflowRunNotFoundError(job.workflowRunAttemptId);
|
|
29
32
|
|
|
30
|
-
const project = await getProjectById(run.projectId);
|
|
31
|
-
if (
|
|
33
|
+
const {project} = await projects.getProjectById({projectId: run.projectId});
|
|
34
|
+
if (project === null) throw new CheckoutIntentUnresolvedError(run.projectId);
|
|
32
35
|
|
|
33
36
|
return {
|
|
34
37
|
workspaceId: project.workspaceId,
|
|
@@ -41,23 +44,47 @@ export async function resolveCheckoutIntent(jobId: string): Promise<CheckoutInte
|
|
|
41
44
|
|
|
42
45
|
/**
|
|
43
46
|
* Resolves the job's checkout intent and exchanges it for a short-lived,
|
|
44
|
-
* scoped checkout spec. `ref`
|
|
45
|
-
*
|
|
47
|
+
* scoped checkout spec. Omitting `ref` lets the provider use the repository's
|
|
48
|
+
* default branch while preserving the JSON-only inter-module boundary.
|
|
46
49
|
*/
|
|
47
50
|
export async function createJobCheckoutSpec({
|
|
48
51
|
jobId,
|
|
49
|
-
|
|
52
|
+
integrations,
|
|
53
|
+
projects,
|
|
50
54
|
}: {
|
|
51
55
|
jobId: string;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
integrations: IntegrationsModuleClient;
|
|
57
|
+
projects: ProjectsModuleClient;
|
|
58
|
+
}): Promise<{
|
|
59
|
+
spec: {
|
|
60
|
+
repositoryUrl: string;
|
|
61
|
+
ref: string;
|
|
62
|
+
credentials?: {username: string; token: string; expiresAt: Date};
|
|
63
|
+
gitAuthor?: {name: string; email: string};
|
|
64
|
+
};
|
|
65
|
+
persistCredentials: boolean;
|
|
66
|
+
}> {
|
|
67
|
+
const intent = await resolveCheckoutIntent(jobId, projects);
|
|
68
|
+
const response = await integrations.createCheckoutSpec({
|
|
56
69
|
workspaceId: intent.workspaceId,
|
|
57
70
|
connectionId: intent.connectionId,
|
|
58
71
|
externalRepositoryId: intent.externalRepositoryId,
|
|
59
|
-
ref: undefined,
|
|
60
72
|
permissions: intent.permissions,
|
|
61
73
|
});
|
|
62
|
-
|
|
74
|
+
const {credentials, gitAuthor, ...checkout} = response;
|
|
75
|
+
return {
|
|
76
|
+
spec: {
|
|
77
|
+
...checkout,
|
|
78
|
+
...(credentials
|
|
79
|
+
? {
|
|
80
|
+
credentials: {
|
|
81
|
+
...credentials,
|
|
82
|
+
expiresAt: new Date(credentials.expiresAt),
|
|
83
|
+
},
|
|
84
|
+
}
|
|
85
|
+
: {}),
|
|
86
|
+
...(gitAuthor ? {gitAuthor} : {}),
|
|
87
|
+
},
|
|
88
|
+
persistCredentials: intent.persistCredentials,
|
|
89
|
+
};
|
|
63
90
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
2
2
|
import type {LogOutcomeDto} from '@shipfox/api-workflows-dto';
|
|
3
3
|
import {
|
|
4
4
|
coerceStepOutputs,
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
recordWorkflowJobExecutionStepsSettled,
|
|
27
27
|
recordWorkflowStepRestartEnqueued,
|
|
28
28
|
} from '#metrics/instance.js';
|
|
29
|
+
import {createAgentDefaultsResolver} from './agent-defaults.js';
|
|
29
30
|
import {defaultStepConditionTrace, explicitConditionTrace} from './condition-trace.js';
|
|
30
31
|
import type {JobExecution} from './entities/job-execution.js';
|
|
31
32
|
import type {PersistedEvaluationTraceEntry, Step, StepStatusReason} from './entities/step.js';
|
|
@@ -83,6 +84,7 @@ interface PendingStepDispatchParams {
|
|
|
83
84
|
readonly jobExecution: JobExecution;
|
|
84
85
|
readonly context: WorkflowEvaluationContext;
|
|
85
86
|
readonly tx: Tx;
|
|
87
|
+
readonly agent?: AgentInterModuleClient | undefined;
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
interface ResolvePendingStepParams {
|
|
@@ -92,6 +94,7 @@ interface ResolvePendingStepParams {
|
|
|
92
94
|
readonly attempts: Awaited<ReturnType<typeof getStepAttemptsByJobExecutionId>>;
|
|
93
95
|
readonly jobs: Awaited<ReturnType<typeof getDirectDependencyJobContexts>>;
|
|
94
96
|
readonly tx: Tx;
|
|
97
|
+
readonly agent?: AgentInterModuleClient | undefined;
|
|
95
98
|
}
|
|
96
99
|
|
|
97
100
|
type StepConditionOutcome =
|
|
@@ -105,6 +108,7 @@ type StepConditionOutcome =
|
|
|
105
108
|
async function nextStepForJobExecutionInTransaction(
|
|
106
109
|
jobExecutionId: string,
|
|
107
110
|
tx: Tx,
|
|
111
|
+
agent?: AgentInterModuleClient | undefined,
|
|
108
112
|
): Promise<NextStep> {
|
|
109
113
|
const steps = await getStepsByJobExecutionIdForUpdate(jobExecutionId, tx);
|
|
110
114
|
const hasNoSteps = steps.length === 0;
|
|
@@ -129,7 +133,7 @@ async function nextStepForJobExecutionInTransaction(
|
|
|
129
133
|
const attempts = await getStepAttemptsByJobExecutionId(jobExecutionId, tx);
|
|
130
134
|
const jobs = await getDirectDependencyJobContexts(jobExecution.jobId, tx);
|
|
131
135
|
|
|
132
|
-
return resolveNextPendingStep({jobExecutionId, steps, jobExecution, attempts, jobs, tx});
|
|
136
|
+
return resolveNextPendingStep({jobExecutionId, steps, jobExecution, attempts, jobs, tx, agent});
|
|
133
137
|
}
|
|
134
138
|
|
|
135
139
|
async function resolveNextPendingStep({
|
|
@@ -139,6 +143,7 @@ async function resolveNextPendingStep({
|
|
|
139
143
|
attempts,
|
|
140
144
|
jobs,
|
|
141
145
|
tx,
|
|
146
|
+
agent,
|
|
142
147
|
}: ResolvePendingStepParams): Promise<NextStep> {
|
|
143
148
|
let skippedAny = false;
|
|
144
149
|
let currentSteps = steps;
|
|
@@ -167,7 +172,7 @@ async function resolveNextPendingStep({
|
|
|
167
172
|
});
|
|
168
173
|
const condition = evaluateStepCondition({step: pending, context});
|
|
169
174
|
if (condition.kind === 'run') {
|
|
170
|
-
return dispatchPendingStep({jobExecutionId, pending, jobExecution, context, tx});
|
|
175
|
+
return dispatchPendingStep({jobExecutionId, pending, jobExecution, context, tx, agent});
|
|
171
176
|
}
|
|
172
177
|
|
|
173
178
|
const skipped = await markStepSkipped(
|
|
@@ -208,12 +213,13 @@ async function dispatchPendingStepWithConfigPlan({
|
|
|
208
213
|
jobExecution,
|
|
209
214
|
context,
|
|
210
215
|
tx,
|
|
216
|
+
agent,
|
|
211
217
|
}: PendingStepDispatchParams): Promise<NextStep> {
|
|
212
218
|
try {
|
|
213
|
-
const completed = completeStepDispatchConfig({
|
|
219
|
+
const completed = await completeStepDispatchConfig({
|
|
214
220
|
step: pending,
|
|
215
221
|
context,
|
|
216
|
-
resolveAgentDefaults:
|
|
222
|
+
resolveAgentDefaults: agent ? createAgentDefaultsResolver(agent, null) : undefined,
|
|
217
223
|
definitionId: jobExecution.jobId,
|
|
218
224
|
});
|
|
219
225
|
const marked = await dispatchStepWithCompletedConfig(
|
|
@@ -258,7 +264,7 @@ async function dispatchPendingStepWithConfigPlan({
|
|
|
258
264
|
});
|
|
259
265
|
if (status) recordWorkflowJobExecutionStepsSettled(status);
|
|
260
266
|
return status === null
|
|
261
|
-
? nextStepForJobExecutionInTransaction(jobExecutionId, tx)
|
|
267
|
+
? nextStepForJobExecutionInTransaction(jobExecutionId, tx, agent)
|
|
262
268
|
: {kind: 'done', status};
|
|
263
269
|
}
|
|
264
270
|
}
|
|
@@ -333,6 +339,7 @@ export interface NextStepForLeasedJobExecutionParams {
|
|
|
333
339
|
jobId: string;
|
|
334
340
|
jobExecutionId: string;
|
|
335
341
|
runnerSessionId: string;
|
|
342
|
+
agent?: AgentInterModuleClient | undefined;
|
|
336
343
|
}
|
|
337
344
|
|
|
338
345
|
export function nextStepForLeasedJobExecution(
|
|
@@ -342,16 +349,19 @@ export function nextStepForLeasedJobExecution(
|
|
|
342
349
|
const leaseIsActive = await lockActiveJobExecutionLeaseForUpdate(params, tx);
|
|
343
350
|
if (!leaseIsActive) throw new JobLeaseNotActiveError(params.jobExecutionId);
|
|
344
351
|
|
|
345
|
-
return nextStepForJobExecutionInTransaction(params.jobExecutionId, tx);
|
|
352
|
+
return nextStepForJobExecutionInTransaction(params.jobExecutionId, tx, params.agent);
|
|
346
353
|
});
|
|
347
354
|
}
|
|
348
355
|
|
|
349
|
-
export function nextStepForJob(
|
|
356
|
+
export function nextStepForJob(
|
|
357
|
+
jobId: string,
|
|
358
|
+
agent?: AgentInterModuleClient | undefined,
|
|
359
|
+
): Promise<NextStep> {
|
|
350
360
|
return withTransaction(async (tx) => {
|
|
351
361
|
const jobExecution = await getLatestJobExecutionByJobId(jobId, tx);
|
|
352
362
|
if (!jobExecution) throw new JobNotFoundError(jobId);
|
|
353
363
|
|
|
354
|
-
return nextStepForJobExecutionInTransaction(jobExecution.id, tx);
|
|
364
|
+
return nextStepForJobExecutionInTransaction(jobExecution.id, tx, agent);
|
|
355
365
|
});
|
|
356
366
|
}
|
|
357
367
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {WorkflowModel} from '@shipfox/api-definitions';
|
|
1
|
+
import type {WorkflowModel} from '@shipfox/api-definitions-dto';
|
|
2
2
|
import type {Job} from '../entities/job.js';
|
|
3
3
|
import type {JobExecution} from '../entities/job-execution.js';
|
|
4
4
|
import type {Step, StepAttempt} from '../entities/step.js';
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import {resolveTestAgentDefaults} from '#test/fixtures/agent-inter-module.js';
|
|
1
2
|
import {workflowModel} from '#test/index.js';
|
|
2
3
|
import {materializeListenerExecution} from './listener-execution-materialization.js';
|
|
3
4
|
|
|
4
5
|
describe('materializeListenerExecution', () => {
|
|
5
|
-
it('fails cleanly when agent integration materialization is unresolvable', () => {
|
|
6
|
+
it('fails cleanly when agent integration materialization is unresolvable', async () => {
|
|
6
7
|
const model = workflowModel({
|
|
7
8
|
jobs: {
|
|
8
9
|
review: {
|
|
@@ -16,7 +17,7 @@ describe('materializeListenerExecution', () => {
|
|
|
16
17
|
},
|
|
17
18
|
});
|
|
18
19
|
|
|
19
|
-
const result = materializeListenerExecution({
|
|
20
|
+
const result = await materializeListenerExecution({
|
|
20
21
|
model,
|
|
21
22
|
run: {
|
|
22
23
|
id: crypto.randomUUID(),
|
|
@@ -37,6 +38,7 @@ describe('materializeListenerExecution', () => {
|
|
|
37
38
|
sequence: 1,
|
|
38
39
|
triggerEvents: [],
|
|
39
40
|
priorExecutions: [],
|
|
41
|
+
resolveAgentDefaults: resolveTestAgentDefaults,
|
|
40
42
|
});
|
|
41
43
|
|
|
42
44
|
expect(result).toMatchObject({
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
catalogDefaultAgentResolver,
|
|
4
|
-
} from '@shipfox/api-agent/core/resolve-agent-config';
|
|
5
|
-
import type {WorkflowModel} from '@shipfox/api-definitions';
|
|
1
|
+
import type {WorkflowModel} from '@shipfox/api-definitions-dto';
|
|
2
|
+
import type {AgentDefaultsResolver} from './agent-defaults.js';
|
|
6
3
|
import type {
|
|
7
4
|
AgentToolMaterializationContext,
|
|
8
5
|
AgentToolMaterializationSnapshot,
|
|
@@ -61,9 +58,9 @@ export interface MaterializedListenerExecution {
|
|
|
61
58
|
readonly steps: readonly MaterializedWorkflowStep[];
|
|
62
59
|
}
|
|
63
60
|
|
|
64
|
-
export function materializeListenerExecution(
|
|
61
|
+
export async function materializeListenerExecution(
|
|
65
62
|
params: MaterializeListenerExecutionParams,
|
|
66
|
-
): MaterializedListenerExecution {
|
|
63
|
+
): Promise<MaterializedListenerExecution> {
|
|
67
64
|
const fallbackName = `${params.job.key} #${params.sequence}`;
|
|
68
65
|
let executionName = fallbackName;
|
|
69
66
|
let evaluationTrace: readonly PersistedEvaluationTraceEntry[] = [];
|
|
@@ -95,11 +92,11 @@ export function materializeListenerExecution(
|
|
|
95
92
|
context,
|
|
96
93
|
definitionId: params.run.definitionId,
|
|
97
94
|
});
|
|
98
|
-
steps = materializeJobExecutionSteps({
|
|
95
|
+
steps = await materializeJobExecutionSteps({
|
|
99
96
|
model: params.model,
|
|
100
97
|
job: modelJob,
|
|
101
98
|
context,
|
|
102
|
-
resolveAgentDefaults: params.resolveAgentDefaults
|
|
99
|
+
resolveAgentDefaults: params.resolveAgentDefaults,
|
|
103
100
|
definitionId: params.run.definitionId,
|
|
104
101
|
agentToolContext: params.agentToolContext,
|
|
105
102
|
agentToolSnapshot: params.agentToolSnapshot,
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
1
2
|
import type {WorkflowDefinition} from '@shipfox/api-definitions';
|
|
3
|
+
import {createWorkflowModelSnapshot} from '@shipfox/api-definitions-dto';
|
|
4
|
+
import type {DefinitionsInterModuleClient} from '@shipfox/api-definitions-dto/inter-module';
|
|
2
5
|
import {workflowModel} from '#test/index.js';
|
|
3
6
|
import type {TriggerPayload} from './entities/workflow-run.js';
|
|
4
7
|
import {DefinitionNotFoundError, ProjectMismatchError} from './errors.js';
|
|
5
8
|
import {runWorkflow} from './run-workflow.js';
|
|
6
9
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
vi.fn().mockReturnValue({
|
|
10
|
+
const mockResolveAgentConfig = vi.hoisted(() =>
|
|
11
|
+
vi.fn().mockResolvedValue({
|
|
10
12
|
harness: 'pi',
|
|
11
13
|
provider: 'openai',
|
|
12
14
|
model: 'gpt-5.5-pro',
|
|
@@ -22,26 +24,26 @@ vi.mock('@shipfox/api-definitions', () => ({
|
|
|
22
24
|
getDefinitionById: vi.fn(),
|
|
23
25
|
}));
|
|
24
26
|
|
|
25
|
-
vi.mock('@shipfox/api-agent/core/resolve-agent-config', () => {
|
|
26
|
-
return {
|
|
27
|
-
catalogDefaultAgentResolver: vi.fn().mockReturnValue({
|
|
28
|
-
harness: 'pi',
|
|
29
|
-
provider: 'anthropic',
|
|
30
|
-
model: 'claude-opus-4-8',
|
|
31
|
-
thinking: 'xhigh',
|
|
32
|
-
}),
|
|
33
|
-
};
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
vi.mock('@shipfox/api-agent/core/workspace-agent-defaults-resolver', () => {
|
|
37
|
-
return {
|
|
38
|
-
createWorkspaceAgentDefaultsResolver: mockCreateWorkspaceAgentDefaultsResolver,
|
|
39
|
-
};
|
|
40
|
-
});
|
|
41
|
-
|
|
42
27
|
import {getDefinitionById} from '@shipfox/api-definitions';
|
|
43
28
|
|
|
44
29
|
const mockGetDefinitionById = vi.mocked(getDefinitionById);
|
|
30
|
+
const definitions: DefinitionsInterModuleClient = {
|
|
31
|
+
getDefinitionForWorkflowRun: async ({definitionId}) => {
|
|
32
|
+
const definition = await mockGetDefinitionById(definitionId);
|
|
33
|
+
return {
|
|
34
|
+
definition:
|
|
35
|
+
definition === undefined
|
|
36
|
+
? null
|
|
37
|
+
: {
|
|
38
|
+
id: definition.id,
|
|
39
|
+
projectId: definition.projectId,
|
|
40
|
+
name: definition.name,
|
|
41
|
+
model: createWorkflowModelSnapshot(definition.model),
|
|
42
|
+
sourceSnapshot: definition.sourceSnapshot,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
};
|
|
45
47
|
|
|
46
48
|
function buildDefinition(overrides?: Partial<WorkflowDefinition>): WorkflowDefinition {
|
|
47
49
|
const model = workflowModel();
|
|
@@ -84,13 +86,15 @@ function manualPayload(): TriggerPayload {
|
|
|
84
86
|
describe('runWorkflow', () => {
|
|
85
87
|
let workspaceId: string;
|
|
86
88
|
let projectId: string;
|
|
89
|
+
const agent: AgentInterModuleClient = {
|
|
90
|
+
resolveAgentConfig: mockResolveAgentConfig,
|
|
91
|
+
resolveRuntimeCredentials: vi.fn(),
|
|
92
|
+
};
|
|
87
93
|
|
|
88
94
|
beforeEach(() => {
|
|
89
95
|
workspaceId = crypto.randomUUID();
|
|
90
96
|
projectId = crypto.randomUUID();
|
|
91
|
-
|
|
92
|
-
mockCreateWorkspaceAgentDefaultsResolver.mockResolvedValue(mockWorkspaceAgentDefaultsResolver);
|
|
93
|
-
mockWorkspaceAgentDefaultsResolver.mockClear();
|
|
97
|
+
mockResolveAgentConfig.mockClear();
|
|
94
98
|
});
|
|
95
99
|
|
|
96
100
|
test('creates a run from a valid definition with the provided manual trigger payload', async () => {
|
|
@@ -98,11 +102,12 @@ describe('runWorkflow', () => {
|
|
|
98
102
|
mockGetDefinitionById.mockResolvedValue(definition);
|
|
99
103
|
const triggerPayload = manualPayload();
|
|
100
104
|
|
|
101
|
-
const run = await runWorkflow({
|
|
105
|
+
const run = await runWorkflow(definitions, {
|
|
102
106
|
workspaceId,
|
|
103
107
|
projectId,
|
|
104
108
|
definitionId: definition.id,
|
|
105
109
|
triggerPayload,
|
|
110
|
+
agent,
|
|
106
111
|
});
|
|
107
112
|
|
|
108
113
|
expect(run.id).toBeDefined();
|
|
@@ -114,7 +119,7 @@ describe('runWorkflow', () => {
|
|
|
114
119
|
expect(run.triggerSource).toBe('manual');
|
|
115
120
|
expect(run.triggerEvent).toBe('fire');
|
|
116
121
|
expect(run.triggerPayload).toEqual(triggerPayload);
|
|
117
|
-
expect(
|
|
122
|
+
expect(mockResolveAgentConfig).not.toHaveBeenCalled();
|
|
118
123
|
});
|
|
119
124
|
|
|
120
125
|
test('builds the workspace agent resolver only when the definition has an agent step', async () => {
|
|
@@ -126,21 +131,16 @@ describe('runWorkflow', () => {
|
|
|
126
131
|
const definition = buildDefinition({projectId, model});
|
|
127
132
|
mockGetDefinitionById.mockResolvedValue(definition);
|
|
128
133
|
|
|
129
|
-
const run = await runWorkflow({
|
|
134
|
+
const run = await runWorkflow(definitions, {
|
|
130
135
|
workspaceId,
|
|
131
136
|
projectId,
|
|
132
137
|
definitionId: definition.id,
|
|
133
138
|
triggerPayload: manualPayload(),
|
|
139
|
+
agent,
|
|
134
140
|
});
|
|
135
141
|
|
|
136
142
|
expect(run.id).toBeDefined();
|
|
137
|
-
expect(
|
|
138
|
-
expect(mockWorkspaceAgentDefaultsResolver).toHaveBeenCalledWith({
|
|
139
|
-
harness: undefined,
|
|
140
|
-
provider: undefined,
|
|
141
|
-
model: undefined,
|
|
142
|
-
thinking: undefined,
|
|
143
|
-
});
|
|
143
|
+
expect(mockResolveAgentConfig).toHaveBeenCalledWith({workspaceId, config: {}});
|
|
144
144
|
});
|
|
145
145
|
|
|
146
146
|
test('persists an integration trigger payload intact', async () => {
|
|
@@ -154,11 +154,12 @@ describe('runWorkflow', () => {
|
|
|
154
154
|
data: {ref: 'main', headCommitSha: 'abc', externalRepositoryId: 'github:1'},
|
|
155
155
|
};
|
|
156
156
|
|
|
157
|
-
const run = await runWorkflow({
|
|
157
|
+
const run = await runWorkflow(definitions, {
|
|
158
158
|
workspaceId,
|
|
159
159
|
projectId,
|
|
160
160
|
definitionId: definition.id,
|
|
161
161
|
triggerPayload,
|
|
162
|
+
agent,
|
|
162
163
|
});
|
|
163
164
|
|
|
164
165
|
expect(run.triggerProvider).toBe('github');
|
|
@@ -172,11 +173,12 @@ describe('runWorkflow', () => {
|
|
|
172
173
|
const definition = buildDefinition({projectId, sourceSnapshot});
|
|
173
174
|
mockGetDefinitionById.mockResolvedValue(definition);
|
|
174
175
|
|
|
175
|
-
const run = await runWorkflow({
|
|
176
|
+
const run = await runWorkflow(definitions, {
|
|
176
177
|
workspaceId,
|
|
177
178
|
projectId,
|
|
178
179
|
definitionId: definition.id,
|
|
179
180
|
triggerPayload: manualPayload(),
|
|
181
|
+
agent,
|
|
180
182
|
});
|
|
181
183
|
|
|
182
184
|
expect(run.sourceSnapshot).toEqual(sourceSnapshot);
|
|
@@ -188,11 +190,12 @@ describe('runWorkflow', () => {
|
|
|
188
190
|
const unknownId = crypto.randomUUID();
|
|
189
191
|
|
|
190
192
|
await expect(
|
|
191
|
-
runWorkflow({
|
|
193
|
+
runWorkflow(definitions, {
|
|
192
194
|
workspaceId,
|
|
193
195
|
projectId,
|
|
194
196
|
definitionId: unknownId,
|
|
195
197
|
triggerPayload: manualPayload(),
|
|
198
|
+
agent,
|
|
196
199
|
}),
|
|
197
200
|
).rejects.toThrow(DefinitionNotFoundError);
|
|
198
201
|
});
|
|
@@ -203,11 +206,12 @@ describe('runWorkflow', () => {
|
|
|
203
206
|
mockGetDefinitionById.mockResolvedValue(definition);
|
|
204
207
|
|
|
205
208
|
await expect(
|
|
206
|
-
runWorkflow({
|
|
209
|
+
runWorkflow(definitions, {
|
|
207
210
|
workspaceId,
|
|
208
211
|
projectId,
|
|
209
212
|
definitionId: definition.id,
|
|
210
213
|
triggerPayload: manualPayload(),
|
|
214
|
+
agent,
|
|
211
215
|
}),
|
|
212
216
|
).rejects.toThrow(ProjectMismatchError);
|
|
213
217
|
});
|
|
@@ -216,11 +220,12 @@ describe('runWorkflow', () => {
|
|
|
216
220
|
const definition = buildDefinition({projectId});
|
|
217
221
|
mockGetDefinitionById.mockResolvedValue(definition);
|
|
218
222
|
|
|
219
|
-
const run = await runWorkflow({
|
|
223
|
+
const run = await runWorkflow(definitions, {
|
|
220
224
|
workspaceId,
|
|
221
225
|
projectId,
|
|
222
226
|
definitionId: definition.id,
|
|
223
227
|
triggerPayload: manualPayload(),
|
|
228
|
+
agent,
|
|
224
229
|
inputs: {env: 'staging'},
|
|
225
230
|
});
|
|
226
231
|
|
package/src/core/run-workflow.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
2
|
+
import {workflowModelFromSnapshot} from '@shipfox/api-definitions-dto';
|
|
3
|
+
import type {DefinitionsInterModuleClient} from '@shipfox/api-definitions-dto/inter-module';
|
|
4
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto';
|
|
5
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
6
|
+
import type {SecretsInterModuleClient} from '@shipfox/api-secrets-dto/inter-module';
|
|
4
7
|
import {createWorkflowRun} from '#db/workflow-runs.js';
|
|
8
|
+
import {createAgentDefaultsResolver} from './agent-defaults.js';
|
|
5
9
|
import type {TriggerPayload, WorkflowRun} from './entities/workflow-run.js';
|
|
6
10
|
import {DefinitionNotFoundError, ProjectMismatchError} from './errors.js';
|
|
7
11
|
import {modelHasAgentStep} from './step-config/materialize-workflow-model.js';
|
|
@@ -13,29 +17,42 @@ export interface RunWorkflowParams {
|
|
|
13
17
|
triggerPayload: TriggerPayload;
|
|
14
18
|
inputs?: Record<string, unknown> | undefined;
|
|
15
19
|
triggerIdempotencyKey?: string | undefined;
|
|
20
|
+
integrations?: IntegrationsModuleClient | undefined;
|
|
21
|
+
projects?: ProjectsModuleClient | undefined;
|
|
16
22
|
}
|
|
17
23
|
|
|
18
|
-
export async function runWorkflow(
|
|
19
|
-
|
|
24
|
+
export async function runWorkflow(
|
|
25
|
+
definitions: DefinitionsInterModuleClient,
|
|
26
|
+
params: RunWorkflowParams & {agent: AgentInterModuleClient},
|
|
27
|
+
options: {secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'>} = {},
|
|
28
|
+
): Promise<WorkflowRun> {
|
|
29
|
+
const {definition} = await definitions.getDefinitionForWorkflowRun({
|
|
30
|
+
definitionId: params.definitionId,
|
|
31
|
+
});
|
|
20
32
|
if (!definition) throw new DefinitionNotFoundError(params.definitionId);
|
|
21
33
|
|
|
22
34
|
if (definition.projectId !== params.projectId) {
|
|
23
35
|
throw new ProjectMismatchError(definition.projectId, params.projectId);
|
|
24
36
|
}
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
37
|
+
const model = workflowModelFromSnapshot(definition.model);
|
|
38
|
+
const resolveAgentDefaults = createAgentDefaultsResolver(
|
|
39
|
+
params.agent,
|
|
40
|
+
modelHasAgentStep(model) ? params.workspaceId : null,
|
|
41
|
+
);
|
|
28
42
|
|
|
29
43
|
return createWorkflowRun({
|
|
30
44
|
workspaceId: params.workspaceId,
|
|
31
45
|
projectId: params.projectId,
|
|
32
46
|
definitionId: definition.id,
|
|
33
47
|
name: definition.name,
|
|
34
|
-
model
|
|
48
|
+
model,
|
|
35
49
|
triggerPayload: params.triggerPayload,
|
|
36
50
|
inputs: params.inputs,
|
|
37
51
|
sourceSnapshot: definition.sourceSnapshot,
|
|
38
52
|
triggerIdempotencyKey: params.triggerIdempotencyKey,
|
|
39
53
|
resolveAgentDefaults,
|
|
54
|
+
secrets: options.secrets,
|
|
55
|
+
integrations: params.integrations,
|
|
56
|
+
projects: params.projects,
|
|
40
57
|
});
|
|
41
58
|
}
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
InvalidAgentModelError,
|
|
3
|
-
UnsupportedHarnessProviderError,
|
|
4
|
-
UnsupportedHarnessThinkingError,
|
|
5
|
-
UnsupportedModelProviderError,
|
|
6
|
-
} from '@shipfox/api-agent/core/errors';
|
|
7
|
-
import type {AgentDefaultsResolver} from '@shipfox/api-agent/core/resolve-agent-config';
|
|
8
1
|
import {
|
|
9
2
|
AGENT_INTEGRATION_MCP_AUTH,
|
|
10
3
|
AGENT_INTEGRATION_MCP_ENDPOINT,
|
|
@@ -14,8 +7,11 @@ import {
|
|
|
14
7
|
type AgentThinking,
|
|
15
8
|
type MaterializedAgentIntegrationConfigDto,
|
|
16
9
|
} from '@shipfox/api-agent-dto';
|
|
17
|
-
import
|
|
10
|
+
import {agentInterModuleContract} from '@shipfox/api-agent-dto/inter-module';
|
|
11
|
+
import type {WorkflowModel} from '@shipfox/api-definitions-dto';
|
|
18
12
|
import type {ResolvedField, SiteResolvedField} from '@shipfox/expression';
|
|
13
|
+
import {isInterModuleKnownError} from '@shipfox/inter-module';
|
|
14
|
+
import type {AgentDefaultsResolver, ResolvedAgentDefaults} from '#core/agent-defaults.js';
|
|
19
15
|
import {
|
|
20
16
|
type AgentToolMaterializationContext,
|
|
21
17
|
type AgentToolMaterializationSnapshot,
|
|
@@ -55,7 +51,7 @@ export interface ResolveAgentStepConfigParams {
|
|
|
55
51
|
readonly context: WorkflowEvaluationContext;
|
|
56
52
|
readonly mode: StepConfigMode;
|
|
57
53
|
readonly definitionId: string;
|
|
58
|
-
readonly resolveAgentDefaults
|
|
54
|
+
readonly resolveAgentDefaults?: AgentDefaultsResolver | undefined;
|
|
59
55
|
readonly agentToolContext?: AgentToolMaterializationContext | undefined;
|
|
60
56
|
readonly agentToolSnapshot?: AgentToolMaterializationSnapshot | null | undefined;
|
|
61
57
|
}
|
|
@@ -68,7 +64,9 @@ export interface AgentStepConfig {
|
|
|
68
64
|
readonly hasTemplates: boolean;
|
|
69
65
|
}
|
|
70
66
|
|
|
71
|
-
export function resolveAgentStepConfig(
|
|
67
|
+
export async function resolveAgentStepConfig(
|
|
68
|
+
params: ResolveAgentStepConfigParams,
|
|
69
|
+
): Promise<AgentStepConfig> {
|
|
72
70
|
const fields = resolveAgentFields(params);
|
|
73
71
|
const usesAuthoredMode = params.mode === 'authored';
|
|
74
72
|
|
|
@@ -78,17 +76,17 @@ export function resolveAgentStepConfig(params: ResolveAgentStepConfigParams): Ag
|
|
|
78
76
|
fields.model?.kind === 'residual' || fields.provider?.kind === 'residual';
|
|
79
77
|
if (hasDeferredModelOrProvider) return deferredAgentStepConfig(params, fields);
|
|
80
78
|
|
|
81
|
-
return agentStepConfigWithDefaults(params.step, params, fields);
|
|
79
|
+
return await agentStepConfigWithDefaults(params.step, params, fields);
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
export function completeAgentConfig(params: {
|
|
82
|
+
export async function completeAgentConfig(params: {
|
|
85
83
|
readonly config: Record<string, unknown>;
|
|
86
84
|
readonly plan: StepConfigDispatchPlan;
|
|
87
85
|
readonly context: WorkflowEvaluationContext;
|
|
88
|
-
readonly resolveAgentDefaults
|
|
86
|
+
readonly resolveAgentDefaults?: AgentDefaultsResolver | undefined;
|
|
89
87
|
readonly definitionId: string;
|
|
90
88
|
readonly trace: PersistedEvaluationTraceEntry[];
|
|
91
|
-
}): void {
|
|
89
|
+
}): Promise<void> {
|
|
92
90
|
const agent = params.plan.agent;
|
|
93
91
|
if (agent === undefined) return;
|
|
94
92
|
|
|
@@ -117,7 +115,7 @@ export function completeAgentConfig(params: {
|
|
|
117
115
|
params,
|
|
118
116
|
});
|
|
119
117
|
|
|
120
|
-
const defaults = completeAgentDefaults({
|
|
118
|
+
const defaults = await completeAgentDefaults({
|
|
121
119
|
harness: agent.harness ?? readConfigHarness(params.config),
|
|
122
120
|
provider,
|
|
123
121
|
model,
|
|
@@ -159,16 +157,18 @@ function completeAgentField(args: {
|
|
|
159
157
|
return resolved.value;
|
|
160
158
|
}
|
|
161
159
|
|
|
162
|
-
export function completeAgentDefaults(params: {
|
|
160
|
+
export async function completeAgentDefaults(params: {
|
|
163
161
|
readonly harness: WorkflowModelAgentStep['harness'] | undefined;
|
|
164
162
|
readonly provider: string | undefined;
|
|
165
163
|
readonly model: string | undefined;
|
|
166
164
|
readonly thinking: AgentThinking | undefined;
|
|
167
|
-
readonly resolveAgentDefaults
|
|
165
|
+
readonly resolveAgentDefaults?: AgentDefaultsResolver | undefined;
|
|
168
166
|
readonly definitionId: string;
|
|
169
|
-
}):
|
|
167
|
+
}): Promise<ResolvedAgentDefaults> {
|
|
168
|
+
if (!params.resolveAgentDefaults) throw new Error('Agent defaults resolver is required');
|
|
169
|
+
|
|
170
170
|
try {
|
|
171
|
-
return params.resolveAgentDefaults({
|
|
171
|
+
return await params.resolveAgentDefaults({
|
|
172
172
|
harness: params.harness,
|
|
173
173
|
provider: params.provider,
|
|
174
174
|
model: params.model,
|
|
@@ -176,10 +176,8 @@ export function completeAgentDefaults(params: {
|
|
|
176
176
|
});
|
|
177
177
|
} catch (error) {
|
|
178
178
|
if (
|
|
179
|
-
error
|
|
180
|
-
error
|
|
181
|
-
error instanceof UnsupportedHarnessThinkingError ||
|
|
182
|
-
error instanceof InvalidAgentModelError
|
|
179
|
+
isInterModuleKnownError(agentInterModuleContract.methods.resolveAgentConfig, error) &&
|
|
180
|
+
error.code === 'agent-config-invalid'
|
|
183
181
|
) {
|
|
184
182
|
throw new AgentConfigUnresolvableError(params.definitionId, {cause: error});
|
|
185
183
|
}
|
|
@@ -273,16 +271,16 @@ function deferredAgentStepConfig(
|
|
|
273
271
|
};
|
|
274
272
|
}
|
|
275
273
|
|
|
276
|
-
function agentStepConfigWithDefaults(
|
|
274
|
+
async function agentStepConfigWithDefaults(
|
|
277
275
|
step: WorkflowModelAgentStep,
|
|
278
276
|
params: ResolveAgentStepConfigParams,
|
|
279
277
|
fields: AgentFieldResolutions,
|
|
280
|
-
): AgentStepConfig {
|
|
278
|
+
): Promise<AgentStepConfig> {
|
|
281
279
|
const providerValue = frozenFieldValue(fields.provider);
|
|
282
280
|
const modelValue = frozenFieldValue(fields.model);
|
|
283
281
|
const promptIsDeferred = fields.prompt.kind === 'residual';
|
|
284
282
|
|
|
285
|
-
const resolved = completeAgentDefaults({
|
|
283
|
+
const resolved = await completeAgentDefaults({
|
|
286
284
|
harness: step.harness,
|
|
287
285
|
provider: providerValue,
|
|
288
286
|
model: modelValue,
|