@dxos/functions 0.8.4-main.ead640a → 0.8.4-main.f466a3d56e

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.
Files changed (185) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +5 -7
  3. package/dist/lib/neutral/index.mjs +602 -0
  4. package/dist/lib/neutral/index.mjs.map +7 -0
  5. package/dist/lib/neutral/meta.json +1 -0
  6. package/dist/types/src/index.d.ts +3 -9
  7. package/dist/types/src/index.d.ts.map +1 -1
  8. package/dist/types/src/protocol/functions-ai-http-client.d.ts +12 -0
  9. package/dist/types/src/protocol/functions-ai-http-client.d.ts.map +1 -0
  10. package/dist/types/src/protocol/functions-ai-http-client.test.d.ts +2 -0
  11. package/dist/types/src/protocol/functions-ai-http-client.test.d.ts.map +1 -0
  12. package/dist/types/src/protocol/index.d.ts +2 -0
  13. package/dist/types/src/protocol/index.d.ts.map +1 -0
  14. package/dist/types/src/protocol/protocol.d.ts +24 -0
  15. package/dist/types/src/protocol/protocol.d.ts.map +1 -0
  16. package/dist/types/src/protocol/protocol.test.d.ts +2 -0
  17. package/dist/types/src/protocol/protocol.test.d.ts.map +1 -0
  18. package/dist/types/src/sdk.d.ts +10 -0
  19. package/dist/types/src/sdk.d.ts.map +1 -0
  20. package/dist/types/src/services/credentials.d.ts +17 -38
  21. package/dist/types/src/services/credentials.d.ts.map +1 -1
  22. package/dist/types/src/services/function-invocation-service.d.ts +9 -19
  23. package/dist/types/src/services/function-invocation-service.d.ts.map +1 -1
  24. package/dist/types/src/services/index.d.ts +1 -6
  25. package/dist/types/src/services/index.d.ts.map +1 -1
  26. package/dist/types/src/services/queues.d.ts +1 -46
  27. package/dist/types/src/services/queues.d.ts.map +1 -1
  28. package/dist/types/src/services/tracing.d.ts +2 -56
  29. package/dist/types/src/services/tracing.d.ts.map +1 -1
  30. package/dist/types/src/types/index.d.ts +2 -0
  31. package/dist/types/src/types/index.d.ts.map +1 -0
  32. package/dist/types/src/types/url.d.ts +13 -0
  33. package/dist/types/src/types/url.d.ts.map +1 -0
  34. package/dist/types/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +26 -64
  36. package/src/index.ts +3 -9
  37. package/src/protocol/functions-ai-http-client.test.ts +105 -0
  38. package/src/protocol/functions-ai-http-client.ts +141 -0
  39. package/src/{executor → protocol}/index.ts +1 -1
  40. package/src/protocol/protocol.test.ts +58 -0
  41. package/src/protocol/protocol.ts +455 -0
  42. package/src/sdk.ts +31 -0
  43. package/src/services/credentials.ts +81 -110
  44. package/src/services/function-invocation-service.ts +22 -70
  45. package/src/services/index.ts +1 -6
  46. package/src/services/queues.ts +1 -80
  47. package/src/services/tracing.ts +1 -136
  48. package/src/types/index.ts +5 -0
  49. package/src/types/url.ts +32 -0
  50. package/dist/lib/browser/bundler/index.mjs +0 -269
  51. package/dist/lib/browser/bundler/index.mjs.map +0 -7
  52. package/dist/lib/browser/chunk-J5LGTIGS.mjs +0 -10
  53. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +0 -7
  54. package/dist/lib/browser/chunk-LKYT2SAL.mjs +0 -665
  55. package/dist/lib/browser/chunk-LKYT2SAL.mjs.map +0 -7
  56. package/dist/lib/browser/edge/index.mjs +0 -83
  57. package/dist/lib/browser/edge/index.mjs.map +0 -7
  58. package/dist/lib/browser/index.mjs +0 -1395
  59. package/dist/lib/browser/index.mjs.map +0 -7
  60. package/dist/lib/browser/meta.json +0 -1
  61. package/dist/lib/browser/testing/index.mjs +0 -131
  62. package/dist/lib/browser/testing/index.mjs.map +0 -7
  63. package/dist/lib/node-esm/bundler/index.mjs +0 -270
  64. package/dist/lib/node-esm/bundler/index.mjs.map +0 -7
  65. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  66. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +0 -7
  67. package/dist/lib/node-esm/chunk-NAQIKLZB.mjs +0 -667
  68. package/dist/lib/node-esm/chunk-NAQIKLZB.mjs.map +0 -7
  69. package/dist/lib/node-esm/edge/index.mjs +0 -84
  70. package/dist/lib/node-esm/edge/index.mjs.map +0 -7
  71. package/dist/lib/node-esm/index.mjs +0 -1396
  72. package/dist/lib/node-esm/index.mjs.map +0 -7
  73. package/dist/lib/node-esm/meta.json +0 -1
  74. package/dist/lib/node-esm/testing/index.mjs +0 -132
  75. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  76. package/dist/types/src/bundler/bundler.d.ts +0 -49
  77. package/dist/types/src/bundler/bundler.d.ts.map +0 -1
  78. package/dist/types/src/bundler/bundler.test.d.ts +0 -2
  79. package/dist/types/src/bundler/bundler.test.d.ts.map +0 -1
  80. package/dist/types/src/bundler/index.d.ts +0 -2
  81. package/dist/types/src/bundler/index.d.ts.map +0 -1
  82. package/dist/types/src/edge/functions.d.ts +0 -17
  83. package/dist/types/src/edge/functions.d.ts.map +0 -1
  84. package/dist/types/src/edge/index.d.ts +0 -2
  85. package/dist/types/src/edge/index.d.ts.map +0 -1
  86. package/dist/types/src/errors.d.ts +0 -137
  87. package/dist/types/src/errors.d.ts.map +0 -1
  88. package/dist/types/src/examples/fib.d.ts +0 -7
  89. package/dist/types/src/examples/fib.d.ts.map +0 -1
  90. package/dist/types/src/examples/index.d.ts +0 -4
  91. package/dist/types/src/examples/index.d.ts.map +0 -1
  92. package/dist/types/src/examples/reply.d.ts +0 -3
  93. package/dist/types/src/examples/reply.d.ts.map +0 -1
  94. package/dist/types/src/examples/sleep.d.ts +0 -5
  95. package/dist/types/src/examples/sleep.d.ts.map +0 -1
  96. package/dist/types/src/executor/executor.d.ts +0 -14
  97. package/dist/types/src/executor/executor.d.ts.map +0 -1
  98. package/dist/types/src/executor/index.d.ts +0 -2
  99. package/dist/types/src/executor/index.d.ts.map +0 -1
  100. package/dist/types/src/handler.d.ts +0 -109
  101. package/dist/types/src/handler.d.ts.map +0 -1
  102. package/dist/types/src/schema.d.ts +0 -43
  103. package/dist/types/src/schema.d.ts.map +0 -1
  104. package/dist/types/src/services/database.d.ts +0 -67
  105. package/dist/types/src/services/database.d.ts.map +0 -1
  106. package/dist/types/src/services/event-logger.d.ts +0 -75
  107. package/dist/types/src/services/event-logger.d.ts.map +0 -1
  108. package/dist/types/src/services/function-invocation-service.test.d.ts +0 -2
  109. package/dist/types/src/services/function-invocation-service.test.d.ts.map +0 -1
  110. package/dist/types/src/services/local-function-execution.d.ts +0 -34
  111. package/dist/types/src/services/local-function-execution.d.ts.map +0 -1
  112. package/dist/types/src/services/remote-function-execution-service.d.ts +0 -22
  113. package/dist/types/src/services/remote-function-execution-service.d.ts.map +0 -1
  114. package/dist/types/src/services/service-container.d.ts +0 -57
  115. package/dist/types/src/services/service-container.d.ts.map +0 -1
  116. package/dist/types/src/services/service-registry.d.ts +0 -31
  117. package/dist/types/src/services/service-registry.d.ts.map +0 -1
  118. package/dist/types/src/services/service-registry.test.d.ts +0 -2
  119. package/dist/types/src/services/service-registry.test.d.ts.map +0 -1
  120. package/dist/types/src/testing/index.d.ts +0 -3
  121. package/dist/types/src/testing/index.d.ts.map +0 -1
  122. package/dist/types/src/testing/layer.d.ts +0 -18
  123. package/dist/types/src/testing/layer.d.ts.map +0 -1
  124. package/dist/types/src/testing/logger.d.ts +0 -5
  125. package/dist/types/src/testing/logger.d.ts.map +0 -1
  126. package/dist/types/src/testing/persist-database.test.d.ts +0 -2
  127. package/dist/types/src/testing/persist-database.test.d.ts.map +0 -1
  128. package/dist/types/src/testing/services.d.ts +0 -59
  129. package/dist/types/src/testing/services.d.ts.map +0 -1
  130. package/dist/types/src/trace.d.ts +0 -122
  131. package/dist/types/src/trace.d.ts.map +0 -1
  132. package/dist/types/src/translations.d.ts +0 -12
  133. package/dist/types/src/translations.d.ts.map +0 -1
  134. package/dist/types/src/triggers/index.d.ts +0 -4
  135. package/dist/types/src/triggers/index.d.ts.map +0 -1
  136. package/dist/types/src/triggers/input-builder.d.ts +0 -3
  137. package/dist/types/src/triggers/input-builder.d.ts.map +0 -1
  138. package/dist/types/src/triggers/invocation-tracer.d.ts +0 -37
  139. package/dist/types/src/triggers/invocation-tracer.d.ts.map +0 -1
  140. package/dist/types/src/triggers/trigger-dispatcher.d.ts +0 -78
  141. package/dist/types/src/triggers/trigger-dispatcher.d.ts.map +0 -1
  142. package/dist/types/src/triggers/trigger-dispatcher.test.d.ts +0 -2
  143. package/dist/types/src/triggers/trigger-dispatcher.test.d.ts.map +0 -1
  144. package/dist/types/src/triggers/trigger-state-store.d.ts +0 -28
  145. package/dist/types/src/triggers/trigger-state-store.d.ts.map +0 -1
  146. package/dist/types/src/types.d.ts +0 -230
  147. package/dist/types/src/types.d.ts.map +0 -1
  148. package/dist/types/src/url.d.ts +0 -21
  149. package/dist/types/src/url.d.ts.map +0 -1
  150. package/src/bundler/bundler.test.ts +0 -58
  151. package/src/bundler/bundler.ts +0 -295
  152. package/src/bundler/index.ts +0 -5
  153. package/src/edge/functions.ts +0 -67
  154. package/src/edge/index.ts +0 -9
  155. package/src/errors.ts +0 -21
  156. package/src/examples/fib.ts +0 -32
  157. package/src/examples/index.ts +0 -7
  158. package/src/examples/reply.ts +0 -21
  159. package/src/examples/sleep.ts +0 -24
  160. package/src/executor/executor.ts +0 -58
  161. package/src/handler.ts +0 -225
  162. package/src/schema.ts +0 -71
  163. package/src/services/database.ts +0 -175
  164. package/src/services/event-logger.ts +0 -121
  165. package/src/services/function-invocation-service.test.ts +0 -81
  166. package/src/services/local-function-execution.ts +0 -153
  167. package/src/services/remote-function-execution-service.ts +0 -63
  168. package/src/services/service-container.ts +0 -115
  169. package/src/services/service-registry.test.ts +0 -45
  170. package/src/services/service-registry.ts +0 -63
  171. package/src/testing/index.ts +0 -6
  172. package/src/testing/layer.ts +0 -114
  173. package/src/testing/logger.ts +0 -17
  174. package/src/testing/persist-database.test.ts +0 -87
  175. package/src/testing/services.ts +0 -115
  176. package/src/trace.ts +0 -178
  177. package/src/translations.ts +0 -20
  178. package/src/triggers/index.ts +0 -7
  179. package/src/triggers/input-builder.ts +0 -35
  180. package/src/triggers/invocation-tracer.ts +0 -101
  181. package/src/triggers/trigger-dispatcher.test.ts +0 -665
  182. package/src/triggers/trigger-dispatcher.ts +0 -533
  183. package/src/triggers/trigger-state-store.ts +0 -61
  184. package/src/types.ts +0 -218
  185. package/src/url.ts +0 -55
