apps 0.0.1-beta.5 → 0.0.1-beta.7
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-FWQC6I3C.js → chunk-5T57N25Q.js} +13 -1
- package/js/{chunk-TDNYXSIX.js → chunk-72JNVHPK.js} +21 -9
- package/js/{chunk-UDDE5KOR.js → chunk-CMYUWAX7.js} +26 -7
- package/js/chunk-FL2QR3XW.js +507 -0
- package/js/{chunk-G7T27IWB.js → chunk-MKWZPDR6.js} +1 -1
- package/js/{chunk-CYYBFC2K.js → chunk-NKLWZJLE.js} +1 -1
- package/js/{chunk-67EVWIGJ.js → chunk-OCYUEU47.js} +4 -4
- package/js/{chunk-YEPYT6SD.js → chunk-R3EV5FTO.js} +12 -0
- package/js/{chunk-XHO2ZX6W.js → chunk-RFVIONFX.js} +27 -10
- package/js/{chunk-LUVSFETN.js → chunk-UESPOTUI.js} +127 -231
- package/js/{chunk-DQAZTA4I.js → chunk-WLE7WX2U.js} +290 -20
- package/js/{chunk-C3VAOK5B.js → chunk-YXQHV65J.js} +53 -26
- package/js/chunk-Z5M2LQOZ.js +209 -0
- package/js/client.js +1 -1
- package/js/contracts.js +34 -11
- package/js/effect.js +9 -11
- package/js/graphql.js +25 -32
- package/js/host.js +9 -11
- package/js/index.js +194 -192
- package/js/mcp/effect.js +11 -13
- package/js/mcp/stdio.js +15 -17
- package/js/mcp.js +50 -36
- package/js/openapi.js +166 -108
- package/js/skills.js +6 -7
- package/package.json +1 -1
- package/runtime.json +1 -1
- package/types/apps/src/contracts/app.d.ts +2 -5
- package/types/apps/src/contracts/host.d.ts +19 -7
- package/types/apps/src/contracts/mcp.d.ts +16 -0
- package/types/apps/src/contracts/openapi.d.ts +4 -0
- 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/4.d.ts +1229 -0
- package/types/apps/src/contracts/protocols/5.d.ts +1090 -0
- package/types/apps/src/contracts/provider.d.ts +51 -5
- package/types/apps/src/contracts/router.d.ts +59 -0
- 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/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/provider.d.ts +9 -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/workflow-context.d.ts +1 -1
- package/types/apps/src/index.d.ts +5 -4
- 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-3XKZDQLM.js +0 -93
- package/js/chunk-4M277YTM.js +0 -136
- package/js/chunk-SB3V4YVR.js +0 -18
- package/js/chunk-W4DMKWAB.js +0 -35
- 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,30 +1,41 @@
|
|
|
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-FL2QR3XW.js";
|
|
4
12
|
import {
|
|
5
13
|
folderSkillsEffect
|
|
6
14
|
} from "./chunk-IPI4MFSN.js";
|
|
7
15
|
import {
|
|
8
|
-
|
|
9
|
-
} from "./chunk-4M277YTM.js";
|
|
10
|
-
import {
|
|
16
|
+
ResponseStatusError,
|
|
11
17
|
authorDatabase,
|
|
12
18
|
isApp,
|
|
13
19
|
toEffectApp,
|
|
14
20
|
unavailableStorage
|
|
15
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-YXQHV65J.js";
|
|
16
22
|
import {
|
|
17
23
|
parseDatabaseSchema
|
|
18
24
|
} from "./chunk-ZQINWV4W.js";
|
|
19
25
|
import {
|
|
26
|
+
declaredOperations,
|
|
20
27
|
fromPromise,
|
|
28
|
+
locate,
|
|
21
29
|
nativeOperation,
|
|
22
30
|
toPromise
|
|
23
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-Z5M2LQOZ.js";
|
|
24
32
|
import {
|
|
33
|
+
accountProviderError,
|
|
34
|
+
httpProviderError,
|
|
25
35
|
parseProviderError
|
|
26
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-MKWZPDR6.js";
|
|
27
37
|
import {
|
|
38
|
+
AccountCheckResult,
|
|
28
39
|
DeclaredProvider,
|
|
29
40
|
DeclaredRequirements,
|
|
30
41
|
ElicitationFailed,
|
|
@@ -35,6 +46,7 @@ import {
|
|
|
35
46
|
HostError,
|
|
36
47
|
HostEvaluationFailed,
|
|
37
48
|
HostInputInvalid,
|
|
49
|
+
HostKindMismatch,
|
|
38
50
|
HostOperationFailed,
|
|
39
51
|
HostOperationNotFound,
|
|
40
52
|
HostOutputInvalid,
|
|
@@ -44,6 +56,7 @@ import {
|
|
|
44
56
|
HostToolBlocked,
|
|
45
57
|
HostToolNotFound,
|
|
46
58
|
HostToolPolicyFailed,
|
|
59
|
+
HostedRouter,
|
|
47
60
|
HostedTool,
|
|
48
61
|
HostedToolSummary,
|
|
49
62
|
HostedWebhook,
|
|
@@ -53,7 +66,7 @@ import {
|
|
|
53
66
|
ManyAccounts,
|
|
54
67
|
McpError,
|
|
55
68
|
NonRetryableError,
|
|
56
|
-
|
|
69
|
+
OpenapiResponseError,
|
|
57
70
|
ResolvedAccounts,
|
|
58
71
|
ToolResultObservation,
|
|
59
72
|
TrustedToolApproval,
|
|
@@ -66,24 +79,17 @@ import {
|
|
|
66
79
|
WorkflowValue,
|
|
67
80
|
approvalElicitation,
|
|
68
81
|
defaultWebhookTransportLimits,
|
|
69
|
-
maxFailureMessageLength,
|
|
70
82
|
maxInputProblems,
|
|
71
83
|
workflowDurationMillis
|
|
72
|
-
} from "./chunk-
|
|
73
|
-
import {
|
|
74
|
-
AppDatabaseError
|
|
75
|
-
} from "./chunk-N7YDVXYJ.js";
|
|
84
|
+
} from "./chunk-WLE7WX2U.js";
|
|
76
85
|
import {
|
|
77
86
|
CacheError
|
|
78
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-R3EV5FTO.js";
|
|
79
88
|
import {
|
|
80
89
|
AppSkills,
|
|
81
90
|
SkillFile,
|
|
82
91
|
SkillLoadFailed
|
|
83
92
|
} from "./chunk-JU7VHODU.js";
|
|
84
|
-
import {
|
|
85
|
-
OpenapiResponseError
|
|
86
|
-
} from "./chunk-W4DMKWAB.js";
|
|
87
93
|
import {
|
|
88
94
|
captureTelemetry,
|
|
89
95
|
invocationFetch
|
|
@@ -91,12 +97,9 @@ import {
|
|
|
91
97
|
import {
|
|
92
98
|
decoderOf,
|
|
93
99
|
importedJsonSchema,
|
|
94
|
-
jsonSchemaDecoder
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
AppStorageError,
|
|
98
|
-
AppStorageUnavailable
|
|
99
|
-
} from "./chunk-PZB6T6KU.js";
|
|
100
|
+
jsonSchemaDecoder,
|
|
101
|
+
jsonSchemaDocument
|
|
102
|
+
} from "./chunk-5T57N25Q.js";
|
|
100
103
|
import {
|
|
101
104
|
JsonObject,
|
|
102
105
|
JsonValue
|
|
@@ -108,7 +111,6 @@ import {
|
|
|
108
111
|
Encoding_exports,
|
|
109
112
|
Match_exports,
|
|
110
113
|
Option_exports,
|
|
111
|
-
Predicate_exports,
|
|
112
114
|
Redacted_exports,
|
|
113
115
|
SchemaIssue_exports,
|
|
114
116
|
Schema_exports,
|
|
@@ -153,109 +155,18 @@ var makeElicit = (handler, signal) => toPromise(
|
|
|
153
155
|
// src/contracts/approval.ts
|
|
154
156
|
var ApprovalDecision = Schema_exports.Literals(["approved", "denied", "user-approval"]);
|
|
155
157
|
|
|
156
|
-
// src/implementation/failure-detail.ts
|
|
157
|
-
var storageMessages = {
|
|
158
|
-
schema: "The app's database schema is invalid.",
|
|
159
|
-
schema_changed: "The app's database schema changed during this operation. Retry it.",
|
|
160
|
-
table: "The operation used a table the app's database schema does not declare.",
|
|
161
|
-
index: "The operation used an index the table does not declare, or used it incorrectly.",
|
|
162
|
-
range: "The index range is invalid for the declared index.",
|
|
163
|
-
value: "A value does not match the table's declared field schema.",
|
|
164
|
-
readonly: "Queries cannot write. Move writes into a mutation.",
|
|
165
|
-
cursor: "The pagination cursor is invalid or belongs to a different query.",
|
|
166
|
-
limit: "The operation exceeded a per-invocation app data limit.",
|
|
167
|
-
closed: "The database session closed before this operation finished.",
|
|
168
|
-
storage: "App storage failed to complete the operation.",
|
|
169
|
-
replay: "A workflow step replayed with different input than its first run."
|
|
170
|
-
};
|
|
171
|
-
var minimumSecretLength = 6;
|
|
172
|
-
var secretValues = (value, found) => {
|
|
173
|
-
if (typeof value === "string") {
|
|
174
|
-
if (value.length >= minimumSecretLength) found.add(value);
|
|
175
|
-
} else if (Array.isArray(value)) for (const item of value) secretValues(item, found);
|
|
176
|
-
else if (Predicate_exports.isObject(value))
|
|
177
|
-
for (const item of Object.values(value)) secretValues(item, found);
|
|
178
|
-
return found;
|
|
179
|
-
};
|
|
180
|
-
var accountFieldSecrets = (accounts) => {
|
|
181
|
-
const found = /* @__PURE__ */ new Set();
|
|
182
|
-
if (Predicate_exports.isObject(accounts)) {
|
|
183
|
-
for (const slot of Object.values(accounts))
|
|
184
|
-
for (const account of Array.isArray(slot) ? slot : [slot])
|
|
185
|
-
if (Predicate_exports.hasProperty(account, "fields")) secretValues(account.fields, found);
|
|
186
|
-
}
|
|
187
|
-
return [...found].sort((a, b) => b.length - a.length);
|
|
188
|
-
};
|
|
189
|
-
var accountSecrets = (accounts) => accountFieldSecrets(Redacted_exports.value(accounts));
|
|
190
|
-
var boundFailureMessage = (message, secrets) => {
|
|
191
|
-
let redacted = message;
|
|
192
|
-
for (const secret of secrets) redacted = redacted.split(secret).join("[redacted]");
|
|
193
|
-
return redacted.length <= maxFailureMessageLength ? redacted : `${redacted.slice(0, maxFailureMessageLength - 1)}\u2026`;
|
|
194
|
-
};
|
|
195
|
-
var errorName = (error) => (error.name.length > 0 ? error.name : "Error").slice(0, 128);
|
|
196
|
-
var ownMessage = (error) => {
|
|
197
|
-
const cause = error.cause;
|
|
198
|
-
const suffix = cause instanceof Error && cause.message.length > 0 ? ` (caused by ${errorName(cause)}: ${cause.message})` : "";
|
|
199
|
-
return error.message.length > 0 ? `${error.message}${suffix}` : void 0;
|
|
200
|
-
};
|
|
201
|
-
var describeFailure = (error) => error instanceof Error ? `${errorName(error)}: ${ownMessage(error) ?? "(no message)"}` : typeof error === "string" ? error : `A non-Error ${error === null ? "null" : typeof error} value was thrown`;
|
|
202
|
-
var failureDetail = (error, secrets) => {
|
|
203
|
-
if (Schema_exports.is(AppDatabaseError)(error))
|
|
204
|
-
return {
|
|
205
|
-
source: "storage",
|
|
206
|
-
errorName: "AppDatabaseError",
|
|
207
|
-
code: error.reason,
|
|
208
|
-
message: boundFailureMessage(ownMessage(error) ?? storageMessages[error.reason], secrets)
|
|
209
|
-
};
|
|
210
|
-
if (Schema_exports.is(AppStorageUnavailable)(error))
|
|
211
|
-
return {
|
|
212
|
-
source: "storage",
|
|
213
|
-
errorName: "AppStorageUnavailable",
|
|
214
|
-
message: "App storage is not available on this host."
|
|
215
|
-
};
|
|
216
|
-
if (Schema_exports.is(AppStorageError)(error))
|
|
217
|
-
return {
|
|
218
|
-
source: "storage",
|
|
219
|
-
errorName: "AppStorageError",
|
|
220
|
-
message: "App storage failed to complete the operation."
|
|
221
|
-
};
|
|
222
|
-
if (Schema_exports.is(OpenapiError)(error))
|
|
223
|
-
return {
|
|
224
|
-
source: "service",
|
|
225
|
-
errorName: "OpenapiError",
|
|
226
|
-
code: error.reason,
|
|
227
|
-
message: error.reason === "request" ? error.status === void 0 ? "The API request failed before a response arrived." : `The API responded with HTTP ${error.status}, which its OpenAPI document does not declare as an error with a message.` : error.reason === "invalid_input" ? "The input could not be encoded as a request for this API operation." : "The API's OpenAPI definition for this operation is invalid."
|
|
228
|
-
};
|
|
229
|
-
if (error instanceof Error)
|
|
230
|
-
return {
|
|
231
|
-
source: "app",
|
|
232
|
-
errorName: errorName(error),
|
|
233
|
-
message: boundFailureMessage(
|
|
234
|
-
ownMessage(error) ?? `${errorName(error)} was thrown without a message.`,
|
|
235
|
-
secrets
|
|
236
|
-
)
|
|
237
|
-
};
|
|
238
|
-
if (typeof error === "string")
|
|
239
|
-
return { source: "app", errorName: "string", message: boundFailureMessage(error, secrets) };
|
|
240
|
-
return {
|
|
241
|
-
source: "app",
|
|
242
|
-
errorName: typeof error,
|
|
243
|
-
message: `A non-Error ${error === null ? "null" : typeof error} value was thrown.`
|
|
244
|
-
};
|
|
245
|
-
};
|
|
246
|
-
|
|
247
158
|
// src/implementation/workflow-context.ts
|
|
248
159
|
var workflowSafe = (work, secrets) => work.pipe(
|
|
249
160
|
Effect_exports.catchCause((cause) => {
|
|
250
161
|
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
251
162
|
const error = Cause_exports.squash(cause);
|
|
252
163
|
if (Schema_exports.is(WorkflowFailure)(error)) return Effect_exports.fail(error);
|
|
253
|
-
const { errorName
|
|
164
|
+
const { errorName, message } = failureDetail(error, secrets);
|
|
254
165
|
return Effect_exports.fail(
|
|
255
166
|
new WorkflowFailure({
|
|
256
167
|
reason: "execution",
|
|
257
168
|
retryable: !(error instanceof NonRetryableError),
|
|
258
|
-
...
|
|
169
|
+
...errorName === void 0 ? {} : { errorName },
|
|
259
170
|
...message === void 0 ? {} : { message }
|
|
260
171
|
})
|
|
261
172
|
);
|
|
@@ -346,9 +257,9 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
|
|
|
346
257
|
});
|
|
347
258
|
const operationStep = (kind, name, operation, input, options) => Effect_exports.gen(function* () {
|
|
348
259
|
const target = nativeOperation(operation);
|
|
349
|
-
const
|
|
350
|
-
const match =
|
|
351
|
-
(
|
|
260
|
+
const root = definition.tools?.kind === "router" ? definition.tools : void 0;
|
|
261
|
+
const match = declaredOperations(root).find(
|
|
262
|
+
(entry) => entry.operation === target && entry.operation.kind === kind
|
|
352
263
|
);
|
|
353
264
|
if (target === void 0 || match === void 0)
|
|
354
265
|
return yield* new WorkflowFailure({ reason: "operation", retryable: false });
|
|
@@ -367,7 +278,7 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
|
|
|
367
278
|
parsed,
|
|
368
279
|
() => attempt(
|
|
369
280
|
parsed,
|
|
370
|
-
execution.invoke({ kind, name: match
|
|
281
|
+
execution.invoke({ kind, name: match.name, input: args, stepId, timeout }).pipe(Effect_exports.provideContext(services))
|
|
371
282
|
)
|
|
372
283
|
).pipe(Effect_exports.mapError(inStep(name)));
|
|
373
284
|
});
|
|
@@ -647,6 +558,10 @@ var authorCache = (host, accounts, signal, deadline) => {
|
|
|
647
558
|
};
|
|
648
559
|
|
|
649
560
|
// src/implementation/host.ts
|
|
561
|
+
var WireCatalog = Schema_exports.Struct({
|
|
562
|
+
tools: Schema_exports.Array(Schema_exports.Union([HostedTool, HostedToolSummary])),
|
|
563
|
+
routers: Schema_exports.Array(HostedRouter)
|
|
564
|
+
});
|
|
650
565
|
function safe2(work, failure) {
|
|
651
566
|
return Effect_exports.suspend(work).pipe(
|
|
652
567
|
Effect_exports.catchCause(
|
|
@@ -666,16 +581,6 @@ var evaluationSafe = (work, secrets) => work.pipe(
|
|
|
666
581
|
);
|
|
667
582
|
})
|
|
668
583
|
);
|
|
669
|
-
function jsonSchema(decoder) {
|
|
670
|
-
const imported = importedJsonSchema(decoder);
|
|
671
|
-
if (imported !== void 0) return Schema_exports.decodeUnknownEffect(JsonObject)(imported);
|
|
672
|
-
const document = Schema_exports.toJsonSchemaDocument(decoder);
|
|
673
|
-
return Schema_exports.decodeUnknownEffect(JsonObject)({
|
|
674
|
-
...document.schema,
|
|
675
|
-
$defs: document.definitions,
|
|
676
|
-
$schema: "https://json-schema.org/draft/2020-12/schema"
|
|
677
|
-
});
|
|
678
|
-
}
|
|
679
584
|
var declarationInvalid = (summary, cause, secrets = []) => new HostDeclarationInvalid({
|
|
680
585
|
source: "app",
|
|
681
586
|
errorName: "HostDeclarationInvalid",
|
|
@@ -699,14 +604,14 @@ function providerDeclaration(provider) {
|
|
|
699
604
|
auth.set(name, {
|
|
700
605
|
type: "secrets",
|
|
701
606
|
label: method.label,
|
|
702
|
-
fields: yield*
|
|
607
|
+
fields: yield* jsonSchemaDocument(method.fields)
|
|
703
608
|
});
|
|
704
609
|
break;
|
|
705
610
|
case "oauth2":
|
|
706
611
|
auth.set(name, {
|
|
707
612
|
type: "oauth2",
|
|
708
613
|
...method.config,
|
|
709
|
-
response: yield*
|
|
614
|
+
response: yield* jsonSchemaDocument(method.response)
|
|
710
615
|
});
|
|
711
616
|
break;
|
|
712
617
|
}
|
|
@@ -723,11 +628,11 @@ function requirements(slots, database) {
|
|
|
723
628
|
return Effect_exports.gen(function* () {
|
|
724
629
|
const accounts = /* @__PURE__ */ new Map();
|
|
725
630
|
for (const [slot, selection] of Object.entries(slots)) {
|
|
631
|
+
const provider = selection instanceof ManyAccounts ? selection.provider : selection;
|
|
726
632
|
accounts.set(slot, {
|
|
727
633
|
cardinality: selection instanceof ManyAccounts ? "many" : "one",
|
|
728
|
-
definition: yield* providerDeclaration(
|
|
729
|
-
|
|
730
|
-
)
|
|
634
|
+
definition: yield* providerDeclaration(provider),
|
|
635
|
+
...provider.health === void 0 ? {} : { health: true }
|
|
731
636
|
});
|
|
732
637
|
}
|
|
733
638
|
return yield* Schema_exports.decodeUnknownEffect(DeclaredRequirements)({
|
|
@@ -845,6 +750,14 @@ function dispatch(app, request, context, signal) {
|
|
|
845
750
|
return yield* new WorkflowFailure({ reason: "engine", retryable: true });
|
|
846
751
|
return result;
|
|
847
752
|
});
|
|
753
|
+
if (request.operation === "account-check")
|
|
754
|
+
return yield* checkAccount(
|
|
755
|
+
native.accounts,
|
|
756
|
+
declared,
|
|
757
|
+
request.requirement,
|
|
758
|
+
context,
|
|
759
|
+
invocationSignal
|
|
760
|
+
).pipe(withinDeadline);
|
|
848
761
|
let running;
|
|
849
762
|
let transactionOpen = false;
|
|
850
763
|
const delivery = (request2, signal2) => Effect_exports.suspend(
|
|
@@ -910,27 +823,33 @@ function dispatch(app, request, context, signal) {
|
|
|
910
823
|
const declared2 = definition.skills ?? (yield* folderSkillsEffect({ files }).pipe(
|
|
911
824
|
Effect_exports.mapError(() => new HostDeclarationInvalid())
|
|
912
825
|
));
|
|
913
|
-
const
|
|
826
|
+
const source = definition.dynamicSkills;
|
|
914
827
|
const before = cacheCommands;
|
|
915
|
-
const dynamic =
|
|
828
|
+
const dynamic = source === void 0 ? [] : yield* evaluationSafe(Effect_exports.suspend(source.list), secrets).pipe(
|
|
916
829
|
Effect_exports.withSpan("app.skills.load")
|
|
917
830
|
);
|
|
918
|
-
const cached =
|
|
919
|
-
const
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
831
|
+
const cached = source !== void 0 && cacheCommands > before;
|
|
832
|
+
const authored = new Set([...declared2, ...dynamic].map((skill) => skill.name));
|
|
833
|
+
const routed = (yield* routerSkills(definition.tools).pipe(
|
|
834
|
+
Effect_exports.withSpan("app.skills.routers")
|
|
835
|
+
)).filter((skill) => !authored.has(skill.name));
|
|
836
|
+
const skills = yield* Schema_exports.decodeUnknownEffect(AppSkills)([
|
|
837
|
+
...declared2,
|
|
838
|
+
...dynamic,
|
|
839
|
+
...routed
|
|
840
|
+
]).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
|
|
841
|
+
return request.sources === true ? { skills, dynamic: source !== void 0, cached } : skills;
|
|
923
842
|
}
|
|
924
843
|
if (request.operation === "workflows") {
|
|
925
844
|
return yield* Effect_exports.forEach(
|
|
926
845
|
Object.entries(definition.workflows ?? {}),
|
|
927
|
-
([
|
|
846
|
+
([name, entry]) => safe2(
|
|
928
847
|
() => Effect_exports.gen(function* () {
|
|
929
848
|
return yield* Schema_exports.decodeUnknownEffect(HostedWorkflow)({
|
|
930
|
-
name
|
|
849
|
+
name,
|
|
931
850
|
...entry.description === void 0 ? {} : { description: entry.description },
|
|
932
|
-
inputSchema: yield*
|
|
933
|
-
...entry.output === void 0 ? {} : { outputSchema: yield*
|
|
851
|
+
inputSchema: yield* jsonSchemaDocument(entry.input),
|
|
852
|
+
...entry.output === void 0 ? {} : { outputSchema: yield* jsonSchemaDocument(entry.output) }
|
|
934
853
|
});
|
|
935
854
|
}),
|
|
936
855
|
new HostDeclarationInvalid()
|
|
@@ -1004,79 +923,19 @@ function dispatch(app, request, context, signal) {
|
|
|
1004
923
|
}
|
|
1005
924
|
if (request.operation === "inspect") {
|
|
1006
925
|
const summary = request.detail === "summary";
|
|
1007
|
-
const
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
const fields = {
|
|
1021
|
-
name: `${prefix}${name2}`,
|
|
1022
|
-
schedules,
|
|
1023
|
-
description: operation.description ?? `${readOnly ? "Query" : "Mutate"} ${name2}`,
|
|
1024
|
-
...operation.title === void 0 ? {} : { title: operation.title },
|
|
1025
|
-
readOnly,
|
|
1026
|
-
annotations: { ...operation.annotations, readOnlyHint: readOnly }
|
|
1027
|
-
};
|
|
1028
|
-
if (summary)
|
|
1029
|
-
return yield* Schema_exports.decodeUnknownEffect(HostedToolSummary)(fields);
|
|
1030
|
-
return yield* Schema_exports.decodeUnknownEffect(HostedTool)({
|
|
1031
|
-
...fields,
|
|
1032
|
-
inputSchema: yield* jsonSchema(operation.input),
|
|
1033
|
-
...operation.output === void 0 ? operation.outputSchema === void 0 ? {} : { outputSchema: operation.outputSchema } : { outputSchema: yield* jsonSchema(operation.output) },
|
|
1034
|
-
...operation._meta === void 0 ? {} : { _meta: operation._meta }
|
|
1035
|
-
});
|
|
1036
|
-
}),
|
|
1037
|
-
new HostDeclarationInvalid()
|
|
1038
|
-
)
|
|
1039
|
-
);
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
const dynamic = request.scheduled === true ? void 0 : definition.dynamicTools;
|
|
1043
|
-
if (dynamic !== void 0 && (wanted === void 0 || metadata.length < wanted.size)) {
|
|
1044
|
-
const declared2 = new Set(metadata.map((tool2) => tool2.name));
|
|
1045
|
-
const discover = () => {
|
|
1046
|
-
if (summary && dynamic.summaries !== void 0) return dynamic.summaries();
|
|
1047
|
-
if (wanted !== void 0 && dynamic.describe !== void 0) {
|
|
1048
|
-
const describe = dynamic.describe;
|
|
1049
|
-
return Effect_exports.forEach(
|
|
1050
|
-
[...wanted].filter((name2) => !declared2.has(name2)),
|
|
1051
|
-
(name2) => describe(name2),
|
|
1052
|
-
{ concurrency: "unbounded" }
|
|
1053
|
-
).pipe(Effect_exports.map((tools) => tools.filter((tool2) => tool2 !== void 0)));
|
|
1054
|
-
}
|
|
1055
|
-
return dynamic.list();
|
|
1056
|
-
};
|
|
1057
|
-
const discovered = yield* evaluationSafe(discover(), secrets).pipe(
|
|
1058
|
-
Effect_exports.flatMap(
|
|
1059
|
-
(value) => safe2(
|
|
1060
|
-
() => summary ? Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedToolSummary))(value) : Schema_exports.decodeUnknownEffect(Schema_exports.Array(HostedTool))(value),
|
|
1061
|
-
new HostDeclarationInvalid()
|
|
1062
|
-
)
|
|
1063
|
-
)
|
|
1064
|
-
);
|
|
1065
|
-
const names = new Set(declared2);
|
|
1066
|
-
for (const tool2 of discovered) {
|
|
1067
|
-
const readOnly = tool2.name.startsWith(OperationToolPrefixes.query);
|
|
1068
|
-
if (!readOnly && !tool2.name.startsWith(OperationToolPrefixes.mutate) || tool2.name === OperationToolPrefixes.query || tool2.name === OperationToolPrefixes.mutate || names.has(tool2.name))
|
|
1069
|
-
return yield* new HostDeclarationInvalid();
|
|
1070
|
-
names.add(tool2.name);
|
|
1071
|
-
if (wanted !== void 0 && !wanted.has(tool2.name)) continue;
|
|
1072
|
-
metadata.push({
|
|
1073
|
-
...tool2,
|
|
1074
|
-
readOnly,
|
|
1075
|
-
annotations: { ...tool2.annotations, readOnlyHint: readOnly }
|
|
1076
|
-
});
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
return metadata;
|
|
926
|
+
const catalog = yield* readCatalog(definition.tools, {
|
|
927
|
+
summary,
|
|
928
|
+
secrets,
|
|
929
|
+
...request.tools === void 0 ? {} : { wanted: new Set(request.tools) },
|
|
930
|
+
...request.scheduled === true ? { scheduled: true } : {},
|
|
931
|
+
schedules: (name) => Object.entries(definition.schedules ?? {}).filter(([, schedule]) => schedule.tool === name).map(([name2, { tool: _tool, ...schedule }]) => ({ name: name2, ...schedule }))
|
|
932
|
+
}).pipe(Effect_exports.withSpan("app.catalog.read"));
|
|
933
|
+
return yield* safe2(
|
|
934
|
+
() => Schema_exports.encodeEffect(WireCatalog)(catalog).pipe(
|
|
935
|
+
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
|
|
936
|
+
),
|
|
937
|
+
new HostDeclarationInvalid()
|
|
938
|
+
);
|
|
1080
939
|
}
|
|
1081
940
|
if (request.operation === "webhook-complete" || request.operation === "webhook-validate" || request.operation === "webhooks" || request.operation === "webhook-register" || request.operation === "webhook-handle" || request.operation === "webhook-unregister") {
|
|
1082
941
|
const executeWebhook = (db) => dispatchWebhook(
|
|
@@ -1107,19 +966,15 @@ function dispatch(app, request, context, signal) {
|
|
|
1107
966
|
})
|
|
1108
967
|
);
|
|
1109
968
|
}
|
|
1110
|
-
const
|
|
1111
|
-
|
|
1112
|
-
const
|
|
1113
|
-
const toolName = `${OperationToolPrefixes[kind]}${name}`;
|
|
1114
|
-
const catalog = kind === "query" ? definition.queries : definition.mutations;
|
|
1115
|
-
const declaredTool = catalog !== void 0 && Object.hasOwn(catalog, name) ? catalog[name] : void 0;
|
|
1116
|
-
const source = definition.dynamicTools;
|
|
1117
|
-
const resolvedTool = source === void 0 || declaredTool !== void 0 ? void 0 : yield* evaluationSafe(source.resolve(toolName), secrets);
|
|
1118
|
-
const tool = declaredTool ?? resolvedTool;
|
|
1119
|
-
if (tool !== void 0 && tool.kind !== (kind === "query" ? "query" : "mutation"))
|
|
1120
|
-
return yield* new HostDeclarationInvalid();
|
|
969
|
+
const toolName = request.operation === "call" ? request.tool : request.name;
|
|
970
|
+
const location = locate(definition.tools, toolName);
|
|
971
|
+
const tool = location === void 0 ? void 0 : location.kind === "operation" ? location.operation : yield* evaluationSafe(location.source.resolve(location.name), secrets);
|
|
1121
972
|
if (tool === void 0)
|
|
1122
973
|
return yield* request.operation === "call" ? new HostToolNotFound() : new HostOperationNotFound();
|
|
974
|
+
const requested = request.operation === "call" ? request.kind : request.operation === "query" ? "query" : "mutation";
|
|
975
|
+
if (requested !== void 0 && tool.kind !== requested)
|
|
976
|
+
return yield* new HostKindMismatch({ tool: toolName, requested, actual: tool.kind });
|
|
977
|
+
const kind = tool.kind === "query" ? "query" : "mutate";
|
|
1123
978
|
const input = yield* Effect_exports.suspend(
|
|
1124
979
|
() => Schema_exports.decodeUnknownEffect(tool.input)(request.input)
|
|
1125
980
|
).pipe(
|
|
@@ -1248,6 +1103,46 @@ function dispatch(app, request, context, signal) {
|
|
|
1248
1103
|
})
|
|
1249
1104
|
);
|
|
1250
1105
|
}
|
|
1106
|
+
function checkAccount(slots, declared, requirement, context, signal) {
|
|
1107
|
+
return Effect_exports.gen(function* () {
|
|
1108
|
+
const selection = Object.hasOwn(slots, requirement) ? slots[requirement] : void 0;
|
|
1109
|
+
const slot = Object.hasOwn(declared.accounts, requirement) ? declared.accounts[requirement] : void 0;
|
|
1110
|
+
if (selection === void 0 || slot === void 0) return yield* new HostAccountsInvalid();
|
|
1111
|
+
const provider = selection instanceof ManyAccounts ? selection.provider : selection;
|
|
1112
|
+
const health = provider.health;
|
|
1113
|
+
if (health === void 0) return yield* new HostOperationNotFound();
|
|
1114
|
+
const { accounts } = yield* bindAccounts(
|
|
1115
|
+
{ [requirement]: provider },
|
|
1116
|
+
{ accounts: { [requirement]: { ...slot, cardinality: "one" } } },
|
|
1117
|
+
context
|
|
1118
|
+
).pipe(Effect_exports.withSpan("app.accounts.bind"));
|
|
1119
|
+
const account = accounts[requirement];
|
|
1120
|
+
if (account === void 0 || !("id" in account)) return yield* new HostAccountsInvalid();
|
|
1121
|
+
const result = yield* Effect_exports.suspend(
|
|
1122
|
+
() => Effect_exports.gen(function* () {
|
|
1123
|
+
return yield* health.run({ account, fetch: yield* invocationFetch(signal), signal });
|
|
1124
|
+
})
|
|
1125
|
+
).pipe(
|
|
1126
|
+
Effect_exports.catchCause((cause) => {
|
|
1127
|
+
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
1128
|
+
const error = Cause_exports.squash(cause);
|
|
1129
|
+
const status = Schema_exports.decodeUnknownOption(ResponseStatusError)(error);
|
|
1130
|
+
const classified = Option_exports.isSome(status) ? Option_exports.fromNullishOr(httpProviderError(status.value.status)) : parseProviderError(error);
|
|
1131
|
+
return Effect_exports.fail(
|
|
1132
|
+
Option_exports.isSome(classified) ? accountProviderError(classified.value, account.id) : new HostOperationFailed()
|
|
1133
|
+
);
|
|
1134
|
+
}),
|
|
1135
|
+
Effect_exports.withSpan("app.account.check")
|
|
1136
|
+
);
|
|
1137
|
+
return yield* safe2(
|
|
1138
|
+
() => Schema_exports.decodeUnknownEffect(AccountCheckResult)(result ?? {}).pipe(
|
|
1139
|
+
Effect_exports.flatMap(Schema_exports.encodeEffect(AccountCheckResult)),
|
|
1140
|
+
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
|
|
1141
|
+
),
|
|
1142
|
+
new HostOutputInvalid()
|
|
1143
|
+
);
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1251
1146
|
var parseSkillLoadFailed = (error) => Schema_exports.decodeUnknownOption(SkillLoadFailed)(error).pipe(
|
|
1252
1147
|
Option_exports.map(
|
|
1253
1148
|
({ reason, message, status }) => new SkillLoadFailed({
|
|
@@ -1273,6 +1168,7 @@ var errorStatus = Match_exports.type().pipe(
|
|
|
1273
1168
|
HostAccountsInvalid: () => 422,
|
|
1274
1169
|
HostInputInvalid: () => 422,
|
|
1275
1170
|
HostOperationNotFound: () => 404,
|
|
1171
|
+
HostKindMismatch: () => 409,
|
|
1276
1172
|
HostToolNotFound: () => 404,
|
|
1277
1173
|
HostToolBlocked: () => 403,
|
|
1278
1174
|
HostToolApprovalRequired: () => 409,
|