@aifabrix/builder 2.54.1 → 2.55.2
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/README.md +8 -0
- package/lib/agent-kit/apply-ops.js +82 -0
- package/lib/agent-kit/checksums.js +28 -0
- package/lib/agent-kit/classify.js +113 -0
- package/lib/agent-kit/claude-shim.js +61 -0
- package/lib/agent-kit/constants.js +55 -0
- package/lib/agent-kit/file-list.js +103 -0
- package/lib/agent-kit/host-approve.js +172 -0
- package/lib/agent-kit/hosting/github.js +63 -0
- package/lib/agent-kit/hosts.js +71 -0
- package/lib/agent-kit/init.js +319 -0
- package/lib/agent-kit/kit-root.js +17 -0
- package/lib/agent-kit/managed-section.js +79 -0
- package/lib/agent-kit/package-load.js +45 -0
- package/lib/agent-kit/plan-ops.js +69 -0
- package/lib/agent-kit/remote-prompts.js +272 -0
- package/lib/agent-kit/render-host-markdown.js +40 -0
- package/lib/agent-kit/repo-guard.js +47 -0
- package/lib/agent-kit/report.js +107 -0
- package/lib/agent-kit/run.js +82 -0
- package/lib/agent-kit/scm/git.js +122 -0
- package/lib/agent-kit/start.js +310 -0
- package/lib/agent-kit/state-file.js +83 -0
- package/lib/agent-kit/status.js +50 -0
- package/lib/agent-kit/v1-detect.js +81 -0
- package/lib/agent-kit/validate-kit.js +87 -0
- package/lib/agent-kit/workspace-name.js +40 -0
- package/lib/agent-kit/workspace-skeleton.js +103 -0
- package/lib/api/role-assistant-test-pack.api.js +86 -0
- package/lib/api/work-search.api.js +31 -4
- package/lib/api/work.api.js +19 -12
- package/lib/app/deploy.js +7 -4
- package/lib/app/list-external-systems.js +2 -1
- package/lib/app/offer-create-from-template.js +184 -0
- package/lib/app/show-display.js +33 -6
- package/lib/app/show.js +25 -2
- package/lib/channels/add-channel.js +1 -0
- package/lib/channels/approval-guides/claude.js +2 -2
- package/lib/channels/channel-add-failure.js +1 -0
- package/lib/channels/channel-add-remaining.js +15 -9
- package/lib/channels/channel-definition-status.js +115 -0
- package/lib/channels/channel-description.js +2 -1
- package/lib/channels/channel-install-envelope.js +4 -2
- package/lib/channels/channel-integration-generator.js +2 -0
- package/lib/channels/channel-runtime-resolver.js +14 -0
- package/lib/channels/channel-targets.js +31 -5
- package/lib/channels/claude-setup-values.js +4 -1
- package/lib/channels/slack-channel-add.js +59 -6
- package/lib/channels/slack-mcp-callback.js +51 -0
- package/lib/channels/slack-mcp-runtime.js +156 -0
- package/lib/channels/slack-provisioning/install-cli.js +14 -2
- package/lib/channels/slack-provisioning/with-curl-on-path.js +6 -1
- package/lib/cli/index.js +4 -0
- package/lib/cli/setup-app.js +8 -1
- package/lib/cli/setup-auth.js +11 -2
- package/lib/cli/setup-certification-commands.js +2 -2
- package/lib/cli/setup-certification.help.js +3 -1
- package/lib/commands/agent-kit-help.js +149 -0
- package/lib/commands/agent-kit.js +417 -0
- package/lib/commands/auth-status-user.js +99 -0
- package/lib/commands/auth-status.js +14 -4
- package/lib/commands/channel-add-help.js +5 -5
- package/lib/commands/datasource-capability-relate-cli.js +5 -4
- package/lib/commands/datasource-load-export-cli.js +7 -2
- package/lib/commands/datasource-test-trust-cli.js +5 -1
- package/lib/commands/governance-command-action.js +5 -4
- package/lib/commands/identity-membership-role-cache.js +6 -1
- package/lib/commands/lifecycle-command-action.js +16 -15
- package/lib/commands/login-credentials.js +8 -3
- package/lib/commands/login-device.js +14 -5
- package/lib/commands/login.js +14 -1
- package/lib/commands/logout.js +50 -15
- package/lib/commands/repair-auth-apply.js +1 -1
- package/lib/commands/repair-datasource-key-skip.js +39 -0
- package/lib/commands/repair-datasource-keys.js +24 -12
- package/lib/commands/repair-rbac.js +16 -10
- package/lib/commands/role-assistant-copy-output.js +61 -0
- package/lib/commands/role-assistant-copy.js +155 -0
- package/lib/commands/role-assistant-test-output.js +8 -9
- package/lib/commands/role-assistant-test-result-rows.js +42 -0
- package/lib/commands/role-assistant.js +140 -59
- package/lib/commands/search.js +143 -0
- package/lib/commands/test-trust-external.js +7 -5
- package/lib/commands/upload-sidecar-followups.js +4 -1
- package/lib/commands/verify-governance-command-action.js +9 -7
- package/lib/commands/verify-operations-command-action.js +9 -8
- package/lib/commands/verify-operations-skip-e2e.js +131 -0
- package/lib/commands/verify-operations-step-plan.js +6 -33
- package/lib/commands/verify-operations-steps.js +3 -1
- package/lib/commands/verify-trust-command-action.js +6 -5
- package/lib/datasource/capability/relate-operations.js +28 -10
- package/lib/datasource/capability/run-capability-relate.js +48 -25
- package/lib/datasource/datasource-identifier.js +13 -5
- package/lib/deployment/deployer-poll-run.js +117 -35
- package/lib/external-system/deploy-dataplane-published.js +70 -0
- package/lib/external-system/deploy.js +12 -2
- package/lib/external-system/download-role-assistant.js +41 -15
- package/lib/external-system/download.js +8 -3
- package/lib/generator/helpers.js +12 -1
- package/lib/generator/wizard-datasource-key.js +54 -0
- package/lib/generator/wizard.js +55 -54
- package/lib/integration-definition/apply-datasource-keys.js +75 -0
- package/lib/integration-definition/apply-relationships.js +195 -0
- package/lib/integration-definition/apply-static-enterprise.js +232 -0
- package/lib/integration-definition/apply-system-file.js +71 -0
- package/lib/integration-definition/apply-test-endpoint.js +89 -0
- package/lib/integration-definition/apply-viewpoint-defaults.js +157 -0
- package/lib/integration-definition/apply.js +78 -59
- package/lib/integration-definition/enrich-openapi-operations.js +36 -10
- package/lib/integration-definition/enrich-openapi-pick.js +87 -0
- package/lib/lifecycle/role-assistant-governance.js +56 -21
- package/lib/programmatic/capability-registry.js +1 -0
- package/lib/programmatic/index.js +2 -0
- package/lib/programmatic/openapi-apply-result-schemas.js +8 -0
- package/lib/programmatic/openapi-channel-install-schemas.js +4 -1
- package/lib/programmatic/openapi-component-schemas.js +1 -0
- package/lib/programmatic/openapi-descriptions.js +9 -3
- package/lib/programmatic/openapi-envelope-examples.js +7 -0
- package/lib/programmatic/openapi-operation-bindings.js +5 -0
- package/lib/programmatic/openapi-request-schemas.js +5 -0
- package/lib/programmatic/openapi-schema-descriptions-channel.js +8 -5
- package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
- package/lib/programmatic/openapi-spec.js +1 -0
- package/lib/programmatic/request-timeout.js +3 -0
- package/lib/programmatic/route-handler-map.js +7 -0
- package/lib/programmatic/run-channel-catalog.js +50 -8
- package/lib/programmatic/run-channel-install-options.js +5 -1
- package/lib/programmatic/run-download.js +41 -0
- package/lib/protection/auth-context.js +3 -1
- package/lib/protection/protection-display.js +3 -2
- package/lib/protection/report-exit.js +50 -0
- package/lib/protection/run-commands.js +2 -0
- package/lib/role-assistant/knowledge-sync-settings-push.js +172 -0
- package/lib/role-assistant/knowledge-sync.js +9 -126
- package/lib/role-assistant/package-validate.js +175 -0
- package/lib/role-assistant/test-case-assertion-row.js +36 -0
- package/lib/role-assistant/test-case-copy-bind.js +77 -0
- package/lib/role-assistant/test-case-copy-expected.js +127 -0
- package/lib/role-assistant/test-case-copy-from-work.js +90 -0
- package/lib/role-assistant/test-case-copy-interactions.js +67 -0
- package/lib/role-assistant/test-case-copy.js +119 -0
- package/lib/role-assistant/test-case-expected-catalog.js +135 -0
- package/lib/role-assistant/test-case-validate.js +88 -0
- package/lib/role-assistant/test-cases-bid.js +117 -4
- package/lib/role-assistant/test-cases-evaluate.js +149 -31
- package/lib/role-assistant/test-cases-evidence.js +44 -5
- package/lib/role-assistant/test-cases-honesty.js +155 -6
- package/lib/role-assistant/test-cases-lifecycle.js +297 -0
- package/lib/role-assistant/test-cases-search-graph.js +122 -0
- package/lib/role-assistant/test-cases-search.js +20 -2
- package/lib/role-assistant/test-cases.js +34 -168
- package/lib/role-assistant/test-pack-map.js +180 -0
- package/lib/role-assistant/test-pack-sync.js +187 -0
- package/lib/role-assistant/test-runner-debug.js +54 -0
- package/lib/role-assistant/test-runner-respond-body.js +36 -0
- package/lib/role-assistant/test-runner-search.js +20 -5
- package/lib/role-assistant/test-runner-start-payload.js +63 -10
- package/lib/role-assistant/test-runner-workhub-answers.js +45 -16
- package/lib/role-assistant/test-runner-workhub.js +45 -21
- package/lib/role-assistant/test-runner.js +53 -10
- package/lib/schema/external-datasource.schema.json +36 -5
- package/lib/schema/external-system.schema.json +20 -2
- package/lib/schema/infra-parameter.schema.json +51 -3
- package/lib/schema/infra.parameter.yaml +476 -40
- package/lib/schema/role-assistant-test-case.schema.json +408 -0
- package/lib/schema/type/document-storage.json +1 -1
- package/lib/search/dataplane-context.js +23 -0
- package/lib/search/search-args.js +211 -0
- package/lib/search/search-display.js +238 -0
- package/lib/search/search-errors.js +50 -0
- package/lib/search/search-prompts.js +119 -0
- package/lib/search/search-roles.js +85 -0
- package/lib/search/search-run.js +241 -0
- package/lib/search/search-skills.js +198 -0
- package/lib/utils/api-required-permissions.js +271 -0
- package/lib/utils/api.js +16 -13
- package/lib/utils/authentication-slot-show.js +153 -0
- package/lib/utils/cli-json-exit.js +41 -0
- package/lib/utils/cli-utils.js +23 -5
- package/lib/utils/controller-url.js +78 -4
- package/lib/utils/credential-display.js +43 -1
- package/lib/utils/deployment-errors.js +15 -0
- package/lib/utils/deployment-validation-helpers.js +4 -1
- package/lib/utils/device-code.js +31 -10
- package/lib/utils/error-formatters/error-parser.js +16 -1
- package/lib/utils/error-formatters/permission-errors.js +19 -5
- package/lib/utils/external-system-readiness-compact-blocks.js +5 -1
- package/lib/utils/external-system-readiness-compact-display.js +30 -1
- package/lib/utils/external-system-validators.js +2 -1
- package/lib/utils/help-builder.js +3 -1
- package/lib/utils/keycloak-realm-ready.js +5 -2
- package/lib/utils/logger.js +1 -0
- package/lib/utils/paths.js +26 -5
- package/lib/utils/schema-loader.js +37 -0
- package/lib/utils/secrets-helpers.js +2 -2
- package/lib/utils/write-stream-and-wait.js +63 -0
- package/lib/validation/validate-external-file.js +5 -1
- package/lib/validation/validate.js +3 -2
- package/package.json +20 -6
- package/templates/agent-kit/adapters/claude/nested.CLAUDE.md +1 -0
- package/templates/agent-kit/adapters/claude/root.CLAUDE.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-0-plan.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-3-push.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-3-prove.md +5 -0
- package/templates/agent-kit/agent-kit.yaml +45 -0
- package/templates/agent-kit/instructions/AGENTKIT.md +104 -0
- package/templates/agent-kit/instructions/integration.AGENTS.md +25 -0
- package/templates/agent-kit/instructions/role-assistant.AGENTS.md +22 -0
- package/templates/agent-kit/instructions/root.AGENTS.md +37 -0
- package/templates/agent-kit/parity-inventory.yaml +188 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +59 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/contract-checklist.md +40 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +54 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/production-safety.md +35 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/scripts/reserved-system-key.js +19 -0
- package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +52 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/challenge-checklist.md +108 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +34 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/plan-template.md +182 -0
- package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +51 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/demo-template.md +65 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +68 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/learning-template.md +66 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +43 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
- package/templates/agent-kit/skills/shared/hosts.md +65 -0
- package/templates/agent-kit/skills/shared/login.md +16 -0
- package/templates/agent-kit/workspace/.cursor/plans/README.md +22 -0
- package/templates/agent-kit/workspace/LICENSE.mit +21 -0
- package/templates/agent-kit/workspace/README.md +89 -0
- package/templates/applications/builder-api/Dockerfile +3 -1
- package/templates/applications/dataplane/application.yaml +2 -3
- package/templates/applications/dataplane/env.template +5 -5
- package/templates/applications/dataplane/rbac.yaml +28 -0
- package/templates/applications/keycloak/env.template +3 -3
- package/templates/applications/miso-controller/application.yaml +21 -2
- package/templates/applications/miso-controller/env.template +96 -25
- package/templates/applications/miso-controller/rbac.yaml +5 -0
- package/templates/channels/claude/TROUBLESHOOTING.md +3 -0
- package/templates/channels/claude/channel.json +1 -1
- package/templates/channels/claude/install.template.md.hbs +1 -0
- package/templates/channels/claude/integration/claude-system.json +1 -1
- package/templates/channels/slack/channel.json +11 -0
- package/templates/channels/slack/install.template.md.hbs +9 -0
- package/templates/channels/slack/integration/slack-system.json +11 -0
- package/templates/channels/slack/manifest.template.json.hbs +6 -3
- package/templates/channels/teams-bot/channel.json +1 -0
- package/templates/python/docker-compose.hbs +14 -0
- package/templates/typescript/docker-compose.hbs +14 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push role-assistant.yaml knowledge/debug/runtime settings to Assistants.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Map local Role Assistant settings onto dataplane Assistants PATCH
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const { updateAssistantSettings } = require('../api/assistants.api');
|
|
12
|
+
const {
|
|
13
|
+
readRoleAssistantSettings,
|
|
14
|
+
resolveDocumentStorageKeyFromRoleAssistantSettings,
|
|
15
|
+
resolveRoleAssistantEnvironmentSettings
|
|
16
|
+
} = require('./settings');
|
|
17
|
+
|
|
18
|
+
function resolveRoleAssistantSettingsEnvKey(environment) {
|
|
19
|
+
const token = String(environment || '').trim().toLowerCase();
|
|
20
|
+
return token === 'dev' || token === 'tst' || token === 'pro' ? token : 'dev';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Map role-assistant.yaml debug.* → Assistants settings PATCH fields.
|
|
25
|
+
* includePromptTrace → fullDebugEnabled (LLM prompt capture gate).
|
|
26
|
+
* enabled → debugEnabled (runtime debug traces).
|
|
27
|
+
* @param {Object|null|undefined} debugSection
|
|
28
|
+
* @returns {{ debugEnabled?: boolean, fullDebugEnabled?: boolean }}
|
|
29
|
+
*/
|
|
30
|
+
function mapRoleAssistantDebugToAssistantsSettings(debugSection) {
|
|
31
|
+
if (!debugSection || typeof debugSection !== 'object') {
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
const body = {};
|
|
35
|
+
if (typeof debugSection.enabled === 'boolean') {
|
|
36
|
+
body.debugEnabled = debugSection.enabled;
|
|
37
|
+
}
|
|
38
|
+
if (typeof debugSection.includePromptTrace === 'boolean') {
|
|
39
|
+
body.fullDebugEnabled = debugSection.includePromptTrace;
|
|
40
|
+
}
|
|
41
|
+
return body;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Map role-assistant.yaml runtime.* to the governed Assistants settings names.
|
|
46
|
+
* Provider selection remains platform-owned; the assistant may override only
|
|
47
|
+
* its workflow reasoning model and execution profile.
|
|
48
|
+
* @param {Object|null|undefined} runtimeSection
|
|
49
|
+
* @returns {{ workflowReasoningModel?: string, temperature?: number, maxLlmLoops?: number, maxToolLoops?: number }}
|
|
50
|
+
*/
|
|
51
|
+
function mapRoleAssistantRuntimeToAssistantsSettings(runtimeSection) {
|
|
52
|
+
if (!runtimeSection || typeof runtimeSection !== 'object') {
|
|
53
|
+
return {};
|
|
54
|
+
}
|
|
55
|
+
const body = {};
|
|
56
|
+
if (typeof runtimeSection.model === 'string' && runtimeSection.model.trim()) {
|
|
57
|
+
body.workflowReasoningModel = runtimeSection.model.trim();
|
|
58
|
+
}
|
|
59
|
+
if (typeof runtimeSection.temperature === 'number') {
|
|
60
|
+
body.temperature = runtimeSection.temperature;
|
|
61
|
+
}
|
|
62
|
+
if (Number.isInteger(runtimeSection.maxLoops)) {
|
|
63
|
+
body.maxLlmLoops = runtimeSection.maxLoops;
|
|
64
|
+
body.maxToolLoops = runtimeSection.maxLoops;
|
|
65
|
+
}
|
|
66
|
+
return body;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Push role-assistant.yaml knowledge + debug settings to dataplane Assistants.
|
|
71
|
+
* Called on upload/deploy so the operator UI and CLI stay aligned.
|
|
72
|
+
*/
|
|
73
|
+
function resolveAssistantSettingsPush(params) {
|
|
74
|
+
const {
|
|
75
|
+
systemKey,
|
|
76
|
+
environment = 'dev',
|
|
77
|
+
pathOptions = {}
|
|
78
|
+
} = params;
|
|
79
|
+
const settingsEnv = resolveRoleAssistantSettingsEnvKey(environment);
|
|
80
|
+
const settings = readRoleAssistantSettings(systemKey, { required: false, pathOptions });
|
|
81
|
+
if (!settings) {
|
|
82
|
+
return { result: { skipped: true, reason: 'missing-role-assistant-settings' } };
|
|
83
|
+
}
|
|
84
|
+
const section = resolveRoleAssistantEnvironmentSettings(settings, settingsEnv, {
|
|
85
|
+
required: false
|
|
86
|
+
});
|
|
87
|
+
if (!section) {
|
|
88
|
+
return { result: { skipped: true, reason: 'missing-env-settings' } };
|
|
89
|
+
}
|
|
90
|
+
const documentStorageKey =
|
|
91
|
+
resolveDocumentStorageKeyFromRoleAssistantSettings(settings, settingsEnv) || '';
|
|
92
|
+
const debugBody = mapRoleAssistantDebugToAssistantsSettings(section.debug);
|
|
93
|
+
const runtimeBody = mapRoleAssistantRuntimeToAssistantsSettings(section.runtime);
|
|
94
|
+
const settingsBody = { ...runtimeBody, ...debugBody };
|
|
95
|
+
if (!documentStorageKey && Object.keys(settingsBody).length === 0) {
|
|
96
|
+
return { result: { skipped: true, reason: 'no-document-storage-key', documentStorageKey: null } };
|
|
97
|
+
}
|
|
98
|
+
const patchBody = { ...settingsBody };
|
|
99
|
+
if (documentStorageKey) {
|
|
100
|
+
patchBody.documentStorageKey = documentStorageKey;
|
|
101
|
+
}
|
|
102
|
+
return { documentStorageKey, debugBody: settingsBody, patchBody };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function applyAssistantSettingsPush(dataplaneUrl, systemKey, authConfig, settingsPush) {
|
|
106
|
+
const { documentStorageKey, debugBody, patchBody } = settingsPush;
|
|
107
|
+
const hasDocumentStorageKey = documentStorageKey !== '';
|
|
108
|
+
const hasDebugSettings = Object.keys(debugBody).length > 0;
|
|
109
|
+
const assistantKey = String(systemKey || '').trim();
|
|
110
|
+
let response = await updateAssistantSettings(
|
|
111
|
+
dataplaneUrl,
|
|
112
|
+
assistantKey,
|
|
113
|
+
authConfig,
|
|
114
|
+
patchBody
|
|
115
|
+
);
|
|
116
|
+
if (response && response.success === false && hasDocumentStorageKey && hasDebugSettings) {
|
|
117
|
+
response = await updateAssistantSettings(
|
|
118
|
+
dataplaneUrl,
|
|
119
|
+
assistantKey,
|
|
120
|
+
authConfig,
|
|
121
|
+
debugBody
|
|
122
|
+
);
|
|
123
|
+
if (response && response.success === false) {
|
|
124
|
+
throw new Error(
|
|
125
|
+
response.formattedError ||
|
|
126
|
+
response.error ||
|
|
127
|
+
'Failed to update Assistants debug settings'
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
skipped: false,
|
|
132
|
+
documentStorageKey: null,
|
|
133
|
+
documentStoragePushFailed: true,
|
|
134
|
+
...debugBody
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (response && response.success === false) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
response.formattedError ||
|
|
140
|
+
response.error ||
|
|
141
|
+
'Failed to update Knowledge document storage settings'
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
skipped: false,
|
|
146
|
+
documentStorageKey: documentStorageKey || null,
|
|
147
|
+
...debugBody
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function pushRoleAssistantDocumentStorageSettings(params) {
|
|
152
|
+
const { systemKey, dataplaneUrl, authConfig, dryRun = false } = params;
|
|
153
|
+
const settingsPush = resolveAssistantSettingsPush(params);
|
|
154
|
+
if (settingsPush.result) {
|
|
155
|
+
return settingsPush.result;
|
|
156
|
+
}
|
|
157
|
+
const { documentStorageKey, debugBody } = settingsPush;
|
|
158
|
+
if (dryRun) {
|
|
159
|
+
return { skipped: false, dryRun: true, documentStorageKey: documentStorageKey || null, ...debugBody };
|
|
160
|
+
}
|
|
161
|
+
if (!dataplaneUrl || !authConfig) {
|
|
162
|
+
return { skipped: true, reason: 'missing-dataplane-auth' };
|
|
163
|
+
}
|
|
164
|
+
return applyAssistantSettingsPush(dataplaneUrl, systemKey, authConfig, settingsPush);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
module.exports = {
|
|
168
|
+
resolveRoleAssistantSettingsEnvKey,
|
|
169
|
+
mapRoleAssistantDebugToAssistantsSettings,
|
|
170
|
+
mapRoleAssistantRuntimeToAssistantsSettings,
|
|
171
|
+
pushRoleAssistantDocumentStorageSettings
|
|
172
|
+
};
|
|
@@ -15,8 +15,7 @@ const yaml = require('js-yaml');
|
|
|
15
15
|
const { listDocuments, validateDocuments, bulkDocuments } = require('../api/datasources-extended.api');
|
|
16
16
|
const {
|
|
17
17
|
extractDocumentStorageKeyFromAssistantDetails,
|
|
18
|
-
getAssistantDetails
|
|
19
|
-
updateAssistantSettings
|
|
18
|
+
getAssistantDetails
|
|
20
19
|
} = require('../api/assistants.api');
|
|
21
20
|
const { resolveExternalSystemPath } = require('../utils/app-path-resolve');
|
|
22
21
|
const { bareRoleKey } = require('../utils/role-assistant-paths');
|
|
@@ -24,9 +23,14 @@ const {
|
|
|
24
23
|
SYSTEM_KIND_DIGITAL_WORKER,
|
|
25
24
|
getRoleAssistantYamlPath,
|
|
26
25
|
readRoleAssistantSettings,
|
|
27
|
-
resolveDocumentStorageKeyFromRoleAssistantSettings
|
|
28
|
-
resolveRoleAssistantEnvironmentSettings
|
|
26
|
+
resolveDocumentStorageKeyFromRoleAssistantSettings
|
|
29
27
|
} = require('./settings');
|
|
28
|
+
const {
|
|
29
|
+
resolveRoleAssistantSettingsEnvKey,
|
|
30
|
+
mapRoleAssistantDebugToAssistantsSettings,
|
|
31
|
+
mapRoleAssistantRuntimeToAssistantsSettings,
|
|
32
|
+
pushRoleAssistantDocumentStorageSettings
|
|
33
|
+
} = require('./knowledge-sync-settings-push');
|
|
30
34
|
const {
|
|
31
35
|
knowledgeSearchMetadataFromFrontmatter,
|
|
32
36
|
splitMarkdownFrontmatter
|
|
@@ -87,123 +91,6 @@ async function resolveDocumentStorageKeyFromDataplane(dataplaneUrl, authConfig,
|
|
|
87
91
|
}
|
|
88
92
|
}
|
|
89
93
|
|
|
90
|
-
/**
|
|
91
|
-
* Map role-assistant.yaml debug.* → Assistants settings PATCH fields.
|
|
92
|
-
* includePromptTrace → fullDebugEnabled (LLM prompt capture gate).
|
|
93
|
-
* enabled → debugEnabled (runtime debug traces).
|
|
94
|
-
* @param {Object|null|undefined} debugSection
|
|
95
|
-
* @returns {{ debugEnabled?: boolean, fullDebugEnabled?: boolean }}
|
|
96
|
-
*/
|
|
97
|
-
function mapRoleAssistantDebugToAssistantsSettings(debugSection) {
|
|
98
|
-
if (!debugSection || typeof debugSection !== 'object') {
|
|
99
|
-
return {};
|
|
100
|
-
}
|
|
101
|
-
const body = {};
|
|
102
|
-
if (typeof debugSection.enabled === 'boolean') {
|
|
103
|
-
body.debugEnabled = debugSection.enabled;
|
|
104
|
-
}
|
|
105
|
-
if (typeof debugSection.includePromptTrace === 'boolean') {
|
|
106
|
-
body.fullDebugEnabled = debugSection.includePromptTrace;
|
|
107
|
-
}
|
|
108
|
-
return body;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Push role-assistant.yaml knowledge + debug settings to dataplane Assistants.
|
|
113
|
-
* Called on upload/deploy so the operator UI and CLI stay aligned.
|
|
114
|
-
*/
|
|
115
|
-
function resolveAssistantSettingsPush(params) {
|
|
116
|
-
const {
|
|
117
|
-
systemKey,
|
|
118
|
-
environment = 'dev',
|
|
119
|
-
pathOptions = {}
|
|
120
|
-
} = params;
|
|
121
|
-
const settingsEnv = resolveRoleAssistantSettingsEnvKey(environment);
|
|
122
|
-
const settings = readRoleAssistantSettings(systemKey, { required: false, pathOptions });
|
|
123
|
-
if (!settings) {
|
|
124
|
-
return { result: { skipped: true, reason: 'missing-role-assistant-settings' } };
|
|
125
|
-
}
|
|
126
|
-
const section = resolveRoleAssistantEnvironmentSettings(settings, settingsEnv, {
|
|
127
|
-
required: false
|
|
128
|
-
});
|
|
129
|
-
if (!section) {
|
|
130
|
-
return { result: { skipped: true, reason: 'missing-env-settings' } };
|
|
131
|
-
}
|
|
132
|
-
const documentStorageKey =
|
|
133
|
-
resolveDocumentStorageKeyFromRoleAssistantSettings(settings, settingsEnv) || '';
|
|
134
|
-
const debugBody = mapRoleAssistantDebugToAssistantsSettings(section.debug);
|
|
135
|
-
if (!documentStorageKey && Object.keys(debugBody).length === 0) {
|
|
136
|
-
return { result: { skipped: true, reason: 'no-document-storage-key', documentStorageKey: null } };
|
|
137
|
-
}
|
|
138
|
-
const patchBody = { ...debugBody };
|
|
139
|
-
if (documentStorageKey) {
|
|
140
|
-
patchBody.documentStorageKey = documentStorageKey;
|
|
141
|
-
}
|
|
142
|
-
return { documentStorageKey, debugBody, patchBody };
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
async function applyAssistantSettingsPush(dataplaneUrl, systemKey, authConfig, settingsPush) {
|
|
146
|
-
const { documentStorageKey, debugBody, patchBody } = settingsPush;
|
|
147
|
-
const hasDocumentStorageKey = documentStorageKey !== '';
|
|
148
|
-
const hasDebugSettings = Object.keys(debugBody).length > 0;
|
|
149
|
-
const assistantKey = String(systemKey || '').trim();
|
|
150
|
-
let response = await updateAssistantSettings(
|
|
151
|
-
dataplaneUrl,
|
|
152
|
-
assistantKey,
|
|
153
|
-
authConfig,
|
|
154
|
-
patchBody
|
|
155
|
-
);
|
|
156
|
-
if (response && response.success === false && hasDocumentStorageKey && hasDebugSettings) {
|
|
157
|
-
response = await updateAssistantSettings(
|
|
158
|
-
dataplaneUrl,
|
|
159
|
-
assistantKey,
|
|
160
|
-
authConfig,
|
|
161
|
-
debugBody
|
|
162
|
-
);
|
|
163
|
-
if (response && response.success === false) {
|
|
164
|
-
throw new Error(
|
|
165
|
-
response.formattedError ||
|
|
166
|
-
response.error ||
|
|
167
|
-
'Failed to update Assistants debug settings'
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
return {
|
|
171
|
-
skipped: false,
|
|
172
|
-
documentStorageKey: null,
|
|
173
|
-
documentStoragePushFailed: true,
|
|
174
|
-
...debugBody
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
if (response && response.success === false) {
|
|
178
|
-
throw new Error(
|
|
179
|
-
response.formattedError ||
|
|
180
|
-
response.error ||
|
|
181
|
-
'Failed to update Knowledge document storage settings'
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
return {
|
|
185
|
-
skipped: false,
|
|
186
|
-
documentStorageKey: documentStorageKey || null,
|
|
187
|
-
...debugBody
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async function pushRoleAssistantDocumentStorageSettings(params) {
|
|
192
|
-
const { systemKey, dataplaneUrl, authConfig, dryRun = false } = params;
|
|
193
|
-
const settingsPush = resolveAssistantSettingsPush(params);
|
|
194
|
-
if (settingsPush.result) {
|
|
195
|
-
return settingsPush.result;
|
|
196
|
-
}
|
|
197
|
-
const { documentStorageKey, debugBody } = settingsPush;
|
|
198
|
-
if (dryRun) {
|
|
199
|
-
return { skipped: false, dryRun: true, documentStorageKey: documentStorageKey || null, ...debugBody };
|
|
200
|
-
}
|
|
201
|
-
if (!dataplaneUrl || !authConfig) {
|
|
202
|
-
return { skipped: true, reason: 'missing-dataplane-auth' };
|
|
203
|
-
}
|
|
204
|
-
return applyAssistantSettingsPush(dataplaneUrl, systemKey, authConfig, settingsPush);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
94
|
/**
|
|
208
95
|
* Resolve Knowledge document storage key.
|
|
209
96
|
* Order: role-assistant.yaml → dataplane Assistants settings → package dataSources.
|
|
@@ -341,11 +228,6 @@ function resolveDocumentFileName(row, index) {
|
|
|
341
228
|
return filePath.startsWith('/') ? filePath.slice(1) : filePath;
|
|
342
229
|
}
|
|
343
230
|
|
|
344
|
-
function resolveRoleAssistantSettingsEnvKey(environment) {
|
|
345
|
-
const token = String(environment || '').trim().toLowerCase();
|
|
346
|
-
return token === 'dev' || token === 'tst' || token === 'pro' ? token : 'dev';
|
|
347
|
-
}
|
|
348
|
-
|
|
349
231
|
function writeRoleAssistantSettingsFile(systemKey, docStorageKey, environment = 'dev', pathOptions = {}) {
|
|
350
232
|
const roleAssistantPath = resolveExternalSystemPath(systemKey, pathOptions);
|
|
351
233
|
const roleAssistantYamlPath = getRoleAssistantYamlPath(systemKey, { pathOptions });
|
|
@@ -477,6 +359,7 @@ module.exports = {
|
|
|
477
359
|
resolveRoleAssistantSettingsEnvKey,
|
|
478
360
|
resolveRoleAssistantDocumentStorageKey,
|
|
479
361
|
mapRoleAssistantDebugToAssistantsSettings,
|
|
362
|
+
mapRoleAssistantRuntimeToAssistantsSettings,
|
|
480
363
|
pushRoleAssistantDocumentStorageSettings,
|
|
481
364
|
importRoleAssistantKnowledge,
|
|
482
365
|
exportRoleAssistantKnowledge,
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role Assistant package folder validation (settings, tests, evidence, knowledge).
|
|
3
|
+
* @fileoverview Walk ra-* governed files. Ignore leftover Connected System artifacts.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const fs = require('../internal/fs-real-sync');
|
|
10
|
+
const { validateExternalFile, parseJsonFileContent } = require('../validation/validate-external-file');
|
|
11
|
+
const { listTestCaseFiles } = require('./test-cases');
|
|
12
|
+
const { validateTestCaseFile } = require('./test-case-validate');
|
|
13
|
+
|
|
14
|
+
const SETTINGS_TYPE = 'role-assistant-settings';
|
|
15
|
+
const EMPTY_TESTS_SKIP = 'tests/: skipped (no test cases)';
|
|
16
|
+
|
|
17
|
+
function fileRow(filePath, type, result) {
|
|
18
|
+
return {
|
|
19
|
+
file: path.basename(filePath),
|
|
20
|
+
type,
|
|
21
|
+
valid: result.valid,
|
|
22
|
+
path: filePath,
|
|
23
|
+
errors: result.errors || [],
|
|
24
|
+
warnings: result.warnings || []
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function listFilesByExt(dirPath, ext, acc) {
|
|
29
|
+
if (!fs.existsSync(dirPath)) {
|
|
30
|
+
return acc;
|
|
31
|
+
}
|
|
32
|
+
for (const name of fs.readdirSync(dirPath)) {
|
|
33
|
+
if (String(name).startsWith('.')) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const full = path.join(dirPath, name);
|
|
37
|
+
const st = fs.statSync(full);
|
|
38
|
+
if (st.isDirectory()) {
|
|
39
|
+
listFilesByExt(full, ext, acc);
|
|
40
|
+
} else if (String(name).toLowerCase().endsWith(ext)) {
|
|
41
|
+
acc.push(full);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return acc;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function evidenceRows(parsed) {
|
|
48
|
+
if (Array.isArray(parsed)) {
|
|
49
|
+
return parsed;
|
|
50
|
+
}
|
|
51
|
+
if (parsed && typeof parsed === 'object') {
|
|
52
|
+
return [parsed];
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function validateEvidenceJsonFile(filePath) {
|
|
58
|
+
const parseResult = parseJsonFileContent(filePath);
|
|
59
|
+
if (parseResult.error) {
|
|
60
|
+
return { ...parseResult.error, file: filePath, type: 'evidence' };
|
|
61
|
+
}
|
|
62
|
+
const rows = evidenceRows(parseResult.parsed);
|
|
63
|
+
const errors = [];
|
|
64
|
+
if (!rows) {
|
|
65
|
+
errors.push(`${filePath}: Evidence JSON must be an object or array of objects`);
|
|
66
|
+
} else {
|
|
67
|
+
rows.forEach((row, index) => {
|
|
68
|
+
const key = row && typeof row === 'object' && !Array.isArray(row) ? String(row.key || '').trim() : '';
|
|
69
|
+
if (!key) {
|
|
70
|
+
errors.push(`${filePath}: item ${index} is missing key`);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return { valid: errors.length === 0, errors, warnings: [], file: filePath, type: 'evidence' };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function validateKnowledgeMarkdown(filePath) {
|
|
78
|
+
const text = fs.readFileSync(filePath, 'utf8');
|
|
79
|
+
if (!String(text).trim()) {
|
|
80
|
+
return {
|
|
81
|
+
valid: false,
|
|
82
|
+
errors: [`${filePath}: knowledge markdown must not be empty`],
|
|
83
|
+
warnings: [],
|
|
84
|
+
file: filePath,
|
|
85
|
+
type: 'knowledge'
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return { valid: true, errors: [], warnings: [], file: filePath, type: 'knowledge' };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function validateSettingsFile(appPath) {
|
|
92
|
+
const yamlPath = path.join(appPath, 'role-assistant.yaml');
|
|
93
|
+
try {
|
|
94
|
+
const result = await validateExternalFile(yamlPath, SETTINGS_TYPE);
|
|
95
|
+
return fileRow(yamlPath, SETTINGS_TYPE, result);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return fileRow(yamlPath, SETTINGS_TYPE, {
|
|
98
|
+
valid: false,
|
|
99
|
+
errors: [error.message],
|
|
100
|
+
warnings: []
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function collectDuplicateCaseIdErrors(caseFiles) {
|
|
106
|
+
const seen = new Map();
|
|
107
|
+
const errors = [];
|
|
108
|
+
for (const row of caseFiles) {
|
|
109
|
+
const parseResult = parseJsonFileContent(row.path);
|
|
110
|
+
const caseId = parseResult.parsed && String(parseResult.parsed.caseId || '').trim();
|
|
111
|
+
if (!caseId) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (seen.has(caseId)) {
|
|
115
|
+
errors.push(`${row.path}: duplicate caseId "${caseId}" (also ${seen.get(caseId)})`);
|
|
116
|
+
} else {
|
|
117
|
+
seen.set(caseId, row.path);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return errors;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function validateTestFiles(appPath) {
|
|
124
|
+
const testsDir = path.join(appPath, 'tests');
|
|
125
|
+
const yamlFiles = listTestCaseFiles(testsDir);
|
|
126
|
+
if (yamlFiles.length === 0) {
|
|
127
|
+
return { files: [], errors: [], warnings: [EMPTY_TESTS_SKIP] };
|
|
128
|
+
}
|
|
129
|
+
const files = yamlFiles.map((filePath) => fileRow(filePath, 'role-assistant-test-case', validateTestCaseFile(filePath)));
|
|
130
|
+
const errors = files.flatMap((row) => row.errors);
|
|
131
|
+
errors.push(...collectDuplicateCaseIdErrors(files));
|
|
132
|
+
return { files, errors, warnings: [] };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function validateEvidenceFiles(appPath) {
|
|
136
|
+
const jsonFiles = listFilesByExt(path.join(appPath, 'evidence'), '.json', []);
|
|
137
|
+
const files = jsonFiles.map((filePath) => fileRow(filePath, 'evidence', validateEvidenceJsonFile(filePath)));
|
|
138
|
+
return { files, errors: files.flatMap((row) => row.errors), warnings: [] };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function validateKnowledgeFiles(appPath) {
|
|
142
|
+
const mdFiles = listFilesByExt(path.join(appPath, 'knowledge'), '.md', []).filter((filePath) => {
|
|
143
|
+
return path.dirname(filePath) === path.join(appPath, 'knowledge');
|
|
144
|
+
});
|
|
145
|
+
const files = mdFiles.map((filePath) => fileRow(filePath, 'knowledge', validateKnowledgeMarkdown(filePath)));
|
|
146
|
+
return { files, errors: files.flatMap((row) => row.errors), warnings: [] };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async function validateRoleAssistantPackage(appPath) {
|
|
150
|
+
const settings = await validateSettingsFile(appPath);
|
|
151
|
+
const tests = validateTestFiles(appPath);
|
|
152
|
+
const evidence = validateEvidenceFiles(appPath);
|
|
153
|
+
const knowledge = validateKnowledgeFiles(appPath);
|
|
154
|
+
const files = [settings, ...tests.files, ...evidence.files, ...knowledge.files];
|
|
155
|
+
const errors = [
|
|
156
|
+
...settings.errors,
|
|
157
|
+
...tests.errors,
|
|
158
|
+
...evidence.errors,
|
|
159
|
+
...knowledge.errors
|
|
160
|
+
];
|
|
161
|
+
const warnings = [...settings.warnings, ...tests.warnings, ...evidence.warnings, ...knowledge.warnings];
|
|
162
|
+
return {
|
|
163
|
+
valid: errors.length === 0,
|
|
164
|
+
errors,
|
|
165
|
+
warnings,
|
|
166
|
+
files
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
module.exports = {
|
|
171
|
+
EMPTY_TESTS_SKIP,
|
|
172
|
+
validateRoleAssistantPackage,
|
|
173
|
+
validateEvidenceJsonFile,
|
|
174
|
+
validateKnowledgeMarkdown
|
|
175
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared assertion row helpers (pass/fail/warn/notes/skip).
|
|
3
|
+
* @fileoverview Kind flags for Role Assistant test result rows
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
function skipRow(id, message) {
|
|
9
|
+
return { id, passed: true, skip: true, kind: 'skip', message };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function notesRow(id, message) {
|
|
13
|
+
return { id, passed: true, notes: true, kind: 'notes', message };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function withKind(row) {
|
|
17
|
+
if (!row || row.kind) {
|
|
18
|
+
return row;
|
|
19
|
+
}
|
|
20
|
+
if (row.notes === true) {
|
|
21
|
+
return { ...row, kind: 'notes' };
|
|
22
|
+
}
|
|
23
|
+
if (row.skip === true) {
|
|
24
|
+
return { ...row, kind: 'skip' };
|
|
25
|
+
}
|
|
26
|
+
if (row.warn === true) {
|
|
27
|
+
return { ...row, kind: 'warn' };
|
|
28
|
+
}
|
|
29
|
+
return { ...row, kind: row.passed ? 'pass' : 'fail' };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = {
|
|
33
|
+
skipRow,
|
|
34
|
+
notesRow,
|
|
35
|
+
withKind
|
|
36
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bind a Work Hub execution to the Role Assistant named on copy.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Fail closed on mismatch; trust the CLI role when identity is absent
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
bareRoleKey,
|
|
11
|
+
roleAssistantSystemKey
|
|
12
|
+
} = require('../utils/role-assistant-paths');
|
|
13
|
+
|
|
14
|
+
const PLACEHOLDER = new Set(['', 'unknown', 'none', 'null']);
|
|
15
|
+
|
|
16
|
+
function throwCopyStatus(message, status) {
|
|
17
|
+
const err = new Error(message);
|
|
18
|
+
err.status = status;
|
|
19
|
+
throw err;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function usableIdentity(value) {
|
|
23
|
+
const token = String(value || '').trim();
|
|
24
|
+
if (!token || PLACEHOLDER.has(token.toLowerCase())) {
|
|
25
|
+
return '';
|
|
26
|
+
}
|
|
27
|
+
return token;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function pushIdentity(acc, value) {
|
|
31
|
+
const token = usableIdentity(value);
|
|
32
|
+
if (token) {
|
|
33
|
+
acc.push(token);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function boundIdentityTokens(status, result) {
|
|
38
|
+
const acc = [];
|
|
39
|
+
const task = result && result.task && typeof result.task === 'object' ? result.task : {};
|
|
40
|
+
pushIdentity(acc, status && status.assistantKey);
|
|
41
|
+
pushIdentity(acc, status && status.digitalWorkerKey);
|
|
42
|
+
pushIdentity(acc, result && result.assistantKey);
|
|
43
|
+
pushIdentity(acc, result && result.digitalWorkerKey);
|
|
44
|
+
pushIdentity(acc, task.assistantKey);
|
|
45
|
+
pushIdentity(acc, task.digitalWorkerKey);
|
|
46
|
+
pushIdentity(acc, task.activeBusinessRoleRef);
|
|
47
|
+
pushIdentity(acc, task.roleKey);
|
|
48
|
+
return [...new Set(acc)];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function identityMatchesSystem(token, systemKey) {
|
|
52
|
+
const expectedSystem = roleAssistantSystemKey(systemKey);
|
|
53
|
+
const expectedBare = bareRoleKey(systemKey).toLowerCase();
|
|
54
|
+
const lower = token.toLowerCase();
|
|
55
|
+
if (lower === expectedSystem.toLowerCase()) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return bareRoleKey(token).toLowerCase() === expectedBare;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function assertCopyBoundToSystem(systemKey, status, result) {
|
|
62
|
+
const tokens = boundIdentityTokens(status, result);
|
|
63
|
+
if (tokens.length === 0) {
|
|
64
|
+
return { bound: false };
|
|
65
|
+
}
|
|
66
|
+
const mismatch = tokens.find((token) => !identityMatchesSystem(token, systemKey));
|
|
67
|
+
if (mismatch) {
|
|
68
|
+
throwCopyStatus('Execution belongs to a different Role Assistant', 409);
|
|
69
|
+
}
|
|
70
|
+
return { bound: true };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = {
|
|
74
|
+
throwCopyStatus,
|
|
75
|
+
boundIdentityTokens,
|
|
76
|
+
assertCopyBoundToSystem
|
|
77
|
+
};
|