apps 0.0.1-beta.3 → 0.0.1-beta.31
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 +68 -44
- package/framework-reference.json +1 -1
- package/js/{chunk-RN2MXB4R.js → chunk-3FJYVAE4.js} +128 -24
- package/js/chunk-4OKYLVU4.js +118 -0
- package/js/{chunk-LGIYBDWA.js → chunk-5DLG2FVN.js} +65 -1
- package/js/{chunk-PLCMJREA.js → chunk-5JVNM3CQ.js} +60 -20
- package/js/chunk-5XJR4XGW.js +254 -0
- package/js/{chunk-FZJOYIZO.js → chunk-6KG4DZD7.js} +1 -1
- package/js/{chunk-EVJUVWN2.js → chunk-6ZJ2H6P4.js} +2 -2
- package/js/{chunk-NQ3OMCA5.js → chunk-AUFVX4KM.js} +2 -2
- package/js/{chunk-D47C7KG5.js → chunk-AYM2FUI5.js} +2 -2
- package/js/{chunk-5MQZEB6Y.js → chunk-BGALSHLT.js} +37 -12
- package/js/{chunk-QKHR7BMF.js → chunk-CJY5X26R.js} +3 -3
- package/js/{chunk-M6ZRRIBI.js → chunk-DASNNAP4.js} +1 -1
- package/js/{chunk-ZCAMUXSG.js → chunk-ETLILMHY.js} +3 -4
- package/js/{chunk-FW5HBOIK.js → chunk-EXGKN554.js} +2005 -1710
- package/js/{chunk-SATWJKN6.js → chunk-FBBXFFFJ.js} +1 -1
- package/js/{chunk-JN55AYQH.js → chunk-FULRJSWU.js} +61 -32
- package/js/{chunk-HDTGZWP2.js → chunk-GG566OOE.js} +139 -32
- package/js/chunk-GZ4UHXRT.js +92 -0
- package/js/{chunk-YEJOQEII.js → chunk-HW3DPBZR.js} +45 -7
- package/js/{chunk-HDJH3RPR.js → chunk-MFHUR5SB.js} +2 -2
- package/js/{chunk-MYYEW3RA.js → chunk-N72RKJ5E.js} +984 -61
- package/js/{chunk-WFSQXYUT.js → chunk-NPGRURDG.js} +390 -18
- package/js/chunk-OD3KFKZD.js +1617 -0
- package/js/{chunk-FDNTX5QJ.js → chunk-OX233L7N.js} +2 -2
- package/js/{chunk-G7ZIRKMK.js → chunk-QYM4STZW.js} +118 -197
- package/js/chunk-RULZPNGP.js +801 -0
- package/js/{chunk-BMOIAIVR.js → chunk-UMCMZFXW.js} +49 -1
- package/js/{chunk-J7O55ZV7.js → chunk-W7F23NQ2.js} +419 -191
- package/js/chunk-WG5DFZFT.js +42 -0
- package/js/{chunk-T2LAZCAD.js → chunk-ZOY7PDMI.js} +1 -1
- package/js/client.js +120 -84
- package/js/contracts.js +110 -16
- package/js/effect.js +20 -20
- package/js/{es-APDZKREY.js → es-DIULA3ZF.js} +62 -1659
- package/js/graphql.js +58 -54
- package/js/host.js +20 -20
- package/js/index.js +247 -204
- package/js/mcp/effect.js +24 -22
- package/js/mcp/stdio.js +35 -30
- package/js/mcp.js +105 -68
- package/js/openapi.js +4087 -1503
- package/js/react.js +3 -3
- package/js/skills/effect.js +5 -3
- package/js/skills.js +15 -15
- package/js/storage/facet.js +4 -4
- package/js/ui/auth/contracts.js +2 -2
- package/js/ui/auth.js +5 -5
- package/js/ui/contracts.js +5 -4
- package/js/ui/serving.js +8516 -214
- package/package.json +1 -1
- package/runtime.json +1 -1
- package/types/app-data/src/contracts/database.d.ts +33 -6
- package/types/app-data/src/implementation/schema.d.ts +2 -17
- package/types/apps/src/contracts/api-response-error.d.ts +4 -0
- package/types/apps/src/contracts/app.d.ts +7 -6
- package/types/apps/src/contracts/failure.d.ts +54 -0
- package/types/apps/src/contracts/graphql.d.ts +2 -1
- package/types/apps/src/contracts/host.d.ts +34 -11
- package/types/apps/src/contracts/mcp.d.ts +91 -10
- package/types/apps/src/contracts/network.d.ts +84 -0
- package/types/apps/src/contracts/openapi-compile.d.ts +31 -3
- package/types/apps/src/contracts/openapi.d.ts +45 -9
- package/types/apps/src/contracts/operations.d.ts +5 -6
- package/types/apps/src/contracts/protocol-version.d.ts +2 -2
- package/types/apps/src/contracts/protocols/1.d.ts +251 -69
- package/types/apps/src/contracts/protocols/2.d.ts +710 -0
- package/types/apps/src/contracts/protocols/3.d.ts +716 -0
- package/types/apps/src/contracts/protocols/4.d.ts +1298 -0
- package/types/apps/src/contracts/protocols/5.d.ts +1174 -0
- package/types/apps/src/contracts/protocols/6.d.ts +1620 -0
- package/types/apps/src/contracts/protocols/7.d.ts +1784 -0
- package/types/apps/src/contracts/protocols/8.d.ts +1119 -0
- package/types/apps/src/contracts/protocols/oauth.d.ts +89 -0
- package/types/apps/src/contracts/provider-error.d.ts +9 -0
- package/types/apps/src/contracts/provider.d.ts +115 -10
- package/types/apps/src/contracts/router.d.ts +59 -0
- package/types/apps/src/contracts/skills.d.ts +18 -5
- package/types/apps/src/contracts/storage.d.ts +3 -3
- package/types/apps/src/contracts/ui.d.ts +18 -0
- package/types/apps/src/contracts/workflows.d.ts +34 -3
- package/types/apps/src/graphql.d.ts +1 -3
- package/types/apps/src/implementation/account-router.d.ts +12 -0
- package/types/apps/src/implementation/app.d.ts +5 -4
- package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
- package/types/apps/src/implementation/catalog-cache.d.ts +34 -4
- package/types/apps/src/implementation/elicitation.d.ts +9 -9
- package/types/apps/src/implementation/failure-detail.d.ts +46 -0
- package/types/apps/src/implementation/graphql-catalog.d.ts +4 -7
- package/types/apps/src/implementation/graphql.d.ts +4 -3
- package/types/apps/src/implementation/input-problems.d.ts +4 -1
- package/types/apps/src/implementation/mcp-call.d.ts +6 -5
- package/types/apps/src/implementation/mcp-catalog.d.ts +7 -8
- package/types/apps/src/implementation/mcp-client.d.ts +49 -25
- package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
- package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
- package/types/apps/src/implementation/mcp.d.ts +52 -25
- package/types/apps/src/implementation/network.d.ts +16 -0
- package/types/apps/src/implementation/openapi-compile.d.ts +27 -6
- package/types/apps/src/implementation/openapi-document.d.ts +46 -19
- package/types/apps/src/implementation/openapi-names.d.ts +9 -4
- package/types/apps/src/implementation/openapi-request.d.ts +10 -2
- package/types/apps/src/implementation/openapi-source.d.ts +8 -6
- package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
- package/types/apps/src/implementation/operations.d.ts +36 -3
- package/types/apps/src/implementation/protocol-operations.d.ts +6 -4
- package/types/apps/src/implementation/provider-error.d.ts +28 -1
- package/types/apps/src/implementation/provider.d.ts +19 -5
- package/types/apps/src/implementation/router-catalog.d.ts +224 -0
- package/types/apps/src/implementation/router.d.ts +68 -0
- package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
- package/types/apps/src/implementation/schema.d.ts +80 -1
- package/types/apps/src/implementation/skills.d.ts +2 -2
- package/types/apps/src/implementation/storage.d.ts +5 -3
- package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
- package/types/apps/src/implementation/ui-client.d.ts +2 -2
- package/types/apps/src/implementation/ui-document.d.ts +5 -0
- package/types/apps/src/implementation/ui-errors.d.ts +1 -1
- package/types/apps/src/implementation/ui-serving.d.ts +10 -4
- package/types/apps/src/implementation/ui-watch.d.ts +1 -1
- package/types/apps/src/implementation/upstream-error.d.ts +7 -0
- package/types/apps/src/implementation/webhooks.d.ts +1 -1
- package/types/apps/src/implementation/workflow-context.d.ts +11 -3
- package/types/apps/src/index.d.ts +29 -11
- package/types/apps/src/mcp-stdio.d.ts +2 -5
- package/types/apps/src/mcp.d.ts +25 -5
- package/types/apps/src/openapi.d.ts +6 -6
- package/types/apps/src/skills.d.ts +4 -4
- package/types/telemetry/src/browser-operations.d.ts +5 -2
- package/types/telemetry/src/config.d.ts +2 -2
- package/types/utils/src/api-error.d.ts +48 -0
- package/js/chunk-PYUYJRSK.js +0 -93
- package/js/chunk-SWPD52J7.js +0 -35
- package/js/chunk-W7D7WVSY.js +0 -18
- package/js/chunk-Z5NMEGJN.js +0 -29
- package/js/chunk-ZJWDMTE3.js +0 -63
- package/types/apps/src/contracts/dynamic-tools.d.ts +0 -13
- package/types/apps/src/implementation/account-operations.d.ts +0 -151
- package/types/apps/src/implementation/dynamic-tools.d.ts +0 -8
|
@@ -1,24 +1,44 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeCache
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AYM2FUI5.js";
|
|
4
|
+
import {
|
|
5
|
+
accountSecrets,
|
|
6
|
+
appInvocationFetch,
|
|
7
|
+
boundFailureMessage,
|
|
8
|
+
describeFailure,
|
|
9
|
+
failureDetail,
|
|
10
|
+
leavingProviderError,
|
|
11
|
+
parseMcpError,
|
|
12
|
+
readCatalog,
|
|
13
|
+
routerSkills
|
|
14
|
+
} from "./chunk-RULZPNGP.js";
|
|
4
15
|
import {
|
|
5
16
|
folderSkillsEffect
|
|
6
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-OX233L7N.js";
|
|
7
18
|
import {
|
|
19
|
+
ResponseStatusError,
|
|
8
20
|
authorDatabase,
|
|
9
21
|
isApp,
|
|
10
22
|
toEffectApp,
|
|
11
23
|
unavailableStorage
|
|
12
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-FULRJSWU.js";
|
|
25
|
+
import {
|
|
26
|
+
parseDatabaseSchema
|
|
27
|
+
} from "./chunk-5JVNM3CQ.js";
|
|
13
28
|
import {
|
|
29
|
+
declaredOperations,
|
|
14
30
|
fromPromise,
|
|
31
|
+
locate,
|
|
15
32
|
nativeOperation,
|
|
16
33
|
toPromise
|
|
17
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-5XJR4XGW.js";
|
|
18
35
|
import {
|
|
36
|
+
accountProviderError,
|
|
37
|
+
httpProviderError,
|
|
19
38
|
parseProviderError
|
|
20
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-4OKYLVU4.js";
|
|
21
40
|
import {
|
|
41
|
+
AccountCheckResult,
|
|
22
42
|
DeclaredProvider,
|
|
23
43
|
DeclaredRequirements,
|
|
24
44
|
ElicitationFailed,
|
|
@@ -29,6 +49,7 @@ import {
|
|
|
29
49
|
HostError,
|
|
30
50
|
HostEvaluationFailed,
|
|
31
51
|
HostInputInvalid,
|
|
52
|
+
HostKindMismatch,
|
|
32
53
|
HostOperationFailed,
|
|
33
54
|
HostOperationNotFound,
|
|
34
55
|
HostOutputInvalid,
|
|
@@ -38,6 +59,7 @@ import {
|
|
|
38
59
|
HostToolBlocked,
|
|
39
60
|
HostToolNotFound,
|
|
40
61
|
HostToolPolicyFailed,
|
|
62
|
+
HostedRouter,
|
|
41
63
|
HostedTool,
|
|
42
64
|
HostedToolSummary,
|
|
43
65
|
HostedWebhook,
|
|
@@ -45,9 +67,8 @@ import {
|
|
|
45
67
|
InvocationDeadline,
|
|
46
68
|
ManualWebhookSetup,
|
|
47
69
|
ManyAccounts,
|
|
48
|
-
McpError,
|
|
49
70
|
NonRetryableError,
|
|
50
|
-
|
|
71
|
+
OpenapiResponseError,
|
|
51
72
|
ResolvedAccounts,
|
|
52
73
|
ToolResultObservation,
|
|
53
74
|
TrustedToolApproval,
|
|
@@ -62,31 +83,33 @@ import {
|
|
|
62
83
|
defaultWebhookTransportLimits,
|
|
63
84
|
maxInputProblems,
|
|
64
85
|
workflowDurationMillis
|
|
65
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-N72RKJ5E.js";
|
|
66
87
|
import {
|
|
67
88
|
CacheError
|
|
68
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-5DLG2FVN.js";
|
|
69
90
|
import {
|
|
70
91
|
AppSkills,
|
|
71
92
|
SkillFile,
|
|
72
93
|
SkillLoadFailed
|
|
73
|
-
} from "./chunk-
|
|
74
|
-
import {
|
|
75
|
-
OpenapiResponseError
|
|
76
|
-
} from "./chunk-SWPD52J7.js";
|
|
94
|
+
} from "./chunk-HW3DPBZR.js";
|
|
77
95
|
import {
|
|
78
|
-
captureTelemetry
|
|
79
|
-
|
|
80
|
-
} from "./chunk-ZCAMUXSG.js";
|
|
96
|
+
captureTelemetry
|
|
97
|
+
} from "./chunk-ETLILMHY.js";
|
|
81
98
|
import {
|
|
99
|
+
allowedValues,
|
|
82
100
|
decoderOf,
|
|
101
|
+
echoableKey,
|
|
83
102
|
importedJsonSchema,
|
|
84
|
-
jsonSchemaDecoder
|
|
85
|
-
|
|
103
|
+
jsonSchemaDecoder,
|
|
104
|
+
jsonSchemaDocument,
|
|
105
|
+
maxAlternativeKeys,
|
|
106
|
+
objectShape,
|
|
107
|
+
unionShape
|
|
108
|
+
} from "./chunk-NPGRURDG.js";
|
|
86
109
|
import {
|
|
87
110
|
JsonObject,
|
|
88
111
|
JsonValue
|
|
89
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-FBBXFFFJ.js";
|
|
90
113
|
import {
|
|
91
114
|
Cause_exports,
|
|
92
115
|
Clock_exports,
|
|
@@ -95,10 +118,11 @@ import {
|
|
|
95
118
|
Match_exports,
|
|
96
119
|
Option_exports,
|
|
97
120
|
Redacted_exports,
|
|
121
|
+
SchemaAST_exports,
|
|
98
122
|
SchemaIssue_exports,
|
|
99
123
|
Schema_exports,
|
|
100
124
|
Stream_exports
|
|
101
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-EXGKN554.js";
|
|
102
126
|
|
|
103
127
|
// src/implementation/elicitation.ts
|
|
104
128
|
var prepareElicitation = (input) => Effect_exports.gen(function* () {
|
|
@@ -139,19 +163,29 @@ var makeElicit = (handler, signal) => toPromise(
|
|
|
139
163
|
var ApprovalDecision = Schema_exports.Literals(["approved", "denied", "user-approval"]);
|
|
140
164
|
|
|
141
165
|
// src/implementation/workflow-context.ts
|
|
142
|
-
var workflowSafe = (work) => work.pipe(
|
|
166
|
+
var workflowSafe = (work, secrets) => work.pipe(
|
|
143
167
|
Effect_exports.catchCause((cause) => {
|
|
144
168
|
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
145
169
|
const error = Cause_exports.squash(cause);
|
|
146
170
|
if (Schema_exports.is(WorkflowFailure)(error)) return Effect_exports.fail(error);
|
|
171
|
+
const { errorName, message } = failureDetail(error, secrets);
|
|
147
172
|
return Effect_exports.fail(
|
|
148
173
|
new WorkflowFailure({
|
|
149
174
|
reason: "execution",
|
|
150
|
-
retryable: !(error instanceof NonRetryableError)
|
|
175
|
+
retryable: !(error instanceof NonRetryableError),
|
|
176
|
+
...errorName === void 0 ? {} : { errorName },
|
|
177
|
+
...message === void 0 ? {} : { message }
|
|
151
178
|
})
|
|
152
179
|
);
|
|
153
180
|
})
|
|
154
181
|
);
|
|
182
|
+
var inStep = (step) => (failure) => failure.step === void 0 ? new WorkflowFailure({
|
|
183
|
+
reason: failure.reason,
|
|
184
|
+
retryable: failure.retryable,
|
|
185
|
+
step: step.slice(0, 200),
|
|
186
|
+
...failure.errorName === void 0 ? {} : { errorName: failure.errorName },
|
|
187
|
+
...failure.message.length === 0 ? {} : { message: failure.message }
|
|
188
|
+
}) : failure;
|
|
155
189
|
var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_exports.gen(function* () {
|
|
156
190
|
const services = yield* Effect_exports.context();
|
|
157
191
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -206,25 +240,33 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
|
|
|
206
240
|
Effect_exports.sync(() => new AbortController()),
|
|
207
241
|
(controller2) => Effect_exports.sync(() => controller2.abort())
|
|
208
242
|
);
|
|
209
|
-
const
|
|
243
|
+
const step2 = yield* fresh(stepId, AbortSignal.any([signal, controller.signal]));
|
|
210
244
|
const result = yield* workflowSafe(
|
|
211
|
-
Effect_exports.tryPromise({
|
|
245
|
+
Effect_exports.tryPromise({
|
|
246
|
+
try: () => callback(step2.context),
|
|
247
|
+
catch: (error) => error
|
|
248
|
+
}),
|
|
249
|
+
step2.secrets
|
|
212
250
|
);
|
|
213
251
|
return yield* Schema_exports.decodeUnknownEffect(WorkflowValue)(result).pipe(
|
|
214
252
|
Effect_exports.mapError(
|
|
215
|
-
() => new WorkflowFailure({
|
|
253
|
+
() => new WorkflowFailure({
|
|
254
|
+
reason: "output",
|
|
255
|
+
retryable: false,
|
|
256
|
+
message: "The step returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
|
|
257
|
+
})
|
|
216
258
|
)
|
|
217
259
|
);
|
|
218
260
|
})
|
|
219
261
|
).pipe(Effect_exports.provideContext(services))
|
|
220
262
|
)
|
|
221
|
-
);
|
|
263
|
+
).pipe(Effect_exports.mapError(inStep(name)));
|
|
222
264
|
});
|
|
223
265
|
const operationStep = (kind, name, operation, input, options) => Effect_exports.gen(function* () {
|
|
224
266
|
const target = nativeOperation(operation);
|
|
225
|
-
const
|
|
226
|
-
const match =
|
|
227
|
-
(
|
|
267
|
+
const root = definition.tools?.kind === "router" ? definition.tools : void 0;
|
|
268
|
+
const match = declaredOperations(root).find(
|
|
269
|
+
(entry) => entry.operation === target && entry.operation.kind === kind
|
|
228
270
|
);
|
|
229
271
|
if (target === void 0 || match === void 0)
|
|
230
272
|
return yield* new WorkflowFailure({ reason: "operation", retryable: false });
|
|
@@ -243,9 +285,9 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
|
|
|
243
285
|
parsed,
|
|
244
286
|
() => attempt(
|
|
245
287
|
parsed,
|
|
246
|
-
execution.invoke({ kind, name: match
|
|
288
|
+
execution.invoke({ kind, name: match.name, input: args, stepId, timeout }).pipe(Effect_exports.provideContext(services))
|
|
247
289
|
)
|
|
248
|
-
);
|
|
290
|
+
).pipe(Effect_exports.mapError(inStep(name)));
|
|
249
291
|
});
|
|
250
292
|
const invoke = (effect) => toPromise(() => effect.pipe(Effect_exports.provideContext(services)), signal)();
|
|
251
293
|
const step = {
|
|
@@ -284,14 +326,91 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
|
|
|
284
326
|
});
|
|
285
327
|
|
|
286
328
|
// src/implementation/input-problems.ts
|
|
287
|
-
var
|
|
329
|
+
var nativeObjectShape = (ast, limit) => objectShape(
|
|
330
|
+
ast.propertySignatures.flatMap(
|
|
331
|
+
({ name, type }) => typeof name === "string" ? [{ name, optional: SchemaAST_exports.isOptional(SchemaAST_exports.toEncoded(type)) }] : []
|
|
332
|
+
),
|
|
333
|
+
ast.indexSignatures.length > 0,
|
|
334
|
+
limit
|
|
335
|
+
);
|
|
336
|
+
var unionMembers = (ast) => SchemaAST_exports.isUnion(ast) ? ast.types.flatMap(unionMembers) : SchemaAST_exports.isUndefined(ast) || SchemaAST_exports.isVoid(ast) ? [] : [ast];
|
|
337
|
+
var fixedValues = (ast) => {
|
|
338
|
+
if (SchemaAST_exports.isLiteral(ast)) return [ast.literal];
|
|
339
|
+
if (SchemaAST_exports.isEnum(ast)) return ast.enums.map(([, value]) => value);
|
|
340
|
+
if (!SchemaAST_exports.isUnion(ast)) return void 0;
|
|
341
|
+
const members = unionMembers(ast).map(fixedValues);
|
|
342
|
+
return members.length > 0 && members.every((values) => values !== void 0) ? members.flat() : void 0;
|
|
343
|
+
};
|
|
344
|
+
var describeMember = (ast) => Match_exports.value(ast).pipe(
|
|
345
|
+
Match_exports.when(
|
|
346
|
+
SchemaAST_exports.isObjects,
|
|
347
|
+
(objects) => objects.propertySignatures.length > 0 ? nativeObjectShape(objects, maxAlternativeKeys) : "object"
|
|
348
|
+
),
|
|
349
|
+
Match_exports.when(SchemaAST_exports.isArrays, () => "array"),
|
|
350
|
+
Match_exports.when(SchemaAST_exports.isTemplateLiteral, () => "a string matching a template"),
|
|
351
|
+
Match_exports.when(SchemaAST_exports.isString, () => "string"),
|
|
352
|
+
Match_exports.when(SchemaAST_exports.isNumber, () => "number"),
|
|
353
|
+
Match_exports.when(SchemaAST_exports.isBoolean, () => "boolean"),
|
|
354
|
+
Match_exports.when(SchemaAST_exports.isNull, () => "null"),
|
|
355
|
+
Match_exports.orElse(() => "a value with other constraints")
|
|
356
|
+
);
|
|
357
|
+
var memberSelector = (members) => {
|
|
358
|
+
const [first] = members;
|
|
359
|
+
if (members.length < 2 || first === void 0 || !SchemaAST_exports.isObjects(first)) return void 0;
|
|
360
|
+
return first.propertySignatures.map(({ name }) => name).find(
|
|
361
|
+
(name) => typeof name === "string" && members.every(
|
|
362
|
+
(member) => SchemaAST_exports.isObjects(member) && member.propertySignatures.some(
|
|
363
|
+
(property) => property.name === name && fixedValues(SchemaAST_exports.toEncoded(property.type)) !== void 0
|
|
364
|
+
)
|
|
365
|
+
)
|
|
366
|
+
);
|
|
367
|
+
};
|
|
368
|
+
var expectedUnion = (ast) => {
|
|
369
|
+
const members = unionMembers(ast);
|
|
370
|
+
const fixed = members.map(fixedValues);
|
|
371
|
+
const values = fixed.flatMap((memberValues) => memberValues === void 0 ? [] : memberValues);
|
|
372
|
+
const others = members.filter((_, index) => fixed[index] === void 0);
|
|
373
|
+
if (others.length === 0) return `Expected ${allowedValues(values)}`;
|
|
374
|
+
return `Expected ${unionShape(
|
|
375
|
+
[
|
|
376
|
+
...values.length === 0 ? [] : [allowedValues(values)],
|
|
377
|
+
...new Set(others.map(describeMember))
|
|
378
|
+
],
|
|
379
|
+
memberSelector(members)
|
|
380
|
+
)}`;
|
|
381
|
+
};
|
|
382
|
+
var leafHook = (issue) => SchemaIssue_exports.hasInput(issue) ? "Invalid value" : Match_exports.value(issue).pipe(
|
|
383
|
+
Match_exports.tag("InvalidType", ({ ast }) => {
|
|
384
|
+
const values = fixedValues(ast);
|
|
385
|
+
return values !== void 0 ? `Expected ${allowedValues(values)}` : SchemaAST_exports.isObjects(ast) && ast.propertySignatures.length > 0 ? `Expected ${nativeObjectShape(ast)}` : SchemaIssue_exports.defaultLeafHook(issue);
|
|
386
|
+
}),
|
|
387
|
+
Match_exports.orElse(SchemaIssue_exports.defaultLeafHook)
|
|
388
|
+
);
|
|
288
389
|
var checkHook = (issue) => SchemaIssue_exports.hasInput(issue) || SchemaIssue_exports.hasInput(issue.issue) ? SchemaIssue_exports.defaultCheckHook(issue) ?? "Invalid value" : SchemaIssue_exports.defaultCheckHook(issue);
|
|
289
390
|
var format = SchemaIssue_exports.makeFormatterStandardSchemaV1({ leafHook, checkHook });
|
|
290
|
-
var
|
|
391
|
+
var located = (issue, path) => Match_exports.value(issue).pipe(
|
|
392
|
+
Match_exports.tag("Pointer", (pointer) => located(pointer.issue, [...path, ...pointer.path])),
|
|
393
|
+
Match_exports.tag("Composite", ({ issues }) => issues.flatMap((issue2) => located(issue2, path))),
|
|
394
|
+
Match_exports.tag("Encoding", (encoding) => located(encoding.issue, path)),
|
|
395
|
+
Match_exports.tag(
|
|
396
|
+
"AnyOf",
|
|
397
|
+
({ ast, issues }) => issues.length === 0 ? [{ path, message: expectedUnion(ast) }] : issues.flatMap((issue2) => located(issue2, path))
|
|
398
|
+
),
|
|
399
|
+
Match_exports.orElse(
|
|
400
|
+
(issue2) => format(issue2).issues.map((problem) => ({
|
|
401
|
+
path: [
|
|
402
|
+
...path,
|
|
403
|
+
...(problem.path ?? []).map((key) => typeof key === "object" ? key.key : key)
|
|
404
|
+
],
|
|
405
|
+
message: problem.message
|
|
406
|
+
}))
|
|
407
|
+
)
|
|
408
|
+
);
|
|
409
|
+
var segment = (key) => typeof key === "number" ? `[${key}]` : typeof key === "string" && echoableKey(key) ? `.${key}` : "[key]";
|
|
291
410
|
var inputInvalid = (error) => {
|
|
292
411
|
if (!Schema_exports.isSchemaError(error)) return new HostInputInvalid();
|
|
293
|
-
const problems =
|
|
294
|
-
const location =
|
|
412
|
+
const problems = located(error.issue, []).slice(0, maxInputProblems).map(({ path, message }) => {
|
|
413
|
+
const location = path.map(segment);
|
|
295
414
|
return `${location.length === 0 ? "input" : `input${location.join("")}`}: ${message}`.slice(
|
|
296
415
|
0,
|
|
297
416
|
512
|
|
@@ -469,7 +588,7 @@ var authorCache = (host, accounts, signal, deadline) => {
|
|
|
469
588
|
...options.staleFor === void 0 ? {} : { staleFor: options.staleFor },
|
|
470
589
|
load: Effect_exports.acquireUseRelease(
|
|
471
590
|
Effect_exports.sync(() => new AbortController()),
|
|
472
|
-
(controller) =>
|
|
591
|
+
(controller) => appInvocationFetch(controller.signal).pipe(
|
|
473
592
|
Effect_exports.flatMap(
|
|
474
593
|
(fetch) => fromPromise(options.load)({
|
|
475
594
|
fetch,
|
|
@@ -523,6 +642,10 @@ var authorCache = (host, accounts, signal, deadline) => {
|
|
|
523
642
|
};
|
|
524
643
|
|
|
525
644
|
// src/implementation/host.ts
|
|
645
|
+
var WireCatalog = Schema_exports.Struct({
|
|
646
|
+
tools: Schema_exports.Array(Schema_exports.Union([HostedTool, HostedToolSummary])),
|
|
647
|
+
routers: Schema_exports.Array(HostedRouter)
|
|
648
|
+
});
|
|
526
649
|
function safe2(work, failure) {
|
|
527
650
|
return Effect_exports.suspend(work).pipe(
|
|
528
651
|
Effect_exports.catchCause(
|
|
@@ -530,30 +653,39 @@ function safe2(work, failure) {
|
|
|
530
653
|
)
|
|
531
654
|
);
|
|
532
655
|
}
|
|
533
|
-
var evaluationSafe = (work) => work.pipe(
|
|
656
|
+
var evaluationSafe = (work, secrets) => work.pipe(
|
|
534
657
|
Effect_exports.catchCause((cause) => {
|
|
535
658
|
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
536
659
|
const error = Cause_exports.squash(cause);
|
|
537
660
|
const provider = parseProviderError(error);
|
|
538
661
|
const skills = parseSkillLoadFailed(error);
|
|
539
|
-
const mcp = parseMcpError(error);
|
|
662
|
+
const mcp = parseMcpError(error, secrets);
|
|
540
663
|
return Effect_exports.fail(
|
|
541
|
-
Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(skills) ? skills.value : Option_exports.isSome(mcp) ? mcp.value : new HostEvaluationFailed()
|
|
664
|
+
Option_exports.isSome(provider) ? leavingProviderError(provider.value, secrets, "discover") : Option_exports.isSome(skills) ? skills.value : Option_exports.isSome(mcp) ? mcp.value : new HostEvaluationFailed(failureDetail(error, secrets))
|
|
542
665
|
);
|
|
543
666
|
})
|
|
544
667
|
);
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
668
|
+
var declarationInvalid = (summary, cause, secrets = []) => new HostDeclarationInvalid({
|
|
669
|
+
source: "app",
|
|
670
|
+
errorName: "HostDeclarationInvalid",
|
|
671
|
+
message: boundFailureMessage(
|
|
672
|
+
cause === void 0 ? summary : `${summary}: ${describeFailure(cause)}`,
|
|
673
|
+
secrets
|
|
674
|
+
)
|
|
675
|
+
});
|
|
676
|
+
var declarationSafe = (work, summary) => Effect_exports.suspend(work).pipe(
|
|
677
|
+
Effect_exports.catchCause(
|
|
678
|
+
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(declarationInvalid(summary, Cause_exports.squash(cause)))
|
|
679
|
+
)
|
|
680
|
+
);
|
|
681
|
+
function declaredExposure(exposure) {
|
|
682
|
+
const named = (kind) => Object.entries(exposure ?? {}).filter(([, value]) => value === kind).map(([field]) => field).sort();
|
|
683
|
+
const plain = named("plain");
|
|
684
|
+
const raw = named("raw");
|
|
685
|
+
return { ...plain.length === 0 ? {} : { plain }, ...raw.length === 0 ? {} : { raw } };
|
|
554
686
|
}
|
|
555
687
|
function providerDeclaration(provider) {
|
|
556
|
-
return
|
|
688
|
+
return declarationSafe(
|
|
557
689
|
() => Effect_exports.gen(function* () {
|
|
558
690
|
const auth = /* @__PURE__ */ new Map();
|
|
559
691
|
for (const [name, method] of Object.entries(provider.auth)) {
|
|
@@ -562,42 +694,50 @@ function providerDeclaration(provider) {
|
|
|
562
694
|
auth.set(name, {
|
|
563
695
|
type: "secrets",
|
|
564
696
|
label: method.label,
|
|
565
|
-
fields: yield*
|
|
697
|
+
fields: yield* jsonSchemaDocument(method.fields),
|
|
698
|
+
...declaredExposure(method.exposure)
|
|
566
699
|
});
|
|
567
700
|
break;
|
|
568
701
|
case "oauth2":
|
|
569
702
|
auth.set(name, {
|
|
570
703
|
type: "oauth2",
|
|
571
704
|
...method.config,
|
|
572
|
-
response: yield*
|
|
705
|
+
response: yield* jsonSchemaDocument(method.response),
|
|
706
|
+
...declaredExposure(method.exposure)
|
|
573
707
|
});
|
|
574
708
|
break;
|
|
575
709
|
}
|
|
576
710
|
}
|
|
577
711
|
return yield* Schema_exports.decodeUnknownEffect(DeclaredProvider)({
|
|
578
712
|
name: provider.name,
|
|
579
|
-
auth: Object.fromEntries(auth)
|
|
713
|
+
auth: Object.fromEntries(auth),
|
|
714
|
+
// Order and repetition carry no meaning, so neither changes the provider's identity.
|
|
715
|
+
...provider.hosts === void 0 ? {} : { hosts: [...new Set(provider.hosts)].sort() }
|
|
580
716
|
});
|
|
581
717
|
}),
|
|
582
|
-
|
|
718
|
+
`Account provider "${provider.name}" has an invalid declaration`
|
|
583
719
|
);
|
|
584
720
|
}
|
|
585
721
|
function requirements(slots, database) {
|
|
586
722
|
return Effect_exports.gen(function* () {
|
|
587
723
|
const accounts = /* @__PURE__ */ new Map();
|
|
588
724
|
for (const [slot, selection] of Object.entries(slots)) {
|
|
725
|
+
const provider = selection instanceof ManyAccounts ? selection.provider : selection;
|
|
589
726
|
accounts.set(slot, {
|
|
590
727
|
cardinality: selection instanceof ManyAccounts ? "many" : "one",
|
|
591
|
-
definition: yield* providerDeclaration(
|
|
592
|
-
|
|
593
|
-
)
|
|
728
|
+
definition: yield* providerDeclaration(provider),
|
|
729
|
+
...provider.health === void 0 ? {} : { health: true }
|
|
594
730
|
});
|
|
595
731
|
}
|
|
596
732
|
return yield* Schema_exports.decodeUnknownEffect(DeclaredRequirements)({
|
|
597
733
|
accounts: Object.fromEntries(accounts),
|
|
598
734
|
capabilities: { skills: true, toolIndex: true, skillSources: true, scheduledTools: true },
|
|
599
735
|
...database === void 0 ? {} : { database }
|
|
600
|
-
}).pipe(
|
|
736
|
+
}).pipe(
|
|
737
|
+
Effect_exports.mapError(
|
|
738
|
+
(cause) => declarationInvalid("The app's account or database declarations are invalid", cause)
|
|
739
|
+
)
|
|
740
|
+
);
|
|
601
741
|
});
|
|
602
742
|
}
|
|
603
743
|
function canonical(value) {
|
|
@@ -607,6 +747,9 @@ function canonical(value) {
|
|
|
607
747
|
}
|
|
608
748
|
return JSON.stringify(value);
|
|
609
749
|
}
|
|
750
|
+
function withoutHosts({ hosts: _hosts, ...provider }) {
|
|
751
|
+
return provider;
|
|
752
|
+
}
|
|
610
753
|
function bindAccounts(slots, declarations, context) {
|
|
611
754
|
return safe2(
|
|
612
755
|
() => Effect_exports.gen(function* () {
|
|
@@ -632,7 +775,7 @@ function bindAccounts(slots, declarations, context) {
|
|
|
632
775
|
for (const account of accounts) {
|
|
633
776
|
if (ids.has(account.id)) return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
634
777
|
ids.add(account.id);
|
|
635
|
-
if (canonical(account.provider) !== canonical(requirement.definition) || !Object.hasOwn(provider.auth, account.method))
|
|
778
|
+
if (canonical(withoutHosts(account.provider)) !== canonical(withoutHosts(requirement.definition)) || !Object.hasOwn(provider.auth, account.method))
|
|
636
779
|
return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
637
780
|
const method = provider.auth[account.method];
|
|
638
781
|
if (method === void 0) return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
@@ -653,17 +796,67 @@ function bindAccounts(slots, declarations, context) {
|
|
|
653
796
|
new HostAccountsInvalid()
|
|
654
797
|
);
|
|
655
798
|
}
|
|
799
|
+
var fetchLifetime = (signal, background) => Effect_exports.acquireRelease(
|
|
800
|
+
Effect_exports.sync(() => {
|
|
801
|
+
const controller = new AbortController();
|
|
802
|
+
let refreshes = 0;
|
|
803
|
+
let ended = false;
|
|
804
|
+
const settle = () => {
|
|
805
|
+
if (ended && refreshes === 0) controller.abort();
|
|
806
|
+
};
|
|
807
|
+
const end = () => {
|
|
808
|
+
ended = true;
|
|
809
|
+
settle();
|
|
810
|
+
};
|
|
811
|
+
signal.addEventListener("abort", end, { once: true });
|
|
812
|
+
if (signal.aborted) end();
|
|
813
|
+
const settled = Effect_exports.sync(() => {
|
|
814
|
+
refreshes -= 1;
|
|
815
|
+
settle();
|
|
816
|
+
});
|
|
817
|
+
return {
|
|
818
|
+
signal: controller.signal,
|
|
819
|
+
close: () => {
|
|
820
|
+
signal.removeEventListener("abort", end);
|
|
821
|
+
end();
|
|
822
|
+
},
|
|
823
|
+
/** Counted from the hand-off, so a refresh that has not started yet keeps the fetch. */
|
|
824
|
+
background: (task) => Effect_exports.suspend(() => {
|
|
825
|
+
refreshes += 1;
|
|
826
|
+
return background(task.pipe(Effect_exports.ensuring(settled))).pipe(
|
|
827
|
+
Effect_exports.onError(() => settled)
|
|
828
|
+
);
|
|
829
|
+
})
|
|
830
|
+
};
|
|
831
|
+
}),
|
|
832
|
+
(lifetime) => Effect_exports.sync(lifetime.close)
|
|
833
|
+
);
|
|
656
834
|
function dispatch(app, request, context, signal) {
|
|
657
835
|
return Effect_exports.scoped(
|
|
658
836
|
Effect_exports.gen(function* () {
|
|
659
|
-
if (!isApp(app))
|
|
837
|
+
if (!isApp(app))
|
|
838
|
+
return yield* Effect_exports.fail(
|
|
839
|
+
declarationInvalid("The app module's default export is not an app created by defineApp")
|
|
840
|
+
);
|
|
660
841
|
const native = toEffectApp(app);
|
|
842
|
+
const secrets = accountSecrets(context.accounts);
|
|
843
|
+
const storageFailure = (error) => Effect_exports.fail(new HostOperationFailed(failureDetail(error, secrets)));
|
|
661
844
|
const declared = yield* requirements(native.accounts, native.database?.schema);
|
|
662
|
-
if (request.operation === "requirements")
|
|
845
|
+
if (request.operation === "requirements") {
|
|
846
|
+
if (native.database !== void 0)
|
|
847
|
+
yield* parseDatabaseSchema(native.database.schema).pipe(
|
|
848
|
+
Effect_exports.catchTag(
|
|
849
|
+
"AppDatabaseError",
|
|
850
|
+
(cause) => Effect_exports.fail(
|
|
851
|
+
declarationInvalid("The app's account or database declarations are invalid", cause)
|
|
852
|
+
)
|
|
853
|
+
)
|
|
854
|
+
);
|
|
663
855
|
return yield* safe2(
|
|
664
856
|
() => Schema_exports.decodeUnknownEffect(JsonValue)(declared),
|
|
665
857
|
new HostDeclarationInvalid()
|
|
666
858
|
);
|
|
859
|
+
}
|
|
667
860
|
const lifetime = yield* Effect_exports.acquireRelease(
|
|
668
861
|
Effect_exports.sync(() => new AbortController()),
|
|
669
862
|
(controller) => Effect_exports.sync(() => controller.abort())
|
|
@@ -689,6 +882,15 @@ function dispatch(app, request, context, signal) {
|
|
|
689
882
|
return yield* new WorkflowFailure({ reason: "engine", retryable: true });
|
|
690
883
|
return result;
|
|
691
884
|
});
|
|
885
|
+
if (request.operation === "account-check")
|
|
886
|
+
return yield* checkAccount(
|
|
887
|
+
native.accounts,
|
|
888
|
+
declared,
|
|
889
|
+
request.requirement,
|
|
890
|
+
context,
|
|
891
|
+
invocationSignal,
|
|
892
|
+
deadline
|
|
893
|
+
).pipe(withinDeadline);
|
|
692
894
|
let running;
|
|
693
895
|
let transactionOpen = false;
|
|
694
896
|
const delivery = (request2, signal2) => Effect_exports.suspend(
|
|
@@ -723,9 +925,19 @@ function dispatch(app, request, context, signal) {
|
|
|
723
925
|
const files = yield* Schema_exports.decodeUnknownEffect(Schema_exports.Array(SkillFile))(
|
|
724
926
|
context.files ?? []
|
|
725
927
|
).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
|
|
928
|
+
let cacheCommands = 0;
|
|
929
|
+
const hostCache = context.cache ?? unavailableCache;
|
|
930
|
+
const fetching = yield* fetchLifetime(signal, hostCache.background);
|
|
726
931
|
const bound = {
|
|
727
932
|
cache: authorCache(
|
|
728
|
-
|
|
933
|
+
{
|
|
934
|
+
...hostCache,
|
|
935
|
+
transport: (command) => {
|
|
936
|
+
cacheCommands += 1;
|
|
937
|
+
return hostCache.transport(command);
|
|
938
|
+
},
|
|
939
|
+
background: fetching.background
|
|
940
|
+
},
|
|
729
941
|
Redacted_exports.value(context.accounts),
|
|
730
942
|
invocationSignal,
|
|
731
943
|
deadline
|
|
@@ -736,35 +948,43 @@ function dispatch(app, request, context, signal) {
|
|
|
736
948
|
),
|
|
737
949
|
workflows: workflowReads,
|
|
738
950
|
signal: invocationSignal,
|
|
739
|
-
fetch: yield*
|
|
951
|
+
fetch: yield* appInvocationFetch(fetching.signal),
|
|
740
952
|
elicit: makeElicit(delivery, invocationSignal)
|
|
741
953
|
};
|
|
742
|
-
const definition = yield* evaluationSafe(native.evaluate(bound)).pipe(
|
|
954
|
+
const definition = yield* evaluationSafe(native.evaluate(bound), secrets).pipe(
|
|
743
955
|
Effect_exports.withSpan("app.evaluate")
|
|
744
956
|
);
|
|
745
957
|
if (request.operation === "skills") {
|
|
746
958
|
const declared2 = definition.skills ?? (yield* folderSkillsEffect({ files }).pipe(
|
|
747
959
|
Effect_exports.mapError(() => new HostDeclarationInvalid())
|
|
748
960
|
));
|
|
749
|
-
const
|
|
750
|
-
const
|
|
961
|
+
const source = definition.dynamicSkills;
|
|
962
|
+
const before = cacheCommands;
|
|
963
|
+
const dynamic = source === void 0 ? [] : yield* evaluationSafe(Effect_exports.suspend(source.list), secrets).pipe(
|
|
751
964
|
Effect_exports.withSpan("app.skills.load")
|
|
752
965
|
);
|
|
753
|
-
const
|
|
754
|
-
|
|
755
|
-
)
|
|
756
|
-
|
|
966
|
+
const cached = source !== void 0 && cacheCommands > before;
|
|
967
|
+
const authored = new Set([...declared2, ...dynamic].map((skill) => skill.name));
|
|
968
|
+
const routed = (yield* routerSkills(definition.tools).pipe(
|
|
969
|
+
Effect_exports.withSpan("app.skills.routers")
|
|
970
|
+
)).filter((skill) => !authored.has(skill.name));
|
|
971
|
+
const skills = yield* Schema_exports.decodeUnknownEffect(AppSkills)([
|
|
972
|
+
...declared2,
|
|
973
|
+
...dynamic,
|
|
974
|
+
...routed
|
|
975
|
+
]).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
|
|
976
|
+
return request.sources === true ? { skills, dynamic: source !== void 0, cached } : skills;
|
|
757
977
|
}
|
|
758
978
|
if (request.operation === "workflows") {
|
|
759
979
|
return yield* Effect_exports.forEach(
|
|
760
980
|
Object.entries(definition.workflows ?? {}),
|
|
761
|
-
([
|
|
981
|
+
([name, entry]) => safe2(
|
|
762
982
|
() => Effect_exports.gen(function* () {
|
|
763
983
|
return yield* Schema_exports.decodeUnknownEffect(HostedWorkflow)({
|
|
764
|
-
name
|
|
984
|
+
name,
|
|
765
985
|
...entry.description === void 0 ? {} : { description: entry.description },
|
|
766
|
-
inputSchema: yield*
|
|
767
|
-
...entry.output === void 0 ? {} : { outputSchema: yield*
|
|
986
|
+
inputSchema: yield* jsonSchemaDocument(entry.input),
|
|
987
|
+
...entry.output === void 0 ? {} : { outputSchema: yield* jsonSchemaDocument(entry.output) }
|
|
768
988
|
});
|
|
769
989
|
}),
|
|
770
990
|
new HostDeclarationInvalid()
|
|
@@ -797,108 +1017,60 @@ function dispatch(app, request, context, signal) {
|
|
|
797
1017
|
new WorkflowFailure({ reason: "credentials", retryable: false })
|
|
798
1018
|
);
|
|
799
1019
|
return {
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
1020
|
+
context: {
|
|
1021
|
+
...accounts,
|
|
1022
|
+
cache: authorCache(
|
|
1023
|
+
context.cache ?? unavailableCache,
|
|
1024
|
+
Redacted_exports.value(current.accounts),
|
|
1025
|
+
signal2
|
|
1026
|
+
),
|
|
1027
|
+
files,
|
|
1028
|
+
fetch: yield* appInvocationFetch(signal2),
|
|
1029
|
+
signal: signal2,
|
|
1030
|
+
runId: execution.runId,
|
|
1031
|
+
stepId,
|
|
1032
|
+
idempotencyKey: stepId
|
|
1033
|
+
},
|
|
1034
|
+
// The resolved values, not the app's decoded fields, which may be `Redacted`.
|
|
1035
|
+
secrets: accountSecrets(current.accounts)
|
|
812
1036
|
};
|
|
813
1037
|
}),
|
|
814
1038
|
invocationSignal
|
|
815
1039
|
);
|
|
816
|
-
const output = yield* workflowSafe(entry.run(workflowContext, input2));
|
|
1040
|
+
const output = yield* workflowSafe(entry.run(workflowContext, input2), secrets);
|
|
817
1041
|
const outputSchema = entry.output;
|
|
818
1042
|
const decoded = outputSchema === void 0 ? output : yield* safe2(
|
|
819
1043
|
() => Schema_exports.decodeUnknownEffect(outputSchema)(output),
|
|
820
|
-
new WorkflowFailure({
|
|
1044
|
+
new WorkflowFailure({
|
|
1045
|
+
reason: "output",
|
|
1046
|
+
retryable: false,
|
|
1047
|
+
message: "The workflow's result does not match its declared output schema."
|
|
1048
|
+
})
|
|
821
1049
|
);
|
|
822
1050
|
return yield* safe2(
|
|
823
1051
|
() => Schema_exports.decodeUnknownEffect(WorkflowValue)(decoded),
|
|
824
|
-
new WorkflowFailure({
|
|
1052
|
+
new WorkflowFailure({
|
|
1053
|
+
reason: "output",
|
|
1054
|
+
retryable: false,
|
|
1055
|
+
message: "The workflow returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
|
|
1056
|
+
})
|
|
825
1057
|
);
|
|
826
1058
|
}
|
|
827
1059
|
if (request.operation === "inspect") {
|
|
828
1060
|
const summary = request.detail === "summary";
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
const fields = {
|
|
843
|
-
name: `${prefix}${name2}`,
|
|
844
|
-
schedules,
|
|
845
|
-
description: operation.description ?? `${readOnly ? "Query" : "Mutate"} ${name2}`,
|
|
846
|
-
...operation.title === void 0 ? {} : { title: operation.title },
|
|
847
|
-
readOnly,
|
|
848
|
-
annotations: { ...operation.annotations, readOnlyHint: readOnly }
|
|
849
|
-
};
|
|
850
|
-
if (summary)
|
|
851
|
-
return yield* Schema_exports.decodeUnknownEffect(HostedToolSummary)(fields);
|
|
852
|
-
return yield* Schema_exports.decodeUnknownEffect(HostedTool)({
|
|
853
|
-
...fields,
|
|
854
|
-
inputSchema: yield* jsonSchema(operation.input),
|
|
855
|
-
...operation.output === void 0 ? operation.outputSchema === void 0 ? {} : { outputSchema: operation.outputSchema } : { outputSchema: yield* jsonSchema(operation.output) },
|
|
856
|
-
...operation._meta === void 0 ? {} : { _meta: operation._meta }
|
|
857
|
-
});
|
|
858
|
-
}),
|
|
859
|
-
new HostDeclarationInvalid()
|
|
860
|
-
)
|
|
861
|
-
);
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
const dynamic = request.scheduled === true ? void 0 : definition.dynamicTools;
|
|
865
|
-
if (dynamic !== void 0 && (wanted === void 0 || metadata.length < wanted.size)) {
|
|
866
|
-
const declared2 = new Set(metadata.map((tool2) => tool2.name));
|
|
867
|
-
const discover = () => {
|
|
868
|
-
if (summary && dynamic.summaries !== void 0) return dynamic.summaries();
|
|
869
|
-
if (wanted !== void 0 && dynamic.describe !== void 0) {
|
|
870
|
-
const describe = dynamic.describe;
|
|
871
|
-
return Effect_exports.forEach(
|
|
872
|
-
[...wanted].filter((name2) => !declared2.has(name2)),
|
|
873
|
-
(name2) => describe(name2),
|
|
874
|
-
{ concurrency: "unbounded" }
|
|
875
|
-
).pipe(Effect_exports.map((tools) => tools.filter((tool2) => tool2 !== void 0)));
|
|
876
|
-
}
|
|
877
|
-
return dynamic.list();
|
|
878
|
-
};
|
|
879
|
-
const discovered = yield* evaluationSafe(discover()).pipe(
|
|
880
|
-
Effect_exports.flatMap(
|
|
881
|
-
(value) => safe2(
|
|
882
|
-
() => summary ? Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedToolSummary))(value) : Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedTool))(value),
|
|
883
|
-
new HostDeclarationInvalid()
|
|
884
|
-
)
|
|
885
|
-
)
|
|
886
|
-
);
|
|
887
|
-
const names = new Set(declared2);
|
|
888
|
-
for (const tool2 of discovered) {
|
|
889
|
-
const readOnly = tool2.name.startsWith(OperationToolPrefixes.query);
|
|
890
|
-
if (!readOnly && !tool2.name.startsWith(OperationToolPrefixes.mutate) || tool2.name === OperationToolPrefixes.query || tool2.name === OperationToolPrefixes.mutate || names.has(tool2.name))
|
|
891
|
-
return yield* new HostDeclarationInvalid();
|
|
892
|
-
names.add(tool2.name);
|
|
893
|
-
if (wanted !== void 0 && !wanted.has(tool2.name)) continue;
|
|
894
|
-
metadata.push({
|
|
895
|
-
...tool2,
|
|
896
|
-
readOnly,
|
|
897
|
-
annotations: { ...tool2.annotations, readOnlyHint: readOnly }
|
|
898
|
-
});
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
return metadata;
|
|
1061
|
+
const catalog = yield* readCatalog(definition.tools, {
|
|
1062
|
+
summary,
|
|
1063
|
+
secrets,
|
|
1064
|
+
...request.tools === void 0 ? {} : { wanted: new Set(request.tools) },
|
|
1065
|
+
...request.scheduled === true ? { scheduled: true } : {},
|
|
1066
|
+
schedules: (name) => Object.entries(definition.schedules ?? {}).filter(([, schedule]) => schedule.tool === name).map(([name2, { tool: _tool, ...schedule }]) => ({ name: name2, ...schedule }))
|
|
1067
|
+
}).pipe(Effect_exports.withSpan("app.catalog.read"));
|
|
1068
|
+
return yield* safe2(
|
|
1069
|
+
() => Schema_exports.encodeEffect(WireCatalog)(catalog).pipe(
|
|
1070
|
+
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
|
|
1071
|
+
),
|
|
1072
|
+
new HostDeclarationInvalid()
|
|
1073
|
+
);
|
|
902
1074
|
}
|
|
903
1075
|
if (request.operation === "webhook-complete" || request.operation === "webhook-validate" || request.operation === "webhooks" || request.operation === "webhook-register" || request.operation === "webhook-handle" || request.operation === "webhook-unregister") {
|
|
904
1076
|
const executeWebhook = (db) => dispatchWebhook(
|
|
@@ -922,25 +1094,22 @@ function dispatch(app, request, context, signal) {
|
|
|
922
1094
|
const storage2 = context.storage ?? unavailableStorage;
|
|
923
1095
|
return yield* storage2.mutate(native.database.schema, executeWebhook).pipe(
|
|
924
1096
|
Effect_exports.catchTags({
|
|
925
|
-
AppDatabaseError:
|
|
926
|
-
|
|
927
|
-
|
|
1097
|
+
AppDatabaseError: storageFailure,
|
|
1098
|
+
DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
|
|
1099
|
+
AppStorageUnavailable: storageFailure,
|
|
1100
|
+
AppStorageError: storageFailure
|
|
928
1101
|
})
|
|
929
1102
|
);
|
|
930
1103
|
}
|
|
931
|
-
const
|
|
932
|
-
|
|
933
|
-
const
|
|
934
|
-
const toolName = `${OperationToolPrefixes[kind]}${name}`;
|
|
935
|
-
const catalog = kind === "query" ? definition.queries : definition.mutations;
|
|
936
|
-
const declaredTool = catalog !== void 0 && Object.hasOwn(catalog, name) ? catalog[name] : void 0;
|
|
937
|
-
const source = definition.dynamicTools;
|
|
938
|
-
const resolvedTool = source === void 0 || declaredTool !== void 0 ? void 0 : yield* evaluationSafe(source.resolve(toolName));
|
|
939
|
-
const tool = declaredTool ?? resolvedTool;
|
|
940
|
-
if (tool !== void 0 && tool.kind !== (kind === "query" ? "query" : "mutation"))
|
|
941
|
-
return yield* new HostDeclarationInvalid();
|
|
1104
|
+
const toolName = request.operation === "call" ? request.tool : request.name;
|
|
1105
|
+
const location = locate(definition.tools, toolName);
|
|
1106
|
+
const tool = location === void 0 ? void 0 : location.kind === "operation" ? location.operation : yield* evaluationSafe(location.source.resolve(location.name), secrets);
|
|
942
1107
|
if (tool === void 0)
|
|
943
1108
|
return yield* request.operation === "call" ? new HostToolNotFound() : new HostOperationNotFound();
|
|
1109
|
+
const requested = request.operation === "call" ? request.kind : request.operation === "query" ? "query" : "mutation";
|
|
1110
|
+
if (requested !== void 0 && tool.kind !== requested)
|
|
1111
|
+
return yield* new HostKindMismatch({ tool: toolName, requested, actual: tool.kind });
|
|
1112
|
+
const kind = tool.kind === "query" ? "query" : "mutate";
|
|
944
1113
|
const input = yield* Effect_exports.suspend(
|
|
945
1114
|
() => Schema_exports.decodeUnknownEffect(tool.input)(request.input)
|
|
946
1115
|
).pipe(
|
|
@@ -994,7 +1163,7 @@ function dispatch(app, request, context, signal) {
|
|
|
994
1163
|
transactionOpen = db !== void 0;
|
|
995
1164
|
const output = yield* Effect_exports.gen(function* () {
|
|
996
1165
|
running = yield* captureTelemetry;
|
|
997
|
-
const fetch = yield*
|
|
1166
|
+
const fetch = yield* appInvocationFetch(fetching.signal);
|
|
998
1167
|
return yield* tool.run(
|
|
999
1168
|
{
|
|
1000
1169
|
...bound,
|
|
@@ -1022,14 +1191,15 @@ function dispatch(app, request, context, signal) {
|
|
|
1022
1191
|
const error = Cause_exports.squash(cause);
|
|
1023
1192
|
const provider = parseProviderError(error);
|
|
1024
1193
|
const response = Schema_exports.decodeUnknownOption(OpenapiResponseError)(error);
|
|
1194
|
+
const mcp = parseMcpError(error, secrets);
|
|
1025
1195
|
const failure = Schema_exports.decodeUnknownOption(ElicitationFailed)(error);
|
|
1026
1196
|
return Effect_exports.fail(
|
|
1027
|
-
Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(response) ? new OpenapiResponseError({
|
|
1197
|
+
Option_exports.isSome(provider) ? leavingProviderError(provider.value, secrets, "call") : Option_exports.isSome(response) ? new OpenapiResponseError({
|
|
1028
1198
|
code: response.value.code,
|
|
1029
1199
|
status: response.value.status,
|
|
1030
1200
|
message: response.value.message,
|
|
1031
1201
|
...response.value.recovery === void 0 ? {} : { recovery: response.value.recovery }
|
|
1032
|
-
}) : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed()
|
|
1202
|
+
}) : Option_exports.isSome(mcp) ? mcp.value : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed(failureDetail(error, secrets))
|
|
1033
1203
|
);
|
|
1034
1204
|
}),
|
|
1035
1205
|
Effect_exports.withSpan("app.operation.execute", {
|
|
@@ -1060,14 +1230,61 @@ function dispatch(app, request, context, signal) {
|
|
|
1060
1230
|
)
|
|
1061
1231
|
).pipe(
|
|
1062
1232
|
Effect_exports.catchTags({
|
|
1063
|
-
AppDatabaseError:
|
|
1064
|
-
|
|
1065
|
-
|
|
1233
|
+
AppDatabaseError: storageFailure,
|
|
1234
|
+
DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
|
|
1235
|
+
AppStorageUnavailable: storageFailure,
|
|
1236
|
+
AppStorageError: storageFailure
|
|
1066
1237
|
})
|
|
1067
1238
|
);
|
|
1068
1239
|
})
|
|
1069
1240
|
);
|
|
1070
1241
|
}
|
|
1242
|
+
function checkAccount(slots, declared, requirement, context, signal, deadline) {
|
|
1243
|
+
return Effect_exports.gen(function* () {
|
|
1244
|
+
const selection = Object.hasOwn(slots, requirement) ? slots[requirement] : void 0;
|
|
1245
|
+
const slot = Object.hasOwn(declared.accounts, requirement) ? declared.accounts[requirement] : void 0;
|
|
1246
|
+
if (selection === void 0 || slot === void 0) return yield* new HostAccountsInvalid();
|
|
1247
|
+
const provider = selection instanceof ManyAccounts ? selection.provider : selection;
|
|
1248
|
+
const health = provider.health;
|
|
1249
|
+
if (health === void 0) return yield* new HostOperationNotFound();
|
|
1250
|
+
const { accounts } = yield* bindAccounts(
|
|
1251
|
+
{ [requirement]: provider },
|
|
1252
|
+
{ accounts: { [requirement]: { ...slot, cardinality: "one" } } },
|
|
1253
|
+
context
|
|
1254
|
+
).pipe(Effect_exports.withSpan("app.accounts.bind"));
|
|
1255
|
+
const account = accounts[requirement];
|
|
1256
|
+
if (account === void 0 || !("id" in account)) return yield* new HostAccountsInvalid();
|
|
1257
|
+
const result = yield* Effect_exports.suspend(
|
|
1258
|
+
() => Effect_exports.gen(function* () {
|
|
1259
|
+
return yield* health.run({
|
|
1260
|
+
account,
|
|
1261
|
+
fetch: yield* appInvocationFetch(signal),
|
|
1262
|
+
signal,
|
|
1263
|
+
...deadline === void 0 ? {} : { deadline }
|
|
1264
|
+
});
|
|
1265
|
+
})
|
|
1266
|
+
).pipe(
|
|
1267
|
+
Effect_exports.catchCause((cause) => {
|
|
1268
|
+
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
1269
|
+
const error = Cause_exports.squash(cause);
|
|
1270
|
+
const status = Schema_exports.decodeUnknownOption(ResponseStatusError)(error);
|
|
1271
|
+
const classified = Option_exports.isSome(status) ? Option_exports.fromNullishOr(httpProviderError(status.value.status)) : parseProviderError(error);
|
|
1272
|
+
const secrets = accountSecrets(context.accounts);
|
|
1273
|
+
return Effect_exports.fail(
|
|
1274
|
+
Option_exports.isSome(classified) ? leavingProviderError(accountProviderError(classified.value, account.id), secrets) : new HostOperationFailed(failureDetail(error, secrets))
|
|
1275
|
+
);
|
|
1276
|
+
}),
|
|
1277
|
+
Effect_exports.withSpan("app.account.check")
|
|
1278
|
+
);
|
|
1279
|
+
return yield* safe2(
|
|
1280
|
+
() => Schema_exports.decodeUnknownEffect(AccountCheckResult)(result ?? {}).pipe(
|
|
1281
|
+
Effect_exports.flatMap(Schema_exports.encodeEffect(AccountCheckResult)),
|
|
1282
|
+
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
|
|
1283
|
+
),
|
|
1284
|
+
new HostOutputInvalid()
|
|
1285
|
+
);
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1071
1288
|
var parseSkillLoadFailed = (error) => Schema_exports.decodeUnknownOption(SkillLoadFailed)(error).pipe(
|
|
1072
1289
|
Option_exports.map(
|
|
1073
1290
|
({ reason, message, status }) => new SkillLoadFailed({
|
|
@@ -1077,11 +1294,6 @@ var parseSkillLoadFailed = (error) => Schema_exports.decodeUnknownOption(SkillLo
|
|
|
1077
1294
|
})
|
|
1078
1295
|
)
|
|
1079
1296
|
);
|
|
1080
|
-
var parseMcpError = (error) => Schema_exports.decodeUnknownOption(McpError)(error).pipe(
|
|
1081
|
-
Option_exports.map(
|
|
1082
|
-
({ phase, reason, status }) => new McpError({ phase, reason, ...status === void 0 ? {} : { status } })
|
|
1083
|
-
)
|
|
1084
|
-
);
|
|
1085
1297
|
var errorStatus = Match_exports.type().pipe(
|
|
1086
1298
|
Match_exports.tagsExhaustive({
|
|
1087
1299
|
ProviderError: () => 502,
|
|
@@ -1093,11 +1305,14 @@ var errorStatus = Match_exports.type().pipe(
|
|
|
1093
1305
|
HostAccountsInvalid: () => 422,
|
|
1094
1306
|
HostInputInvalid: () => 422,
|
|
1095
1307
|
HostOperationNotFound: () => 404,
|
|
1308
|
+
HostKindMismatch: () => 409,
|
|
1096
1309
|
HostToolNotFound: () => 404,
|
|
1097
1310
|
HostToolBlocked: () => 403,
|
|
1098
1311
|
HostToolApprovalRequired: () => 409,
|
|
1099
1312
|
HostToolPolicyFailed: () => 500,
|
|
1100
1313
|
HostOperationFailed: () => 500,
|
|
1314
|
+
DatabaseLimitExceeded: () => 422,
|
|
1315
|
+
DatabaseFieldReserved: () => 422,
|
|
1101
1316
|
HostDeclarationInvalid: () => 500,
|
|
1102
1317
|
HostEvaluationFailed: () => 500,
|
|
1103
1318
|
HostOutputInvalid: () => 500,
|
|
@@ -1124,6 +1339,14 @@ var createAppHandler = (app) => (request, context) => Effect_exports.gen(functio
|
|
|
1124
1339
|
toolError = true;
|
|
1125
1340
|
}
|
|
1126
1341
|
}),
|
|
1342
|
+
// Name what failed on the span; the bounded message stays in the reply only.
|
|
1343
|
+
Effect_exports.tapError(
|
|
1344
|
+
(error) => (error._tag === "HostEvaluationFailed" || error._tag === "HostOperationFailed" || error._tag === "HostDeclarationInvalid") && error.errorName !== void 0 ? Effect_exports.annotateCurrentSpan({
|
|
1345
|
+
"error.type": error.errorName,
|
|
1346
|
+
...error.source === void 0 ? {} : { "executor.failure.source": error.source },
|
|
1347
|
+
...error.code === void 0 ? {} : { "executor.failure.code": error.code }
|
|
1348
|
+
}) : Effect_exports.void
|
|
1349
|
+
),
|
|
1127
1350
|
Effect_exports.withSpan(`app.${command.operation}`)
|
|
1128
1351
|
);
|
|
1129
1352
|
if (toolError)
|
|
@@ -1143,12 +1366,17 @@ var createAppHandler = (app) => (request, context) => Effect_exports.gen(functio
|
|
|
1143
1366
|
),
|
|
1144
1367
|
Effect_exports.catchCause(
|
|
1145
1368
|
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.logError(cause).pipe(
|
|
1146
|
-
Effect_exports.
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1369
|
+
Effect_exports.andThen(
|
|
1370
|
+
Schema_exports.encodeEffect(HostError)(
|
|
1371
|
+
declarationInvalid(
|
|
1372
|
+
"The app failed while it was loaded",
|
|
1373
|
+
Cause_exports.squash(cause),
|
|
1374
|
+
accountSecrets(context.accounts)
|
|
1375
|
+
)
|
|
1150
1376
|
)
|
|
1151
|
-
)
|
|
1377
|
+
),
|
|
1378
|
+
Effect_exports.map((error) => Response.json({ ok: false, error }, { status: 500 })),
|
|
1379
|
+
Effect_exports.orDie
|
|
1152
1380
|
)
|
|
1153
1381
|
)
|
|
1154
1382
|
);
|