@mondaydotcomorg/atp-server 0.17.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +489 -0
- package/dist/aggregator/index.d.ts +59 -0
- package/dist/aggregator/index.d.ts.map +1 -0
- package/dist/aggregator/index.js +171 -0
- package/dist/aggregator/index.js.map +1 -0
- package/dist/callback/index.d.ts +98 -0
- package/dist/callback/index.d.ts.map +1 -0
- package/dist/callback/index.js +136 -0
- package/dist/callback/index.js.map +1 -0
- package/dist/client-sessions.d.ts +82 -0
- package/dist/client-sessions.d.ts.map +1 -0
- package/dist/client-sessions.js +174 -0
- package/dist/client-sessions.js.map +1 -0
- package/dist/controllers/definitions.controller.d.ts +4 -0
- package/dist/controllers/definitions.controller.d.ts.map +1 -0
- package/dist/controllers/definitions.controller.js +11 -0
- package/dist/controllers/definitions.controller.js.map +1 -0
- package/dist/controllers/execute.controller.d.ts +18 -0
- package/dist/controllers/execute.controller.d.ts.map +1 -0
- package/dist/controllers/execute.controller.js +122 -0
- package/dist/controllers/execute.controller.js.map +1 -0
- package/dist/controllers/info.controller.d.ts +3 -0
- package/dist/controllers/info.controller.d.ts.map +1 -0
- package/dist/controllers/info.controller.js +13 -0
- package/dist/controllers/info.controller.js.map +1 -0
- package/dist/controllers/resume.controller.d.ts +11 -0
- package/dist/controllers/resume.controller.d.ts.map +1 -0
- package/dist/controllers/resume.controller.js +61 -0
- package/dist/controllers/resume.controller.js.map +1 -0
- package/dist/controllers/search.controller.d.ts +4 -0
- package/dist/controllers/search.controller.d.ts.map +1 -0
- package/dist/controllers/search.controller.js +7 -0
- package/dist/controllers/search.controller.js.map +1 -0
- package/dist/controllers/stream.controller.d.ts +19 -0
- package/dist/controllers/stream.controller.d.ts.map +1 -0
- package/dist/controllers/stream.controller.js +141 -0
- package/dist/controllers/stream.controller.js.map +1 -0
- package/dist/core/config.d.ts +161 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +7 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/http.d.ts +4 -0
- package/dist/core/http.d.ts.map +1 -0
- package/dist/core/http.js +17 -0
- package/dist/core/http.js.map +1 -0
- package/dist/create-server.d.ts +120 -0
- package/dist/create-server.d.ts.map +1 -0
- package/dist/create-server.js +423 -0
- package/dist/create-server.js.map +1 -0
- package/dist/execution-state/index.d.ts +95 -0
- package/dist/execution-state/index.d.ts.map +1 -0
- package/dist/execution-state/index.js +128 -0
- package/dist/execution-state/index.js.map +1 -0
- package/dist/executor/ast-provenance-bridge.d.ts +12 -0
- package/dist/executor/ast-provenance-bridge.d.ts.map +1 -0
- package/dist/executor/ast-provenance-bridge.js +66 -0
- package/dist/executor/ast-provenance-bridge.js.map +1 -0
- package/dist/executor/ast-tracking-runtime.d.ts +7 -0
- package/dist/executor/ast-tracking-runtime.d.ts.map +1 -0
- package/dist/executor/ast-tracking-runtime.js +559 -0
- package/dist/executor/ast-tracking-runtime.js.map +1 -0
- package/dist/executor/bootstrap-generated.d.ts +32 -0
- package/dist/executor/bootstrap-generated.d.ts.map +1 -0
- package/dist/executor/bootstrap-generated.js +90 -0
- package/dist/executor/bootstrap-generated.js.map +1 -0
- package/dist/executor/compiler-config.d.ts +32 -0
- package/dist/executor/compiler-config.d.ts.map +1 -0
- package/dist/executor/compiler-config.js +99 -0
- package/dist/executor/compiler-config.js.map +1 -0
- package/dist/executor/constants.d.ts +4 -0
- package/dist/executor/constants.d.ts.map +1 -0
- package/dist/executor/constants.js +4 -0
- package/dist/executor/constants.js.map +1 -0
- package/dist/executor/error-handler.d.ts +9 -0
- package/dist/executor/error-handler.d.ts.map +1 -0
- package/dist/executor/error-handler.js +95 -0
- package/dist/executor/error-handler.js.map +1 -0
- package/dist/executor/execution-error-handler.d.ts +7 -0
- package/dist/executor/execution-error-handler.d.ts.map +1 -0
- package/dist/executor/execution-error-handler.js +136 -0
- package/dist/executor/execution-error-handler.js.map +1 -0
- package/dist/executor/executor.d.ts +20 -0
- package/dist/executor/executor.d.ts.map +1 -0
- package/dist/executor/executor.js +452 -0
- package/dist/executor/executor.js.map +1 -0
- package/dist/executor/index.d.ts +4 -0
- package/dist/executor/index.d.ts.map +1 -0
- package/dist/executor/index.js +3 -0
- package/dist/executor/index.js.map +1 -0
- package/dist/executor/resume-handler.d.ts +9 -0
- package/dist/executor/resume-handler.d.ts.map +1 -0
- package/dist/executor/resume-handler.js +22 -0
- package/dist/executor/resume-handler.js.map +1 -0
- package/dist/executor/sandbox-builder.d.ts +29 -0
- package/dist/executor/sandbox-builder.d.ts.map +1 -0
- package/dist/executor/sandbox-builder.js +538 -0
- package/dist/executor/sandbox-builder.js.map +1 -0
- package/dist/executor/sandbox-injector.d.ts +7 -0
- package/dist/executor/sandbox-injector.d.ts.map +1 -0
- package/dist/executor/sandbox-injector.js +293 -0
- package/dist/executor/sandbox-injector.js.map +1 -0
- package/dist/executor/types.d.ts +21 -0
- package/dist/executor/types.d.ts.map +1 -0
- package/dist/executor/types.js +2 -0
- package/dist/executor/types.js.map +1 -0
- package/dist/explorer/index.d.ts +69 -0
- package/dist/explorer/index.d.ts.map +1 -0
- package/dist/explorer/index.js +228 -0
- package/dist/explorer/index.js.map +1 -0
- package/dist/handlers/definitions.handler.d.ts +3 -0
- package/dist/handlers/definitions.handler.d.ts.map +1 -0
- package/dist/handlers/definitions.handler.js +11 -0
- package/dist/handlers/definitions.handler.js.map +1 -0
- package/dist/handlers/execute.handler.d.ts +7 -0
- package/dist/handlers/execute.handler.d.ts.map +1 -0
- package/dist/handlers/execute.handler.js +225 -0
- package/dist/handlers/execute.handler.js.map +1 -0
- package/dist/handlers/explorer.handler.d.ts +4 -0
- package/dist/handlers/explorer.handler.d.ts.map +1 -0
- package/dist/handlers/explorer.handler.js +10 -0
- package/dist/handlers/explorer.handler.js.map +1 -0
- package/dist/handlers/init.handler.d.ts +5 -0
- package/dist/handlers/init.handler.d.ts.map +1 -0
- package/dist/handlers/init.handler.js +41 -0
- package/dist/handlers/init.handler.js.map +1 -0
- package/dist/handlers/resume.handler.d.ts +6 -0
- package/dist/handlers/resume.handler.d.ts.map +1 -0
- package/dist/handlers/resume.handler.js +256 -0
- package/dist/handlers/resume.handler.js.map +1 -0
- package/dist/handlers/search.handler.d.ts +5 -0
- package/dist/handlers/search.handler.d.ts.map +1 -0
- package/dist/handlers/search.handler.js +11 -0
- package/dist/handlers/search.handler.js.map +1 -0
- package/dist/http/request-handler.d.ts +15 -0
- package/dist/http/request-handler.d.ts.map +1 -0
- package/dist/http/request-handler.js +94 -0
- package/dist/http/request-handler.js.map +1 -0
- package/dist/http/router.d.ts +4 -0
- package/dist/http/router.d.ts.map +1 -0
- package/dist/http/router.js +32 -0
- package/dist/http/router.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/instrumentation/index.d.ts +5 -0
- package/dist/instrumentation/index.d.ts.map +1 -0
- package/dist/instrumentation/index.js +5 -0
- package/dist/instrumentation/index.js.map +1 -0
- package/dist/instrumentation/serializer.d.ts +61 -0
- package/dist/instrumentation/serializer.d.ts.map +1 -0
- package/dist/instrumentation/serializer.js +334 -0
- package/dist/instrumentation/serializer.js.map +1 -0
- package/dist/instrumentation/state-manager.d.ts +61 -0
- package/dist/instrumentation/state-manager.d.ts.map +1 -0
- package/dist/instrumentation/state-manager.js +205 -0
- package/dist/instrumentation/state-manager.js.map +1 -0
- package/dist/instrumentation/transformer.d.ts +9 -0
- package/dist/instrumentation/transformer.d.ts.map +1 -0
- package/dist/instrumentation/transformer.js +70 -0
- package/dist/instrumentation/transformer.js.map +1 -0
- package/dist/instrumentation/types.d.ts +59 -0
- package/dist/instrumentation/types.d.ts.map +1 -0
- package/dist/instrumentation/types.js +5 -0
- package/dist/instrumentation/types.js.map +1 -0
- package/dist/middleware/audit.d.ts +18 -0
- package/dist/middleware/audit.d.ts.map +1 -0
- package/dist/middleware/audit.js +76 -0
- package/dist/middleware/audit.js.map +1 -0
- package/dist/openapi/index.d.ts +133 -0
- package/dist/openapi/index.d.ts.map +1 -0
- package/dist/openapi/index.js +235 -0
- package/dist/openapi/index.js.map +1 -0
- package/dist/openapi-loader.d.ts +87 -0
- package/dist/openapi-loader.d.ts.map +1 -0
- package/dist/openapi-loader.js +491 -0
- package/dist/openapi-loader.js.map +1 -0
- package/dist/routes/index.d.ts +21 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +47 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/search/index.d.ts +48 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +156 -0
- package/dist/search/index.js.map +1 -0
- package/dist/security/index.d.ts +2 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +2 -0
- package/dist/security/index.js.map +1 -0
- package/dist/shutdown.d.ts +19 -0
- package/dist/shutdown.d.ts.map +1 -0
- package/dist/shutdown.js +87 -0
- package/dist/shutdown.js.map +1 -0
- package/dist/utils/banner.d.ts +12 -0
- package/dist/utils/banner.d.ts.map +1 -0
- package/dist/utils/banner.js +18 -0
- package/dist/utils/banner.js.map +1 -0
- package/dist/utils/context.d.ts +16 -0
- package/dist/utils/context.d.ts.map +1 -0
- package/dist/utils/context.js +44 -0
- package/dist/utils/context.js.map +1 -0
- package/dist/utils/error.d.ts +8 -0
- package/dist/utils/error.d.ts.map +1 -0
- package/dist/utils/error.js +17 -0
- package/dist/utils/error.js.map +1 -0
- package/dist/utils/hint-based-instrumentation.d.ts +14 -0
- package/dist/utils/hint-based-instrumentation.d.ts.map +1 -0
- package/dist/utils/hint-based-instrumentation.js +84 -0
- package/dist/utils/hint-based-instrumentation.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/info.d.ts +20 -0
- package/dist/utils/info.d.ts.map +1 -0
- package/dist/utils/info.js +15 -0
- package/dist/utils/info.js.map +1 -0
- package/dist/utils/provenance-reattachment.d.ts +32 -0
- package/dist/utils/provenance-reattachment.d.ts.map +1 -0
- package/dist/utils/provenance-reattachment.js +115 -0
- package/dist/utils/provenance-reattachment.js.map +1 -0
- package/dist/utils/request.d.ts +21 -0
- package/dist/utils/request.d.ts.map +1 -0
- package/dist/utils/request.js +44 -0
- package/dist/utils/request.js.map +1 -0
- package/dist/utils/response.d.ts +30 -0
- package/dist/utils/response.d.ts.map +1 -0
- package/dist/utils/response.js +53 -0
- package/dist/utils/response.js.map +1 -0
- package/dist/utils/runtime-types.d.ts +6 -0
- package/dist/utils/runtime-types.d.ts.map +1 -0
- package/dist/utils/runtime-types.js +14 -0
- package/dist/utils/runtime-types.js.map +1 -0
- package/dist/utils/schema.d.ts +9 -0
- package/dist/utils/schema.d.ts.map +1 -0
- package/dist/utils/schema.js +13 -0
- package/dist/utils/schema.js.map +1 -0
- package/dist/utils/token-emitter.d.ts +21 -0
- package/dist/utils/token-emitter.d.ts.map +1 -0
- package/dist/utils/token-emitter.js +129 -0
- package/dist/utils/token-emitter.js.map +1 -0
- package/dist/validator/index.d.ts +36 -0
- package/dist/validator/index.d.ts.map +1 -0
- package/dist/validator/index.js +224 -0
- package/dist/validator/index.js.map +1 -0
- package/package.json +68 -0
- package/src/aggregator/index.ts +207 -0
- package/src/callback/index.ts +191 -0
- package/src/client-sessions.ts +234 -0
- package/src/controllers/definitions.controller.ts +19 -0
- package/src/controllers/execute.controller.ts +166 -0
- package/src/controllers/info.controller.ts +14 -0
- package/src/controllers/resume.controller.ts +92 -0
- package/src/controllers/search.controller.ts +16 -0
- package/src/controllers/stream.controller.ts +190 -0
- package/src/core/config.ts +180 -0
- package/src/core/http.ts +21 -0
- package/src/create-server.ts +536 -0
- package/src/execution-state/index.ts +204 -0
- package/src/executor/ast-provenance-bridge.ts +80 -0
- package/src/executor/ast-tracking-runtime.ts +558 -0
- package/src/executor/bootstrap-generated.ts +90 -0
- package/src/executor/compiler-config.ts +146 -0
- package/src/executor/constants.ts +5 -0
- package/src/executor/error-handler.ts +118 -0
- package/src/executor/execution-error-handler.ts +178 -0
- package/src/executor/executor.ts +631 -0
- package/src/executor/index.ts +3 -0
- package/src/executor/resume-handler.ts +39 -0
- package/src/executor/sandbox-builder.ts +684 -0
- package/src/executor/sandbox-injector.ts +345 -0
- package/src/executor/types.ts +22 -0
- package/src/explorer/index.ts +297 -0
- package/src/handlers/definitions.handler.ts +13 -0
- package/src/handlers/execute.handler.ts +286 -0
- package/src/handlers/explorer.handler.ts +18 -0
- package/src/handlers/init.handler.ts +53 -0
- package/src/handlers/resume.handler.ts +316 -0
- package/src/handlers/search.handler.ts +32 -0
- package/src/http/request-handler.ts +117 -0
- package/src/http/router.ts +29 -0
- package/src/index.ts +60 -0
- package/src/instrumentation/index.ts +4 -0
- package/src/instrumentation/serializer.ts +421 -0
- package/src/instrumentation/state-manager.ts +237 -0
- package/src/instrumentation/transformer.ts +84 -0
- package/src/instrumentation/types.ts +76 -0
- package/src/middleware/audit.ts +101 -0
- package/src/openapi/index.ts +378 -0
- package/src/openapi-loader.ts +744 -0
- package/src/routes/index.ts +93 -0
- package/src/search/index.ts +216 -0
- package/src/security/index.ts +1 -0
- package/src/shutdown.ts +108 -0
- package/src/utils/banner.ts +25 -0
- package/src/utils/context.ts +58 -0
- package/src/utils/error.ts +25 -0
- package/src/utils/hint-based-instrumentation.ts +99 -0
- package/src/utils/index.ts +15 -0
- package/src/utils/info.ts +31 -0
- package/src/utils/provenance-reattachment.ts +144 -0
- package/src/utils/request.ts +53 -0
- package/src/utils/response.ts +69 -0
- package/src/utils/runtime-types.ts +14 -0
- package/src/utils/schema.ts +18 -0
- package/src/utils/token-emitter.ts +182 -0
- package/src/validator/index.ts +253 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import type { RequestContext, ResolvedServerConfig } from '../core/config.js';
|
|
2
|
+
import type { SandboxExecutor } from '../executor/index.js';
|
|
3
|
+
import type { ExecutionStateManager } from '../execution-state/index.js';
|
|
4
|
+
import type { ClientSessionManager } from '../client-sessions.js';
|
|
5
|
+
import type { AuditSink, AuditEvent } from '@mondaydotcomorg/atp-protocol';
|
|
6
|
+
import { ExecutionStatus, ProvenanceMode } from '@mondaydotcomorg/atp-protocol';
|
|
7
|
+
import { nanoid } from 'nanoid';
|
|
8
|
+
import {
|
|
9
|
+
captureProvenanceSnapshot,
|
|
10
|
+
verifyProvenanceHints,
|
|
11
|
+
type ProvenanceMetadata,
|
|
12
|
+
} from '@mondaydotcomorg/atp-provenance';
|
|
13
|
+
import { emitProvenanceTokens } from '../utils/token-emitter.js';
|
|
14
|
+
import { storeHintMap, clearHintMap } from '../utils/provenance-reattachment.js';
|
|
15
|
+
import { log } from '@mondaydotcomorg/atp-runtime';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Recursively remove __prov_id__ properties from result
|
|
19
|
+
* Handles both enumerable and non-enumerable properties
|
|
20
|
+
*/
|
|
21
|
+
function cleanProvenanceIds(value: unknown): unknown {
|
|
22
|
+
if (value === null || value === undefined) {
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
if (typeof value !== 'object') {
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
if (Array.isArray(value)) {
|
|
29
|
+
return value.map((item) => cleanProvenanceIds(item));
|
|
30
|
+
}
|
|
31
|
+
const cleaned: Record<string, unknown> = {};
|
|
32
|
+
// Use Object.getOwnPropertyNames to get ALL properties (including non-enumerable)
|
|
33
|
+
const allKeys = Object.getOwnPropertyNames(value);
|
|
34
|
+
for (const key of allKeys) {
|
|
35
|
+
if (key !== '__prov_id__') {
|
|
36
|
+
cleaned[key] = cleanProvenanceIds((value as Record<string, unknown>)[key]);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return cleaned;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function handleExecute(
|
|
43
|
+
ctx: RequestContext,
|
|
44
|
+
executor: SandboxExecutor,
|
|
45
|
+
stateManager: ExecutionStateManager,
|
|
46
|
+
config: ResolvedServerConfig,
|
|
47
|
+
auditSink?: AuditSink,
|
|
48
|
+
sessionManager?: ClientSessionManager
|
|
49
|
+
): Promise<unknown> {
|
|
50
|
+
const request = ctx.body as any;
|
|
51
|
+
const code = request.code || '';
|
|
52
|
+
const requestConfig = request.config || request.options || {};
|
|
53
|
+
|
|
54
|
+
if (sessionManager && ctx.clientId && ctx.clientId !== 'anonymous') {
|
|
55
|
+
const requestToken = ctx.headers['authorization']?.replace('Bearer ', '');
|
|
56
|
+
|
|
57
|
+
if (!requestToken) {
|
|
58
|
+
log.warn('Execute attempt without token', { clientId: ctx.clientId });
|
|
59
|
+
ctx.throw(401, 'Authentication error: Invalid token or client ID mismatch');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const isValid = await sessionManager.verifyClient(ctx.clientId, requestToken);
|
|
63
|
+
if (!isValid) {
|
|
64
|
+
log.warn('Execute attempt with invalid token', { clientId: ctx.clientId });
|
|
65
|
+
ctx.throw(403, 'Authentication error: Invalid token or client ID mismatch');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const memoryInBytes =
|
|
70
|
+
requestConfig.memoryLimit || requestConfig.memory || config.execution.memory;
|
|
71
|
+
|
|
72
|
+
let clientServices = requestConfig.clientServices;
|
|
73
|
+
if (sessionManager && ctx.clientId && ctx.clientId !== 'anonymous') {
|
|
74
|
+
try {
|
|
75
|
+
const session = await sessionManager.getSession(ctx.clientId);
|
|
76
|
+
const hasTools = session?.tools && session.tools.length > 0;
|
|
77
|
+
|
|
78
|
+
clientServices = {
|
|
79
|
+
...clientServices,
|
|
80
|
+
hasTools: hasTools || false,
|
|
81
|
+
};
|
|
82
|
+
} catch (error) {}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const executionConfig = {
|
|
86
|
+
timeout: requestConfig.timeout || config.execution.timeout,
|
|
87
|
+
maxMemory: memoryInBytes,
|
|
88
|
+
maxLLMCalls: requestConfig.llmCalls || config.execution.llmCalls,
|
|
89
|
+
allowedAPIs: [],
|
|
90
|
+
allowLLMCalls: true,
|
|
91
|
+
clientServices,
|
|
92
|
+
provenanceMode:
|
|
93
|
+
requestConfig.provenanceMode || config.execution.provenanceMode || ProvenanceMode.NONE,
|
|
94
|
+
securityPolicies: config.execution.securityPolicies || [],
|
|
95
|
+
provenanceHints: requestConfig.provenanceHints,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// Verify provenance hints if provided
|
|
99
|
+
let hintMap: Map<string, ProvenanceMetadata> | undefined;
|
|
100
|
+
const prelimExecutionId = nanoid();
|
|
101
|
+
if (
|
|
102
|
+
executionConfig.provenanceHints &&
|
|
103
|
+
executionConfig.provenanceHints.length > 0 &&
|
|
104
|
+
executionConfig.provenanceMode !== ProvenanceMode.NONE &&
|
|
105
|
+
ctx.cache
|
|
106
|
+
) {
|
|
107
|
+
try {
|
|
108
|
+
// Cap hints at 1000
|
|
109
|
+
if (executionConfig.provenanceHints.length > 1000) {
|
|
110
|
+
log.warn('Provenance hints capped', {
|
|
111
|
+
provided: executionConfig.provenanceHints.length,
|
|
112
|
+
capped: 1000,
|
|
113
|
+
});
|
|
114
|
+
ctx.throw(400, 'Too many provenance hints (max 1000)');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
hintMap = await verifyProvenanceHints(
|
|
118
|
+
executionConfig.provenanceHints,
|
|
119
|
+
ctx.clientId || 'anonymous',
|
|
120
|
+
prelimExecutionId,
|
|
121
|
+
ctx.cache,
|
|
122
|
+
1000 // maxHints
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// Store hint map for this execution
|
|
126
|
+
if (hintMap && hintMap.size > 0) {
|
|
127
|
+
storeHintMap(prelimExecutionId, hintMap);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
log.info('Provenance hints verified', {
|
|
131
|
+
hintsProvided: executionConfig.provenanceHints.length,
|
|
132
|
+
hintsValid: hintMap.size,
|
|
133
|
+
executionId: prelimExecutionId,
|
|
134
|
+
});
|
|
135
|
+
} catch (error) {
|
|
136
|
+
log.error('Failed to verify provenance hints', { error });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const startTime = Date.now();
|
|
141
|
+
|
|
142
|
+
if (auditSink) {
|
|
143
|
+
const startEvent: AuditEvent = {
|
|
144
|
+
eventId: nanoid(),
|
|
145
|
+
timestamp: startTime,
|
|
146
|
+
clientId: ctx.clientId || 'anonymous',
|
|
147
|
+
eventType: 'execution',
|
|
148
|
+
action: 'start',
|
|
149
|
+
code,
|
|
150
|
+
status: 'success',
|
|
151
|
+
};
|
|
152
|
+
await auditSink.write(startEvent).catch(() => {});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Pass the prelimExecutionId so executor can access hints
|
|
156
|
+
const result = await executor.execute(code, executionConfig, ctx.clientId, {
|
|
157
|
+
callbackHistory: [],
|
|
158
|
+
newCallbackResult: undefined,
|
|
159
|
+
executionId: prelimExecutionId,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Emit provenance tokens for completed executions
|
|
163
|
+
if (
|
|
164
|
+
result.status === ExecutionStatus.COMPLETED &&
|
|
165
|
+
executionConfig.provenanceMode &&
|
|
166
|
+
executionConfig.provenanceMode !== ProvenanceMode.NONE &&
|
|
167
|
+
ctx.cache &&
|
|
168
|
+
(result as any).provenanceSnapshot
|
|
169
|
+
) {
|
|
170
|
+
try {
|
|
171
|
+
log.info('Attempting to emit provenance tokens from snapshot', {
|
|
172
|
+
executionId: result.executionId,
|
|
173
|
+
provenanceMode: executionConfig.provenanceMode,
|
|
174
|
+
hasCache: !!ctx.cache,
|
|
175
|
+
hasSnapshot: !!(result as any).provenanceSnapshot,
|
|
176
|
+
resultType: typeof result.result,
|
|
177
|
+
});
|
|
178
|
+
const tokens = await emitProvenanceTokens(
|
|
179
|
+
result.result,
|
|
180
|
+
ctx.clientId || 'anonymous',
|
|
181
|
+
result.executionId,
|
|
182
|
+
executionConfig.provenanceMode,
|
|
183
|
+
ctx.cache,
|
|
184
|
+
log.child({ executionId: result.executionId }),
|
|
185
|
+
5000, // maxTokens
|
|
186
|
+
3600, // tokenTTL (1hr)
|
|
187
|
+
(result as any).provenanceSnapshot // Pass snapshot
|
|
188
|
+
);
|
|
189
|
+
log.info('Provenance tokens emitted', {
|
|
190
|
+
executionId: result.executionId,
|
|
191
|
+
tokenCount: tokens.length,
|
|
192
|
+
});
|
|
193
|
+
if (tokens.length > 0) {
|
|
194
|
+
(result as any).provenanceTokens = tokens;
|
|
195
|
+
}
|
|
196
|
+
} catch (error) {
|
|
197
|
+
log.error('Failed to emit provenance tokens', { error, executionId: result.executionId });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Always clean snapshot and provenance IDs before returning
|
|
202
|
+
delete (result as any).provenanceSnapshot;
|
|
203
|
+
if (result.result && typeof result.result === 'object') {
|
|
204
|
+
const hasProv = '__prov_id__' in result.result;
|
|
205
|
+
(result as any).result = cleanProvenanceIds(result.result);
|
|
206
|
+
const stillHasProv =
|
|
207
|
+
result.result && typeof result.result === 'object' && '__prov_id__' in result.result;
|
|
208
|
+
if (hasProv && !stillHasProv) {
|
|
209
|
+
log.debug('Successfully cleaned __prov_id__ from result');
|
|
210
|
+
} else if (hasProv && stillHasProv) {
|
|
211
|
+
log.warn('Failed to clean __prov_id__ from result!');
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (auditSink) {
|
|
216
|
+
const endEvent: AuditEvent = {
|
|
217
|
+
eventId: nanoid(),
|
|
218
|
+
timestamp: Date.now(),
|
|
219
|
+
clientId: ctx.clientId || 'anonymous',
|
|
220
|
+
eventType: 'execution',
|
|
221
|
+
action: result.status === ExecutionStatus.PAUSED ? 'pause' : 'complete',
|
|
222
|
+
resourceId: result.executionId,
|
|
223
|
+
status:
|
|
224
|
+
result.status === ExecutionStatus.COMPLETED
|
|
225
|
+
? 'success'
|
|
226
|
+
: result.status === ExecutionStatus.FAILED
|
|
227
|
+
? 'failed'
|
|
228
|
+
: 'paused',
|
|
229
|
+
duration: Date.now() - startTime,
|
|
230
|
+
memoryUsed: result.stats?.memoryUsed,
|
|
231
|
+
llmCallsCount: result.stats?.llmCallsCount,
|
|
232
|
+
error: result.error
|
|
233
|
+
? {
|
|
234
|
+
message: result.error.message,
|
|
235
|
+
code: result.error.code,
|
|
236
|
+
stack: result.error.stack,
|
|
237
|
+
}
|
|
238
|
+
: undefined,
|
|
239
|
+
};
|
|
240
|
+
await auditSink.write(endEvent).catch(() => {});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (
|
|
244
|
+
result.status === 'paused' &&
|
|
245
|
+
(result.needsCallback || result.needsCallbacks) &&
|
|
246
|
+
result.callbackHistory
|
|
247
|
+
) {
|
|
248
|
+
if (!ctx.clientId) {
|
|
249
|
+
ctx.throw(400, 'Client ID required for paused executions');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const provenanceSnap =
|
|
253
|
+
executionConfig.provenanceMode && executionConfig.provenanceMode !== ProvenanceMode.NONE
|
|
254
|
+
? captureProvenanceSnapshot(result.executionId)
|
|
255
|
+
: undefined;
|
|
256
|
+
|
|
257
|
+
const callbackRequest =
|
|
258
|
+
result.needsCallback || (result.needsCallbacks && result.needsCallbacks[0]);
|
|
259
|
+
|
|
260
|
+
if (!callbackRequest) {
|
|
261
|
+
ctx.throw(500, 'Invalid paused state: no callback request');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
await stateManager.pause({
|
|
265
|
+
executionId: result.executionId,
|
|
266
|
+
code: (result as any).transformedCode || code,
|
|
267
|
+
config: executionConfig,
|
|
268
|
+
clientId: ctx.clientId,
|
|
269
|
+
callbackRequest,
|
|
270
|
+
pausedAt: Date.now(),
|
|
271
|
+
callbackHistory: result.callbackHistory,
|
|
272
|
+
currentCallbackIndex: result.callbackHistory.length - 1,
|
|
273
|
+
context: {
|
|
274
|
+
codeTransformed: !!(result as any).transformedCode,
|
|
275
|
+
},
|
|
276
|
+
provenanceState: provenanceSnap,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Cleanup hint map
|
|
281
|
+
if (hintMap && hintMap.size > 0) {
|
|
282
|
+
clearHintMap(prelimExecutionId);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { RequestContext } from '../core/config.js';
|
|
2
|
+
import type { ExplorerService } from '../explorer/index.js';
|
|
3
|
+
|
|
4
|
+
export async function handleExplore(
|
|
5
|
+
ctx: RequestContext,
|
|
6
|
+
explorerService: ExplorerService
|
|
7
|
+
): Promise<unknown> {
|
|
8
|
+
const body = ctx.body as { path?: string };
|
|
9
|
+
const path = body.path || '/';
|
|
10
|
+
|
|
11
|
+
const result = explorerService.explore(path);
|
|
12
|
+
|
|
13
|
+
if (!result) {
|
|
14
|
+
ctx.throw(404, `Path not found: ${path}`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { RequestContext } from '../core/config.js';
|
|
2
|
+
import type { ClientSessionManager } from '../client-sessions.js';
|
|
3
|
+
import type { AuditSink, AuditEvent } from '@mondaydotcomorg/atp-protocol';
|
|
4
|
+
import { nanoid } from 'nanoid';
|
|
5
|
+
import { log } from '@mondaydotcomorg/atp-runtime';
|
|
6
|
+
|
|
7
|
+
export async function handleInit(
|
|
8
|
+
ctx: RequestContext,
|
|
9
|
+
sessionManager: ClientSessionManager,
|
|
10
|
+
auditSink?: AuditSink
|
|
11
|
+
): Promise<unknown> {
|
|
12
|
+
const request = ctx.body as any;
|
|
13
|
+
|
|
14
|
+
if (request.tools && Array.isArray(request.tools)) {
|
|
15
|
+
log.info('Client registering tools', {
|
|
16
|
+
toolCount: request.tools.length,
|
|
17
|
+
toolNames: request.tools.map((t: any) => t.name),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
for (const tool of request.tools) {
|
|
21
|
+
if (!tool.name || typeof tool.name !== 'string') {
|
|
22
|
+
ctx.throw(400, 'Invalid tool definition: name is required');
|
|
23
|
+
}
|
|
24
|
+
if (!tool.description || typeof tool.description !== 'string') {
|
|
25
|
+
ctx.throw(400, `Invalid tool definition for '${tool.name}': description is required`);
|
|
26
|
+
}
|
|
27
|
+
if (!tool.inputSchema || typeof tool.inputSchema !== 'object') {
|
|
28
|
+
ctx.throw(400, `Invalid tool definition for '${tool.name}': inputSchema is required`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const result = await sessionManager.initClient(request || {});
|
|
34
|
+
|
|
35
|
+
if (auditSink) {
|
|
36
|
+
const event: AuditEvent = {
|
|
37
|
+
eventId: nanoid(),
|
|
38
|
+
timestamp: Date.now(),
|
|
39
|
+
clientId: (result as any).clientId,
|
|
40
|
+
eventType: 'client_init',
|
|
41
|
+
action: 'init',
|
|
42
|
+
status: 'success',
|
|
43
|
+
metadata: {
|
|
44
|
+
clientInfo: request.clientInfo,
|
|
45
|
+
toolsRegistered: request.tools ? request.tools.length : 0,
|
|
46
|
+
toolNames: request.tools ? request.tools.map((t: any) => t.name) : [],
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
await auditSink.write(event).catch(() => {});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import type { RequestContext, ResolvedServerConfig } from '../core/config.js';
|
|
2
|
+
import type { SandboxExecutor } from '../executor/index.js';
|
|
3
|
+
import type { ExecutionStateManager } from '../execution-state/index.js';
|
|
4
|
+
import type { ClientSessionManager } from '../client-sessions.js';
|
|
5
|
+
import { log } from '@mondaydotcomorg/atp-runtime';
|
|
6
|
+
import { ExecutionStatus, ProvenanceMode } from '@mondaydotcomorg/atp-protocol';
|
|
7
|
+
import {
|
|
8
|
+
restoreProvenanceSnapshot,
|
|
9
|
+
captureProvenanceSnapshot,
|
|
10
|
+
createProvenanceProxy,
|
|
11
|
+
markPrimitiveTainted,
|
|
12
|
+
ProvenanceSource,
|
|
13
|
+
type ProvenanceSnapshot,
|
|
14
|
+
type ProvenanceState,
|
|
15
|
+
type SourceMetadata,
|
|
16
|
+
} from '@mondaydotcomorg/atp-provenance';
|
|
17
|
+
import { nanoid } from 'nanoid';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Tag a callback result with provenance metadata
|
|
21
|
+
*/
|
|
22
|
+
function tagCallbackResult(
|
|
23
|
+
callbackRecord: { type: string; operation: string; payload: any },
|
|
24
|
+
result: unknown,
|
|
25
|
+
provenanceMode?: string
|
|
26
|
+
): unknown {
|
|
27
|
+
// Don't tag if provenance is disabled or not specified
|
|
28
|
+
// ProvenanceMode.NONE is 'none', so just check for falsy or 'none'
|
|
29
|
+
if (!provenanceMode || provenanceMode === ProvenanceMode.NONE) {
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (result === null || result === undefined) {
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const tagValue = (value: unknown, source: SourceMetadata): unknown => {
|
|
38
|
+
if (value === null || value === undefined) {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Primitive: taint it
|
|
43
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
44
|
+
const metadata = {
|
|
45
|
+
id: nanoid(),
|
|
46
|
+
source,
|
|
47
|
+
readers: { type: 'public' as const },
|
|
48
|
+
dependencies: [],
|
|
49
|
+
context: {},
|
|
50
|
+
};
|
|
51
|
+
markPrimitiveTainted(value, metadata);
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Objects/arrays: create provenance proxy
|
|
56
|
+
if (typeof value === 'object') {
|
|
57
|
+
return createProvenanceProxy(value, source, { type: 'public' });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return value;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Determine source based on callback type
|
|
64
|
+
if (callbackRecord.type === 'llm') {
|
|
65
|
+
const source: SourceMetadata = {
|
|
66
|
+
type: ProvenanceSource.LLM,
|
|
67
|
+
operation: (callbackRecord.operation as 'call' | 'extract' | 'classify') || 'call',
|
|
68
|
+
timestamp: Date.now(),
|
|
69
|
+
};
|
|
70
|
+
return Array.isArray(result)
|
|
71
|
+
? result.map((r) => tagValue(r, source))
|
|
72
|
+
: tagValue(result, source);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (callbackRecord.type === 'tool') {
|
|
76
|
+
const source: SourceMetadata = {
|
|
77
|
+
type: ProvenanceSource.TOOL,
|
|
78
|
+
toolName: (callbackRecord.payload as any)?.toolName || 'clientTool',
|
|
79
|
+
apiGroup: (callbackRecord.payload as any)?.namespace || 'client',
|
|
80
|
+
timestamp: Date.now(),
|
|
81
|
+
};
|
|
82
|
+
return Array.isArray(result)
|
|
83
|
+
? result.map((r) => tagValue(r, source))
|
|
84
|
+
: tagValue(result, source);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// No tagging for other callback types
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function handleResume(
|
|
92
|
+
ctx: RequestContext,
|
|
93
|
+
executionId: string,
|
|
94
|
+
executor: SandboxExecutor,
|
|
95
|
+
stateManager: ExecutionStateManager,
|
|
96
|
+
serverConfig: ResolvedServerConfig,
|
|
97
|
+
sessionManager?: ClientSessionManager
|
|
98
|
+
): Promise<unknown> {
|
|
99
|
+
const requestClientId = ctx.headers['x-client-id'] || ctx.clientId;
|
|
100
|
+
const requestToken = ctx.headers['authorization']?.replace('Bearer ', '');
|
|
101
|
+
|
|
102
|
+
if (!requestClientId || !requestToken) {
|
|
103
|
+
log.warn('Resume attempt without authentication', { executionId });
|
|
104
|
+
ctx.throw(401, 'Authentication required');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
ctx.clientId = requestClientId;
|
|
108
|
+
|
|
109
|
+
if (sessionManager) {
|
|
110
|
+
const isValid = await sessionManager.verifyClient(requestClientId, requestToken);
|
|
111
|
+
if (!isValid) {
|
|
112
|
+
log.warn('Resume attempt with invalid token', { executionId, clientId: requestClientId });
|
|
113
|
+
ctx.throw(403, 'Invalid client credentials');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const pausedState = await stateManager.get(executionId);
|
|
118
|
+
|
|
119
|
+
if (!pausedState) {
|
|
120
|
+
ctx.throw(404, 'Not found');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (pausedState.clientId !== requestClientId) {
|
|
124
|
+
log.warn('Resume attempt by unauthorized client', {
|
|
125
|
+
executionId,
|
|
126
|
+
requestClientId,
|
|
127
|
+
ownerClientId: pausedState.clientId,
|
|
128
|
+
});
|
|
129
|
+
ctx.throw(403, 'Unauthorized: execution belongs to different client');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
log.info('Resume authorized', { executionId, clientId: requestClientId });
|
|
133
|
+
|
|
134
|
+
if (
|
|
135
|
+
pausedState.provenanceState &&
|
|
136
|
+
pausedState.config.provenanceMode &&
|
|
137
|
+
pausedState.config.provenanceMode !== ProvenanceMode.NONE
|
|
138
|
+
) {
|
|
139
|
+
// Check if it's a ProvenanceSnapshot (with primitives) or old ProvenanceState
|
|
140
|
+
const state = pausedState.provenanceState;
|
|
141
|
+
if ('primitives' in state) {
|
|
142
|
+
// New snapshot format
|
|
143
|
+
restoreProvenanceSnapshot(executionId, state as ProvenanceSnapshot);
|
|
144
|
+
log.info('Provenance snapshot restored', {
|
|
145
|
+
executionId,
|
|
146
|
+
registryEntries: state.registry.length,
|
|
147
|
+
primitiveEntries: state.primitives.length,
|
|
148
|
+
});
|
|
149
|
+
} else {
|
|
150
|
+
// Old state format (backward compat)
|
|
151
|
+
const provenanceMap = new Map<string, any>(state.registry);
|
|
152
|
+
restoreProvenanceSnapshot(executionId, {
|
|
153
|
+
registry: state.registry,
|
|
154
|
+
primitives: [],
|
|
155
|
+
});
|
|
156
|
+
log.info('Provenance state restored (legacy format)', {
|
|
157
|
+
executionId,
|
|
158
|
+
entries: provenanceMap.size,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const request = ctx.body as any;
|
|
164
|
+
|
|
165
|
+
let updatedHistory: any[];
|
|
166
|
+
let callbackResult: unknown;
|
|
167
|
+
|
|
168
|
+
const lastRecord = pausedState.callbackHistory[pausedState.currentCallbackIndex];
|
|
169
|
+
|
|
170
|
+
if (!lastRecord) {
|
|
171
|
+
log.error('No callback record found at current index', {
|
|
172
|
+
executionId,
|
|
173
|
+
currentIndex: pausedState.currentCallbackIndex,
|
|
174
|
+
});
|
|
175
|
+
ctx.throw(500, 'Invalid paused state: no callback record');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (request.results) {
|
|
179
|
+
const batchResults = request.results as Array<{ id: string; result: unknown }>;
|
|
180
|
+
log.info('Processing batch callback results', {
|
|
181
|
+
executionId,
|
|
182
|
+
batchCount: batchResults.length,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
for (const br of batchResults) {
|
|
186
|
+
if (br.result && typeof br.result === 'object' && '__error' in br.result) {
|
|
187
|
+
const errorObj = br.result as { __error: boolean; message: string };
|
|
188
|
+
if (errorObj.message && errorObj.message.includes('service not provided')) {
|
|
189
|
+
log.error('Service provider error in batch', { executionId, error: errorObj.message });
|
|
190
|
+
await stateManager.delete(executionId);
|
|
191
|
+
return {
|
|
192
|
+
executionId,
|
|
193
|
+
status: ExecutionStatus.FAILED,
|
|
194
|
+
error: {
|
|
195
|
+
message: errorObj.message || 'Service not available',
|
|
196
|
+
code: 'SERVICE_NOT_PROVIDED',
|
|
197
|
+
},
|
|
198
|
+
stats: {
|
|
199
|
+
duration: 0,
|
|
200
|
+
memoryUsed: 0,
|
|
201
|
+
llmCallsCount: 0,
|
|
202
|
+
approvalCallsCount: 0,
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Tag batch results
|
|
210
|
+
const taggedBatchResults = batchResults.map((br) => ({
|
|
211
|
+
...br,
|
|
212
|
+
result: tagCallbackResult(lastRecord, br.result, pausedState.config.provenanceMode),
|
|
213
|
+
}));
|
|
214
|
+
callbackResult = taggedBatchResults.map((br) => br.result);
|
|
215
|
+
|
|
216
|
+
updatedHistory = pausedState.callbackHistory.map((record, index) => {
|
|
217
|
+
if (index === pausedState.currentCallbackIndex) {
|
|
218
|
+
return { ...record, result: callbackResult };
|
|
219
|
+
}
|
|
220
|
+
return record;
|
|
221
|
+
});
|
|
222
|
+
} else {
|
|
223
|
+
// Tag single result
|
|
224
|
+
const rawResult = request.result;
|
|
225
|
+
|
|
226
|
+
// Check for service provider errors (not tool errors)
|
|
227
|
+
if (rawResult && typeof rawResult === 'object' && '__error' in rawResult) {
|
|
228
|
+
const errorObj = rawResult as { __error: boolean; message: string };
|
|
229
|
+
// Only fail execution for service provider errors (service not available)
|
|
230
|
+
if (errorObj.message && errorObj.message.includes('service not provided')) {
|
|
231
|
+
log.error('Service provider error', { executionId, error: errorObj.message });
|
|
232
|
+
await stateManager.delete(executionId);
|
|
233
|
+
return {
|
|
234
|
+
executionId,
|
|
235
|
+
status: ExecutionStatus.FAILED,
|
|
236
|
+
error: {
|
|
237
|
+
message: errorObj.message || 'Service not available',
|
|
238
|
+
code: 'SERVICE_NOT_PROVIDED',
|
|
239
|
+
},
|
|
240
|
+
stats: {
|
|
241
|
+
duration: 0,
|
|
242
|
+
memoryUsed: 0,
|
|
243
|
+
llmCallsCount: 0,
|
|
244
|
+
approvalCallsCount: 0,
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
callbackResult = tagCallbackResult(lastRecord, rawResult, pausedState.config.provenanceMode);
|
|
251
|
+
|
|
252
|
+
updatedHistory = pausedState.callbackHistory.map((record, index) => {
|
|
253
|
+
if (index === pausedState.currentCallbackIndex) {
|
|
254
|
+
return { ...record, result: callbackResult };
|
|
255
|
+
}
|
|
256
|
+
return record;
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const restoredConfig = {
|
|
261
|
+
...pausedState.config,
|
|
262
|
+
securityPolicies: serverConfig.execution.securityPolicies || [],
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const result = await executor.execute(pausedState.code, restoredConfig, pausedState.clientId, {
|
|
266
|
+
callbackHistory: updatedHistory,
|
|
267
|
+
newCallbackResult: callbackResult,
|
|
268
|
+
executionId,
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
if (result.status === ExecutionStatus.PAUSED && result.needsCallbacks && result.callbackHistory) {
|
|
272
|
+
const provenanceState =
|
|
273
|
+
pausedState.config.provenanceMode && pausedState.config.provenanceMode !== ProvenanceMode.NONE
|
|
274
|
+
? captureProvenanceSnapshot(result.executionId)
|
|
275
|
+
: undefined;
|
|
276
|
+
|
|
277
|
+
await stateManager.pause({
|
|
278
|
+
executionId: result.executionId,
|
|
279
|
+
code: pausedState.code,
|
|
280
|
+
config: pausedState.config,
|
|
281
|
+
clientId: pausedState.clientId,
|
|
282
|
+
callbackRequest: result.needsCallbacks[0]!,
|
|
283
|
+
pausedAt: Date.now(),
|
|
284
|
+
callbackHistory: result.callbackHistory,
|
|
285
|
+
currentCallbackIndex: result.callbackHistory.length - 1,
|
|
286
|
+
context: {},
|
|
287
|
+
provenanceState,
|
|
288
|
+
});
|
|
289
|
+
} else if (
|
|
290
|
+
result.status === ExecutionStatus.PAUSED &&
|
|
291
|
+
result.needsCallback &&
|
|
292
|
+
result.callbackHistory
|
|
293
|
+
) {
|
|
294
|
+
const provenanceState =
|
|
295
|
+
pausedState.config.provenanceMode && pausedState.config.provenanceMode !== ProvenanceMode.NONE
|
|
296
|
+
? captureProvenanceSnapshot(result.executionId)
|
|
297
|
+
: undefined;
|
|
298
|
+
|
|
299
|
+
await stateManager.pause({
|
|
300
|
+
executionId: result.executionId,
|
|
301
|
+
code: pausedState.code,
|
|
302
|
+
config: pausedState.config,
|
|
303
|
+
clientId: pausedState.clientId,
|
|
304
|
+
callbackRequest: result.needsCallback,
|
|
305
|
+
pausedAt: Date.now(),
|
|
306
|
+
callbackHistory: result.callbackHistory,
|
|
307
|
+
currentCallbackIndex: result.callbackHistory.length - 1,
|
|
308
|
+
context: {},
|
|
309
|
+
provenanceState,
|
|
310
|
+
});
|
|
311
|
+
} else {
|
|
312
|
+
await stateManager.delete(executionId);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return result;
|
|
316
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { RequestContext, ResolvedServerConfig } from '../core/config.js';
|
|
2
|
+
import type { SearchEngine } from '../search/index.js';
|
|
3
|
+
|
|
4
|
+
export async function handleSearch(
|
|
5
|
+
ctx: RequestContext,
|
|
6
|
+
searchEngine: SearchEngine,
|
|
7
|
+
config: ResolvedServerConfig
|
|
8
|
+
): Promise<unknown> {
|
|
9
|
+
const searchOptions = ctx.body as any;
|
|
10
|
+
const results = await searchEngine.search(
|
|
11
|
+
searchOptions,
|
|
12
|
+
ctx.userId,
|
|
13
|
+
ctx.auth,
|
|
14
|
+
config.discovery.scopeFiltering
|
|
15
|
+
);
|
|
16
|
+
return { results };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function handleSearchQuery(
|
|
20
|
+
ctx: RequestContext,
|
|
21
|
+
searchEngine: SearchEngine,
|
|
22
|
+
config: ResolvedServerConfig
|
|
23
|
+
): Promise<unknown> {
|
|
24
|
+
const query = ctx.query.query || ctx.query.keyword || '';
|
|
25
|
+
const results = await searchEngine.search(
|
|
26
|
+
{ query },
|
|
27
|
+
ctx.userId,
|
|
28
|
+
ctx.auth,
|
|
29
|
+
config.discovery.scopeFiltering
|
|
30
|
+
);
|
|
31
|
+
return { results };
|
|
32
|
+
}
|