@@ -0,0 +1,602 @@
1
+ // src/services/credentials.ts
2
+ import * as HttpClient from "@effect/platform/HttpClient";
3
+ import * as HttpClientRequest from "@effect/platform/HttpClientRequest";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Layer from "effect/Layer";
6
+ import * as Redacted from "effect/Redacted";
7
+ import { Credential } from "@dxos/compute";
8
+ import { Database, Query } from "@dxos/echo";
9
+ import { AccessToken } from "@dxos/types";
10
+ var ConfiguredCredentialsService = class {
11
+ credentials;
12
+ constructor(credentials = []) {
13
+ this.credentials = credentials;
14
+ }
15
+ addCredentials(credentials) {
16
+ this.credentials.push(...credentials);
17
+ return this;
18
+ }
19
+ async queryCredentials(query) {
20
+ return this.credentials.filter((credential) => credential.service === query.service);
21
+ }
22
+ async getCredential(query) {
23
+ const credential = this.credentials.find((credential2) => credential2.service === query.service);
24
+ if (!credential) {
25
+ throw new Error(`Credential not found for service: ${query.service}`);
26
+ }
27
+ return credential;
28
+ }
29
+ };
30
+ var withAuthorization = (token, kind) => HttpClient.mapRequest((request) => {
31
+ const authorization = kind ? `${kind} ${token}` : token;
32
+ return HttpClientRequest.setHeader(request, "Authorization", authorization);
33
+ });
34
+ var configuredCredentialsLayer = (credentials) => Layer.succeed(Credential.CredentialsService, new ConfiguredCredentialsService(credentials));
35
+ var credentialsLayerConfig = (credentials) => Layer.effect(Credential.CredentialsService, Effect.gen(function* () {
36
+ const serviceCredentials = yield* Effect.forEach(credentials, ({ service, apiKey }) => Effect.gen(function* () {
37
+ return {
38
+ service,
39
+ apiKey: Redacted.value(yield* apiKey)
40
+ };
41
+ }));
42
+ return new ConfiguredCredentialsService(serviceCredentials);
43
+ }));
44
+ var credentialsLayerFromDatabase = ({ caching = false } = {}) => Layer.effect(Credential.CredentialsService, Effect.gen(function* () {
45
+ const dbService = yield* Database.Service;
46
+ const cache = /* @__PURE__ */ new Map();
47
+ const queryCredentials = async (query) => {
48
+ const cacheKey = JSON.stringify(query);
49
+ if (caching && cache.has(cacheKey)) {
50
+ return cache.get(cacheKey);
51
+ }
52
+ const accessTokens = await dbService.db.query(Query.type(AccessToken.AccessToken)).run();
53
+ const credentials = accessTokens.filter((accessToken) => accessToken.source === query.service).map((accessToken) => ({
54
+ service: accessToken.source,
55
+ apiKey: accessToken.token
56
+ }));
57
+ if (caching) {
58
+ cache.set(cacheKey, credentials);
59
+ }
60
+ return credentials;
61
+ };
62
+ return {
63
+ getCredential: async (query) => {
64
+ const credentials = await queryCredentials(query);
65
+ if (credentials.length === 0) {
66
+ throw new Error(`Credential not found for service: ${query.service}`);
67
+ }
68
+ return credentials[0];
69
+ },
70
+ queryCredentials: async (query) => {
71
+ return queryCredentials(query);
72
+ }
73
+ };
74
+ }));
75
+
76
+ // src/services/function-invocation-service.ts
77
+ import * as Context from "effect/Context";
78
+ import * as Effect2 from "effect/Effect";
79
+ import * as Layer2 from "effect/Layer";
80
+ var FunctionInvocationService = class _FunctionInvocationService extends Context.Tag("@dxos/functions/FunctionInvocationService")() {
81
+ static layerNotAvailable = Layer2.succeed(_FunctionInvocationService, {
82
+ invokeFunction: () => Effect2.die("FunctionInvocationService is not avaialble."),
83
+ resolveFunction: () => Effect2.die("FunctionInvocationService is not available.")
84
+ });
85
+ static invokeFunction = (functionDef, input) => Effect2.serviceFunctionEffect(_FunctionInvocationService, (service) => service.invokeFunction)(functionDef, input);
86
+ static resolveFunction = (key) => Effect2.serviceFunctionEffect(_FunctionInvocationService, (service) => service.resolveFunction)(key);
87
+ };
88
+
89
+ // src/services/queues.ts
90
+ import { QueueService, feedServiceFromQueueServiceLayer } from "@dxos/echo-db";
91
+
92
+ // src/services/tracing.ts
93
+ var MESSAGE_PROPERTY_TOOL_CALL_ID = "toolCallId";
94
+
95
+ // src/types/url.ts
96
+ var FUNCTIONS_META_KEY = "org.dxos.service.function";
97
+ var FUNCTIONS_PRESET_META_KEY = "org.dxos.service.function-preset";
98
+ var getUserFunctionIdInMetadata = (meta) => {
99
+ return meta.keys.find((key) => key.source === FUNCTIONS_META_KEY)?.id;
100
+ };
101
+ var setUserFunctionIdInMetadata = (meta, functionId) => {
102
+ const key = meta.keys.find((key2) => key2.source === FUNCTIONS_META_KEY);
103
+ if (key) {
104
+ if (key.id !== functionId) {
105
+ throw new Error("Metadata mismatch");
106
+ }
107
+ } else {
108
+ meta.keys.push({
109
+ source: FUNCTIONS_META_KEY,
110
+ id: functionId
111
+ });
112
+ }
113
+ };
114
+
115
+ // src/protocol/protocol.ts
116
+ import * as AnthropicClient from "@effect/ai-anthropic/AnthropicClient";
117
+ import * as Effect4 from "effect/Effect";
118
+ import * as Layer4 from "effect/Layer";
119
+ import * as Option from "effect/Option";
120
+ import * as Schema from "effect/Schema";
121
+ import * as SchemaAST from "effect/SchemaAST";
122
+ import { AiModelResolver, AiService, OpaqueToolkit } from "@dxos/ai";
123
+ import { AnthropicResolver } from "@dxos/ai/resolvers";
124
+ import { Blueprint, FunctionError, InvalidOperationInputError, InvalidOperationOutputError, Operation, OperationRegistry, Trace } from "@dxos/compute";
125
+ import { LifecycleState, Resource } from "@dxos/context";
126
+ import { Database as Database2, Feed, JsonSchema, Ref } from "@dxos/echo";
127
+ import { createFeedServiceLayer, EchoClient } from "@dxos/echo-db";
128
+ import { refFromEncodedReference } from "@dxos/echo/internal";
129
+ import { runAndForwardErrors } from "@dxos/effect";
130
+ import { assertState, failedInvariant, invariant } from "@dxos/invariant";
131
+ import { PublicKey } from "@dxos/keys";
132
+ import { log as log2 } from "@dxos/log";
133
+ import { ErrorCodec as ErrorCodec2 } from "@dxos/protocols";
134
+
135
+ // src/protocol/functions-ai-http-client.ts
136
+ import * as Headers from "@effect/platform/Headers";
137
+ import * as HttpClient2 from "@effect/platform/HttpClient";
138
+ import * as HttpClientError from "@effect/platform/HttpClientError";
139
+ import * as HttpClientResponse from "@effect/platform/HttpClientResponse";
140
+ import * as Effect3 from "effect/Effect";
141
+ import * as FiberRef from "effect/FiberRef";
142
+ import * as Layer3 from "effect/Layer";
143
+ import * as Stream from "effect/Stream";
144
+ import { FunctionsAiMemoizationMissError, FunctionsAiUpstreamError } from "@dxos/compute";
145
+ import { log } from "@dxos/log";
146
+ import { ErrorCodec } from "@dxos/protocols";
147
+ var __dxlog_file = "/__w/dxos/dxos/packages/core/compute/functions/src/protocol/functions-ai-http-client.ts";
148
+ var requestInitTagKey = "@effect/platform/FetchHttpClient/FetchOptions";
149
+ var FunctionsAiHttpClient = class _FunctionsAiHttpClient {
150
+ static make = (service) => HttpClient2.make((request, url, signal, fiber) => {
151
+ const context = fiber.getFiberRef(FiberRef.currentContext);
152
+ const options = context.unsafeMap.get(requestInitTagKey) ?? {};
153
+ const headers = options.headers ? Headers.merge(Headers.fromInput(options.headers), request.headers) : request.headers;
154
+ const send = (body) => Effect3.tryPromise({
155
+ try: () => service.fetch(new Request(url, {
156
+ ...options,
157
+ method: request.method,
158
+ headers,
159
+ body
160
+ })),
161
+ catch: (cause) => {
162
+ log.error("Failed to fetch", {
163
+ errorSerialized: ErrorCodec.encode(cause)
164
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 31, S: this });
165
+ return new HttpClientError.RequestError({
166
+ request,
167
+ reason: "Transport",
168
+ cause
169
+ });
170
+ }
171
+ }).pipe(Effect3.flatMap((response) => (
172
+ // Inspect the body before handing the response to `@effect/ai` so that structured
173
+ // upstream errors surface as typed defects (`FunctionsAiUpstreamError` and friends)
174
+ // rather than as the generic `HttpResponseError` from `@effect/ai/AiError`.
175
+ Effect3.flatMap(Effect3.promise(() => parseUpstreamError(response)), (typedError) => typedError ? Effect3.die(typedError) : Effect3.succeed(HttpClientResponse.fromWeb(request, response)))
176
+ )));
177
+ switch (request.body._tag) {
178
+ case "Raw":
179
+ case "Uint8Array":
180
+ return send(request.body.body);
181
+ case "FormData":
182
+ return send(request.body.formData);
183
+ case "Stream":
184
+ return Stream.toReadableStreamEffect(request.body.stream).pipe(Effect3.flatMap(send));
185
+ }
186
+ return send(void 0);
187
+ });
188
+ static layer = (service) => Layer3.succeed(HttpClient2.HttpClient, _FunctionsAiHttpClient.make(service));
189
+ };
190
+ var parseUpstreamError = async (response) => {
191
+ if (response.ok) {
192
+ return void 0;
193
+ }
194
+ const contentType = response.headers.get("content-type") ?? "";
195
+ if (!contentType.toLowerCase().includes("application/json")) {
196
+ return void 0;
197
+ }
198
+ let body;
199
+ try {
200
+ body = await response.clone().json();
201
+ } catch {
202
+ return void 0;
203
+ }
204
+ if (!body || body.type !== "error" || typeof body.error !== "object" || body.error === null) {
205
+ return void 0;
206
+ }
207
+ const inner = body.error;
208
+ const message = inner.message ?? `Upstream AI service responded with HTTP ${response.status}`;
209
+ if (inner.type === "memoization_miss" && typeof inner.cacheKey === "string") {
210
+ return new FunctionsAiMemoizationMissError({
211
+ message,
212
+ context: {
213
+ cacheKey: inner.cacheKey,
214
+ status: response.status
215
+ }
216
+ });
217
+ }
218
+ return new FunctionsAiUpstreamError({
219
+ message,
220
+ context: {
221
+ type: inner.type,
222
+ status: response.status,
223
+ ...inner.cacheKey ? {
224
+ cacheKey: inner.cacheKey
225
+ } : {}
226
+ }
227
+ });
228
+ };
229
+
230
+ // src/protocol/protocol.ts
231
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/core/compute/functions/src/protocol/protocol.ts";
232
+ function _ts_add_disposable_resource(env, value2, async) {
233
+ if (value2 !== null && value2 !== void 0) {
234
+ if (typeof value2 !== "object" && typeof value2 !== "function") throw new TypeError("Object expected.");
235
+ var dispose, inner;
236
+ if (async) {
237
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
238
+ dispose = value2[Symbol.asyncDispose];
239
+ }
240
+ if (dispose === void 0) {
241
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
242
+ dispose = value2[Symbol.dispose];
243
+ if (async) inner = dispose;
244
+ }
245
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
246
+ if (inner) dispose = function() {
247
+ try {
248
+ inner.call(this);
249
+ } catch (e) {
250
+ return Promise.reject(e);
251
+ }
252
+ };
253
+ env.stack.push({
254
+ value: value2,
255
+ dispose,
256
+ async
257
+ });
258
+ } else if (async) {
259
+ env.stack.push({
260
+ async: true
261
+ });
262
+ }
263
+ return value2;
264
+ }
265
+ function _ts_dispose_resources(env) {
266
+ var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
267
+ var e = new Error(message);
268
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
269
+ };
270
+ return (_ts_dispose_resources = function _ts_dispose_resources2(env2) {
271
+ function fail(e) {
272
+ env2.error = env2.hasError ? new _SuppressedError(e, env2.error, "An error was suppressed during disposal.") : e;
273
+ env2.hasError = true;
274
+ }
275
+ var r, s = 0;
276
+ function next() {
277
+ while (r = env2.stack.pop()) {
278
+ try {
279
+ if (!r.async && s === 1) return s = 0, env2.stack.push(r), Promise.resolve().then(next);
280
+ if (r.dispose) {
281
+ var result = r.dispose.call(r.value);
282
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
283
+ fail(e);
284
+ return next();
285
+ });
286
+ } else s |= 1;
287
+ } catch (e) {
288
+ fail(e);
289
+ }
290
+ }
291
+ if (s === 1) return env2.hasError ? Promise.reject(env2.error) : Promise.resolve();
292
+ if (env2.hasError) throw env2.error;
293
+ }
294
+ return next();
295
+ })(env);
296
+ }
297
+ var wrapFunctionHandler = (func, opts = {}) => {
298
+ if (!Operation.isOperationWithHandler(func)) {
299
+ throw new TypeError("Expected operation with handler");
300
+ }
301
+ const serviceTags = func.services.map((service) => service.key);
302
+ return {
303
+ meta: {
304
+ key: func.meta.key,
305
+ name: func.meta.name,
306
+ description: func.meta.description,
307
+ inputSchema: JsonSchema.toJsonSchema(func.input),
308
+ outputSchema: func.output === void 0 ? void 0 : JsonSchema.toJsonSchema(func.output),
309
+ services: func.services.map((service) => service.key)
310
+ },
311
+ handler: async ({ data, context }) => {
312
+ if ((serviceTags.includes(Database2.Service.key) || serviceTags.includes(QueueService.key) || serviceTags.includes(Feed.FeedService.key)) && (!context.services.dataService || !context.services.queryService)) {
313
+ throw new FunctionError({
314
+ message: "Services not provided: dataService, queryService"
315
+ });
316
+ }
317
+ try {
318
+ const env = {
319
+ stack: [],
320
+ error: void 0,
321
+ hasError: false
322
+ };
323
+ try {
324
+ if (!SchemaAST.isAnyKeyword(func.input.ast)) {
325
+ try {
326
+ Schema.validateSync(func.input, {
327
+ onExcessProperty: "error"
328
+ })(data);
329
+ } catch (error) {
330
+ throw new InvalidOperationInputError({
331
+ message: `Operation input did not match schema (${func.meta.key}): ${error.message}`,
332
+ cause: error
333
+ });
334
+ }
335
+ }
336
+ const funcContext = _ts_add_disposable_resource(env, await new FunctionContext(context, opts).open(), true);
337
+ const types = [
338
+ ...opts.types ?? [],
339
+ ...func.types ?? []
340
+ ];
341
+ if (types.length > 0) {
342
+ invariant(funcContext.db, "Database is required for functions with types", { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 137, S: void 0, A: ["funcContext.db", "'Database is required for functions with types'"] });
343
+ await funcContext.db.graph.schemaRegistry.register(types);
344
+ }
345
+ const dataWithDecodedRefs = funcContext.db && !SchemaAST.isAnyKeyword(func.input.ast) ? decodeRefsFromSchema(func.input.ast, data, funcContext.db) : data;
346
+ let result = await func.handler(dataWithDecodedRefs);
347
+ if (Effect4.isEffect(result)) {
348
+ result = await runAndForwardErrors(result.pipe(Effect4.orDie, Effect4.provide(funcContext.createLayer())));
349
+ }
350
+ if (serviceTags.includes(Database2.Service.key) && funcContext.db) {
351
+ await funcContext.db.flush({
352
+ disk: true,
353
+ indexes: false
354
+ });
355
+ }
356
+ if (func.output && !SchemaAST.isAnyKeyword(func.output.ast)) {
357
+ try {
358
+ Schema.validateSync(func.output, {
359
+ onExcessProperty: "error"
360
+ })(result);
361
+ } catch (error) {
362
+ throw new InvalidOperationOutputError({
363
+ message: `Operation output did not match schema (${func.meta.key}): ${error.message}`,
364
+ cause: error
365
+ });
366
+ }
367
+ }
368
+ return result;
369
+ } catch (e) {
370
+ env.error = e;
371
+ env.hasError = true;
372
+ } finally {
373
+ const result = _ts_dispose_resources(env);
374
+ if (result) await result;
375
+ }
376
+ } catch (error) {
377
+ throw error;
378
+ }
379
+ }
380
+ };
381
+ };
382
+ var FunctionContext = class extends Resource {
383
+ context;
384
+ client;
385
+ db;
386
+ queues;
387
+ opts;
388
+ constructor(context, opts) {
389
+ super();
390
+ this.context = context;
391
+ this.opts = opts;
392
+ if (context.services.dataService && context.services.queryService) {
393
+ this.client = new EchoClient().connectToService({
394
+ dataService: context.services.dataService,
395
+ queryService: context.services.queryService,
396
+ queueService: context.services.queueService
397
+ });
398
+ }
399
+ }
400
+ async _open() {
401
+ await this.client?.open();
402
+ this.db = this.client && this.context.spaceId ? this.client.constructDatabase({
403
+ spaceId: this.context.spaceId ?? failedInvariant(),
404
+ spaceKey: PublicKey.fromHex(this.context.spaceKey ?? failedInvariant("spaceKey missing in context")),
405
+ reactiveSchemaQuery: false,
406
+ preloadSchemaOnOpen: false
407
+ }) : void 0;
408
+ await this.db?.setSpaceRoot(this.context.spaceRootUrl ?? failedInvariant("spaceRootUrl missing in context"));
409
+ await this.db?.open();
410
+ this.queues = this.client && this.context.spaceId ? this.client.constructQueueFactory(this.context.spaceId) : void 0;
411
+ }
412
+ async _close() {
413
+ await this.db?.close();
414
+ await this.client?.close();
415
+ }
416
+ createLayer() {
417
+ assertState(this._lifecycleState === LifecycleState.OPEN, "FunctionContext is not open");
418
+ const dbLayer = this.db ? Database2.layer(this.db) : Database2.notAvailable;
419
+ const queuesLayer = this.queues ? QueueService.layer(this.queues) : QueueService.notAvailable;
420
+ const feedLayer = this.queues ? createFeedServiceLayer(this.queues) : Feed.notAvailable;
421
+ const credentials = dbLayer ? credentialsLayerFromDatabase({
422
+ caching: true
423
+ }).pipe(Layer4.provide(dbLayer)) : configuredCredentialsLayer([]);
424
+ const aiLayer = this.context.services.functionsAiService ? InternalAiServiceLayer(this.context.services.functionsAiService) : AiService.notAvailable;
425
+ const operationServiceLayer = this.context.services.functionsService ? makeOperationServiceLayer(this.context.services.functionsService) : unavailableOperationServiceLayer;
426
+ const operationRegistryLayer = this.context.services.functionsService ? makeOperationRegistryLayer(this.context.services.functionsService, this.context.spaceId) : emptyOperationRegistryLayer;
427
+ const traceWriterLayer = this.context.services.traceService ? makeTraceWriterLayer(this.context.services.traceService) : Trace.writerLayerNoop;
428
+ log2("Creating function context layer", {
429
+ traceService: !!this.context.services.traceService,
430
+ functionsService: !!this.context.services.functionsService,
431
+ functionsAiService: !!this.context.services.functionsAiService,
432
+ spaceId: this.context.spaceId,
433
+ spaceRootUrl: this.context.spaceRootUrl,
434
+ toolkits: this.opts.toolkits?.length ?? 0,
435
+ types: this.opts.types?.length ?? 0
436
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 234, S: this });
437
+ const blueprintRegistryLayer = this.opts.blueprintRegistry ? Layer4.succeed(Blueprint.RegistryService, this.opts.blueprintRegistry) : Blueprint.RegistryService.notAvailable;
438
+ return Layer4.mergeAll(
439
+ dbLayer,
440
+ queuesLayer,
441
+ feedLayer,
442
+ credentials,
443
+ operationServiceLayer,
444
+ operationRegistryLayer,
445
+ aiLayer,
446
+ OpaqueToolkit.providerLayer(OpaqueToolkit.merge(...this.opts.toolkits ?? [])),
447
+ traceWriterLayer,
448
+ blueprintRegistryLayer,
449
+ // `FunctionInvocationService` is deprecated; new code should yield `Operation.Service`.
450
+ // The cloudflare wrapper provides only the unavailable layer to satisfy the (still-present)
451
+ // type union — handlers that yield it will die at invocation time.
452
+ FunctionInvocationService.layerNotAvailable
453
+ );
454
+ }
455
+ };
456
+ var makeTraceWriterLayer = (traceService) => Layer4.succeed(Trace.TraceService, {
457
+ write: (eventType, payload) => {
458
+ log2("Writing trace event", {
459
+ eventType: eventType.key
460
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 255, S: void 0 });
461
+ traceService.write([
462
+ {
463
+ key: eventType.key,
464
+ isEphemeral: eventType.isEphemeral,
465
+ data: payload
466
+ }
467
+ ]);
468
+ }
469
+ });
470
+ var InternalAiServiceLayer = (functionsAiService) => AiModelResolver.AiModelResolver.buildAiService.pipe(Layer4.provide(AnthropicResolver.make().pipe(Layer4.provide(AnthropicClient.layer({
471
+ // Note: It doesn't matter what is base url here, it will be proxied to ai gateway in edge.
472
+ apiUrl: "http://internal/provider/anthropic"
473
+ }).pipe(Layer4.provide(FunctionsAiHttpClient.layer(functionsAiService)))))));
474
+ var makeOperationServiceLayer = (functionsService) => {
475
+ const invokeRemote = async (op, input, options) => {
476
+ invariant(op.meta.deployedId, `Operation '${op.meta.key}' has no deployedId; cannot invoke remotely.`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 279, S: void 0, A: ["op.meta.deployedId", "`Operation '${op.meta.key}' has no deployedId; cannot invoke remotely.`"] });
477
+ const result = await functionsService.invoke(op.meta.deployedId, input, {
478
+ spaceId: options?.spaceId,
479
+ // Forward the conversation DXN so the remote runtime can rebuild conversation-scoped
480
+ // services (e.g. `AiContext.Service`) needed by operations like `GetContext`.
481
+ conversation: options?.conversation
482
+ });
483
+ if (result._kind === "success") {
484
+ return {
485
+ data: result.data
486
+ };
487
+ }
488
+ return {
489
+ error: ErrorCodec2.decode(result.error)
490
+ };
491
+ };
492
+ return Layer4.succeed(Operation.Service, {
493
+ invoke: (op, input, options) => Effect4.tryPromise(() => invokeRemote(op, input, options)).pipe(Effect4.orDie, Effect4.flatMap((outcome) => outcome.error ? Effect4.die(outcome.error) : Effect4.succeed(outcome.data))),
494
+ schedule: (op, input) => Effect4.sync(() => {
495
+ invariant(op.meta.deployedId, `Operation '${op.meta.key}' has no deployedId; cannot schedule remotely.`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 298, S: void 0, A: ["op.meta.deployedId", "`Operation '${op.meta.key}' has no deployedId; cannot schedule remotely.`"] });
496
+ void functionsService.invoke(op.meta.deployedId, input).catch(() => {
497
+ });
498
+ }),
499
+ invokePromise: (op, input, options) => invokeRemote(op, input, options).catch((error) => ({
500
+ error: error instanceof Error ? error : new Error(String(error))
501
+ }))
502
+ });
503
+ };
504
+ var unavailableOperationServiceLayer = Layer4.succeed(Operation.Service, {
505
+ invoke: () => Effect4.die("Operation.Service is not available: missing functionsService in EDGE context."),
506
+ schedule: () => Effect4.die("Operation.Service is not available: missing functionsService in EDGE context."),
507
+ invokePromise: async () => ({
508
+ error: new Error("Operation.Service is not available: missing functionsService in EDGE context.")
509
+ })
510
+ });
511
+ var makeOperationRegistryLayer = (functionsService, spaceId) => Layer4.succeed(OperationRegistry.Service, {
512
+ resolve: (key) => Effect4.gen(function* () {
513
+ const records = yield* Effect4.tryPromise(() => functionsService.query({
514
+ spaceId
515
+ })).pipe(Effect4.orDie);
516
+ const match = records.find((record) => Operation.getKey(record) === key);
517
+ return match ? Option.some(Operation.deserialize(match)) : Option.none();
518
+ })
519
+ });
520
+ var emptyOperationRegistryLayer = Layer4.succeed(OperationRegistry.Service, {
521
+ resolve: () => Effect4.succeed(Option.none())
522
+ });
523
+ var decodeRefsFromSchema = (ast, value2, db) => {
524
+ if (value2 == null) {
525
+ return value2;
526
+ }
527
+ const encoded = SchemaAST.encodedBoundAST(ast);
528
+ if (Ref.isRefType(encoded)) {
529
+ if (Ref.isRef(value2)) {
530
+ return value2;
531
+ }
532
+ if (typeof value2 === "object" && value2 !== null && typeof value2["/"] === "string") {
533
+ const resolver = db.graph.createRefResolver({
534
+ context: {
535
+ space: db.spaceId
536
+ }
537
+ });
538
+ return refFromEncodedReference(value2, resolver);
539
+ }
540
+ return value2;
541
+ }
542
+ switch (encoded._tag) {
543
+ case "TypeLiteral": {
544
+ if (typeof value2 !== "object" || value2 === null || Array.isArray(value2)) {
545
+ return value2;
546
+ }
547
+ const result = {
548
+ ...value2
549
+ };
550
+ for (const prop of SchemaAST.getPropertySignatures(encoded)) {
551
+ const key = prop.name.toString();
552
+ if (key in result) {
553
+ result[key] = decodeRefsFromSchema(prop.type, result[key], db);
554
+ }
555
+ }
556
+ return result;
557
+ }
558
+ case "TupleType": {
559
+ if (!Array.isArray(value2)) {
560
+ return value2;
561
+ }
562
+ if (encoded.elements.length === 0 && encoded.rest.length === 1) {
563
+ const elementType = encoded.rest[0].type;
564
+ return value2.map((item) => decodeRefsFromSchema(elementType, item, db));
565
+ }
566
+ return value2;
567
+ }
568
+ case "Union": {
569
+ const nonUndefined = encoded.types.filter((t) => !SchemaAST.isUndefinedKeyword(t));
570
+ if (nonUndefined.length === 1) {
571
+ return decodeRefsFromSchema(nonUndefined[0], value2, db);
572
+ }
573
+ return value2;
574
+ }
575
+ case "Suspend": {
576
+ return decodeRefsFromSchema(encoded.f(), value2, db);
577
+ }
578
+ case "Refinement": {
579
+ return decodeRefsFromSchema(encoded.from, value2, db);
580
+ }
581
+ default: {
582
+ return value2;
583
+ }
584
+ }
585
+ };
586
+ export {
587
+ ConfiguredCredentialsService,
588
+ FUNCTIONS_META_KEY,
589
+ FUNCTIONS_PRESET_META_KEY,
590
+ FunctionInvocationService,
591
+ MESSAGE_PROPERTY_TOOL_CALL_ID,
592
+ QueueService,
593
+ configuredCredentialsLayer,
594
+ credentialsLayerConfig,
595
+ credentialsLayerFromDatabase,
596
+ feedServiceFromQueueServiceLayer,
597
+ getUserFunctionIdInMetadata,
598
+ setUserFunctionIdInMetadata,
599
+ withAuthorization,
600
+ wrapFunctionHandler
601
+ };
602
+ //# sourceMappingURL=index.mjs.map