@forestadmin/workflow-executor 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +141 -0
- package/dist/adapters/activity-log-drainer.d.ts +6 -0
- package/dist/adapters/activity-log-drainer.js +21 -0
- package/dist/adapters/agent-client-agent-port.d.ts +27 -0
- package/dist/adapters/agent-client-agent-port.js +211 -0
- package/dist/adapters/ai-client-adapter.d.ts +11 -0
- package/dist/adapters/ai-client-adapter.js +38 -0
- package/dist/adapters/always-error-ai-model-port.d.ts +8 -0
- package/dist/adapters/always-error-ai-model-port.js +23 -0
- package/dist/adapters/console-logger.d.ts +7 -0
- package/dist/adapters/console-logger.js +15 -0
- package/dist/adapters/forest-server-workflow-port.d.ts +25 -0
- package/dist/adapters/forest-server-workflow-port.js +163 -0
- package/dist/adapters/forestadmin-client-activity-log-port-factory.d.ts +12 -0
- package/dist/adapters/forestadmin-client-activity-log-port-factory.js +22 -0
- package/dist/adapters/forestadmin-client-activity-log-port.d.ts +15 -0
- package/dist/adapters/forestadmin-client-activity-log-port.js +78 -0
- package/dist/adapters/pretty-logger.d.ts +9 -0
- package/dist/adapters/pretty-logger.js +37 -0
- package/dist/adapters/record-id-serializer.d.ts +4 -0
- package/dist/adapters/record-id-serializer.js +20 -0
- package/dist/adapters/run-to-available-step-mapper.d.ts +4 -0
- package/dist/adapters/run-to-available-step-mapper.js +137 -0
- package/dist/adapters/server-ai-adapter.d.ts +16 -0
- package/dist/adapters/server-ai-adapter.js +60 -0
- package/dist/adapters/server-types.d.ts +181 -0
- package/dist/adapters/server-types.js +35 -0
- package/dist/adapters/step-definition-mapper.d.ts +4 -0
- package/dist/adapters/step-definition-mapper.js +68 -0
- package/dist/adapters/step-outcome-to-update-step-mapper.d.ts +4 -0
- package/dist/adapters/step-outcome-to-update-step-mapper.js +34 -0
- package/dist/adapters/with-retry.d.ts +6 -0
- package/dist/adapters/with-retry.js +40 -0
- package/dist/build-workflow-executor.d.ts +35 -0
- package/dist/build-workflow-executor.js +175 -0
- package/dist/cli-core.d.ts +26 -0
- package/dist/cli-core.js +228 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +17 -0
- package/dist/defaults.d.ts +9 -0
- package/dist/defaults.js +12 -0
- package/dist/errors.d.ts +153 -0
- package/dist/errors.js +327 -0
- package/dist/executors/activity-log.d.ts +14 -0
- package/dist/executors/activity-log.js +33 -0
- package/dist/executors/agent-with-log.d.ts +33 -0
- package/dist/executors/agent-with-log.js +76 -0
- package/dist/executors/base-step-executor.d.ts +40 -0
- package/dist/executors/base-step-executor.js +267 -0
- package/dist/executors/condition-step-executor.d.ts +15 -0
- package/dist/executors/condition-step-executor.js +108 -0
- package/dist/executors/guidance-step-executor.d.ts +12 -0
- package/dist/executors/guidance-step-executor.js +39 -0
- package/dist/executors/load-related-record-step-executor.d.ts +38 -0
- package/dist/executors/load-related-record-step-executor.js +478 -0
- package/dist/executors/mcp-step-executor.d.ts +22 -0
- package/dist/executors/mcp-step-executor.js +188 -0
- package/dist/executors/read-record-step-executor.d.ts +10 -0
- package/dist/executors/read-record-step-executor.js +100 -0
- package/dist/executors/record-step-executor.d.ts +19 -0
- package/dist/executors/record-step-executor.js +108 -0
- package/dist/executors/step-executor-factory.d.ts +24 -0
- package/dist/executors/step-executor-factory.js +99 -0
- package/dist/executors/summary/step-execution-formatters.d.ts +8 -0
- package/dist/executors/summary/step-execution-formatters.js +49 -0
- package/dist/executors/summary/step-summary-builder.d.ts +7 -0
- package/dist/executors/summary/step-summary-builder.js +52 -0
- package/dist/executors/trigger-record-action-step-executor.d.ts +17 -0
- package/dist/executors/trigger-record-action-step-executor.js +169 -0
- package/dist/executors/update-record-step-executor.d.ts +13 -0
- package/dist/executors/update-record-step-executor.js +245 -0
- package/dist/http/executor-http-server.d.ts +25 -0
- package/dist/http/executor-http-server.js +170 -0
- package/dist/http/pending-data-validators.d.ts +25 -0
- package/dist/http/pending-data-validators.js +79 -0
- package/dist/http/step-serializer.d.ts +3 -0
- package/dist/http/step-serializer.js +47 -0
- package/dist/in-flight-run-registry.d.ts +9 -0
- package/dist/in-flight-run-registry.js +30 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +88 -0
- package/dist/ports/activity-log-port.d.ts +24 -0
- package/dist/ports/activity-log-port.js +3 -0
- package/dist/ports/agent-port.d.ts +54 -0
- package/dist/ports/agent-port.js +3 -0
- package/dist/ports/ai-model-port.d.ts +7 -0
- package/dist/ports/ai-model-port.js +3 -0
- package/dist/ports/logger-port.d.ts +6 -0
- package/dist/ports/logger-port.js +3 -0
- package/dist/ports/run-store.d.ts +9 -0
- package/dist/ports/run-store.js +3 -0
- package/dist/ports/workflow-port.d.ts +30 -0
- package/dist/ports/workflow-port.js +3 -0
- package/dist/remote-tool-fetcher.d.ts +19 -0
- package/dist/remote-tool-fetcher.js +56 -0
- package/dist/runner.d.ts +50 -0
- package/dist/runner.js +317 -0
- package/dist/schema-cache.d.ts +11 -0
- package/dist/schema-cache.js +37 -0
- package/dist/schema-resolver.d.ts +11 -0
- package/dist/schema-resolver.js +24 -0
- package/dist/stores/build-run-store.d.ts +5 -0
- package/dist/stores/build-run-store.js +28 -0
- package/dist/stores/database-store.d.ts +17 -0
- package/dist/stores/database-store.js +119 -0
- package/dist/stores/in-memory-store.d.ts +11 -0
- package/dist/stores/in-memory-store.js +48 -0
- package/dist/types/execution-context.d.ts +37 -0
- package/dist/types/execution-context.js +3 -0
- package/dist/types/step-execution-data.d.ts +137 -0
- package/dist/types/step-execution-data.js +3 -0
- package/dist/types/validated/collection.d.ts +126 -0
- package/dist/types/validated/collection.js +96 -0
- package/dist/types/validated/execution.d.ts +362 -0
- package/dist/types/validated/execution.js +43 -0
- package/dist/types/validated/step-definition.d.ts +243 -0
- package/dist/types/validated/step-definition.js +128 -0
- package/dist/types/validated/step-outcome.d.ts +108 -0
- package/dist/types/validated/step-outcome.js +66 -0
- package/dist/validate-secrets.d.ts +5 -0
- package/dist/validate-secrets.js +14 -0
- package/package.json +50 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const forestadmin_client_1 = require("@forestadmin/forestadmin-client");
|
|
7
|
+
const zod_1 = require("zod");
|
|
8
|
+
const console_logger_1 = __importDefault(require("./console-logger"));
|
|
9
|
+
const run_to_available_step_mapper_1 = __importDefault(require("./run-to-available-step-mapper"));
|
|
10
|
+
const step_outcome_to_update_step_mapper_1 = __importDefault(require("./step-outcome-to-update-step-mapper"));
|
|
11
|
+
const with_retry_1 = __importDefault(require("./with-retry"));
|
|
12
|
+
const errors_1 = require("../errors");
|
|
13
|
+
const collection_1 = require("../types/validated/collection");
|
|
14
|
+
const ROUTES = {
|
|
15
|
+
pendingRuns: '/api/workflow-orchestrator/pending-run',
|
|
16
|
+
availableRun: (runId) => `/api/workflow-orchestrator/available-run/${encodeURIComponent(runId)}`,
|
|
17
|
+
updateStep: '/api/workflow-orchestrator/update-step',
|
|
18
|
+
collectionSchema: (collectionName, runId) => `/api/workflow-orchestrator/collection-schema/${encodeURIComponent(collectionName)}?runId=${encodeURIComponent(runId)}`,
|
|
19
|
+
accessCheck: (runId, userId) => `/api/workflow-orchestrator/run/${encodeURIComponent(runId)}/access-check?userId=${userId}`,
|
|
20
|
+
mcpServerConfigs: '/liana/mcp-server-configs-with-details',
|
|
21
|
+
};
|
|
22
|
+
// Forest sends relatedCollectionName as a `collection.targetKey` reference (e.g. "store.id");
|
|
23
|
+
// normalize it to a plain collection name (the related PK comes from the schema's primaryKeyFields).
|
|
24
|
+
function stripReferenceKey(name) {
|
|
25
|
+
return name?.includes('.') ? name.slice(0, name.lastIndexOf('.')) : name;
|
|
26
|
+
}
|
|
27
|
+
class ForestServerWorkflowPort {
|
|
28
|
+
constructor(params) {
|
|
29
|
+
this.options = { envSecret: params.envSecret, forestServerUrl: params.forestServerUrl };
|
|
30
|
+
this.logger = params.logger ?? new console_logger_1.default();
|
|
31
|
+
}
|
|
32
|
+
async getAvailableRuns() {
|
|
33
|
+
const runs = await this.callPort('getAvailableRuns', () => forestadmin_client_1.ServerUtils.query(this.options, 'get', ROUTES.pendingRuns));
|
|
34
|
+
const pending = [];
|
|
35
|
+
const malformed = [];
|
|
36
|
+
for (const run of runs) {
|
|
37
|
+
try {
|
|
38
|
+
const dispatch = this.toDispatch(run);
|
|
39
|
+
if (dispatch)
|
|
40
|
+
pending.push(dispatch);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof errors_1.WorkflowExecutorError) {
|
|
44
|
+
malformed.push(this.toMalformedInfo(run, error));
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
this.logger.error('Failed to hydrate pending run — unexpected error', {
|
|
48
|
+
runId: run.id,
|
|
49
|
+
error: (0, errors_1.extractErrorMessage)(error),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { pending, malformed };
|
|
55
|
+
}
|
|
56
|
+
async getAvailableRun(runId) {
|
|
57
|
+
const run = await this.callPort('getAvailableRun', () => forestadmin_client_1.ServerUtils.query(this.options, 'get', ROUTES.availableRun(runId)));
|
|
58
|
+
if (!run)
|
|
59
|
+
return null;
|
|
60
|
+
try {
|
|
61
|
+
return this.toDispatch(run);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (error instanceof errors_1.WorkflowExecutorError) {
|
|
65
|
+
throw new errors_1.MalformedRunError(this.toMalformedInfo(run, error));
|
|
66
|
+
}
|
|
67
|
+
/* istanbul ignore next — defensive fallback for unexpected non-domain errors */
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Validates userProfile + serverToken at the adapter boundary. Split into two checks so an
|
|
72
|
+
// operator can diagnose "userProfile missing" vs "serverToken missing" from the error alone.
|
|
73
|
+
toDispatch(run) {
|
|
74
|
+
if (!run.userProfile) {
|
|
75
|
+
throw new errors_1.InvalidStepDefinitionError(`Run ${run.id} is missing required field userProfile — ` +
|
|
76
|
+
`the orchestrator must include it in the run payload`);
|
|
77
|
+
}
|
|
78
|
+
const token = run.userProfile.serverToken;
|
|
79
|
+
if (typeof token !== 'string' || !token) {
|
|
80
|
+
throw new errors_1.InvalidStepDefinitionError(`Run ${run.id} userProfile is missing serverToken — ` +
|
|
81
|
+
`the orchestrator must include it in the run payload`);
|
|
82
|
+
}
|
|
83
|
+
const step = (0, run_to_available_step_mapper_1.default)(run);
|
|
84
|
+
if (!step)
|
|
85
|
+
return null;
|
|
86
|
+
return { step, auth: { forestServerToken: token } };
|
|
87
|
+
}
|
|
88
|
+
toMalformedInfo(run, err) {
|
|
89
|
+
const pending = run.workflowHistory.at(-1) ?? null;
|
|
90
|
+
return {
|
|
91
|
+
runId: String(run.id),
|
|
92
|
+
stepId: pending?.stepName ?? null,
|
|
93
|
+
stepIndex: pending?.stepIndex ?? null,
|
|
94
|
+
userMessage: err.userMessage,
|
|
95
|
+
technicalMessage: err.message,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
async updateStepExecution(runId, stepOutcome) {
|
|
99
|
+
return this.callPort('updateStepExecution', async () => {
|
|
100
|
+
const body = (0, step_outcome_to_update_step_mapper_1.default)(runId, stepOutcome);
|
|
101
|
+
const run = await forestadmin_client_1.ServerUtils.query(this.options, 'post', ROUTES.updateStep, {}, body);
|
|
102
|
+
if (!run)
|
|
103
|
+
return null;
|
|
104
|
+
try {
|
|
105
|
+
return this.toDispatch(run);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
// The outcome was recorded server-side; only the chain parse failed. Fall back to the
|
|
109
|
+
// next poll cycle — don't let a malformed chain response mask the successful update.
|
|
110
|
+
this.logger.error('Failed to parse chained next step from /update-step response', {
|
|
111
|
+
runId: String(run.id),
|
|
112
|
+
error: (0, errors_1.extractErrorMessage)(error),
|
|
113
|
+
});
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}, { retry: true });
|
|
117
|
+
}
|
|
118
|
+
async getCollectionSchema(collectionName, runId) {
|
|
119
|
+
return this.callPort('getCollectionSchema', async () => {
|
|
120
|
+
const response = await forestadmin_client_1.ServerUtils.query(this.options, 'get', ROUTES.collectionSchema(collectionName, runId));
|
|
121
|
+
try {
|
|
122
|
+
const schema = collection_1.CollectionSchemaSchema.parse(response);
|
|
123
|
+
return {
|
|
124
|
+
...schema,
|
|
125
|
+
fields: schema.fields.map(field => ({
|
|
126
|
+
...field,
|
|
127
|
+
relatedCollectionName: stripReferenceKey(field.relatedCollectionName),
|
|
128
|
+
})),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
if (err instanceof zod_1.z.ZodError) {
|
|
133
|
+
// runId is passed for observability — the schema call is scoped to a run.
|
|
134
|
+
throw new errors_1.DomainValidationError(Number(runId) || 0, err);
|
|
135
|
+
}
|
|
136
|
+
/* istanbul ignore next — zod.parse only throws ZodError; defensive fallback */
|
|
137
|
+
throw err;
|
|
138
|
+
}
|
|
139
|
+
}, { retry: true });
|
|
140
|
+
}
|
|
141
|
+
async getMcpServerConfigs() {
|
|
142
|
+
return this.callPort('getMcpServerConfigs', () => forestadmin_client_1.ServerUtils.query(this.options, 'get', ROUTES.mcpServerConfigs), { retry: true });
|
|
143
|
+
}
|
|
144
|
+
async hasRunAccess(runId, user) {
|
|
145
|
+
return this.callPort('hasRunAccess', async () => {
|
|
146
|
+
const { hasAccess } = await forestadmin_client_1.ServerUtils.query(this.options, 'get', ROUTES.accessCheck(runId, user.id));
|
|
147
|
+
return hasAccess === true;
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
async callPort(operation, fn, options) {
|
|
151
|
+
const run = options?.retry ? () => (0, with_retry_1.default)(operation, fn, { logger: this.logger }) : fn;
|
|
152
|
+
try {
|
|
153
|
+
return await run();
|
|
154
|
+
}
|
|
155
|
+
catch (cause) {
|
|
156
|
+
if (cause instanceof errors_1.WorkflowExecutorError)
|
|
157
|
+
throw cause;
|
|
158
|
+
throw new errors_1.WorkflowPortError(operation, cause);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.default = ForestServerWorkflowPort;
|
|
163
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZXN0LXNlcnZlci13b3JrZmxvdy1wb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXJzL2ZvcmVzdC1zZXJ2ZXItd29ya2Zsb3ctcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQWNBLHdFQUE4RDtBQUM5RCw2QkFBd0I7QUFFeEIsc0VBQTZDO0FBQzdDLGtHQUFzRTtBQUN0RSw4R0FBdUU7QUFDdkUsOERBQXFDO0FBQ3JDLHNDQU9tQjtBQUNuQiw4REFBdUU7QUFFdkUsTUFBTSxNQUFNLEdBQUc7SUFDYixXQUFXLEVBQUUsd0NBQXdDO0lBQ3JELFlBQVksRUFBRSxDQUFDLEtBQWEsRUFBRSxFQUFFLENBQzlCLDRDQUE0QyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsRUFBRTtJQUN6RSxVQUFVLEVBQUUsd0NBQXdDO0lBQ3BELGdCQUFnQixFQUFFLENBQUMsY0FBc0IsRUFBRSxLQUFhLEVBQUUsRUFBRSxDQUMxRCxnREFBZ0Qsa0JBQWtCLENBQ2hFLGNBQWMsQ0FDZixVQUFVLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxFQUFFO0lBQ3hDLFdBQVcsRUFBRSxDQUFDLEtBQWEsRUFBRSxNQUFjLEVBQUUsRUFBRSxDQUM3QyxrQ0FBa0Msa0JBQWtCLENBQUMsS0FBSyxDQUFDLHdCQUF3QixNQUFNLEVBQUU7SUFDN0YsZ0JBQWdCLEVBQUUsd0NBQXdDO0NBQzNELENBQUM7QUFFRiw4RkFBOEY7QUFDOUYscUdBQXFHO0FBQ3JHLFNBQVMsaUJBQWlCLENBQUMsSUFBd0I7SUFDakQsT0FBTyxJQUFJLEVBQUUsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUMzRSxDQUFDO0FBRUQsTUFBcUIsd0JBQXdCO0lBSTNDLFlBQVksTUFB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
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ActivityLogPort, ActivityLogPortFactory } from '../ports/activity-log-port';
|
|
2
|
+
import type { Logger } from '../ports/logger-port';
|
|
3
|
+
import type { ActivityLogsServiceInterface } from '@forestadmin/forestadmin-client';
|
|
4
|
+
export default class ForestadminClientActivityLogPortFactory implements ActivityLogPortFactory {
|
|
5
|
+
private readonly service;
|
|
6
|
+
private readonly logger;
|
|
7
|
+
private readonly drainer;
|
|
8
|
+
constructor(service: ActivityLogsServiceInterface, logger: Logger);
|
|
9
|
+
forRun(forestServerToken: string): ActivityLogPort;
|
|
10
|
+
drain(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=forestadmin-client-activity-log-port-factory.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const activity_log_drainer_1 = __importDefault(require("./activity-log-drainer"));
|
|
7
|
+
const forestadmin_client_activity_log_port_1 = __importDefault(require("./forestadmin-client-activity-log-port"));
|
|
8
|
+
class ForestadminClientActivityLogPortFactory {
|
|
9
|
+
constructor(service, logger) {
|
|
10
|
+
this.service = service;
|
|
11
|
+
this.logger = logger;
|
|
12
|
+
this.drainer = new activity_log_drainer_1.default();
|
|
13
|
+
}
|
|
14
|
+
forRun(forestServerToken) {
|
|
15
|
+
return new forestadmin_client_activity_log_port_1.default(this.service, this.logger, forestServerToken, this.drainer);
|
|
16
|
+
}
|
|
17
|
+
async drain() {
|
|
18
|
+
return this.drainer.drain();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.default = ForestadminClientActivityLogPortFactory;
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZXN0YWRtaW4tY2xpZW50LWFjdGl2aXR5LWxvZy1wb3J0LWZhY3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlcnMvZm9yZXN0YWRtaW4tY2xpZW50LWFjdGl2aXR5LWxvZy1wb3J0LWZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFJQSxrRkFBd0Q7QUFDeEQsa0hBQXNGO0FBRXRGLE1BQXFCLHVDQUF1QztJQUcxRCxZQUNtQixPQUFxQyxFQUNyQyxNQUFjO1FBRGQsWUFBTyxHQUFQLE9BQU8sQ0FBOEI7UUFDckMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUpoQixZQUFPLEdBQUcsSUFBSSw4QkFBa0IsRUFBRSxDQUFDO0lBS2pELENBQUM7SUFFSixNQUFNLENBQUMsaUJBQXlCO1FBQzlCLE9BQU8sSUFBSSw4Q0FBZ0MsQ0FDekMsSUFBSSxDQUFDLE9BQU8sRUFDWixJQUFJLENBQUMsTUFBTSxFQUNYLGlCQUFpQixFQUNqQixJQUFJLENBQUMsT0FBTyxDQUNiLENBQUM7SUFDSixDQUFDO0lBRUQsS0FBSyxDQUFDLEtBQUs7UUFDVCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDOUIsQ0FBQztDQUNGO0FBcEJELDBEQW9CQyJ9
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type ActivityLogDrainer from './activity-log-drainer';
|
|
2
|
+
import type { ActivityLogHandle, ActivityLogPort, CreateActivityLogArgs } from '../ports/activity-log-port';
|
|
3
|
+
import type { Logger } from '../ports/logger-port';
|
|
4
|
+
import type { ActivityLogsServiceInterface } from '@forestadmin/forestadmin-client';
|
|
5
|
+
export default class ForestadminClientActivityLogPort implements ActivityLogPort {
|
|
6
|
+
private readonly service;
|
|
7
|
+
private readonly logger;
|
|
8
|
+
private readonly forestServerToken;
|
|
9
|
+
private readonly drainer;
|
|
10
|
+
constructor(service: ActivityLogsServiceInterface, logger: Logger, forestServerToken: string, drainer: ActivityLogDrainer);
|
|
11
|
+
createPending(args: CreateActivityLogArgs): Promise<ActivityLogHandle>;
|
|
12
|
+
markSucceeded(handle: ActivityLogHandle): Promise<void>;
|
|
13
|
+
markFailed(handle: ActivityLogHandle): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=forestadmin-client-activity-log-port.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const record_id_serializer_1 = require("./record-id-serializer");
|
|
7
|
+
const with_retry_1 = __importDefault(require("./with-retry"));
|
|
8
|
+
const errors_1 = require("../errors");
|
|
9
|
+
class ForestadminClientActivityLogPort {
|
|
10
|
+
constructor(service, logger, forestServerToken, drainer) {
|
|
11
|
+
this.service = service;
|
|
12
|
+
this.logger = logger;
|
|
13
|
+
this.forestServerToken = forestServerToken;
|
|
14
|
+
this.drainer = drainer;
|
|
15
|
+
}
|
|
16
|
+
async createPending(args) {
|
|
17
|
+
try {
|
|
18
|
+
const response = await (0, with_retry_1.default)('activity log create', () => this.service.createActivityLog({
|
|
19
|
+
forestServerToken: this.forestServerToken,
|
|
20
|
+
renderingId: String(args.renderingId),
|
|
21
|
+
action: args.action,
|
|
22
|
+
type: args.type,
|
|
23
|
+
// The lib writes this value verbatim into relationships.collection.data.id
|
|
24
|
+
// (JSON:API). The Forest server audit-trail API expects the numeric collectionId.
|
|
25
|
+
collectionName: args.collectionId,
|
|
26
|
+
// Record ids are serialized to the pipe wire format here, never in the executor.
|
|
27
|
+
recordId: args.recordId?.length ? (0, record_id_serializer_1.serializeRecordId)(args.recordId) : undefined,
|
|
28
|
+
label: args.label,
|
|
29
|
+
}), { logger: this.logger });
|
|
30
|
+
return { id: response.id, index: response.attributes.index };
|
|
31
|
+
}
|
|
32
|
+
catch (cause) {
|
|
33
|
+
this.logger.error('activity log create failed', {
|
|
34
|
+
action: args.action,
|
|
35
|
+
collectionId: args.collectionId,
|
|
36
|
+
status: cause.status,
|
|
37
|
+
error: (0, errors_1.extractErrorMessage)(cause),
|
|
38
|
+
});
|
|
39
|
+
throw new errors_1.ActivityLogCreationError(cause);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async markSucceeded(handle) {
|
|
43
|
+
return this.drainer.track(async () => {
|
|
44
|
+
try {
|
|
45
|
+
await (0, with_retry_1.default)('activity log mark-as-completed', () => this.service.updateActivityLogStatus({
|
|
46
|
+
forestServerToken: this.forestServerToken,
|
|
47
|
+
activityLog: { id: handle.id, attributes: { index: handle.index } },
|
|
48
|
+
status: 'completed',
|
|
49
|
+
}), { logger: this.logger, extraRetryStatuses: [404] });
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
this.logger.error('activity log mark-as-completed failed', {
|
|
53
|
+
handleId: handle.id,
|
|
54
|
+
error: (0, errors_1.extractErrorMessage)(err),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
async markFailed(handle) {
|
|
60
|
+
return this.drainer.track(async () => {
|
|
61
|
+
try {
|
|
62
|
+
await (0, with_retry_1.default)('activity log mark-as-failed', () => this.service.updateActivityLogStatus({
|
|
63
|
+
forestServerToken: this.forestServerToken,
|
|
64
|
+
activityLog: { id: handle.id, attributes: { index: handle.index } },
|
|
65
|
+
status: 'failed',
|
|
66
|
+
}), { logger: this.logger, extraRetryStatuses: [404] });
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
this.logger.error('activity log mark-as-failed failed', {
|
|
70
|
+
handleId: handle.id,
|
|
71
|
+
error: (0, errors_1.extractErrorMessage)(err),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.default = ForestadminClientActivityLogPort;
|
|
78
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZXN0YWRtaW4tY2xpZW50LWFjdGl2aXR5LWxvZy1wb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXJzL2ZvcmVzdGFkbWluLWNsaWVudC1hY3Rpdml0eS1sb2ctcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVNBLGlFQUEyRDtBQUMzRCw4REFBcUM7QUFDckMsc0NBQTBFO0FBRTFFLE1BQXFCLGdDQUFnQztJQUNuRCxZQUNtQixPQUFxQyxFQUNyQyxNQUFjLEVBQ2QsaUJBQXlCLEVBQ3pCLE9BQTJCO1FBSDNCLFlBQU8sR0FBUCxPQUFPLENBQThCO1FBQ3JDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxzQkFBaUIsR0FBakIsaUJBQWlCLENBQVE7UUFDekIsWUFBTyxHQUFQLE9BQU8sQ0FBb0I7SUFDM0MsQ0FBQztJQUVKLEtBQUssQ0FBQyxhQUFhLENBQUMsSUFBMkI7UUFDN0MsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFBLG9CQUFTLEVBQzlCLHFCQUFxQixFQUNyQixHQUFHLEVBQUUsQ0FDSCxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDO2dCQUM3QixpQkFBaUIsRUFBRSxJQUFJLENBQUMsaUJBQWlCO2dCQUN6QyxXQUFXLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7Z0JBQ3JDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtnQkFDbkIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO2dCQUNmLDJFQUEyRTtnQkFDM0Usa0ZBQWtGO2dCQUNsRixjQUFjLEVBQUUsSUFBSSxDQUFDLFlBQVk7Z0JBQ2pDLGlGQUFpRjtnQkFDakYsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFBLHdDQUFpQixFQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztnQkFDOUUs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
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Logger } from '../ports/logger-port';
|
|
2
|
+
export default class PrettyLogger implements Logger {
|
|
3
|
+
info(message: string, context: Record<string, unknown>): void;
|
|
4
|
+
warn(message: string, context: Record<string, unknown>): void;
|
|
5
|
+
error(message: string, context: Record<string, unknown>): void;
|
|
6
|
+
private format;
|
|
7
|
+
private formatContext;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=pretty-logger.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
7
|
+
// Colorized logger for TTY/dev. Pair with ConsoleLogger for piped output.
|
|
8
|
+
// CLI auto-picks via process.stdout.isTTY + --pretty/--json flags. NO_COLOR is honored.
|
|
9
|
+
class PrettyLogger {
|
|
10
|
+
info(message, context) {
|
|
11
|
+
// eslint-disable-next-line no-console
|
|
12
|
+
console.info(this.format(picocolors_1.default.cyan('info '), message, context));
|
|
13
|
+
}
|
|
14
|
+
warn(message, context) {
|
|
15
|
+
// eslint-disable-next-line no-console
|
|
16
|
+
console.warn(this.format(picocolors_1.default.yellow('warn '), message, context));
|
|
17
|
+
}
|
|
18
|
+
error(message, context) {
|
|
19
|
+
// eslint-disable-next-line no-console
|
|
20
|
+
console.error(this.format(picocolors_1.default.red('error'), message, context));
|
|
21
|
+
}
|
|
22
|
+
format(level, message, context) {
|
|
23
|
+
const timestamp = picocolors_1.default.dim(new Date().toISOString().substring(11, 19));
|
|
24
|
+
const contextStr = this.formatContext(context);
|
|
25
|
+
return contextStr
|
|
26
|
+
? `${timestamp} ${level} ${message} ${contextStr}`
|
|
27
|
+
: `${timestamp} ${level} ${message}`;
|
|
28
|
+
}
|
|
29
|
+
formatContext(context) {
|
|
30
|
+
const parts = Object.entries(context).map(([key, value]) => `${key}=${JSON.stringify(value)}`);
|
|
31
|
+
if (parts.length === 0)
|
|
32
|
+
return '';
|
|
33
|
+
return picocolors_1.default.dim(parts.join(' '));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.default = PrettyLogger;
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldHR5LWxvZ2dlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVycy9wcmV0dHktbG9nZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBRUEsNERBQTRCO0FBRTVCLDBFQUEwRTtBQUMxRSx3RkFBd0Y7QUFDeEYsTUFBcUIsWUFBWTtJQUMvQixJQUFJLENBQUMsT0FBZSxFQUFFLE9BQWdDO1FBQ3BELHNDQUFzQztRQUN0QyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsb0JBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELElBQUksQ0FBQyxPQUFlLEVBQUUsT0FBZ0M7UUFDcEQsc0NBQXNDO1FBQ3RDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxvQkFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQsS0FBSyxDQUFDLE9BQWUsRUFBRSxPQUFnQztRQUNyRCxzQ0FBc0M7UUFDdEMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLG9CQUFFLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFTyxNQUFNLENBQUMsS0FBYSxFQUFFLE9BQWUsRUFBRSxPQUFnQztRQUM3RSxNQUFNLFNBQVMsR0FBRyxvQkFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyRSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRS9DLE9BQU8sVUFBVTtZQUNmLENBQUMsQ0FBQyxHQUFHLFNBQVMsSUFBSSxLQUFLLElBQUksT0FBTyxJQUFJLFVBQVUsRUFBRTtZQUNsRCxDQUFDLENBQUMsR0FBRyxTQUFTLElBQUksS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO0lBQ3pDLENBQUM7SUFFTyxhQUFhLENBQUMsT0FBZ0M7UUFDcEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDL0YsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUVsQyxPQUFPLG9CQUFFLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNqQyxDQUFDO0NBQ0Y7QUEvQkQsK0JBK0JDIn0=
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serializeRecordId = serializeRecordId;
|
|
4
|
+
exports.deserializeRecordId = deserializeRecordId;
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
function serializeRecordId(recordId) {
|
|
7
|
+
return recordId
|
|
8
|
+
.map(part => {
|
|
9
|
+
const serialized = String(part);
|
|
10
|
+
if (serialized.includes('|')) {
|
|
11
|
+
throw new errors_1.RecordIdSerializationError(serialized);
|
|
12
|
+
}
|
|
13
|
+
return serialized;
|
|
14
|
+
})
|
|
15
|
+
.join('|');
|
|
16
|
+
}
|
|
17
|
+
function deserializeRecordId(value) {
|
|
18
|
+
return value.split('|');
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkLWlkLXNlcmlhbGl6ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlcnMvcmVjb3JkLWlkLXNlcmlhbGl6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFJQSw4Q0FZQztBQUVELGtEQUVDO0FBbEJELHNDQUF1RDtBQUV2RCxTQUFnQixpQkFBaUIsQ0FBQyxRQUFrQjtJQUNsRCxPQUFPLFFBQVE7U0FDWixHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDVixNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFaEMsSUFBSSxVQUFVLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDN0IsTUFBTSxJQUFJLG1DQUEwQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ25ELENBQUM7UUFFRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDLENBQUM7U0FDRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZixDQUFDO0FBRUQsU0FBZ0IsbUJBQW1CLENBQUMsS0FBYTtJQUMvQyxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDMUIsQ0FBQyJ9
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ServerHydratedWorkflowRun } from './server-types';
|
|
2
|
+
import { type AvailableStepExecution } from '../types/validated/execution';
|
|
3
|
+
export default function toAvailableStepExecution(run: ServerHydratedWorkflowRun): AvailableStepExecution | null;
|
|
4
|
+
//# sourceMappingURL=run-to-available-step-mapper.d.ts.map
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = toAvailableStepExecution;
|
|
7
|
+
const zod_1 = require("zod");
|
|
8
|
+
const record_id_serializer_1 = require("./record-id-serializer");
|
|
9
|
+
const step_definition_mapper_1 = __importDefault(require("./step-definition-mapper"));
|
|
10
|
+
const errors_1 = require("../errors");
|
|
11
|
+
const execution_1 = require("../types/validated/execution");
|
|
12
|
+
const step_outcome_1 = require("../types/validated/step-outcome");
|
|
13
|
+
function toRecordStatus(ctxStatus) {
|
|
14
|
+
if (ctxStatus === 'error')
|
|
15
|
+
return 'error';
|
|
16
|
+
if (ctxStatus === 'awaiting-input')
|
|
17
|
+
return 'awaiting-input';
|
|
18
|
+
return 'success';
|
|
19
|
+
}
|
|
20
|
+
// `context` may come from the executor (our StepOutcome, stored verbatim) or the legacy frontend
|
|
21
|
+
// (free-form). We whitelist known fields per type to avoid leaking legacy ones back to the
|
|
22
|
+
// orchestrator and to enforce the discriminated-union shape.
|
|
23
|
+
function toStepOutcome(s) {
|
|
24
|
+
const stepDef = (0, step_definition_mapper_1.default)(s.stepDefinition);
|
|
25
|
+
const outcomeType = (0, step_outcome_1.stepTypeToOutcomeType)(stepDef.type);
|
|
26
|
+
const ctx = (s.context ?? {});
|
|
27
|
+
const baseFromCtx = {
|
|
28
|
+
stepId: s.stepName,
|
|
29
|
+
stepIndex: s.stepIndex,
|
|
30
|
+
error: typeof ctx.error === 'string' ? ctx.error : undefined,
|
|
31
|
+
};
|
|
32
|
+
if (outcomeType === 'condition') {
|
|
33
|
+
const status = toRecordStatus(ctx.status);
|
|
34
|
+
const selectedOption = typeof ctx.selectedOption === 'string' ? ctx.selectedOption : undefined;
|
|
35
|
+
return {
|
|
36
|
+
type: 'condition',
|
|
37
|
+
...baseFromCtx,
|
|
38
|
+
status,
|
|
39
|
+
...(selectedOption !== undefined && { selectedOption }),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (outcomeType === 'guidance') {
|
|
43
|
+
const status = ctx.status === 'error' ? 'error' : 'success';
|
|
44
|
+
return { type: 'guidance', ...baseFromCtx, status };
|
|
45
|
+
}
|
|
46
|
+
const status = toRecordStatus(ctx.status);
|
|
47
|
+
if (outcomeType === 'mcp') {
|
|
48
|
+
return { type: 'mcp', ...baseFromCtx, status };
|
|
49
|
+
}
|
|
50
|
+
return { type: 'record', ...baseFromCtx, status };
|
|
51
|
+
}
|
|
52
|
+
function tryMapStep(s) {
|
|
53
|
+
try {
|
|
54
|
+
return {
|
|
55
|
+
stepDefinition: (0, step_definition_mapper_1.default)(s.stepDefinition),
|
|
56
|
+
stepOutcome: toStepOutcome(s),
|
|
57
|
+
...(s.originalStepIndex !== undefined && { originalStepIndex: s.originalStepIndex }),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
// Sub-workflow navigation steps (start-sub-workflow, close-sub-workflow) are not
|
|
62
|
+
// meaningful for AI context — skip them rather than failing the whole run.
|
|
63
|
+
if (err instanceof errors_1.UnsupportedStepTypeError)
|
|
64
|
+
return null;
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Mirrors the orchestrator's own read filter: revised and cancelled entries are not on the
|
|
69
|
+
// live path.
|
|
70
|
+
function toPreviousSteps(history, pendingStepIndex) {
|
|
71
|
+
return history
|
|
72
|
+
.filter(s => s.done && !s.revised && !s.cancelled && s.stepIndex < pendingStepIndex)
|
|
73
|
+
.map(s => tryMapStep(s))
|
|
74
|
+
.filter((s) => s !== null);
|
|
75
|
+
}
|
|
76
|
+
function toStepUser(runId, profile) {
|
|
77
|
+
// renderingId is stringified into the activity-log payload — reject non-finite so we don't
|
|
78
|
+
// silently post "undefined"/"NaN" to the audit trail.
|
|
79
|
+
if (typeof profile.renderingId !== 'number' || !Number.isFinite(profile.renderingId)) {
|
|
80
|
+
throw new errors_1.InvalidStepDefinitionError(`Run ${runId} userProfile has no valid renderingId (got "${String(profile.renderingId)}")`);
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
id: profile.id,
|
|
84
|
+
email: profile.email,
|
|
85
|
+
firstName: profile.firstName ?? '',
|
|
86
|
+
lastName: profile.lastName ?? '',
|
|
87
|
+
team: profile.team ?? '',
|
|
88
|
+
renderingId: profile.renderingId,
|
|
89
|
+
role: profile.role ?? '',
|
|
90
|
+
permissionLevel: profile.permissionLevel ?? '',
|
|
91
|
+
tags: profile.tags,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
// Returns null when the run has no available step (terminal state or all done/cancelled).
|
|
95
|
+
// Throws InvalidStepDefinitionError on missing required fields (collectionId, collectionName,
|
|
96
|
+
// userProfile) or an unmappable step definition.
|
|
97
|
+
function toAvailableStepExecution(run) {
|
|
98
|
+
if (!run.collectionName) {
|
|
99
|
+
throw new errors_1.InvalidStepDefinitionError(`Run ${run.id} has no collectionName — cannot build baseRecordRef`);
|
|
100
|
+
}
|
|
101
|
+
if (!run.collectionId) {
|
|
102
|
+
throw new errors_1.InvalidStepDefinitionError(`Run ${run.id} has no collectionId — cannot build baseRecordRef`);
|
|
103
|
+
}
|
|
104
|
+
if (!run.selectedRecordId) {
|
|
105
|
+
throw new errors_1.InvalidStepDefinitionError(`Run ${run.id} has no selectedRecordId — cannot build baseRecordRef`);
|
|
106
|
+
}
|
|
107
|
+
const pending = run.workflowHistory.at(-1) ?? null;
|
|
108
|
+
if (!pending || pending.done)
|
|
109
|
+
return null;
|
|
110
|
+
const result = {
|
|
111
|
+
runId: String(run.id),
|
|
112
|
+
stepId: pending.stepName,
|
|
113
|
+
stepIndex: pending.stepIndex,
|
|
114
|
+
collectionId: run.collectionId,
|
|
115
|
+
baseRecordRef: {
|
|
116
|
+
collectionName: run.collectionName,
|
|
117
|
+
recordId: (0, record_id_serializer_1.deserializeRecordId)(run.selectedRecordId),
|
|
118
|
+
stepIndex: 0,
|
|
119
|
+
},
|
|
120
|
+
stepDefinition: (0, step_definition_mapper_1.default)(pending.stepDefinition),
|
|
121
|
+
previousSteps: toPreviousSteps(run.workflowHistory, pending.stepIndex),
|
|
122
|
+
user: toStepUser(run.id, run.userProfile),
|
|
123
|
+
};
|
|
124
|
+
// Defense against mapper bugs: zod asserts the shape we produce is what the domain expects,
|
|
125
|
+
// before any executor consumes it. Fails loudly with a typed error instead of crashing deep.
|
|
126
|
+
try {
|
|
127
|
+
return execution_1.AvailableStepExecutionSchema.parse(result);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
if (err instanceof zod_1.z.ZodError) {
|
|
131
|
+
throw new errors_1.DomainValidationError(run.id, err);
|
|
132
|
+
}
|
|
133
|
+
/* istanbul ignore next — zod.parse only throws ZodError; defensive fallback */
|
|
134
|
+
throw err;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLXRvLWF2YWlsYWJsZS1zdGVwLW1hcHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVycy9ydW4tdG8tYXZhaWxhYmxlLXN0ZXAtbWFwcGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBa0lBLDJDQW9EQztBQXpLRCw2QkFBd0I7QUFFeEIsaUVBQTZEO0FBQzdELHNGQUF3RDtBQUN4RCxzQ0FJbUI7QUFDbkIsNERBS3NDO0FBQ3RDLGtFQUF3RTtBQUV4RSxTQUFTLGNBQWMsQ0FBQyxTQUFrQjtJQUN4QyxJQUFJLFNBQVMsS0FBSyxPQUFPO1FBQUUsT0FBTyxPQUFPLENBQUM7SUFDMUMsSUFBSSxTQUFTLEtBQUssZ0JBQWdCO1FBQUUsT0FBTyxnQkFBZ0IsQ0FBQztJQUU1RCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRUQsaUdBQWlHO0FBQ2pHLDJGQUEyRjtBQUMzRiw2REFBNkQ7QUFDN0QsU0FBUyxhQUFhLENBQUMsQ0FBb0I7SUFDekMsTUFBTSxPQUFPLEdBQUcsSUFBQSxnQ0FBZ0IsRUFBQyxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDbkQsTUFBTSxXQUFXLEdBQUcsSUFBQSxvQ0FBcUIsRUFBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEQsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBNEIsQ0FBQztJQUV6RCxNQUFNLFdBQVcsR0FBRztRQUNsQixNQUFNLEVBQUUsQ0FBQyxDQUFDLFFBQVE7UUFDbEIsU0FBUyxFQUFFLENBQUMsQ0FBQyxTQUFTO1FBQ3RCLEtBQUssRUFBRSxPQUFPLEdBQUcsQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTO0tBQzdELENBQUM7SUFFRixJQUFJLFdBQVcsS0FBSyxXQUFXLEVBQUUsQ0FBQztRQUNoQyxNQUFNLE1B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
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AiModelPort } from '../ports/ai-model-port';
|
|
2
|
+
import type { BaseChatModel, RemoteTool, ToolConfig } from '@forestadmin/ai-proxy';
|
|
3
|
+
export interface ServerAiAdapterOptions {
|
|
4
|
+
forestServerUrl: string;
|
|
5
|
+
envSecret: string;
|
|
6
|
+
}
|
|
7
|
+
export default class ServerAiAdapter implements AiModelPort {
|
|
8
|
+
private readonly aiClient;
|
|
9
|
+
constructor(options: ServerAiAdapterOptions);
|
|
10
|
+
getModel(): BaseChatModel;
|
|
11
|
+
loadRemoteTools(configs: Record<string, ToolConfig>): Promise<RemoteTool[]>;
|
|
12
|
+
closeConnections(): Promise<void>;
|
|
13
|
+
private static buildProxyConfiguration;
|
|
14
|
+
private callPort;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=server-ai-adapter.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ai_proxy_1 = require("@forestadmin/ai-proxy");
|
|
4
|
+
const errors_1 = require("../errors");
|
|
5
|
+
class ServerAiAdapter {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.aiClient = new ai_proxy_1.AiClient({
|
|
8
|
+
aiConfigurations: [ServerAiAdapter.buildProxyConfiguration(options)],
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
getModel() {
|
|
12
|
+
try {
|
|
13
|
+
return this.aiClient.getModel();
|
|
14
|
+
}
|
|
15
|
+
catch (cause) {
|
|
16
|
+
if (cause instanceof errors_1.WorkflowExecutorError)
|
|
17
|
+
throw cause;
|
|
18
|
+
throw new errors_1.AiModelPortError('getModel', cause);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
loadRemoteTools(configs) {
|
|
22
|
+
return this.callPort('loadRemoteTools', () => this.aiClient.loadRemoteTools(configs));
|
|
23
|
+
}
|
|
24
|
+
closeConnections() {
|
|
25
|
+
return this.callPort('closeConnections', () => this.aiClient.closeConnections());
|
|
26
|
+
}
|
|
27
|
+
// Every call is routed to the Forest server's AI proxy, which picks the real provider/model.
|
|
28
|
+
// The model name is therefore a placeholder, and fetch is rewritten to hit the proxy with the
|
|
29
|
+
// env secret instead of an OpenAI Authorization header.
|
|
30
|
+
static buildProxyConfiguration({ forestServerUrl, envSecret, }) {
|
|
31
|
+
const aiProxyUrl = `${forestServerUrl}/liana/v1/ai-proxy`;
|
|
32
|
+
return {
|
|
33
|
+
name: 'forest-server',
|
|
34
|
+
provider: 'openai',
|
|
35
|
+
model: 'gpt-4.1',
|
|
36
|
+
maxRetries: 2,
|
|
37
|
+
configuration: {
|
|
38
|
+
apiKey: 'unused',
|
|
39
|
+
fetch: (_url, init) => {
|
|
40
|
+
const headers = new Headers(init?.headers);
|
|
41
|
+
headers.delete('authorization');
|
|
42
|
+
headers.set('forest-secret-key', envSecret);
|
|
43
|
+
return fetch(aiProxyUrl, { ...init, headers });
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async callPort(operation, fn) {
|
|
49
|
+
try {
|
|
50
|
+
return await fn();
|
|
51
|
+
}
|
|
52
|
+
catch (cause) {
|
|
53
|
+
if (cause instanceof errors_1.WorkflowExecutorError)
|
|
54
|
+
throw cause;
|
|
55
|
+
throw new errors_1.AiModelPortError(operation, cause);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.default = ServerAiAdapter;
|
|
60
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLWFpLWFkYXB0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlcnMvc2VydmVyLWFpLWFkYXB0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFHQSxvREFBaUQ7QUFFakQsc0NBQW9FO0FBT3BFLE1BQXFCLGVBQWU7SUFHbEMsWUFBWSxPQUErQjtRQUN6QyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksbUJBQVEsQ0FBQztZQUMzQixnQkFBZ0IsRUFBRSxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNyRSxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQztZQUNILE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNsQyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxZQUFZLDhCQUFxQjtnQkFBRSxNQUFNLEtBQUssQ0FBQztZQUN4RCxNQUFNLElBQUkseUJBQWdCLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hELENBQUM7SUFDSCxDQUFDO0lBRUQsZUFBZSxDQUFDLE9BQW1DO1FBQ2pELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFFRCxnQkFBZ0I7UUFDZCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUVELDZGQUE2RjtJQUM3Riw4RkFBOEY7SUFDOUYsd0RBQXdEO0lBQ2hELE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxFQUNyQyxlQUFlLEVBQ2YsU0FBUyxHQUNjO1FBQ3ZCLE1BQU0sVUFBVSxHQUFHLEdBQUcsZUFBZSxvQkFBb0IsQ0FBQztRQUUxRCxPQUFPO1lBQ0wsSUFBSSxFQUFFLGVBQWU7WUFDckIsUUFBUSxFQUFFLFFBQVE7WUFDbEIsS0FBSyxFQUFFLFNBQVM7WUFDaEIsVUFBVSxFQUFFLENBQUM7WUFDYixhQUFhLEVBQUU7Z0JBQ2IsTUFBTSxFQUFFLFFBQVE7Z0JBQ2hCLEtBQUssRUFBRSxDQUFDLElBQXVCLEVBQUUsSUFBa0IsRUFBRSxFQUFFO29CQUNyRCxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7b0JBQzNDLE9BQU8sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7b0JBQ2hDLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEVBQUUsU0FBUyxDQUFDLENBQUM7b0JBRTVDLE9BQU8sS0FBSyxDQUFDLFVBQVUsRUFBRSxFQUFFLEdBQUcsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBQ2pELENBQUM7YUFDRjtTQUNGLENBQUM7SUFDSixDQUFDO0lBRU8sS0FBSyxDQUFDLFFBQVEsQ0FBSSxTQUFpQixFQUFFLEVBQW9CO1FBQy9ELElBQUksQ0FBQztZQUNILE9BQU8sTUFBTSxFQUFFLEVBQUUsQ0FBQztRQUNwQixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxZQUFZLDhCQUFxQjtnQkFBRSxNQUFNLEtBQUssQ0FBQztZQUN4RCxNQUFNLElBQUkseUJBQWdCLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9DLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUE3REQsa0NBNkRDIn0=
|