apps 0.0.1-beta.3 → 0.0.1-beta.30
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-G7ZIRKMK.js → chunk-2D2PKLGQ.js} +118 -197
- package/js/chunk-3SPRHIEE.js +42 -0
- package/js/{chunk-FDNTX5QJ.js → chunk-4N26L465.js} +2 -2
- package/js/chunk-5ZHHO4OM.js +92 -0
- package/js/{chunk-EVJUVWN2.js → chunk-65SZ23BK.js} +2 -2
- package/js/{chunk-M6ZRRIBI.js → chunk-6JBTHTI5.js} +1 -1
- package/js/{chunk-J7O55ZV7.js → chunk-6NK26ONC.js} +332 -187
- package/js/chunk-6VWYEQ4X.js +254 -0
- package/js/{chunk-RN2MXB4R.js → chunk-AE4FWJQU.js} +128 -24
- package/js/{chunk-HDJH3RPR.js → chunk-BBTELEAN.js} +2 -2
- package/js/{chunk-LGIYBDWA.js → chunk-BRGF7VFN.js} +65 -1
- package/js/{chunk-MYYEW3RA.js → chunk-BSRU52RU.js} +984 -61
- package/js/{chunk-FZJOYIZO.js → chunk-BTJMXW4I.js} +1 -1
- package/js/{chunk-HDTGZWP2.js → chunk-IMCEF6KE.js} +139 -32
- package/js/chunk-KQCMHI3K.js +118 -0
- package/js/{chunk-BMOIAIVR.js → chunk-M2KEEOIQ.js} +49 -1
- package/js/{chunk-YEJOQEII.js → chunk-MYCVMDWI.js} +45 -7
- package/js/{chunk-FW5HBOIK.js → chunk-NXTXZ635.js} +1841 -1701
- package/js/chunk-OD3KFKZD.js +1617 -0
- package/js/{chunk-JN55AYQH.js → chunk-OI5CKSBU.js} +61 -32
- package/js/{chunk-NQ3OMCA5.js → chunk-P46HIAX6.js} +2 -2
- package/js/chunk-PUC24GZP.js +801 -0
- package/js/{chunk-SATWJKN6.js → chunk-PWF2DRJ3.js} +1 -1
- package/js/{chunk-D47C7KG5.js → chunk-VUVBMNKC.js} +2 -2
- package/js/{chunk-ZCAMUXSG.js → chunk-WGBI5MVX.js} +3 -4
- package/js/{chunk-T2LAZCAD.js → chunk-WQ5MVBTP.js} +1 -1
- package/js/{chunk-PLCMJREA.js → chunk-XBQTJP76.js} +60 -20
- package/js/{chunk-QKHR7BMF.js → chunk-XGN5IFOZ.js} +3 -3
- package/js/{chunk-WFSQXYUT.js → chunk-YML53Z7H.js} +42 -5
- package/js/{chunk-5MQZEB6Y.js → chunk-ZZOCEUTB.js} +37 -12
- 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/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 +35 -8
- 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 +52 -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-VUVBMNKC.js";
|
|
4
|
+
import {
|
|
5
|
+
accountSecrets,
|
|
6
|
+
appInvocationFetch,
|
|
7
|
+
boundFailureMessage,
|
|
8
|
+
describeFailure,
|
|
9
|
+
failureDetail,
|
|
10
|
+
leavingProviderError,
|
|
11
|
+
parseMcpError,
|
|
12
|
+
readCatalog,
|
|
13
|
+
routerSkills
|
|
14
|
+
} from "./chunk-PUC24GZP.js";
|
|
4
15
|
import {
|
|
5
16
|
folderSkillsEffect
|
|
6
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-4N26L465.js";
|
|
7
18
|
import {
|
|
19
|
+
ResponseStatusError,
|
|
8
20
|
authorDatabase,
|
|
9
21
|
isApp,
|
|
10
22
|
toEffectApp,
|
|
11
23
|
unavailableStorage
|
|
12
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-OI5CKSBU.js";
|
|
25
|
+
import {
|
|
26
|
+
parseDatabaseSchema
|
|
27
|
+
} from "./chunk-XBQTJP76.js";
|
|
13
28
|
import {
|
|
29
|
+
declaredOperations,
|
|
14
30
|
fromPromise,
|
|
31
|
+
locate,
|
|
15
32
|
nativeOperation,
|
|
16
33
|
toPromise
|
|
17
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-6VWYEQ4X.js";
|
|
18
35
|
import {
|
|
36
|
+
accountProviderError,
|
|
37
|
+
httpProviderError,
|
|
19
38
|
parseProviderError
|
|
20
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-KQCMHI3K.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,28 @@ import {
|
|
|
62
83
|
defaultWebhookTransportLimits,
|
|
63
84
|
maxInputProblems,
|
|
64
85
|
workflowDurationMillis
|
|
65
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-BSRU52RU.js";
|
|
66
87
|
import {
|
|
67
88
|
CacheError
|
|
68
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-BRGF7VFN.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-MYCVMDWI.js";
|
|
77
95
|
import {
|
|
78
|
-
captureTelemetry
|
|
79
|
-
|
|
80
|
-
} from "./chunk-ZCAMUXSG.js";
|
|
96
|
+
captureTelemetry
|
|
97
|
+
} from "./chunk-WGBI5MVX.js";
|
|
81
98
|
import {
|
|
82
99
|
decoderOf,
|
|
83
100
|
importedJsonSchema,
|
|
84
|
-
jsonSchemaDecoder
|
|
85
|
-
|
|
101
|
+
jsonSchemaDecoder,
|
|
102
|
+
jsonSchemaDocument
|
|
103
|
+
} from "./chunk-YML53Z7H.js";
|
|
86
104
|
import {
|
|
87
105
|
JsonObject,
|
|
88
106
|
JsonValue
|
|
89
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-PWF2DRJ3.js";
|
|
90
108
|
import {
|
|
91
109
|
Cause_exports,
|
|
92
110
|
Clock_exports,
|
|
@@ -98,7 +116,7 @@ import {
|
|
|
98
116
|
SchemaIssue_exports,
|
|
99
117
|
Schema_exports,
|
|
100
118
|
Stream_exports
|
|
101
|
-
} from "./chunk-
|
|
119
|
+
} from "./chunk-NXTXZ635.js";
|
|
102
120
|
|
|
103
121
|
// src/implementation/elicitation.ts
|
|
104
122
|
var prepareElicitation = (input) => Effect_exports.gen(function* () {
|
|
@@ -139,19 +157,29 @@ var makeElicit = (handler, signal) => toPromise(
|
|
|
139
157
|
var ApprovalDecision = Schema_exports.Literals(["approved", "denied", "user-approval"]);
|
|
140
158
|
|
|
141
159
|
// src/implementation/workflow-context.ts
|
|
142
|
-
var workflowSafe = (work) => work.pipe(
|
|
160
|
+
var workflowSafe = (work, secrets) => work.pipe(
|
|
143
161
|
Effect_exports.catchCause((cause) => {
|
|
144
162
|
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
145
163
|
const error = Cause_exports.squash(cause);
|
|
146
164
|
if (Schema_exports.is(WorkflowFailure)(error)) return Effect_exports.fail(error);
|
|
165
|
+
const { errorName, message } = failureDetail(error, secrets);
|
|
147
166
|
return Effect_exports.fail(
|
|
148
167
|
new WorkflowFailure({
|
|
149
168
|
reason: "execution",
|
|
150
|
-
retryable: !(error instanceof NonRetryableError)
|
|
169
|
+
retryable: !(error instanceof NonRetryableError),
|
|
170
|
+
...errorName === void 0 ? {} : { errorName },
|
|
171
|
+
...message === void 0 ? {} : { message }
|
|
151
172
|
})
|
|
152
173
|
);
|
|
153
174
|
})
|
|
154
175
|
);
|
|
176
|
+
var inStep = (step) => (failure) => failure.step === void 0 ? new WorkflowFailure({
|
|
177
|
+
reason: failure.reason,
|
|
178
|
+
retryable: failure.retryable,
|
|
179
|
+
step: step.slice(0, 200),
|
|
180
|
+
...failure.errorName === void 0 ? {} : { errorName: failure.errorName },
|
|
181
|
+
...failure.message.length === 0 ? {} : { message: failure.message }
|
|
182
|
+
}) : failure;
|
|
155
183
|
var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_exports.gen(function* () {
|
|
156
184
|
const services = yield* Effect_exports.context();
|
|
157
185
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -206,25 +234,33 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
|
|
|
206
234
|
Effect_exports.sync(() => new AbortController()),
|
|
207
235
|
(controller2) => Effect_exports.sync(() => controller2.abort())
|
|
208
236
|
);
|
|
209
|
-
const
|
|
237
|
+
const step2 = yield* fresh(stepId, AbortSignal.any([signal, controller.signal]));
|
|
210
238
|
const result = yield* workflowSafe(
|
|
211
|
-
Effect_exports.tryPromise({
|
|
239
|
+
Effect_exports.tryPromise({
|
|
240
|
+
try: () => callback(step2.context),
|
|
241
|
+
catch: (error) => error
|
|
242
|
+
}),
|
|
243
|
+
step2.secrets
|
|
212
244
|
);
|
|
213
245
|
return yield* Schema_exports.decodeUnknownEffect(WorkflowValue)(result).pipe(
|
|
214
246
|
Effect_exports.mapError(
|
|
215
|
-
() => new WorkflowFailure({
|
|
247
|
+
() => new WorkflowFailure({
|
|
248
|
+
reason: "output",
|
|
249
|
+
retryable: false,
|
|
250
|
+
message: "The step returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
|
|
251
|
+
})
|
|
216
252
|
)
|
|
217
253
|
);
|
|
218
254
|
})
|
|
219
255
|
).pipe(Effect_exports.provideContext(services))
|
|
220
256
|
)
|
|
221
|
-
);
|
|
257
|
+
).pipe(Effect_exports.mapError(inStep(name)));
|
|
222
258
|
});
|
|
223
259
|
const operationStep = (kind, name, operation, input, options) => Effect_exports.gen(function* () {
|
|
224
260
|
const target = nativeOperation(operation);
|
|
225
|
-
const
|
|
226
|
-
const match =
|
|
227
|
-
(
|
|
261
|
+
const root = definition.tools?.kind === "router" ? definition.tools : void 0;
|
|
262
|
+
const match = declaredOperations(root).find(
|
|
263
|
+
(entry) => entry.operation === target && entry.operation.kind === kind
|
|
228
264
|
);
|
|
229
265
|
if (target === void 0 || match === void 0)
|
|
230
266
|
return yield* new WorkflowFailure({ reason: "operation", retryable: false });
|
|
@@ -243,9 +279,9 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
|
|
|
243
279
|
parsed,
|
|
244
280
|
() => attempt(
|
|
245
281
|
parsed,
|
|
246
|
-
execution.invoke({ kind, name: match
|
|
282
|
+
execution.invoke({ kind, name: match.name, input: args, stepId, timeout }).pipe(Effect_exports.provideContext(services))
|
|
247
283
|
)
|
|
248
|
-
);
|
|
284
|
+
).pipe(Effect_exports.mapError(inStep(name)));
|
|
249
285
|
});
|
|
250
286
|
const invoke = (effect) => toPromise(() => effect.pipe(Effect_exports.provideContext(services)), signal)();
|
|
251
287
|
const step = {
|
|
@@ -469,7 +505,7 @@ var authorCache = (host, accounts, signal, deadline) => {
|
|
|
469
505
|
...options.staleFor === void 0 ? {} : { staleFor: options.staleFor },
|
|
470
506
|
load: Effect_exports.acquireUseRelease(
|
|
471
507
|
Effect_exports.sync(() => new AbortController()),
|
|
472
|
-
(controller) =>
|
|
508
|
+
(controller) => appInvocationFetch(controller.signal).pipe(
|
|
473
509
|
Effect_exports.flatMap(
|
|
474
510
|
(fetch) => fromPromise(options.load)({
|
|
475
511
|
fetch,
|
|
@@ -523,6 +559,10 @@ var authorCache = (host, accounts, signal, deadline) => {
|
|
|
523
559
|
};
|
|
524
560
|
|
|
525
561
|
// src/implementation/host.ts
|
|
562
|
+
var WireCatalog = Schema_exports.Struct({
|
|
563
|
+
tools: Schema_exports.Array(Schema_exports.Union([HostedTool, HostedToolSummary])),
|
|
564
|
+
routers: Schema_exports.Array(HostedRouter)
|
|
565
|
+
});
|
|
526
566
|
function safe2(work, failure) {
|
|
527
567
|
return Effect_exports.suspend(work).pipe(
|
|
528
568
|
Effect_exports.catchCause(
|
|
@@ -530,30 +570,39 @@ function safe2(work, failure) {
|
|
|
530
570
|
)
|
|
531
571
|
);
|
|
532
572
|
}
|
|
533
|
-
var evaluationSafe = (work) => work.pipe(
|
|
573
|
+
var evaluationSafe = (work, secrets) => work.pipe(
|
|
534
574
|
Effect_exports.catchCause((cause) => {
|
|
535
575
|
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
536
576
|
const error = Cause_exports.squash(cause);
|
|
537
577
|
const provider = parseProviderError(error);
|
|
538
578
|
const skills = parseSkillLoadFailed(error);
|
|
539
|
-
const mcp = parseMcpError(error);
|
|
579
|
+
const mcp = parseMcpError(error, secrets);
|
|
540
580
|
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()
|
|
581
|
+
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
582
|
);
|
|
543
583
|
})
|
|
544
584
|
);
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
585
|
+
var declarationInvalid = (summary, cause, secrets = []) => new HostDeclarationInvalid({
|
|
586
|
+
source: "app",
|
|
587
|
+
errorName: "HostDeclarationInvalid",
|
|
588
|
+
message: boundFailureMessage(
|
|
589
|
+
cause === void 0 ? summary : `${summary}: ${describeFailure(cause)}`,
|
|
590
|
+
secrets
|
|
591
|
+
)
|
|
592
|
+
});
|
|
593
|
+
var declarationSafe = (work, summary) => Effect_exports.suspend(work).pipe(
|
|
594
|
+
Effect_exports.catchCause(
|
|
595
|
+
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(declarationInvalid(summary, Cause_exports.squash(cause)))
|
|
596
|
+
)
|
|
597
|
+
);
|
|
598
|
+
function declaredExposure(exposure) {
|
|
599
|
+
const named = (kind) => Object.entries(exposure ?? {}).filter(([, value]) => value === kind).map(([field]) => field).sort();
|
|
600
|
+
const plain = named("plain");
|
|
601
|
+
const raw = named("raw");
|
|
602
|
+
return { ...plain.length === 0 ? {} : { plain }, ...raw.length === 0 ? {} : { raw } };
|
|
554
603
|
}
|
|
555
604
|
function providerDeclaration(provider) {
|
|
556
|
-
return
|
|
605
|
+
return declarationSafe(
|
|
557
606
|
() => Effect_exports.gen(function* () {
|
|
558
607
|
const auth = /* @__PURE__ */ new Map();
|
|
559
608
|
for (const [name, method] of Object.entries(provider.auth)) {
|
|
@@ -562,42 +611,50 @@ function providerDeclaration(provider) {
|
|
|
562
611
|
auth.set(name, {
|
|
563
612
|
type: "secrets",
|
|
564
613
|
label: method.label,
|
|
565
|
-
fields: yield*
|
|
614
|
+
fields: yield* jsonSchemaDocument(method.fields),
|
|
615
|
+
...declaredExposure(method.exposure)
|
|
566
616
|
});
|
|
567
617
|
break;
|
|
568
618
|
case "oauth2":
|
|
569
619
|
auth.set(name, {
|
|
570
620
|
type: "oauth2",
|
|
571
621
|
...method.config,
|
|
572
|
-
response: yield*
|
|
622
|
+
response: yield* jsonSchemaDocument(method.response),
|
|
623
|
+
...declaredExposure(method.exposure)
|
|
573
624
|
});
|
|
574
625
|
break;
|
|
575
626
|
}
|
|
576
627
|
}
|
|
577
628
|
return yield* Schema_exports.decodeUnknownEffect(DeclaredProvider)({
|
|
578
629
|
name: provider.name,
|
|
579
|
-
auth: Object.fromEntries(auth)
|
|
630
|
+
auth: Object.fromEntries(auth),
|
|
631
|
+
// Order and repetition carry no meaning, so neither changes the provider's identity.
|
|
632
|
+
...provider.hosts === void 0 ? {} : { hosts: [...new Set(provider.hosts)].sort() }
|
|
580
633
|
});
|
|
581
634
|
}),
|
|
582
|
-
|
|
635
|
+
`Account provider "${provider.name}" has an invalid declaration`
|
|
583
636
|
);
|
|
584
637
|
}
|
|
585
638
|
function requirements(slots, database) {
|
|
586
639
|
return Effect_exports.gen(function* () {
|
|
587
640
|
const accounts = /* @__PURE__ */ new Map();
|
|
588
641
|
for (const [slot, selection] of Object.entries(slots)) {
|
|
642
|
+
const provider = selection instanceof ManyAccounts ? selection.provider : selection;
|
|
589
643
|
accounts.set(slot, {
|
|
590
644
|
cardinality: selection instanceof ManyAccounts ? "many" : "one",
|
|
591
|
-
definition: yield* providerDeclaration(
|
|
592
|
-
|
|
593
|
-
)
|
|
645
|
+
definition: yield* providerDeclaration(provider),
|
|
646
|
+
...provider.health === void 0 ? {} : { health: true }
|
|
594
647
|
});
|
|
595
648
|
}
|
|
596
649
|
return yield* Schema_exports.decodeUnknownEffect(DeclaredRequirements)({
|
|
597
650
|
accounts: Object.fromEntries(accounts),
|
|
598
651
|
capabilities: { skills: true, toolIndex: true, skillSources: true, scheduledTools: true },
|
|
599
652
|
...database === void 0 ? {} : { database }
|
|
600
|
-
}).pipe(
|
|
653
|
+
}).pipe(
|
|
654
|
+
Effect_exports.mapError(
|
|
655
|
+
(cause) => declarationInvalid("The app's account or database declarations are invalid", cause)
|
|
656
|
+
)
|
|
657
|
+
);
|
|
601
658
|
});
|
|
602
659
|
}
|
|
603
660
|
function canonical(value) {
|
|
@@ -607,6 +664,9 @@ function canonical(value) {
|
|
|
607
664
|
}
|
|
608
665
|
return JSON.stringify(value);
|
|
609
666
|
}
|
|
667
|
+
function withoutHosts({ hosts: _hosts, ...provider }) {
|
|
668
|
+
return provider;
|
|
669
|
+
}
|
|
610
670
|
function bindAccounts(slots, declarations, context) {
|
|
611
671
|
return safe2(
|
|
612
672
|
() => Effect_exports.gen(function* () {
|
|
@@ -632,7 +692,7 @@ function bindAccounts(slots, declarations, context) {
|
|
|
632
692
|
for (const account of accounts) {
|
|
633
693
|
if (ids.has(account.id)) return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
634
694
|
ids.add(account.id);
|
|
635
|
-
if (canonical(account.provider) !== canonical(requirement.definition) || !Object.hasOwn(provider.auth, account.method))
|
|
695
|
+
if (canonical(withoutHosts(account.provider)) !== canonical(withoutHosts(requirement.definition)) || !Object.hasOwn(provider.auth, account.method))
|
|
636
696
|
return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
637
697
|
const method = provider.auth[account.method];
|
|
638
698
|
if (method === void 0) return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
@@ -653,17 +713,67 @@ function bindAccounts(slots, declarations, context) {
|
|
|
653
713
|
new HostAccountsInvalid()
|
|
654
714
|
);
|
|
655
715
|
}
|
|
716
|
+
var fetchLifetime = (signal, background) => Effect_exports.acquireRelease(
|
|
717
|
+
Effect_exports.sync(() => {
|
|
718
|
+
const controller = new AbortController();
|
|
719
|
+
let refreshes = 0;
|
|
720
|
+
let ended = false;
|
|
721
|
+
const settle = () => {
|
|
722
|
+
if (ended && refreshes === 0) controller.abort();
|
|
723
|
+
};
|
|
724
|
+
const end = () => {
|
|
725
|
+
ended = true;
|
|
726
|
+
settle();
|
|
727
|
+
};
|
|
728
|
+
signal.addEventListener("abort", end, { once: true });
|
|
729
|
+
if (signal.aborted) end();
|
|
730
|
+
const settled = Effect_exports.sync(() => {
|
|
731
|
+
refreshes -= 1;
|
|
732
|
+
settle();
|
|
733
|
+
});
|
|
734
|
+
return {
|
|
735
|
+
signal: controller.signal,
|
|
736
|
+
close: () => {
|
|
737
|
+
signal.removeEventListener("abort", end);
|
|
738
|
+
end();
|
|
739
|
+
},
|
|
740
|
+
/** Counted from the hand-off, so a refresh that has not started yet keeps the fetch. */
|
|
741
|
+
background: (task) => Effect_exports.suspend(() => {
|
|
742
|
+
refreshes += 1;
|
|
743
|
+
return background(task.pipe(Effect_exports.ensuring(settled))).pipe(
|
|
744
|
+
Effect_exports.onError(() => settled)
|
|
745
|
+
);
|
|
746
|
+
})
|
|
747
|
+
};
|
|
748
|
+
}),
|
|
749
|
+
(lifetime) => Effect_exports.sync(lifetime.close)
|
|
750
|
+
);
|
|
656
751
|
function dispatch(app, request, context, signal) {
|
|
657
752
|
return Effect_exports.scoped(
|
|
658
753
|
Effect_exports.gen(function* () {
|
|
659
|
-
if (!isApp(app))
|
|
754
|
+
if (!isApp(app))
|
|
755
|
+
return yield* Effect_exports.fail(
|
|
756
|
+
declarationInvalid("The app module's default export is not an app created by defineApp")
|
|
757
|
+
);
|
|
660
758
|
const native = toEffectApp(app);
|
|
759
|
+
const secrets = accountSecrets(context.accounts);
|
|
760
|
+
const storageFailure = (error) => Effect_exports.fail(new HostOperationFailed(failureDetail(error, secrets)));
|
|
661
761
|
const declared = yield* requirements(native.accounts, native.database?.schema);
|
|
662
|
-
if (request.operation === "requirements")
|
|
762
|
+
if (request.operation === "requirements") {
|
|
763
|
+
if (native.database !== void 0)
|
|
764
|
+
yield* parseDatabaseSchema(native.database.schema).pipe(
|
|
765
|
+
Effect_exports.catchTag(
|
|
766
|
+
"AppDatabaseError",
|
|
767
|
+
(cause) => Effect_exports.fail(
|
|
768
|
+
declarationInvalid("The app's account or database declarations are invalid", cause)
|
|
769
|
+
)
|
|
770
|
+
)
|
|
771
|
+
);
|
|
663
772
|
return yield* safe2(
|
|
664
773
|
() => Schema_exports.decodeUnknownEffect(JsonValue)(declared),
|
|
665
774
|
new HostDeclarationInvalid()
|
|
666
775
|
);
|
|
776
|
+
}
|
|
667
777
|
const lifetime = yield* Effect_exports.acquireRelease(
|
|
668
778
|
Effect_exports.sync(() => new AbortController()),
|
|
669
779
|
(controller) => Effect_exports.sync(() => controller.abort())
|
|
@@ -689,6 +799,15 @@ function dispatch(app, request, context, signal) {
|
|
|
689
799
|
return yield* new WorkflowFailure({ reason: "engine", retryable: true });
|
|
690
800
|
return result;
|
|
691
801
|
});
|
|
802
|
+
if (request.operation === "account-check")
|
|
803
|
+
return yield* checkAccount(
|
|
804
|
+
native.accounts,
|
|
805
|
+
declared,
|
|
806
|
+
request.requirement,
|
|
807
|
+
context,
|
|
808
|
+
invocationSignal,
|
|
809
|
+
deadline
|
|
810
|
+
).pipe(withinDeadline);
|
|
692
811
|
let running;
|
|
693
812
|
let transactionOpen = false;
|
|
694
813
|
const delivery = (request2, signal2) => Effect_exports.suspend(
|
|
@@ -723,9 +842,19 @@ function dispatch(app, request, context, signal) {
|
|
|
723
842
|
const files = yield* Schema_exports.decodeUnknownEffect(Schema_exports.Array(SkillFile))(
|
|
724
843
|
context.files ?? []
|
|
725
844
|
).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
|
|
845
|
+
let cacheCommands = 0;
|
|
846
|
+
const hostCache = context.cache ?? unavailableCache;
|
|
847
|
+
const fetching = yield* fetchLifetime(signal, hostCache.background);
|
|
726
848
|
const bound = {
|
|
727
849
|
cache: authorCache(
|
|
728
|
-
|
|
850
|
+
{
|
|
851
|
+
...hostCache,
|
|
852
|
+
transport: (command) => {
|
|
853
|
+
cacheCommands += 1;
|
|
854
|
+
return hostCache.transport(command);
|
|
855
|
+
},
|
|
856
|
+
background: fetching.background
|
|
857
|
+
},
|
|
729
858
|
Redacted_exports.value(context.accounts),
|
|
730
859
|
invocationSignal,
|
|
731
860
|
deadline
|
|
@@ -736,35 +865,43 @@ function dispatch(app, request, context, signal) {
|
|
|
736
865
|
),
|
|
737
866
|
workflows: workflowReads,
|
|
738
867
|
signal: invocationSignal,
|
|
739
|
-
fetch: yield*
|
|
868
|
+
fetch: yield* appInvocationFetch(fetching.signal),
|
|
740
869
|
elicit: makeElicit(delivery, invocationSignal)
|
|
741
870
|
};
|
|
742
|
-
const definition = yield* evaluationSafe(native.evaluate(bound)).pipe(
|
|
871
|
+
const definition = yield* evaluationSafe(native.evaluate(bound), secrets).pipe(
|
|
743
872
|
Effect_exports.withSpan("app.evaluate")
|
|
744
873
|
);
|
|
745
874
|
if (request.operation === "skills") {
|
|
746
875
|
const declared2 = definition.skills ?? (yield* folderSkillsEffect({ files }).pipe(
|
|
747
876
|
Effect_exports.mapError(() => new HostDeclarationInvalid())
|
|
748
877
|
));
|
|
749
|
-
const
|
|
750
|
-
const
|
|
878
|
+
const source = definition.dynamicSkills;
|
|
879
|
+
const before = cacheCommands;
|
|
880
|
+
const dynamic = source === void 0 ? [] : yield* evaluationSafe(Effect_exports.suspend(source.list), secrets).pipe(
|
|
751
881
|
Effect_exports.withSpan("app.skills.load")
|
|
752
882
|
);
|
|
753
|
-
const
|
|
754
|
-
|
|
755
|
-
)
|
|
756
|
-
|
|
883
|
+
const cached = source !== void 0 && cacheCommands > before;
|
|
884
|
+
const authored = new Set([...declared2, ...dynamic].map((skill) => skill.name));
|
|
885
|
+
const routed = (yield* routerSkills(definition.tools).pipe(
|
|
886
|
+
Effect_exports.withSpan("app.skills.routers")
|
|
887
|
+
)).filter((skill) => !authored.has(skill.name));
|
|
888
|
+
const skills = yield* Schema_exports.decodeUnknownEffect(AppSkills)([
|
|
889
|
+
...declared2,
|
|
890
|
+
...dynamic,
|
|
891
|
+
...routed
|
|
892
|
+
]).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
|
|
893
|
+
return request.sources === true ? { skills, dynamic: source !== void 0, cached } : skills;
|
|
757
894
|
}
|
|
758
895
|
if (request.operation === "workflows") {
|
|
759
896
|
return yield* Effect_exports.forEach(
|
|
760
897
|
Object.entries(definition.workflows ?? {}),
|
|
761
|
-
([
|
|
898
|
+
([name, entry]) => safe2(
|
|
762
899
|
() => Effect_exports.gen(function* () {
|
|
763
900
|
return yield* Schema_exports.decodeUnknownEffect(HostedWorkflow)({
|
|
764
|
-
name
|
|
901
|
+
name,
|
|
765
902
|
...entry.description === void 0 ? {} : { description: entry.description },
|
|
766
|
-
inputSchema: yield*
|
|
767
|
-
...entry.output === void 0 ? {} : { outputSchema: yield*
|
|
903
|
+
inputSchema: yield* jsonSchemaDocument(entry.input),
|
|
904
|
+
...entry.output === void 0 ? {} : { outputSchema: yield* jsonSchemaDocument(entry.output) }
|
|
768
905
|
});
|
|
769
906
|
}),
|
|
770
907
|
new HostDeclarationInvalid()
|
|
@@ -797,108 +934,60 @@ function dispatch(app, request, context, signal) {
|
|
|
797
934
|
new WorkflowFailure({ reason: "credentials", retryable: false })
|
|
798
935
|
);
|
|
799
936
|
return {
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
937
|
+
context: {
|
|
938
|
+
...accounts,
|
|
939
|
+
cache: authorCache(
|
|
940
|
+
context.cache ?? unavailableCache,
|
|
941
|
+
Redacted_exports.value(current.accounts),
|
|
942
|
+
signal2
|
|
943
|
+
),
|
|
944
|
+
files,
|
|
945
|
+
fetch: yield* appInvocationFetch(signal2),
|
|
946
|
+
signal: signal2,
|
|
947
|
+
runId: execution.runId,
|
|
948
|
+
stepId,
|
|
949
|
+
idempotencyKey: stepId
|
|
950
|
+
},
|
|
951
|
+
// The resolved values, not the app's decoded fields, which may be `Redacted`.
|
|
952
|
+
secrets: accountSecrets(current.accounts)
|
|
812
953
|
};
|
|
813
954
|
}),
|
|
814
955
|
invocationSignal
|
|
815
956
|
);
|
|
816
|
-
const output = yield* workflowSafe(entry.run(workflowContext, input2));
|
|
957
|
+
const output = yield* workflowSafe(entry.run(workflowContext, input2), secrets);
|
|
817
958
|
const outputSchema = entry.output;
|
|
818
959
|
const decoded = outputSchema === void 0 ? output : yield* safe2(
|
|
819
960
|
() => Schema_exports.decodeUnknownEffect(outputSchema)(output),
|
|
820
|
-
new WorkflowFailure({
|
|
961
|
+
new WorkflowFailure({
|
|
962
|
+
reason: "output",
|
|
963
|
+
retryable: false,
|
|
964
|
+
message: "The workflow's result does not match its declared output schema."
|
|
965
|
+
})
|
|
821
966
|
);
|
|
822
967
|
return yield* safe2(
|
|
823
968
|
() => Schema_exports.decodeUnknownEffect(WorkflowValue)(decoded),
|
|
824
|
-
new WorkflowFailure({
|
|
969
|
+
new WorkflowFailure({
|
|
970
|
+
reason: "output",
|
|
971
|
+
retryable: false,
|
|
972
|
+
message: "The workflow returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
|
|
973
|
+
})
|
|
825
974
|
);
|
|
826
975
|
}
|
|
827
976
|
if (request.operation === "inspect") {
|
|
828
977
|
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;
|
|
978
|
+
const catalog = yield* readCatalog(definition.tools, {
|
|
979
|
+
summary,
|
|
980
|
+
secrets,
|
|
981
|
+
...request.tools === void 0 ? {} : { wanted: new Set(request.tools) },
|
|
982
|
+
...request.scheduled === true ? { scheduled: true } : {},
|
|
983
|
+
schedules: (name) => Object.entries(definition.schedules ?? {}).filter(([, schedule]) => schedule.tool === name).map(([name2, { tool: _tool, ...schedule }]) => ({ name: name2, ...schedule }))
|
|
984
|
+
}).pipe(Effect_exports.withSpan("app.catalog.read"));
|
|
985
|
+
return yield* safe2(
|
|
986
|
+
() => Schema_exports.encodeEffect(WireCatalog)(catalog).pipe(
|
|
987
|
+
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
|
|
988
|
+
),
|
|
989
|
+
new HostDeclarationInvalid()
|
|
990
|
+
);
|
|
902
991
|
}
|
|
903
992
|
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
993
|
const executeWebhook = (db) => dispatchWebhook(
|
|
@@ -922,25 +1011,22 @@ function dispatch(app, request, context, signal) {
|
|
|
922
1011
|
const storage2 = context.storage ?? unavailableStorage;
|
|
923
1012
|
return yield* storage2.mutate(native.database.schema, executeWebhook).pipe(
|
|
924
1013
|
Effect_exports.catchTags({
|
|
925
|
-
AppDatabaseError:
|
|
926
|
-
|
|
927
|
-
|
|
1014
|
+
AppDatabaseError: storageFailure,
|
|
1015
|
+
DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
|
|
1016
|
+
AppStorageUnavailable: storageFailure,
|
|
1017
|
+
AppStorageError: storageFailure
|
|
928
1018
|
})
|
|
929
1019
|
);
|
|
930
1020
|
}
|
|
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();
|
|
1021
|
+
const toolName = request.operation === "call" ? request.tool : request.name;
|
|
1022
|
+
const location = locate(definition.tools, toolName);
|
|
1023
|
+
const tool = location === void 0 ? void 0 : location.kind === "operation" ? location.operation : yield* evaluationSafe(location.source.resolve(location.name), secrets);
|
|
942
1024
|
if (tool === void 0)
|
|
943
1025
|
return yield* request.operation === "call" ? new HostToolNotFound() : new HostOperationNotFound();
|
|
1026
|
+
const requested = request.operation === "call" ? request.kind : request.operation === "query" ? "query" : "mutation";
|
|
1027
|
+
if (requested !== void 0 && tool.kind !== requested)
|
|
1028
|
+
return yield* new HostKindMismatch({ tool: toolName, requested, actual: tool.kind });
|
|
1029
|
+
const kind = tool.kind === "query" ? "query" : "mutate";
|
|
944
1030
|
const input = yield* Effect_exports.suspend(
|
|
945
1031
|
() => Schema_exports.decodeUnknownEffect(tool.input)(request.input)
|
|
946
1032
|
).pipe(
|
|
@@ -994,7 +1080,7 @@ function dispatch(app, request, context, signal) {
|
|
|
994
1080
|
transactionOpen = db !== void 0;
|
|
995
1081
|
const output = yield* Effect_exports.gen(function* () {
|
|
996
1082
|
running = yield* captureTelemetry;
|
|
997
|
-
const fetch = yield*
|
|
1083
|
+
const fetch = yield* appInvocationFetch(fetching.signal);
|
|
998
1084
|
return yield* tool.run(
|
|
999
1085
|
{
|
|
1000
1086
|
...bound,
|
|
@@ -1022,14 +1108,15 @@ function dispatch(app, request, context, signal) {
|
|
|
1022
1108
|
const error = Cause_exports.squash(cause);
|
|
1023
1109
|
const provider = parseProviderError(error);
|
|
1024
1110
|
const response = Schema_exports.decodeUnknownOption(OpenapiResponseError)(error);
|
|
1111
|
+
const mcp = parseMcpError(error, secrets);
|
|
1025
1112
|
const failure = Schema_exports.decodeUnknownOption(ElicitationFailed)(error);
|
|
1026
1113
|
return Effect_exports.fail(
|
|
1027
|
-
Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(response) ? new OpenapiResponseError({
|
|
1114
|
+
Option_exports.isSome(provider) ? leavingProviderError(provider.value, secrets, "call") : Option_exports.isSome(response) ? new OpenapiResponseError({
|
|
1028
1115
|
code: response.value.code,
|
|
1029
1116
|
status: response.value.status,
|
|
1030
1117
|
message: response.value.message,
|
|
1031
1118
|
...response.value.recovery === void 0 ? {} : { recovery: response.value.recovery }
|
|
1032
|
-
}) : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed()
|
|
1119
|
+
}) : Option_exports.isSome(mcp) ? mcp.value : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed(failureDetail(error, secrets))
|
|
1033
1120
|
);
|
|
1034
1121
|
}),
|
|
1035
1122
|
Effect_exports.withSpan("app.operation.execute", {
|
|
@@ -1060,14 +1147,61 @@ function dispatch(app, request, context, signal) {
|
|
|
1060
1147
|
)
|
|
1061
1148
|
).pipe(
|
|
1062
1149
|
Effect_exports.catchTags({
|
|
1063
|
-
AppDatabaseError:
|
|
1064
|
-
|
|
1065
|
-
|
|
1150
|
+
AppDatabaseError: storageFailure,
|
|
1151
|
+
DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
|
|
1152
|
+
AppStorageUnavailable: storageFailure,
|
|
1153
|
+
AppStorageError: storageFailure
|
|
1066
1154
|
})
|
|
1067
1155
|
);
|
|
1068
1156
|
})
|
|
1069
1157
|
);
|
|
1070
1158
|
}
|
|
1159
|
+
function checkAccount(slots, declared, requirement, context, signal, deadline) {
|
|
1160
|
+
return Effect_exports.gen(function* () {
|
|
1161
|
+
const selection = Object.hasOwn(slots, requirement) ? slots[requirement] : void 0;
|
|
1162
|
+
const slot = Object.hasOwn(declared.accounts, requirement) ? declared.accounts[requirement] : void 0;
|
|
1163
|
+
if (selection === void 0 || slot === void 0) return yield* new HostAccountsInvalid();
|
|
1164
|
+
const provider = selection instanceof ManyAccounts ? selection.provider : selection;
|
|
1165
|
+
const health = provider.health;
|
|
1166
|
+
if (health === void 0) return yield* new HostOperationNotFound();
|
|
1167
|
+
const { accounts } = yield* bindAccounts(
|
|
1168
|
+
{ [requirement]: provider },
|
|
1169
|
+
{ accounts: { [requirement]: { ...slot, cardinality: "one" } } },
|
|
1170
|
+
context
|
|
1171
|
+
).pipe(Effect_exports.withSpan("app.accounts.bind"));
|
|
1172
|
+
const account = accounts[requirement];
|
|
1173
|
+
if (account === void 0 || !("id" in account)) return yield* new HostAccountsInvalid();
|
|
1174
|
+
const result = yield* Effect_exports.suspend(
|
|
1175
|
+
() => Effect_exports.gen(function* () {
|
|
1176
|
+
return yield* health.run({
|
|
1177
|
+
account,
|
|
1178
|
+
fetch: yield* appInvocationFetch(signal),
|
|
1179
|
+
signal,
|
|
1180
|
+
...deadline === void 0 ? {} : { deadline }
|
|
1181
|
+
});
|
|
1182
|
+
})
|
|
1183
|
+
).pipe(
|
|
1184
|
+
Effect_exports.catchCause((cause) => {
|
|
1185
|
+
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
1186
|
+
const error = Cause_exports.squash(cause);
|
|
1187
|
+
const status = Schema_exports.decodeUnknownOption(ResponseStatusError)(error);
|
|
1188
|
+
const classified = Option_exports.isSome(status) ? Option_exports.fromNullishOr(httpProviderError(status.value.status)) : parseProviderError(error);
|
|
1189
|
+
const secrets = accountSecrets(context.accounts);
|
|
1190
|
+
return Effect_exports.fail(
|
|
1191
|
+
Option_exports.isSome(classified) ? leavingProviderError(accountProviderError(classified.value, account.id), secrets) : new HostOperationFailed(failureDetail(error, secrets))
|
|
1192
|
+
);
|
|
1193
|
+
}),
|
|
1194
|
+
Effect_exports.withSpan("app.account.check")
|
|
1195
|
+
);
|
|
1196
|
+
return yield* safe2(
|
|
1197
|
+
() => Schema_exports.decodeUnknownEffect(AccountCheckResult)(result ?? {}).pipe(
|
|
1198
|
+
Effect_exports.flatMap(Schema_exports.encodeEffect(AccountCheckResult)),
|
|
1199
|
+
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
|
|
1200
|
+
),
|
|
1201
|
+
new HostOutputInvalid()
|
|
1202
|
+
);
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1071
1205
|
var parseSkillLoadFailed = (error) => Schema_exports.decodeUnknownOption(SkillLoadFailed)(error).pipe(
|
|
1072
1206
|
Option_exports.map(
|
|
1073
1207
|
({ reason, message, status }) => new SkillLoadFailed({
|
|
@@ -1077,11 +1211,6 @@ var parseSkillLoadFailed = (error) => Schema_exports.decodeUnknownOption(SkillLo
|
|
|
1077
1211
|
})
|
|
1078
1212
|
)
|
|
1079
1213
|
);
|
|
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
1214
|
var errorStatus = Match_exports.type().pipe(
|
|
1086
1215
|
Match_exports.tagsExhaustive({
|
|
1087
1216
|
ProviderError: () => 502,
|
|
@@ -1093,11 +1222,14 @@ var errorStatus = Match_exports.type().pipe(
|
|
|
1093
1222
|
HostAccountsInvalid: () => 422,
|
|
1094
1223
|
HostInputInvalid: () => 422,
|
|
1095
1224
|
HostOperationNotFound: () => 404,
|
|
1225
|
+
HostKindMismatch: () => 409,
|
|
1096
1226
|
HostToolNotFound: () => 404,
|
|
1097
1227
|
HostToolBlocked: () => 403,
|
|
1098
1228
|
HostToolApprovalRequired: () => 409,
|
|
1099
1229
|
HostToolPolicyFailed: () => 500,
|
|
1100
1230
|
HostOperationFailed: () => 500,
|
|
1231
|
+
DatabaseLimitExceeded: () => 422,
|
|
1232
|
+
DatabaseFieldReserved: () => 422,
|
|
1101
1233
|
HostDeclarationInvalid: () => 500,
|
|
1102
1234
|
HostEvaluationFailed: () => 500,
|
|
1103
1235
|
HostOutputInvalid: () => 500,
|
|
@@ -1124,6 +1256,14 @@ var createAppHandler = (app) => (request, context) => Effect_exports.gen(functio
|
|
|
1124
1256
|
toolError = true;
|
|
1125
1257
|
}
|
|
1126
1258
|
}),
|
|
1259
|
+
// Name what failed on the span; the bounded message stays in the reply only.
|
|
1260
|
+
Effect_exports.tapError(
|
|
1261
|
+
(error) => (error._tag === "HostEvaluationFailed" || error._tag === "HostOperationFailed" || error._tag === "HostDeclarationInvalid") && error.errorName !== void 0 ? Effect_exports.annotateCurrentSpan({
|
|
1262
|
+
"error.type": error.errorName,
|
|
1263
|
+
...error.source === void 0 ? {} : { "executor.failure.source": error.source },
|
|
1264
|
+
...error.code === void 0 ? {} : { "executor.failure.code": error.code }
|
|
1265
|
+
}) : Effect_exports.void
|
|
1266
|
+
),
|
|
1127
1267
|
Effect_exports.withSpan(`app.${command.operation}`)
|
|
1128
1268
|
);
|
|
1129
1269
|
if (toolError)
|
|
@@ -1143,12 +1283,17 @@ var createAppHandler = (app) => (request, context) => Effect_exports.gen(functio
|
|
|
1143
1283
|
),
|
|
1144
1284
|
Effect_exports.catchCause(
|
|
1145
1285
|
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.logError(cause).pipe(
|
|
1146
|
-
Effect_exports.
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1286
|
+
Effect_exports.andThen(
|
|
1287
|
+
Schema_exports.encodeEffect(HostError)(
|
|
1288
|
+
declarationInvalid(
|
|
1289
|
+
"The app failed while it was loaded",
|
|
1290
|
+
Cause_exports.squash(cause),
|
|
1291
|
+
accountSecrets(context.accounts)
|
|
1292
|
+
)
|
|
1150
1293
|
)
|
|
1151
|
-
)
|
|
1294
|
+
),
|
|
1295
|
+
Effect_exports.map((error) => Response.json({ ok: false, error }, { status: 500 })),
|
|
1296
|
+
Effect_exports.orDie
|
|
1152
1297
|
)
|
|
1153
1298
|
)
|
|
1154
1299
|
);
|