apps 0.0.1-beta.4 → 0.0.1-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -43
- package/framework-reference.json +1 -1
- package/js/{chunk-SATWJKN6.js → chunk-27F7W2LG.js} +1 -1
- package/js/{chunk-HDJH3RPR.js → chunk-57RKNWL2.js} +2 -2
- package/js/{chunk-WFSQXYUT.js → chunk-5T57N25Q.js} +15 -3
- package/js/{chunk-EQB7JMAL.js → chunk-6BSSI67S.js} +8 -8
- package/js/{chunk-3M2MEDNL.js → chunk-B3EOZTK3.js} +351 -33
- package/js/{chunk-FW5HBOIK.js → chunk-CDL5PM2Q.js} +307 -169
- package/js/{chunk-Z5NMEGJN.js → chunk-ECQFRCH4.js} +21 -9
- package/js/{chunk-G7ZIRKMK.js → chunk-IJX4CYZO.js} +3 -3
- package/js/{chunk-FDNTX5QJ.js → chunk-IPI4MFSN.js} +2 -2
- package/js/{chunk-2VPJHFOU.js → chunk-ITM77QPO.js} +28 -9
- package/js/{chunk-YEJOQEII.js → chunk-JU7VHODU.js} +1 -1
- package/js/{chunk-NQ3OMCA5.js → chunk-KUMBKVJD.js} +2 -2
- package/js/{chunk-EVJUVWN2.js → chunk-M3B3DE4K.js} +2 -2
- package/js/{chunk-ZJWDMTE3.js → chunk-MKWZPDR6.js} +3 -3
- package/js/chunk-MNMNLXBL.js +507 -0
- package/js/{chunk-BMOIAIVR.js → chunk-N7YDVXYJ.js} +49 -1
- package/js/{chunk-D47C7KG5.js → chunk-NKLWZJLE.js} +2 -2
- package/js/{chunk-DHUDODG5.js → chunk-OE3QQTSB.js} +41 -32
- package/js/{chunk-M6ZRRIBI.js → chunk-PJJ24GU7.js} +1 -1
- package/js/{chunk-FZJOYIZO.js → chunk-PZB6T6KU.js} +1 -1
- package/js/{chunk-LGIYBDWA.js → chunk-R3EV5FTO.js} +13 -1
- package/js/{chunk-5MQZEB6Y.js → chunk-RFVIONFX.js} +29 -12
- package/js/{chunk-ZCAMUXSG.js → chunk-RJDDBDSN.js} +3 -3
- package/js/{chunk-6VRYO2BG.js → chunk-SB4HEPNJ.js} +191 -170
- package/js/chunk-T7GKZBLP.js +209 -0
- package/js/{chunk-QKHR7BMF.js → chunk-UK573G7W.js} +1 -1
- package/js/{chunk-T2LAZCAD.js → chunk-VFZKSM3T.js} +1 -1
- package/js/{chunk-PLCMJREA.js → chunk-ZQINWV4W.js} +60 -20
- package/js/client.js +10 -10
- package/js/contracts.js +52 -16
- package/js/effect.js +19 -20
- package/js/graphql.js +34 -40
- package/js/host.js +19 -20
- package/js/index.js +189 -178
- package/js/mcp/effect.js +21 -22
- package/js/mcp/stdio.js +25 -26
- package/js/mcp.js +60 -45
- package/js/openapi.js +182 -224
- package/js/react.js +3 -3
- package/js/skills/effect.js +3 -3
- package/js/skills.js +12 -13
- 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 +4 -4
- package/js/ui/serving.js +8 -8
- 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/app.d.ts +2 -5
- package/types/apps/src/contracts/failure.d.ts +25 -0
- package/types/apps/src/contracts/host.d.ts +18 -9
- package/types/apps/src/contracts/mcp.d.ts +16 -0
- package/types/apps/src/contracts/openapi.d.ts +5 -1
- package/types/apps/src/contracts/operations.d.ts +0 -5
- package/types/apps/src/contracts/protocol-version.d.ts +2 -2
- package/types/apps/src/contracts/protocols/1.d.ts +15 -1
- package/types/apps/src/contracts/protocols/2.d.ts +2 -2
- package/types/apps/src/contracts/protocols/3.d.ts +676 -0
- package/types/apps/src/contracts/protocols/4.d.ts +1229 -0
- package/types/apps/src/contracts/router.d.ts +59 -0
- package/types/apps/src/contracts/storage.d.ts +3 -3
- 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/catalog-cache.d.ts +9 -2
- package/types/apps/src/implementation/elicitation.d.ts +1 -1
- package/types/apps/src/implementation/failure-detail.d.ts +25 -0
- package/types/apps/src/implementation/graphql-catalog.d.ts +1 -4
- package/types/apps/src/implementation/mcp-catalog.d.ts +1 -4
- package/types/apps/src/implementation/mcp-client.d.ts +35 -19
- package/types/apps/src/implementation/mcp.d.ts +35 -19
- package/types/apps/src/implementation/openapi-compile.d.ts +2 -1
- package/types/apps/src/implementation/openapi-source.d.ts +2 -6
- package/types/apps/src/implementation/operations.d.ts +26 -3
- package/types/apps/src/implementation/protocol-operations.d.ts +3 -4
- package/types/apps/src/implementation/router-catalog.d.ts +225 -0
- package/types/apps/src/implementation/router.d.ts +59 -0
- package/types/apps/src/implementation/schema.d.ts +5 -1
- package/types/apps/src/implementation/storage.d.ts +5 -3
- 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 +3 -2
- package/types/apps/src/mcp-stdio.d.ts +2 -5
- package/types/apps/src/mcp.d.ts +5 -4
- package/types/apps/src/openapi.d.ts +6 -6
- package/js/chunk-PYUYJRSK.js +0 -93
- package/js/chunk-SWPD52J7.js +0 -35
- package/js/chunk-W7D7WVSY.js +0 -18
- 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,23 +1,36 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeCache
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NKLWZJLE.js";
|
|
4
|
+
import {
|
|
5
|
+
accountSecrets,
|
|
6
|
+
boundFailureMessage,
|
|
7
|
+
describeFailure,
|
|
8
|
+
failureDetail,
|
|
9
|
+
readCatalog,
|
|
10
|
+
routerSkills
|
|
11
|
+
} from "./chunk-MNMNLXBL.js";
|
|
4
12
|
import {
|
|
5
13
|
folderSkillsEffect
|
|
6
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-IPI4MFSN.js";
|
|
7
15
|
import {
|
|
8
16
|
authorDatabase,
|
|
9
17
|
isApp,
|
|
10
18
|
toEffectApp,
|
|
11
19
|
unavailableStorage
|
|
12
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-OE3QQTSB.js";
|
|
21
|
+
import {
|
|
22
|
+
parseDatabaseSchema
|
|
23
|
+
} from "./chunk-ZQINWV4W.js";
|
|
13
24
|
import {
|
|
25
|
+
declaredOperations,
|
|
14
26
|
fromPromise,
|
|
27
|
+
locate,
|
|
15
28
|
nativeOperation,
|
|
16
29
|
toPromise
|
|
17
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-T7GKZBLP.js";
|
|
18
31
|
import {
|
|
19
32
|
parseProviderError
|
|
20
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-MKWZPDR6.js";
|
|
21
34
|
import {
|
|
22
35
|
DeclaredProvider,
|
|
23
36
|
DeclaredRequirements,
|
|
@@ -29,6 +42,7 @@ import {
|
|
|
29
42
|
HostError,
|
|
30
43
|
HostEvaluationFailed,
|
|
31
44
|
HostInputInvalid,
|
|
45
|
+
HostKindMismatch,
|
|
32
46
|
HostOperationFailed,
|
|
33
47
|
HostOperationNotFound,
|
|
34
48
|
HostOutputInvalid,
|
|
@@ -38,6 +52,7 @@ import {
|
|
|
38
52
|
HostToolBlocked,
|
|
39
53
|
HostToolNotFound,
|
|
40
54
|
HostToolPolicyFailed,
|
|
55
|
+
HostedRouter,
|
|
41
56
|
HostedTool,
|
|
42
57
|
HostedToolSummary,
|
|
43
58
|
HostedWebhook,
|
|
@@ -47,7 +62,7 @@ import {
|
|
|
47
62
|
ManyAccounts,
|
|
48
63
|
McpError,
|
|
49
64
|
NonRetryableError,
|
|
50
|
-
|
|
65
|
+
OpenapiResponseError,
|
|
51
66
|
ResolvedAccounts,
|
|
52
67
|
ToolResultObservation,
|
|
53
68
|
TrustedToolApproval,
|
|
@@ -62,31 +77,29 @@ import {
|
|
|
62
77
|
defaultWebhookTransportLimits,
|
|
63
78
|
maxInputProblems,
|
|
64
79
|
workflowDurationMillis
|
|
65
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-B3EOZTK3.js";
|
|
66
81
|
import {
|
|
67
82
|
CacheError
|
|
68
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-R3EV5FTO.js";
|
|
69
84
|
import {
|
|
70
85
|
AppSkills,
|
|
71
86
|
SkillFile,
|
|
72
87
|
SkillLoadFailed
|
|
73
|
-
} from "./chunk-
|
|
74
|
-
import {
|
|
75
|
-
OpenapiResponseError
|
|
76
|
-
} from "./chunk-SWPD52J7.js";
|
|
88
|
+
} from "./chunk-JU7VHODU.js";
|
|
77
89
|
import {
|
|
78
90
|
captureTelemetry,
|
|
79
91
|
invocationFetch
|
|
80
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-RJDDBDSN.js";
|
|
81
93
|
import {
|
|
82
94
|
decoderOf,
|
|
83
95
|
importedJsonSchema,
|
|
84
|
-
jsonSchemaDecoder
|
|
85
|
-
|
|
96
|
+
jsonSchemaDecoder,
|
|
97
|
+
jsonSchemaDocument
|
|
98
|
+
} from "./chunk-5T57N25Q.js";
|
|
86
99
|
import {
|
|
87
100
|
JsonObject,
|
|
88
101
|
JsonValue
|
|
89
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-27F7W2LG.js";
|
|
90
103
|
import {
|
|
91
104
|
Cause_exports,
|
|
92
105
|
Clock_exports,
|
|
@@ -98,7 +111,7 @@ import {
|
|
|
98
111
|
SchemaIssue_exports,
|
|
99
112
|
Schema_exports,
|
|
100
113
|
Stream_exports
|
|
101
|
-
} from "./chunk-
|
|
114
|
+
} from "./chunk-CDL5PM2Q.js";
|
|
102
115
|
|
|
103
116
|
// src/implementation/elicitation.ts
|
|
104
117
|
var prepareElicitation = (input) => Effect_exports.gen(function* () {
|
|
@@ -139,19 +152,29 @@ var makeElicit = (handler, signal) => toPromise(
|
|
|
139
152
|
var ApprovalDecision = Schema_exports.Literals(["approved", "denied", "user-approval"]);
|
|
140
153
|
|
|
141
154
|
// src/implementation/workflow-context.ts
|
|
142
|
-
var workflowSafe = (work) => work.pipe(
|
|
155
|
+
var workflowSafe = (work, secrets) => work.pipe(
|
|
143
156
|
Effect_exports.catchCause((cause) => {
|
|
144
157
|
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
145
158
|
const error = Cause_exports.squash(cause);
|
|
146
159
|
if (Schema_exports.is(WorkflowFailure)(error)) return Effect_exports.fail(error);
|
|
160
|
+
const { errorName, message } = failureDetail(error, secrets);
|
|
147
161
|
return Effect_exports.fail(
|
|
148
162
|
new WorkflowFailure({
|
|
149
163
|
reason: "execution",
|
|
150
|
-
retryable: !(error instanceof NonRetryableError)
|
|
164
|
+
retryable: !(error instanceof NonRetryableError),
|
|
165
|
+
...errorName === void 0 ? {} : { errorName },
|
|
166
|
+
...message === void 0 ? {} : { message }
|
|
151
167
|
})
|
|
152
168
|
);
|
|
153
169
|
})
|
|
154
170
|
);
|
|
171
|
+
var inStep = (step) => (failure) => failure.step === void 0 ? new WorkflowFailure({
|
|
172
|
+
reason: failure.reason,
|
|
173
|
+
retryable: failure.retryable,
|
|
174
|
+
step: step.slice(0, 200),
|
|
175
|
+
...failure.errorName === void 0 ? {} : { errorName: failure.errorName },
|
|
176
|
+
...failure.message.length === 0 ? {} : { message: failure.message }
|
|
177
|
+
}) : failure;
|
|
155
178
|
var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_exports.gen(function* () {
|
|
156
179
|
const services = yield* Effect_exports.context();
|
|
157
180
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -206,25 +229,33 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
|
|
|
206
229
|
Effect_exports.sync(() => new AbortController()),
|
|
207
230
|
(controller2) => Effect_exports.sync(() => controller2.abort())
|
|
208
231
|
);
|
|
209
|
-
const
|
|
232
|
+
const step2 = yield* fresh(stepId, AbortSignal.any([signal, controller.signal]));
|
|
210
233
|
const result = yield* workflowSafe(
|
|
211
|
-
Effect_exports.tryPromise({
|
|
234
|
+
Effect_exports.tryPromise({
|
|
235
|
+
try: () => callback(step2.context),
|
|
236
|
+
catch: (error) => error
|
|
237
|
+
}),
|
|
238
|
+
step2.secrets
|
|
212
239
|
);
|
|
213
240
|
return yield* Schema_exports.decodeUnknownEffect(WorkflowValue)(result).pipe(
|
|
214
241
|
Effect_exports.mapError(
|
|
215
|
-
() => new WorkflowFailure({
|
|
242
|
+
() => new WorkflowFailure({
|
|
243
|
+
reason: "output",
|
|
244
|
+
retryable: false,
|
|
245
|
+
message: "The step returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
|
|
246
|
+
})
|
|
216
247
|
)
|
|
217
248
|
);
|
|
218
249
|
})
|
|
219
250
|
).pipe(Effect_exports.provideContext(services))
|
|
220
251
|
)
|
|
221
|
-
);
|
|
252
|
+
).pipe(Effect_exports.mapError(inStep(name)));
|
|
222
253
|
});
|
|
223
254
|
const operationStep = (kind, name, operation, input, options) => Effect_exports.gen(function* () {
|
|
224
255
|
const target = nativeOperation(operation);
|
|
225
|
-
const
|
|
226
|
-
const match =
|
|
227
|
-
(
|
|
256
|
+
const root = definition.tools?.kind === "router" ? definition.tools : void 0;
|
|
257
|
+
const match = declaredOperations(root).find(
|
|
258
|
+
(entry) => entry.operation === target && entry.operation.kind === kind
|
|
228
259
|
);
|
|
229
260
|
if (target === void 0 || match === void 0)
|
|
230
261
|
return yield* new WorkflowFailure({ reason: "operation", retryable: false });
|
|
@@ -243,9 +274,9 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
|
|
|
243
274
|
parsed,
|
|
244
275
|
() => attempt(
|
|
245
276
|
parsed,
|
|
246
|
-
execution.invoke({ kind, name: match
|
|
277
|
+
execution.invoke({ kind, name: match.name, input: args, stepId, timeout }).pipe(Effect_exports.provideContext(services))
|
|
247
278
|
)
|
|
248
|
-
);
|
|
279
|
+
).pipe(Effect_exports.mapError(inStep(name)));
|
|
249
280
|
});
|
|
250
281
|
const invoke = (effect) => toPromise(() => effect.pipe(Effect_exports.provideContext(services)), signal)();
|
|
251
282
|
const step = {
|
|
@@ -523,6 +554,10 @@ var authorCache = (host, accounts, signal, deadline) => {
|
|
|
523
554
|
};
|
|
524
555
|
|
|
525
556
|
// src/implementation/host.ts
|
|
557
|
+
var WireCatalog = Schema_exports.Struct({
|
|
558
|
+
tools: Schema_exports.Array(Schema_exports.Union([HostedTool, HostedToolSummary])),
|
|
559
|
+
routers: Schema_exports.Array(HostedRouter)
|
|
560
|
+
});
|
|
526
561
|
function safe2(work, failure) {
|
|
527
562
|
return Effect_exports.suspend(work).pipe(
|
|
528
563
|
Effect_exports.catchCause(
|
|
@@ -530,7 +565,7 @@ function safe2(work, failure) {
|
|
|
530
565
|
)
|
|
531
566
|
);
|
|
532
567
|
}
|
|
533
|
-
var evaluationSafe = (work) => work.pipe(
|
|
568
|
+
var evaluationSafe = (work, secrets) => work.pipe(
|
|
534
569
|
Effect_exports.catchCause((cause) => {
|
|
535
570
|
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
536
571
|
const error = Cause_exports.squash(cause);
|
|
@@ -538,22 +573,25 @@ var evaluationSafe = (work) => work.pipe(
|
|
|
538
573
|
const skills = parseSkillLoadFailed(error);
|
|
539
574
|
const mcp = parseMcpError(error);
|
|
540
575
|
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()
|
|
576
|
+
Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(skills) ? skills.value : Option_exports.isSome(mcp) ? mcp.value : new HostEvaluationFailed(failureDetail(error, secrets))
|
|
542
577
|
);
|
|
543
578
|
})
|
|
544
579
|
);
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
580
|
+
var declarationInvalid = (summary, cause, secrets = []) => new HostDeclarationInvalid({
|
|
581
|
+
source: "app",
|
|
582
|
+
errorName: "HostDeclarationInvalid",
|
|
583
|
+
message: boundFailureMessage(
|
|
584
|
+
cause === void 0 ? summary : `${summary}: ${describeFailure(cause)}`,
|
|
585
|
+
secrets
|
|
586
|
+
)
|
|
587
|
+
});
|
|
588
|
+
var declarationSafe = (work, summary) => Effect_exports.suspend(work).pipe(
|
|
589
|
+
Effect_exports.catchCause(
|
|
590
|
+
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(declarationInvalid(summary, Cause_exports.squash(cause)))
|
|
591
|
+
)
|
|
592
|
+
);
|
|
555
593
|
function providerDeclaration(provider) {
|
|
556
|
-
return
|
|
594
|
+
return declarationSafe(
|
|
557
595
|
() => Effect_exports.gen(function* () {
|
|
558
596
|
const auth = /* @__PURE__ */ new Map();
|
|
559
597
|
for (const [name, method] of Object.entries(provider.auth)) {
|
|
@@ -562,14 +600,14 @@ function providerDeclaration(provider) {
|
|
|
562
600
|
auth.set(name, {
|
|
563
601
|
type: "secrets",
|
|
564
602
|
label: method.label,
|
|
565
|
-
fields: yield*
|
|
603
|
+
fields: yield* jsonSchemaDocument(method.fields)
|
|
566
604
|
});
|
|
567
605
|
break;
|
|
568
606
|
case "oauth2":
|
|
569
607
|
auth.set(name, {
|
|
570
608
|
type: "oauth2",
|
|
571
609
|
...method.config,
|
|
572
|
-
response: yield*
|
|
610
|
+
response: yield* jsonSchemaDocument(method.response)
|
|
573
611
|
});
|
|
574
612
|
break;
|
|
575
613
|
}
|
|
@@ -579,7 +617,7 @@ function providerDeclaration(provider) {
|
|
|
579
617
|
auth: Object.fromEntries(auth)
|
|
580
618
|
});
|
|
581
619
|
}),
|
|
582
|
-
|
|
620
|
+
`Account provider "${provider.name}" has an invalid declaration`
|
|
583
621
|
);
|
|
584
622
|
}
|
|
585
623
|
function requirements(slots, database) {
|
|
@@ -597,7 +635,11 @@ function requirements(slots, database) {
|
|
|
597
635
|
accounts: Object.fromEntries(accounts),
|
|
598
636
|
capabilities: { skills: true, toolIndex: true, skillSources: true, scheduledTools: true },
|
|
599
637
|
...database === void 0 ? {} : { database }
|
|
600
|
-
}).pipe(
|
|
638
|
+
}).pipe(
|
|
639
|
+
Effect_exports.mapError(
|
|
640
|
+
(cause) => declarationInvalid("The app's account or database declarations are invalid", cause)
|
|
641
|
+
)
|
|
642
|
+
);
|
|
601
643
|
});
|
|
602
644
|
}
|
|
603
645
|
function canonical(value) {
|
|
@@ -656,14 +698,29 @@ function bindAccounts(slots, declarations, context) {
|
|
|
656
698
|
function dispatch(app, request, context, signal) {
|
|
657
699
|
return Effect_exports.scoped(
|
|
658
700
|
Effect_exports.gen(function* () {
|
|
659
|
-
if (!isApp(app))
|
|
701
|
+
if (!isApp(app))
|
|
702
|
+
return yield* Effect_exports.fail(
|
|
703
|
+
declarationInvalid("The app module's default export is not an app created by defineApp")
|
|
704
|
+
);
|
|
660
705
|
const native = toEffectApp(app);
|
|
706
|
+
const secrets = accountSecrets(context.accounts);
|
|
707
|
+
const storageFailure = (error) => Effect_exports.fail(new HostOperationFailed(failureDetail(error, secrets)));
|
|
661
708
|
const declared = yield* requirements(native.accounts, native.database?.schema);
|
|
662
|
-
if (request.operation === "requirements")
|
|
709
|
+
if (request.operation === "requirements") {
|
|
710
|
+
if (native.database !== void 0)
|
|
711
|
+
yield* parseDatabaseSchema(native.database.schema).pipe(
|
|
712
|
+
Effect_exports.catchTag(
|
|
713
|
+
"AppDatabaseError",
|
|
714
|
+
(cause) => Effect_exports.fail(
|
|
715
|
+
declarationInvalid("The app's account or database declarations are invalid", cause)
|
|
716
|
+
)
|
|
717
|
+
)
|
|
718
|
+
);
|
|
663
719
|
return yield* safe2(
|
|
664
720
|
() => Schema_exports.decodeUnknownEffect(JsonValue)(declared),
|
|
665
721
|
new HostDeclarationInvalid()
|
|
666
722
|
);
|
|
723
|
+
}
|
|
667
724
|
const lifetime = yield* Effect_exports.acquireRelease(
|
|
668
725
|
Effect_exports.sync(() => new AbortController()),
|
|
669
726
|
(controller) => Effect_exports.sync(() => controller.abort())
|
|
@@ -747,34 +804,40 @@ function dispatch(app, request, context, signal) {
|
|
|
747
804
|
fetch: yield* invocationFetch(invocationSignal),
|
|
748
805
|
elicit: makeElicit(delivery, invocationSignal)
|
|
749
806
|
};
|
|
750
|
-
const definition = yield* evaluationSafe(native.evaluate(bound)).pipe(
|
|
807
|
+
const definition = yield* evaluationSafe(native.evaluate(bound), secrets).pipe(
|
|
751
808
|
Effect_exports.withSpan("app.evaluate")
|
|
752
809
|
);
|
|
753
810
|
if (request.operation === "skills") {
|
|
754
811
|
const declared2 = definition.skills ?? (yield* folderSkillsEffect({ files }).pipe(
|
|
755
812
|
Effect_exports.mapError(() => new HostDeclarationInvalid())
|
|
756
813
|
));
|
|
757
|
-
const
|
|
814
|
+
const source = definition.dynamicSkills;
|
|
758
815
|
const before = cacheCommands;
|
|
759
|
-
const dynamic =
|
|
816
|
+
const dynamic = source === void 0 ? [] : yield* evaluationSafe(Effect_exports.suspend(source.list), secrets).pipe(
|
|
760
817
|
Effect_exports.withSpan("app.skills.load")
|
|
761
818
|
);
|
|
762
|
-
const cached =
|
|
763
|
-
const
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
819
|
+
const cached = source !== void 0 && cacheCommands > before;
|
|
820
|
+
const authored = new Set([...declared2, ...dynamic].map((skill) => skill.name));
|
|
821
|
+
const routed = (yield* routerSkills(definition.tools).pipe(
|
|
822
|
+
Effect_exports.withSpan("app.skills.routers")
|
|
823
|
+
)).filter((skill) => !authored.has(skill.name));
|
|
824
|
+
const skills = yield* Schema_exports.decodeUnknownEffect(AppSkills)([
|
|
825
|
+
...declared2,
|
|
826
|
+
...dynamic,
|
|
827
|
+
...routed
|
|
828
|
+
]).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
|
|
829
|
+
return request.sources === true ? { skills, dynamic: source !== void 0, cached } : skills;
|
|
767
830
|
}
|
|
768
831
|
if (request.operation === "workflows") {
|
|
769
832
|
return yield* Effect_exports.forEach(
|
|
770
833
|
Object.entries(definition.workflows ?? {}),
|
|
771
|
-
([
|
|
834
|
+
([name, entry]) => safe2(
|
|
772
835
|
() => Effect_exports.gen(function* () {
|
|
773
836
|
return yield* Schema_exports.decodeUnknownEffect(HostedWorkflow)({
|
|
774
|
-
name
|
|
837
|
+
name,
|
|
775
838
|
...entry.description === void 0 ? {} : { description: entry.description },
|
|
776
|
-
inputSchema: yield*
|
|
777
|
-
...entry.output === void 0 ? {} : { outputSchema: yield*
|
|
839
|
+
inputSchema: yield* jsonSchemaDocument(entry.input),
|
|
840
|
+
...entry.output === void 0 ? {} : { outputSchema: yield* jsonSchemaDocument(entry.output) }
|
|
778
841
|
});
|
|
779
842
|
}),
|
|
780
843
|
new HostDeclarationInvalid()
|
|
@@ -807,108 +870,60 @@ function dispatch(app, request, context, signal) {
|
|
|
807
870
|
new WorkflowFailure({ reason: "credentials", retryable: false })
|
|
808
871
|
);
|
|
809
872
|
return {
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
873
|
+
context: {
|
|
874
|
+
...accounts,
|
|
875
|
+
cache: authorCache(
|
|
876
|
+
context.cache ?? unavailableCache,
|
|
877
|
+
Redacted_exports.value(current.accounts),
|
|
878
|
+
signal2
|
|
879
|
+
),
|
|
880
|
+
files,
|
|
881
|
+
fetch: yield* invocationFetch(signal2),
|
|
882
|
+
signal: signal2,
|
|
883
|
+
runId: execution.runId,
|
|
884
|
+
stepId,
|
|
885
|
+
idempotencyKey: stepId
|
|
886
|
+
},
|
|
887
|
+
// The resolved values, not the app's decoded fields, which may be `Redacted`.
|
|
888
|
+
secrets: accountSecrets(current.accounts)
|
|
822
889
|
};
|
|
823
890
|
}),
|
|
824
891
|
invocationSignal
|
|
825
892
|
);
|
|
826
|
-
const output = yield* workflowSafe(entry.run(workflowContext, input2));
|
|
893
|
+
const output = yield* workflowSafe(entry.run(workflowContext, input2), secrets);
|
|
827
894
|
const outputSchema = entry.output;
|
|
828
895
|
const decoded = outputSchema === void 0 ? output : yield* safe2(
|
|
829
896
|
() => Schema_exports.decodeUnknownEffect(outputSchema)(output),
|
|
830
|
-
new WorkflowFailure({
|
|
897
|
+
new WorkflowFailure({
|
|
898
|
+
reason: "output",
|
|
899
|
+
retryable: false,
|
|
900
|
+
message: "The workflow's result does not match its declared output schema."
|
|
901
|
+
})
|
|
831
902
|
);
|
|
832
903
|
return yield* safe2(
|
|
833
904
|
() => Schema_exports.decodeUnknownEffect(WorkflowValue)(decoded),
|
|
834
|
-
new WorkflowFailure({
|
|
905
|
+
new WorkflowFailure({
|
|
906
|
+
reason: "output",
|
|
907
|
+
retryable: false,
|
|
908
|
+
message: "The workflow returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
|
|
909
|
+
})
|
|
835
910
|
);
|
|
836
911
|
}
|
|
837
912
|
if (request.operation === "inspect") {
|
|
838
913
|
const summary = request.detail === "summary";
|
|
839
|
-
const
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
const fields = {
|
|
853
|
-
name: `${prefix}${name2}`,
|
|
854
|
-
schedules,
|
|
855
|
-
description: operation.description ?? `${readOnly ? "Query" : "Mutate"} ${name2}`,
|
|
856
|
-
...operation.title === void 0 ? {} : { title: operation.title },
|
|
857
|
-
readOnly,
|
|
858
|
-
annotations: { ...operation.annotations, readOnlyHint: readOnly }
|
|
859
|
-
};
|
|
860
|
-
if (summary)
|
|
861
|
-
return yield* Schema_exports.decodeUnknownEffect(HostedToolSummary)(fields);
|
|
862
|
-
return yield* Schema_exports.decodeUnknownEffect(HostedTool)({
|
|
863
|
-
...fields,
|
|
864
|
-
inputSchema: yield* jsonSchema(operation.input),
|
|
865
|
-
...operation.output === void 0 ? operation.outputSchema === void 0 ? {} : { outputSchema: operation.outputSchema } : { outputSchema: yield* jsonSchema(operation.output) },
|
|
866
|
-
...operation._meta === void 0 ? {} : { _meta: operation._meta }
|
|
867
|
-
});
|
|
868
|
-
}),
|
|
869
|
-
new HostDeclarationInvalid()
|
|
870
|
-
)
|
|
871
|
-
);
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
const dynamic = request.scheduled === true ? void 0 : definition.dynamicTools;
|
|
875
|
-
if (dynamic !== void 0 && (wanted === void 0 || metadata.length < wanted.size)) {
|
|
876
|
-
const declared2 = new Set(metadata.map((tool2) => tool2.name));
|
|
877
|
-
const discover = () => {
|
|
878
|
-
if (summary && dynamic.summaries !== void 0) return dynamic.summaries();
|
|
879
|
-
if (wanted !== void 0 && dynamic.describe !== void 0) {
|
|
880
|
-
const describe = dynamic.describe;
|
|
881
|
-
return Effect_exports.forEach(
|
|
882
|
-
[...wanted].filter((name2) => !declared2.has(name2)),
|
|
883
|
-
(name2) => describe(name2),
|
|
884
|
-
{ concurrency: "unbounded" }
|
|
885
|
-
).pipe(Effect_exports.map((tools) => tools.filter((tool2) => tool2 !== void 0)));
|
|
886
|
-
}
|
|
887
|
-
return dynamic.list();
|
|
888
|
-
};
|
|
889
|
-
const discovered = yield* evaluationSafe(discover()).pipe(
|
|
890
|
-
Effect_exports.flatMap(
|
|
891
|
-
(value) => safe2(
|
|
892
|
-
() => summary ? Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedToolSummary))(value) : Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedTool))(value),
|
|
893
|
-
new HostDeclarationInvalid()
|
|
894
|
-
)
|
|
895
|
-
)
|
|
896
|
-
);
|
|
897
|
-
const names = new Set(declared2);
|
|
898
|
-
for (const tool2 of discovered) {
|
|
899
|
-
const readOnly = tool2.name.startsWith(OperationToolPrefixes.query);
|
|
900
|
-
if (!readOnly && !tool2.name.startsWith(OperationToolPrefixes.mutate) || tool2.name === OperationToolPrefixes.query || tool2.name === OperationToolPrefixes.mutate || names.has(tool2.name))
|
|
901
|
-
return yield* new HostDeclarationInvalid();
|
|
902
|
-
names.add(tool2.name);
|
|
903
|
-
if (wanted !== void 0 && !wanted.has(tool2.name)) continue;
|
|
904
|
-
metadata.push({
|
|
905
|
-
...tool2,
|
|
906
|
-
readOnly,
|
|
907
|
-
annotations: { ...tool2.annotations, readOnlyHint: readOnly }
|
|
908
|
-
});
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
return metadata;
|
|
914
|
+
const catalog = yield* readCatalog(definition.tools, {
|
|
915
|
+
summary,
|
|
916
|
+
secrets,
|
|
917
|
+
...request.tools === void 0 ? {} : { wanted: new Set(request.tools) },
|
|
918
|
+
...request.scheduled === true ? { scheduled: true } : {},
|
|
919
|
+
schedules: (name) => Object.entries(definition.schedules ?? {}).filter(([, schedule]) => schedule.tool === name).map(([name2, { tool: _tool, ...schedule }]) => ({ name: name2, ...schedule }))
|
|
920
|
+
}).pipe(Effect_exports.withSpan("app.catalog.read"));
|
|
921
|
+
return yield* safe2(
|
|
922
|
+
() => Schema_exports.encodeEffect(WireCatalog)(catalog).pipe(
|
|
923
|
+
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
|
|
924
|
+
),
|
|
925
|
+
new HostDeclarationInvalid()
|
|
926
|
+
);
|
|
912
927
|
}
|
|
913
928
|
if (request.operation === "webhook-complete" || request.operation === "webhook-validate" || request.operation === "webhooks" || request.operation === "webhook-register" || request.operation === "webhook-handle" || request.operation === "webhook-unregister") {
|
|
914
929
|
const executeWebhook = (db) => dispatchWebhook(
|
|
@@ -932,25 +947,22 @@ function dispatch(app, request, context, signal) {
|
|
|
932
947
|
const storage2 = context.storage ?? unavailableStorage;
|
|
933
948
|
return yield* storage2.mutate(native.database.schema, executeWebhook).pipe(
|
|
934
949
|
Effect_exports.catchTags({
|
|
935
|
-
AppDatabaseError:
|
|
936
|
-
|
|
937
|
-
|
|
950
|
+
AppDatabaseError: storageFailure,
|
|
951
|
+
DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
|
|
952
|
+
AppStorageUnavailable: storageFailure,
|
|
953
|
+
AppStorageError: storageFailure
|
|
938
954
|
})
|
|
939
955
|
);
|
|
940
956
|
}
|
|
941
|
-
const
|
|
942
|
-
|
|
943
|
-
const
|
|
944
|
-
const toolName = `${OperationToolPrefixes[kind]}${name}`;
|
|
945
|
-
const catalog = kind === "query" ? definition.queries : definition.mutations;
|
|
946
|
-
const declaredTool = catalog !== void 0 && Object.hasOwn(catalog, name) ? catalog[name] : void 0;
|
|
947
|
-
const source = definition.dynamicTools;
|
|
948
|
-
const resolvedTool = source === void 0 || declaredTool !== void 0 ? void 0 : yield* evaluationSafe(source.resolve(toolName));
|
|
949
|
-
const tool = declaredTool ?? resolvedTool;
|
|
950
|
-
if (tool !== void 0 && tool.kind !== (kind === "query" ? "query" : "mutation"))
|
|
951
|
-
return yield* new HostDeclarationInvalid();
|
|
957
|
+
const toolName = request.operation === "call" ? request.tool : request.name;
|
|
958
|
+
const location = locate(definition.tools, toolName);
|
|
959
|
+
const tool = location === void 0 ? void 0 : location.kind === "operation" ? location.operation : yield* evaluationSafe(location.source.resolve(location.name), secrets);
|
|
952
960
|
if (tool === void 0)
|
|
953
961
|
return yield* request.operation === "call" ? new HostToolNotFound() : new HostOperationNotFound();
|
|
962
|
+
const requested = request.operation === "call" ? request.kind : request.operation === "query" ? "query" : "mutation";
|
|
963
|
+
if (requested !== void 0 && tool.kind !== requested)
|
|
964
|
+
return yield* new HostKindMismatch({ tool: toolName, requested, actual: tool.kind });
|
|
965
|
+
const kind = tool.kind === "query" ? "query" : "mutate";
|
|
954
966
|
const input = yield* Effect_exports.suspend(
|
|
955
967
|
() => Schema_exports.decodeUnknownEffect(tool.input)(request.input)
|
|
956
968
|
).pipe(
|
|
@@ -1039,7 +1051,7 @@ function dispatch(app, request, context, signal) {
|
|
|
1039
1051
|
status: response.value.status,
|
|
1040
1052
|
message: response.value.message,
|
|
1041
1053
|
...response.value.recovery === void 0 ? {} : { recovery: response.value.recovery }
|
|
1042
|
-
}) : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed()
|
|
1054
|
+
}) : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed(failureDetail(error, secrets))
|
|
1043
1055
|
);
|
|
1044
1056
|
}),
|
|
1045
1057
|
Effect_exports.withSpan("app.operation.execute", {
|
|
@@ -1070,9 +1082,10 @@ function dispatch(app, request, context, signal) {
|
|
|
1070
1082
|
)
|
|
1071
1083
|
).pipe(
|
|
1072
1084
|
Effect_exports.catchTags({
|
|
1073
|
-
AppDatabaseError:
|
|
1074
|
-
|
|
1075
|
-
|
|
1085
|
+
AppDatabaseError: storageFailure,
|
|
1086
|
+
DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
|
|
1087
|
+
AppStorageUnavailable: storageFailure,
|
|
1088
|
+
AppStorageError: storageFailure
|
|
1076
1089
|
})
|
|
1077
1090
|
);
|
|
1078
1091
|
})
|
|
@@ -1103,11 +1116,14 @@ var errorStatus = Match_exports.type().pipe(
|
|
|
1103
1116
|
HostAccountsInvalid: () => 422,
|
|
1104
1117
|
HostInputInvalid: () => 422,
|
|
1105
1118
|
HostOperationNotFound: () => 404,
|
|
1119
|
+
HostKindMismatch: () => 409,
|
|
1106
1120
|
HostToolNotFound: () => 404,
|
|
1107
1121
|
HostToolBlocked: () => 403,
|
|
1108
1122
|
HostToolApprovalRequired: () => 409,
|
|
1109
1123
|
HostToolPolicyFailed: () => 500,
|
|
1110
1124
|
HostOperationFailed: () => 500,
|
|
1125
|
+
DatabaseLimitExceeded: () => 422,
|
|
1126
|
+
DatabaseFieldReserved: () => 422,
|
|
1111
1127
|
HostDeclarationInvalid: () => 500,
|
|
1112
1128
|
HostEvaluationFailed: () => 500,
|
|
1113
1129
|
HostOutputInvalid: () => 500,
|
|
@@ -1153,12 +1169,17 @@ var createAppHandler = (app) => (request, context) => Effect_exports.gen(functio
|
|
|
1153
1169
|
),
|
|
1154
1170
|
Effect_exports.catchCause(
|
|
1155
1171
|
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.logError(cause).pipe(
|
|
1156
|
-
Effect_exports.
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1172
|
+
Effect_exports.andThen(
|
|
1173
|
+
Schema_exports.encodeEffect(HostError)(
|
|
1174
|
+
declarationInvalid(
|
|
1175
|
+
"The app failed while it was loaded",
|
|
1176
|
+
Cause_exports.squash(cause),
|
|
1177
|
+
accountSecrets(context.accounts)
|
|
1178
|
+
)
|
|
1160
1179
|
)
|
|
1161
|
-
)
|
|
1180
|
+
),
|
|
1181
|
+
Effect_exports.map((error) => Response.json({ ok: false, error }, { status: 500 })),
|
|
1182
|
+
Effect_exports.orDie
|
|
1162
1183
|
)
|
|
1163
1184
|
)
|
|
1164
1185
|
);
|