@elaraai/e3-api-server 1.0.5 → 1.0.6

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.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { ExecuteResult, CallStatusResult } from './types.js';
6
+ /**
7
+ * Create a new function call and return its ID plus the AbortController
8
+ * that cancels it.
9
+ */
10
+ export declare function createFunctionCall(): {
11
+ callId: string;
12
+ abort: AbortController;
13
+ };
14
+ /**
15
+ * Mark a call as succeeded with its terminal ExecuteResult.
16
+ *
17
+ * "Succeeded" means the call ran to a terminal result — the result itself
18
+ * may still carry a `failed`/`too_large`/`timed_out` outcome.
19
+ */
20
+ export declare function completeFunctionCall(callId: string, result: ExecuteResult): void;
21
+ /**
22
+ * Mark a call as failed with an infrastructure error message.
23
+ */
24
+ export declare function failFunctionCall(callId: string, error: string): void;
25
+ /**
26
+ * Get the status of a call as a wire CallStatusResult.
27
+ * Returns null if the call doesn't exist (or was evicted).
28
+ */
29
+ export declare function getFunctionCall(callId: string): CallStatusResult | null;
30
+ /**
31
+ * Cancel an in-flight call: abort its process and mark it cancelled.
32
+ * Returns false if the call doesn't exist; true otherwise (idempotent for
33
+ * already-terminal calls).
34
+ */
35
+ export declare function cancelFunctionCall(callId: string): boolean;
36
+ /**
37
+ * Clear all call state. Useful for cleanup in tests.
38
+ */
39
+ export declare function clearAllFunctionCalls(): void;
40
+ //# sourceMappingURL=function-call-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-call-state.d.ts","sourceRoot":"","sources":["../../src/function-call-state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiBH,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA+BlE;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,CAU/E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAQhF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAQpE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CA4BvE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAY1D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ /**
6
+ * In-memory state storage for async function / one-shot calls.
7
+ *
8
+ * Modelled on async-operation-state.ts (the GC pattern), with the eviction
9
+ * gap fixed: terminal entries are evicted after a TTL on a lazy sweep at
10
+ * each read/write, so the registry can't grow without bound. The finished
11
+ * result is held only transiently until polled — never in the durable
12
+ * object store.
13
+ *
14
+ * This serves as a development/test mock for the short-TTL DynamoDB record
15
+ * used by the cloud (ComputeResultStore pattern).
16
+ */
17
+ import { randomUUID } from 'crypto';
18
+ import { variant, some, none } from '@elaraai/east';
19
+ /** How long a terminal call entry survives un-polled. */
20
+ const CALL_TTL_MS = 5 * 60 * 1000;
21
+ // Key: callId (UUID)
22
+ const calls = new Map();
23
+ /**
24
+ * Evict terminal entries older than the TTL. Called lazily on every
25
+ * read/write — no timers to leak.
26
+ */
27
+ function sweep() {
28
+ const now = Date.now();
29
+ for (const [id, call] of calls) {
30
+ if (call.completedAt !== undefined && now - call.completedAt > CALL_TTL_MS) {
31
+ calls.delete(id);
32
+ }
33
+ }
34
+ }
35
+ /**
36
+ * Create a new function call and return its ID plus the AbortController
37
+ * that cancels it.
38
+ */
39
+ export function createFunctionCall() {
40
+ sweep();
41
+ const callId = randomUUID();
42
+ const abort = new AbortController();
43
+ calls.set(callId, {
44
+ status: 'running',
45
+ startedAt: Date.now(),
46
+ abort,
47
+ });
48
+ return { callId, abort };
49
+ }
50
+ /**
51
+ * Mark a call as succeeded with its terminal ExecuteResult.
52
+ *
53
+ * "Succeeded" means the call ran to a terminal result — the result itself
54
+ * may still carry a `failed`/`too_large`/`timed_out` outcome.
55
+ */
56
+ export function completeFunctionCall(callId, result) {
57
+ sweep();
58
+ const call = calls.get(callId);
59
+ if (call && call.status === 'running') {
60
+ call.status = 'succeeded';
61
+ call.completedAt = Date.now();
62
+ call.result = result;
63
+ }
64
+ }
65
+ /**
66
+ * Mark a call as failed with an infrastructure error message.
67
+ */
68
+ export function failFunctionCall(callId, error) {
69
+ sweep();
70
+ const call = calls.get(callId);
71
+ if (call && call.status === 'running') {
72
+ call.status = 'failed';
73
+ call.completedAt = Date.now();
74
+ call.error = error;
75
+ }
76
+ }
77
+ /**
78
+ * Get the status of a call as a wire CallStatusResult.
79
+ * Returns null if the call doesn't exist (or was evicted).
80
+ */
81
+ export function getFunctionCall(callId) {
82
+ sweep();
83
+ const call = calls.get(callId);
84
+ if (!call) {
85
+ return null;
86
+ }
87
+ let status;
88
+ switch (call.status) {
89
+ case 'running':
90
+ status = variant('running', null);
91
+ break;
92
+ case 'succeeded':
93
+ status = variant('succeeded', null);
94
+ break;
95
+ case 'failed':
96
+ status = variant('failed', null);
97
+ break;
98
+ case 'cancelled':
99
+ status = variant('cancelled', null);
100
+ break;
101
+ }
102
+ return {
103
+ status,
104
+ result: call.result ? some(call.result) : none,
105
+ error: call.error ? some(call.error) : none,
106
+ };
107
+ }
108
+ /**
109
+ * Cancel an in-flight call: abort its process and mark it cancelled.
110
+ * Returns false if the call doesn't exist; true otherwise (idempotent for
111
+ * already-terminal calls).
112
+ */
113
+ export function cancelFunctionCall(callId) {
114
+ sweep();
115
+ const call = calls.get(callId);
116
+ if (!call) {
117
+ return false;
118
+ }
119
+ if (call.status === 'running') {
120
+ call.status = 'cancelled';
121
+ call.completedAt = Date.now();
122
+ call.abort.abort();
123
+ }
124
+ return true;
125
+ }
126
+ /**
127
+ * Clear all call state. Useful for cleanup in tests.
128
+ */
129
+ export function clearAllFunctionCalls() {
130
+ calls.clear();
131
+ }
132
+ //# sourceMappingURL=function-call-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-call-state.js","sourceRoot":"","sources":["../../src/function-call-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { StorageBackend, TaskRunner } from '@elaraai/e3-core';
6
+ import { type FunctionCallRequest, type OneShotRequest } from '../types.js';
7
+ /**
8
+ * List a package's functions with their signatures.
9
+ */
10
+ export declare function listPackageFunctions(storage: StorageBackend, repoPath: string, pkgName: string, version: string): Promise<Response>;
11
+ /**
12
+ * Describe a single function (signature) so dynamic callers can encode args.
13
+ */
14
+ export declare function describePackageFunction(storage: StorageBackend, repoPath: string, pkgName: string, version: string, fnName: string): Promise<Response>;
15
+ /**
16
+ * Call a named function synchronously: resolve → validate arity → run →
17
+ * 200 ExecuteResult. The sync path enforces a server-owned deadline so the
18
+ * caller gets a structured `timed_out` instead of a transport cut.
19
+ */
20
+ export declare function callFunctionSync(storage: StorageBackend, repoPath: string, runner: TaskRunner, pkgName: string, version: string, fnName: string, req: FunctionCallRequest): Promise<Response>;
21
+ /**
22
+ * Call a named function asynchronously: resolve up front (so a missing
23
+ * function is a request error, not a failed call), then fire the run
24
+ * detached and return 202 `{callId}` for polling.
25
+ */
26
+ export declare function callFunctionAsync(storage: StorageBackend, repoPath: string, runner: TaskRunner, pkgName: string, version: string, fnName: string, req: FunctionCallRequest): Promise<Response>;
27
+ /**
28
+ * Poll an async call's status (and result, once terminal).
29
+ */
30
+ export declare function getCallStatus(callId: string): Response;
31
+ /**
32
+ * Cancel an in-flight async call (kills the runner's process group).
33
+ */
34
+ export declare function cancelCall(callId: string): Response;
35
+ /**
36
+ * Run a one-shot synchronously. SECURITY: caller-supplied IR — the route
37
+ * layer gates this behind an elevated role.
38
+ */
39
+ export declare function callOneShotSync(storage: StorageBackend, repoPath: string, runner: TaskRunner, workspace: string, req: OneShotRequest): Promise<Response>;
40
+ /**
41
+ * Launch a one-shot asynchronously → 202 `{callId}`. Dataset args are
42
+ * resolved + pinned inside the detached run at launch time.
43
+ */
44
+ export declare function callOneShotAsync(storage: StorageBackend, repoPath: string, runner: TaskRunner, workspace: string, req: OneShotRequest): Promise<Response>;
45
+ //# sourceMappingURL=functions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../../src/handlers/functions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAsBH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAkB,MAAM,kBAAkB,CAAC;AAInF,OAAO,EAOL,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAkOrB;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,QAAQ,CAAC,CAkBnB;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,QAAQ,CAAC,CAYnB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,QAAQ,CAAC,CAQnB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,QAAQ,CAAC,CAkBnB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAMtD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAMnD;AAMD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,QAAQ,CAAC,CASnB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,QAAQ,CAAC,CAkBnB"}
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ /**
6
+ * Handlers for named package functions and one-shot execution.
7
+ *
8
+ * Both reduce to the graph-free `runDetached` primitive: marshal inputs →
9
+ * run a body IR on a runner → return the result inline. Nothing durable is
10
+ * written — no output object, no execution record, no logs, no dataset ref.
11
+ *
12
+ * Named functions are author-published IR (same trust as a deployed task).
13
+ * One-shot evaluates CALLER-supplied IR — remote code execution with the
14
+ * server's authority — and must be gated by the route layer (see
15
+ * routes/functions.ts).
16
+ */
17
+ import { ArrayType, NullType, decodeBeast2For, variant, none } from '@elaraai/east';
18
+ import { packageRead, workspaceGetPackage, workspaceGetDatasetHash, TaskNotFoundError, } from '@elaraai/e3-core';
19
+ import { FunctionObjectType } from '@elaraai/e3-types';
20
+ import { sendSuccess, sendError, sendSuccessWithStatus } from '../beast2.js';
21
+ import { errorToVariant } from '../errors.js';
22
+ import { FunctionSignatureType, ExecuteResultType, CallStartResultType, CallStatusResultType, } from '../types.js';
23
+ import { createFunctionCall, completeFunctionCall, failFunctionCall, getFunctionCall, cancelFunctionCall, } from '../function-call-state.js';
24
+ // =============================================================================
25
+ // Limits (server-owned, clamped)
26
+ // =============================================================================
27
+ /** Default per-call timeout when the request doesn't specify one. */
28
+ const DEFAULT_TIMEOUT_MS = 60_000;
29
+ /** Hard ceiling on any call's timeout (async included). */
30
+ const MAX_TIMEOUT_MS = 10 * 60_000;
31
+ /** Sync calls additionally respect a server-owned wall-clock deadline so the
32
+ * caller gets a structured `timed_out` instead of a transport cut. (The
33
+ * cloud sets this below API Gateway's 29 s; locally we can be generous.) */
34
+ const SERVER_SYNC_DEADLINE_MS = 120_000;
35
+ /** Default + ceiling for the inline result size (see design §9: 1 MB leaves
36
+ * 3-4x headroom under the base64-inflated Lambda ceiling and still allows
37
+ * multi-thousand-row tables inline). Requests may lower it, never raise it. */
38
+ const MAX_RESULT_BYTES = 1024 * 1024;
39
+ /** Default + ceiling for each captured log stream's tail. */
40
+ const MAX_LOG_BYTES = 256 * 1024;
41
+ const DEFAULT_LOG_BYTES = 64 * 1024;
42
+ function resolveLimits(limits, sync) {
43
+ const req = limits.type === 'some' ? limits.value : undefined;
44
+ let timeoutMs = req && req.timeoutMs.type === 'some'
45
+ ? Number(req.timeoutMs.value)
46
+ : DEFAULT_TIMEOUT_MS;
47
+ timeoutMs = Math.min(Math.max(1, timeoutMs), MAX_TIMEOUT_MS);
48
+ if (sync)
49
+ timeoutMs = Math.min(timeoutMs, SERVER_SYNC_DEADLINE_MS);
50
+ let maxResultBytes = req && req.maxResultBytes.type === 'some'
51
+ ? Number(req.maxResultBytes.value)
52
+ : MAX_RESULT_BYTES;
53
+ maxResultBytes = Math.min(Math.max(1, maxResultBytes), MAX_RESULT_BYTES);
54
+ let maxLogBytes = req && req.maxLogBytes.type === 'some'
55
+ ? Number(req.maxLogBytes.value)
56
+ : DEFAULT_LOG_BYTES;
57
+ maxLogBytes = Math.min(Math.max(0, maxLogBytes), MAX_LOG_BYTES);
58
+ return { timeoutMs, maxResultBytes, maxLogBytes };
59
+ }
60
+ // =============================================================================
61
+ // Shared helpers
62
+ // =============================================================================
63
+ const decodeFunctionObject = decodeBeast2For(FunctionObjectType);
64
+ /**
65
+ * Resolve a named function in a package to its FunctionObject.
66
+ *
67
+ * @throws {TaskNotFoundError} If the function doesn't exist (functions are
68
+ * named callables; the wire format has no separate function_not_found tag —
69
+ * adding one would reorder ErrorType's sorted variant tags, a breaking
70
+ * wire change).
71
+ */
72
+ async function resolveFunction(storage, repoPath, pkgName, version, fnName) {
73
+ const pkg = await packageRead(storage, repoPath, pkgName, version);
74
+ const fnHash = pkg.functions.get(fnName);
75
+ if (!fnHash) {
76
+ throw new TaskNotFoundError(`function '${fnName}' in ${pkgName}@${version}`);
77
+ }
78
+ const fnData = await storage.objects.read(repoPath, fnHash);
79
+ return decodeFunctionObject(Buffer.from(fnData));
80
+ }
81
+ /** Map a DetachedResult to the wire ExecuteResult. */
82
+ function detachedToExecuteResult(result) {
83
+ const streams = {
84
+ stdout: result.stdout,
85
+ stderr: result.stderr,
86
+ stdoutTruncated: result.stdoutTruncated,
87
+ stderrTruncated: result.stderrTruncated,
88
+ };
89
+ switch (result.kind) {
90
+ case 'success':
91
+ return { outcome: variant('success', { value: result.value }), ...streams };
92
+ case 'failed':
93
+ return { outcome: variant('failed', { exitCode: BigInt(result.exitCode) }), ...streams };
94
+ case 'too_large':
95
+ return { outcome: variant('too_large', { bytes: BigInt(result.bytes), limit: BigInt(result.limit) }), ...streams };
96
+ case 'timed_out':
97
+ return { outcome: variant('timed_out', { ms: BigInt(result.ms) }), ...streams };
98
+ }
99
+ }
100
+ /** Build an `invalid` ExecuteResult (signature/IR error; nothing ran). */
101
+ function invalidResult(message) {
102
+ return {
103
+ outcome: variant('invalid', {
104
+ diagnostics: [{ message, filename: none, line: none, column: none }],
105
+ }),
106
+ stdout: '',
107
+ stderr: '',
108
+ stdoutTruncated: false,
109
+ stderrTruncated: false,
110
+ };
111
+ }
112
+ /**
113
+ * Execute a resolved named function: arity check → read bodyIr → runDetached.
114
+ * Never throws for execution outcomes — only for storage/infra errors.
115
+ */
116
+ async function executeFunction(storage, repoPath, runner, fnObj, req, sync, signal) {
117
+ // Signature validation: arity is checked here, before anything runs.
118
+ // Per-element type errors surface as a runtime decode failure (`failed`)
119
+ // from the runner.
120
+ if (req.args.length !== fnObj.inputTypes.length) {
121
+ return invalidResult(`Expected ${fnObj.inputTypes.length} argument(s), got ${req.args.length}`);
122
+ }
123
+ const bodyIr = await storage.objects.read(repoPath, fnObj.bodyIr);
124
+ const runnerValue = req.runner.type === 'some' ? req.runner.value : fnObj.runner;
125
+ const limits = resolveLimits(req.limits, sync);
126
+ const result = await runner.runDetached({
127
+ bodyIr,
128
+ args: req.args.map((a) => a),
129
+ runner: runnerValue,
130
+ limits,
131
+ }, { signal });
132
+ return detachedToExecuteResult(result);
133
+ }
134
+ /**
135
+ * Resolve one-shot args: inline values pass through; dataset paths are
136
+ * resolved + pinned by content hash at launch (objects are immutable, so no
137
+ * lock is needed — snapshot consistency).
138
+ *
139
+ * @returns The arg bytes, or an `invalid` ExecuteResult if a dataset arg is
140
+ * unassigned.
141
+ */
142
+ async function resolveOneShotArgs(storage, repoPath, workspace, args) {
143
+ const bytes = [];
144
+ for (let i = 0; i < args.length; i++) {
145
+ const arg = args[i];
146
+ if (arg.type === 'value') {
147
+ bytes.push(arg.value);
148
+ }
149
+ else {
150
+ const path = arg.value;
151
+ const { refType, hash } = await workspaceGetDatasetHash(storage, repoPath, workspace, path);
152
+ if (refType !== 'value' || hash === null) {
153
+ return {
154
+ ok: false,
155
+ invalid: invalidResult(`Dataset argument ${i} is not assigned (ref type: ${refType})`),
156
+ };
157
+ }
158
+ bytes.push(await storage.objects.read(repoPath, hash));
159
+ }
160
+ }
161
+ return { ok: true, bytes };
162
+ }
163
+ /** Execute a one-shot request (bodyIr from the request). */
164
+ async function executeOneShot(storage, repoPath, workspace, runner, req, sync, signal) {
165
+ const resolved = await resolveOneShotArgs(storage, repoPath, workspace, req.args);
166
+ if (!resolved.ok) {
167
+ return resolved.invalid;
168
+ }
169
+ const limits = resolveLimits(req.limits, sync);
170
+ const result = await runner.runDetached({
171
+ bodyIr: req.bodyIr,
172
+ args: resolved.bytes,
173
+ runner: req.runner,
174
+ limits,
175
+ }, { signal });
176
+ return detachedToExecuteResult(result);
177
+ }
178
+ // =============================================================================
179
+ // Named function handlers
180
+ // =============================================================================
181
+ /**
182
+ * List a package's functions with their signatures.
183
+ */
184
+ export async function listPackageFunctions(storage, repoPath, pkgName, version) {
185
+ try {
186
+ const pkg = await packageRead(storage, repoPath, pkgName, version);
187
+ const signatures = [];
188
+ for (const [name, fnHash] of pkg.functions) {
189
+ const fnData = await storage.objects.read(repoPath, fnHash);
190
+ const fnObj = decodeFunctionObject(Buffer.from(fnData));
191
+ signatures.push({
192
+ name,
193
+ inputTypes: fnObj.inputTypes,
194
+ outputType: fnObj.outputType,
195
+ runner: fnObj.runner,
196
+ });
197
+ }
198
+ return sendSuccess(ArrayType(FunctionSignatureType), signatures);
199
+ }
200
+ catch (err) {
201
+ return sendError(ArrayType(FunctionSignatureType), errorToVariant(err));
202
+ }
203
+ }
204
+ /**
205
+ * Describe a single function (signature) so dynamic callers can encode args.
206
+ */
207
+ export async function describePackageFunction(storage, repoPath, pkgName, version, fnName) {
208
+ try {
209
+ const fnObj = await resolveFunction(storage, repoPath, pkgName, version, fnName);
210
+ return sendSuccess(FunctionSignatureType, {
211
+ name: fnName,
212
+ inputTypes: fnObj.inputTypes,
213
+ outputType: fnObj.outputType,
214
+ runner: fnObj.runner,
215
+ });
216
+ }
217
+ catch (err) {
218
+ return sendError(FunctionSignatureType, errorToVariant(err));
219
+ }
220
+ }
221
+ /**
222
+ * Call a named function synchronously: resolve → validate arity → run →
223
+ * 200 ExecuteResult. The sync path enforces a server-owned deadline so the
224
+ * caller gets a structured `timed_out` instead of a transport cut.
225
+ */
226
+ export async function callFunctionSync(storage, repoPath, runner, pkgName, version, fnName, req) {
227
+ try {
228
+ const fnObj = await resolveFunction(storage, repoPath, pkgName, version, fnName);
229
+ const result = await executeFunction(storage, repoPath, runner, fnObj, req, true);
230
+ return sendSuccess(ExecuteResultType, result);
231
+ }
232
+ catch (err) {
233
+ return sendError(ExecuteResultType, errorToVariant(err));
234
+ }
235
+ }
236
+ /**
237
+ * Call a named function asynchronously: resolve up front (so a missing
238
+ * function is a request error, not a failed call), then fire the run
239
+ * detached and return 202 `{callId}` for polling.
240
+ */
241
+ export async function callFunctionAsync(storage, repoPath, runner, pkgName, version, fnName, req) {
242
+ try {
243
+ const fnObj = await resolveFunction(storage, repoPath, pkgName, version, fnName);
244
+ const { callId, abort } = createFunctionCall();
245
+ void (async () => {
246
+ try {
247
+ const result = await executeFunction(storage, repoPath, runner, fnObj, req, false, abort.signal);
248
+ completeFunctionCall(callId, result);
249
+ }
250
+ catch (err) {
251
+ failFunctionCall(callId, err instanceof Error ? err.message : String(err));
252
+ }
253
+ })();
254
+ return sendSuccessWithStatus(CallStartResultType, { callId }, 202);
255
+ }
256
+ catch (err) {
257
+ return sendError(CallStartResultType, errorToVariant(err));
258
+ }
259
+ }
260
+ /**
261
+ * Poll an async call's status (and result, once terminal).
262
+ */
263
+ export function getCallStatus(callId) {
264
+ const status = getFunctionCall(callId);
265
+ if (!status) {
266
+ return sendError(CallStatusResultType, variant('execution_not_found', { task: callId }));
267
+ }
268
+ return sendSuccess(CallStatusResultType, status);
269
+ }
270
+ /**
271
+ * Cancel an in-flight async call (kills the runner's process group).
272
+ */
273
+ export function cancelCall(callId) {
274
+ const found = cancelFunctionCall(callId);
275
+ if (!found) {
276
+ return sendError(NullType, variant('execution_not_found', { task: callId }));
277
+ }
278
+ return sendSuccess(NullType, null);
279
+ }
280
+ // =============================================================================
281
+ // One-shot handlers (workspace-scoped; anonymous caller-supplied IR)
282
+ // =============================================================================
283
+ /**
284
+ * Run a one-shot synchronously. SECURITY: caller-supplied IR — the route
285
+ * layer gates this behind an elevated role.
286
+ */
287
+ export async function callOneShotSync(storage, repoPath, runner, workspace, req) {
288
+ try {
289
+ // Validate the workspace exists / is deployed before running anything.
290
+ await workspaceGetPackage(storage, repoPath, workspace);
291
+ const result = await executeOneShot(storage, repoPath, workspace, runner, req, true);
292
+ return sendSuccess(ExecuteResultType, result);
293
+ }
294
+ catch (err) {
295
+ return sendError(ExecuteResultType, errorToVariant(err));
296
+ }
297
+ }
298
+ /**
299
+ * Launch a one-shot asynchronously → 202 `{callId}`. Dataset args are
300
+ * resolved + pinned inside the detached run at launch time.
301
+ */
302
+ export async function callOneShotAsync(storage, repoPath, runner, workspace, req) {
303
+ try {
304
+ await workspaceGetPackage(storage, repoPath, workspace);
305
+ const { callId, abort } = createFunctionCall();
306
+ void (async () => {
307
+ try {
308
+ const result = await executeOneShot(storage, repoPath, workspace, runner, req, false, abort.signal);
309
+ completeFunctionCall(callId, result);
310
+ }
311
+ catch (err) {
312
+ failFunctionCall(callId, err instanceof Error ? err.message : String(err));
313
+ }
314
+ })();
315
+ return sendSuccessWithStatus(CallStartResultType, { callId }, 202);
316
+ }
317
+ catch (err) {
318
+ return sendError(CallStartResultType, errorToVariant(err));
319
+ }
320
+ }
321
+ //# sourceMappingURL=functions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functions.js","sourceRoot":"","sources":["../../../src/handlers/functions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=functions.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functions.spec.d.ts","sourceRoot":"","sources":["../../../src/handlers/functions.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}