@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
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse optional YAML frontmatter from Role Assistant knowledge markdown.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview knowledge-markdown-frontmatter
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const yaml = require('js-yaml');
|
|
12
|
+
|
|
13
|
+
const SEARCH_META_KEYS = [
|
|
14
|
+
'aspect',
|
|
15
|
+
'knowledgeType',
|
|
16
|
+
'knowledgeKey',
|
|
17
|
+
'title',
|
|
18
|
+
'resourceType',
|
|
19
|
+
'roleKey'
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Split markdown into optional YAML frontmatter and body.
|
|
24
|
+
* @param {string} content
|
|
25
|
+
* @returns {{ frontmatter: Object|null, body: string }}
|
|
26
|
+
*/
|
|
27
|
+
function splitMarkdownFrontmatter(content) {
|
|
28
|
+
const text = typeof content === 'string' ? content : '';
|
|
29
|
+
if (!text.startsWith('---')) {
|
|
30
|
+
return { frontmatter: null, body: text };
|
|
31
|
+
}
|
|
32
|
+
const end = text.indexOf('\n---', 3);
|
|
33
|
+
if (end < 0) {
|
|
34
|
+
return { frontmatter: null, body: text };
|
|
35
|
+
}
|
|
36
|
+
const raw = text.slice(3, end).trim();
|
|
37
|
+
const body = text.slice(end + 4).replace(/^(?:\r?\n)+/, '');
|
|
38
|
+
if (!raw) {
|
|
39
|
+
return { frontmatter: {}, body };
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const parsed = yaml.load(raw);
|
|
43
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
44
|
+
return { frontmatter: null, body: text };
|
|
45
|
+
}
|
|
46
|
+
return { frontmatter: parsed, body };
|
|
47
|
+
} catch (_error) {
|
|
48
|
+
return { frontmatter: null, body: text };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Project searchable metadata fields from frontmatter.
|
|
54
|
+
* @param {Object|null|undefined} frontmatter
|
|
55
|
+
* @returns {Object}
|
|
56
|
+
*/
|
|
57
|
+
function knowledgeSearchMetadataFromFrontmatter(frontmatter) {
|
|
58
|
+
const out = {};
|
|
59
|
+
if (!frontmatter || typeof frontmatter !== 'object') {
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
for (const key of SEARCH_META_KEYS) {
|
|
63
|
+
const value = frontmatter[key];
|
|
64
|
+
if (typeof value === 'string' && value.trim()) {
|
|
65
|
+
out[key] = value.trim();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = {
|
|
72
|
+
SEARCH_META_KEYS,
|
|
73
|
+
splitMarkdownFrontmatter,
|
|
74
|
+
knowledgeSearchMetadataFromFrontmatter
|
|
75
|
+
};
|
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role Assistant knowledge import/export for document storage datasources.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Sync local role-assistant knowledge/*.md with dataplane document storage
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const crypto = require('crypto');
|
|
13
|
+
const fs = require('../internal/fs-real-sync');
|
|
14
|
+
const yaml = require('js-yaml');
|
|
15
|
+
const logger = require('../utils/logger');
|
|
16
|
+
const { formatSuccessLine, formatWarningLine, metadata } = require('../utils/cli-test-layout-chalk');
|
|
17
|
+
const { listDocuments, validateDocuments, bulkDocuments } = require('../api/datasources-extended.api');
|
|
18
|
+
const {
|
|
19
|
+
extractDocumentStorageKeyFromAssistantDetails,
|
|
20
|
+
getAssistantDetails,
|
|
21
|
+
updateAssistantSettings
|
|
22
|
+
} = require('../api/assistants.api');
|
|
23
|
+
const { resolveExternalSystemPath } = require('../utils/app-path-resolve');
|
|
24
|
+
const {
|
|
25
|
+
SYSTEM_KIND_DIGITAL_WORKER,
|
|
26
|
+
getRoleAssistantYamlPath,
|
|
27
|
+
readRoleAssistantSettings,
|
|
28
|
+
resolveDocumentStorageKeyFromRoleAssistantSettings,
|
|
29
|
+
resolveRoleAssistantEnvironmentSettings
|
|
30
|
+
} = require('./settings');
|
|
31
|
+
const {
|
|
32
|
+
knowledgeSearchMetadataFromFrontmatter,
|
|
33
|
+
splitMarkdownFrontmatter
|
|
34
|
+
} = require('./knowledge-markdown-frontmatter');
|
|
35
|
+
|
|
36
|
+
function resolveSystemNode(input) {
|
|
37
|
+
if (!input || typeof input !== 'object') {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return input.system || input.application || null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isDigitalWorkerModel(input) {
|
|
44
|
+
const systemNode = resolveSystemNode(input);
|
|
45
|
+
if (!systemNode || typeof systemNode.systemKind !== 'string') {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return systemNode.systemKind.trim() === SYSTEM_KIND_DIGITAL_WORKER;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function resolveDatasourceKeyFromCollection(dataSources) {
|
|
52
|
+
if (!Array.isArray(dataSources)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
for (const row of dataSources) {
|
|
56
|
+
if (!row || typeof row !== 'object') {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (String(row.entityType || '').trim() !== 'documentStorage') {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const candidate = String(row.key || row.datasourceKey || '').trim();
|
|
63
|
+
if (candidate) {
|
|
64
|
+
return candidate;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function resolveDocumentStorageKeyFromDataplane(dataplaneUrl, authConfig, systemKey) {
|
|
71
|
+
if (!dataplaneUrl || !authConfig || !systemKey) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const response = await getAssistantDetails(dataplaneUrl, systemKey, authConfig);
|
|
76
|
+
return extractDocumentStorageKeyFromAssistantDetails(response);
|
|
77
|
+
} catch (_error) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Push role-assistant.yaml knowledge.documentStorageKey to dataplane Assistants settings.
|
|
84
|
+
* Called on upload/deploy so the operator UI and CLI stay aligned.
|
|
85
|
+
*/
|
|
86
|
+
async function pushRoleAssistantDocumentStorageSettings(params) {
|
|
87
|
+
const {
|
|
88
|
+
systemKey,
|
|
89
|
+
dataplaneUrl,
|
|
90
|
+
authConfig,
|
|
91
|
+
environment = 'dev',
|
|
92
|
+
pathOptions = {},
|
|
93
|
+
dryRun = false
|
|
94
|
+
} = params;
|
|
95
|
+
const settingsEnv = resolveRoleAssistantSettingsEnvKey(environment);
|
|
96
|
+
const settings = readRoleAssistantSettings(systemKey, { required: false, pathOptions });
|
|
97
|
+
if (!settings) {
|
|
98
|
+
return { skipped: true, reason: 'missing-role-assistant-settings' };
|
|
99
|
+
}
|
|
100
|
+
const section = resolveRoleAssistantEnvironmentSettings(settings, settingsEnv, {
|
|
101
|
+
required: false
|
|
102
|
+
});
|
|
103
|
+
if (!section) {
|
|
104
|
+
return { skipped: true, reason: 'missing-env-settings' };
|
|
105
|
+
}
|
|
106
|
+
const documentStorageKey =
|
|
107
|
+
resolveDocumentStorageKeyFromRoleAssistantSettings(settings, settingsEnv) || '';
|
|
108
|
+
if (dryRun) {
|
|
109
|
+
return {
|
|
110
|
+
skipped: false,
|
|
111
|
+
dryRun: true,
|
|
112
|
+
documentStorageKey: documentStorageKey || null
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (documentStorageKey === '') {
|
|
116
|
+
// No Knowledge binding in role-assistant.yaml — skip Assistants settings write.
|
|
117
|
+
// Draft / not-yet-catalogued digital workers would 404 on PATCH otherwise.
|
|
118
|
+
return {
|
|
119
|
+
skipped: true,
|
|
120
|
+
reason: 'no-document-storage-key',
|
|
121
|
+
documentStorageKey: null
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
if (!dataplaneUrl || !authConfig) {
|
|
125
|
+
return { skipped: true, reason: 'missing-dataplane-auth' };
|
|
126
|
+
}
|
|
127
|
+
const response = await updateAssistantSettings(dataplaneUrl, systemKey, authConfig, {
|
|
128
|
+
documentStorageKey
|
|
129
|
+
});
|
|
130
|
+
if (response && response.success === false) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
response.formattedError ||
|
|
133
|
+
response.error ||
|
|
134
|
+
'Failed to update Knowledge document storage settings'
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
skipped: false,
|
|
139
|
+
documentStorageKey: documentStorageKey || null
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Resolve Knowledge document storage key.
|
|
145
|
+
* Order: role-assistant.yaml → dataplane Assistants settings → package dataSources.
|
|
146
|
+
*/
|
|
147
|
+
async function resolveRoleAssistantDocumentStorageKey({
|
|
148
|
+
systemKey,
|
|
149
|
+
model,
|
|
150
|
+
environment,
|
|
151
|
+
pathOptions,
|
|
152
|
+
dataplaneUrl,
|
|
153
|
+
authConfig
|
|
154
|
+
}) {
|
|
155
|
+
const settingsEnv = resolveRoleAssistantSettingsEnvKey(environment);
|
|
156
|
+
const settings = readRoleAssistantSettings(systemKey, { required: false, pathOptions });
|
|
157
|
+
const settingsKey = resolveDocumentStorageKeyFromRoleAssistantSettings(settings, settingsEnv);
|
|
158
|
+
if (settingsKey) {
|
|
159
|
+
return settingsKey;
|
|
160
|
+
}
|
|
161
|
+
const fromApi = await resolveDocumentStorageKeyFromDataplane(
|
|
162
|
+
dataplaneUrl,
|
|
163
|
+
authConfig,
|
|
164
|
+
systemKey
|
|
165
|
+
);
|
|
166
|
+
if (fromApi) {
|
|
167
|
+
return fromApi;
|
|
168
|
+
}
|
|
169
|
+
return resolveDatasourceKeyFromCollection(model && model.dataSources);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function collectKnowledgeMarkdownFiles(dirPath) {
|
|
173
|
+
if (!fs.existsSync(dirPath)) {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
177
|
+
const files = [];
|
|
178
|
+
for (const entry of entries) {
|
|
179
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
180
|
+
if (entry.isDirectory()) {
|
|
181
|
+
files.push(...collectKnowledgeMarkdownFiles(fullPath));
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const lower = entry.name.toLowerCase();
|
|
185
|
+
if (lower.endsWith('.md') || lower.endsWith('.markdown')) {
|
|
186
|
+
files.push(fullPath);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return files;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function normalizeDocumentExternalId(knowledgeRoot, filePath) {
|
|
193
|
+
const relative = path.relative(knowledgeRoot, filePath).replace(/\\/g, '/');
|
|
194
|
+
return relative.replace(/\.(md|markdown)$/i, '');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function buildDocumentRecord(knowledgeRoot, filePath) {
|
|
198
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
199
|
+
const { frontmatter, body } = splitMarkdownFrontmatter(raw);
|
|
200
|
+
const searchMeta = knowledgeSearchMetadataFromFrontmatter(frontmatter);
|
|
201
|
+
const externalId = normalizeDocumentExternalId(knowledgeRoot, filePath);
|
|
202
|
+
const title =
|
|
203
|
+
(typeof searchMeta.title === 'string' && searchMeta.title) || path.basename(externalId);
|
|
204
|
+
const content = typeof body === 'string' ? body : raw;
|
|
205
|
+
const contentHash = crypto.createHash('sha256').update(content, 'utf8').digest('hex');
|
|
206
|
+
const metadata = {
|
|
207
|
+
externalId,
|
|
208
|
+
mimeType: 'text/markdown',
|
|
209
|
+
sourcePath: path.relative(knowledgeRoot, filePath).replace(/\\/g, '/'),
|
|
210
|
+
sourceType: 'role-assistant-markdown',
|
|
211
|
+
...searchMeta,
|
|
212
|
+
title
|
|
213
|
+
};
|
|
214
|
+
return {
|
|
215
|
+
key: externalId,
|
|
216
|
+
// Prefer sourcePath (*.md) so binary storage uses a known markdown extension
|
|
217
|
+
// instead of inventing ".guide" from path-like keys or titles.
|
|
218
|
+
name: metadata.sourcePath || `${externalId}.md`,
|
|
219
|
+
contentHash,
|
|
220
|
+
metadata,
|
|
221
|
+
binaryBase64: Buffer.from(content, 'utf8').toString('base64'),
|
|
222
|
+
// retained for export/debug consumers that still read flat fields
|
|
223
|
+
externalId,
|
|
224
|
+
title,
|
|
225
|
+
content
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function toDocumentValidatePayload(record) {
|
|
230
|
+
return {
|
|
231
|
+
key: record.key,
|
|
232
|
+
contentHash: record.contentHash,
|
|
233
|
+
metadata: record.metadata || {}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function toDocumentBulkPayload(record) {
|
|
238
|
+
return {
|
|
239
|
+
key: record.key,
|
|
240
|
+
name: record.name || record.title || record.key,
|
|
241
|
+
contentHash: record.contentHash,
|
|
242
|
+
metadata: record.metadata || {},
|
|
243
|
+
binaryBase64: record.binaryBase64
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function extractDocumentRows(payload) {
|
|
248
|
+
const candidates = [
|
|
249
|
+
payload?.data?.items,
|
|
250
|
+
payload?.data?.rows,
|
|
251
|
+
payload?.data,
|
|
252
|
+
payload?.items,
|
|
253
|
+
payload?.rows
|
|
254
|
+
];
|
|
255
|
+
for (const candidate of candidates) {
|
|
256
|
+
if (Array.isArray(candidate)) {
|
|
257
|
+
return candidate;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return [];
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function extractDocumentContent(row) {
|
|
264
|
+
const values = [row?.content, row?.text, row?.body, row?.markdown, row?.document];
|
|
265
|
+
for (const value of values) {
|
|
266
|
+
if (typeof value === 'string') {
|
|
267
|
+
return value;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return '';
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function resolveDocumentFileName(row, index) {
|
|
274
|
+
const seed = row?.externalId || row?.documentKey || row?.key || row?.id || row?.title || `doc-${index + 1}`;
|
|
275
|
+
const normalized = String(seed).trim().replace(/[^\w.-/]/g, '-').replace(/\/+/g, '/');
|
|
276
|
+
const filePath = normalized.endsWith('.md') ? normalized : `${normalized}.md`;
|
|
277
|
+
return filePath.startsWith('/') ? filePath.slice(1) : filePath;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function resolveRoleAssistantSettingsEnvKey(environment) {
|
|
281
|
+
const token = String(environment || '').trim().toLowerCase();
|
|
282
|
+
return token === 'dev' || token === 'tst' || token === 'pro' ? token : 'dev';
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function writeRoleAssistantSettingsFile(systemKey, docStorageKey, environment = 'dev', pathOptions = {}) {
|
|
286
|
+
const roleAssistantPath = resolveExternalSystemPath(systemKey, pathOptions);
|
|
287
|
+
const roleAssistantYamlPath = getRoleAssistantYamlPath(systemKey, { pathOptions });
|
|
288
|
+
if (fs.existsSync(roleAssistantYamlPath)) {
|
|
289
|
+
return roleAssistantYamlPath;
|
|
290
|
+
}
|
|
291
|
+
const envKey = resolveRoleAssistantSettingsEnvKey(environment);
|
|
292
|
+
fs.mkdirSync(roleAssistantPath, { recursive: true });
|
|
293
|
+
const payload = {
|
|
294
|
+
apiVersion: 'aifabrix.ai/v1',
|
|
295
|
+
version: '1.0.0',
|
|
296
|
+
kind: 'RoleAssistantSettings',
|
|
297
|
+
roleKey: systemKey,
|
|
298
|
+
[envKey]: {
|
|
299
|
+
knowledge: docStorageKey ? { documentStorageKey: docStorageKey } : {}
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
fs.writeFileSync(roleAssistantYamlPath, yaml.dump(payload, { lineWidth: -1 }), 'utf8');
|
|
303
|
+
return roleAssistantYamlPath;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
async function uploadRoleAssistantKnowledgeRecords(dataplaneUrl, datasourceKey, authConfig, records) {
|
|
307
|
+
const validateBody = records.map(toDocumentValidatePayload);
|
|
308
|
+
const validationResult = await validateDocuments(
|
|
309
|
+
dataplaneUrl,
|
|
310
|
+
datasourceKey,
|
|
311
|
+
authConfig,
|
|
312
|
+
validateBody
|
|
313
|
+
);
|
|
314
|
+
if (!validationResult || validationResult.success === false) {
|
|
315
|
+
throw new Error(validationResult?.formattedError || validationResult?.error || 'Knowledge validation failed');
|
|
316
|
+
}
|
|
317
|
+
const bulkBody = records.map(toDocumentBulkPayload);
|
|
318
|
+
const uploadResult = await bulkDocuments(dataplaneUrl, datasourceKey, authConfig, bulkBody);
|
|
319
|
+
if (!uploadResult || uploadResult.success === false) {
|
|
320
|
+
throw new Error(uploadResult?.formattedError || uploadResult?.error || 'Knowledge upload failed');
|
|
321
|
+
}
|
|
322
|
+
const payload = uploadResult.data && typeof uploadResult.data === 'object' ? uploadResult.data : uploadResult;
|
|
323
|
+
return Number(payload.inserted || payload.upserted || payload.recordsProcessed || bulkBody.length || 0);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async function importRoleAssistantKnowledge(params) {
|
|
327
|
+
const {
|
|
328
|
+
systemKey,
|
|
329
|
+
dataplaneUrl,
|
|
330
|
+
authConfig,
|
|
331
|
+
model,
|
|
332
|
+
environment = 'dev',
|
|
333
|
+
pathOptions = {},
|
|
334
|
+
dryRun = false
|
|
335
|
+
} = params;
|
|
336
|
+
if (!isDigitalWorkerModel(model)) {
|
|
337
|
+
return { skipped: true, reason: 'not-role-assistant' };
|
|
338
|
+
}
|
|
339
|
+
const datasourceKey = await resolveRoleAssistantDocumentStorageKey({
|
|
340
|
+
systemKey,
|
|
341
|
+
model,
|
|
342
|
+
environment,
|
|
343
|
+
pathOptions,
|
|
344
|
+
dataplaneUrl,
|
|
345
|
+
authConfig
|
|
346
|
+
});
|
|
347
|
+
if (!datasourceKey) {
|
|
348
|
+
return { skipped: true, reason: 'missing-document-storage-datasource' };
|
|
349
|
+
}
|
|
350
|
+
const appPath = resolveExternalSystemPath(systemKey, pathOptions);
|
|
351
|
+
const knowledgePath = path.join(appPath, 'knowledge');
|
|
352
|
+
const files = collectKnowledgeMarkdownFiles(knowledgePath);
|
|
353
|
+
const records = files.map((filePath) => buildDocumentRecord(knowledgePath, filePath));
|
|
354
|
+
if (records.length === 0) {
|
|
355
|
+
return { skipped: true, reason: 'no-knowledge-files', datasourceKey };
|
|
356
|
+
}
|
|
357
|
+
if (dryRun) {
|
|
358
|
+
return { skipped: false, dryRun: true, datasourceKey, fileCount: files.length, recordCount: records.length };
|
|
359
|
+
}
|
|
360
|
+
const uploaded = await uploadRoleAssistantKnowledgeRecords(
|
|
361
|
+
dataplaneUrl,
|
|
362
|
+
datasourceKey,
|
|
363
|
+
authConfig,
|
|
364
|
+
records
|
|
365
|
+
);
|
|
366
|
+
return {
|
|
367
|
+
skipped: false,
|
|
368
|
+
datasourceKey,
|
|
369
|
+
fileCount: files.length,
|
|
370
|
+
recordCount: records.length,
|
|
371
|
+
uploaded
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
async function exportRoleAssistantKnowledge(params) {
|
|
376
|
+
const { systemKey, dataplaneUrl, authConfig, manifest, environment = 'dev', pathOptions = {} } = params;
|
|
377
|
+
const model = { system: manifest?.application, dataSources: manifest?.dataSources || [] };
|
|
378
|
+
if (!isDigitalWorkerModel(model)) {
|
|
379
|
+
return { skipped: true, reason: 'not-role-assistant' };
|
|
380
|
+
}
|
|
381
|
+
const datasourceKey = await resolveRoleAssistantDocumentStorageKey({
|
|
382
|
+
systemKey,
|
|
383
|
+
model,
|
|
384
|
+
environment,
|
|
385
|
+
pathOptions,
|
|
386
|
+
dataplaneUrl,
|
|
387
|
+
authConfig
|
|
388
|
+
});
|
|
389
|
+
if (!datasourceKey) {
|
|
390
|
+
const settingsPath = writeRoleAssistantSettingsFile(systemKey, null, environment, pathOptions);
|
|
391
|
+
return { skipped: true, reason: 'missing-document-storage-datasource', settingsPath };
|
|
392
|
+
}
|
|
393
|
+
const appPath = resolveExternalSystemPath(systemKey, pathOptions);
|
|
394
|
+
const knowledgePath = path.join(appPath, 'knowledge');
|
|
395
|
+
fs.mkdirSync(knowledgePath, { recursive: true });
|
|
396
|
+
const response = await listDocuments(dataplaneUrl, datasourceKey, authConfig, { limit: 1000 });
|
|
397
|
+
if (!response || response.success === false) {
|
|
398
|
+
throw new Error(response?.formattedError || response?.error || 'Knowledge export failed');
|
|
399
|
+
}
|
|
400
|
+
const rows = extractDocumentRows(response);
|
|
401
|
+
rows.forEach((row, index) => {
|
|
402
|
+
const relativeFile = resolveDocumentFileName(row, index);
|
|
403
|
+
const fullPath = path.join(knowledgePath, relativeFile);
|
|
404
|
+
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
405
|
+
fs.writeFileSync(fullPath, `${extractDocumentContent(row)}\n`, 'utf8');
|
|
406
|
+
});
|
|
407
|
+
const settingsPath = writeRoleAssistantSettingsFile(systemKey, datasourceKey, environment, pathOptions);
|
|
408
|
+
return { skipped: false, datasourceKey, count: rows.length, knowledgePath, settingsPath };
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function logKnowledgeImportSummary(systemKey, result, options = {}) {
|
|
412
|
+
if (result.skipped) {
|
|
413
|
+
if (options.verbose === true) {
|
|
414
|
+
logger.log(metadata(`Knowledge sync skipped (${systemKey}): ${result.reason}`));
|
|
415
|
+
}
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
if (result.dryRun) {
|
|
419
|
+
logger.log(
|
|
420
|
+
formatWarningLine(
|
|
421
|
+
`Role assistant knowledge dry-run: ${result.fileCount} file(s), ${result.recordCount} record(s), datasource ${result.datasourceKey}`
|
|
422
|
+
)
|
|
423
|
+
);
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
logger.log(
|
|
427
|
+
formatSuccessLine(
|
|
428
|
+
`Role assistant knowledge synced (${result.datasourceKey}): ${result.recordCount} record(s) from ${result.fileCount} file(s).`
|
|
429
|
+
)
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function logDocumentStorageSettingsPushSummary(systemKey, result, options = {}) {
|
|
434
|
+
if (result.skipped) {
|
|
435
|
+
if (options.verbose === true) {
|
|
436
|
+
logger.log(
|
|
437
|
+
metadata(`Knowledge document storage settings skipped (${systemKey}): ${result.reason}`)
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (result.dryRun) {
|
|
443
|
+
logger.log(
|
|
444
|
+
formatWarningLine(
|
|
445
|
+
`Knowledge document storage settings dry-run (${systemKey}): ${
|
|
446
|
+
result.documentStorageKey || '(clear)'
|
|
447
|
+
}`
|
|
448
|
+
)
|
|
449
|
+
);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
logger.log(
|
|
453
|
+
formatSuccessLine(
|
|
454
|
+
`Knowledge document storage settings updated (${systemKey}): ${
|
|
455
|
+
result.documentStorageKey || '(cleared)'
|
|
456
|
+
}`
|
|
457
|
+
)
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
function logKnowledgeExportSummary(systemKey, result, options = {}) {
|
|
462
|
+
if (result.skipped) {
|
|
463
|
+
if (options.verbose === true) {
|
|
464
|
+
logger.log(metadata(`Knowledge export skipped (${systemKey}): ${result.reason}`));
|
|
465
|
+
}
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
logger.log(
|
|
469
|
+
formatSuccessLine(
|
|
470
|
+
`Role assistant knowledge exported (${result.datasourceKey}): ${result.count} document(s) to ${result.knowledgePath}.`
|
|
471
|
+
)
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
module.exports = {
|
|
476
|
+
isDigitalWorkerModel,
|
|
477
|
+
resolveRoleAssistantSettingsEnvKey,
|
|
478
|
+
resolveRoleAssistantDocumentStorageKey,
|
|
479
|
+
pushRoleAssistantDocumentStorageSettings,
|
|
480
|
+
importRoleAssistantKnowledge,
|
|
481
|
+
exportRoleAssistantKnowledge,
|
|
482
|
+
logKnowledgeImportSummary,
|
|
483
|
+
logDocumentStorageSettingsPushSummary,
|
|
484
|
+
logKnowledgeExportSummary
|
|
485
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role Assistant settings reader and validator.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview role-assistant.yaml parsing for digitalWorker packages
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const fs = require('../internal/fs-real-sync');
|
|
13
|
+
const yaml = require('js-yaml');
|
|
14
|
+
const { resolveExternalSystemPath } = require('../utils/app-path-resolve');
|
|
15
|
+
const { loadRoleAssistantSettingsSchema } = require('../utils/schema-loader');
|
|
16
|
+
const { SYSTEM_KIND_DIGITAL_WORKER } = require('../utils/role-assistant-paths');
|
|
17
|
+
|
|
18
|
+
function getRoleAssistantYamlPath(systemKey, options = {}) {
|
|
19
|
+
const appPath = resolveExternalSystemPath(systemKey, options.pathOptions || {});
|
|
20
|
+
const yamlPath = path.join(appPath, 'role-assistant.yaml');
|
|
21
|
+
if (fs.existsSync(yamlPath)) {
|
|
22
|
+
return yamlPath;
|
|
23
|
+
}
|
|
24
|
+
const ymlPath = path.join(appPath, 'role-assistant.yml');
|
|
25
|
+
if (fs.existsSync(ymlPath)) {
|
|
26
|
+
return ymlPath;
|
|
27
|
+
}
|
|
28
|
+
return yamlPath;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function isDigitalWorkerManifest(manifest) {
|
|
32
|
+
return Boolean(
|
|
33
|
+
manifest &&
|
|
34
|
+
manifest.system &&
|
|
35
|
+
typeof manifest.system.systemKind === 'string' &&
|
|
36
|
+
manifest.system.systemKind.trim() === SYSTEM_KIND_DIGITAL_WORKER
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function parseRoleAssistantYaml(roleAssistantPath) {
|
|
41
|
+
const content = fs.readFileSync(roleAssistantPath, 'utf8');
|
|
42
|
+
const parsed = yaml.load(content);
|
|
43
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
44
|
+
throw new Error(`Invalid role-assistant.yaml content: ${roleAssistantPath}`);
|
|
45
|
+
}
|
|
46
|
+
return parsed;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function formatAjvErrors(errors) {
|
|
50
|
+
if (!Array.isArray(errors) || errors.length === 0) {
|
|
51
|
+
return ['role-assistant.yaml schema validation failed'];
|
|
52
|
+
}
|
|
53
|
+
return errors.map((item) => {
|
|
54
|
+
const location = item.instancePath || '(root)';
|
|
55
|
+
return `${location} ${item.message}`;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function validateRoleAssistantSettings(settings, roleAssistantPath) {
|
|
60
|
+
const validate = loadRoleAssistantSettingsSchema();
|
|
61
|
+
const valid = validate(settings);
|
|
62
|
+
if (!valid) {
|
|
63
|
+
const lines = formatAjvErrors(validate.errors).join('; ');
|
|
64
|
+
throw new Error(`Invalid role-assistant.yaml (${roleAssistantPath}): ${lines}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function readRoleAssistantSettings(systemKey, options = {}) {
|
|
69
|
+
const filePath = getRoleAssistantYamlPath(systemKey, options);
|
|
70
|
+
if (!fs.existsSync(filePath)) {
|
|
71
|
+
if (options.required === true) {
|
|
72
|
+
throw new Error(`Missing required role-assistant.yaml: ${filePath}`);
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const settings = parseRoleAssistantYaml(filePath);
|
|
77
|
+
validateRoleAssistantSettings(settings, filePath);
|
|
78
|
+
return settings;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function resolveRoleAssistantEnvironmentSettings(settings, envName, options = {}) {
|
|
82
|
+
if (!settings || typeof settings !== 'object') {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const env = String(envName || '').trim() || 'dev';
|
|
86
|
+
const section = settings[env];
|
|
87
|
+
if (!section) {
|
|
88
|
+
if (options.required !== false) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`role-assistant.yaml is missing "${env}" section. Add "${env}" with runtime/debug/knowledge settings.`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return section;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function resolveDocumentStorageKeyFromRoleAssistantSettings(settings, envName) {
|
|
99
|
+
const section = resolveRoleAssistantEnvironmentSettings(settings, envName, { required: false });
|
|
100
|
+
const key = section && section.knowledge && section.knowledge.documentStorageKey;
|
|
101
|
+
if (typeof key !== 'string' || !key.trim()) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
return key.trim();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function resolveRoleAssistantSettingsVersion(settings) {
|
|
108
|
+
if (!settings || typeof settings !== 'object') {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
const value = settings.version;
|
|
112
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
return value.trim();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
module.exports = {
|
|
119
|
+
SYSTEM_KIND_DIGITAL_WORKER,
|
|
120
|
+
getRoleAssistantYamlPath,
|
|
121
|
+
isDigitalWorkerManifest,
|
|
122
|
+
readRoleAssistantSettings,
|
|
123
|
+
resolveRoleAssistantEnvironmentSettings,
|
|
124
|
+
resolveDocumentStorageKeyFromRoleAssistantSettings,
|
|
125
|
+
resolveRoleAssistantSettingsVersion
|
|
126
|
+
};
|