@superpanel-sdk/runtime 0.5.0 → 0.7.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/README.md +3 -3
- package/dist/builder/codegen/emit.d.ts +5 -10
- package/dist/builder/codegen/emit.js +100 -106
- package/dist/builder/codegen/generate.d.ts +3 -5
- package/dist/builder/codegen/generate.js +13 -32
- package/dist/builder/company-imports.d.ts +5 -0
- package/dist/builder/company-imports.js +9 -1
- package/dist/builder/compile/compile-sequence.d.ts +13 -11
- package/dist/builder/compile/compile-sequence.js +135 -83
- package/dist/builder/compile/function-code.d.ts +15 -9
- package/dist/builder/compile/function-code.js +59 -29
- package/dist/builder/compile/registry.d.ts +4 -4
- package/dist/builder/compile/registry.js +14 -12
- package/dist/builder/errors.d.ts +9 -0
- package/dist/builder/errors.js +17 -0
- package/dist/builder/function-params.d.ts +10 -0
- package/dist/builder/function-params.js +203 -0
- package/dist/builder/load.d.ts +17 -17
- package/dist/builder/load.js +27 -25
- package/dist/builder/paths.d.ts +6 -1
- package/dist/builder/paths.js +16 -2
- package/dist/builder/schedules.d.ts +9 -7
- package/dist/builder/schedules.js +20 -21
- package/dist/builder/typecheck.d.ts +1 -1
- package/dist/builder/typecheck.js +3 -6
- package/dist/builder/types.d.ts +41 -5
- package/dist/builder/types.js +19 -0
- package/dist/cli/calls/index.d.ts +177 -0
- package/dist/cli/calls/index.js +96 -0
- package/dist/cli/debug/index.d.ts +31 -0
- package/dist/cli/debug/index.js +119 -0
- package/dist/cli/exec/index.d.ts +39 -0
- package/dist/cli/exec/index.js +138 -0
- package/dist/cli/exec/session.d.ts +48 -0
- package/dist/cli/exec/session.js +82 -0
- package/dist/cli/exec/trace.d.ts +18 -0
- package/dist/cli/exec/trace.js +52 -0
- package/dist/cli/index.js +84 -1
- package/dist/cli/logs/index.d.ts +47 -0
- package/dist/cli/logs/index.js +113 -0
- package/dist/cli/mobile/index.d.ts +12 -0
- package/dist/cli/mobile/index.js +405 -0
- package/dist/cli/serve/index.d.ts +40 -4
- package/dist/cli/serve/index.js +167 -28
- package/dist/cli/turns/index.d.ts +105 -0
- package/dist/cli/turns/index.js +128 -0
- package/dist/cli/turns/run.d.ts +13 -0
- package/dist/cli/turns/run.js +57 -0
- package/dist/cli/turns/shadow.d.ts +112 -0
- package/dist/cli/turns/shadow.js +54 -0
- package/dist/cli/type-gen/index.js +0 -1
- package/dist/compute-host/compute-host.d.ts +5 -6
- package/dist/compute-host/compute-host.js +4 -13
- package/dist/compute-host/source-compute-host.d.ts +5 -7
- package/dist/compute-host/source-compute-host.js +12 -33
- package/dist/core/case-orchestrator/contact-hours.d.ts +26 -6
- package/dist/core/case-orchestrator/contact-hours.js +27 -8
- package/dist/core/case-orchestrator/index.d.ts +1 -4
- package/dist/core/case-orchestrator/index.js +1 -4
- package/dist/core/case-orchestrator/render.d.ts +1 -1
- package/dist/core/case-orchestrator/render.js +15 -10
- package/dist/core/case-orchestrator/types.d.ts +83 -128
- package/dist/core/case-orchestrator/types.js +0 -4
- package/dist/core/context/email-message.d.ts +40 -1
- package/dist/core/context/email-message.js +27 -0
- package/dist/core/context/email.d.ts +13 -1
- package/dist/core/context/email.js +2 -3
- package/dist/core/context/exchanges.d.ts +25 -0
- package/dist/core/context/exchanges.js +25 -7
- package/dist/core/context/instances.d.ts +31 -2
- package/dist/core/context/instances.js +18 -4
- package/dist/core/context/platform-registry.d.ts +35 -0
- package/dist/core/context/sms.d.ts +30 -0
- package/dist/core/context/sms.js +20 -0
- package/dist/core/context/types.d.ts +29 -1
- package/dist/core/conversation/index.d.ts +58 -4
- package/dist/core/conversation/index.js +123 -4
- package/dist/core/functions/errors.d.ts +74 -0
- package/dist/core/functions/errors.js +26 -0
- package/dist/core/functions/events.d.ts +23 -78
- package/dist/core/functions/events.js +8 -17
- package/dist/core/functions/schedules.d.ts +9 -10
- package/dist/core/functions/schedules.js +2 -2
- package/dist/core/functions/types.d.ts +17 -72
- package/dist/core/functions/types.js +1 -9
- package/dist/core/page/define.d.ts +230 -160
- package/dist/core/page/define.js +145 -104
- package/dist/core/page/envelope.d.ts +55 -0
- package/dist/core/page/envelope.js +4 -0
- package/dist/core/page/fns.d.ts +448 -0
- package/dist/core/page/fns.js +539 -0
- package/dist/core/page/memory-reader.d.ts +27 -0
- package/dist/core/page/memory-reader.js +299 -0
- package/dist/core/page/page-host.d.ts +20 -0
- package/dist/core/page/page-host.js +57 -0
- package/dist/core/page/records-query.d.ts +234 -0
- package/dist/core/page/records-query.js +780 -0
- package/dist/core/page/render.d.ts +67 -25
- package/dist/core/page/render.js +492 -272
- package/dist/core/page/sandbox.d.ts +85 -0
- package/dist/core/page/sandbox.js +357 -0
- package/dist/core/page/time-format.d.ts +27 -0
- package/dist/core/page/time-format.js +84 -0
- package/dist/core/page/typed.d.ts +165 -159
- package/dist/core/page/workspace.d.ts +25 -1
- package/dist/core/page/workspace.js +48 -13
- package/dist/core/party/schema.d.ts +74 -3
- package/dist/core/party/schema.js +39 -6
- package/dist/core/party/types.d.ts +8 -13
- package/dist/core/sequence/define.d.ts +1 -2
- package/dist/core/slot/company-metadata.d.ts +11 -22
- package/dist/core/slot/company-metadata.js +12 -39
- package/dist/core/slot/compile-schema.js +6 -6
- package/dist/core/slot/field.d.ts +1 -2
- package/dist/core/slot/field.js +0 -2
- package/dist/core/slot/index.d.ts +3 -3
- package/dist/core/slot/index.js +3 -3
- package/dist/core/slot/naming.d.ts +1 -1
- package/dist/core/slot/naming.js +1 -1
- package/dist/core/slot/platform-fields.d.ts +4 -4
- package/dist/core/slot/platform-fields.js +5 -5
- package/dist/core/slot/schema-compat.d.ts +8 -7
- package/dist/core/slot/schema-compat.js +22 -31
- package/dist/core/slot/schema.d.ts +3 -59
- package/dist/core/slot/schema.js +0 -15
- package/dist/core/slot/types.d.ts +4 -10
- package/dist/core/slot/value.d.ts +2 -0
- package/dist/core/slot/value.js +6 -2
- package/dist/dev-overlay/protocol.d.ts +38 -5
- package/dist/fn-context/build-context.js +10 -4
- package/dist/fn-context/fake/index.d.ts +2 -0
- package/dist/fn-context/fake/index.js +5 -3
- package/dist/fn-context/fn-params.d.ts +2 -5
- package/dist/fn-context/fn-params.js +6 -9
- package/dist/fn-context/index.d.ts +1 -1
- package/dist/fn-context/make-ctx.js +5 -4
- package/dist/fn-context/rpc/case-orchestrator-tools.d.ts +11 -3
- package/dist/fn-context/rpc/case-orchestrator-tools.js +0 -1
- package/dist/fn-context/rpc/errors.d.ts +13 -0
- package/dist/fn-context/rpc/errors.js +22 -0
- package/dist/fn-context/rpc/index.d.ts +1 -1
- package/dist/fn-context/rpc/index.js +1 -1
- package/dist/fn-context/rpc/integration/index.d.ts +11 -1
- package/dist/fn-context/rpc/log.d.ts +11 -1
- package/dist/fn-context/rpc/platform.d.ts +11 -1
- package/dist/fn-context/rpc/records.d.ts +13 -6
- package/dist/fn-context/rpc/records.js +2 -4
- package/dist/fn-context/rpc/trpc-client.d.ts +42 -0
- package/dist/fn-context/rpc/trpc-client.js +151 -22
- package/dist/fn-context/rpc/trpc-init.d.ts +19 -1
- package/dist/fn-context/rpc/trpc-init.js +10 -4
- package/dist/fn-context/rpc/trpc-router-factory.d.ts +66 -8
- package/dist/fn-context/run-scope.js +1 -1
- package/dist/fn-context/types.d.ts +20 -6
- package/dist/index.d.ts +11 -12
- package/dist/index.js +5 -8
- package/dist/logger.d.ts +4 -0
- package/dist/logger.js +8 -0
- package/dist/platform.d.ts +32 -33
- package/dist/platform.js +23 -22
- package/dist/testing-compile-child.d.ts +2 -0
- package/dist/testing-compile-child.js +20 -0
- package/dist/testing.d.ts +368 -0
- package/dist/testing.js +439 -0
- package/dist/voice-service/actions.d.ts +12 -35
- package/dist/voice-service/index.d.ts +2 -0
- package/dist/voice-service/index.js +2 -0
- package/dist/voice-service/protocol.d.ts +604 -0
- package/dist/voice-service/protocol.js +67 -0
- package/dist/voice-service/types.d.ts +16 -6
- package/dist/worker.d.ts +2 -1
- package/dist/worker.js +2 -1
- package/package.json +20 -16
- package/dist/core/case-orchestrator/follow-ups.d.ts +0 -31
- package/dist/core/case-orchestrator/follow-ups.js +0 -103
- package/dist/core/case-orchestrator/tools.d.ts +0 -29
- package/dist/core/case-orchestrator/tools.js +0 -31
- package/dist/core/case-orchestrator/validate.d.ts +0 -11
- package/dist/core/case-orchestrator/validate.js +0 -63
- package/dist/core/functions/define/bind.d.ts +0 -25
- package/dist/core/functions/define/bind.js +0 -14
- package/dist/core/functions/define/case.d.ts +0 -9
- package/dist/core/functions/define/case.js +0 -13
- package/dist/core/functions/define/events.d.ts +0 -20
- package/dist/core/functions/define/events.js +0 -21
- package/dist/core/functions/define/no-case.d.ts +0 -4
- package/dist/core/functions/define/no-case.js +0 -9
- package/dist/core/functions/func-ref.d.ts +0 -25
- package/dist/core/functions/func-ref.js +0 -20
|
@@ -12,7 +12,17 @@ export type PlatformInvokeHandler = (input: {
|
|
|
12
12
|
export declare function createPlatformRouter(invoke: PlatformInvokeHandler): import("@trpc/server").TRPCBuiltRouter<{
|
|
13
13
|
ctx: RpcContext;
|
|
14
14
|
meta: object;
|
|
15
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
15
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
16
|
+
message: string;
|
|
17
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
18
|
+
data: {
|
|
19
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
20
|
+
httpStatus: number;
|
|
21
|
+
path?: string;
|
|
22
|
+
stack?: string;
|
|
23
|
+
reason: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
16
26
|
transformer: false;
|
|
17
27
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
18
28
|
invoke: import("@trpc/server").TRPCMutationProcedure<{
|
|
@@ -2,9 +2,8 @@ import { z } from 'zod';
|
|
|
2
2
|
import { type RpcContext } from './trpc-init.js';
|
|
3
3
|
/**
|
|
4
4
|
* `ctx.api.db` of every function and the Orchestrator (15 §10.16): the same
|
|
5
|
-
* reads and writes as a page script and its actions, over RPC, one call per request. A write
|
|
6
|
-
*
|
|
7
|
-
* request sent again returns the first answer instead of writing twice.
|
|
5
|
+
* reads and writes as a page script and its actions, over RPC, one call per request. A write is done
|
|
6
|
+
* each time it is sent (38 §2.7): the platform keeps no key to answer a repeat with the first answer.
|
|
8
7
|
*/
|
|
9
8
|
declare const readInput: z.ZodObject<{
|
|
10
9
|
table: z.ZodString;
|
|
@@ -25,7 +24,6 @@ declare const writeInput: z.ZodObject<{
|
|
|
25
24
|
upsert: "upsert";
|
|
26
25
|
}>;
|
|
27
26
|
args: z.ZodUnknown;
|
|
28
|
-
callKey: z.ZodString;
|
|
29
27
|
}, z.core.$strip>;
|
|
30
28
|
export type RecordsReadInput = z.infer<typeof readInput>;
|
|
31
29
|
export type RecordsWriteInput = z.infer<typeof writeInput>;
|
|
@@ -51,7 +49,17 @@ export type RecordsHandlers = {
|
|
|
51
49
|
export declare function createRecordsRouter(handlers: RecordsHandlers): import("@trpc/server").TRPCBuiltRouter<{
|
|
52
50
|
ctx: RpcContext;
|
|
53
51
|
meta: object;
|
|
54
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
52
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
53
|
+
message: string;
|
|
54
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
55
|
+
data: {
|
|
56
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
57
|
+
httpStatus: number;
|
|
58
|
+
path?: string;
|
|
59
|
+
stack?: string;
|
|
60
|
+
reason: string;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
55
63
|
transformer: false;
|
|
56
64
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
57
65
|
read: import("@trpc/server").TRPCMutationProcedure<{
|
|
@@ -68,7 +76,6 @@ export declare function createRecordsRouter(handlers: RecordsHandlers): import("
|
|
|
68
76
|
table: string;
|
|
69
77
|
method: "create" | "delete" | "update" | "upsert";
|
|
70
78
|
args: unknown;
|
|
71
|
-
callKey: string;
|
|
72
79
|
};
|
|
73
80
|
output: RecordsResult;
|
|
74
81
|
meta: object;
|
|
@@ -2,9 +2,8 @@ import { z } from 'zod';
|
|
|
2
2
|
import { publicProcedure, router } from './trpc-init.js';
|
|
3
3
|
/**
|
|
4
4
|
* `ctx.api.db` of every function and the Orchestrator (15 §10.16): the same
|
|
5
|
-
* reads and writes as a page script and its actions, over RPC, one call per request. A write
|
|
6
|
-
*
|
|
7
|
-
* request sent again returns the first answer instead of writing twice.
|
|
5
|
+
* reads and writes as a page script and its actions, over RPC, one call per request. A write is done
|
|
6
|
+
* each time it is sent (38 §2.7): the platform keeps no key to answer a repeat with the first answer.
|
|
8
7
|
*/
|
|
9
8
|
const readInput = z.object({
|
|
10
9
|
table: z.string().min(1),
|
|
@@ -15,7 +14,6 @@ const writeInput = z.object({
|
|
|
15
14
|
table: z.string().min(1),
|
|
16
15
|
method: z.enum(['create', 'update', 'upsert', 'delete']),
|
|
17
16
|
args: z.unknown(),
|
|
18
|
-
callKey: z.string().min(1).max(200),
|
|
19
17
|
});
|
|
20
18
|
export function createRecordsRouter(handlers) {
|
|
21
19
|
return router({
|
|
@@ -1,4 +1,41 @@
|
|
|
1
1
|
import type { ApiHost, CaseOrchestratorApiHost } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A request that got no answer from the platform itself (74 §3.2): the platform always answers JSON, so any
|
|
4
|
+
* other answer is a gateway's. `reached: false` only when the request certainly never got to the platform.
|
|
5
|
+
*/
|
|
6
|
+
export declare class RpcTransportError extends Error {
|
|
7
|
+
readonly reached: boolean | 'unknown';
|
|
8
|
+
readonly name = "RpcTransportError";
|
|
9
|
+
constructor(message: string, reached: boolean | 'unknown');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* `fetch` for the platform's RPC: a failure to connect, or an answer that is not the platform's (not JSON),
|
|
13
|
+
* becomes an {@link RpcTransportError} saying whether the request reached it. The answer is read whole here:
|
|
14
|
+
* one that breaks as it is read (a body cut off, bad JSON) is an {@link RpcTransportError} too, so whatever
|
|
15
|
+
* fails before this is called (the code's arguments that cannot be sent as JSON) stays the code's.
|
|
16
|
+
*/
|
|
17
|
+
export declare function platformFetch(input: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]): Promise<Response>;
|
|
18
|
+
/** Sent again: the platform was busy (`TOO_MANY_REQUESTS`), or the request never reached it. */
|
|
19
|
+
export declare function shouldRetryRpc(error: {
|
|
20
|
+
data?: {
|
|
21
|
+
code?: string;
|
|
22
|
+
} | null;
|
|
23
|
+
cause?: unknown;
|
|
24
|
+
}, attempts: number): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* A failed call as company code sees it: an `Error` with the platform's message and, when the platform
|
|
27
|
+
* refused it for a reason of the business (`subject_busy`, `run_ended`, a write's code), that reason as
|
|
28
|
+
* `error.code` (64 §12).
|
|
29
|
+
*/
|
|
30
|
+
export declare function rpcSafe<T>(promise: Promise<T>): Promise<T>;
|
|
31
|
+
/**
|
|
32
|
+
* A read's arguments as sent, `after` cut down to the place the platform reads off it (18 §4.6): the
|
|
33
|
+
* row's `id`, `createdAt` and `updatedAt`, and of each field this read's `orderBy` names, the slot's
|
|
34
|
+
* `value`. `after: rows.at(-1)` is a row with whatever it `include`d; sent whole, a big include tree
|
|
35
|
+
* could pass the request's size limit for nothing. Anything that is no row goes as given, for the
|
|
36
|
+
* platform to refuse with its reason.
|
|
37
|
+
*/
|
|
38
|
+
export declare function placeOnly(args: unknown): unknown;
|
|
2
39
|
export declare function createRpcApiHost(options: {
|
|
3
40
|
baseUrl: string;
|
|
4
41
|
getToken: () => string | Promise<string>;
|
|
@@ -7,5 +44,10 @@ export declare function createRpcApiHost(options: {
|
|
|
7
44
|
getRequestId?: () => string | undefined;
|
|
8
45
|
getTags?: () => string[] | undefined;
|
|
9
46
|
waitUntil?: (promise: Promise<unknown>) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Asked before each call is sent, with its procedure's path (`platform.invoke`, `log.emit`, …): throws
|
|
49
|
+
* to refuse it. The Worker refuses a `ctx` kept from another call (64 §6).
|
|
50
|
+
*/
|
|
51
|
+
checkCall?: (path: string) => void;
|
|
10
52
|
}): ApiHost & CaseOrchestratorApiHost;
|
|
11
53
|
//# sourceMappingURL=trpc-client.d.ts.map
|
|
@@ -4,6 +4,7 @@ import { integrationSurfaceKeys, } from '../../core/context/types.js';
|
|
|
4
4
|
import { bindEnvService } from '../../core/context/env.js';
|
|
5
5
|
import { CASE_ORCHESTRATOR_TOOL_NAMES, } from '../../core/case-orchestrator/types.js';
|
|
6
6
|
import { getLogger } from '../../logger.js';
|
|
7
|
+
import { PlatformUnavailableError } from '../../core/functions/errors.js';
|
|
7
8
|
import { REQUEST_ID_HEADER, RUNTIME_VERSION_HEADER, formatRuntimeVersion } from './request-id.js';
|
|
8
9
|
const logger = getLogger(['runtime', 'rpc']);
|
|
9
10
|
/**
|
|
@@ -12,6 +13,83 @@ const logger = getLogger(['runtime', 'rpc']);
|
|
|
12
13
|
*/
|
|
13
14
|
const BUSY_RETRIES = 5;
|
|
14
15
|
const busyDelayMs = (attempt) => Math.min(500 * 2 ** attempt, 5_000) + Math.floor(Math.random() * 250);
|
|
16
|
+
/**
|
|
17
|
+
* A call that certainly never reached the platform (a gateway's error page, a refused connection, a name that
|
|
18
|
+
* did not resolve) is sent again this many times, after the same growing pause (74 §3.2). One that may have
|
|
19
|
+
* reached it (504, a connection cut after it was sent) is not, read or write alike.
|
|
20
|
+
*/
|
|
21
|
+
const UNREACHED_RETRIES = 3;
|
|
22
|
+
/**
|
|
23
|
+
* A request that got no answer from the platform itself (74 §3.2): the platform always answers JSON, so any
|
|
24
|
+
* other answer is a gateway's. `reached: false` only when the request certainly never got to the platform.
|
|
25
|
+
*/
|
|
26
|
+
export class RpcTransportError extends Error {
|
|
27
|
+
reached;
|
|
28
|
+
name = 'RpcTransportError';
|
|
29
|
+
constructor(message, reached) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.reached = reached;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** A gateway's own answer that may come after the platform got the request: its timeouts (504; Cloudflare 520, 524). */
|
|
35
|
+
const MAYBE_REACHED_STATUSES = new Set([504, 520, 524]);
|
|
36
|
+
/** Fetch failures where no connection was ever made. */
|
|
37
|
+
const NOT_CONNECTED = /ECONNREFUSED|ENOTFOUND|EAI_AGAIN|getaddrinfo/;
|
|
38
|
+
function connectFailure(error) {
|
|
39
|
+
for (let current = error, depth = 0; current && depth < 5; depth += 1) {
|
|
40
|
+
const { code, message, errors } = current;
|
|
41
|
+
if (NOT_CONNECTED.test(`${String(code ?? '')} ${String(message ?? '')}`))
|
|
42
|
+
return true;
|
|
43
|
+
if (Array.isArray(errors) && errors.some(connectFailure))
|
|
44
|
+
return true;
|
|
45
|
+
current = current.cause;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* `fetch` for the platform's RPC: a failure to connect, or an answer that is not the platform's (not JSON),
|
|
51
|
+
* becomes an {@link RpcTransportError} saying whether the request reached it. The answer is read whole here:
|
|
52
|
+
* one that breaks as it is read (a body cut off, bad JSON) is an {@link RpcTransportError} too, so whatever
|
|
53
|
+
* fails before this is called (the code's arguments that cannot be sent as JSON) stays the code's.
|
|
54
|
+
*/
|
|
55
|
+
export async function platformFetch(input, init) {
|
|
56
|
+
let response;
|
|
57
|
+
try {
|
|
58
|
+
response = await fetch(input, init);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
const reached = connectFailure(error) ? false : 'unknown';
|
|
62
|
+
throw new RpcTransportError(`the platform could not be reached: ${error instanceof Error ? error.message : String(error)}`, reached);
|
|
63
|
+
}
|
|
64
|
+
if (!/json/i.test(response.headers.get('content-type') ?? '')) {
|
|
65
|
+
const body = (await response.text().catch(() => '')).slice(0, 120).replace(/\s+/g, ' ');
|
|
66
|
+
throw new RpcTransportError(`HTTP ${response.status} from a gateway, not the platform: ${body}`, MAYBE_REACHED_STATUSES.has(response.status) ? 'unknown' : false);
|
|
67
|
+
}
|
|
68
|
+
let text;
|
|
69
|
+
try {
|
|
70
|
+
text = await response.text();
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
throw new RpcTransportError(`the platform's answer was cut off: ${error instanceof Error ? error.message : String(error)}`, 'unknown');
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
JSON.parse(text);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
throw new RpcTransportError(`the platform's answer is not valid JSON: ${text.slice(0, 120)}`, 'unknown');
|
|
80
|
+
}
|
|
81
|
+
return new Response(text, { status: response.status, statusText: response.statusText, headers: response.headers });
|
|
82
|
+
}
|
|
83
|
+
function transportErrorOf(error) {
|
|
84
|
+
const cause = error?.cause;
|
|
85
|
+
return cause instanceof RpcTransportError ? cause : null;
|
|
86
|
+
}
|
|
87
|
+
/** Sent again: the platform was busy (`TOO_MANY_REQUESTS`), or the request never reached it. */
|
|
88
|
+
export function shouldRetryRpc(error, attempts) {
|
|
89
|
+
if (error.data?.code === 'TOO_MANY_REQUESTS')
|
|
90
|
+
return attempts <= BUSY_RETRIES;
|
|
91
|
+
return transportErrorOf(error)?.reached === false && attempts <= UNREACHED_RETRIES;
|
|
92
|
+
}
|
|
15
93
|
function rpcLogger(c, getTags, waitUntil) {
|
|
16
94
|
const emit = (level, message, extra) => {
|
|
17
95
|
const pending = c.log.emit.mutate({ level, message, extra, tags: getTags?.() }).catch(() => { });
|
|
@@ -28,10 +106,25 @@ function rpcLogger(c, getTags, waitUntil) {
|
|
|
28
106
|
error: (message, extra) => emit('error', message, extra),
|
|
29
107
|
};
|
|
30
108
|
}
|
|
31
|
-
|
|
109
|
+
/**
|
|
110
|
+
* A failed call as company code sees it: an `Error` with the platform's message and, when the platform
|
|
111
|
+
* refused it for a reason of the business (`subject_busy`, `run_ended`, a write's code), that reason as
|
|
112
|
+
* `error.code` (64 §12).
|
|
113
|
+
*/
|
|
114
|
+
export function rpcSafe(promise) {
|
|
32
115
|
return promise.catch((err) => {
|
|
33
116
|
if (err instanceof Error && err.constructor?.name === 'TRPCClientError') {
|
|
34
|
-
|
|
117
|
+
// No answer from the platform, one that broke as it was read (`platformFetch` says so), or its own
|
|
118
|
+
// failure (5xx): the platform's (74 §3.2), marked so. What failed before the request was sent (the
|
|
119
|
+
// code's arguments that are no JSON, a ctx kept from another call) stays the code's.
|
|
120
|
+
const status = err.data?.httpStatus;
|
|
121
|
+
const platform = transportErrorOf(err) !== null || (typeof status === 'number' && status >= 500);
|
|
122
|
+
const message = `RPC call failed: ${transportErrorOf(err)?.message ?? err.message}`;
|
|
123
|
+
const failed = (platform ? new PlatformUnavailableError(message) : new Error(message));
|
|
124
|
+
const reason = err.data?.reason;
|
|
125
|
+
if (typeof reason === 'string')
|
|
126
|
+
failed.code = reason;
|
|
127
|
+
throw failed;
|
|
35
128
|
}
|
|
36
129
|
throw err;
|
|
37
130
|
});
|
|
@@ -93,7 +186,7 @@ function buildPlatformApis(c) {
|
|
|
93
186
|
function buildCaseOrchestratorTools(c) {
|
|
94
187
|
const tools = CASE_ORCHESTRATOR_TOOL_NAMES.map((tool) => [
|
|
95
188
|
tool,
|
|
96
|
-
(input
|
|
189
|
+
(input) => rpcSafe(c.caseOrchestratorTools.invoke.mutate({ tool, input })),
|
|
97
190
|
]);
|
|
98
191
|
// The tool registry guarantees the shape; TS cannot follow it through Object.fromEntries.
|
|
99
192
|
return Object.fromEntries(tools);
|
|
@@ -106,24 +199,49 @@ function unwrapRecords(result) {
|
|
|
106
199
|
error.code = result.error.code;
|
|
107
200
|
throw error;
|
|
108
201
|
}
|
|
202
|
+
function isPlainObject(value) {
|
|
203
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
204
|
+
}
|
|
205
|
+
/** The keys of a row the platform always reads off `after`: its id and times. */
|
|
206
|
+
const PLACE_KEYS = new Set(['id', 'createdAt', 'updatedAt']);
|
|
207
|
+
/**
|
|
208
|
+
* A read's arguments as sent, `after` cut down to the place the platform reads off it (18 §4.6): the
|
|
209
|
+
* row's `id`, `createdAt` and `updatedAt`, and of each field this read's `orderBy` names, the slot's
|
|
210
|
+
* `value`. `after: rows.at(-1)` is a row with whatever it `include`d; sent whole, a big include tree
|
|
211
|
+
* could pass the request's size limit for nothing. Anything that is no row goes as given, for the
|
|
212
|
+
* platform to refuse with its reason.
|
|
213
|
+
*/
|
|
214
|
+
export function placeOnly(args) {
|
|
215
|
+
if (!isPlainObject(args) || !isPlainObject(args.after))
|
|
216
|
+
return args;
|
|
217
|
+
const ordered = new Set();
|
|
218
|
+
for (const entry of Array.isArray(args.orderBy) ? args.orderBy : [args.orderBy]) {
|
|
219
|
+
if (isPlainObject(entry))
|
|
220
|
+
for (const field of Object.keys(entry))
|
|
221
|
+
ordered.add(field);
|
|
222
|
+
}
|
|
223
|
+
const place = Object.entries(args.after).flatMap(([key, value]) => {
|
|
224
|
+
if (PLACE_KEYS.has(key))
|
|
225
|
+
return [[key, value]];
|
|
226
|
+
if (!ordered.has(key))
|
|
227
|
+
return [];
|
|
228
|
+
// A slot: only its value places the row (a lookup's included `row` does not).
|
|
229
|
+
return [[key, isPlainObject(value) ? (Object.hasOwn(value, 'value') ? { value: value.value } : {}) : value]];
|
|
230
|
+
});
|
|
231
|
+
return { ...args, after: Object.fromEntries(place) };
|
|
232
|
+
}
|
|
109
233
|
/**
|
|
110
234
|
* `ctx.api.db` of every function and the Orchestrator (15 §10.15 task 4, §10.16): every table, as a
|
|
111
|
-
* page script and its actions see them, one request per call
|
|
112
|
-
*
|
|
113
|
-
* same key and is not made twice.
|
|
235
|
+
* page script and its actions see them, one request per call; a write is done each time (38 §2.7). A
|
|
236
|
+
* read's `after` goes as its place only ({@link placeOnly}).
|
|
114
237
|
*/
|
|
115
238
|
function buildDbApi(c) {
|
|
116
|
-
let writes = 0;
|
|
117
239
|
const db = new Proxy({}, {
|
|
118
240
|
get(_, table) {
|
|
119
241
|
if (typeof table !== 'string')
|
|
120
242
|
return undefined;
|
|
121
|
-
const read = (method) => async (args) => unwrapRecords(await rpcSafe(c.records.read.mutate({ table, method, args: args ?? {} })));
|
|
122
|
-
const write = (method) => async (args) => {
|
|
123
|
-
writes += 1;
|
|
124
|
-
const callKey = `write:${writes}`;
|
|
125
|
-
return unwrapRecords(await rpcSafe(c.records.write.mutate({ table, method, args: args ?? {}, callKey })));
|
|
126
|
-
};
|
|
243
|
+
const read = (method) => async (args) => unwrapRecords(await rpcSafe(c.records.read.mutate({ table, method, args: placeOnly(args ?? {}) })));
|
|
244
|
+
const write = (method) => async (args) => unwrapRecords(await rpcSafe(c.records.write.mutate({ table, method, args: args ?? {} })));
|
|
127
245
|
return {
|
|
128
246
|
$table: table,
|
|
129
247
|
findUnique: read('findUnique'),
|
|
@@ -147,12 +265,14 @@ export function createRpcApiHost(options) {
|
|
|
147
265
|
client = createTRPCClient({
|
|
148
266
|
links: [
|
|
149
267
|
retryLink({
|
|
150
|
-
retry: ({ error, attempts }) => error
|
|
268
|
+
retry: ({ error, attempts }) => shouldRetryRpc(error, attempts),
|
|
151
269
|
retryDelayMs: busyDelayMs,
|
|
152
270
|
}),
|
|
153
271
|
httpLink({
|
|
154
272
|
url: baseUrl,
|
|
155
|
-
|
|
273
|
+
fetch: platformFetch,
|
|
274
|
+
headers: async ({ op }) => {
|
|
275
|
+
options.checkCall?.(op.path);
|
|
156
276
|
const headers = {
|
|
157
277
|
authorization: `Bearer ${await options.getToken()}`,
|
|
158
278
|
[RUNTIME_VERSION_HEADER]: formatRuntimeVersion(options.runtimeVersion, options.runtimeSource),
|
|
@@ -169,24 +289,33 @@ export function createRpcApiHost(options) {
|
|
|
169
289
|
}
|
|
170
290
|
return client;
|
|
171
291
|
}
|
|
292
|
+
/** The integrations the call brought; without them, the backend lists them. */
|
|
293
|
+
async function surfacesOf(c, given) {
|
|
294
|
+
if (given.surfaces)
|
|
295
|
+
return given.surfaces;
|
|
296
|
+
const started = Date.now();
|
|
297
|
+
logger.info('integration.listSurfaces start', { url: options.baseUrl });
|
|
298
|
+
const metas = await rpcSafe(c.integration.listSurfaces.query());
|
|
299
|
+
logger.info('integration.listSurfaces ok', { durationMs: Date.now() - started, count: metas.length });
|
|
300
|
+
return metas;
|
|
301
|
+
}
|
|
172
302
|
return {
|
|
173
|
-
async buildApi(_run) {
|
|
303
|
+
async buildApi(_run, given = {}) {
|
|
174
304
|
const c = getClient(options.baseUrl);
|
|
175
|
-
const
|
|
176
|
-
logger.info('integration.listSurfaces start', { url: options.baseUrl });
|
|
177
|
-
const metas = await rpcSafe(c.integration.listSurfaces.query());
|
|
178
|
-
logger.info('integration.listSurfaces ok', { durationMs: Date.now() - started, count: metas.length });
|
|
305
|
+
const metas = await surfacesOf(c, given);
|
|
179
306
|
return {
|
|
180
307
|
...buildPlatformApis(c),
|
|
181
308
|
integration: buildSurfaces(c, metas),
|
|
182
309
|
log: rpcLogger(c, options.getTags, options.waitUntil),
|
|
310
|
+
// Every function's (38 §2.7): each call names its instance.
|
|
311
|
+
tools: buildCaseOrchestratorTools(c),
|
|
183
312
|
...buildDbApi(c),
|
|
184
313
|
};
|
|
185
314
|
},
|
|
186
|
-
async buildCaseOrchestratorApi(_run) {
|
|
315
|
+
async buildCaseOrchestratorApi(_run, given = {}) {
|
|
187
316
|
const c = getClient(options.baseUrl);
|
|
188
317
|
// A function's api (25 §7), so a function called from the Orchestrator with its ctx works the same.
|
|
189
|
-
const metas = await
|
|
318
|
+
const metas = await surfacesOf(c, given);
|
|
190
319
|
return {
|
|
191
320
|
...buildPlatformApis(c),
|
|
192
321
|
integration: buildSurfaces(c, metas),
|
|
@@ -3,11 +3,29 @@ export type RpcContext = {
|
|
|
3
3
|
run: RunClaims;
|
|
4
4
|
requestId?: string;
|
|
5
5
|
runtimeVersion?: string;
|
|
6
|
+
/**
|
|
7
|
+
* The platform's gate around every procedure (64 §5): the rate, and whether an Orchestrator's task still
|
|
8
|
+
* runs. Set by the platform's context; every procedure built on {@link publicProcedure} passes through it,
|
|
9
|
+
* so a new one cannot miss it. Absent (a test calling one router directly), the procedure just runs.
|
|
10
|
+
*/
|
|
11
|
+
around?: <T>(call: {
|
|
12
|
+
path: string;
|
|
13
|
+
}, next: () => Promise<T>) => Promise<T>;
|
|
6
14
|
};
|
|
7
15
|
export declare const router: import("@trpc/server").TRPCRouterBuilder<{
|
|
8
16
|
ctx: RpcContext;
|
|
9
17
|
meta: object;
|
|
10
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
18
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
19
|
+
message: string;
|
|
20
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
21
|
+
data: {
|
|
22
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
23
|
+
httpStatus: number;
|
|
24
|
+
path?: string;
|
|
25
|
+
stack?: string;
|
|
26
|
+
reason: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
11
29
|
transformer: false;
|
|
12
30
|
}>;
|
|
13
31
|
/**
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { initTRPC, TRPCError } from '@trpc/server';
|
|
2
|
-
import { isRpcCodedError } from './errors.js';
|
|
3
|
-
const t = initTRPC.context().create(
|
|
2
|
+
import { isRpcCodedError, rpcErrorReason } from './errors.js';
|
|
3
|
+
const t = initTRPC.context().create({
|
|
4
|
+
// A refusal's business code (`subject_busy`, `run_ended`, …) goes back beside its message (64 §12).
|
|
5
|
+
errorFormatter({ shape, error }) {
|
|
6
|
+
const reason = rpcErrorReason(error.cause);
|
|
7
|
+
return reason ? { ...shape, data: { ...shape.data, reason } } : shape;
|
|
8
|
+
},
|
|
9
|
+
});
|
|
4
10
|
export const router = t.router;
|
|
5
11
|
/**
|
|
6
12
|
* Applied to every procedure so domain errors reach the caller with the status they declared,
|
|
7
13
|
* without each dispatcher wrapping its own body in try/catch.
|
|
8
14
|
*/
|
|
9
|
-
export const publicProcedure = t.procedure.use(async ({ next }) => {
|
|
10
|
-
const result = await next();
|
|
15
|
+
export const publicProcedure = t.procedure.use(async ({ ctx, path, next }) => {
|
|
16
|
+
const result = ctx.around ? await ctx.around({ path }, () => next()) : await next();
|
|
11
17
|
if (!result.ok && isRpcCodedError(result.error.cause)) {
|
|
12
18
|
const cause = result.error.cause;
|
|
13
19
|
throw new TRPCError({ code: cause.rpcCode, message: cause.message, cause });
|
|
@@ -12,13 +12,33 @@ export declare function createAppRouter(modules: {
|
|
|
12
12
|
}): import("@trpc/server").TRPCBuiltRouter<{
|
|
13
13
|
ctx: import("./trpc-init.js").RpcContext;
|
|
14
14
|
meta: object;
|
|
15
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
15
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
16
|
+
message: string;
|
|
17
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
18
|
+
data: {
|
|
19
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
20
|
+
httpStatus: number;
|
|
21
|
+
path?: string;
|
|
22
|
+
stack?: string;
|
|
23
|
+
reason: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
16
26
|
transformer: false;
|
|
17
27
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
18
28
|
integration: import("@trpc/server").TRPCBuiltRouter<{
|
|
19
29
|
ctx: import("./trpc-init.js").RpcContext;
|
|
20
30
|
meta: object;
|
|
21
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
31
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
32
|
+
message: string;
|
|
33
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
34
|
+
data: {
|
|
35
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
36
|
+
httpStatus: number;
|
|
37
|
+
path?: string;
|
|
38
|
+
stack?: string;
|
|
39
|
+
reason: string;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
22
42
|
transformer: false;
|
|
23
43
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
24
44
|
listSurfaces: import("@trpc/server").TRPCQueryProcedure<{
|
|
@@ -52,7 +72,17 @@ export declare function createAppRouter(modules: {
|
|
|
52
72
|
platform: import("@trpc/server").TRPCBuiltRouter<{
|
|
53
73
|
ctx: import("./trpc-init.js").RpcContext;
|
|
54
74
|
meta: object;
|
|
55
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
75
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
76
|
+
message: string;
|
|
77
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
78
|
+
data: {
|
|
79
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
80
|
+
httpStatus: number;
|
|
81
|
+
path?: string;
|
|
82
|
+
stack?: string;
|
|
83
|
+
reason: string;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
56
86
|
transformer: false;
|
|
57
87
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
58
88
|
invoke: import("@trpc/server").TRPCMutationProcedure<{
|
|
@@ -68,7 +98,17 @@ export declare function createAppRouter(modules: {
|
|
|
68
98
|
log: import("@trpc/server").TRPCBuiltRouter<{
|
|
69
99
|
ctx: import("./trpc-init.js").RpcContext;
|
|
70
100
|
meta: object;
|
|
71
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
101
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
102
|
+
message: string;
|
|
103
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
104
|
+
data: {
|
|
105
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
106
|
+
httpStatus: number;
|
|
107
|
+
path?: string;
|
|
108
|
+
stack?: string;
|
|
109
|
+
reason: string;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
72
112
|
transformer: false;
|
|
73
113
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
74
114
|
emit: import("@trpc/server").TRPCMutationProcedure<{
|
|
@@ -87,14 +127,23 @@ export declare function createAppRouter(modules: {
|
|
|
87
127
|
caseOrchestratorTools: import("@trpc/server").TRPCBuiltRouter<{
|
|
88
128
|
ctx: import("./trpc-init.js").RpcContext;
|
|
89
129
|
meta: object;
|
|
90
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
130
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
131
|
+
message: string;
|
|
132
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
133
|
+
data: {
|
|
134
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
135
|
+
httpStatus: number;
|
|
136
|
+
path?: string;
|
|
137
|
+
stack?: string;
|
|
138
|
+
reason: string;
|
|
139
|
+
};
|
|
140
|
+
};
|
|
91
141
|
transformer: false;
|
|
92
142
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
93
143
|
invoke: import("@trpc/server").TRPCMutationProcedure<{
|
|
94
144
|
input: {
|
|
95
145
|
tool: string;
|
|
96
146
|
input: unknown;
|
|
97
|
-
callKey: string;
|
|
98
147
|
};
|
|
99
148
|
output: unknown;
|
|
100
149
|
meta: object;
|
|
@@ -103,7 +152,17 @@ export declare function createAppRouter(modules: {
|
|
|
103
152
|
records: import("@trpc/server").TRPCBuiltRouter<{
|
|
104
153
|
ctx: import("./trpc-init.js").RpcContext;
|
|
105
154
|
meta: object;
|
|
106
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
155
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
156
|
+
message: string;
|
|
157
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
158
|
+
data: {
|
|
159
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
160
|
+
httpStatus: number;
|
|
161
|
+
path?: string;
|
|
162
|
+
stack?: string;
|
|
163
|
+
reason: string;
|
|
164
|
+
};
|
|
165
|
+
};
|
|
107
166
|
transformer: false;
|
|
108
167
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
109
168
|
read: import("@trpc/server").TRPCMutationProcedure<{
|
|
@@ -120,7 +179,6 @@ export declare function createAppRouter(modules: {
|
|
|
120
179
|
table: string;
|
|
121
180
|
method: "create" | "delete" | "update" | "upsert";
|
|
122
181
|
args: unknown;
|
|
123
|
-
callKey: string;
|
|
124
182
|
};
|
|
125
183
|
output: import("./records.js").RecordsResult;
|
|
126
184
|
meta: object;
|
|
@@ -2,7 +2,7 @@ import { ORCHESTRATOR_ENTRY } from '../core/case-orchestrator/types.js';
|
|
|
2
2
|
/** The Case Orchestrator scope of a run, or null when it is not a complete Case Orchestrator run. */
|
|
3
3
|
export function asCaseOrchestratorRun(run) {
|
|
4
4
|
const scoped = run;
|
|
5
|
-
if (run.entry !== ORCHESTRATOR_ENTRY || !scoped.instanceId || !scoped.
|
|
5
|
+
if (run.entry !== ORCHESTRATOR_ENTRY || !scoped.instanceId || !scoped.orchestratorTaskId)
|
|
6
6
|
return null;
|
|
7
7
|
return run;
|
|
8
8
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ORCHESTRATOR_ENTRY, CaseOrchestratorApi, CaseOrchestratorContext } from '../core/case-orchestrator/types.js';
|
|
2
|
-
import type { SystemContext } from '../core/context/types.js';
|
|
2
|
+
import type { IntegrationSurfaceMeta, SystemContext } from '../core/context/types.js';
|
|
3
3
|
/** Alias for {@link SystemContext} (08 ActionContext shape). */
|
|
4
4
|
export type ActionContext = SystemContext;
|
|
5
5
|
/**
|
|
@@ -7,8 +7,19 @@ export type ActionContext = SystemContext;
|
|
|
7
7
|
* function runs). Its ids are plain strings on the wire; the function's `ctx.meta` types them.
|
|
8
8
|
*/
|
|
9
9
|
export type ActionDataSlice = Pick<ActionContext, 'config'> & {
|
|
10
|
-
|
|
10
|
+
/** `ignore` absent (a platform before 68 §6.2): nothing is ignored. */
|
|
11
|
+
time: Omit<ActionContext['time'], 'format' | 'day' | 'at' | 'parts' | 'ignore'> & Partial<Pick<ActionContext['time'], 'ignore'>>;
|
|
11
12
|
meta: ActionContext['meta'];
|
|
13
|
+
/**
|
|
14
|
+
* What `ctx.api.integration` offers this run (its connections and mailboxes, with their credentials),
|
|
15
|
+
* listed by the platform as it calls the function: the host builds the api from it instead of asking
|
|
16
|
+
* the backend first. Not part of `ctx` itself.
|
|
17
|
+
*/
|
|
18
|
+
surfaces?: IntegrationSurfaceMeta[];
|
|
19
|
+
};
|
|
20
|
+
/** What the call brought for the api ({@link ActionDataSlice.surfaces}): a host lists what is left out. */
|
|
21
|
+
export type ApiGiven = {
|
|
22
|
+
surfaces?: IntegrationSurfaceMeta[];
|
|
12
23
|
};
|
|
13
24
|
/** Identity / scope for a single function invocation (ApiHost may key caches on this). */
|
|
14
25
|
export type RunScope = {
|
|
@@ -31,19 +42,22 @@ export type RunScope = {
|
|
|
31
42
|
};
|
|
32
43
|
/** Who fulfills `ctx.api` (Fake local vs Rpc remote). */
|
|
33
44
|
export type ApiHost = {
|
|
34
|
-
buildApi(run: RunScope): Promise<ActionContext['api']>;
|
|
45
|
+
buildApi(run: RunScope, given?: ApiGiven): Promise<ActionContext['api']>;
|
|
35
46
|
};
|
|
36
47
|
/** `ctx` of `orchestrator` before the host adds `params`. */
|
|
37
48
|
export type CaseOrchestratorActionContext = Omit<CaseOrchestratorContext, 'params'>;
|
|
38
49
|
/** Who fulfills the Case Orchestrator's `ctx.api` (Fake local vs Rpc remote). */
|
|
39
50
|
export type CaseOrchestratorApiHost = {
|
|
40
|
-
buildCaseOrchestratorApi(run: RunScope): Promise<CaseOrchestratorApi>;
|
|
51
|
+
buildCaseOrchestratorApi(run: RunScope, given?: ApiGiven): Promise<CaseOrchestratorApi>;
|
|
41
52
|
};
|
|
42
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Run scope of an Orchestrator call: the instance it is limited to and the `OrchestratorTask` it runs
|
|
55
|
+
* for (40 §2.3: no `AgentRun`), refused once that task stops running.
|
|
56
|
+
*/
|
|
43
57
|
export type CaseOrchestratorRunScope = RunScope & {
|
|
44
58
|
entry: typeof ORCHESTRATOR_ENTRY;
|
|
45
59
|
instanceId: string;
|
|
46
|
-
|
|
60
|
+
orchestratorTaskId: string;
|
|
47
61
|
};
|
|
48
62
|
/** A verified run token's scope; narrow with {@link asCaseOrchestratorRun}. */
|
|
49
63
|
export type RunClaims = RunScope | CaseOrchestratorRunScope;
|