@exaudeus/workrail 3.16.0 → 3.17.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/dist/application/use-cases/raw-workflow-file-scanner.js +10 -13
- package/dist/cli/commands/index.d.ts +1 -1
- package/dist/cli/commands/index.js +2 -1
- package/dist/cli/commands/init.d.ts +10 -0
- package/dist/cli/commands/init.js +72 -0
- package/dist/cli.js +13 -1
- package/dist/config/config-file.d.ts +8 -0
- package/dist/config/config-file.js +141 -0
- package/dist/config/feature-flags.js +8 -0
- package/dist/console/assets/index-BwJelCXK.js +28 -0
- package/dist/console/index.html +1 -1
- package/dist/di/container.d.ts +1 -0
- package/dist/di/container.js +24 -7
- package/dist/infrastructure/session/HttpServer.d.ts +0 -1
- package/dist/infrastructure/session/HttpServer.js +4 -46
- package/dist/manifest.json +101 -109
- package/dist/mcp/assert-output.js +2 -1
- package/dist/mcp/dev-mode.d.ts +1 -0
- package/dist/mcp/dev-mode.js +12 -0
- package/dist/mcp/handler-factory.d.ts +1 -1
- package/dist/mcp/handler-factory.js +8 -7
- package/dist/mcp/handlers/shared/request-workflow-reader.d.ts +1 -0
- package/dist/mcp/handlers/shared/request-workflow-reader.js +90 -20
- package/dist/mcp/handlers/v2-execution/continue-advance.d.ts +1 -0
- package/dist/mcp/handlers/v2-execution/continue-advance.js +3 -1
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.d.ts +1 -0
- package/dist/mcp/handlers/v2-execution/continue-rehydrate.js +2 -1
- package/dist/mcp/handlers/v2-execution/index.js +2 -0
- package/dist/mcp/handlers/v2-execution/replay.d.ts +2 -0
- package/dist/mcp/handlers/v2-execution/replay.js +3 -0
- package/dist/mcp/handlers/v2-execution/start.js +48 -20
- package/dist/mcp/handlers/v2-workflow.js +4 -2
- package/dist/mcp/output-schemas.d.ts +5 -0
- package/dist/mcp/output-schemas.js +2 -0
- package/dist/mcp/server.js +3 -2
- package/dist/mcp/v2-response-formatter.d.ts +1 -1
- package/dist/mcp/v2-response-formatter.js +2 -3
- package/dist/types/workflow-definition.d.ts +3 -1
- package/dist/types/workflow-definition.js +2 -0
- package/dist/v2/durable-core/domain/prompt-renderer.d.ts +1 -0
- package/dist/v2/durable-core/domain/prompt-renderer.js +1 -2
- package/dist/v2/durable-core/schemas/compiled-workflow/index.js +4 -3
- package/dist/v2/infra/local/pinned-workflow-store/index.d.ts +2 -0
- package/dist/v2/infra/local/pinned-workflow-store/index.js +49 -0
- package/dist/v2/infra/local/remembered-roots-store/index.d.ts +3 -1
- package/dist/v2/infra/local/remembered-roots-store/index.js +6 -3
- package/dist/v2/infra/local/workspace-anchor/index.js +4 -2
- package/dist/v2/ports/pinned-workflow-store.port.d.ts +2 -0
- package/dist/v2/usecases/console-routes.js +3 -2
- package/package.json +1 -1
- package/dist/console/assets/index-BE5PAgPO.js +0 -28
- package/dist/env-flags.d.ts +0 -1
- package/dist/env-flags.js +0 -4
- package/dist/mcp/handlers/v2-resolve-refs-envelope.d.ts +0 -5
- package/dist/mcp/handlers/v2-resolve-refs-envelope.js +0 -17
|
@@ -2,6 +2,6 @@ import { z } from 'zod';
|
|
|
2
2
|
import type { ToolContext, ToolResult } from './types.js';
|
|
3
3
|
import type { PreValidateResult } from './validation/workflow-next-prevalidate.js';
|
|
4
4
|
import type { WrappedToolHandler, McpCallToolResult } from './types/workflow-tool-edition.js';
|
|
5
|
-
export declare function toMcpResult<T>(result: ToolResult<T
|
|
5
|
+
export declare function toMcpResult<T>(result: ToolResult<T>, ctx?: ToolContext): McpCallToolResult;
|
|
6
6
|
export declare function createHandler<TInput extends z.ZodType, TOutput>(schema: TInput, handler: (input: z.infer<TInput>, ctx: ToolContext) => Promise<ToolResult<TOutput>>, shapeSchema?: z.ZodObject<z.ZodRawShape>, aliasMap?: Readonly<Record<string, string>>): WrappedToolHandler;
|
|
7
7
|
export declare function createValidatingHandler<TInput extends z.ZodType, TOutput>(schema: TInput, preValidate: (args: unknown) => PreValidateResult, handler: (input: z.infer<TInput>, ctx: ToolContext) => Promise<ToolResult<TOutput>>, shapeSchema?: z.ZodObject<z.ZodRawShape>, aliasMap?: Readonly<Record<string, string>>): WrappedToolHandler;
|
|
@@ -11,11 +11,12 @@ const v2_execution_helpers_js_1 = require("./handlers/v2-execution-helpers.js");
|
|
|
11
11
|
const v2_response_formatter_js_1 = require("./v2-response-formatter.js");
|
|
12
12
|
const render_envelope_js_1 = require("./render-envelope.js");
|
|
13
13
|
const jsonResponsesOverride = process.env.WORKRAIL_JSON_RESPONSES === 'true';
|
|
14
|
-
function toMcpResult(result) {
|
|
14
|
+
function toMcpResult(result, ctx) {
|
|
15
15
|
switch (result.type) {
|
|
16
16
|
case 'success': {
|
|
17
|
+
const cleanResponseFormat = ctx?.featureFlags.isEnabled('cleanResponseFormat') ?? false;
|
|
17
18
|
if (!jsonResponsesOverride) {
|
|
18
|
-
const formatted = (0, v2_response_formatter_js_1.formatV2ExecutionResponse)(result.data) ?? (0, v2_response_formatter_js_1.formatV2ResumeResponse)(result.data);
|
|
19
|
+
const formatted = (0, v2_response_formatter_js_1.formatV2ExecutionResponse)(result.data, cleanResponseFormat) ?? (0, v2_response_formatter_js_1.formatV2ResumeResponse)(result.data);
|
|
19
20
|
if (formatted !== null) {
|
|
20
21
|
const content = [{ type: 'text', text: formatted.primary }];
|
|
21
22
|
if (formatted.references != null) {
|
|
@@ -76,14 +77,14 @@ function createHandler(schema, handler, shapeSchema, aliasMap) {
|
|
|
76
77
|
message: e.message,
|
|
77
78
|
})),
|
|
78
79
|
...patchedDetails,
|
|
79
|
-
}));
|
|
80
|
+
}), ctx);
|
|
80
81
|
}
|
|
81
82
|
try {
|
|
82
|
-
return toMcpResult(await handler(parseResult.data, ctx));
|
|
83
|
+
return toMcpResult(await handler(parseResult.data, ctx), ctx);
|
|
83
84
|
}
|
|
84
85
|
catch (err) {
|
|
85
86
|
console.error('[WorkRail] Unhandled exception in tool handler:', err);
|
|
86
|
-
return toMcpResult((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail encountered an unexpected error. This is not caused by your input.', { suggestion: (0, v2_execution_helpers_js_1.internalSuggestion)('Retry the call.', 'WorkRail has an internal error.') }));
|
|
87
|
+
return toMcpResult((0, types_js_1.errNotRetryable)('INTERNAL_ERROR', 'WorkRail encountered an unexpected error. This is not caused by your input.', { suggestion: (0, v2_execution_helpers_js_1.internalSuggestion)('Retry the call.', 'WorkRail has an internal error.') }), ctx);
|
|
87
88
|
}
|
|
88
89
|
};
|
|
89
90
|
}
|
|
@@ -109,9 +110,9 @@ function createValidatingHandler(schema, preValidate, handler, shapeSchema, alia
|
|
|
109
110
|
...error,
|
|
110
111
|
details: boundedDetails,
|
|
111
112
|
};
|
|
112
|
-
return toMcpResult(boundedError);
|
|
113
|
+
return toMcpResult(boundedError, ctx);
|
|
113
114
|
}
|
|
114
|
-
return toMcpResult(error);
|
|
115
|
+
return toMcpResult(error, ctx);
|
|
115
116
|
}
|
|
116
117
|
return innerHandler(normalizedArgs, ctx);
|
|
117
118
|
};
|
|
@@ -2,6 +2,7 @@ import type { IWorkflowReader } from '../../../types/storage.js';
|
|
|
2
2
|
import type { IFeatureFlagProvider } from '../../../config/feature-flags.js';
|
|
3
3
|
import type { RememberedRootsStorePortV2 } from '../../../v2/ports/remembered-roots-store.port.js';
|
|
4
4
|
import type { ManagedSourceRecordV2, ManagedSourceStorePortV2 } from '../../../v2/ports/managed-source-store.port.js';
|
|
5
|
+
export declare function clearWalkCacheForTesting(): void;
|
|
5
6
|
export interface RequestWorkflowReaderOptions {
|
|
6
7
|
readonly featureFlags: IFeatureFlagProvider;
|
|
7
8
|
readonly workspacePath?: string;
|
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.clearWalkCacheForTesting = clearWalkCacheForTesting;
|
|
6
7
|
exports.hasRequestWorkspaceSignal = hasRequestWorkspaceSignal;
|
|
7
8
|
exports.resolveRequestWorkspaceDirectory = resolveRequestWorkspaceDirectory;
|
|
8
9
|
exports.toProjectWorkflowDirectory = toProjectWorkflowDirectory;
|
|
@@ -13,6 +14,27 @@ const path_1 = __importDefault(require("path"));
|
|
|
13
14
|
const url_1 = require("url");
|
|
14
15
|
const enhanced_multi_source_workflow_storage_js_1 = require("../../../infrastructure/storage/enhanced-multi-source-workflow-storage.js");
|
|
15
16
|
const schema_validating_workflow_storage_js_1 = require("../../../infrastructure/storage/schema-validating-workflow-storage.js");
|
|
17
|
+
const with_timeout_js_1 = require("./with-timeout.js");
|
|
18
|
+
const SKIP_DIRS = new Set([
|
|
19
|
+
'.git', 'node_modules',
|
|
20
|
+
'build', 'dist', 'out', 'target',
|
|
21
|
+
'.gradle', '.gradle-cache', '.cache',
|
|
22
|
+
'DerivedData', 'Pods',
|
|
23
|
+
'vendor',
|
|
24
|
+
'__pycache__', '.venv', 'venv',
|
|
25
|
+
'.next', '.nuxt', '.turbo', '.parcel-cache',
|
|
26
|
+
'.claude', '.claude-worktrees', '.firebender',
|
|
27
|
+
'coverage', '.nyc_output',
|
|
28
|
+
]);
|
|
29
|
+
const MAX_WALK_DEPTH = 5;
|
|
30
|
+
const WALK_CACHE_TTL_MS = 300000;
|
|
31
|
+
const walkCache = new Map();
|
|
32
|
+
const walkInFlight = new Map();
|
|
33
|
+
function clearWalkCacheForTesting() {
|
|
34
|
+
walkCache.clear();
|
|
35
|
+
walkInFlight.clear();
|
|
36
|
+
}
|
|
37
|
+
const DISCOVERY_TIMEOUT_MS = 10000;
|
|
16
38
|
function hasRequestWorkspaceSignal(options) {
|
|
17
39
|
return Boolean(options.workspacePath) || (options.resolvedRootUris?.length ?? 0) > 0;
|
|
18
40
|
}
|
|
@@ -34,18 +56,38 @@ function toProjectWorkflowDirectory(workspaceDirectory) {
|
|
|
34
56
|
? workspaceDirectory
|
|
35
57
|
: path_1.default.join(workspaceDirectory, 'workflows');
|
|
36
58
|
}
|
|
37
|
-
|
|
59
|
+
function discoverRootedWorkflowDirectories(roots) {
|
|
60
|
+
const cacheKey = roots.map((r) => path_1.default.resolve(r)).sort().join('\0');
|
|
61
|
+
const now = Date.now();
|
|
62
|
+
const cached = walkCache.get(cacheKey);
|
|
63
|
+
if (cached && cached.expiresAt > now) {
|
|
64
|
+
return Promise.resolve(cached.result);
|
|
65
|
+
}
|
|
66
|
+
const inFlight = walkInFlight.get(cacheKey);
|
|
67
|
+
if (inFlight)
|
|
68
|
+
return inFlight;
|
|
69
|
+
const promise = _doWalk(cacheKey, roots, now);
|
|
70
|
+
walkInFlight.set(cacheKey, promise);
|
|
71
|
+
promise.then(() => walkInFlight.delete(cacheKey), () => walkInFlight.delete(cacheKey));
|
|
72
|
+
return promise;
|
|
73
|
+
}
|
|
74
|
+
async function _doWalk(cacheKey, roots, now) {
|
|
38
75
|
const discoveredByPath = new Set();
|
|
39
76
|
const discoveredPaths = [];
|
|
40
77
|
const stalePaths = [];
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
78
|
+
const resolvedRoots = roots.map((r) => path_1.default.resolve(r));
|
|
79
|
+
const rootResults = await Promise.allSettled(resolvedRoots.map((rootPath) => discoverWorkflowDirectoriesUnderRoot(rootPath)));
|
|
80
|
+
for (let i = 0; i < resolvedRoots.length; i++) {
|
|
81
|
+
const rootPath = resolvedRoots[i];
|
|
82
|
+
const rootResult = rootResults[i];
|
|
83
|
+
if (rootResult.status === 'rejected') {
|
|
84
|
+
throw rootResult.reason;
|
|
85
|
+
}
|
|
86
|
+
if (rootResult.value.stale) {
|
|
45
87
|
stalePaths.push(rootPath);
|
|
46
88
|
continue;
|
|
47
89
|
}
|
|
48
|
-
for (const nextPath of
|
|
90
|
+
for (const nextPath of rootResult.value.discovered) {
|
|
49
91
|
const normalizedPath = path_1.default.resolve(nextPath);
|
|
50
92
|
if (discoveredByPath.has(normalizedPath))
|
|
51
93
|
continue;
|
|
@@ -53,13 +95,22 @@ async function discoverRootedWorkflowDirectories(roots) {
|
|
|
53
95
|
discoveredPaths.push(normalizedPath);
|
|
54
96
|
}
|
|
55
97
|
}
|
|
56
|
-
|
|
98
|
+
const result = { discovered: discoveredPaths, stale: stalePaths };
|
|
99
|
+
walkCache.set(cacheKey, { result, expiresAt: now + WALK_CACHE_TTL_MS });
|
|
100
|
+
return result;
|
|
57
101
|
}
|
|
58
102
|
async function createWorkflowReaderForRequest(options) {
|
|
59
103
|
const workspaceDirectory = resolveRequestWorkspaceDirectory(options);
|
|
60
104
|
const projectWorkflowDirectory = toProjectWorkflowDirectory(workspaceDirectory);
|
|
61
105
|
const rememberedRoots = await listRememberedRoots(options.rememberedRootsStore);
|
|
62
|
-
|
|
106
|
+
let discoveryResult;
|
|
107
|
+
try {
|
|
108
|
+
discoveryResult = await (0, with_timeout_js_1.withTimeout)(discoverRootedWorkflowDirectories(rememberedRoots), DISCOVERY_TIMEOUT_MS, 'workflow_root_discovery');
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
discoveryResult = { discovered: [], stale: [] };
|
|
112
|
+
}
|
|
113
|
+
const { discovered: rootedWorkflowDirectories, stale: stalePaths } = discoveryResult;
|
|
63
114
|
const rootedCustomPaths = rootedWorkflowDirectories.filter((directory) => directory !== projectWorkflowDirectory);
|
|
64
115
|
const { records: allManagedRecords, storeError: managedStoreError } = await listManagedSourceRecords(options.managedSourceStore);
|
|
65
116
|
const envCustomPaths = parseWorkflowStoragePathEnv();
|
|
@@ -70,17 +121,30 @@ async function createWorkflowReaderForRequest(options) {
|
|
|
70
121
|
const additionalManagedPaths = [];
|
|
71
122
|
const activeManagedRecords = [];
|
|
72
123
|
const staleManagedRecords = [];
|
|
124
|
+
const alreadyCovered = [];
|
|
125
|
+
const needsStatCheck = [];
|
|
73
126
|
for (const record of allManagedRecords) {
|
|
74
127
|
if (normalizedCustom.has(path_1.default.resolve(record.path))) {
|
|
75
|
-
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
if (await isDirectory(record.path)) {
|
|
79
|
-
additionalManagedPaths.push(record.path);
|
|
80
|
-
activeManagedRecords.push(record);
|
|
128
|
+
alreadyCovered.push(record);
|
|
81
129
|
}
|
|
82
130
|
else {
|
|
83
|
-
|
|
131
|
+
needsStatCheck.push(record);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
activeManagedRecords.push(...alreadyCovered);
|
|
135
|
+
if (needsStatCheck.length > 0) {
|
|
136
|
+
const statResults = await (0, with_timeout_js_1.withTimeout)(Promise.allSettled(needsStatCheck.map((record) => isDirectory(record.path))), DISCOVERY_TIMEOUT_MS, 'managed_source_stat').catch(() => null);
|
|
137
|
+
for (let i = 0; i < needsStatCheck.length; i++) {
|
|
138
|
+
const record = needsStatCheck[i];
|
|
139
|
+
const result = statResults?.[i];
|
|
140
|
+
const isDir = result?.status === 'fulfilled' && result.value === true;
|
|
141
|
+
if (isDir) {
|
|
142
|
+
additionalManagedPaths.push(record.path);
|
|
143
|
+
activeManagedRecords.push(record);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
staleManagedRecords.push(record);
|
|
147
|
+
}
|
|
84
148
|
}
|
|
85
149
|
}
|
|
86
150
|
const customPaths = [...rootedCustomPaths, ...additionalManagedPaths];
|
|
@@ -118,8 +182,8 @@ async function listRememberedRoots(rememberedRootsStore) {
|
|
|
118
182
|
return [];
|
|
119
183
|
const result = await rememberedRootsStore.listRoots();
|
|
120
184
|
if (result.isErr()) {
|
|
121
|
-
|
|
122
|
-
|
|
185
|
+
console.error(`[workrail] Failed to load remembered workflow roots: ${result.error.code}: ${result.error.message}`);
|
|
186
|
+
return [];
|
|
123
187
|
}
|
|
124
188
|
return result.value.map((root) => path_1.default.resolve(root));
|
|
125
189
|
}
|
|
@@ -136,7 +200,7 @@ async function discoverWorkflowDirectoriesUnderRoot(rootPath) {
|
|
|
136
200
|
}
|
|
137
201
|
return { discovered: discoveredPaths, stale: false };
|
|
138
202
|
}
|
|
139
|
-
async function walkForRootedWorkflowDirectories(currentDirectory, discoveredPaths) {
|
|
203
|
+
async function walkForRootedWorkflowDirectories(currentDirectory, discoveredPaths, depth = 0) {
|
|
140
204
|
const entries = await promises_1.default.readdir(currentDirectory, { withFileTypes: true });
|
|
141
205
|
const sortedEntries = [...entries].sort((a, b) => a.name.localeCompare(b.name));
|
|
142
206
|
for (const entry of sortedEntries) {
|
|
@@ -152,14 +216,20 @@ async function walkForRootedWorkflowDirectories(currentDirectory, discoveredPath
|
|
|
152
216
|
}
|
|
153
217
|
continue;
|
|
154
218
|
}
|
|
155
|
-
|
|
219
|
+
if (depth >= MAX_WALK_DEPTH) {
|
|
220
|
+
if (process.env['WORKRAIL_DEV'] === '1') {
|
|
221
|
+
console.error(`[workrail] walk depth limit (${MAX_WALK_DEPTH}) reached at: ${entryPath}`);
|
|
222
|
+
}
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
await walkForRootedWorkflowDirectories(entryPath, discoveredPaths, depth + 1).catch((err) => {
|
|
156
226
|
if (err.code !== 'ENOENT')
|
|
157
227
|
throw err;
|
|
158
228
|
});
|
|
159
229
|
}
|
|
160
230
|
}
|
|
161
231
|
function shouldSkipDirectory(name) {
|
|
162
|
-
return
|
|
232
|
+
return SKIP_DIRS.has(name);
|
|
163
233
|
}
|
|
164
234
|
async function isDirectory(targetPath) {
|
|
165
235
|
try {
|
|
@@ -28,4 +28,5 @@ export declare function handleAdvanceIntent(args: {
|
|
|
28
28
|
readonly sha256: Sha256PortV2;
|
|
29
29
|
readonly aliasStore: import('../../../v2/ports/token-alias-store.port.js').TokenAliasStorePortV2;
|
|
30
30
|
readonly entropy: import('../../../v2/ports/random-entropy.port.js').RandomEntropyPortV2;
|
|
31
|
+
readonly cleanResponseFormat?: boolean;
|
|
31
32
|
}): RA<z.infer<typeof V2ContinueWorkflowOutputSchema>, ContinueWorkflowError>;
|
|
@@ -11,7 +11,7 @@ const advance_js_1 = require("./advance.js");
|
|
|
11
11
|
const sorted_event_log_js_1 = require("../../../v2/durable-core/sorted-event-log.js");
|
|
12
12
|
const session_index_js_1 = require("../../../v2/durable-core/session-index.js");
|
|
13
13
|
function handleAdvanceIntent(args) {
|
|
14
|
-
const { input, sessionId, runId, nodeId, attemptId, workflowHashRef, truth, gate, sessionStore, snapshotStore, pinnedStore, tokenCodecPorts, idFactory, sha256, aliasStore, entropy } = args;
|
|
14
|
+
const { input, sessionId, runId, nodeId, attemptId, workflowHashRef, truth, gate, sessionStore, snapshotStore, pinnedStore, tokenCodecPorts, idFactory, sha256, aliasStore, entropy, cleanResponseFormat } = args;
|
|
15
15
|
const dedupeKey = `advance_recorded:${sessionId}:${nodeId}:${attemptId}`;
|
|
16
16
|
const preLockSortedResult = (0, sorted_event_log_js_1.asSortedEventLog)(truth.events);
|
|
17
17
|
if (preLockSortedResult.isErr()) {
|
|
@@ -101,6 +101,7 @@ function handleAdvanceIntent(args) {
|
|
|
101
101
|
tokenCodecPorts,
|
|
102
102
|
aliasStore,
|
|
103
103
|
entropy,
|
|
104
|
+
cleanResponseFormat,
|
|
104
105
|
});
|
|
105
106
|
}
|
|
106
107
|
return gate
|
|
@@ -198,6 +199,7 @@ function handleAdvanceIntent(args) {
|
|
|
198
199
|
tokenCodecPorts,
|
|
199
200
|
aliasStore,
|
|
200
201
|
entropy,
|
|
202
|
+
cleanResponseFormat,
|
|
201
203
|
});
|
|
202
204
|
});
|
|
203
205
|
});
|
|
@@ -27,4 +27,5 @@ export declare function handleRehydrateIntent(args: {
|
|
|
27
27
|
readonly aliasStore: import('../../../v2/ports/token-alias-store.port.js').TokenAliasStorePortV2;
|
|
28
28
|
readonly entropy: import('../../../v2/ports/random-entropy.port.js').RandomEntropyPortV2;
|
|
29
29
|
readonly resolvedRootUris?: readonly string[];
|
|
30
|
+
readonly cleanResponseFormat?: boolean;
|
|
30
31
|
}): RA<RehydrateResult, ContinueWorkflowError>;
|
|
@@ -20,7 +20,7 @@ const index_js_2 = require("./index.js");
|
|
|
20
20
|
const step_content_envelope_js_1 = require("../../step-content-envelope.js");
|
|
21
21
|
const assert_output_js_1 = require("../../assert-output.js");
|
|
22
22
|
function handleRehydrateIntent(args) {
|
|
23
|
-
const { input, sessionId, runId, nodeId, workflowHashRef, truth, tokenCodecPorts, pinnedStore, snapshotStore, idFactory, aliasStore, entropy, resolvedRootUris } = args;
|
|
23
|
+
const { input, sessionId, runId, nodeId, workflowHashRef, truth, tokenCodecPorts, pinnedStore, snapshotStore, idFactory, aliasStore, entropy, resolvedRootUris, cleanResponseFormat } = args;
|
|
24
24
|
const runStarted = truth.events.find((e) => e.kind === constants_js_1.EVENT_KIND.RUN_STARTED && e.scope.runId === String(runId));
|
|
25
25
|
const workflowId = runStarted?.data.workflowId;
|
|
26
26
|
if (!runStarted || typeof workflowId !== 'string' || workflowId.trim() === '') {
|
|
@@ -124,6 +124,7 @@ function handleRehydrateIntent(args) {
|
|
|
124
124
|
runId: (0, index_js_1.asRunId)(String(runId)),
|
|
125
125
|
nodeId: (0, index_js_1.asNodeId)(String(nodeId)),
|
|
126
126
|
rehydrateOnly: true,
|
|
127
|
+
cleanResponseFormat,
|
|
127
128
|
});
|
|
128
129
|
if (metaRes.isErr()) {
|
|
129
130
|
return (0, neverthrow_1.errAsync)({
|
|
@@ -75,6 +75,7 @@ function loadAndRehydrate(args) {
|
|
|
75
75
|
aliasStore: tokenAliasStore,
|
|
76
76
|
entropy,
|
|
77
77
|
resolvedRootUris: args.ctx.v2.resolvedRootUris,
|
|
78
|
+
cleanResponseFormat: args.ctx.featureFlags?.isEnabled('cleanResponseFormat') ?? false,
|
|
78
79
|
}));
|
|
79
80
|
}
|
|
80
81
|
function executeContinueWorkflow(input, ctx) {
|
|
@@ -140,6 +141,7 @@ function executeContinueWorkflow(input, ctx) {
|
|
|
140
141
|
sha256,
|
|
141
142
|
aliasStore: tokenAliasStore,
|
|
142
143
|
entropy,
|
|
144
|
+
cleanResponseFormat: ctx.featureFlags?.isEnabled('cleanResponseFormat') ?? false,
|
|
143
145
|
}))
|
|
144
146
|
.map((response) => ({ response }));
|
|
145
147
|
});
|
|
@@ -25,6 +25,7 @@ export declare function buildAdvancedReplayResponse(args: {
|
|
|
25
25
|
readonly aliasStore: import('../../../v2/ports/token-alias-store.port.js').TokenAliasStorePortV2;
|
|
26
26
|
readonly entropy: import('../../../v2/ports/random-entropy.port.js').RandomEntropyPortV2;
|
|
27
27
|
readonly precomputedIndex?: import('../../../v2/durable-core/session-index.js').SessionIndex;
|
|
28
|
+
readonly cleanResponseFormat?: boolean;
|
|
28
29
|
}): RA<z.infer<typeof V2ContinueWorkflowOutputSchema>, ContinueWorkflowError>;
|
|
29
30
|
export declare function replayFromRecordedAdvance(args: {
|
|
30
31
|
readonly recordedEvent: Extract<DomainEventV1, {
|
|
@@ -43,4 +44,5 @@ export declare function replayFromRecordedAdvance(args: {
|
|
|
43
44
|
readonly aliasStore: import('../../../v2/ports/token-alias-store.port.js').TokenAliasStorePortV2;
|
|
44
45
|
readonly entropy: import('../../../v2/ports/random-entropy.port.js').RandomEntropyPortV2;
|
|
45
46
|
readonly precomputedIndex?: import('../../../v2/durable-core/session-index.js').SessionIndex;
|
|
47
|
+
readonly cleanResponseFormat?: boolean;
|
|
46
48
|
}): RA<z.infer<typeof V2ContinueWorkflowOutputSchema>, ContinueWorkflowError>;
|
|
@@ -78,6 +78,7 @@ function buildAdvancedReplayResponse(args) {
|
|
|
78
78
|
nodeId: (0, index_js_1.asNodeId)(String(toNodeIdBranded)),
|
|
79
79
|
rehydrateOnly: false,
|
|
80
80
|
precomputedIndex: args.precomputedIndex,
|
|
81
|
+
cleanResponseFormat: args.cleanResponseFormat,
|
|
81
82
|
});
|
|
82
83
|
if (result.isErr()) {
|
|
83
84
|
return (0, neverthrow_1.errAsync)({ kind: 'prompt_render_failed', message: result.error.message });
|
|
@@ -116,6 +117,7 @@ function buildAdvancedReplayResponse(args) {
|
|
|
116
117
|
nodeId: (0, index_js_1.asNodeId)(String(toNodeIdBranded)),
|
|
117
118
|
rehydrateOnly: false,
|
|
118
119
|
precomputedIndex: args.precomputedIndex,
|
|
120
|
+
cleanResponseFormat: args.cleanResponseFormat,
|
|
119
121
|
});
|
|
120
122
|
if (result.isErr()) {
|
|
121
123
|
return (0, neverthrow_1.errAsync)({ kind: 'prompt_render_failed', message: result.error.message });
|
|
@@ -208,6 +210,7 @@ function replayFromRecordedAdvance(args) {
|
|
|
208
210
|
aliasStore,
|
|
209
211
|
entropy,
|
|
210
212
|
precomputedIndex: args.precomputedIndex,
|
|
213
|
+
cleanResponseFormat: args.cleanResponseFormat,
|
|
211
214
|
});
|
|
212
215
|
});
|
|
213
216
|
}
|
|
@@ -26,6 +26,8 @@ const request_workflow_reader_js_1 = require("../shared/request-workflow-reader.
|
|
|
26
26
|
const step_content_envelope_js_1 = require("../../step-content-envelope.js");
|
|
27
27
|
const v2_workspace_resolution_js_2 = require("../v2-workspace-resolution.js");
|
|
28
28
|
const v2_reference_resolver_js_1 = require("../v2-reference-resolver.js");
|
|
29
|
+
const with_timeout_js_1 = require("../shared/with-timeout.js");
|
|
30
|
+
const REFERENCE_RESOLUTION_TIMEOUT_MS = 5000;
|
|
29
31
|
function loadAndPinWorkflow(args) {
|
|
30
32
|
const { workflowId, workflowReader, crypto, pinnedStore, validationPipelineDeps, workspacePath, resolvedRootUris } = args;
|
|
31
33
|
return neverthrow_1.ResultAsync.fromPromise(workflowReader.getWorkflowById(workflowId), (e) => ({
|
|
@@ -77,7 +79,7 @@ function loadAndPinWorkflow(args) {
|
|
|
77
79
|
}
|
|
78
80
|
return pinnedStore.put(workflowHash, enrichedCompiled)
|
|
79
81
|
.mapErr((cause) => ({ kind: 'pinned_workflow_store_failed', cause }))
|
|
80
|
-
.
|
|
82
|
+
.map(() => enrichedCompiled);
|
|
81
83
|
})
|
|
82
84
|
.andThen((pinned) => {
|
|
83
85
|
if (!pinned || pinned.sourceKind !== 'v1_pinned' || !(0, workflow_definition_js_1.hasWorkflowDefinitionShape)(pinned.definition)) {
|
|
@@ -239,10 +241,11 @@ function executeStartWorkflow(input, ctx) {
|
|
|
239
241
|
workspacePath: input.workspacePath,
|
|
240
242
|
resolvedRootUris: ctx.v2.resolvedRootUris,
|
|
241
243
|
rememberedRootsStore: ctx.v2.rememberedRootsStore,
|
|
244
|
+
managedSourceStore: ctx.v2.managedSourceStore,
|
|
242
245
|
}), (err) => ({
|
|
243
246
|
kind: 'precondition_failed',
|
|
244
247
|
message: `Failed to initialize workflow reader: ${String(err)}`,
|
|
245
|
-
})).map(({ reader, stalePaths }) => ({
|
|
248
|
+
})).map(({ reader, stalePaths, managedStoreError }) => ({
|
|
246
249
|
workflowReader: {
|
|
247
250
|
getWorkflowById: async (workflowId) => {
|
|
248
251
|
const requestResult = await reader.getWorkflowById(workflowId);
|
|
@@ -252,21 +255,24 @@ function executeStartWorkflow(input, ctx) {
|
|
|
252
255
|
},
|
|
253
256
|
},
|
|
254
257
|
stalePaths,
|
|
258
|
+
managedStoreError,
|
|
255
259
|
}))
|
|
256
|
-
: (0, neverthrow_1.okAsync)({ workflowReader: ctx.workflowService, stalePaths: [] });
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
.
|
|
269
|
-
|
|
260
|
+
: (0, neverthrow_1.okAsync)({ workflowReader: ctx.workflowService, stalePaths: [], managedStoreError: undefined });
|
|
261
|
+
const anchorsRA = (0, v2_workspace_resolution_js_1.resolveWorkspaceAnchors)(ctx.v2, input.workspacePath)
|
|
262
|
+
.map((anchors) => (0, observation_builder_js_1.anchorsToObservations)(anchors))
|
|
263
|
+
.mapErr((x) => x);
|
|
264
|
+
return readerRA.andThen(({ workflowReader, stalePaths, managedStoreError }) => {
|
|
265
|
+
const pinnedRA = loadAndPinWorkflow({
|
|
266
|
+
workflowId: input.workflowId,
|
|
267
|
+
workflowReader,
|
|
268
|
+
crypto,
|
|
269
|
+
pinnedStore,
|
|
270
|
+
validationPipelineDeps,
|
|
271
|
+
workspacePath: input.workspacePath,
|
|
272
|
+
resolvedRootUris: ctx.v2.resolvedRootUris,
|
|
273
|
+
});
|
|
274
|
+
return neverthrow_1.ResultAsync.combine([pinnedRA, anchorsRA])
|
|
275
|
+
.andThen(([{ workflow, firstStep, workflowHash, pinnedWorkflow, resolvedReferences }, observations]) => {
|
|
270
276
|
const sessionId = idFactory.mintSessionId();
|
|
271
277
|
const runId = idFactory.mintRunId();
|
|
272
278
|
const nodeId = idFactory.mintNodeId();
|
|
@@ -314,11 +320,11 @@ function executeStartWorkflow(input, ctx) {
|
|
|
314
320
|
snapshotPins: [{ snapshotRef, eventIndex: 2, createdByEventId: events[2].eventId }],
|
|
315
321
|
}, emptyTruth))
|
|
316
322
|
.mapErr((cause) => ({ kind: 'session_append_failed', cause }))
|
|
317
|
-
.map(() => ({ workflow, firstStep, workflowHash, pinnedWorkflow, resolvedReferences, sessionId, runId, nodeId }));
|
|
323
|
+
.map(() => ({ workflow, firstStep, workflowHash, pinnedWorkflow, resolvedReferences, sessionId, runId, nodeId, stalePaths, managedStoreError }));
|
|
318
324
|
});
|
|
319
325
|
});
|
|
320
326
|
})
|
|
321
|
-
.andThen(({ pinnedWorkflow, firstStep, workflowHash, sessionId, runId, nodeId, resolvedReferences }) => {
|
|
327
|
+
.andThen(({ pinnedWorkflow, firstStep, workflowHash, sessionId, runId, nodeId, resolvedReferences, stalePaths, managedStoreError }) => {
|
|
322
328
|
const wfRefRes = (0, workflow_hash_ref_js_1.deriveWorkflowHashRef)(workflowHash);
|
|
323
329
|
if (wfRefRes.isErr()) {
|
|
324
330
|
return (0, neverthrow_1.errAsync)({
|
|
@@ -346,6 +352,7 @@ function executeStartWorkflow(input, ctx) {
|
|
|
346
352
|
runId: (0, index_js_1.asRunId)(String(runId)),
|
|
347
353
|
nodeId: (0, index_js_1.asNodeId)(String(nodeId)),
|
|
348
354
|
rehydrateOnly: false,
|
|
355
|
+
cleanResponseFormat: ctx.featureFlags?.isEnabled('cleanResponseFormat') ?? false,
|
|
349
356
|
});
|
|
350
357
|
if (metaResult.isErr()) {
|
|
351
358
|
return (0, neverthrow_1.errAsync)({
|
|
@@ -361,6 +368,9 @@ function executeStartWorkflow(input, ctx) {
|
|
|
361
368
|
meta,
|
|
362
369
|
references: resolvedReferences,
|
|
363
370
|
});
|
|
371
|
+
const startWarnings = managedStoreError !== undefined
|
|
372
|
+
? [`Managed workflow source store was temporarily unavailable (${managedStoreError}). Managed sources were not loaded.`]
|
|
373
|
+
: undefined;
|
|
364
374
|
const parsed = {
|
|
365
375
|
continueToken: tokens.continueToken,
|
|
366
376
|
checkpointToken: tokens.checkpointToken,
|
|
@@ -370,16 +380,34 @@ function executeStartWorkflow(input, ctx) {
|
|
|
370
380
|
nextIntent,
|
|
371
381
|
nextCall: (0, index_js_2.buildNextCall)({ continueToken: tokens.continueToken, isComplete: false, pending }),
|
|
372
382
|
...(stalePaths.length > 0 ? { staleRoots: [...stalePaths] } : {}),
|
|
383
|
+
...(startWarnings !== undefined ? { warnings: startWarnings } : {}),
|
|
373
384
|
};
|
|
374
385
|
return (0, neverthrow_1.okAsync)({ response: parsed, contentEnvelope });
|
|
375
386
|
});
|
|
376
|
-
})
|
|
387
|
+
});
|
|
377
388
|
}
|
|
378
389
|
function enrichPinnedSnapshotWithResolvedReferences(snapshot, references, workspacePath) {
|
|
379
390
|
if (references.length === 0) {
|
|
380
391
|
return (0, neverthrow_1.okAsync)({ snapshot, resolvedReferences: [] });
|
|
381
392
|
}
|
|
382
|
-
|
|
393
|
+
const allUnresolved = references.map((ref) => ({
|
|
394
|
+
id: ref.id,
|
|
395
|
+
title: ref.title,
|
|
396
|
+
source: ref.source,
|
|
397
|
+
purpose: ref.purpose,
|
|
398
|
+
authoritative: ref.authoritative,
|
|
399
|
+
resolveFrom: (ref.resolveFrom ?? 'workspace'),
|
|
400
|
+
status: 'unresolved',
|
|
401
|
+
}));
|
|
402
|
+
const resolutionPromise = (0, with_timeout_js_1.withTimeout)((0, v2_reference_resolver_js_1.resolveWorkflowReferences)(references, workspacePath), REFERENCE_RESOLUTION_TIMEOUT_MS, 'reference_resolution').catch(() => null);
|
|
403
|
+
return neverthrow_1.ResultAsync.fromPromise(resolutionPromise, () => ({ kind: 'reference_resolution_failed' })).map((result) => {
|
|
404
|
+
if (result === null) {
|
|
405
|
+
console.warn('[workrail:reference-resolution] timed out; all references marked unresolved');
|
|
406
|
+
return {
|
|
407
|
+
snapshot: { ...snapshot, resolvedReferences: [...allUnresolved] },
|
|
408
|
+
resolvedReferences: allUnresolved,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
383
411
|
for (const warning of result.warnings) {
|
|
384
412
|
console.warn(`[workrail:reference-resolution] ${warning.message}`);
|
|
385
413
|
}
|
|
@@ -15,6 +15,7 @@ const neverthrow_1 = require("neverthrow");
|
|
|
15
15
|
const types_js_1 = require("../types.js");
|
|
16
16
|
const error_mapper_js_1 = require("../error-mapper.js");
|
|
17
17
|
const v2_execution_helpers_js_1 = require("./v2-execution-helpers.js");
|
|
18
|
+
const assert_never_js_1 = require("../../runtime/assert-never.js");
|
|
18
19
|
const v1_to_v2_shim_js_1 = require("../../v2/read-only/v1-to-v2-shim.js");
|
|
19
20
|
const hashing_js_1 = require("../../v2/durable-core/canonical/hashing.js");
|
|
20
21
|
const TIMEOUT_MS = 30000;
|
|
@@ -35,8 +36,7 @@ function readCurrentSpecVersion() {
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
const CURRENT_SPEC_VERSION = readCurrentSpecVersion();
|
|
38
|
-
|
|
39
|
-
function shouldShowStaleness(category, devMode = DEV_STALENESS) {
|
|
39
|
+
function shouldShowStaleness(category, devMode = (0, dev_mode_js_1.isDevMode)()) {
|
|
40
40
|
if (devMode)
|
|
41
41
|
return true;
|
|
42
42
|
return category === 'personal' || category === 'rooted_sharing' || category === 'external';
|
|
@@ -96,6 +96,7 @@ function computeWorkflowStaleness(stamp, currentVersion) {
|
|
|
96
96
|
specVersionAtLastReview: stamp,
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
|
+
const dev_mode_js_1 = require("../dev-mode.js");
|
|
99
100
|
const with_timeout_js_1 = require("./shared/with-timeout.js");
|
|
100
101
|
const request_workflow_reader_js_1 = require("./shared/request-workflow-reader.js");
|
|
101
102
|
const remembered_roots_js_1 = require("./shared/remembered-roots.js");
|
|
@@ -443,6 +444,7 @@ function deriveSourceCatalogEntry(options) {
|
|
|
443
444
|
case 'plugin':
|
|
444
445
|
return { sourceKey, category: 'external', source: { kind: source.kind, displayName }, sourceMode: 'live_directory', effectiveWorkflowCount: effective, totalWorkflowCount: total, shadowedWorkflowCount: shadowed };
|
|
445
446
|
}
|
|
447
|
+
(0, assert_never_js_1.assertNever)(source);
|
|
446
448
|
}
|
|
447
449
|
function deriveSourceKey(source) {
|
|
448
450
|
switch (source.kind) {
|
|
@@ -2443,6 +2443,7 @@ export declare const V2StartWorkflowOutputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
2443
2443
|
tool: "continue_workflow";
|
|
2444
2444
|
}>>;
|
|
2445
2445
|
staleRoots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
2446
|
+
warnings: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
2446
2447
|
}, "strip", z.ZodTypeAny, {
|
|
2447
2448
|
pending: {
|
|
2448
2449
|
stepId: string;
|
|
@@ -2462,6 +2463,7 @@ export declare const V2StartWorkflowOutputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
2462
2463
|
};
|
|
2463
2464
|
tool: "continue_workflow";
|
|
2464
2465
|
} | null;
|
|
2466
|
+
warnings?: string[] | undefined;
|
|
2465
2467
|
continueToken?: string | undefined;
|
|
2466
2468
|
checkpointToken?: string | undefined;
|
|
2467
2469
|
staleRoots?: string[] | undefined;
|
|
@@ -2484,6 +2486,7 @@ export declare const V2StartWorkflowOutputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
2484
2486
|
};
|
|
2485
2487
|
tool: "continue_workflow";
|
|
2486
2488
|
} | null;
|
|
2489
|
+
warnings?: string[] | undefined;
|
|
2487
2490
|
continueToken?: string | undefined;
|
|
2488
2491
|
checkpointToken?: string | undefined;
|
|
2489
2492
|
staleRoots?: string[] | undefined;
|
|
@@ -2506,6 +2509,7 @@ export declare const V2StartWorkflowOutputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
2506
2509
|
};
|
|
2507
2510
|
tool: "continue_workflow";
|
|
2508
2511
|
} | null;
|
|
2512
|
+
warnings?: string[] | undefined;
|
|
2509
2513
|
continueToken?: string | undefined;
|
|
2510
2514
|
checkpointToken?: string | undefined;
|
|
2511
2515
|
staleRoots?: string[] | undefined;
|
|
@@ -2528,6 +2532,7 @@ export declare const V2StartWorkflowOutputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
2528
2532
|
};
|
|
2529
2533
|
tool: "continue_workflow";
|
|
2530
2534
|
} | null;
|
|
2535
|
+
warnings?: string[] | undefined;
|
|
2531
2536
|
continueToken?: string | undefined;
|
|
2532
2537
|
checkpointToken?: string | undefined;
|
|
2533
2538
|
staleRoots?: string[] | undefined;
|
|
@@ -392,6 +392,8 @@ exports.V2StartWorkflowOutputSchema = zod_1.z.object({
|
|
|
392
392
|
staleRoots: zod_1.z.array(zod_1.z.string()).optional().describe('Workflow source paths that were inaccessible during discovery (missing remembered roots or missing managed source directories). ' +
|
|
393
393
|
'Workflows from these paths were not included in this response. ' +
|
|
394
394
|
'These paths will be rechecked on the next call.'),
|
|
395
|
+
warnings: zod_1.z.array(zod_1.z.string()).optional().describe('Non-fatal warnings about workflow source availability. ' +
|
|
396
|
+
'The workflow was started successfully but some sources may have been unavailable (e.g., managed source store temporarily inaccessible).'),
|
|
395
397
|
}).refine((data) => (data.pending ? data.continueToken != null : true), { message: 'continueToken is required when a pending step exists' });
|
|
396
398
|
exports.CreateSessionOutputSchema = zod_1.z.object({
|
|
397
399
|
sessionId: zod_1.z.string().min(1),
|
package/dist/mcp/server.js
CHANGED
|
@@ -217,10 +217,11 @@ async function composeServer() {
|
|
|
217
217
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
218
218
|
tools,
|
|
219
219
|
}));
|
|
220
|
-
const
|
|
220
|
+
const devMode = (0, dev_mode_js_1.isDevMode)();
|
|
221
|
+
const timingSink = devMode
|
|
221
222
|
? (0, tool_call_timing_js_1.composeSinks)((0, tool_call_timing_js_1.createRingBufferSink)(timingRingBuffer), (0, tool_call_timing_js_1.createDevPerfSink)())
|
|
222
223
|
: (0, tool_call_timing_js_1.createRingBufferSink)(timingRingBuffer);
|
|
223
|
-
if (
|
|
224
|
+
if (devMode) {
|
|
224
225
|
console.error('[PerfTrace] WORKRAIL_DEV=1 -- tool call timing active');
|
|
225
226
|
}
|
|
226
227
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
@@ -8,5 +8,5 @@ export interface FormattedResponse {
|
|
|
8
8
|
readonly references?: FormattedReferences;
|
|
9
9
|
readonly supplements?: readonly FormattedSupplement[];
|
|
10
10
|
}
|
|
11
|
-
export declare function formatV2ExecutionResponse(data: unknown): FormattedResponse | null;
|
|
11
|
+
export declare function formatV2ExecutionResponse(data: unknown, cleanResponseFormat: boolean): FormattedResponse | null;
|
|
12
12
|
export declare function formatV2ResumeResponse(data: unknown): FormattedResponse | null;
|
|
@@ -4,7 +4,6 @@ exports.formatV2ExecutionResponse = formatV2ExecutionResponse;
|
|
|
4
4
|
exports.formatV2ResumeResponse = formatV2ResumeResponse;
|
|
5
5
|
const render_envelope_js_1 = require("./render-envelope.js");
|
|
6
6
|
const response_supplements_js_1 = require("./response-supplements.js");
|
|
7
|
-
const env_flags_js_1 = require("../env-flags.js");
|
|
8
7
|
function isV2ExecutionResponse(data) {
|
|
9
8
|
if (typeof data !== 'object' || data === null)
|
|
10
9
|
return false;
|
|
@@ -348,11 +347,11 @@ function renderReferencesSection(contentEnvelope, lifecycle) {
|
|
|
348
347
|
return null;
|
|
349
348
|
}
|
|
350
349
|
}
|
|
351
|
-
function formatV2ExecutionResponse(data) {
|
|
350
|
+
function formatV2ExecutionResponse(data, cleanResponseFormat) {
|
|
352
351
|
const renderInput = deriveRenderInput(data);
|
|
353
352
|
if (!renderInput)
|
|
354
353
|
return null;
|
|
355
|
-
const cleanFormat =
|
|
354
|
+
const cleanFormat = cleanResponseFormat;
|
|
356
355
|
const { response, lifecycle, contentEnvelope } = renderInput;
|
|
357
356
|
const references = renderReferencesSection(contentEnvelope, lifecycle);
|
|
358
357
|
if (cleanFormat) {
|