@aifabrix/builder 2.52.0 → 2.53.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/lib/api/datasources-extended.api.js +8 -8
- package/lib/api/keycloak.api.js +92 -0
- package/lib/api/token-providers.api.js +77 -0
- package/lib/api/types/keycloak.types.js +23 -0
- package/lib/api/types/token-providers.types.js +65 -0
- package/lib/app/deploy-config.js +3 -2
- package/lib/app/down.js +16 -1
- package/lib/channels/add-channel.js +134 -57
- package/lib/channels/approval-guides/chatgpt.js +1 -1
- package/lib/channels/approval-guides/index.js +3 -0
- package/lib/channels/approval-guides/microsoft-copilot.js +27 -14
- package/lib/channels/channel-add-ensure.js +128 -0
- package/lib/channels/channel-add-existing.js +72 -0
- package/lib/channels/channel-artifact-generator.js +11 -1
- package/lib/channels/channel-branding.js +94 -0
- package/lib/channels/channel-credential.js +8 -0
- package/lib/channels/channel-discovery.js +330 -0
- package/lib/channels/channel-external-system.js +1 -1
- package/lib/channels/channel-runtime-resolver.js +107 -14
- package/lib/channels/channel-status-display.js +36 -3
- package/lib/channels/microsoft-copilot-channel-add.js +138 -0
- package/lib/channels/microsoft-copilot-entra-sso-form.js +251 -0
- package/lib/channels/microsoft-copilot-entra-sso.js +285 -0
- package/lib/channels/microsoft-copilot-icons.js +74 -0
- package/lib/channels/microsoft-copilot-limits.js +103 -0
- package/lib/channels/microsoft-copilot-package.js +178 -52
- package/lib/channels/microsoft-copilot-validate.js +227 -0
- package/lib/cli/attach-default-help-examples.js +102 -0
- package/lib/cli/index.js +4 -0
- package/lib/cli/infra-guided.js +13 -6
- package/lib/cli/setup-credential-deployment.js +7 -5
- package/lib/cli/setup-infra.js +31 -4
- package/lib/cli/setup-utility-validate.js +1 -0
- package/lib/commands/channel-add-setup.js +28 -9
- package/lib/commands/channel.js +14 -10
- package/lib/commands/credential-push.js +37 -5
- package/lib/commands/integration-definition.js +158 -0
- package/lib/commands/package-score.js +72 -0
- package/lib/commands/repair-auth-apply.js +19 -5
- package/lib/commands/repair-datasource-sync-operations.js +4 -1
- package/lib/commands/role-assistant-test-output.js +200 -0
- package/lib/commands/role-assistant.js +163 -166
- package/lib/datasource/capability/capability-resolve.js +15 -5
- package/lib/datasource/capability/copy-operations.js +14 -4
- package/lib/deployment/deployer-poll-run.js +2 -2
- package/lib/deployment/deployer.js +1 -1
- package/lib/deployment/environment.js +2 -2
- package/lib/external-system/deploy.js +11 -21
- package/lib/infrastructure/index.js +19 -4
- package/lib/integration-definition/apply.js +476 -0
- package/lib/integration-definition/canonical-json.js +51 -0
- package/lib/integration-definition/emit-suite-bid.js +94 -0
- package/lib/integration-definition/enrich-crm-field-mappings.js +240 -0
- package/lib/integration-definition/enrich-openapi-operations.js +433 -0
- package/lib/integration-definition/from-discovery.js +339 -0
- package/lib/integration-definition/hash.js +37 -0
- package/lib/integration-definition/index.js +37 -0
- package/lib/integration-definition/resource-type-catalog.js +59 -0
- package/lib/integration-definition/system-kind-enum.js +40 -0
- package/lib/integration-definition/validate.js +148 -0
- package/lib/lab/package-parity-score.js +417 -0
- package/lib/programmatic/builder-api-request.js +5 -1
- package/lib/programmatic/builder-help-governance.js +3 -2
- package/lib/programmatic/capability-registry.js +20 -0
- package/lib/programmatic/help-content/channel-onboarding.md +35 -0
- package/lib/programmatic/help-content/cip-overview.md +27 -0
- package/lib/programmatic/help-content/connected-system-ui.md +70 -0
- package/lib/programmatic/help-content/dimensions-guide.md +23 -0
- package/lib/programmatic/help-content/enterprise-sync-fabrix.md +123 -0
- package/lib/programmatic/help-content/overview.md +25 -0
- package/lib/programmatic/help-content/subscription-guide.md +27 -0
- package/lib/programmatic/help-content/workflow.md +50 -0
- package/lib/programmatic/openapi-component-schemas.js +7 -1
- package/lib/programmatic/openapi-descriptions.js +46 -0
- package/lib/programmatic/openapi-envelope-examples.js +280 -0
- package/lib/programmatic/openapi-operation-bindings.js +50 -0
- package/lib/programmatic/openapi-request-schemas.js +40 -0
- package/lib/programmatic/openapi-result-schemas-overflow.js +101 -0
- package/lib/programmatic/openapi-result-schemas.js +76 -99
- package/lib/programmatic/openapi-schema-descriptions-core.js +25 -4
- package/lib/programmatic/openapi-schema-descriptions-help.js +1 -1
- package/lib/programmatic/openapi-schema-descriptions-operations.js +43 -0
- package/lib/programmatic/openapi-schema-helpers.js +9 -9
- package/lib/programmatic/openapi-spec.js +11 -1
- package/lib/programmatic/orchestration-openapi-meta.js +10 -0
- package/lib/programmatic/persist-supplied-openapi.js +180 -0
- package/lib/programmatic/route-handler-map.js +35 -1
- package/lib/programmatic/run-channel-package.js +236 -0
- package/lib/programmatic/run-integration-definition.js +77 -0
- package/lib/role-assistant/evidence-sync.js +55 -7
- package/lib/role-assistant/knowledge-sync-logging.js +58 -0
- package/lib/role-assistant/knowledge-sync.js +88 -93
- package/lib/role-assistant/test-cases-bid.js +155 -0
- package/lib/role-assistant/test-cases-evaluate.js +9 -1
- package/lib/role-assistant/test-cases-honesty.js +24 -10
- package/lib/role-assistant/test-cases.js +28 -0
- package/lib/role-assistant/test-runner-attachments.js +118 -0
- package/lib/role-assistant/test-runner-bid-apply.js +201 -0
- package/lib/role-assistant/test-runner-bid-document.js +278 -0
- package/lib/role-assistant/test-runner-start-payload.js +96 -0
- package/lib/role-assistant/test-runner-workhub-answers.js +249 -20
- package/lib/role-assistant/test-runner-workhub-helpers.js +100 -0
- package/lib/role-assistant/test-runner-workhub-soft.js +86 -0
- package/lib/role-assistant/test-runner-workhub.js +152 -107
- package/lib/role-assistant/test-runner.js +5 -63
- package/lib/role-assistant/test-suite.js +112 -0
- package/lib/schema/application-schema.json +56 -6
- package/lib/schema/external-datasource.schema.json +103 -17
- package/lib/schema/external-system.schema.json +54 -3
- package/lib/schema/integration-definition.schema.json +195 -0
- package/lib/utils/authentication-shape.js +6 -0
- package/lib/utils/compose-generator.js +10 -1
- package/lib/utils/compose-traefik-extra-routes.js +107 -0
- package/lib/utils/docker-build.js +2 -2
- package/lib/utils/help-builder.js +3 -1
- package/lib/utils/promote-dev-docker-image.js +102 -18
- package/lib/utils/transient-developer-id.js +28 -0
- package/package.json +14 -16
- package/templates/README.md +12 -1
- package/templates/applications/dataplane/application.yaml +10 -2
- package/templates/applications/dataplane/env.template +7 -6
- package/templates/applications/miso-controller/application.yaml +23 -8
- package/templates/applications/miso-controller/env.template +8 -2
- package/templates/applications/miso-controller/rbac.yaml +1 -0
- package/templates/channels/README.md +11 -1
- package/templates/channels/brand/color-192.png +0 -0
- package/templates/channels/brand/dark/128.png +0 -0
- package/templates/channels/brand/dark/192.png +0 -0
- package/templates/channels/brand/dark/256.png +0 -0
- package/templates/channels/brand/dark/32.png +0 -0
- package/templates/channels/brand/dark/512.png +0 -0
- package/templates/channels/brand/dark/64.png +0 -0
- package/templates/channels/brand/light/128.png +0 -0
- package/templates/channels/brand/light/192.png +0 -0
- package/templates/channels/brand/light/256.png +0 -0
- package/templates/channels/brand/light/32.png +0 -0
- package/templates/channels/brand/light/512.png +0 -0
- package/templates/channels/brand/light/64.png +0 -0
- package/templates/channels/brand/mono-white/128.png +0 -0
- package/templates/channels/brand/mono-white/192.png +0 -0
- package/templates/channels/brand/mono-white/256.png +0 -0
- package/templates/channels/brand/mono-white/32.png +0 -0
- package/templates/channels/brand/mono-white/512.png +0 -0
- package/templates/channels/brand/mono-white/64.png +0 -0
- package/templates/channels/brand/outline-32.png +0 -0
- package/templates/channels/chatgpt/install.template.md.hbs +6 -4
- package/templates/channels/chatgpt/integration/README.md +4 -5
- package/templates/channels/chatgpt/integration/chatgpt-system.json +1 -16
- package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +14 -16
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +5 -3
- package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +30 -0
- package/templates/channels/microsoft-copilot/fi-fi.template.json.hbs +7 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +93 -22
- package/templates/channels/microsoft-copilot/integration/README.md +2 -3
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +1 -22
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +34 -19
- package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +15 -0
- package/templates/channels/slack/integration/README.md +2 -4
- package/templates/channels/teams-bot/install.template.md.hbs +4 -0
- package/templates/channels/teams-bot/integration/README.md +3 -5
- package/templates/channels/web-embed/integration/web-embed-system.json +1 -16
- package/templates/python/docker-compose.hbs +36 -0
- package/templates/typescript/docker-compose.hbs +36 -0
- package/.cursor/plans/Done/157.1-security-quality-violations-by-type.csv +0 -374
- package/.cursor/process/README.md +0 -9
- package/.cursor/rules/anchor-docs.mdc +0 -15
- package/.cursor/rules/assistant-driven-integration-build.mdc +0 -40
- package/.cursor/rules/cli-layout.mdc +0 -81
- package/.cursor/rules/cli-product-neutral.mdc +0 -43
- package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +0 -49
- package/.cursor/rules/docs-rules.mdc +0 -32
- package/.cursor/rules/plan-rules/application-lifecycle.mdc +0 -30
- package/.cursor/rules/plan-rules/plan-frontmatter.mdc +0 -35
- package/.cursor/rules/plan-rules/plan-lifecycle.mdc +0 -31
- package/.cursor/rules/plan-rules/plan-validation-gate.mdc +0 -34
- package/.cursor/rules/project-rules.mdc +0 -913
- package/.cursor/skills/README.md +0 -15
- package/.dockerignore +0 -52
- package/.eslintignore +0 -22
- package/.markdownlint.json +0 -14
- package/anchor-docs/README.md +0 -10
- package/anchor-docs/_TEMPLATE +0 -24
- package/babel.config.js +0 -6
- package/bin/builder-api-cleanup.js +0 -26
- package/bin/builder-api-nest.js +0 -10
- package/bin/builder-api-spike.js +0 -19
- package/enterprise-knowledge/README.md +0 -50
- package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +0 -22
- package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +0 -15
- package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +0 -69
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +0 -52
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +0 -29
- package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +0 -2
- package/integration/README.md +0 -81
- package/integration/github/README.md +0 -53
- package/integration/github/application.json +0 -21
- package/integration/github/deploy.js +0 -72
- package/integration/github/env.template +0 -11
- package/integration/github/github-datasource-issue-comments.json +0 -239
- package/integration/github/github-datasource-issues.json +0 -399
- package/integration/github/github-datasource-repository.json +0 -354
- package/integration/github/github-deploy.json +0 -1202
- package/integration/github/github-system.json +0 -82
- package/integration/hubspot-test/README.md +0 -159
- package/integration/hubspot-test/application.json +0 -54
- package/integration/hubspot-test/companies.json +0 -2048
- package/integration/hubspot-test/create-hubspot.js +0 -523
- package/integration/hubspot-test/env.template +0 -4
- package/integration/hubspot-test/hubspot-test-datasource-company.json +0 -138
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +0 -146
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +0 -146
- package/integration/hubspot-test/hubspot-test-datasource-users.json +0 -76
- package/integration/hubspot-test/hubspot-test-deploy.json +0 -2160
- package/integration/hubspot-test/hubspot-test-system.json +0 -74
- package/integration/hubspot-test/rbac.json +0 -166
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +0 -20
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +0 -9
- package/integration/hubspot-test/test-artifacts/wizard-invalid-add-datasource.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-app-name.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-create.yaml +0 -7
- package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-select.yaml +0 -7
- package/integration/hubspot-test/test-artifacts/wizard-invalid-known-platform.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-app.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
- package/integration/hubspot-test/test-artifacts/wizard-invalid-mode.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-file.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-url.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-source.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-array-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +0 -5
- package/integration/hubspot-test/test-dataplane-down-helpers.js +0 -249
- package/integration/hubspot-test/test-dataplane-down-tests.js +0 -386
- package/integration/hubspot-test/test-dataplane-down.js +0 -209
- package/integration/hubspot-test/test.js +0 -1588
- package/integration/hubspot-test/wizard-hubspot-e2e.yaml +0 -16
- package/integration/hubspot-test/wizard-hubspot-platform.yaml +0 -8
- package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +0 -23
- package/integration/roundtrip-test-local/README.md +0 -143
- package/integration/roundtrip-test-local/application.yaml +0 -13
- package/integration/roundtrip-test-local/env.template +0 -15
- package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +0 -14
- package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +0 -61
- package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +0 -25
- package/integration/roundtrip-test-local2/README.md +0 -143
- package/integration/roundtrip-test-local2/application.yaml +0 -13
- package/integration/roundtrip-test-local2/env.template +0 -15
- package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +0 -31
- package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +0 -86
- package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +0 -25
- package/integration/test/wizard.yaml +0 -8
- package/jest.config.coverage.js +0 -37
- package/jest.config.default.js +0 -11
- package/jest.config.integration.fixtures.js +0 -22
- package/jest.config.integration.js +0 -33
- package/jest.config.isolated.js +0 -11
- package/jest.config.manual.js +0 -30
- package/jest.global-live-fabrix-hooks.js +0 -36
- package/jest.isolated-projects.js +0 -260
- package/jest.projects.js +0 -76
- package/packages/builder-api/README.md +0 -120
- package/packages/builder-api/package.json +0 -30
- package/packages/builder-api/src/app.module.ts +0 -7
- package/packages/builder-api/src/auth/auth.module.ts +0 -5
- package/packages/builder-api/src/external-system/external-system.module.ts +0 -5
- package/packages/builder-api/src/main.ts +0 -16
- package/packages/builder-api/tsconfig.json +0 -15
- package/scripts/check-builder-api-architecture-grep.js +0 -79
- package/scripts/check-datasource-test-run-schema-sync.js +0 -34
- package/scripts/ci-fix.sh +0 -19
- package/scripts/ci-simulate.sh +0 -19
- package/scripts/diagnose-cli.js +0 -150
- package/scripts/docker_image_content_gate.js +0 -47
- package/scripts/docker_image_content_gate.sh +0 -5
- package/scripts/export-builder-api-evidence.js +0 -262
- package/scripts/install-local.js +0 -490
- package/scripts/lib/builder-api-docker-staging-copy.js +0 -60
- package/scripts/lib/builder-api-docker-staging-core.js +0 -183
- package/scripts/lib/docker-image-content-gate-core.js +0 -166
- package/scripts/lib/plan-actor.js +0 -109
- package/scripts/lib/plan-config.js +0 -20
- package/scripts/lib/plan-gates.js +0 -154
- package/scripts/lib/plan-meta.js +0 -104
- package/scripts/lib/plan-parse.js +0 -162
- package/scripts/lib/plan-prevalidate-gates.js +0 -337
- package/scripts/lib/plan-run-core.js +0 -125
- package/scripts/lib/plan-run-report.js +0 -119
- package/scripts/plan-approve.js +0 -24
- package/scripts/plan-archive.js +0 -49
- package/scripts/plan-run.js +0 -13
- package/scripts/plan-set-actor.js +0 -21
- package/scripts/plan-validate.js +0 -80
- package/scripts/pnpm/af.mjs +0 -110
- package/scripts/pnpm/check-quiet.mjs +0 -32
- package/scripts/pnpm/dev-install.mjs +0 -29
- package/scripts/pnpm/dev-reload.mjs +0 -18
- package/scripts/pnpm/help.mjs +0 -55
- package/scripts/pnpm/lib/dev-reload-core.mjs +0 -189
- package/scripts/pnpm/lib/dev-reload-log-capture.mjs +0 -67
- package/scripts/pnpm/lib/dev-reload-log-utils.mjs +0 -32
- package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +0 -124
- package/scripts/pnpm/lib/resolve-app-url.mjs +0 -183
- package/scripts/pnpm/lib/spinner.mjs +0 -42
- package/scripts/pnpm-global-remove.js +0 -48
- package/scripts/stage_builder_api_for_docker.js +0 -65
- package/scripts/sync-builder-api-template.js +0 -44
- package/scripts/test-dataplane-bootstrap.js +0 -331
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Work Hub test-runner helpers (ids, delays, path detection).
|
|
3
|
+
* @fileoverview Pure helpers for role-assistant Work Hub harness
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const TERMINAL_TASK = new Set(['completed', 'failed', 'cancelled', 'canceled']);
|
|
9
|
+
const PLAN_LOST_RE =
|
|
10
|
+
/work plan not found|plan not found|404|ephemeral|reload|timed out|timeout|network error|econnreset|socket|fetch failed/i;
|
|
11
|
+
const APPROVAL_NOT_PENDING_RE = /approval state is not pending|not pending/i;
|
|
12
|
+
|
|
13
|
+
function delayMs(ms) {
|
|
14
|
+
const wait = Number(ms);
|
|
15
|
+
if (!Number.isFinite(wait) || wait <= 0) {
|
|
16
|
+
return Promise.resolve();
|
|
17
|
+
}
|
|
18
|
+
return new Promise((resolve) => setTimeout(resolve, wait));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function resolveInput(testCase) {
|
|
22
|
+
const input = testCase && typeof testCase.input === 'object' && testCase.input ? testCase.input : {};
|
|
23
|
+
return Array.isArray(input) ? {} : input;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function resolveObjective(testCase) {
|
|
27
|
+
const input = resolveInput(testCase);
|
|
28
|
+
const candidates = [input.message, input.text, input.prompt, input.objective];
|
|
29
|
+
for (const row of candidates) {
|
|
30
|
+
if (typeof row === 'string' && row.trim()) {
|
|
31
|
+
return row.trim();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return '';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function wantsWorkHubPath(testCase) {
|
|
38
|
+
const input = resolveInput(testCase);
|
|
39
|
+
const pathToken = String(input.executionPath || input.mode || '').trim().toLowerCase();
|
|
40
|
+
if (pathToken === 'workhub' || pathToken === 'work-hub' || pathToken === 'plan') {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
if (pathToken === 'work.start' || pathToken === 'start' || pathToken === 'intent') {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return Boolean(resolveObjective(testCase));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function unwrapId(value) {
|
|
50
|
+
if (typeof value === 'string' && value.trim()) {
|
|
51
|
+
return value.trim();
|
|
52
|
+
}
|
|
53
|
+
if (value && typeof value === 'object') {
|
|
54
|
+
const nested = value.id || value.value || value.ref;
|
|
55
|
+
if (typeof nested === 'string' && nested.trim()) {
|
|
56
|
+
return nested.trim();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function extractPeFromTask(task) {
|
|
63
|
+
const candidates = [task?.processExecutionId, task?.processExecutionRef];
|
|
64
|
+
for (const row of candidates) {
|
|
65
|
+
const id = unwrapId(row);
|
|
66
|
+
if (id) {
|
|
67
|
+
return id;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return '';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function planAlreadyActivated(plan) {
|
|
74
|
+
const assistant = plan?.recommendedAssistant;
|
|
75
|
+
if (!assistant || typeof assistant !== 'object' || assistant.isActivated !== true) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return Boolean(unwrapId(assistant.activationId));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function isPlanLostError(error) {
|
|
82
|
+
return PLAN_LOST_RE.test(String((error && error.message) || error || ''));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function isApprovalNotPendingError(error) {
|
|
86
|
+
return APPROVAL_NOT_PENDING_RE.test(String((error && error.message) || error || ''));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = {
|
|
90
|
+
TERMINAL_TASK,
|
|
91
|
+
delayMs,
|
|
92
|
+
resolveInput,
|
|
93
|
+
resolveObjective,
|
|
94
|
+
wantsWorkHubPath,
|
|
95
|
+
unwrapId,
|
|
96
|
+
extractPeFromTask,
|
|
97
|
+
planAlreadyActivated,
|
|
98
|
+
isPlanLostError,
|
|
99
|
+
isApprovalNotPendingError
|
|
100
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Soft Work Hub outcomes for insufficient-info / clarify-first Intent.
|
|
3
|
+
* Soft cases may stop before accept when Intent is not Act-ready — that is a
|
|
4
|
+
* governed fail-closed outcome, not a harness failure.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
function isIntentNotActReadyError(error) {
|
|
10
|
+
const msg = String((error && error.message) || error || '');
|
|
11
|
+
return /not Act-ready|intentNotActReady/i.test(msg);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function attachPlanIdToError(error, planId) {
|
|
15
|
+
if (error && typeof error === 'object' && planId) {
|
|
16
|
+
error.planId = planId;
|
|
17
|
+
}
|
|
18
|
+
return error;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function buildSoftClarifyLifecycleResult(roleKey, testCase, planId, error) {
|
|
22
|
+
const message = String((error && error.message) || error || 'intentNotActReady');
|
|
23
|
+
return {
|
|
24
|
+
roleKey,
|
|
25
|
+
caseId: testCase.caseId,
|
|
26
|
+
processExecutionId: null,
|
|
27
|
+
startResponse: {
|
|
28
|
+
planId: planId || null,
|
|
29
|
+
path: 'workHub',
|
|
30
|
+
softClarifyStop: true
|
|
31
|
+
},
|
|
32
|
+
finalStatus: {
|
|
33
|
+
status: 'stopped',
|
|
34
|
+
wait: null,
|
|
35
|
+
reason: 'intentNotActReady'
|
|
36
|
+
},
|
|
37
|
+
timeline: [],
|
|
38
|
+
interactions: [{ type: 'softClarifyStop', message }],
|
|
39
|
+
workResult: null,
|
|
40
|
+
workResultError: null
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param {Function} createActivateAcceptPlan
|
|
46
|
+
* @param {Object} startArgs
|
|
47
|
+
* @param {string} startArgs.dataplaneUrl
|
|
48
|
+
* @param {Object} startArgs.authConfig
|
|
49
|
+
* @param {Object} startArgs.planBody
|
|
50
|
+
* @param {string} startArgs.assistantName
|
|
51
|
+
* @param {Object} [startArgs.options]
|
|
52
|
+
* @param {Object} softCtx
|
|
53
|
+
* @param {string} softCtx.roleKey
|
|
54
|
+
* @param {Object} softCtx.testCase
|
|
55
|
+
*/
|
|
56
|
+
async function startWorkHubOrSoftClarify(createActivateAcceptPlan, startArgs, softCtx) {
|
|
57
|
+
const { dataplaneUrl, authConfig, planBody, assistantName, options } = startArgs;
|
|
58
|
+
const { roleKey, testCase } = softCtx;
|
|
59
|
+
try {
|
|
60
|
+
return {
|
|
61
|
+
soft: false,
|
|
62
|
+
started: await createActivateAcceptPlan(
|
|
63
|
+
dataplaneUrl,
|
|
64
|
+
authConfig,
|
|
65
|
+
planBody,
|
|
66
|
+
assistantName,
|
|
67
|
+
options
|
|
68
|
+
)
|
|
69
|
+
};
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (testCase?.expected?.soft === true && isIntentNotActReadyError(error)) {
|
|
72
|
+
return {
|
|
73
|
+
soft: true,
|
|
74
|
+
result: buildSoftClarifyLifecycleResult(roleKey, testCase, error.planId, error)
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = {
|
|
82
|
+
isIntentNotActReadyError,
|
|
83
|
+
attachPlanIdToError,
|
|
84
|
+
buildSoftClarifyLifecycleResult,
|
|
85
|
+
startWorkHubOrSoftClarify
|
|
86
|
+
};
|
|
@@ -23,87 +23,25 @@ const {
|
|
|
23
23
|
alreadyResponded,
|
|
24
24
|
buildRespondPayload
|
|
25
25
|
} = require('./test-runner-workhub-answers');
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
function resolveObjective(testCase) {
|
|
46
|
-
const input = resolveInput(testCase);
|
|
47
|
-
const candidates = [input.message, input.text, input.prompt, input.objective];
|
|
48
|
-
for (const row of candidates) {
|
|
49
|
-
if (typeof row === 'string' && row.trim()) {
|
|
50
|
-
return row.trim();
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return '';
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function wantsWorkHubPath(testCase) {
|
|
57
|
-
const input = resolveInput(testCase);
|
|
58
|
-
const pathToken = String(input.executionPath || input.mode || '').trim().toLowerCase();
|
|
59
|
-
if (pathToken === 'workhub' || pathToken === 'work-hub' || pathToken === 'plan') {
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
if (pathToken === 'work.start' || pathToken === 'start' || pathToken === 'intent') {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
return Boolean(resolveObjective(testCase));
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function unwrapId(value) {
|
|
69
|
-
if (typeof value === 'string' && value.trim()) {
|
|
70
|
-
return value.trim();
|
|
71
|
-
}
|
|
72
|
-
if (value && typeof value === 'object') {
|
|
73
|
-
const nested = value.id || value.value || value.ref;
|
|
74
|
-
if (typeof nested === 'string' && nested.trim()) {
|
|
75
|
-
return nested.trim();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return '';
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function extractPeFromTask(task) {
|
|
82
|
-
const candidates = [task?.processExecutionId, task?.processExecutionRef];
|
|
83
|
-
for (const row of candidates) {
|
|
84
|
-
const id = unwrapId(row);
|
|
85
|
-
if (id) {
|
|
86
|
-
return id;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return '';
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function planAlreadyActivated(plan) {
|
|
93
|
-
const assistant = plan?.recommendedAssistant;
|
|
94
|
-
if (!assistant || typeof assistant !== 'object' || assistant.isActivated !== true) {
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
return Boolean(unwrapId(assistant.activationId));
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function isPlanLostError(error) {
|
|
101
|
-
return PLAN_LOST_RE.test(String((error && error.message) || error || ''));
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function isApprovalNotPendingError(error) {
|
|
105
|
-
return APPROVAL_NOT_PENDING_RE.test(String((error && error.message) || error || ''));
|
|
106
|
-
}
|
|
26
|
+
const {
|
|
27
|
+
shouldApplyBidAfterWait,
|
|
28
|
+
shouldSoftHttpBidApply,
|
|
29
|
+
applyCaseBidViaBuilderApi,
|
|
30
|
+
persistCaseOpenApiViaBuilderApi
|
|
31
|
+
} = require('./test-runner-bid-apply');
|
|
32
|
+
const { resolveTargetSystemKey } = require('./test-runner-bid-document');
|
|
33
|
+
const {
|
|
34
|
+
TERMINAL_TASK,
|
|
35
|
+
delayMs,
|
|
36
|
+
resolveInput,
|
|
37
|
+
resolveObjective,
|
|
38
|
+
wantsWorkHubPath,
|
|
39
|
+
unwrapId,
|
|
40
|
+
extractPeFromTask,
|
|
41
|
+
planAlreadyActivated,
|
|
42
|
+
isPlanLostError,
|
|
43
|
+
isApprovalNotPendingError
|
|
44
|
+
} = require('./test-runner-workhub-helpers');
|
|
107
45
|
|
|
108
46
|
async function waitDataplaneHealthy(dataplaneUrl, attempts = 12) {
|
|
109
47
|
const base = String(dataplaneUrl || '')
|
|
@@ -149,11 +87,18 @@ async function acceptPlanForTask(dataplaneUrl, authConfig, planId) {
|
|
|
149
87
|
}
|
|
150
88
|
|
|
151
89
|
async function createActivateAcceptOnce(dataplaneUrl, authConfig, planBody, assistantName) {
|
|
90
|
+
const {
|
|
91
|
+
attachPlanIdToError
|
|
92
|
+
} = require('./test-runner-workhub-soft');
|
|
152
93
|
await waitDataplaneHealthy(dataplaneUrl);
|
|
153
94
|
const plan = await createWorkTaskPlan(dataplaneUrl, authConfig, planBody);
|
|
154
95
|
const planId = await activateIfNeeded(dataplaneUrl, authConfig, plan, assistantName);
|
|
155
|
-
|
|
156
|
-
|
|
96
|
+
try {
|
|
97
|
+
const taskId = await acceptPlanForTask(dataplaneUrl, authConfig, planId);
|
|
98
|
+
return { planId, taskId };
|
|
99
|
+
} catch (error) {
|
|
100
|
+
throw attachPlanIdToError(error, planId);
|
|
101
|
+
}
|
|
157
102
|
}
|
|
158
103
|
|
|
159
104
|
async function createActivateAcceptPlan(dataplaneUrl, authConfig, planBody, assistantName, options) {
|
|
@@ -189,7 +134,16 @@ function _approveGateDecision(ctx) {
|
|
|
189
134
|
return 'skip';
|
|
190
135
|
}
|
|
191
136
|
const approvalState = String(ctx.taskRow?.approvalState || '').trim().toLowerCase();
|
|
192
|
-
|
|
137
|
+
// Treat empty / pending* as still actionable. Stop only after a terminal decision.
|
|
138
|
+
const terminalDecision = new Set([
|
|
139
|
+
'approved',
|
|
140
|
+
'rejected',
|
|
141
|
+
'cancelled',
|
|
142
|
+
'canceled',
|
|
143
|
+
'notrequired',
|
|
144
|
+
'not_required'
|
|
145
|
+
]);
|
|
146
|
+
if (approvalState && terminalDecision.has(approvalState)) {
|
|
193
147
|
return 'stop';
|
|
194
148
|
}
|
|
195
149
|
if ((Number(ctx.approveAttempts) || 0) >= 8) {
|
|
@@ -225,46 +179,133 @@ async function maybeApproveTask(dataplaneUrl, authConfig, taskId, ctx) {
|
|
|
225
179
|
await _attemptApproveTask(dataplaneUrl, authConfig, taskId, ctx);
|
|
226
180
|
}
|
|
227
181
|
|
|
182
|
+
function recordSkippedResponse(interactions, peId, fingerprint, wait) {
|
|
183
|
+
interactions.push({
|
|
184
|
+
type: 'respond-skipped',
|
|
185
|
+
processExecutionId: peId,
|
|
186
|
+
fingerprint,
|
|
187
|
+
questionKey: wait.questionKey || wait.requestKey || null,
|
|
188
|
+
objectRefKind: wait.objectRef?.kind || null,
|
|
189
|
+
reason: 'no-matching-answer-or-synthesis'
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function recordBidEmit(testCase, interactions, peId) {
|
|
194
|
+
const { loadCaseBidDocument } = require('./test-runner-workhub-answers');
|
|
195
|
+
const emittedBid = loadCaseBidDocument(testCase);
|
|
196
|
+
if (!(emittedBid && emittedBid.meta && emittedBid.meta.suiteRunId)) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
interactions.push({
|
|
200
|
+
type: 'bid-emit',
|
|
201
|
+
processExecutionId: peId,
|
|
202
|
+
suiteRunId: emittedBid.meta.suiteRunId,
|
|
203
|
+
definitionId: emittedBid.definitionId,
|
|
204
|
+
definitionHash: emittedBid.definitionHash
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async function softHttpBidApplyAfterWait(authConfig, testCase, interactions, peId) {
|
|
209
|
+
try {
|
|
210
|
+
const applied = await applyCaseBidViaBuilderApi(authConfig, testCase);
|
|
211
|
+
interactions.push({
|
|
212
|
+
type: 'bid-apply',
|
|
213
|
+
processExecutionId: peId,
|
|
214
|
+
systemKey: applied && applied.systemKey,
|
|
215
|
+
definitionHash: applied && applied.definitionHash,
|
|
216
|
+
suiteRunId: applied && applied.suiteRunId,
|
|
217
|
+
status: applied && applied.status,
|
|
218
|
+
softHttp: true
|
|
219
|
+
});
|
|
220
|
+
} catch (applyErr) {
|
|
221
|
+
interactions.push({
|
|
222
|
+
type: 'bid-apply-error',
|
|
223
|
+
processExecutionId: peId,
|
|
224
|
+
error: applyErr.message || String(applyErr),
|
|
225
|
+
softHttp: true
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async function respondToWaitingExecution(
|
|
231
|
+
dataplaneUrl,
|
|
232
|
+
authConfig,
|
|
233
|
+
peId,
|
|
234
|
+
testCase,
|
|
235
|
+
interactions,
|
|
236
|
+
statusRow
|
|
237
|
+
) {
|
|
238
|
+
const wait = statusRow.wait && typeof statusRow.wait === 'object' ? statusRow.wait : {};
|
|
239
|
+
const fingerprint = waitRespondFingerprint(wait);
|
|
240
|
+
if (alreadyResponded(interactions, fingerprint)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const payload = buildRespondPayload(
|
|
244
|
+
peId,
|
|
245
|
+
wait,
|
|
246
|
+
testCase,
|
|
247
|
+
statusRow,
|
|
248
|
+
interactions,
|
|
249
|
+
resolveObjective(testCase)
|
|
250
|
+
);
|
|
251
|
+
if (!payload) {
|
|
252
|
+
recordSkippedResponse(interactions, peId, fingerprint, wait);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
// Stage suite OpenAPI into workspace before CIP apply (517.2 layout).
|
|
256
|
+
// Product path: DE admits persistsuppliedopenapi; this is lab debt until then.
|
|
257
|
+
if (shouldApplyBidAfterWait(testCase, wait)) {
|
|
258
|
+
const systemKey = resolveTargetSystemKey(testCase);
|
|
259
|
+
if (systemKey) {
|
|
260
|
+
await persistCaseOpenApiViaBuilderApi(authConfig, testCase, systemKey);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
await respondWorkExecution(dataplaneUrl, authConfig, peId, payload);
|
|
264
|
+
await continueWorkExecution(dataplaneUrl, authConfig, peId, {});
|
|
265
|
+
interactions.push({ type: 'respond', processExecutionId: peId, fingerprint });
|
|
266
|
+
if (shouldApplyBidAfterWait(testCase, wait)) {
|
|
267
|
+
recordBidEmit(testCase, interactions, peId);
|
|
268
|
+
}
|
|
269
|
+
// Soft HTTP apply is lab debt only. Hard cases (expected.soft !== true) rely on
|
|
270
|
+
// DE → capability.execute(template.applyintegrationdefinition) after continue.
|
|
271
|
+
if (shouldSoftHttpBidApply(testCase, wait)) {
|
|
272
|
+
await softHttpBidApplyAfterWait(authConfig, testCase, interactions, peId);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
228
276
|
async function maybeRespondWaiting(dataplaneUrl, authConfig, taskRow, testCase, interactions) {
|
|
229
277
|
const peId = extractPeFromTask(taskRow);
|
|
230
278
|
if (!peId) {
|
|
231
279
|
return;
|
|
232
280
|
}
|
|
233
281
|
try {
|
|
282
|
+
testCase._activeProcessExecutionId = peId;
|
|
234
283
|
const statusRow = await getWorkExecutionStatus(dataplaneUrl, authConfig, peId);
|
|
235
284
|
if (String(statusRow?.status || '').toLowerCase() !== 'waiting') {
|
|
236
285
|
return;
|
|
237
286
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
const payload = buildRespondPayload(
|
|
287
|
+
await respondToWaitingExecution(
|
|
288
|
+
dataplaneUrl,
|
|
289
|
+
authConfig,
|
|
244
290
|
peId,
|
|
245
|
-
wait,
|
|
246
291
|
testCase,
|
|
247
|
-
statusRow,
|
|
248
292
|
interactions,
|
|
249
|
-
|
|
293
|
+
statusRow
|
|
250
294
|
);
|
|
251
|
-
if (!payload) {
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
await respondWorkExecution(dataplaneUrl, authConfig, peId, payload);
|
|
255
|
-
await continueWorkExecution(dataplaneUrl, authConfig, peId, {});
|
|
256
|
-
interactions.push({ type: 'respond', processExecutionId: peId, fingerprint });
|
|
257
295
|
} catch (_err) {
|
|
258
296
|
// Soft: continue polling task.
|
|
259
297
|
}
|
|
260
298
|
}
|
|
261
299
|
|
|
262
|
-
function assertTerminalWorkHubTask(last, taskId, timeoutMs) {
|
|
300
|
+
function assertTerminalWorkHubTask(last, taskId, timeoutMs, options = {}) {
|
|
263
301
|
if (!last) {
|
|
264
302
|
throw new Error(`Work Hub task ${taskId} produced no status rows.`);
|
|
265
303
|
}
|
|
266
304
|
const finalStatusToken = String(last?.status || last?.taskStatus || '').trim().toLowerCase();
|
|
267
305
|
if (!TERMINAL_TASK.has(finalStatusToken)) {
|
|
306
|
+
if (options.soft === true) {
|
|
307
|
+
return last;
|
|
308
|
+
}
|
|
268
309
|
throw new Error(
|
|
269
310
|
`Work Hub task ${taskId} did not reach a terminal status within ${timeoutMs}ms (last=${finalStatusToken || 'unknown'}).`
|
|
270
311
|
);
|
|
@@ -275,6 +316,7 @@ function assertTerminalWorkHubTask(last, taskId, timeoutMs) {
|
|
|
275
316
|
async function pollWorkHubTask(dataplaneUrl, authConfig, taskId, testCase, options) {
|
|
276
317
|
const timeoutMs = Number(options.pollTimeoutMs) || 180000;
|
|
277
318
|
const intervalMs = Number(options.pollIntervalMs) || 3000;
|
|
319
|
+
const soft = testCase?.expected?.soft === true;
|
|
278
320
|
const started = Date.now();
|
|
279
321
|
let last = null;
|
|
280
322
|
const timeline = [];
|
|
@@ -301,7 +343,7 @@ async function pollWorkHubTask(dataplaneUrl, authConfig, taskId, testCase, optio
|
|
|
301
343
|
}
|
|
302
344
|
|
|
303
345
|
return {
|
|
304
|
-
finalTask: assertTerminalWorkHubTask(last, taskId, timeoutMs),
|
|
346
|
+
finalTask: assertTerminalWorkHubTask(last, taskId, timeoutMs, { soft }),
|
|
305
347
|
timeline,
|
|
306
348
|
interactions: ctx.interactions
|
|
307
349
|
};
|
|
@@ -347,6 +389,7 @@ function buildWorkHubLifecycleResult(roleKey, testCase, started, pollState, peBu
|
|
|
347
389
|
}
|
|
348
390
|
|
|
349
391
|
async function runWorkHubCaseLifecycle(roleKey, testCase, runtimeContext, options = {}) {
|
|
392
|
+
const { startWorkHubOrSoftClarify } = require('./test-runner-workhub-soft');
|
|
350
393
|
const dataplaneUrl = runtimeContext?.dataplaneUrl;
|
|
351
394
|
const authConfig = runtimeContext?.authConfig;
|
|
352
395
|
const objective = resolveObjective(testCase);
|
|
@@ -363,13 +406,15 @@ async function runWorkHubCaseLifecycle(roleKey, testCase, runtimeContext, option
|
|
|
363
406
|
objective,
|
|
364
407
|
digitalWorkerKey: String(input.digitalWorkerKey || roleKey).trim()
|
|
365
408
|
};
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
authConfig,
|
|
369
|
-
|
|
370
|
-
assistantName,
|
|
371
|
-
options
|
|
409
|
+
const gate = await startWorkHubOrSoftClarify(
|
|
410
|
+
createActivateAcceptPlan,
|
|
411
|
+
{ dataplaneUrl, authConfig, planBody, assistantName, options },
|
|
412
|
+
{ roleKey, testCase }
|
|
372
413
|
);
|
|
414
|
+
if (gate.soft) {
|
|
415
|
+
return gate.result;
|
|
416
|
+
}
|
|
417
|
+
const started = gate.started;
|
|
373
418
|
const pollState = await pollWorkHubTask(
|
|
374
419
|
dataplaneUrl,
|
|
375
420
|
authConfig,
|
|
@@ -18,6 +18,11 @@ const {
|
|
|
18
18
|
getWorkExecutionResult
|
|
19
19
|
} = require('../api/work.api');
|
|
20
20
|
const { wantsWorkHubPath, runWorkHubCaseLifecycle } = require('./test-runner-workhub');
|
|
21
|
+
const {
|
|
22
|
+
buildStartIntentPayload,
|
|
23
|
+
resolveInputObject,
|
|
24
|
+
resolveInputMessage
|
|
25
|
+
} = require('./test-runner-start-payload');
|
|
21
26
|
const TERMINAL_STATUSES = new Set(['completed', 'stopped']);
|
|
22
27
|
const WAITING_STATUS = 'waiting';
|
|
23
28
|
|
|
@@ -52,22 +57,6 @@ function applyOptionalStringField(payload, value, key) {
|
|
|
52
57
|
}
|
|
53
58
|
}
|
|
54
59
|
|
|
55
|
-
function resolveInputObject(testCase) {
|
|
56
|
-
const input = testCase && typeof testCase.input === 'object' && testCase.input ? testCase.input : {};
|
|
57
|
-
return Array.isArray(input) ? {} : input;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function resolveInputMessage(testCase) {
|
|
61
|
-
const input = resolveInputObject(testCase);
|
|
62
|
-
const candidates = [input.message, input.text, input.prompt];
|
|
63
|
-
for (const row of candidates) {
|
|
64
|
-
if (typeof row === 'string' && row.trim()) {
|
|
65
|
-
return row.trim();
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return '';
|
|
69
|
-
}
|
|
70
|
-
|
|
71
60
|
function isExecutableRoleAssistantCase(testCase) {
|
|
72
61
|
const input = resolveInputObject(testCase);
|
|
73
62
|
if (typeof input.content !== 'undefined') {
|
|
@@ -79,53 +68,6 @@ function isExecutableRoleAssistantCase(testCase) {
|
|
|
79
68
|
return false;
|
|
80
69
|
}
|
|
81
70
|
|
|
82
|
-
function buildStartPayloadSourceMetadata(roleKey, testCase, input) {
|
|
83
|
-
return {
|
|
84
|
-
roleKey,
|
|
85
|
-
caseId: testCase.caseId,
|
|
86
|
-
runner: 'aifabrix-role-assistant-test',
|
|
87
|
-
...(input.sourceMetadata && typeof input.sourceMetadata === 'object' ? input.sourceMetadata : {})
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function applyStartPayloadOptionalFields(payload, input) {
|
|
92
|
-
const mappedFields = [
|
|
93
|
-
['activationId', 'activationId'],
|
|
94
|
-
['workerTaskId', 'workerTaskId'],
|
|
95
|
-
['principalRef', 'principalRef'],
|
|
96
|
-
['businessRoleRef', 'businessRoleRef']
|
|
97
|
-
];
|
|
98
|
-
for (const [inputKey, payloadKey] of mappedFields) {
|
|
99
|
-
applyOptionalStringField(payload, input[inputKey], payloadKey);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function buildStartIntentPayload(roleKey, testCase) {
|
|
104
|
-
const input = resolveInputObject(testCase);
|
|
105
|
-
const message = resolveInputMessage(testCase);
|
|
106
|
-
const hasContent = typeof input.content !== 'undefined';
|
|
107
|
-
if (!hasContent && !message) {
|
|
108
|
-
throw new Error(
|
|
109
|
-
`Role assistant test case "${testCase.caseId}" is missing input.message or input.content for runtime execution.`
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
const payload = {
|
|
113
|
-
submissionId: String(input.submissionId || buildRuntimeId(`ra-${roleKey}`)),
|
|
114
|
-
content: hasContent ? input.content : message,
|
|
115
|
-
comModelRef: String(input.comModelRef || 'aifabrix.com/intent/default'),
|
|
116
|
-
comModelVersion: String(input.comModelVersion || '1.0'),
|
|
117
|
-
comVocabulary: Array.isArray(input.comVocabulary) && input.comVocabulary.length > 0
|
|
118
|
-
? input.comVocabulary.map((row) => String(row))
|
|
119
|
-
: ['objective', 'entity', 'action'],
|
|
120
|
-
sourceType: String(input.sourceType || 'api'),
|
|
121
|
-
sourceLanguage: String(input.sourceLanguage || 'en'),
|
|
122
|
-
responseLanguage: String(input.responseLanguage || input.sourceLanguage || 'en'),
|
|
123
|
-
sourceMetadata: buildStartPayloadSourceMetadata(roleKey, testCase, input)
|
|
124
|
-
};
|
|
125
|
-
applyStartPayloadOptionalFields(payload, input);
|
|
126
|
-
return payload;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
71
|
function extractProcessExecutionId(startResponse) {
|
|
130
72
|
const candidates = [
|
|
131
73
|
startResponse?.intent?.processExecutionId,
|