@aifabrix/builder 2.51.0 → 2.52.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/jest.isolated-projects.js +77 -1
- package/jest.projects.js +5 -426
- package/lib/api/assistants.api.js +67 -0
- package/lib/api/datasources-extended.api.js +6 -6
- package/lib/api/evidence-authoring-helpers.js +267 -0
- package/lib/api/evidence-authoring.api.js +337 -0
- package/lib/api/evidence.api.js +57 -1
- package/lib/api/index.js +24 -7
- package/lib/api/pipeline.api.js +43 -3
- package/lib/api/records-bulk.api.js +28 -3
- package/lib/api/types/evidence.types.js +156 -8
- package/lib/api/work.api.js +283 -0
- package/lib/app/run-container-start.js +4 -0
- package/lib/app/run-deploy-job.js +216 -0
- package/lib/app/run-env-compose.js +32 -0
- package/lib/app/run-env-recovery.js +35 -0
- package/lib/app/run-helpers.js +15 -9
- package/lib/app/run.js +18 -2
- package/lib/channels/add-channel.js +54 -23
- package/lib/channels/approval-guides/chatgpt.js +13 -9
- package/lib/channels/approval-guides/microsoft-copilot.js +7 -8
- package/lib/channels/channel-artifact-generator.js +14 -2
- package/lib/channels/channel-credential.js +3 -1
- package/lib/channels/channel-probe-evidence.js +79 -0
- package/lib/channels/channel-probe.js +265 -13
- package/lib/channels/channel-runtime-resolver.js +120 -29
- package/lib/channels/channel-status-display.js +44 -0
- package/lib/channels/channel-targets.js +25 -1
- package/lib/channels/chatgpt-runtime-contract.js +29 -0
- package/lib/channels/microsoft-copilot-package.js +280 -0
- package/lib/channels/runtime-tool-catalog.js +165 -0
- package/lib/cli/index.js +2 -0
- package/lib/cli/infra-guided-footers.js +1 -1
- package/lib/cli/infra-guided-public-url-warn.js +55 -0
- package/lib/cli/infra-guided.js +65 -56
- package/lib/cli/setup-app.help.js +4 -0
- package/lib/cli/setup-app.js +4 -0
- package/lib/cli/setup-app.test-commands.js +59 -28
- package/lib/cli/setup-external-system-help.js +8 -2
- package/lib/cli/setup-external-system.js +62 -12
- package/lib/commands/app-test.js +2 -14
- package/lib/commands/channel-add-setup.js +8 -2
- package/lib/commands/channel.js +16 -5
- package/lib/commands/datasource-load-export-cli.js +6 -1
- package/lib/commands/deploy-gate-failure-details.js +19 -17
- package/lib/commands/deploy-gate-orchestrator.js +3 -2
- package/lib/commands/dev-down.js +2 -6
- package/lib/commands/evidence-kind.js +65 -15
- package/lib/commands/governance-generate-external.js +56 -21
- package/lib/commands/governance-verify-external.js +2 -5
- package/lib/commands/lifecycle-external.js +21 -8
- package/lib/commands/repair-datasource-apply.js +10 -1
- package/lib/commands/repair-datasource-run.js +4 -2
- package/lib/commands/repair-datasource-test-payload.js +80 -19
- package/lib/commands/repair-datasource-webhooks-sync-bridge.js +42 -3
- package/lib/commands/repair-internal.js +9 -1
- package/lib/commands/repair-openapi-sync.js +34 -17
- package/lib/commands/role-assistant.js +371 -0
- package/lib/commands/test-governance-external.js +2 -5
- package/lib/commands/up-miso.js +61 -24
- package/lib/commands/upload-data-sync-finalize.js +25 -7
- package/lib/commands/upload-sidecar-followups.js +144 -47
- package/lib/commands/upload.js +43 -6
- package/lib/commands/verify-governance-combined-external.js +73 -9
- package/lib/commands/verify-governance-db.js +80 -25
- package/lib/commands/verify-governance-external.js +31 -10
- package/lib/commands/verify-operations-external.js +2 -5
- package/lib/commands/verify-operations-step-plan.js +31 -0
- package/lib/commands/verify-trust-command-action.js +2 -5
- package/lib/commands/wizard-core-helpers.js +7 -3
- package/lib/commands/wizard-core.js +78 -9
- package/lib/datasource/bulk-loader-run-batches.js +4 -2
- package/lib/datasource/bulk-loader-service.js +5 -1
- package/lib/datasource/datasource-identifier.js +4 -3
- package/lib/datasource/datasource-validate-summary.js +2 -2
- package/lib/datasource/integration-context.js +3 -3
- package/lib/datasource/resolve-app.js +90 -8
- package/lib/datasource/test-e2e.js +2 -2
- package/lib/datasource/unified-validation-run-body.js +15 -1
- package/lib/datasource/unified-validation-run-resolve.js +2 -2
- package/lib/datasource/validate.js +13 -6
- package/lib/external-system/deploy-helpers.js +39 -1
- package/lib/external-system/deploy.js +25 -11
- package/lib/external-system/download-helpers.js +111 -2
- package/lib/external-system/download-role-assistant.js +55 -0
- package/lib/external-system/download.js +45 -26
- package/lib/external-system/test-helpers.js +1 -1
- package/lib/external-system/test-system-level.js +21 -3
- package/lib/external-system/test.js +43 -7
- package/lib/generator/builders.js +12 -15
- package/lib/generator/wizard.js +51 -4
- package/lib/lifecycle/access-control-abac.js +121 -0
- package/lib/lifecycle/lifecycle-governance-options.js +4 -1
- package/lib/lifecycle/product-model.js +3 -2
- package/lib/lifecycle/report-display.js +14 -2
- package/lib/programmatic/capability-registry.js +20 -1
- package/lib/programmatic/command-options.js +1 -0
- package/lib/programmatic/index.js +4 -0
- package/lib/programmatic/manifest-patch-section.js +48 -9
- package/lib/programmatic/manifest-section-registry-data.js +3 -2
- package/lib/programmatic/openapi-apply-result-schemas.js +44 -0
- package/lib/programmatic/openapi-component-schemas.js +16 -1
- package/lib/programmatic/openapi-description-enricher.js +3 -1
- package/lib/programmatic/openapi-descriptions.js +55 -5
- package/lib/programmatic/openapi-evidence-schemas.js +161 -0
- package/lib/programmatic/openapi-manifest-schemas.js +6 -2
- package/lib/programmatic/openapi-operation-bindings.js +99 -0
- package/lib/programmatic/openapi-request-schemas.js +36 -1
- package/lib/programmatic/openapi-result-schemas.js +1 -1
- package/lib/programmatic/openapi-schema-descriptions-certify.js +5 -1
- package/lib/programmatic/openapi-schema-descriptions-core.js +1 -1
- package/lib/programmatic/openapi-schema-descriptions-evidence.js +156 -0
- package/lib/programmatic/openapi-schema-descriptions-manifest.js +4 -3
- package/lib/programmatic/openapi-schema-descriptions-operations.js +70 -0
- package/lib/programmatic/openapi-spec.js +47 -28
- package/lib/programmatic/orchestration-openapi-meta.js +5 -0
- package/lib/programmatic/request-timeout.js +3 -0
- package/lib/programmatic/route-handler-map.js +89 -2
- package/lib/programmatic/run-certify.js +15 -2
- package/lib/programmatic/run-deploy.js +74 -0
- package/lib/programmatic/run-evidence-authoring.js +80 -0
- package/lib/programmatic/run-protection.js +124 -0
- package/lib/programmatic/run-template-workspace.js +28 -1
- package/lib/programmatic/workspace-context.js +6 -0
- package/lib/protection/auth-context.js +48 -6
- package/lib/protection/paths.js +22 -0
- package/lib/protection/run-protection-create-helpers.js +22 -1
- package/lib/protection/run-protection-create.js +1 -1
- package/lib/protection/sync-after-upload.js +1 -1
- package/lib/role-assistant/evidence-sync.js +450 -0
- package/lib/role-assistant/github-workflow.js +96 -0
- package/lib/role-assistant/knowledge-markdown-frontmatter.js +75 -0
- package/lib/role-assistant/knowledge-sync.js +485 -0
- package/lib/role-assistant/settings.js +126 -0
- package/lib/role-assistant/test-cases-evaluate.js +170 -0
- package/lib/role-assistant/test-cases-honesty.js +184 -0
- package/lib/role-assistant/test-cases.js +364 -0
- package/lib/role-assistant/test-runner-workhub-answers.js +221 -0
- package/lib/role-assistant/test-runner-workhub.js +399 -0
- package/lib/role-assistant/test-runner.js +500 -0
- package/lib/schema/application-schema.json +24 -28
- package/lib/schema/deployment-rules.yaml +1 -0
- package/lib/schema/external-datasource.schema.json +38 -4
- package/lib/schema/external-system.schema.json +4 -4
- package/lib/schema/role-assistant-settings.schema.json +108 -0
- package/lib/utils/api.js +52 -27
- package/lib/utils/app-path-resolve.js +72 -24
- package/lib/utils/authentication-shape.js +3 -1
- package/lib/utils/certify-external-workspace.js +40 -0
- package/lib/utils/deployment-validation.js +28 -3
- package/lib/utils/docker-run-ephemeral.js +115 -0
- package/lib/utils/enterprise-knowledge-paths.js +29 -12
- package/lib/utils/env-copy-keycloak.js +196 -0
- package/lib/utils/env-copy.js +34 -1
- package/lib/utils/external-system-readiness-compact-display.js +3 -0
- package/lib/utils/health-check-public-warn.js +31 -13
- package/lib/utils/health-check.js +11 -1
- package/lib/utils/help-builder.js +1 -0
- package/lib/utils/paths.js +80 -38
- package/lib/utils/pipeline-upload-auth-retry.js +15 -3
- package/lib/utils/role-assistant-paths.js +160 -0
- package/lib/utils/schema-loader.js +41 -0
- package/lib/utils/schema-resolver.js +36 -4
- package/lib/utils/token-manager.js +38 -29
- package/lib/utils/upload-sync-options.js +7 -4
- package/lib/utils/url-declarative-resolve-load-doc.js +38 -1
- package/lib/validation/external-manifest-validator.js +31 -8
- package/lib/validation/reserved-system-key-prefixes.js +56 -0
- package/lib/validation/validate-external-file.js +8 -1
- package/lib/validation/validate.js +54 -19
- package/package.json +2 -1
- package/scripts/export-builder-api-evidence.js +1 -1
- package/templates/applications/builder-api/application.yaml +3 -3
- package/templates/applications/dataplane/application.yaml +24 -17
- package/templates/applications/dataplane/env.template +2 -2
- package/templates/applications/dataplane/rbac.yaml +24 -10
- package/templates/applications/keycloak/application.yaml +2 -2
- package/templates/applications/keycloak/env.template +5 -2
- package/templates/applications/miso-controller/application.yaml +3 -3
- package/templates/applications/miso-controller/env.template +17 -2
- package/templates/channels/chatgpt/install.template.md.hbs +82 -26
- package/templates/channels/chatgpt/integration/README.md +11 -7
- package/templates/channels/chatgpt/integration/application.json +2 -2
- package/templates/channels/chatgpt/integration/chatgpt-system.json +3 -3
- package/templates/channels/chatgpt/integration/env.template +1 -1
- package/templates/channels/chatgpt/manifest.template.json.hbs +36 -5
- package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +28 -0
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +22 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +32 -22
- package/templates/channels/microsoft-copilot/integration/README.md +9 -7
- package/templates/channels/microsoft-copilot/integration/application.json +2 -2
- package/templates/channels/microsoft-copilot/integration/env.template +1 -1
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +7 -6
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +34 -6
- package/templates/channels/slack/install.template.md.hbs +6 -1
- package/templates/python/docker-compose.hbs +10 -0
- package/templates/typescript/docker-compose.hbs +10 -0
- /package/.cursor/plans/{157.1-security-quality-violations-by-type.csv → Done/157.1-security-quality-violations-by-type.csv} +0 -0
package/lib/api/index.js
CHANGED
|
@@ -79,7 +79,7 @@ class ApiClient {
|
|
|
79
79
|
headers['Content-Type'] = 'application/json';
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
// User token (bearer) → Authorization: Bearer;
|
|
82
|
+
// User token (bearer) → Authorization: Bearer; app token (client-token) → x-client-token.
|
|
83
83
|
if (this.authConfig.type === 'bootstrap' && this.authConfig.encryptionKey) {
|
|
84
84
|
headers['x-encryption-key'] = String(this.authConfig.encryptionKey);
|
|
85
85
|
} else if (this.authConfig.token) {
|
|
@@ -160,7 +160,10 @@ class ApiClient {
|
|
|
160
160
|
transport.timeoutMs = options.timeoutMs;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
if (
|
|
163
|
+
if (
|
|
164
|
+
this.authConfig.type === 'bearer' ||
|
|
165
|
+
this.authConfig.type === 'client-token'
|
|
166
|
+
) {
|
|
164
167
|
// Pass full authConfig to enable proper token refresh using controller URL
|
|
165
168
|
return await authenticatedApiCall(url, transport, this.authConfig);
|
|
166
169
|
}
|
|
@@ -213,7 +216,10 @@ class ApiClient {
|
|
|
213
216
|
requestOptions.timeoutMs = options.timeoutMs;
|
|
214
217
|
}
|
|
215
218
|
|
|
216
|
-
if (
|
|
219
|
+
if (
|
|
220
|
+
this.authConfig.type === 'bearer' ||
|
|
221
|
+
this.authConfig.type === 'client-token'
|
|
222
|
+
) {
|
|
217
223
|
// Pass full authConfig to enable proper token refresh using controller URL
|
|
218
224
|
return await authenticatedApiCall(url, requestOptions, this.authConfig);
|
|
219
225
|
}
|
|
@@ -241,7 +247,9 @@ class ApiClient {
|
|
|
241
247
|
body: formData
|
|
242
248
|
};
|
|
243
249
|
|
|
244
|
-
const hasToken =
|
|
250
|
+
const hasToken =
|
|
251
|
+
this.authConfig.type === 'bearer' ||
|
|
252
|
+
this.authConfig.type === 'client-token';
|
|
245
253
|
if (hasToken && this.authConfig.token) {
|
|
246
254
|
return await authenticatedApiCall(url, requestOptions, this.authConfig);
|
|
247
255
|
}
|
|
@@ -272,7 +280,10 @@ class ApiClient {
|
|
|
272
280
|
requestOptions.body = JSON.stringify(options.body);
|
|
273
281
|
}
|
|
274
282
|
|
|
275
|
-
if (
|
|
283
|
+
if (
|
|
284
|
+
this.authConfig.type === 'bearer' ||
|
|
285
|
+
this.authConfig.type === 'client-token'
|
|
286
|
+
) {
|
|
276
287
|
// Pass full authConfig to enable proper token refresh using controller URL
|
|
277
288
|
return await authenticatedApiCall(url, requestOptions, this.authConfig);
|
|
278
289
|
}
|
|
@@ -303,7 +314,10 @@ class ApiClient {
|
|
|
303
314
|
requestOptions.body = JSON.stringify(options.body);
|
|
304
315
|
}
|
|
305
316
|
|
|
306
|
-
if (
|
|
317
|
+
if (
|
|
318
|
+
this.authConfig.type === 'bearer' ||
|
|
319
|
+
this.authConfig.type === 'client-token'
|
|
320
|
+
) {
|
|
307
321
|
// Pass full authConfig to enable proper token refresh using controller URL
|
|
308
322
|
return await authenticatedApiCall(url, requestOptions, this.authConfig);
|
|
309
323
|
}
|
|
@@ -329,7 +343,10 @@ class ApiClient {
|
|
|
329
343
|
headers
|
|
330
344
|
};
|
|
331
345
|
|
|
332
|
-
if (
|
|
346
|
+
if (
|
|
347
|
+
this.authConfig.type === 'bearer' ||
|
|
348
|
+
this.authConfig.type === 'client-token'
|
|
349
|
+
) {
|
|
333
350
|
// Pass full authConfig to enable proper token refresh using controller URL
|
|
334
351
|
return await authenticatedApiCall(url, requestOptions, this.authConfig);
|
|
335
352
|
}
|
package/lib/api/pipeline.api.js
CHANGED
|
@@ -249,13 +249,51 @@ async function testDatasourceViaPipeline({ dataplaneUrl, systemKey, datasourceKe
|
|
|
249
249
|
*/
|
|
250
250
|
/** Multi-datasource publish often exceeds the default 30s HTTP timeout. */
|
|
251
251
|
const PIPELINE_UPLOAD_TIMEOUT_MS = 300000;
|
|
252
|
+
const PIPELINE_UPLOAD_TIMEOUT_MIN_MS = 5000;
|
|
253
|
+
const PIPELINE_UPLOAD_TIMEOUT_MAX_MS = 45 * 60 * 1000;
|
|
252
254
|
|
|
253
|
-
|
|
255
|
+
/**
|
|
256
|
+
* Resolve pipeline upload timeout (ms) for HTTP + dataplane budget.
|
|
257
|
+
* @param {number|string|undefined|null} raw
|
|
258
|
+
* @returns {number}
|
|
259
|
+
*/
|
|
260
|
+
function resolvePipelineUploadTimeoutMs(raw) {
|
|
261
|
+
if (raw === undefined || raw === null || raw === '') {
|
|
262
|
+
return PIPELINE_UPLOAD_TIMEOUT_MS;
|
|
263
|
+
}
|
|
264
|
+
const n = typeof raw === 'number' ? raw : Number(raw);
|
|
265
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
266
|
+
throw new Error(
|
|
267
|
+
`--timeout must be a positive number of milliseconds (got ${String(raw)})`
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
return Math.min(
|
|
271
|
+
PIPELINE_UPLOAD_TIMEOUT_MAX_MS,
|
|
272
|
+
Math.max(PIPELINE_UPLOAD_TIMEOUT_MIN_MS, Math.floor(n))
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* @param {string} dataplaneUrl
|
|
278
|
+
* @param {Object} authConfig
|
|
279
|
+
* @param {Object} payload
|
|
280
|
+
* @param {Object} [options]
|
|
281
|
+
* @param {number|string} [options.timeoutMs] - HTTP + dataplane publish budget (default 300000)
|
|
282
|
+
*/
|
|
283
|
+
async function uploadApplicationViaPipeline(
|
|
284
|
+
dataplaneUrl,
|
|
285
|
+
authConfig,
|
|
286
|
+
payload,
|
|
287
|
+
options = {}
|
|
288
|
+
) {
|
|
254
289
|
const body = { ...payload, status: payload.status ?? 'draft' };
|
|
290
|
+
const timeoutMs = resolvePipelineUploadTimeoutMs(options.timeoutMs);
|
|
255
291
|
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
256
292
|
return await client.post('/api/v1/pipeline/upload', {
|
|
257
293
|
body,
|
|
258
|
-
timeoutMs
|
|
294
|
+
timeoutMs,
|
|
295
|
+
params: { timeoutMs: String(timeoutMs) },
|
|
296
|
+
headers: { 'X-Aifabrix-Timeout-Ms': String(timeoutMs) }
|
|
259
297
|
});
|
|
260
298
|
}
|
|
261
299
|
|
|
@@ -268,6 +306,8 @@ module.exports = {
|
|
|
268
306
|
validatePipelineConfig,
|
|
269
307
|
testSystemViaPipeline,
|
|
270
308
|
testDatasourceViaPipeline,
|
|
271
|
-
uploadApplicationViaPipeline
|
|
309
|
+
uploadApplicationViaPipeline,
|
|
310
|
+
resolvePipelineUploadTimeoutMs,
|
|
311
|
+
PIPELINE_UPLOAD_TIMEOUT_MS
|
|
272
312
|
};
|
|
273
313
|
|
|
@@ -7,6 +7,26 @@
|
|
|
7
7
|
const { createDataplaneApiClient } = require('./index');
|
|
8
8
|
const { unwrapApiData } = require('../utils/external-system-readiness-core');
|
|
9
9
|
|
|
10
|
+
/** Default HTTP budget for records/bulk (ABAC projection can exceed 30s under load). */
|
|
11
|
+
const DEFAULT_BULK_SYNC_TIMEOUT_MS = 120000;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Resolve per-request timeout for bulk sync.
|
|
15
|
+
* @param {Object} [transportOpts]
|
|
16
|
+
* @returns {number}
|
|
17
|
+
*/
|
|
18
|
+
function resolveBulkSyncTimeoutMs(transportOpts = {}) {
|
|
19
|
+
const raw = transportOpts.timeoutMs ?? transportOpts.timeout;
|
|
20
|
+
if (raw === undefined || raw === null || raw === '') {
|
|
21
|
+
return DEFAULT_BULK_SYNC_TIMEOUT_MS;
|
|
22
|
+
}
|
|
23
|
+
const n = typeof raw === 'number' ? raw : parseInt(String(raw), 10);
|
|
24
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
25
|
+
return DEFAULT_BULK_SYNC_TIMEOUT_MS;
|
|
26
|
+
}
|
|
27
|
+
return n;
|
|
28
|
+
}
|
|
29
|
+
|
|
10
30
|
/**
|
|
11
31
|
* Bulk sync external records for a datasource.
|
|
12
32
|
* POST /api/v1/data-storage/{sourceIdOrKey}/records/bulk
|
|
@@ -16,13 +36,16 @@ const { unwrapApiData } = require('../utils/external-system-readiness-core');
|
|
|
16
36
|
* @param {string} sourceIdOrKey
|
|
17
37
|
* @param {Object} authConfig
|
|
18
38
|
* @param {import('./types/records-bulk.types').ExternalRecordBulkRequest} body
|
|
39
|
+
* @param {Object} [transportOpts]
|
|
40
|
+
* @param {number} [transportOpts.timeoutMs] - Per-request HTTP timeout (default 120000)
|
|
19
41
|
* @returns {Promise<import('./types/records-bulk.types').ExternalRecordBulkResponse>}
|
|
20
42
|
*/
|
|
21
|
-
async function bulkSyncRecords(dataplaneUrl, sourceIdOrKey, authConfig, body) {
|
|
43
|
+
async function bulkSyncRecords(dataplaneUrl, sourceIdOrKey, authConfig, body, transportOpts = {}) {
|
|
22
44
|
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
45
|
+
const timeoutMs = resolveBulkSyncTimeoutMs(transportOpts);
|
|
23
46
|
const res = await client.post(
|
|
24
47
|
`/api/v1/data-storage/${encodeURIComponent(sourceIdOrKey)}/records/bulk`,
|
|
25
|
-
{ body }
|
|
48
|
+
{ body, timeoutMs }
|
|
26
49
|
);
|
|
27
50
|
if (res && res.success === false) {
|
|
28
51
|
const msg =
|
|
@@ -39,5 +62,7 @@ async function bulkSyncRecords(dataplaneUrl, sourceIdOrKey, authConfig, body) {
|
|
|
39
62
|
}
|
|
40
63
|
|
|
41
64
|
module.exports = {
|
|
42
|
-
bulkSyncRecords
|
|
65
|
+
bulkSyncRecords,
|
|
66
|
+
resolveBulkSyncTimeoutMs,
|
|
67
|
+
DEFAULT_BULK_SYNC_TIMEOUT_MS
|
|
43
68
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview JSDoc types for Evidence Fabrix dataplane API.
|
|
3
3
|
* @author AI Fabrix Team
|
|
4
|
-
* @version 1.
|
|
4
|
+
* @version 1.1.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @typedef {'active' | 'disabled'} EvidenceStatus
|
|
8
|
+
* @typedef {'candidate' | 'active' | 'disabled' | 'archived'} EvidenceStatus
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -19,11 +19,44 @@
|
|
|
19
19
|
* @property {string|null} [roleKey]
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {Object} EvidenceContributionOverride
|
|
24
|
+
* @property {string} contributionKey
|
|
25
|
+
* @property {number} referenceValue
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @typedef {Object} EvidenceValueProposal
|
|
30
|
+
* @property {number|null} [primaryReferenceValue]
|
|
31
|
+
* @property {string|null} [primaryContributionKey]
|
|
32
|
+
* @property {string|null} [unit]
|
|
33
|
+
* @property {string|null} [rationale]
|
|
34
|
+
* @property {EvidenceContributionOverride[]} [overrides]
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @typedef {Object} EvidenceContributionProjectionItem
|
|
39
|
+
* @property {string} contributionKey
|
|
40
|
+
* @property {string|null} [typeRef]
|
|
41
|
+
* @property {string|null} [unit]
|
|
42
|
+
* @property {boolean} [primary]
|
|
43
|
+
* @property {number|null} [inheritedReferenceValue]
|
|
44
|
+
* @property {number|null} [effectiveReferenceValue]
|
|
45
|
+
* @property {boolean} [overridden]
|
|
46
|
+
* @property {string|null} [attributionKey]
|
|
47
|
+
* @property {string|null} [attributionBoundary]
|
|
48
|
+
* @property {string|null} [kindKey]
|
|
49
|
+
* @property {string|null} [kindVersion]
|
|
50
|
+
*/
|
|
51
|
+
|
|
22
52
|
/**
|
|
23
53
|
* @typedef {Object} EvidenceRow
|
|
24
54
|
* @property {string} id
|
|
25
|
-
* @property {string}
|
|
55
|
+
* @property {string|null} [key]
|
|
56
|
+
* @property {string|null} [resourceType]
|
|
26
57
|
* @property {string|null} [roleKey]
|
|
58
|
+
* @property {string|null} [kindKey]
|
|
59
|
+
* @property {string|null} [kindVersion]
|
|
27
60
|
* @property {string} title
|
|
28
61
|
* @property {string|null} [description]
|
|
29
62
|
* @property {string} when
|
|
@@ -32,23 +65,34 @@
|
|
|
32
65
|
* @property {EvidenceStatus} status
|
|
33
66
|
* @property {number|null} [generationConfidence]
|
|
34
67
|
* @property {string|null} [suggestionExplanation]
|
|
68
|
+
* @property {EvidenceContributionOverride[]|null} [contributionOverrides]
|
|
69
|
+
* @property {EvidenceValueProposal|null} [valueProposal]
|
|
70
|
+
* @property {EvidenceContributionProjectionItem[]|null} [contributionProjection]
|
|
71
|
+
* @property {string|null} [fingerprint]
|
|
72
|
+
* @property {Object|null} [provenanceSummary]
|
|
73
|
+
* @property {Object|null} [trustProjections]
|
|
35
74
|
* @property {EvidenceApprovalPolicy} approval
|
|
36
|
-
* @property {'human' | 'assistant'} createdByType
|
|
37
|
-
* @property {string} createdById
|
|
38
|
-
* @property {string} createdAt
|
|
39
|
-
* @property {string} updatedAt
|
|
75
|
+
* @property {'human' | 'assistant'} [createdByType]
|
|
76
|
+
* @property {string|Object} [createdById]
|
|
77
|
+
* @property {string} [createdAt]
|
|
78
|
+
* @property {string} [updatedAt]
|
|
40
79
|
*/
|
|
41
80
|
|
|
42
81
|
/**
|
|
43
82
|
* @typedef {Object} EvidenceCreatePayload
|
|
44
|
-
* @property {string}
|
|
83
|
+
* @property {string|null} [key]
|
|
84
|
+
* @property {string|null} [resourceType]
|
|
45
85
|
* @property {string|null} [roleKey]
|
|
86
|
+
* @property {string|null} [kindKey]
|
|
87
|
+
* @property {string|null} [kindVersion]
|
|
46
88
|
* @property {string} title
|
|
47
89
|
* @property {string|null} [description]
|
|
48
90
|
* @property {string} when
|
|
49
91
|
* @property {string} expectedBehavior
|
|
50
92
|
* @property {number|null} [order]
|
|
51
93
|
* @property {EvidenceStatus} [status]
|
|
94
|
+
* @property {EvidenceContributionOverride[]} [contributionOverrides]
|
|
95
|
+
* @property {string|null} [suggestionExplanation]
|
|
52
96
|
* @property {EvidenceApprovalPolicy} [approval]
|
|
53
97
|
*/
|
|
54
98
|
|
|
@@ -62,6 +106,110 @@
|
|
|
62
106
|
* @property {string} [roleKey]
|
|
63
107
|
* @property {boolean} [genericOnly]
|
|
64
108
|
* @property {EvidenceStatus} [status]
|
|
109
|
+
* @property {string} [kindKey]
|
|
110
|
+
* @property {string} [aspect]
|
|
111
|
+
* @property {string} [search]
|
|
112
|
+
* @property {number} [limit]
|
|
113
|
+
* @property {number} [offset]
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @typedef {Object} EvidenceMetadataKind
|
|
118
|
+
* @property {string|null} key
|
|
119
|
+
* @property {string|null} version
|
|
120
|
+
* @property {string|null} [displayName]
|
|
121
|
+
* @property {string|null} [purpose]
|
|
122
|
+
*/
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @typedef {Object} EvidenceMetadataResourceType
|
|
126
|
+
* @property {string|null} key
|
|
127
|
+
* @property {string|null} [displayName]
|
|
128
|
+
* @property {string|null} [category]
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @typedef {Object} EvidenceAuthoringMetadata
|
|
133
|
+
* @property {string} roleKey
|
|
134
|
+
* @property {EvidenceMetadataKind[]} evidenceKinds
|
|
135
|
+
* @property {string[]} aspects
|
|
136
|
+
* @property {EvidenceMetadataResourceType[]} resourceTypes
|
|
137
|
+
* @property {string[]} assistantCapabilities
|
|
138
|
+
* @property {string[]} writableFields
|
|
139
|
+
* @property {string[]} requiredFields
|
|
140
|
+
* @property {Object} constraints
|
|
141
|
+
* @property {Object} constraints.certification
|
|
142
|
+
* @property {string} constraints.certification.validationStatus
|
|
143
|
+
* @property {string} constraints.certification.candidateStatus
|
|
144
|
+
* @property {Object} constraints.activation
|
|
145
|
+
* @property {boolean} constraints.activation.requiresCertified
|
|
146
|
+
* @property {boolean} constraints.activation.requiresAuthority
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @typedef {EvidenceListParams & { roleKey: string }} EvidenceDownloadParams
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @typedef {Object} EvidenceDownloadResponse
|
|
155
|
+
* @property {string} roleKey
|
|
156
|
+
* @property {number} count
|
|
157
|
+
* @property {EvidenceRow[]} data
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* @typedef {Object} EvidenceUploadRequest
|
|
162
|
+
* @property {string} roleKey
|
|
163
|
+
* @property {EvidenceCreatePayload[]} rows
|
|
164
|
+
* @property {string} [comment]
|
|
165
|
+
*/
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @typedef {Object} EvidenceUploadAcceptedItem
|
|
169
|
+
* @property {number} index
|
|
170
|
+
* @property {string} evidenceRef
|
|
171
|
+
* @property {string} status
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @typedef {Object} EvidenceUploadRejectedItem
|
|
176
|
+
* @property {number} index
|
|
177
|
+
* @property {string} error
|
|
178
|
+
* @property {string} [evidenceRef]
|
|
179
|
+
* @property {Object[]} [issues]
|
|
180
|
+
*/
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* @typedef {Object} EvidenceUploadCertifiedItem
|
|
184
|
+
* @property {number} index
|
|
185
|
+
* @property {string} evidenceRef
|
|
186
|
+
* @property {string} status
|
|
187
|
+
* @property {Object} data
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @typedef {Object} EvidenceUploadResponse
|
|
192
|
+
* @property {string} roleKey
|
|
193
|
+
* @property {number} inserted
|
|
194
|
+
* @property {number} updated
|
|
195
|
+
* @property {EvidenceUploadAcceptedItem[]} accepted
|
|
196
|
+
* @property {EvidenceUploadRejectedItem[]} rejected
|
|
197
|
+
* @property {Object[]} warnings
|
|
198
|
+
* @property {EvidenceUploadCertifiedItem[]} certified
|
|
199
|
+
* @property {boolean} readyToActivate
|
|
200
|
+
*/
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* @typedef {Object} EvidenceActivateRequest
|
|
204
|
+
* @property {string[]} evidenceIds
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* @typedef {Object} EvidenceActivateResponse
|
|
209
|
+
* @property {number} requested
|
|
210
|
+
* @property {Array<{ evidenceId: string, result: Object }>} activated
|
|
211
|
+
* @property {Array<{ evidenceId: string, error: string, status: number|null }>} failed
|
|
212
|
+
* @property {boolean} success
|
|
65
213
|
*/
|
|
66
214
|
|
|
67
215
|
module.exports = {};
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Dataplane work runtime API client for role-assistant test flows.
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { createDataplaneApiClient } = require('./index');
|
|
10
|
+
const { unwrapApiData } = require('../utils/external-system-readiness-core');
|
|
11
|
+
|
|
12
|
+
/** Work Hub plan create runs LLM planning; 30s default is too short under load/reload. */
|
|
13
|
+
const WORK_PLAN_TIMEOUT_MS = 120000;
|
|
14
|
+
/** Task poll / result fetch can wait on Celery + CIP. */
|
|
15
|
+
const WORK_TASK_TIMEOUT_MS = 60000;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Some dataplane work routes return `{ data: { … } }` while ApiClient already
|
|
19
|
+
* wraps once — peel a nested `data` envelope when top-level identity is missing.
|
|
20
|
+
*/
|
|
21
|
+
function unwrapWorkPayload(res) {
|
|
22
|
+
const cur = unwrapApiData(res);
|
|
23
|
+
if (!cur || typeof cur !== 'object' || Array.isArray(cur)) {
|
|
24
|
+
return cur;
|
|
25
|
+
}
|
|
26
|
+
if (cur.planId || cur.taskId || cur.processExecutionId || cur.status || cur.schemaVersion) {
|
|
27
|
+
return cur;
|
|
28
|
+
}
|
|
29
|
+
if (cur.data && typeof cur.data === 'object' && !Array.isArray(cur.data)) {
|
|
30
|
+
return cur.data;
|
|
31
|
+
}
|
|
32
|
+
return cur;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function extractApiErrorMessage(res, fallbackMessage) {
|
|
36
|
+
return (
|
|
37
|
+
(res &&
|
|
38
|
+
res.error &&
|
|
39
|
+
(res.error.formattedError || res.error.error || res.error.message || res.error.detail)) ||
|
|
40
|
+
(res && (res.formattedError || res.error || res.message)) ||
|
|
41
|
+
fallbackMessage
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function assertObjectShape(value, fallbackMessage) {
|
|
46
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
47
|
+
throw new Error(fallbackMessage);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* POST /api/v1/work/start
|
|
53
|
+
* @requiresPermission {Dataplane} worker-task:create
|
|
54
|
+
* @async
|
|
55
|
+
* @param {string} dataplaneUrl
|
|
56
|
+
* @param {Object} authConfig
|
|
57
|
+
* @param {Object} body
|
|
58
|
+
* @returns {Promise<Object>}
|
|
59
|
+
*/
|
|
60
|
+
async function startWorkIntent(dataplaneUrl, authConfig, body) {
|
|
61
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
62
|
+
const res = await client.post('/api/v1/work/start', { body });
|
|
63
|
+
if (res && res.success === false) {
|
|
64
|
+
throw new Error(extractApiErrorMessage(res, 'work.start request failed'));
|
|
65
|
+
}
|
|
66
|
+
const unwrapped = unwrapWorkPayload(res);
|
|
67
|
+
assertObjectShape(unwrapped, 'work.start returned an unexpected response shape');
|
|
68
|
+
return unwrapped;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* GET /api/v1/work/executions/{processExecutionId}
|
|
73
|
+
* @requiresPermission {Dataplane} worker-task:read
|
|
74
|
+
* @async
|
|
75
|
+
* @param {string} dataplaneUrl
|
|
76
|
+
* @param {Object} authConfig
|
|
77
|
+
* @param {string} processExecutionId
|
|
78
|
+
* @returns {Promise<Object>}
|
|
79
|
+
*/
|
|
80
|
+
async function getWorkExecutionStatus(dataplaneUrl, authConfig, processExecutionId) {
|
|
81
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
82
|
+
const encodedId = encodeURIComponent(String(processExecutionId));
|
|
83
|
+
const res = await client.get(`/api/v1/work/executions/${encodedId}`, {
|
|
84
|
+
timeoutMs: WORK_TASK_TIMEOUT_MS
|
|
85
|
+
});
|
|
86
|
+
if (res && res.success === false) {
|
|
87
|
+
throw new Error(extractApiErrorMessage(res, 'work.status request failed'));
|
|
88
|
+
}
|
|
89
|
+
const unwrapped = unwrapWorkPayload(res);
|
|
90
|
+
assertObjectShape(unwrapped, 'work.status returned an unexpected response shape');
|
|
91
|
+
return unwrapped;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* POST /api/v1/work/executions/{processExecutionId}/respond
|
|
96
|
+
* @requiresPermission {Dataplane} worker-task:update
|
|
97
|
+
* @async
|
|
98
|
+
* @param {string} dataplaneUrl
|
|
99
|
+
* @param {Object} authConfig
|
|
100
|
+
* @param {string} processExecutionId
|
|
101
|
+
* @param {Object} body
|
|
102
|
+
* @returns {Promise<Object>}
|
|
103
|
+
*/
|
|
104
|
+
async function respondWorkExecution(dataplaneUrl, authConfig, processExecutionId, body) {
|
|
105
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
106
|
+
const encodedId = encodeURIComponent(String(processExecutionId));
|
|
107
|
+
const res = await client.post(`/api/v1/work/executions/${encodedId}/respond`, {
|
|
108
|
+
body,
|
|
109
|
+
timeoutMs: WORK_TASK_TIMEOUT_MS
|
|
110
|
+
});
|
|
111
|
+
if (res && res.success === false) {
|
|
112
|
+
throw new Error(extractApiErrorMessage(res, 'work.respond request failed'));
|
|
113
|
+
}
|
|
114
|
+
const unwrapped = unwrapWorkPayload(res);
|
|
115
|
+
assertObjectShape(unwrapped, 'work.respond returned an unexpected response shape');
|
|
116
|
+
return unwrapped;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* POST /api/v1/work/executions/{processExecutionId}/continue
|
|
121
|
+
* @requiresPermission {Dataplane} worker-task:update
|
|
122
|
+
* @async
|
|
123
|
+
* @param {string} dataplaneUrl
|
|
124
|
+
* @param {Object} authConfig
|
|
125
|
+
* @param {string} processExecutionId
|
|
126
|
+
* @param {Object} [body]
|
|
127
|
+
* @returns {Promise<Object>}
|
|
128
|
+
*/
|
|
129
|
+
async function continueWorkExecution(dataplaneUrl, authConfig, processExecutionId, body = {}) {
|
|
130
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
131
|
+
const encodedId = encodeURIComponent(String(processExecutionId));
|
|
132
|
+
const res = await client.post(`/api/v1/work/executions/${encodedId}/continue`, {
|
|
133
|
+
body,
|
|
134
|
+
timeoutMs: WORK_TASK_TIMEOUT_MS
|
|
135
|
+
});
|
|
136
|
+
if (res && res.success === false) {
|
|
137
|
+
throw new Error(extractApiErrorMessage(res, 'work.continue request failed'));
|
|
138
|
+
}
|
|
139
|
+
const unwrapped = unwrapWorkPayload(res);
|
|
140
|
+
assertObjectShape(unwrapped, 'work.continue returned an unexpected response shape');
|
|
141
|
+
return unwrapped;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* GET /api/v1/work/executions/{processExecutionId}/result
|
|
146
|
+
* @requiresPermission {Dataplane} worker-task:read
|
|
147
|
+
* @async
|
|
148
|
+
* @param {string} dataplaneUrl
|
|
149
|
+
* @param {Object} authConfig
|
|
150
|
+
* @param {string} processExecutionId
|
|
151
|
+
* @param {Object} [query]
|
|
152
|
+
* @returns {Promise<Object>}
|
|
153
|
+
*/
|
|
154
|
+
async function getWorkExecutionResult(dataplaneUrl, authConfig, processExecutionId, query = {}) {
|
|
155
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
156
|
+
const encodedId = encodeURIComponent(String(processExecutionId));
|
|
157
|
+
const params = {};
|
|
158
|
+
if (query && typeof query === 'object') {
|
|
159
|
+
if (query.requestedDepth) {
|
|
160
|
+
params.requestedDepth = String(query.requestedDepth);
|
|
161
|
+
}
|
|
162
|
+
if (query.format) {
|
|
163
|
+
params.format = String(query.format);
|
|
164
|
+
}
|
|
165
|
+
if (query.projection) {
|
|
166
|
+
params.projection = String(query.projection);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const res = await client.get(`/api/v1/work/executions/${encodedId}/result`, {
|
|
170
|
+
params,
|
|
171
|
+
timeoutMs: WORK_TASK_TIMEOUT_MS
|
|
172
|
+
});
|
|
173
|
+
if (res && res.success === false) {
|
|
174
|
+
throw new Error(extractApiErrorMessage(res, 'work.result request failed'));
|
|
175
|
+
}
|
|
176
|
+
const unwrapped = unwrapWorkPayload(res);
|
|
177
|
+
assertObjectShape(unwrapped, 'work.result returned an unexpected response shape');
|
|
178
|
+
return unwrapped;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* POST /api/v1/work/tasks/plan — Work Hub plan (objective → Role Assistant).
|
|
183
|
+
* @requiresPermission {Dataplane} worker-task:create
|
|
184
|
+
*/
|
|
185
|
+
async function createWorkTaskPlan(dataplaneUrl, authConfig, body) {
|
|
186
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
187
|
+
const res = await client.post('/api/v1/work/tasks/plan', {
|
|
188
|
+
body,
|
|
189
|
+
timeoutMs: WORK_PLAN_TIMEOUT_MS
|
|
190
|
+
});
|
|
191
|
+
if (res && res.success === false) {
|
|
192
|
+
throw new Error(extractApiErrorMessage(res, 'work.tasks.plan request failed'));
|
|
193
|
+
}
|
|
194
|
+
const unwrapped = unwrapWorkPayload(res);
|
|
195
|
+
assertObjectShape(unwrapped, 'work.tasks.plan returned an unexpected response shape');
|
|
196
|
+
return unwrapped;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* POST /api/v1/work/tasks/plan/{planId}/activate-assistant
|
|
201
|
+
* @requiresPermission {Dataplane} worker-task:update
|
|
202
|
+
*/
|
|
203
|
+
async function activateWorkPlanAssistant(dataplaneUrl, authConfig, planId, body) {
|
|
204
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
205
|
+
const encodedId = encodeURIComponent(String(planId));
|
|
206
|
+
const res = await client.post(`/api/v1/work/tasks/plan/${encodedId}/activate-assistant`, {
|
|
207
|
+
body,
|
|
208
|
+
timeoutMs: WORK_TASK_TIMEOUT_MS
|
|
209
|
+
});
|
|
210
|
+
if (res && res.success === false) {
|
|
211
|
+
throw new Error(extractApiErrorMessage(res, 'work.tasks.plan.activate-assistant failed'));
|
|
212
|
+
}
|
|
213
|
+
const unwrapped = unwrapWorkPayload(res);
|
|
214
|
+
assertObjectShape(unwrapped, 'activate-assistant returned an unexpected response shape');
|
|
215
|
+
return unwrapped;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* POST /api/v1/work/tasks/plan/{planId}/accept
|
|
220
|
+
* @requiresPermission {Dataplane} worker-task:update
|
|
221
|
+
*/
|
|
222
|
+
async function acceptWorkTaskPlan(dataplaneUrl, authConfig, planId, body = {}) {
|
|
223
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
224
|
+
const encodedId = encodeURIComponent(String(planId));
|
|
225
|
+
const res = await client.post(`/api/v1/work/tasks/plan/${encodedId}/accept`, {
|
|
226
|
+
body: { planId, ...body },
|
|
227
|
+
timeoutMs: WORK_PLAN_TIMEOUT_MS
|
|
228
|
+
});
|
|
229
|
+
if (res && res.success === false) {
|
|
230
|
+
throw new Error(extractApiErrorMessage(res, 'work.tasks.plan.accept failed'));
|
|
231
|
+
}
|
|
232
|
+
const unwrapped = unwrapWorkPayload(res);
|
|
233
|
+
assertObjectShape(unwrapped, 'work.tasks.plan.accept returned an unexpected response shape');
|
|
234
|
+
return unwrapped;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* GET /api/v1/work/tasks/{taskId}
|
|
239
|
+
* @requiresPermission {Dataplane} worker-task:read
|
|
240
|
+
*/
|
|
241
|
+
async function getWorkTask(dataplaneUrl, authConfig, taskId) {
|
|
242
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
243
|
+
const encodedId = encodeURIComponent(String(taskId));
|
|
244
|
+
const res = await client.get(`/api/v1/work/tasks/${encodedId}`, {
|
|
245
|
+
timeoutMs: WORK_TASK_TIMEOUT_MS
|
|
246
|
+
});
|
|
247
|
+
if (res && res.success === false) {
|
|
248
|
+
throw new Error(extractApiErrorMessage(res, 'work.tasks.get failed'));
|
|
249
|
+
}
|
|
250
|
+
const unwrapped = unwrapWorkPayload(res);
|
|
251
|
+
assertObjectShape(unwrapped, 'work.tasks.get returned an unexpected response shape');
|
|
252
|
+
return unwrapped;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* POST /api/v1/work/tasks/{taskId}/approve
|
|
257
|
+
* @requiresPermission {Dataplane} worker-task:update
|
|
258
|
+
*/
|
|
259
|
+
async function approveWorkTask(dataplaneUrl, authConfig, taskId, body = {}) {
|
|
260
|
+
const client = createDataplaneApiClient(dataplaneUrl, authConfig);
|
|
261
|
+
const encodedId = encodeURIComponent(String(taskId));
|
|
262
|
+
const res = await client.post(`/api/v1/work/tasks/${encodedId}/approve`, {
|
|
263
|
+
body: { taskId, ...body },
|
|
264
|
+
timeoutMs: WORK_TASK_TIMEOUT_MS
|
|
265
|
+
});
|
|
266
|
+
if (res && res.success === false) {
|
|
267
|
+
throw new Error(extractApiErrorMessage(res, 'work.tasks.approve failed'));
|
|
268
|
+
}
|
|
269
|
+
return unwrapWorkPayload(res);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
module.exports = {
|
|
273
|
+
startWorkIntent,
|
|
274
|
+
getWorkExecutionStatus,
|
|
275
|
+
respondWorkExecution,
|
|
276
|
+
continueWorkExecution,
|
|
277
|
+
getWorkExecutionResult,
|
|
278
|
+
createWorkTaskPlan,
|
|
279
|
+
activateWorkPlanAssistant,
|
|
280
|
+
acceptWorkTaskPlan,
|
|
281
|
+
getWorkTask,
|
|
282
|
+
approveWorkTask
|
|
283
|
+
};
|