apps 0.0.1-beta.5 → 0.0.1-beta.55
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-47F7VXST.js +221 -0
- package/js/chunk-5FHWNLCI.js +88 -0
- package/js/{chunk-M3B3DE4K.js → chunk-74YVXBKY.js} +463 -218
- package/js/chunk-7UUHJR2Q.js +49 -0
- package/js/{chunk-CYYBFC2K.js → chunk-AQU56EPI.js} +9 -5
- package/js/chunk-BTSIG4NQ.js +1885 -0
- package/js/chunk-CDXQDN7W.js +92 -0
- package/js/{chunk-UK573G7W.js → chunk-EOPQ727L.js} +87 -51
- package/js/{chunk-27F7W2LG.js → chunk-H2CJWXA3.js} +2 -2
- package/js/{chunk-JU7VHODU.js → chunk-H72MEDMN.js} +65 -10
- package/js/{chunk-CDL5PM2Q.js → chunk-IFJU5SYQ.js} +19082 -18402
- package/js/{chunk-UDDE5KOR.js → chunk-JK5S2N2S.js} +148 -34
- package/js/{chunk-RJDDBDSN.js → chunk-JM7LOD2W.js} +628 -85
- package/js/{chunk-VFZKSM3T.js → chunk-JPEUKEV4.js} +3 -3
- package/js/{chunk-FWQC6I3C.js → chunk-KGCTYL2S.js} +523 -63
- package/js/{chunk-KUMBKVJD.js → chunk-KLYSEHUD.js} +2 -2
- package/js/chunk-L4K2K22P.js +42 -0
- package/js/chunk-LTDHQJ2Z.js +171 -0
- package/js/chunk-MWKHKOTL.js +240 -0
- package/js/chunk-OD3KFKZD.js +1617 -0
- package/js/{chunk-57RKNWL2.js → chunk-PD6I2SDG.js} +4 -4
- package/js/chunk-PXXZ6ABC.js +266 -0
- package/js/chunk-QEBRH5AP.js +729 -0
- package/js/chunk-TLWLJ7PD.js +4342 -0
- package/js/{chunk-IJX4CYZO.js → chunk-TUMGL2OC.js} +228 -264
- package/js/{chunk-XHO2ZX6W.js → chunk-UM62MBJQ.js} +96 -41
- package/js/{chunk-IPI4MFSN.js → chunk-XBG7HHXC.js} +2 -2
- package/js/chunk-XCSG7FT7.js +340 -0
- package/js/client.js +142 -94
- package/js/contracts.js +123 -33
- package/js/effect.js +19 -21
- package/js/{es-APDZKREY.js → es-DIULA3ZF.js} +62 -1659
- package/js/graphql.js +63 -60
- package/js/host.js +83 -60
- package/js/index.js +262 -222
- package/js/mcp/effect.js +23 -23
- package/js/mcp/stdio.js +48 -40
- package/js/mcp.js +109 -72
- package/js/openapi.js +4129 -1419
- package/js/react.js +2 -3
- package/js/skills/effect.js +6 -3
- package/js/skills.js +208 -82
- package/js/storage/facet.js +1 -540
- 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 +8517 -214
- package/package.json +2 -3
- package/runtime.json +1 -1
- package/types/app-cache/src/index.d.ts +10 -1
- package/types/apps/src/contracts/api-response-error.d.ts +4 -0
- package/types/apps/src/contracts/app.d.ts +9 -8
- package/types/apps/src/contracts/cache.d.ts +20 -0
- package/types/apps/src/contracts/context.d.ts +19 -11
- package/types/apps/src/contracts/elicitation.d.ts +6 -6
- package/types/apps/src/contracts/events.d.ts +93 -0
- package/types/apps/src/contracts/failure.d.ts +30 -1
- package/types/apps/src/contracts/graphql.d.ts +2 -1
- package/types/apps/src/contracts/host.d.ts +57 -18
- package/types/apps/src/contracts/live.d.ts +2 -0
- package/types/apps/src/contracts/mcp.d.ts +96 -10
- package/types/apps/src/contracts/network.d.ts +84 -0
- package/types/apps/src/contracts/openapi-compile.d.ts +32 -3
- package/types/apps/src/contracts/openapi.d.ts +45 -9
- package/types/apps/src/contracts/operations.d.ts +8 -9
- package/types/apps/src/contracts/protocol-version.d.ts +2 -2
- package/types/apps/src/contracts/protocols/1.d.ts +733 -81
- package/types/apps/src/contracts/protocols/10.d.ts +1450 -0
- package/types/apps/src/contracts/protocols/2.d.ts +69 -26
- package/types/apps/src/contracts/protocols/3.d.ts +133 -33
- package/types/apps/src/contracts/protocols/4.d.ts +1306 -0
- package/types/apps/src/contracts/protocols/5.d.ts +1200 -0
- package/types/apps/src/contracts/protocols/6.d.ts +1629 -0
- package/types/apps/src/contracts/protocols/7.d.ts +1785 -0
- package/types/apps/src/contracts/protocols/8.d.ts +1182 -0
- package/types/apps/src/contracts/protocols/9.d.ts +1104 -0
- package/types/apps/src/contracts/protocols/current.d.ts +2476 -0
- package/types/apps/src/contracts/protocols/oauth-6.d.ts +74 -0
- package/types/apps/src/contracts/protocols/oauth.d.ts +134 -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 +50 -13
- package/types/apps/src/contracts/sql.d.ts +58 -0
- package/types/apps/src/contracts/ui.d.ts +19 -1
- package/types/apps/src/contracts/workflows.d.ts +6 -0
- package/types/apps/src/facet.d.ts +4 -5
- package/types/apps/src/graphql.d.ts +1 -3
- package/types/apps/src/host.d.ts +5 -0
- package/types/apps/src/implementation/account-router.d.ts +13 -0
- package/types/apps/src/implementation/app.d.ts +5 -4
- package/types/apps/src/implementation/authoring.d.ts +25 -5
- package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
- package/types/apps/src/implementation/cache.d.ts +4 -0
- package/types/apps/src/implementation/catalog-cache.d.ts +43 -5
- package/types/apps/src/implementation/elicitation.d.ts +18 -15
- package/types/apps/src/implementation/events.d.ts +59 -0
- package/types/apps/src/implementation/failure-detail.d.ts +25 -3
- package/types/apps/src/implementation/graphql-catalog.d.ts +4 -7
- package/types/apps/src/implementation/graphql.d.ts +4 -3
- package/types/apps/src/implementation/input-problems.d.ts +6 -2
- package/types/apps/src/implementation/invocation-timing.d.ts +16 -0
- package/types/apps/src/implementation/live.d.ts +2 -2
- package/types/apps/src/implementation/mcp-call.d.ts +6 -5
- package/types/apps/src/implementation/mcp-catalog.d.ts +7 -8
- package/types/apps/src/implementation/mcp-client.d.ts +49 -25
- package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
- package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
- package/types/apps/src/implementation/mcp.d.ts +52 -25
- package/types/apps/src/implementation/network.d.ts +16 -0
- package/types/apps/src/implementation/openapi-compile.d.ts +27 -6
- package/types/apps/src/implementation/openapi-document.d.ts +46 -19
- package/types/apps/src/implementation/openapi-names.d.ts +9 -4
- package/types/apps/src/implementation/openapi-request.d.ts +10 -2
- package/types/apps/src/implementation/openapi-source.d.ts +8 -6
- package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
- package/types/apps/src/implementation/operations.d.ts +43 -5
- package/types/apps/src/implementation/optimistic.d.ts +1 -1
- 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/query-commit.d.ts +1 -1
- package/types/apps/src/implementation/router-catalog.d.ts +223 -0
- package/types/apps/src/implementation/router.d.ts +70 -0
- package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
- package/types/apps/src/implementation/schema.d.ts +95 -11
- package/types/apps/src/implementation/skills.d.ts +18 -24
- package/types/apps/src/implementation/sql.d.ts +71 -0
- package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
- package/types/apps/src/implementation/ui-auth.d.ts +1 -1
- 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 +11 -5
- 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 +1 -1
- package/types/apps/src/implementation/workflows.d.ts +1 -1
- package/types/apps/src/index.d.ts +32 -13
- 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/react.d.ts +1 -1
- package/types/apps/src/skills.d.ts +10 -8
- package/types/telemetry/src/app-records.d.ts +42 -0
- package/types/telemetry/src/browser-operations.d.ts +7 -4
- package/types/telemetry/src/browser.d.ts +8 -3
- package/types/telemetry/src/config.d.ts +2 -2
- package/types/telemetry/src/index.d.ts +1 -0
- package/types/telemetry/src/layer.d.ts +2 -2
- package/types/telemetry/src/ownership.d.ts +56 -0
- package/types/telemetry/src/recorded-failure.d.ts +29 -0
- package/types/telemetry/src/relay.d.ts +2 -2
- package/types/telemetry/src/transport.d.ts +8 -1
- package/types/utils/src/api-error.d.ts +55 -0
- package/types/utils/src/connection-failure.d.ts +33 -0
- package/types/utils/src/recorded-message.d.ts +18 -0
- package/types/utils/src/user-facing-error.d.ts +83 -0
- package/js/chunk-3XKZDQLM.js +0 -93
- package/js/chunk-4M277YTM.js +0 -136
- package/js/chunk-67EVWIGJ.js +0 -224
- package/js/chunk-C3VAOK5B.js +0 -215
- package/js/chunk-DQAZTA4I.js +0 -2375
- package/js/chunk-G7T27IWB.js +0 -63
- package/js/chunk-LUVSFETN.js +0 -1347
- package/js/chunk-N7YDVXYJ.js +0 -186
- package/js/chunk-PJJ24GU7.js +0 -877
- package/js/chunk-PZB6T6KU.js +0 -19
- package/js/chunk-SB3V4YVR.js +0 -18
- package/js/chunk-TDNYXSIX.js +0 -29
- package/js/chunk-W4DMKWAB.js +0 -35
- package/js/chunk-YEPYT6SD.js +0 -85
- package/js/chunk-ZQINWV4W.js +0 -630
- package/types/app-data/src/implementation/cursor.d.ts +0 -10
- package/types/app-data/src/implementation/index-key.d.ts +0 -7
- package/types/app-data/src/implementation/promise.d.ts +0 -68
- package/types/app-data/src/implementation/range.d.ts +0 -8
- package/types/app-data/src/implementation/schema.d.ts +0 -18
- package/types/app-data/src/implementation/sqlite.d.ts +0 -11
- package/types/app-data/src/index.d.ts +0 -4
- package/types/apps/src/contracts/dynamic-tools.d.ts +0 -13
- package/types/apps/src/contracts/storage.d.ts +0 -68
- package/types/apps/src/implementation/account-operations.d.ts +0 -151
- package/types/apps/src/implementation/dynamic-tools.d.ts +0 -8
- package/types/apps/src/implementation/storage.d.ts +0 -15
package/js/chunk-LUVSFETN.js
DELETED
|
@@ -1,1347 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
makeCache
|
|
3
|
-
} from "./chunk-CYYBFC2K.js";
|
|
4
|
-
import {
|
|
5
|
-
folderSkillsEffect
|
|
6
|
-
} from "./chunk-IPI4MFSN.js";
|
|
7
|
-
import {
|
|
8
|
-
OpenapiError
|
|
9
|
-
} from "./chunk-4M277YTM.js";
|
|
10
|
-
import {
|
|
11
|
-
authorDatabase,
|
|
12
|
-
isApp,
|
|
13
|
-
toEffectApp,
|
|
14
|
-
unavailableStorage
|
|
15
|
-
} from "./chunk-C3VAOK5B.js";
|
|
16
|
-
import {
|
|
17
|
-
parseDatabaseSchema
|
|
18
|
-
} from "./chunk-ZQINWV4W.js";
|
|
19
|
-
import {
|
|
20
|
-
fromPromise,
|
|
21
|
-
nativeOperation,
|
|
22
|
-
toPromise
|
|
23
|
-
} from "./chunk-3XKZDQLM.js";
|
|
24
|
-
import {
|
|
25
|
-
parseProviderError
|
|
26
|
-
} from "./chunk-G7T27IWB.js";
|
|
27
|
-
import {
|
|
28
|
-
DeclaredProvider,
|
|
29
|
-
DeclaredRequirements,
|
|
30
|
-
ElicitationFailed,
|
|
31
|
-
ElicitationResponse,
|
|
32
|
-
FormElicitation,
|
|
33
|
-
HostAccountsInvalid,
|
|
34
|
-
HostDeclarationInvalid,
|
|
35
|
-
HostError,
|
|
36
|
-
HostEvaluationFailed,
|
|
37
|
-
HostInputInvalid,
|
|
38
|
-
HostOperationFailed,
|
|
39
|
-
HostOperationNotFound,
|
|
40
|
-
HostOutputInvalid,
|
|
41
|
-
HostRequest,
|
|
42
|
-
HostRequestInvalid,
|
|
43
|
-
HostToolApprovalRequired,
|
|
44
|
-
HostToolBlocked,
|
|
45
|
-
HostToolNotFound,
|
|
46
|
-
HostToolPolicyFailed,
|
|
47
|
-
HostedTool,
|
|
48
|
-
HostedToolSummary,
|
|
49
|
-
HostedWebhook,
|
|
50
|
-
HostedWorkflow,
|
|
51
|
-
InvocationDeadline,
|
|
52
|
-
ManualWebhookSetup,
|
|
53
|
-
ManyAccounts,
|
|
54
|
-
McpError,
|
|
55
|
-
NonRetryableError,
|
|
56
|
-
OperationToolPrefixes,
|
|
57
|
-
ResolvedAccounts,
|
|
58
|
-
ToolResultObservation,
|
|
59
|
-
TrustedToolApproval,
|
|
60
|
-
WebhookResponseData,
|
|
61
|
-
WorkflowDuration,
|
|
62
|
-
WorkflowFailure,
|
|
63
|
-
WorkflowName,
|
|
64
|
-
WorkflowReplay,
|
|
65
|
-
WorkflowStepOptions,
|
|
66
|
-
WorkflowValue,
|
|
67
|
-
approvalElicitation,
|
|
68
|
-
defaultWebhookTransportLimits,
|
|
69
|
-
maxFailureMessageLength,
|
|
70
|
-
maxInputProblems,
|
|
71
|
-
workflowDurationMillis
|
|
72
|
-
} from "./chunk-DQAZTA4I.js";
|
|
73
|
-
import {
|
|
74
|
-
AppDatabaseError
|
|
75
|
-
} from "./chunk-N7YDVXYJ.js";
|
|
76
|
-
import {
|
|
77
|
-
CacheError
|
|
78
|
-
} from "./chunk-YEPYT6SD.js";
|
|
79
|
-
import {
|
|
80
|
-
AppSkills,
|
|
81
|
-
SkillFile,
|
|
82
|
-
SkillLoadFailed
|
|
83
|
-
} from "./chunk-JU7VHODU.js";
|
|
84
|
-
import {
|
|
85
|
-
OpenapiResponseError
|
|
86
|
-
} from "./chunk-W4DMKWAB.js";
|
|
87
|
-
import {
|
|
88
|
-
captureTelemetry,
|
|
89
|
-
invocationFetch
|
|
90
|
-
} from "./chunk-RJDDBDSN.js";
|
|
91
|
-
import {
|
|
92
|
-
decoderOf,
|
|
93
|
-
importedJsonSchema,
|
|
94
|
-
jsonSchemaDecoder
|
|
95
|
-
} from "./chunk-FWQC6I3C.js";
|
|
96
|
-
import {
|
|
97
|
-
AppStorageError,
|
|
98
|
-
AppStorageUnavailable
|
|
99
|
-
} from "./chunk-PZB6T6KU.js";
|
|
100
|
-
import {
|
|
101
|
-
JsonObject,
|
|
102
|
-
JsonValue
|
|
103
|
-
} from "./chunk-27F7W2LG.js";
|
|
104
|
-
import {
|
|
105
|
-
Cause_exports,
|
|
106
|
-
Clock_exports,
|
|
107
|
-
Effect_exports,
|
|
108
|
-
Encoding_exports,
|
|
109
|
-
Match_exports,
|
|
110
|
-
Option_exports,
|
|
111
|
-
Predicate_exports,
|
|
112
|
-
Redacted_exports,
|
|
113
|
-
SchemaIssue_exports,
|
|
114
|
-
Schema_exports,
|
|
115
|
-
Stream_exports
|
|
116
|
-
} from "./chunk-CDL5PM2Q.js";
|
|
117
|
-
|
|
118
|
-
// src/implementation/elicitation.ts
|
|
119
|
-
var prepareElicitation = (input) => Effect_exports.gen(function* () {
|
|
120
|
-
const request = yield* Schema_exports.decodeUnknownEffect(FormElicitation)(input, {
|
|
121
|
-
onExcessProperty: "error"
|
|
122
|
-
}).pipe(Effect_exports.mapError(() => new ElicitationFailed({ reason: "invalid-request" })));
|
|
123
|
-
const content = yield* jsonSchemaDecoder(request.requestedSchema).pipe(
|
|
124
|
-
Effect_exports.mapError(() => new ElicitationFailed({ reason: "invalid-request" }))
|
|
125
|
-
);
|
|
126
|
-
const respond = (input2) => Effect_exports.gen(function* () {
|
|
127
|
-
const response = yield* Schema_exports.decodeUnknownEffect(ElicitationResponse)(input2).pipe(
|
|
128
|
-
Effect_exports.catchTag(
|
|
129
|
-
"SchemaError",
|
|
130
|
-
() => Effect_exports.fail(new ElicitationFailed({ reason: "invalid-response" }))
|
|
131
|
-
)
|
|
132
|
-
);
|
|
133
|
-
if (response.action === "accept") {
|
|
134
|
-
const fields = response.content === void 0 ? {} : response.content;
|
|
135
|
-
yield* Schema_exports.decodeUnknownEffect(content)(fields).pipe(
|
|
136
|
-
Effect_exports.mapError(() => new ElicitationFailed({ reason: "invalid-response" }))
|
|
137
|
-
);
|
|
138
|
-
return { ...response, content: fields };
|
|
139
|
-
}
|
|
140
|
-
return response;
|
|
141
|
-
});
|
|
142
|
-
return { request, respond };
|
|
143
|
-
});
|
|
144
|
-
var makeElicit = (handler, signal) => toPromise(
|
|
145
|
-
(input) => Effect_exports.gen(function* () {
|
|
146
|
-
if (handler === void 0) return yield* new ElicitationFailed({ reason: "unavailable" });
|
|
147
|
-
const form = yield* prepareElicitation(input);
|
|
148
|
-
return yield* handler(form.request, signal).pipe(Effect_exports.flatMap(form.respond));
|
|
149
|
-
}),
|
|
150
|
-
signal
|
|
151
|
-
);
|
|
152
|
-
|
|
153
|
-
// src/contracts/approval.ts
|
|
154
|
-
var ApprovalDecision = Schema_exports.Literals(["approved", "denied", "user-approval"]);
|
|
155
|
-
|
|
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
|
-
// src/implementation/workflow-context.ts
|
|
248
|
-
var workflowSafe = (work, secrets) => work.pipe(
|
|
249
|
-
Effect_exports.catchCause((cause) => {
|
|
250
|
-
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
251
|
-
const error = Cause_exports.squash(cause);
|
|
252
|
-
if (Schema_exports.is(WorkflowFailure)(error)) return Effect_exports.fail(error);
|
|
253
|
-
const { errorName: errorName2, message } = failureDetail(error, secrets);
|
|
254
|
-
return Effect_exports.fail(
|
|
255
|
-
new WorkflowFailure({
|
|
256
|
-
reason: "execution",
|
|
257
|
-
retryable: !(error instanceof NonRetryableError),
|
|
258
|
-
...errorName2 === void 0 ? {} : { errorName: errorName2 },
|
|
259
|
-
...message === void 0 ? {} : { message }
|
|
260
|
-
})
|
|
261
|
-
);
|
|
262
|
-
})
|
|
263
|
-
);
|
|
264
|
-
var inStep = (step) => (failure) => failure.step === void 0 ? new WorkflowFailure({
|
|
265
|
-
reason: failure.reason,
|
|
266
|
-
retryable: failure.retryable,
|
|
267
|
-
step: step.slice(0, 200),
|
|
268
|
-
...failure.errorName === void 0 ? {} : { errorName: failure.errorName },
|
|
269
|
-
...failure.message.length === 0 ? {} : { message: failure.message }
|
|
270
|
-
}) : failure;
|
|
271
|
-
var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_exports.gen(function* () {
|
|
272
|
-
const services = yield* Effect_exports.context();
|
|
273
|
-
const counts = /* @__PURE__ */ new Map();
|
|
274
|
-
const identify = (kind, name) => Effect_exports.gen(function* () {
|
|
275
|
-
yield* Schema_exports.decodeUnknownEffect(WorkflowName)(name).pipe(
|
|
276
|
-
Effect_exports.mapError(() => new WorkflowFailure({ reason: "input", retryable: false }))
|
|
277
|
-
);
|
|
278
|
-
const key = JSON.stringify([kind, name]);
|
|
279
|
-
const count = (counts.get(key) ?? 0) + 1;
|
|
280
|
-
counts.set(key, count);
|
|
281
|
-
const digest = yield* Effect_exports.tryPromise({
|
|
282
|
-
try: () => crypto.subtle.digest(
|
|
283
|
-
"SHA-256",
|
|
284
|
-
new TextEncoder().encode(JSON.stringify([execution.runId, kind, name, count]))
|
|
285
|
-
),
|
|
286
|
-
catch: () => new WorkflowFailure({ reason: "execution", retryable: false })
|
|
287
|
-
});
|
|
288
|
-
return Array.from(
|
|
289
|
-
new Uint8Array(digest),
|
|
290
|
-
(byte) => byte.toString(16).padStart(2, "0")
|
|
291
|
-
).join("");
|
|
292
|
-
});
|
|
293
|
-
const attempt = (options, work) => {
|
|
294
|
-
const timeout = workflowDurationMillis(options.timeout ?? "10 minutes");
|
|
295
|
-
if (timeout === void 0)
|
|
296
|
-
return Effect_exports.fail(new WorkflowFailure({ reason: "input", retryable: false }));
|
|
297
|
-
return work.pipe(
|
|
298
|
-
Effect_exports.timeout(timeout),
|
|
299
|
-
Effect_exports.catchTag(
|
|
300
|
-
"TimeoutError",
|
|
301
|
-
() => (
|
|
302
|
-
// Both the capability deadline and the native engine deadline describe
|
|
303
|
-
// the same cancellation, regardless of which timer fires first.
|
|
304
|
-
Effect_exports.fail(new WorkflowFailure({ reason: "engine", retryable: true }))
|
|
305
|
-
)
|
|
306
|
-
)
|
|
307
|
-
);
|
|
308
|
-
};
|
|
309
|
-
const runStep = (name, options, callback) => Effect_exports.gen(function* () {
|
|
310
|
-
const stepId = yield* identify("do", name);
|
|
311
|
-
const parsed = yield* Schema_exports.decodeUnknownEffect(WorkflowStepOptions)(options).pipe(
|
|
312
|
-
Effect_exports.mapError(() => new WorkflowFailure({ reason: "input", retryable: false }))
|
|
313
|
-
);
|
|
314
|
-
return yield* execution.driver.do(
|
|
315
|
-
`do:${name.slice(0, 100)}:${stepId}`,
|
|
316
|
-
parsed,
|
|
317
|
-
() => attempt(
|
|
318
|
-
parsed,
|
|
319
|
-
Effect_exports.scoped(
|
|
320
|
-
Effect_exports.gen(function* () {
|
|
321
|
-
const controller = yield* Effect_exports.acquireRelease(
|
|
322
|
-
Effect_exports.sync(() => new AbortController()),
|
|
323
|
-
(controller2) => Effect_exports.sync(() => controller2.abort())
|
|
324
|
-
);
|
|
325
|
-
const step2 = yield* fresh(stepId, AbortSignal.any([signal, controller.signal]));
|
|
326
|
-
const result = yield* workflowSafe(
|
|
327
|
-
Effect_exports.tryPromise({
|
|
328
|
-
try: () => callback(step2.context),
|
|
329
|
-
catch: (error) => error
|
|
330
|
-
}),
|
|
331
|
-
step2.secrets
|
|
332
|
-
);
|
|
333
|
-
return yield* Schema_exports.decodeUnknownEffect(WorkflowValue)(result).pipe(
|
|
334
|
-
Effect_exports.mapError(
|
|
335
|
-
() => new WorkflowFailure({
|
|
336
|
-
reason: "output",
|
|
337
|
-
retryable: false,
|
|
338
|
-
message: "The step returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
|
|
339
|
-
})
|
|
340
|
-
)
|
|
341
|
-
);
|
|
342
|
-
})
|
|
343
|
-
).pipe(Effect_exports.provideContext(services))
|
|
344
|
-
)
|
|
345
|
-
).pipe(Effect_exports.mapError(inStep(name)));
|
|
346
|
-
});
|
|
347
|
-
const operationStep = (kind, name, operation, input, options) => Effect_exports.gen(function* () {
|
|
348
|
-
const target = nativeOperation(operation);
|
|
349
|
-
const catalog = kind === "query" ? definition.queries : definition.mutations;
|
|
350
|
-
const match = Object.entries(catalog ?? {}).find(
|
|
351
|
-
([, value]) => value === target && value.kind === kind
|
|
352
|
-
);
|
|
353
|
-
if (target === void 0 || match === void 0)
|
|
354
|
-
return yield* new WorkflowFailure({ reason: "operation", retryable: false });
|
|
355
|
-
const args = yield* Schema_exports.decodeUnknownEffect(JsonValue)(input).pipe(
|
|
356
|
-
Effect_exports.mapError(() => new WorkflowFailure({ reason: "input", retryable: false }))
|
|
357
|
-
);
|
|
358
|
-
const parsed = yield* Schema_exports.decodeUnknownEffect(WorkflowStepOptions)(options).pipe(
|
|
359
|
-
Effect_exports.mapError(() => new WorkflowFailure({ reason: "input", retryable: false }))
|
|
360
|
-
);
|
|
361
|
-
const stepId = yield* identify(kind, name);
|
|
362
|
-
const timeout = workflowDurationMillis(parsed.timeout ?? "10 minutes");
|
|
363
|
-
if (timeout === void 0)
|
|
364
|
-
return yield* new WorkflowFailure({ reason: "input", retryable: false });
|
|
365
|
-
return yield* execution.driver.do(
|
|
366
|
-
`${kind}:${name.slice(0, 100)}:${stepId}`,
|
|
367
|
-
parsed,
|
|
368
|
-
() => attempt(
|
|
369
|
-
parsed,
|
|
370
|
-
execution.invoke({ kind, name: match[0], input: args, stepId, timeout }).pipe(Effect_exports.provideContext(services))
|
|
371
|
-
)
|
|
372
|
-
).pipe(Effect_exports.mapError(inStep(name)));
|
|
373
|
-
});
|
|
374
|
-
const invoke = (effect) => toPromise(() => effect.pipe(Effect_exports.provideContext(services)), signal)();
|
|
375
|
-
const step = {
|
|
376
|
-
do: (name, options, run) => {
|
|
377
|
-
const callback = typeof options === "function" ? options : run;
|
|
378
|
-
if (callback === void 0)
|
|
379
|
-
return Promise.reject(new WorkflowFailure({ reason: "input", retryable: false }));
|
|
380
|
-
return invoke(runStep(name, typeof options === "function" ? {} : options, callback));
|
|
381
|
-
},
|
|
382
|
-
runQuery: (name, operation, input, options = {}) => invoke(operationStep("query", name, operation, input, options)),
|
|
383
|
-
runMutation: (name, operation, input, options = {}) => invoke(operationStep("mutation", name, operation, input, options)),
|
|
384
|
-
sleep: (name, duration) => invoke(
|
|
385
|
-
Schema_exports.decodeUnknownEffect(WorkflowDuration)(duration).pipe(
|
|
386
|
-
Effect_exports.mapError(() => new WorkflowFailure({ reason: "input", retryable: false })),
|
|
387
|
-
Effect_exports.flatMap(
|
|
388
|
-
(parsed) => identify("sleep", name).pipe(
|
|
389
|
-
Effect_exports.flatMap(
|
|
390
|
-
(id) => execution.driver.sleep(`sleep:${name.slice(0, 100)}:${id}`, parsed)
|
|
391
|
-
)
|
|
392
|
-
)
|
|
393
|
-
)
|
|
394
|
-
)
|
|
395
|
-
),
|
|
396
|
-
sleepUntil: (name, timestamp) => invoke(
|
|
397
|
-
identify("until", name).pipe(
|
|
398
|
-
Effect_exports.flatMap(
|
|
399
|
-
(id) => execution.driver.sleepUntil(
|
|
400
|
-
`until:${name.slice(0, 100)}:${id}`,
|
|
401
|
-
timestamp instanceof Date ? timestamp.getTime() : timestamp
|
|
402
|
-
)
|
|
403
|
-
)
|
|
404
|
-
)
|
|
405
|
-
)
|
|
406
|
-
};
|
|
407
|
-
return { runId: execution.runId, step };
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
// src/implementation/input-problems.ts
|
|
411
|
-
var leafHook = (issue) => SchemaIssue_exports.hasInput(issue) ? "Invalid value" : SchemaIssue_exports.defaultLeafHook(issue);
|
|
412
|
-
var checkHook = (issue) => SchemaIssue_exports.hasInput(issue) || SchemaIssue_exports.hasInput(issue.issue) ? SchemaIssue_exports.defaultCheckHook(issue) ?? "Invalid value" : SchemaIssue_exports.defaultCheckHook(issue);
|
|
413
|
-
var format = SchemaIssue_exports.makeFormatterStandardSchemaV1({ leafHook, checkHook });
|
|
414
|
-
var segment = (key) => typeof key === "number" ? `[${key}]` : typeof key === "string" && /^[A-Za-z_$][\w$-]{0,63}$/.test(key) ? `.${key}` : "[key]";
|
|
415
|
-
var inputInvalid = (error) => {
|
|
416
|
-
if (!Schema_exports.isSchemaError(error)) return new HostInputInvalid();
|
|
417
|
-
const problems = format(error.issue).issues.slice(0, maxInputProblems).map(({ path, message }) => {
|
|
418
|
-
const location = (path ?? []).map((key) => segment(typeof key === "object" ? key.key : key));
|
|
419
|
-
return `${location.length === 0 ? "input" : `input${location.join("")}`}: ${message}`.slice(
|
|
420
|
-
0,
|
|
421
|
-
512
|
|
422
|
-
);
|
|
423
|
-
});
|
|
424
|
-
return new HostInputInvalid({ problems });
|
|
425
|
-
};
|
|
426
|
-
|
|
427
|
-
// src/implementation/webhooks.ts
|
|
428
|
-
var safe = (work, error) => Effect_exports.suspend(work).pipe(
|
|
429
|
-
Effect_exports.catchCause(
|
|
430
|
-
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(error)
|
|
431
|
-
)
|
|
432
|
-
);
|
|
433
|
-
var dispatchWebhook = (definition, command, context, accounts) => Effect_exports.gen(function* () {
|
|
434
|
-
const hooks = definition.webhooks ?? {};
|
|
435
|
-
if (command.operation === "webhooks") {
|
|
436
|
-
return yield* Effect_exports.forEach(
|
|
437
|
-
Object.entries(hooks),
|
|
438
|
-
([name, hook2]) => safe(
|
|
439
|
-
() => Effect_exports.gen(function* () {
|
|
440
|
-
if (!Object.hasOwn(accounts, hook2.account))
|
|
441
|
-
return yield* new HostDeclarationInvalid();
|
|
442
|
-
const describe = (schema) => {
|
|
443
|
-
const imported = importedJsonSchema(schema);
|
|
444
|
-
if (imported !== void 0) return Schema_exports.decodeUnknownEffect(JsonObject)(imported);
|
|
445
|
-
const document = Schema_exports.toJsonSchemaDocument(schema);
|
|
446
|
-
return Schema_exports.decodeUnknownEffect(JsonObject)({
|
|
447
|
-
...document.schema,
|
|
448
|
-
$defs: document.definitions
|
|
449
|
-
});
|
|
450
|
-
};
|
|
451
|
-
const configSchema = yield* describe(hook2.config);
|
|
452
|
-
if (hook2.setup === void 0 ? hook2.register === void 0 || hook2.unregister === void 0 : hook2.register !== void 0 || hook2.unregister !== void 0)
|
|
453
|
-
return yield* new HostDeclarationInvalid();
|
|
454
|
-
const setup = hook2.setup === void 0 ? void 0 : {
|
|
455
|
-
...yield* Schema_exports.decodeUnknownEffect(ManualWebhookSetup)(hook2.setup),
|
|
456
|
-
stateSchema: yield* describe(hook2.state)
|
|
457
|
-
};
|
|
458
|
-
return yield* Schema_exports.decodeUnknownEffect(HostedWebhook)({
|
|
459
|
-
name,
|
|
460
|
-
account: hook2.account,
|
|
461
|
-
configSchema,
|
|
462
|
-
...setup === void 0 ? {} : { setup }
|
|
463
|
-
});
|
|
464
|
-
}),
|
|
465
|
-
new HostDeclarationInvalid()
|
|
466
|
-
)
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
const hook = Object.hasOwn(hooks, command.name) ? hooks[command.name] : void 0;
|
|
470
|
-
if (hook === void 0) return yield* new HostOperationNotFound();
|
|
471
|
-
const selected = accounts[hook.account];
|
|
472
|
-
const source = Array.isArray(selected) ? selected.find((account2) => account2.id === command.sourceAccount) : selected;
|
|
473
|
-
if (source === void 0 || source.id !== command.sourceAccount)
|
|
474
|
-
return yield* new HostInputInvalid();
|
|
475
|
-
const bound = context.accounts[hook.account];
|
|
476
|
-
const account = Array.isArray(bound) ? bound.find(
|
|
477
|
-
(value) => typeof value === "object" && value !== null && "id" in value && value.id === source.id
|
|
478
|
-
) : bound;
|
|
479
|
-
const config = yield* safe(
|
|
480
|
-
() => Schema_exports.decodeUnknownEffect(hook.config)(command.config),
|
|
481
|
-
new HostInputInvalid()
|
|
482
|
-
);
|
|
483
|
-
if (command.operation === "webhook-validate")
|
|
484
|
-
return yield* safe(
|
|
485
|
-
() => Schema_exports.decodeUnknownEffect(JsonValue)(config),
|
|
486
|
-
new HostInputInvalid()
|
|
487
|
-
);
|
|
488
|
-
const input = {
|
|
489
|
-
config,
|
|
490
|
-
subscriptionId: command.subscriptionId,
|
|
491
|
-
account,
|
|
492
|
-
callbackUrl: command.callbackUrl,
|
|
493
|
-
secret: command.secret
|
|
494
|
-
};
|
|
495
|
-
const invoke = (callback, value) => safe(() => callback(context, value), new HostOperationFailed());
|
|
496
|
-
if (command.operation === "webhook-complete") {
|
|
497
|
-
if (hook.setup === void 0) return yield* new HostInputInvalid();
|
|
498
|
-
return yield* safe(
|
|
499
|
-
() => Schema_exports.decodeUnknownEffect(hook.state)(command.state).pipe(
|
|
500
|
-
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
|
|
501
|
-
),
|
|
502
|
-
new HostInputInvalid()
|
|
503
|
-
);
|
|
504
|
-
}
|
|
505
|
-
if (command.operation === "webhook-register") {
|
|
506
|
-
if (hook.register === void 0 || hook.setup !== void 0)
|
|
507
|
-
return yield* new HostOperationFailed();
|
|
508
|
-
const state2 = yield* invoke(hook.register, input);
|
|
509
|
-
return yield* safe(
|
|
510
|
-
() => Schema_exports.decodeUnknownEffect(hook.state)(state2).pipe(
|
|
511
|
-
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
|
|
512
|
-
),
|
|
513
|
-
new HostOutputInvalid()
|
|
514
|
-
);
|
|
515
|
-
}
|
|
516
|
-
const state = command.state === null ? null : yield* safe(
|
|
517
|
-
() => Schema_exports.decodeUnknownEffect(hook.state)(command.state),
|
|
518
|
-
new HostInputInvalid()
|
|
519
|
-
);
|
|
520
|
-
if (command.operation === "webhook-unregister") {
|
|
521
|
-
if (hook.unregister === void 0 || hook.setup !== void 0)
|
|
522
|
-
return yield* new HostOperationFailed();
|
|
523
|
-
yield* invoke(hook.unregister, { ...input, state });
|
|
524
|
-
return null;
|
|
525
|
-
}
|
|
526
|
-
const body = yield* Effect_exports.fromResult(Encoding_exports.decodeBase64(command.request.body)).pipe(
|
|
527
|
-
Effect_exports.mapError(() => new HostInputInvalid())
|
|
528
|
-
);
|
|
529
|
-
if (body.byteLength > defaultWebhookTransportLimits.maxBodyBytes)
|
|
530
|
-
return yield* new HostInputInvalid();
|
|
531
|
-
const request = yield* safe(
|
|
532
|
-
() => Effect_exports.sync(
|
|
533
|
-
() => new Request(command.request.url, {
|
|
534
|
-
method: command.request.method,
|
|
535
|
-
headers: command.request.headers,
|
|
536
|
-
...context.signal === void 0 ? {} : { signal: context.signal },
|
|
537
|
-
...command.request.method === "GET" || command.request.method === "HEAD" ? {} : { body: Uint8Array.from(body) }
|
|
538
|
-
})
|
|
539
|
-
),
|
|
540
|
-
new HostInputInvalid()
|
|
541
|
-
);
|
|
542
|
-
const response = yield* invoke(hook.handle, { ...input, state, request });
|
|
543
|
-
if (!(response instanceof Response)) return yield* new HostOutputInvalid();
|
|
544
|
-
const chunks = [];
|
|
545
|
-
let size = 0;
|
|
546
|
-
const stream = response.body;
|
|
547
|
-
if (stream !== null)
|
|
548
|
-
yield* Stream_exports.fromReadableStream({
|
|
549
|
-
evaluate: () => stream,
|
|
550
|
-
onError: () => new HostOutputInvalid()
|
|
551
|
-
}).pipe(
|
|
552
|
-
Stream_exports.runForEach(
|
|
553
|
-
(chunk) => Effect_exports.gen(function* () {
|
|
554
|
-
size += chunk.byteLength;
|
|
555
|
-
if (size > defaultWebhookTransportLimits.maxBodyBytes)
|
|
556
|
-
return yield* new HostOutputInvalid();
|
|
557
|
-
chunks.push(chunk);
|
|
558
|
-
})
|
|
559
|
-
)
|
|
560
|
-
);
|
|
561
|
-
const bytes = new Uint8Array(size);
|
|
562
|
-
let offset = 0;
|
|
563
|
-
for (const chunk of chunks) {
|
|
564
|
-
bytes.set(chunk, offset);
|
|
565
|
-
offset += chunk.byteLength;
|
|
566
|
-
}
|
|
567
|
-
const headers = {};
|
|
568
|
-
response.headers.forEach((value, name) => {
|
|
569
|
-
headers[name] = value;
|
|
570
|
-
});
|
|
571
|
-
return yield* safe(
|
|
572
|
-
() => Schema_exports.decodeUnknownEffect(WebhookResponseData)({
|
|
573
|
-
status: response.status,
|
|
574
|
-
headers,
|
|
575
|
-
body: Encoding_exports.encodeBase64(new Uint8Array(bytes))
|
|
576
|
-
}),
|
|
577
|
-
new HostOutputInvalid()
|
|
578
|
-
);
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
// src/implementation/cache.ts
|
|
582
|
-
var unavailableCache = {
|
|
583
|
-
transport: () => Effect_exports.fail(new CacheError({ reason: "unavailable" })),
|
|
584
|
-
background: () => Effect_exports.die(new Error("Cache background runner is unavailable"))
|
|
585
|
-
};
|
|
586
|
-
var authorCache = (host, accounts, signal, deadline) => {
|
|
587
|
-
const scoped = (scope, callerSignal = signal) => {
|
|
588
|
-
const cache = makeCache(host.transport, host.background, scope, deadline);
|
|
589
|
-
const load = (method, options) => cache[method]({
|
|
590
|
-
key: options.key,
|
|
591
|
-
schema: decoderOf(options.schema),
|
|
592
|
-
freshFor: options.freshFor,
|
|
593
|
-
...options.staleFor === void 0 ? {} : { staleFor: options.staleFor },
|
|
594
|
-
load: Effect_exports.acquireUseRelease(
|
|
595
|
-
Effect_exports.sync(() => new AbortController()),
|
|
596
|
-
(controller) => invocationFetch(controller.signal).pipe(
|
|
597
|
-
Effect_exports.flatMap(
|
|
598
|
-
(fetch) => fromPromise(options.load)({
|
|
599
|
-
fetch,
|
|
600
|
-
signal: controller.signal,
|
|
601
|
-
cache: scoped(scope, controller.signal)
|
|
602
|
-
})
|
|
603
|
-
)
|
|
604
|
-
),
|
|
605
|
-
(controller) => Effect_exports.sync(() => controller.abort())
|
|
606
|
-
)
|
|
607
|
-
});
|
|
608
|
-
return {
|
|
609
|
-
get: toPromise((options) => load("get", options), callerSignal),
|
|
610
|
-
revalidate: toPromise(
|
|
611
|
-
(options) => load("revalidate", options),
|
|
612
|
-
callerSignal
|
|
613
|
-
),
|
|
614
|
-
read: toPromise(
|
|
615
|
-
(key, schema) => cache.read([key]).pipe(
|
|
616
|
-
Effect_exports.flatMap((entries) => {
|
|
617
|
-
const entry = entries[0];
|
|
618
|
-
return entry === void 0 || entry === null ? Effect_exports.succeed(void 0) : Schema_exports.decodeUnknownEffect(decoderOf(schema))(entry.value);
|
|
619
|
-
})
|
|
620
|
-
),
|
|
621
|
-
callerSignal
|
|
622
|
-
),
|
|
623
|
-
readMany: toPromise(
|
|
624
|
-
(keys, schema) => cache.read(keys).pipe(
|
|
625
|
-
Effect_exports.flatMap(
|
|
626
|
-
(entries) => Effect_exports.forEach(
|
|
627
|
-
entries,
|
|
628
|
-
(entry) => entry === null ? Effect_exports.succeed(void 0) : Schema_exports.decodeUnknownEffect(decoderOf(schema))(entry.value)
|
|
629
|
-
)
|
|
630
|
-
)
|
|
631
|
-
),
|
|
632
|
-
callerSignal
|
|
633
|
-
),
|
|
634
|
-
write: toPromise(cache.write, callerSignal),
|
|
635
|
-
invalidate: toPromise(cache.invalidate, callerSignal),
|
|
636
|
-
forAccount: (account) => {
|
|
637
|
-
const bound = Object.values(accounts).flatMap((value) => Array.isArray(value) ? value : [value]).find((value) => value.id === account.id);
|
|
638
|
-
if (bound === void 0) throw new CacheError({ reason: "invalid" });
|
|
639
|
-
return scoped(
|
|
640
|
-
{ account: bound.id, method: bound.method, generation: bound.generation },
|
|
641
|
-
callerSignal
|
|
642
|
-
);
|
|
643
|
-
}
|
|
644
|
-
};
|
|
645
|
-
};
|
|
646
|
-
return scoped("shared");
|
|
647
|
-
};
|
|
648
|
-
|
|
649
|
-
// src/implementation/host.ts
|
|
650
|
-
function safe2(work, failure) {
|
|
651
|
-
return Effect_exports.suspend(work).pipe(
|
|
652
|
-
Effect_exports.catchCause(
|
|
653
|
-
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(failure)
|
|
654
|
-
)
|
|
655
|
-
);
|
|
656
|
-
}
|
|
657
|
-
var evaluationSafe = (work, secrets) => work.pipe(
|
|
658
|
-
Effect_exports.catchCause((cause) => {
|
|
659
|
-
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
660
|
-
const error = Cause_exports.squash(cause);
|
|
661
|
-
const provider = parseProviderError(error);
|
|
662
|
-
const skills = parseSkillLoadFailed(error);
|
|
663
|
-
const mcp = parseMcpError(error);
|
|
664
|
-
return Effect_exports.fail(
|
|
665
|
-
Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(skills) ? skills.value : Option_exports.isSome(mcp) ? mcp.value : new HostEvaluationFailed(failureDetail(error, secrets))
|
|
666
|
-
);
|
|
667
|
-
})
|
|
668
|
-
);
|
|
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
|
-
var declarationInvalid = (summary, cause, secrets = []) => new HostDeclarationInvalid({
|
|
680
|
-
source: "app",
|
|
681
|
-
errorName: "HostDeclarationInvalid",
|
|
682
|
-
message: boundFailureMessage(
|
|
683
|
-
cause === void 0 ? summary : `${summary}: ${describeFailure(cause)}`,
|
|
684
|
-
secrets
|
|
685
|
-
)
|
|
686
|
-
});
|
|
687
|
-
var declarationSafe = (work, summary) => Effect_exports.suspend(work).pipe(
|
|
688
|
-
Effect_exports.catchCause(
|
|
689
|
-
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(declarationInvalid(summary, Cause_exports.squash(cause)))
|
|
690
|
-
)
|
|
691
|
-
);
|
|
692
|
-
function providerDeclaration(provider) {
|
|
693
|
-
return declarationSafe(
|
|
694
|
-
() => Effect_exports.gen(function* () {
|
|
695
|
-
const auth = /* @__PURE__ */ new Map();
|
|
696
|
-
for (const [name, method] of Object.entries(provider.auth)) {
|
|
697
|
-
switch (method._tag) {
|
|
698
|
-
case "secrets":
|
|
699
|
-
auth.set(name, {
|
|
700
|
-
type: "secrets",
|
|
701
|
-
label: method.label,
|
|
702
|
-
fields: yield* jsonSchema(method.fields)
|
|
703
|
-
});
|
|
704
|
-
break;
|
|
705
|
-
case "oauth2":
|
|
706
|
-
auth.set(name, {
|
|
707
|
-
type: "oauth2",
|
|
708
|
-
...method.config,
|
|
709
|
-
response: yield* jsonSchema(method.response)
|
|
710
|
-
});
|
|
711
|
-
break;
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
return yield* Schema_exports.decodeUnknownEffect(DeclaredProvider)({
|
|
715
|
-
name: provider.name,
|
|
716
|
-
auth: Object.fromEntries(auth)
|
|
717
|
-
});
|
|
718
|
-
}),
|
|
719
|
-
`Account provider "${provider.name}" has an invalid declaration`
|
|
720
|
-
);
|
|
721
|
-
}
|
|
722
|
-
function requirements(slots, database) {
|
|
723
|
-
return Effect_exports.gen(function* () {
|
|
724
|
-
const accounts = /* @__PURE__ */ new Map();
|
|
725
|
-
for (const [slot, selection] of Object.entries(slots)) {
|
|
726
|
-
accounts.set(slot, {
|
|
727
|
-
cardinality: selection instanceof ManyAccounts ? "many" : "one",
|
|
728
|
-
definition: yield* providerDeclaration(
|
|
729
|
-
selection instanceof ManyAccounts ? selection.provider : selection
|
|
730
|
-
)
|
|
731
|
-
});
|
|
732
|
-
}
|
|
733
|
-
return yield* Schema_exports.decodeUnknownEffect(DeclaredRequirements)({
|
|
734
|
-
accounts: Object.fromEntries(accounts),
|
|
735
|
-
capabilities: { skills: true, toolIndex: true, skillSources: true, scheduledTools: true },
|
|
736
|
-
...database === void 0 ? {} : { database }
|
|
737
|
-
}).pipe(
|
|
738
|
-
Effect_exports.mapError(
|
|
739
|
-
(cause) => declarationInvalid("The app's account or database declarations are invalid", cause)
|
|
740
|
-
)
|
|
741
|
-
);
|
|
742
|
-
});
|
|
743
|
-
}
|
|
744
|
-
function canonical(value) {
|
|
745
|
-
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
746
|
-
if (value !== null && typeof value === "object") {
|
|
747
|
-
return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(",")}}`;
|
|
748
|
-
}
|
|
749
|
-
return JSON.stringify(value);
|
|
750
|
-
}
|
|
751
|
-
function bindAccounts(slots, declarations, context) {
|
|
752
|
-
return safe2(
|
|
753
|
-
() => Effect_exports.gen(function* () {
|
|
754
|
-
const selected = yield* Schema_exports.decodeUnknownEffect(ResolvedAccounts)(
|
|
755
|
-
Redacted_exports.value(context.accounts)
|
|
756
|
-
);
|
|
757
|
-
if (Object.keys(selected).some((slot) => !Object.hasOwn(slots, slot))) {
|
|
758
|
-
return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
759
|
-
}
|
|
760
|
-
const bound = /* @__PURE__ */ new Map();
|
|
761
|
-
for (const [slot, selection] of Object.entries(slots)) {
|
|
762
|
-
const requirement = declarations.accounts[slot];
|
|
763
|
-
const supplied = Object.hasOwn(selected, slot) ? selected[slot] : void 0;
|
|
764
|
-
if (requirement === void 0 || supplied === void 0)
|
|
765
|
-
return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
766
|
-
const provider = selection instanceof ManyAccounts ? selection.provider : selection;
|
|
767
|
-
const many = selection instanceof ManyAccounts;
|
|
768
|
-
if (many !== Array.isArray(supplied))
|
|
769
|
-
return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
770
|
-
const accounts = Array.isArray(supplied) ? supplied : [supplied];
|
|
771
|
-
const ids = /* @__PURE__ */ new Set();
|
|
772
|
-
const values = [];
|
|
773
|
-
for (const account of accounts) {
|
|
774
|
-
if (ids.has(account.id)) return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
775
|
-
ids.add(account.id);
|
|
776
|
-
if (canonical(account.provider) !== canonical(requirement.definition) || !Object.hasOwn(provider.auth, account.method))
|
|
777
|
-
return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
778
|
-
const method = provider.auth[account.method];
|
|
779
|
-
if (method === void 0) return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
780
|
-
const fields = yield* Schema_exports.decodeUnknownEffect(
|
|
781
|
-
method._tag === "secrets" ? method.fields : method.response
|
|
782
|
-
)(account.fields);
|
|
783
|
-
values.push({ id: account.id, method: account.method, fields });
|
|
784
|
-
}
|
|
785
|
-
if (many) bound.set(slot, values);
|
|
786
|
-
else {
|
|
787
|
-
const account = values[0];
|
|
788
|
-
if (account === void 0) return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
789
|
-
bound.set(slot, account);
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
return { accounts: Object.fromEntries(bound) };
|
|
793
|
-
}),
|
|
794
|
-
new HostAccountsInvalid()
|
|
795
|
-
);
|
|
796
|
-
}
|
|
797
|
-
function dispatch(app, request, context, signal) {
|
|
798
|
-
return Effect_exports.scoped(
|
|
799
|
-
Effect_exports.gen(function* () {
|
|
800
|
-
if (!isApp(app))
|
|
801
|
-
return yield* Effect_exports.fail(
|
|
802
|
-
declarationInvalid("The app module's default export is not an app created by defineApp")
|
|
803
|
-
);
|
|
804
|
-
const native = toEffectApp(app);
|
|
805
|
-
const secrets = accountSecrets(context.accounts);
|
|
806
|
-
const storageFailure = (error) => Effect_exports.fail(new HostOperationFailed(failureDetail(error, secrets)));
|
|
807
|
-
const declared = yield* requirements(native.accounts, native.database?.schema);
|
|
808
|
-
if (request.operation === "requirements") {
|
|
809
|
-
if (native.database !== void 0)
|
|
810
|
-
yield* parseDatabaseSchema(native.database.schema).pipe(
|
|
811
|
-
Effect_exports.catchTag(
|
|
812
|
-
"AppDatabaseError",
|
|
813
|
-
(cause) => Effect_exports.fail(
|
|
814
|
-
declarationInvalid("The app's account or database declarations are invalid", cause)
|
|
815
|
-
)
|
|
816
|
-
)
|
|
817
|
-
);
|
|
818
|
-
return yield* safe2(
|
|
819
|
-
() => Schema_exports.decodeUnknownEffect(JsonValue)(declared),
|
|
820
|
-
new HostDeclarationInvalid()
|
|
821
|
-
);
|
|
822
|
-
}
|
|
823
|
-
const lifetime = yield* Effect_exports.acquireRelease(
|
|
824
|
-
Effect_exports.sync(() => new AbortController()),
|
|
825
|
-
(controller) => Effect_exports.sync(() => controller.abort())
|
|
826
|
-
);
|
|
827
|
-
const invocationSignal = AbortSignal.any([signal, lifetime.signal]);
|
|
828
|
-
const deadline = context.deadline === void 0 ? void 0 : yield* safe2(
|
|
829
|
-
() => Schema_exports.decodeUnknownEffect(InvocationDeadline)(context.deadline),
|
|
830
|
-
new HostInputInvalid()
|
|
831
|
-
);
|
|
832
|
-
const withinDeadline = (work) => Effect_exports.gen(function* () {
|
|
833
|
-
if (deadline === void 0) return yield* work;
|
|
834
|
-
const remaining = deadline - (yield* Clock_exports.currentTimeMillis);
|
|
835
|
-
if (remaining <= 0)
|
|
836
|
-
return yield* new WorkflowFailure({ reason: "engine", retryable: true });
|
|
837
|
-
const result = yield* work.pipe(
|
|
838
|
-
Effect_exports.timeout(remaining),
|
|
839
|
-
Effect_exports.catchTag(
|
|
840
|
-
"TimeoutError",
|
|
841
|
-
() => Effect_exports.fail(new WorkflowFailure({ reason: "engine", retryable: true }))
|
|
842
|
-
)
|
|
843
|
-
);
|
|
844
|
-
if ((yield* Clock_exports.currentTimeMillis) >= deadline)
|
|
845
|
-
return yield* new WorkflowFailure({ reason: "engine", retryable: true });
|
|
846
|
-
return result;
|
|
847
|
-
});
|
|
848
|
-
let running;
|
|
849
|
-
let transactionOpen = false;
|
|
850
|
-
const delivery = (request2, signal2) => Effect_exports.suspend(
|
|
851
|
-
() => transactionOpen ? Effect_exports.fail(new ElicitationFailed({ reason: "transaction" })) : running !== void 0 && context.elicitation !== void 0 ? context.elicitation(request2, signal2).pipe(
|
|
852
|
-
Effect_exports.withSpan("app.tool.elicitation"),
|
|
853
|
-
Effect_exports.provideContext(running.context)
|
|
854
|
-
) : Effect_exports.fail(new ElicitationFailed({ reason: "unavailable" }))
|
|
855
|
-
);
|
|
856
|
-
const unavailableWorkflow = () => Effect_exports.fail(new WorkflowFailure({ reason: "unavailable", retryable: false }));
|
|
857
|
-
const workflowControls = {
|
|
858
|
-
start: toPromise(
|
|
859
|
-
(input2) => context.workflowControls === void 0 ? unavailableWorkflow() : context.workflowControls.start(input2),
|
|
860
|
-
invocationSignal
|
|
861
|
-
),
|
|
862
|
-
get: toPromise(
|
|
863
|
-
(input2) => context.workflowControls === void 0 ? unavailableWorkflow() : context.workflowControls.get(input2),
|
|
864
|
-
invocationSignal
|
|
865
|
-
),
|
|
866
|
-
list: toPromise(
|
|
867
|
-
(input2) => context.workflowControls === void 0 ? unavailableWorkflow() : context.workflowControls.list(input2),
|
|
868
|
-
invocationSignal
|
|
869
|
-
),
|
|
870
|
-
terminate: toPromise(
|
|
871
|
-
(input2) => context.workflowControls === void 0 ? unavailableWorkflow() : context.workflowControls.terminate(input2),
|
|
872
|
-
invocationSignal
|
|
873
|
-
)
|
|
874
|
-
};
|
|
875
|
-
const workflowReads = {
|
|
876
|
-
get: workflowControls.get,
|
|
877
|
-
list: workflowControls.list
|
|
878
|
-
};
|
|
879
|
-
const files = yield* Schema_exports.decodeUnknownEffect(Schema_exports.Array(SkillFile))(
|
|
880
|
-
context.files ?? []
|
|
881
|
-
).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
|
|
882
|
-
let cacheCommands = 0;
|
|
883
|
-
const hostCache = context.cache ?? unavailableCache;
|
|
884
|
-
const bound = {
|
|
885
|
-
cache: authorCache(
|
|
886
|
-
{
|
|
887
|
-
...hostCache,
|
|
888
|
-
transport: (command) => {
|
|
889
|
-
cacheCommands += 1;
|
|
890
|
-
return hostCache.transport(command);
|
|
891
|
-
}
|
|
892
|
-
},
|
|
893
|
-
Redacted_exports.value(context.accounts),
|
|
894
|
-
invocationSignal,
|
|
895
|
-
deadline
|
|
896
|
-
),
|
|
897
|
-
files,
|
|
898
|
-
...yield* bindAccounts(native.accounts, declared, context).pipe(
|
|
899
|
-
Effect_exports.withSpan("app.accounts.bind")
|
|
900
|
-
),
|
|
901
|
-
workflows: workflowReads,
|
|
902
|
-
signal: invocationSignal,
|
|
903
|
-
fetch: yield* invocationFetch(invocationSignal),
|
|
904
|
-
elicit: makeElicit(delivery, invocationSignal)
|
|
905
|
-
};
|
|
906
|
-
const definition = yield* evaluationSafe(native.evaluate(bound), secrets).pipe(
|
|
907
|
-
Effect_exports.withSpan("app.evaluate")
|
|
908
|
-
);
|
|
909
|
-
if (request.operation === "skills") {
|
|
910
|
-
const declared2 = definition.skills ?? (yield* folderSkillsEffect({ files }).pipe(
|
|
911
|
-
Effect_exports.mapError(() => new HostDeclarationInvalid())
|
|
912
|
-
));
|
|
913
|
-
const source2 = definition.dynamicSkills;
|
|
914
|
-
const before = cacheCommands;
|
|
915
|
-
const dynamic = source2 === void 0 ? [] : yield* evaluationSafe(Effect_exports.suspend(source2.list), secrets).pipe(
|
|
916
|
-
Effect_exports.withSpan("app.skills.load")
|
|
917
|
-
);
|
|
918
|
-
const cached = source2 !== void 0 && cacheCommands > before;
|
|
919
|
-
const skills = yield* Schema_exports.decodeUnknownEffect(AppSkills)([...declared2, ...dynamic]).pipe(
|
|
920
|
-
Effect_exports.mapError(() => new HostDeclarationInvalid())
|
|
921
|
-
);
|
|
922
|
-
return request.sources === true ? { skills, dynamic: source2 !== void 0, cached } : skills;
|
|
923
|
-
}
|
|
924
|
-
if (request.operation === "workflows") {
|
|
925
|
-
return yield* Effect_exports.forEach(
|
|
926
|
-
Object.entries(definition.workflows ?? {}),
|
|
927
|
-
([name2, entry]) => safe2(
|
|
928
|
-
() => Effect_exports.gen(function* () {
|
|
929
|
-
return yield* Schema_exports.decodeUnknownEffect(HostedWorkflow)({
|
|
930
|
-
name: name2,
|
|
931
|
-
...entry.description === void 0 ? {} : { description: entry.description },
|
|
932
|
-
inputSchema: yield* jsonSchema(entry.input),
|
|
933
|
-
...entry.output === void 0 ? {} : { outputSchema: yield* jsonSchema(entry.output) }
|
|
934
|
-
});
|
|
935
|
-
}),
|
|
936
|
-
new HostDeclarationInvalid()
|
|
937
|
-
)
|
|
938
|
-
);
|
|
939
|
-
}
|
|
940
|
-
if (request.operation === "workflow-validate" || request.operation === "workflow-run") {
|
|
941
|
-
const entry = definition.workflows !== void 0 && Object.hasOwn(definition.workflows, request.name) ? definition.workflows[request.name] : void 0;
|
|
942
|
-
if (entry === void 0)
|
|
943
|
-
return yield* new WorkflowFailure({ reason: "not_found", retryable: false });
|
|
944
|
-
const input2 = yield* safe2(
|
|
945
|
-
() => Schema_exports.decodeUnknownEffect(entry.input)(request.input),
|
|
946
|
-
new WorkflowFailure({ reason: "input", retryable: false })
|
|
947
|
-
);
|
|
948
|
-
if (request.operation === "workflow-validate")
|
|
949
|
-
return yield* safe2(
|
|
950
|
-
() => Schema_exports.decodeUnknownEffect(WorkflowValue)(input2),
|
|
951
|
-
new WorkflowFailure({ reason: "input", retryable: false })
|
|
952
|
-
);
|
|
953
|
-
const execution = context.workflow;
|
|
954
|
-
if (execution === void 0)
|
|
955
|
-
return yield* new WorkflowFailure({ reason: "unavailable", retryable: false });
|
|
956
|
-
const workflowContext = yield* makeWorkflowContext(
|
|
957
|
-
execution,
|
|
958
|
-
definition,
|
|
959
|
-
(stepId, signal2) => Effect_exports.gen(function* () {
|
|
960
|
-
const current = yield* execution.resolve();
|
|
961
|
-
const accounts = yield* safe2(
|
|
962
|
-
() => bindAccounts(native.accounts, declared, current),
|
|
963
|
-
new WorkflowFailure({ reason: "credentials", retryable: false })
|
|
964
|
-
);
|
|
965
|
-
return {
|
|
966
|
-
context: {
|
|
967
|
-
...accounts,
|
|
968
|
-
cache: authorCache(
|
|
969
|
-
context.cache ?? unavailableCache,
|
|
970
|
-
Redacted_exports.value(current.accounts),
|
|
971
|
-
signal2
|
|
972
|
-
),
|
|
973
|
-
files,
|
|
974
|
-
fetch: yield* invocationFetch(signal2),
|
|
975
|
-
signal: signal2,
|
|
976
|
-
runId: execution.runId,
|
|
977
|
-
stepId,
|
|
978
|
-
idempotencyKey: stepId
|
|
979
|
-
},
|
|
980
|
-
// The resolved values, not the app's decoded fields, which may be `Redacted`.
|
|
981
|
-
secrets: accountSecrets(current.accounts)
|
|
982
|
-
};
|
|
983
|
-
}),
|
|
984
|
-
invocationSignal
|
|
985
|
-
);
|
|
986
|
-
const output = yield* workflowSafe(entry.run(workflowContext, input2), secrets);
|
|
987
|
-
const outputSchema = entry.output;
|
|
988
|
-
const decoded = outputSchema === void 0 ? output : yield* safe2(
|
|
989
|
-
() => Schema_exports.decodeUnknownEffect(outputSchema)(output),
|
|
990
|
-
new WorkflowFailure({
|
|
991
|
-
reason: "output",
|
|
992
|
-
retryable: false,
|
|
993
|
-
message: "The workflow's result does not match its declared output schema."
|
|
994
|
-
})
|
|
995
|
-
);
|
|
996
|
-
return yield* safe2(
|
|
997
|
-
() => Schema_exports.decodeUnknownEffect(WorkflowValue)(decoded),
|
|
998
|
-
new WorkflowFailure({
|
|
999
|
-
reason: "output",
|
|
1000
|
-
retryable: false,
|
|
1001
|
-
message: "The workflow returned a value that is not JSON, such as undefined, or is larger than 1 MiB. Return null for no result."
|
|
1002
|
-
})
|
|
1003
|
-
);
|
|
1004
|
-
}
|
|
1005
|
-
if (request.operation === "inspect") {
|
|
1006
|
-
const summary = request.detail === "summary";
|
|
1007
|
-
const wanted = request.tools === void 0 ? void 0 : new Set(request.tools);
|
|
1008
|
-
const metadata = [];
|
|
1009
|
-
for (const [prefix, readOnly, catalog2] of [
|
|
1010
|
-
[OperationToolPrefixes.query, true, definition.queries],
|
|
1011
|
-
[OperationToolPrefixes.mutate, false, definition.mutations]
|
|
1012
|
-
]) {
|
|
1013
|
-
for (const [name2, operation] of Object.entries(catalog2 ?? {})) {
|
|
1014
|
-
if (wanted !== void 0 && !wanted.has(`${prefix}${name2}`)) continue;
|
|
1015
|
-
const schedules = Object.entries(definition.schedules ?? {}).filter(([, schedule]) => schedule.tool === `${prefix}${name2}`).map(([name3, { tool: _tool, ...schedule }]) => ({ name: name3, ...schedule }));
|
|
1016
|
-
if (request.scheduled === true && schedules.length === 0) continue;
|
|
1017
|
-
metadata.push(
|
|
1018
|
-
yield* safe2(
|
|
1019
|
-
() => Effect_exports.gen(function* () {
|
|
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;
|
|
1080
|
-
}
|
|
1081
|
-
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
|
-
const executeWebhook = (db) => dispatchWebhook(
|
|
1083
|
-
definition,
|
|
1084
|
-
request,
|
|
1085
|
-
{
|
|
1086
|
-
files,
|
|
1087
|
-
cache: bound.cache,
|
|
1088
|
-
accounts: bound.accounts,
|
|
1089
|
-
workflows: workflowControls,
|
|
1090
|
-
signal: bound.signal,
|
|
1091
|
-
fetch: bound.fetch,
|
|
1092
|
-
...db === void 0 || native.database === void 0 ? {} : {
|
|
1093
|
-
db: authorDatabase(native.database.tables, db, invocationSignal, true)
|
|
1094
|
-
}
|
|
1095
|
-
},
|
|
1096
|
-
Redacted_exports.value(context.accounts)
|
|
1097
|
-
);
|
|
1098
|
-
if (native.database === void 0 || !["webhook-register", "webhook-handle", "webhook-unregister"].includes(request.operation))
|
|
1099
|
-
return yield* executeWebhook();
|
|
1100
|
-
const storage2 = context.storage ?? unavailableStorage;
|
|
1101
|
-
return yield* storage2.mutate(native.database.schema, executeWebhook).pipe(
|
|
1102
|
-
Effect_exports.catchTags({
|
|
1103
|
-
AppDatabaseError: storageFailure,
|
|
1104
|
-
DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
|
|
1105
|
-
AppStorageUnavailable: storageFailure,
|
|
1106
|
-
AppStorageError: storageFailure
|
|
1107
|
-
})
|
|
1108
|
-
);
|
|
1109
|
-
}
|
|
1110
|
-
const kind = request.operation === "call" ? request.tool.startsWith(OperationToolPrefixes.query) ? "query" : request.tool.startsWith(OperationToolPrefixes.mutate) ? "mutate" : void 0 : request.operation;
|
|
1111
|
-
if (kind === void 0) return yield* new HostToolNotFound();
|
|
1112
|
-
const name = request.operation === "call" ? request.tool.slice(OperationToolPrefixes[kind].length) : request.name;
|
|
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();
|
|
1121
|
-
if (tool === void 0)
|
|
1122
|
-
return yield* request.operation === "call" ? new HostToolNotFound() : new HostOperationNotFound();
|
|
1123
|
-
const input = yield* Effect_exports.suspend(
|
|
1124
|
-
() => Schema_exports.decodeUnknownEffect(tool.input)(request.input)
|
|
1125
|
-
).pipe(
|
|
1126
|
-
Effect_exports.catchCause(
|
|
1127
|
-
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(inputInvalid(Cause_exports.squash(cause)))
|
|
1128
|
-
)
|
|
1129
|
-
);
|
|
1130
|
-
if (context.approval !== void 0) {
|
|
1131
|
-
const approved = yield* safe2(
|
|
1132
|
-
() => Schema_exports.decodeUnknownEffect(TrustedToolApproval)(context.approval),
|
|
1133
|
-
new HostInputInvalid()
|
|
1134
|
-
);
|
|
1135
|
-
const decoded = yield* safe2(
|
|
1136
|
-
() => Schema_exports.decodeUnknownEffect(JsonValue)(input),
|
|
1137
|
-
new HostInputInvalid()
|
|
1138
|
-
);
|
|
1139
|
-
if (approved.tool !== toolName || !Schema_exports.toEquivalence(JsonValue)(approved.input, decoded)) {
|
|
1140
|
-
return yield* new HostInputInvalid();
|
|
1141
|
-
}
|
|
1142
|
-
} else if (tool.approval !== void 0) {
|
|
1143
|
-
const approval = tool.approval;
|
|
1144
|
-
const decision = yield* safe2(
|
|
1145
|
-
() => approval({ toolName, toolInput: input, signal: invocationSignal }).pipe(
|
|
1146
|
-
Effect_exports.withSpan("app.tool.approval", {
|
|
1147
|
-
attributes: { "executor.tool.name": toolName }
|
|
1148
|
-
}),
|
|
1149
|
-
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(ApprovalDecision))
|
|
1150
|
-
),
|
|
1151
|
-
new HostToolPolicyFailed()
|
|
1152
|
-
);
|
|
1153
|
-
yield* Match_exports.value(decision).pipe(
|
|
1154
|
-
Match_exports.when("approved", () => Effect_exports.void),
|
|
1155
|
-
Match_exports.when("denied", () => Effect_exports.fail(new HostToolBlocked())),
|
|
1156
|
-
Match_exports.when(
|
|
1157
|
-
"user-approval",
|
|
1158
|
-
() => safe2(() => Schema_exports.decodeUnknownEffect(JsonValue)(input), new HostInputInvalid()).pipe(
|
|
1159
|
-
Effect_exports.flatMap(
|
|
1160
|
-
(input2) => Effect_exports.fail(
|
|
1161
|
-
new HostToolApprovalRequired({
|
|
1162
|
-
input: input2,
|
|
1163
|
-
elicitation: approvalElicitation(toolName, input2)
|
|
1164
|
-
})
|
|
1165
|
-
)
|
|
1166
|
-
)
|
|
1167
|
-
)
|
|
1168
|
-
),
|
|
1169
|
-
Match_exports.exhaustive
|
|
1170
|
-
);
|
|
1171
|
-
}
|
|
1172
|
-
const execute = (db) => Effect_exports.gen(function* () {
|
|
1173
|
-
transactionOpen = db !== void 0;
|
|
1174
|
-
const output = yield* Effect_exports.gen(function* () {
|
|
1175
|
-
running = yield* captureTelemetry;
|
|
1176
|
-
const fetch = yield* invocationFetch(invocationSignal);
|
|
1177
|
-
return yield* tool.run(
|
|
1178
|
-
{
|
|
1179
|
-
...bound,
|
|
1180
|
-
fetch,
|
|
1181
|
-
workflows: kind === "mutate" ? workflowControls : workflowReads,
|
|
1182
|
-
...db === void 0 || native.database === void 0 ? {} : {
|
|
1183
|
-
db: authorDatabase(
|
|
1184
|
-
native.database.tables,
|
|
1185
|
-
db,
|
|
1186
|
-
invocationSignal,
|
|
1187
|
-
kind === "mutate"
|
|
1188
|
-
)
|
|
1189
|
-
}
|
|
1190
|
-
},
|
|
1191
|
-
input
|
|
1192
|
-
);
|
|
1193
|
-
}).pipe(
|
|
1194
|
-
Effect_exports.ensuring(
|
|
1195
|
-
Effect_exports.sync(() => {
|
|
1196
|
-
running = void 0;
|
|
1197
|
-
})
|
|
1198
|
-
),
|
|
1199
|
-
Effect_exports.catchCause((cause) => {
|
|
1200
|
-
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
1201
|
-
const error = Cause_exports.squash(cause);
|
|
1202
|
-
const provider = parseProviderError(error);
|
|
1203
|
-
const response = Schema_exports.decodeUnknownOption(OpenapiResponseError)(error);
|
|
1204
|
-
const failure = Schema_exports.decodeUnknownOption(ElicitationFailed)(error);
|
|
1205
|
-
return Effect_exports.fail(
|
|
1206
|
-
Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(response) ? new OpenapiResponseError({
|
|
1207
|
-
code: response.value.code,
|
|
1208
|
-
status: response.value.status,
|
|
1209
|
-
message: response.value.message,
|
|
1210
|
-
...response.value.recovery === void 0 ? {} : { recovery: response.value.recovery }
|
|
1211
|
-
}) : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed(failureDetail(error, secrets))
|
|
1212
|
-
);
|
|
1213
|
-
}),
|
|
1214
|
-
Effect_exports.withSpan("app.operation.execute", {
|
|
1215
|
-
attributes: { "executor.tool.name": toolName, "executor.operation": kind }
|
|
1216
|
-
})
|
|
1217
|
-
);
|
|
1218
|
-
const outputSchema = tool.output;
|
|
1219
|
-
const decoded = outputSchema === void 0 ? output : yield* safe2(
|
|
1220
|
-
() => Schema_exports.decodeUnknownEffect(outputSchema)(output),
|
|
1221
|
-
new HostOutputInvalid()
|
|
1222
|
-
);
|
|
1223
|
-
return yield* safe2(
|
|
1224
|
-
() => Schema_exports.decodeUnknownEffect(JsonValue)(decoded),
|
|
1225
|
-
new HostOutputInvalid()
|
|
1226
|
-
);
|
|
1227
|
-
});
|
|
1228
|
-
const replay = context.replay === void 0 ? void 0 : yield* safe2(
|
|
1229
|
-
() => Schema_exports.decodeUnknownEffect(WorkflowReplay)(context.replay),
|
|
1230
|
-
new HostInputInvalid()
|
|
1231
|
-
);
|
|
1232
|
-
if (replay !== void 0 && kind !== "mutate") return yield* new HostInputInvalid();
|
|
1233
|
-
if (native.database === void 0) return yield* withinDeadline(execute());
|
|
1234
|
-
const storage = context.storage ?? unavailableStorage;
|
|
1235
|
-
return yield* storage[kind === "query" ? "read" : "mutate"](
|
|
1236
|
-
native.database.schema,
|
|
1237
|
-
(db) => withinDeadline(
|
|
1238
|
-
replay === void 0 ? execute(db) : db.once(replay.key, replay.fingerprint, () => execute(db))
|
|
1239
|
-
)
|
|
1240
|
-
).pipe(
|
|
1241
|
-
Effect_exports.catchTags({
|
|
1242
|
-
AppDatabaseError: storageFailure,
|
|
1243
|
-
DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
|
|
1244
|
-
AppStorageUnavailable: storageFailure,
|
|
1245
|
-
AppStorageError: storageFailure
|
|
1246
|
-
})
|
|
1247
|
-
);
|
|
1248
|
-
})
|
|
1249
|
-
);
|
|
1250
|
-
}
|
|
1251
|
-
var parseSkillLoadFailed = (error) => Schema_exports.decodeUnknownOption(SkillLoadFailed)(error).pipe(
|
|
1252
|
-
Option_exports.map(
|
|
1253
|
-
({ reason, message, status }) => new SkillLoadFailed({
|
|
1254
|
-
reason,
|
|
1255
|
-
...message ? { message } : {},
|
|
1256
|
-
...status === void 0 ? {} : { status }
|
|
1257
|
-
})
|
|
1258
|
-
)
|
|
1259
|
-
);
|
|
1260
|
-
var parseMcpError = (error) => Schema_exports.decodeUnknownOption(McpError)(error).pipe(
|
|
1261
|
-
Option_exports.map(
|
|
1262
|
-
({ phase, reason, status }) => new McpError({ phase, reason, ...status === void 0 ? {} : { status } })
|
|
1263
|
-
)
|
|
1264
|
-
);
|
|
1265
|
-
var errorStatus = Match_exports.type().pipe(
|
|
1266
|
-
Match_exports.tagsExhaustive({
|
|
1267
|
-
ProviderError: () => 502,
|
|
1268
|
-
McpError: () => 502,
|
|
1269
|
-
SkillLoadFailed: () => 502,
|
|
1270
|
-
OpenapiResponseError: () => 502,
|
|
1271
|
-
WorkflowFailure: () => 422,
|
|
1272
|
-
HostRequestInvalid: () => 400,
|
|
1273
|
-
HostAccountsInvalid: () => 422,
|
|
1274
|
-
HostInputInvalid: () => 422,
|
|
1275
|
-
HostOperationNotFound: () => 404,
|
|
1276
|
-
HostToolNotFound: () => 404,
|
|
1277
|
-
HostToolBlocked: () => 403,
|
|
1278
|
-
HostToolApprovalRequired: () => 409,
|
|
1279
|
-
HostToolPolicyFailed: () => 500,
|
|
1280
|
-
HostOperationFailed: () => 500,
|
|
1281
|
-
DatabaseLimitExceeded: () => 422,
|
|
1282
|
-
DatabaseFieldReserved: () => 422,
|
|
1283
|
-
HostDeclarationInvalid: () => 500,
|
|
1284
|
-
HostEvaluationFailed: () => 500,
|
|
1285
|
-
HostOutputInvalid: () => 500,
|
|
1286
|
-
ElicitationFailed: () => 422
|
|
1287
|
-
})
|
|
1288
|
-
);
|
|
1289
|
-
var createAppHandler = (app) => (request, context) => Effect_exports.gen(function* () {
|
|
1290
|
-
if (request.method !== "POST") return yield* Effect_exports.fail(new HostRequestInvalid());
|
|
1291
|
-
const input = yield* Effect_exports.tryPromise({
|
|
1292
|
-
try: () => request.json(),
|
|
1293
|
-
catch: () => new HostRequestInvalid()
|
|
1294
|
-
});
|
|
1295
|
-
const command = yield* Schema_exports.decodeUnknownEffect(HostRequest)(input, {
|
|
1296
|
-
onExcessProperty: "error"
|
|
1297
|
-
}).pipe(Effect_exports.mapError(() => new HostRequestInvalid()));
|
|
1298
|
-
yield* Effect_exports.annotateCurrentSpan({
|
|
1299
|
-
"executor.operation": command.operation,
|
|
1300
|
-
...command.operation === "call" ? { "executor.tool.name": command.tool } : {}
|
|
1301
|
-
});
|
|
1302
|
-
let toolError = false;
|
|
1303
|
-
const value = yield* dispatch(app, command, context, request.signal).pipe(
|
|
1304
|
-
Effect_exports.provideService(ToolResultObservation, {
|
|
1305
|
-
failed: () => {
|
|
1306
|
-
toolError = true;
|
|
1307
|
-
}
|
|
1308
|
-
}),
|
|
1309
|
-
Effect_exports.withSpan(`app.${command.operation}`)
|
|
1310
|
-
);
|
|
1311
|
-
if (toolError)
|
|
1312
|
-
yield* Effect_exports.annotateCurrentSpan({
|
|
1313
|
-
"executor.outcome": "failed",
|
|
1314
|
-
"error.type": "McpToolError"
|
|
1315
|
-
});
|
|
1316
|
-
return Response.json({ ok: true, value, ...toolError ? { toolError: true } : {} });
|
|
1317
|
-
}).pipe(
|
|
1318
|
-
Effect_exports.catch(
|
|
1319
|
-
(error) => Schema_exports.encodeEffect(HostError)(error).pipe(
|
|
1320
|
-
Effect_exports.map(
|
|
1321
|
-
(encoded) => Response.json({ ok: false, error: encoded }, { status: errorStatus(error) })
|
|
1322
|
-
),
|
|
1323
|
-
Effect_exports.orDie
|
|
1324
|
-
)
|
|
1325
|
-
),
|
|
1326
|
-
Effect_exports.catchCause(
|
|
1327
|
-
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.logError(cause).pipe(
|
|
1328
|
-
Effect_exports.andThen(
|
|
1329
|
-
Schema_exports.encodeEffect(HostError)(
|
|
1330
|
-
declarationInvalid(
|
|
1331
|
-
"The app failed while it was loaded",
|
|
1332
|
-
Cause_exports.squash(cause),
|
|
1333
|
-
accountSecrets(context.accounts)
|
|
1334
|
-
)
|
|
1335
|
-
)
|
|
1336
|
-
),
|
|
1337
|
-
Effect_exports.map((error) => Response.json({ ok: false, error }, { status: 500 })),
|
|
1338
|
-
Effect_exports.orDie
|
|
1339
|
-
)
|
|
1340
|
-
)
|
|
1341
|
-
);
|
|
1342
|
-
|
|
1343
|
-
export {
|
|
1344
|
-
prepareElicitation,
|
|
1345
|
-
ApprovalDecision,
|
|
1346
|
-
createAppHandler
|
|
1347
|
-
};
|