@dxos/functions 0.8.4-main.1068cf700f → 0.8.4-main.1c7ec43d41
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 +4 -6
- package/dist/lib/neutral/index.mjs +283 -919
- package/dist/lib/neutral/index.mjs.map +4 -4
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/types/src/index.d.ts +0 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/protocol/functions-ai-http-client.d.ts.map +1 -1
- package/dist/types/src/protocol/functions-ai-http-client.test.d.ts +2 -0
- package/dist/types/src/protocol/functions-ai-http-client.test.d.ts.map +1 -0
- package/dist/types/src/protocol/protocol.d.ts +14 -2
- package/dist/types/src/protocol/protocol.d.ts.map +1 -1
- package/dist/types/src/sdk.d.ts +5 -109
- package/dist/types/src/sdk.d.ts.map +1 -1
- package/dist/types/src/services/credentials.d.ts +15 -38
- package/dist/types/src/services/credentials.d.ts.map +1 -1
- package/dist/types/src/services/function-invocation-service.d.ts +5 -6
- package/dist/types/src/services/function-invocation-service.d.ts.map +1 -1
- package/dist/types/src/services/index.d.ts +1 -4
- package/dist/types/src/services/index.d.ts.map +1 -1
- package/dist/types/src/services/queues.d.ts +1 -46
- package/dist/types/src/services/queues.d.ts.map +1 -1
- package/dist/types/src/services/tracing.d.ts +1 -84
- package/dist/types/src/services/tracing.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +0 -4
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/url.d.ts +3 -3
- package/dist/types/src/types/url.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -16
- package/src/index.ts +0 -2
- package/src/protocol/functions-ai-http-client.test.ts +105 -0
- package/src/protocol/functions-ai-http-client.ts +75 -1
- package/src/protocol/protocol.test.ts +9 -10
- package/src/protocol/protocol.ts +224 -58
- package/src/sdk.ts +12 -270
- package/src/services/credentials.ts +75 -118
- package/src/services/function-invocation-service.ts +6 -10
- package/src/services/index.ts +1 -4
- package/src/services/queues.ts +1 -78
- package/src/services/tracing.ts +0 -159
- package/src/types/index.ts +0 -4
- package/src/types/url.ts +3 -3
- package/dist/types/src/errors.d.ts +0 -121
- package/dist/types/src/errors.d.ts.map +0 -1
- package/dist/types/src/example/fib.d.ts +0 -7
- package/dist/types/src/example/fib.d.ts.map +0 -1
- package/dist/types/src/example/forex-effect.d.ts +0 -3
- package/dist/types/src/example/forex-effect.d.ts.map +0 -1
- package/dist/types/src/example/index.d.ts +0 -12
- package/dist/types/src/example/index.d.ts.map +0 -1
- package/dist/types/src/example/reply.d.ts +0 -3
- package/dist/types/src/example/reply.d.ts.map +0 -1
- package/dist/types/src/example/sleep.d.ts +0 -5
- package/dist/types/src/example/sleep.d.ts.map +0 -1
- package/dist/types/src/operation-compatibility.test.d.ts +0 -2
- package/dist/types/src/operation-compatibility.test.d.ts.map +0 -1
- package/dist/types/src/services/event-logger.d.ts +0 -81
- package/dist/types/src/services/event-logger.d.ts.map +0 -1
- package/dist/types/src/types/Function.d.ts +0 -52
- package/dist/types/src/types/Function.d.ts.map +0 -1
- package/dist/types/src/types/Script.d.ts +0 -21
- package/dist/types/src/types/Script.d.ts.map +0 -1
- package/dist/types/src/types/Trigger.d.ts +0 -121
- package/dist/types/src/types/Trigger.d.ts.map +0 -1
- package/dist/types/src/types/TriggerEvent.d.ts +0 -74
- package/dist/types/src/types/TriggerEvent.d.ts.map +0 -1
- package/src/errors.ts +0 -21
- package/src/example/fib.ts +0 -32
- package/src/example/forex-effect.ts +0 -40
- package/src/example/index.ts +0 -13
- package/src/example/reply.ts +0 -21
- package/src/example/sleep.ts +0 -24
- package/src/operation-compatibility.test.ts +0 -185
- package/src/services/event-logger.ts +0 -127
- package/src/types/Function.ts +0 -82
- package/src/types/Script.ts +0 -34
- package/src/types/Trigger.ts +0 -143
- package/src/types/TriggerEvent.ts +0 -62
|
@@ -1,608 +1,13 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __export = (target, all) => {
|
|
3
|
-
for (var name in all)
|
|
4
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
// src/errors.ts
|
|
8
|
-
import { BaseError } from "@dxos/errors";
|
|
9
|
-
var ServiceNotAvailableError = class extends BaseError.extend("ServiceNotAvailable", "Service not available") {
|
|
10
|
-
constructor(service, options) {
|
|
11
|
-
super({
|
|
12
|
-
context: {
|
|
13
|
-
service
|
|
14
|
-
},
|
|
15
|
-
...options
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
var FunctionNotFoundError = class extends BaseError.extend("FunctionNotFound", "Function not found") {
|
|
20
|
-
constructor(functionKey, options) {
|
|
21
|
-
super({
|
|
22
|
-
context: {
|
|
23
|
-
function: functionKey
|
|
24
|
-
},
|
|
25
|
-
...options
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
var FunctionError = class extends BaseError.extend("FunctionError", "Function invocation error") {
|
|
30
|
-
};
|
|
31
|
-
var TriggerStateNotFoundError = class extends BaseError.extend("TriggerStateNotFound", "Trigger state not found") {
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
// src/example/fib.ts
|
|
35
|
-
import * as Effect2 from "effect/Effect";
|
|
36
|
-
import * as Schema6 from "effect/Schema";
|
|
37
|
-
|
|
38
|
-
// src/sdk.ts
|
|
39
|
-
import * as Effect from "effect/Effect";
|
|
40
|
-
import * as Schema5 from "effect/Schema";
|
|
41
|
-
import { Obj as Obj4, Type as Type5 } from "@dxos/echo";
|
|
42
|
-
import { assertArgument, failedInvariant } from "@dxos/invariant";
|
|
43
|
-
import { Operation } from "@dxos/operation";
|
|
44
|
-
|
|
45
|
-
// src/types/Function.ts
|
|
46
|
-
var Function_exports = {};
|
|
47
|
-
__export(Function_exports, {
|
|
48
|
-
Function: () => Function,
|
|
49
|
-
make: () => make2,
|
|
50
|
-
setFrom: () => setFrom
|
|
51
|
-
});
|
|
52
|
-
import * as Schema2 from "effect/Schema";
|
|
53
|
-
import { Annotation as Annotation2, JsonSchema, Obj as Obj2, Type as Type2 } from "@dxos/echo";
|
|
54
|
-
import { SystemTypeAnnotation } from "@dxos/echo/internal";
|
|
55
|
-
|
|
56
|
-
// src/types/Script.ts
|
|
57
|
-
var Script_exports = {};
|
|
58
|
-
__export(Script_exports, {
|
|
59
|
-
Script: () => Script,
|
|
60
|
-
make: () => make
|
|
61
|
-
});
|
|
62
|
-
import * as Schema from "effect/Schema";
|
|
63
|
-
import { Annotation, Obj, Ref, Type } from "@dxos/echo";
|
|
64
|
-
import { FormInputAnnotation } from "@dxos/echo/internal";
|
|
65
|
-
import { Text } from "@dxos/schema";
|
|
66
|
-
var Script = Schema.Struct({
|
|
67
|
-
name: Schema.String.pipe(Schema.optional),
|
|
68
|
-
description: Schema.String.pipe(Schema.optional),
|
|
69
|
-
// TODO(burdon): Change to hash of deployed content.
|
|
70
|
-
// Whether source has changed since last deploy.
|
|
71
|
-
changed: Schema.Boolean.pipe(FormInputAnnotation.set(false), Schema.optional),
|
|
72
|
-
source: Type.Ref(Text.Text).pipe(FormInputAnnotation.set(false))
|
|
73
|
-
}).pipe(Type.object({
|
|
74
|
-
typename: "dxos.org/type/Script",
|
|
75
|
-
version: "0.1.0"
|
|
76
|
-
}), Annotation.LabelAnnotation.set([
|
|
77
|
-
"name"
|
|
78
|
-
]));
|
|
79
|
-
var make = ({ source = "", ...props } = {}) => Obj.make(Script, {
|
|
80
|
-
...props,
|
|
81
|
-
source: Ref.make(Text.make(source))
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
// src/types/Function.ts
|
|
85
|
-
var Function = Schema2.Struct({
|
|
86
|
-
/**
|
|
87
|
-
* Global registry ID.
|
|
88
|
-
* NOTE: The `key` property refers to the original registry entry.
|
|
89
|
-
*/
|
|
90
|
-
// TODO(burdon): Create Format type for DXN-like ids, such as this and schema type.
|
|
91
|
-
// TODO(dmaretskyi): Consider making it part of ECHO meta.
|
|
92
|
-
// TODO(dmaretskyi): Make required.
|
|
93
|
-
key: Schema2.optional(Schema2.String).annotations({
|
|
94
|
-
description: "Unique registration key for the blueprint"
|
|
95
|
-
}),
|
|
96
|
-
name: Schema2.NonEmptyString,
|
|
97
|
-
version: Schema2.String,
|
|
98
|
-
description: Schema2.optional(Schema2.String),
|
|
99
|
-
/**
|
|
100
|
-
* ISO date string of the last deployment.
|
|
101
|
-
*/
|
|
102
|
-
updated: Schema2.optional(Schema2.String),
|
|
103
|
-
// Reference to a source script if it exists within ECHO.
|
|
104
|
-
// TODO(burdon): Don't ref ScriptType directly (core).
|
|
105
|
-
source: Schema2.optional(Type2.Ref(Script)),
|
|
106
|
-
inputSchema: Schema2.optional(JsonSchema.JsonSchema),
|
|
107
|
-
outputSchema: Schema2.optional(JsonSchema.JsonSchema),
|
|
108
|
-
/**
|
|
109
|
-
* List of required services.
|
|
110
|
-
* Match the Context.Tag keys of the FunctionServices variants.
|
|
111
|
-
*/
|
|
112
|
-
services: Schema2.optional(Schema2.Array(Schema2.String)),
|
|
113
|
-
// Local binding to a function name.
|
|
114
|
-
binding: Schema2.optional(Schema2.String)
|
|
115
|
-
}).pipe(Type2.object({
|
|
116
|
-
typename: "dxos.org/type/Function",
|
|
117
|
-
version: "0.1.0"
|
|
118
|
-
}), Annotation2.LabelAnnotation.set([
|
|
119
|
-
"name"
|
|
120
|
-
]), SystemTypeAnnotation.set(true));
|
|
121
|
-
var make2 = (props) => Obj2.make(Function, props);
|
|
122
|
-
var setFrom = (target, source) => {
|
|
123
|
-
Obj2.change(target, (t) => {
|
|
124
|
-
t.key = source.key ?? target.key;
|
|
125
|
-
t.name = source.name ?? target.name;
|
|
126
|
-
t.version = source.version;
|
|
127
|
-
t.description = source.description;
|
|
128
|
-
t.updated = source.updated;
|
|
129
|
-
t.inputSchema = source.inputSchema ? JSON.parse(JSON.stringify(source.inputSchema)) : void 0;
|
|
130
|
-
t.outputSchema = source.outputSchema ? JSON.parse(JSON.stringify(source.outputSchema)) : void 0;
|
|
131
|
-
Obj2.getMeta(t).keys = JSON.parse(JSON.stringify(Obj2.getMeta(source).keys));
|
|
132
|
-
});
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
// src/types/Trigger.ts
|
|
136
|
-
var Trigger_exports = {};
|
|
137
|
-
__export(Trigger_exports, {
|
|
138
|
-
EmailSpec: () => EmailSpec,
|
|
139
|
-
Kinds: () => Kinds,
|
|
140
|
-
QueueSpec: () => QueueSpec,
|
|
141
|
-
Spec: () => Spec,
|
|
142
|
-
SubscriptionSpec: () => SubscriptionSpec,
|
|
143
|
-
TimerSpec: () => TimerSpec,
|
|
144
|
-
Trigger: () => Trigger,
|
|
145
|
-
WebhookSpec: () => WebhookSpec,
|
|
146
|
-
make: () => make3
|
|
147
|
-
});
|
|
148
|
-
import * as Schema3 from "effect/Schema";
|
|
149
|
-
import * as SchemaAST from "effect/SchemaAST";
|
|
150
|
-
import { Obj as Obj3, QueryAST, Type as Type3 } from "@dxos/echo";
|
|
151
|
-
import { OptionsAnnotationId, SystemTypeAnnotation as SystemTypeAnnotation2 } from "@dxos/echo/internal";
|
|
152
|
-
import { DXN } from "@dxos/keys";
|
|
153
|
-
import { Expando } from "@dxos/schema";
|
|
154
|
-
var Kinds = [
|
|
155
|
-
"email",
|
|
156
|
-
"queue",
|
|
157
|
-
"subscription",
|
|
158
|
-
"timer",
|
|
159
|
-
"webhook"
|
|
160
|
-
];
|
|
161
|
-
var kindLiteralAnnotations = {
|
|
162
|
-
title: "Kind"
|
|
163
|
-
};
|
|
164
|
-
var EmailSpec = Schema3.Struct({
|
|
165
|
-
kind: Schema3.Literal("email").annotations(kindLiteralAnnotations)
|
|
166
|
-
});
|
|
167
|
-
var QueueSpec = Schema3.Struct({
|
|
168
|
-
kind: Schema3.Literal("queue").annotations(kindLiteralAnnotations),
|
|
169
|
-
// TODO(dmaretskyi): Change to a reference.
|
|
170
|
-
queue: DXN.Schema
|
|
171
|
-
});
|
|
172
|
-
var SubscriptionSpec = Schema3.Struct({
|
|
173
|
-
kind: Schema3.Literal("subscription").annotations(kindLiteralAnnotations),
|
|
174
|
-
query: Schema3.Struct({
|
|
175
|
-
raw: Schema3.optional(Schema3.String.annotations({
|
|
176
|
-
title: "Query"
|
|
177
|
-
})),
|
|
178
|
-
ast: QueryAST.Query
|
|
179
|
-
}),
|
|
180
|
-
options: Schema3.optional(Schema3.Struct({
|
|
181
|
-
// Watch changes to object (not just creation).
|
|
182
|
-
deep: Schema3.optional(Schema3.Boolean.annotations({
|
|
183
|
-
title: "Nested"
|
|
184
|
-
})),
|
|
185
|
-
// Debounce changes (delay in ms).
|
|
186
|
-
delay: Schema3.optional(Schema3.Number.annotations({
|
|
187
|
-
title: "Delay"
|
|
188
|
-
}))
|
|
189
|
-
}).annotations({
|
|
190
|
-
title: "Options"
|
|
191
|
-
}))
|
|
192
|
-
});
|
|
193
|
-
var TimerSpec = Schema3.Struct({
|
|
194
|
-
kind: Schema3.Literal("timer").annotations(kindLiteralAnnotations),
|
|
195
|
-
cron: Schema3.String.annotations({
|
|
196
|
-
title: "Cron",
|
|
197
|
-
[SchemaAST.ExamplesAnnotationId]: [
|
|
198
|
-
"0 0 * * *"
|
|
199
|
-
]
|
|
200
|
-
})
|
|
201
|
-
});
|
|
202
|
-
var WebhookSpec = Schema3.Struct({
|
|
203
|
-
kind: Schema3.Literal("webhook").annotations(kindLiteralAnnotations),
|
|
204
|
-
method: Schema3.optional(Schema3.String.annotations({
|
|
205
|
-
title: "Method",
|
|
206
|
-
[OptionsAnnotationId]: [
|
|
207
|
-
"GET",
|
|
208
|
-
"POST"
|
|
209
|
-
]
|
|
210
|
-
})),
|
|
211
|
-
port: Schema3.optional(Schema3.Number.annotations({
|
|
212
|
-
title: "Port"
|
|
213
|
-
}))
|
|
214
|
-
});
|
|
215
|
-
var Spec = Schema3.Union(EmailSpec, QueueSpec, SubscriptionSpec, TimerSpec, WebhookSpec).annotations({
|
|
216
|
-
title: "Trigger"
|
|
217
|
-
});
|
|
218
|
-
var TriggerSchema = Schema3.Struct({
|
|
219
|
-
/**
|
|
220
|
-
* Function or workflow to invoke.
|
|
221
|
-
*/
|
|
222
|
-
// TODO(dmaretskyi): Can be a Ref(FunctionType) or Ref(ComputeGraphType).
|
|
223
|
-
function: Schema3.optional(Type3.Ref(Expando.Expando).annotations({
|
|
224
|
-
title: "Function"
|
|
225
|
-
})),
|
|
226
|
-
/**
|
|
227
|
-
* Only used for workflowSchema.
|
|
228
|
-
* Specifies the input node in the circuit.
|
|
229
|
-
* @deprecated Remove and enforce a single input node in all compute graphSchema.
|
|
230
|
-
*/
|
|
231
|
-
inputNodeId: Schema3.optional(Schema3.String.annotations({
|
|
232
|
-
title: "Input Node ID"
|
|
233
|
-
})),
|
|
234
|
-
// TODO(burdon): NO BOOLEAN PROPERTIES (enabld/disabled/paused, etc.)
|
|
235
|
-
// Need lint rule; or agent rule to require PR review for "boolean" key word.
|
|
236
|
-
enabled: Schema3.optional(Schema3.Boolean.annotations({
|
|
237
|
-
title: "Enabled"
|
|
238
|
-
})),
|
|
239
|
-
spec: Schema3.optional(Spec),
|
|
240
|
-
/**
|
|
241
|
-
* Passed as the input data to the function.
|
|
242
|
-
* Must match the function's input schema.
|
|
243
|
-
*
|
|
244
|
-
* @example
|
|
245
|
-
* {
|
|
246
|
-
* item: '{{$.trigger.event}}',
|
|
247
|
-
* instructions: 'Summarize and perform entity-extraction'
|
|
248
|
-
* mailbox: { '/': 'dxn:echo:AAA:ZZZ' }
|
|
249
|
-
* }
|
|
250
|
-
*/
|
|
251
|
-
input: Schema3.optional(Schema3.Record({
|
|
252
|
-
key: Schema3.String,
|
|
253
|
-
value: Schema3.Any
|
|
254
|
-
}))
|
|
255
|
-
}).pipe(Type3.object({
|
|
256
|
-
typename: "dxos.org/type/Trigger",
|
|
257
|
-
version: "0.1.0"
|
|
258
|
-
}), SystemTypeAnnotation2.set(true));
|
|
259
|
-
var Trigger = TriggerSchema;
|
|
260
|
-
var make3 = (props) => Obj3.make(Trigger, props);
|
|
261
|
-
|
|
262
|
-
// src/types/TriggerEvent.ts
|
|
263
|
-
var TriggerEvent_exports = {};
|
|
264
|
-
__export(TriggerEvent_exports, {
|
|
265
|
-
EmailEvent: () => EmailEvent,
|
|
266
|
-
QueueEvent: () => QueueEvent,
|
|
267
|
-
SubscriptionEvent: () => SubscriptionEvent,
|
|
268
|
-
TimerEvent: () => TimerEvent,
|
|
269
|
-
TriggerEvent: () => TriggerEvent,
|
|
270
|
-
WebhookEvent: () => WebhookEvent
|
|
271
|
-
});
|
|
272
|
-
import * as Schema4 from "effect/Schema";
|
|
273
|
-
import { DXN as DXN2, Type as Type4 } from "@dxos/echo";
|
|
274
|
-
var EmailEvent = Schema4.Struct({
|
|
275
|
-
from: Schema4.String,
|
|
276
|
-
to: Schema4.String,
|
|
277
|
-
subject: Schema4.String,
|
|
278
|
-
created: Schema4.String,
|
|
279
|
-
body: Schema4.String
|
|
280
|
-
});
|
|
281
|
-
var QueueEvent = Schema4.Struct({
|
|
282
|
-
queue: DXN2.Schema,
|
|
283
|
-
item: Schema4.Any,
|
|
284
|
-
cursor: Schema4.String
|
|
285
|
-
});
|
|
286
|
-
var SubscriptionEvent = Schema4.Struct({
|
|
287
|
-
/**
|
|
288
|
-
* Type of the mutation.
|
|
289
|
-
*/
|
|
290
|
-
// TODO(dmaretskyi): Specify enum.
|
|
291
|
-
type: Schema4.String,
|
|
292
|
-
/**
|
|
293
|
-
* Reference to the object that was changed or created.
|
|
294
|
-
*/
|
|
295
|
-
subject: Type4.Ref(Type4.Obj),
|
|
296
|
-
/**
|
|
297
|
-
* @deprecated
|
|
298
|
-
*/
|
|
299
|
-
changedObjectId: Schema4.optional(Schema4.String)
|
|
300
|
-
});
|
|
301
|
-
var TimerEvent = Schema4.Struct({
|
|
302
|
-
tick: Schema4.Number
|
|
303
|
-
});
|
|
304
|
-
var WebhookEvent = Schema4.Struct({
|
|
305
|
-
url: Schema4.String,
|
|
306
|
-
method: Schema4.Literal("GET", "POST"),
|
|
307
|
-
headers: Schema4.Record({
|
|
308
|
-
key: Schema4.String,
|
|
309
|
-
value: Schema4.String
|
|
310
|
-
}),
|
|
311
|
-
bodyText: Schema4.String
|
|
312
|
-
});
|
|
313
|
-
var TriggerEvent = Schema4.Union(EmailEvent, QueueEvent, SubscriptionEvent, TimerEvent, WebhookEvent);
|
|
314
|
-
|
|
315
|
-
// src/types/url.ts
|
|
316
|
-
var FUNCTIONS_META_KEY = "dxos.org/service/function";
|
|
317
|
-
var FUNCTIONS_PRESET_META_KEY = "dxos.org/service/function-preset";
|
|
318
|
-
var getUserFunctionIdInMetadata = (meta) => {
|
|
319
|
-
return meta.keys.find((key) => key.source === FUNCTIONS_META_KEY)?.id;
|
|
320
|
-
};
|
|
321
|
-
var setUserFunctionIdInMetadata = (meta, functionId) => {
|
|
322
|
-
const key = meta.keys.find((key2) => key2.source === FUNCTIONS_META_KEY);
|
|
323
|
-
if (key) {
|
|
324
|
-
if (key.id !== functionId) {
|
|
325
|
-
throw new Error("Metadata mismatch");
|
|
326
|
-
}
|
|
327
|
-
} else {
|
|
328
|
-
meta.keys.push({
|
|
329
|
-
source: FUNCTIONS_META_KEY,
|
|
330
|
-
id: functionId
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
// src/sdk.ts
|
|
336
|
-
var typeId = Symbol.for("@dxos/functions/FunctionDefinition");
|
|
337
|
-
var defineFunction = ({ key, name, description, inputSchema, outputSchema = Schema5.Any, handler, types, services }) => {
|
|
338
|
-
if (!Schema5.isSchema(inputSchema)) {
|
|
339
|
-
throw new Error("Input schema must be a valid schema");
|
|
340
|
-
}
|
|
341
|
-
if (typeof handler !== "function") {
|
|
342
|
-
throw new Error("Handler must be a function");
|
|
343
|
-
}
|
|
344
|
-
const limit = Error.stackTraceLimit;
|
|
345
|
-
Error.stackTraceLimit = 2;
|
|
346
|
-
const traceError = new Error();
|
|
347
|
-
Error.stackTraceLimit = limit;
|
|
348
|
-
let cache = false;
|
|
349
|
-
const captureStackTrace = () => {
|
|
350
|
-
if (cache !== false) {
|
|
351
|
-
return cache;
|
|
352
|
-
}
|
|
353
|
-
if (traceError.stack !== void 0) {
|
|
354
|
-
const stack = traceError.stack.split("\n");
|
|
355
|
-
if (stack[2] !== void 0) {
|
|
356
|
-
cache = stack[2].trim();
|
|
357
|
-
return cache;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
};
|
|
361
|
-
const handlerWithSpan = (...args) => {
|
|
362
|
-
const result = handler(...args);
|
|
363
|
-
if (Effect.isEffect(result)) {
|
|
364
|
-
return Effect.withSpan(result, `${key ?? name}`, {
|
|
365
|
-
captureStackTrace
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
return result;
|
|
369
|
-
};
|
|
370
|
-
return {
|
|
371
|
-
[typeId]: true,
|
|
372
|
-
key,
|
|
373
|
-
name,
|
|
374
|
-
description,
|
|
375
|
-
inputSchema,
|
|
376
|
-
outputSchema,
|
|
377
|
-
handler: handlerWithSpan,
|
|
378
|
-
types: types ?? [],
|
|
379
|
-
services: !services ? [] : getServiceKeys(services)
|
|
380
|
-
};
|
|
381
|
-
};
|
|
382
|
-
var getServiceKeys = (services) => {
|
|
383
|
-
return services.map((tag) => {
|
|
384
|
-
if (typeof tag.key === "string") {
|
|
385
|
-
return tag.key;
|
|
386
|
-
}
|
|
387
|
-
failedInvariant();
|
|
388
|
-
});
|
|
389
|
-
};
|
|
390
|
-
var toOperation = (functionDef) => {
|
|
391
|
-
const op = Operation.make({
|
|
392
|
-
schema: {
|
|
393
|
-
input: functionDef.inputSchema,
|
|
394
|
-
output: functionDef.outputSchema ?? Schema5.Any
|
|
395
|
-
},
|
|
396
|
-
meta: {
|
|
397
|
-
key: functionDef.key,
|
|
398
|
-
name: functionDef.name,
|
|
399
|
-
description: functionDef.description
|
|
400
|
-
}
|
|
401
|
-
});
|
|
402
|
-
const operationHandler = (input) => {
|
|
403
|
-
const result = functionDef.handler({
|
|
404
|
-
context: {},
|
|
405
|
-
data: input
|
|
406
|
-
});
|
|
407
|
-
if (Effect.isEffect(result)) {
|
|
408
|
-
return result;
|
|
409
|
-
}
|
|
410
|
-
if (result instanceof Promise) {
|
|
411
|
-
return Effect.tryPromise(() => result);
|
|
412
|
-
}
|
|
413
|
-
return Effect.succeed(result);
|
|
414
|
-
};
|
|
415
|
-
return {
|
|
416
|
-
...op,
|
|
417
|
-
handler: operationHandler
|
|
418
|
-
};
|
|
419
|
-
};
|
|
420
|
-
var FunctionDefinition = {
|
|
421
|
-
make: defineFunction,
|
|
422
|
-
isFunction: (value2) => {
|
|
423
|
-
return typeof value2 === "object" && value2 !== null && Symbol.for("@dxos/functions/FunctionDefinition") in value2;
|
|
424
|
-
},
|
|
425
|
-
serialize: (functionDef) => {
|
|
426
|
-
assertArgument(FunctionDefinition.isFunction(functionDef), "functionDef");
|
|
427
|
-
return serializeFunction(functionDef);
|
|
428
|
-
},
|
|
429
|
-
deserialize: (functionObj) => {
|
|
430
|
-
assertArgument(Obj4.instanceOf(Function_exports.Function, functionObj), "functionObj");
|
|
431
|
-
return deserializeFunction(functionObj);
|
|
432
|
-
},
|
|
433
|
-
toOperation
|
|
434
|
-
};
|
|
435
|
-
var serializeFunction = (functionDef) => {
|
|
436
|
-
const fn4 = Function_exports.make({
|
|
437
|
-
key: functionDef.key,
|
|
438
|
-
name: functionDef.name,
|
|
439
|
-
version: "0.1.0",
|
|
440
|
-
description: functionDef.description,
|
|
441
|
-
inputSchema: Type5.toJsonSchema(functionDef.inputSchema),
|
|
442
|
-
outputSchema: !functionDef.outputSchema ? void 0 : Type5.toJsonSchema(functionDef.outputSchema),
|
|
443
|
-
services: functionDef.services
|
|
444
|
-
});
|
|
445
|
-
if (functionDef.meta?.deployedFunctionId) {
|
|
446
|
-
Obj4.change(fn4, (fn5) => setUserFunctionIdInMetadata(Obj4.getMeta(fn5), functionDef.meta.deployedFunctionId));
|
|
447
|
-
}
|
|
448
|
-
return fn4;
|
|
449
|
-
};
|
|
450
|
-
var deserializeFunction = (functionObj) => {
|
|
451
|
-
return {
|
|
452
|
-
[typeId]: true,
|
|
453
|
-
// TODO(dmaretskyi): Fix key.
|
|
454
|
-
key: functionObj.key ?? functionObj.name,
|
|
455
|
-
name: functionObj.name,
|
|
456
|
-
description: functionObj.description,
|
|
457
|
-
inputSchema: !functionObj.inputSchema ? Schema5.Unknown : Type5.toEffectSchema(functionObj.inputSchema),
|
|
458
|
-
outputSchema: !functionObj.outputSchema ? void 0 : Type5.toEffectSchema(functionObj.outputSchema),
|
|
459
|
-
// TODO(dmaretskyi): This should throw error.
|
|
460
|
-
handler: () => {
|
|
461
|
-
},
|
|
462
|
-
services: functionObj.services ?? [],
|
|
463
|
-
types: [],
|
|
464
|
-
meta: {
|
|
465
|
-
deployedFunctionId: getUserFunctionIdInMetadata(Obj4.getMeta(functionObj))
|
|
466
|
-
}
|
|
467
|
-
};
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
// src/example/fib.ts
|
|
471
|
-
var fib_default = defineFunction({
|
|
472
|
-
key: "example.org/function/fib",
|
|
473
|
-
name: "Fibonacci",
|
|
474
|
-
description: "Function that calculates a Fibonacci number",
|
|
475
|
-
inputSchema: Schema6.Struct({
|
|
476
|
-
iterations: Schema6.optional(Schema6.Number).annotations({
|
|
477
|
-
description: "Number of iterations",
|
|
478
|
-
default: 1e5
|
|
479
|
-
})
|
|
480
|
-
}),
|
|
481
|
-
outputSchema: Schema6.Struct({
|
|
482
|
-
result: Schema6.String
|
|
483
|
-
}),
|
|
484
|
-
handler: Effect2.fn(function* ({ data: { iterations = 1e5 } }) {
|
|
485
|
-
let a = 0n;
|
|
486
|
-
let b = 1n;
|
|
487
|
-
for (let i = 0; i < iterations; i++) {
|
|
488
|
-
a += b;
|
|
489
|
-
b = a - b;
|
|
490
|
-
}
|
|
491
|
-
return {
|
|
492
|
-
result: a.toString()
|
|
493
|
-
};
|
|
494
|
-
})
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
// src/example/reply.ts
|
|
498
|
-
import * as Console from "effect/Console";
|
|
499
|
-
import * as Effect3 from "effect/Effect";
|
|
500
|
-
import * as Schema7 from "effect/Schema";
|
|
501
|
-
var reply_default = defineFunction({
|
|
502
|
-
key: "example.org/function/reply",
|
|
503
|
-
name: "Reply",
|
|
504
|
-
description: "Function that echoes the input",
|
|
505
|
-
inputSchema: Schema7.Any,
|
|
506
|
-
outputSchema: Schema7.Any,
|
|
507
|
-
handler: Effect3.fn(function* ({ data }) {
|
|
508
|
-
yield* Console.log("reply", {
|
|
509
|
-
data
|
|
510
|
-
});
|
|
511
|
-
return data;
|
|
512
|
-
})
|
|
513
|
-
});
|
|
514
|
-
|
|
515
|
-
// src/example/sleep.ts
|
|
516
|
-
import * as Effect4 from "effect/Effect";
|
|
517
|
-
import * as Schema8 from "effect/Schema";
|
|
518
|
-
var sleep_default = defineFunction({
|
|
519
|
-
key: "example.org/function/sleep",
|
|
520
|
-
name: "Sleep",
|
|
521
|
-
description: "Function that sleeps for a given amount of time",
|
|
522
|
-
inputSchema: Schema8.Struct({
|
|
523
|
-
duration: Schema8.optional(Schema8.Number).annotations({
|
|
524
|
-
description: "Milliseconds to sleep",
|
|
525
|
-
default: 1e5
|
|
526
|
-
})
|
|
527
|
-
}),
|
|
528
|
-
outputSchema: Schema8.Void,
|
|
529
|
-
handler: Effect4.fn(function* ({ data: { duration = 1e5 } }) {
|
|
530
|
-
yield* Effect4.sleep(duration);
|
|
531
|
-
})
|
|
532
|
-
});
|
|
533
|
-
|
|
534
|
-
// src/example/index.ts
|
|
535
|
-
(function(Example2) {
|
|
536
|
-
Example2.fib = fib_default;
|
|
537
|
-
Example2.reply = reply_default;
|
|
538
|
-
Example2.sleep = sleep_default;
|
|
539
|
-
})(Example || (Example = {}));
|
|
540
|
-
var Example;
|
|
541
|
-
|
|
542
1
|
// src/services/credentials.ts
|
|
543
2
|
import * as HttpClient from "@effect/platform/HttpClient";
|
|
544
3
|
import * as HttpClientRequest from "@effect/platform/HttpClientRequest";
|
|
545
|
-
import * as
|
|
546
|
-
import * as Effect5 from "effect/Effect";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
547
5
|
import * as Layer from "effect/Layer";
|
|
548
6
|
import * as Redacted from "effect/Redacted";
|
|
7
|
+
import { Credential } from "@dxos/compute";
|
|
549
8
|
import { Query } from "@dxos/echo";
|
|
550
9
|
import { Database } from "@dxos/echo";
|
|
551
10
|
import { AccessToken } from "@dxos/types";
|
|
552
|
-
var CredentialsService = class _CredentialsService extends Context.Tag("@dxos/functions/CredentialsService")() {
|
|
553
|
-
static getCredential = (query) => Effect5.gen(function* () {
|
|
554
|
-
const credentials = yield* _CredentialsService;
|
|
555
|
-
return yield* Effect5.promise(() => credentials.getCredential(query));
|
|
556
|
-
});
|
|
557
|
-
static getApiKey = (query) => Effect5.gen(function* () {
|
|
558
|
-
const credential = yield* _CredentialsService.getCredential(query);
|
|
559
|
-
if (!credential.apiKey) {
|
|
560
|
-
throw new Error(`API key not found for service: ${query.service}`);
|
|
561
|
-
}
|
|
562
|
-
return Redacted.make(credential.apiKey);
|
|
563
|
-
});
|
|
564
|
-
static configuredLayer = (credentials) => Layer.succeed(_CredentialsService, new ConfiguredCredentialsService(credentials));
|
|
565
|
-
static layerConfig = (credentials) => Layer.effect(_CredentialsService, Effect5.gen(function* () {
|
|
566
|
-
const serviceCredentials = yield* Effect5.forEach(credentials, ({ service, apiKey }) => Effect5.gen(function* () {
|
|
567
|
-
return {
|
|
568
|
-
service,
|
|
569
|
-
apiKey: Redacted.value(yield* apiKey)
|
|
570
|
-
};
|
|
571
|
-
}));
|
|
572
|
-
return new ConfiguredCredentialsService(serviceCredentials);
|
|
573
|
-
}));
|
|
574
|
-
static layerFromDatabase = ({ caching = false } = {}) => Layer.effect(_CredentialsService, Effect5.gen(function* () {
|
|
575
|
-
const dbService = yield* Database.Service;
|
|
576
|
-
const cache = /* @__PURE__ */ new Map();
|
|
577
|
-
const queryCredentials = async (query) => {
|
|
578
|
-
const cacheKey = JSON.stringify(query);
|
|
579
|
-
if (caching && cache.has(cacheKey)) {
|
|
580
|
-
return cache.get(cacheKey);
|
|
581
|
-
}
|
|
582
|
-
const accessTokens = await dbService.db.query(Query.type(AccessToken.AccessToken)).run();
|
|
583
|
-
const credentials = accessTokens.filter((accessToken) => accessToken.source === query.service).map((accessToken) => ({
|
|
584
|
-
service: accessToken.source,
|
|
585
|
-
apiKey: accessToken.token
|
|
586
|
-
}));
|
|
587
|
-
if (caching) {
|
|
588
|
-
cache.set(cacheKey, credentials);
|
|
589
|
-
}
|
|
590
|
-
return credentials;
|
|
591
|
-
};
|
|
592
|
-
return {
|
|
593
|
-
getCredential: async (query) => {
|
|
594
|
-
const credentials = await queryCredentials(query);
|
|
595
|
-
if (credentials.length === 0) {
|
|
596
|
-
throw new Error(`Credential not found for service: ${query.service}`);
|
|
597
|
-
}
|
|
598
|
-
return credentials[0];
|
|
599
|
-
},
|
|
600
|
-
queryCredentials: async (query) => {
|
|
601
|
-
return queryCredentials(query);
|
|
602
|
-
}
|
|
603
|
-
};
|
|
604
|
-
}));
|
|
605
|
-
};
|
|
606
11
|
var ConfiguredCredentialsService = class {
|
|
607
12
|
credentials;
|
|
608
13
|
constructor(credentials = []) {
|
|
@@ -627,277 +32,127 @@ var withAuthorization = (token, kind) => HttpClient.mapRequest((request) => {
|
|
|
627
32
|
const authorization = kind ? `${kind} ${token}` : token;
|
|
628
33
|
return HttpClientRequest.setHeader(request, "Authorization", authorization);
|
|
629
34
|
});
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
import * as Effect7 from "effect/Effect";
|
|
634
|
-
import * as Layer3 from "effect/Layer";
|
|
635
|
-
import * as Schema9 from "effect/Schema";
|
|
636
|
-
import { Obj as Obj6, Type as Type6 } from "@dxos/echo";
|
|
637
|
-
import { invariant } from "@dxos/invariant";
|
|
638
|
-
import { LogLevel, log as log2 } from "@dxos/log";
|
|
639
|
-
|
|
640
|
-
// src/services/tracing.ts
|
|
641
|
-
import * as Context2 from "effect/Context";
|
|
642
|
-
import * as Effect6 from "effect/Effect";
|
|
643
|
-
import * as Layer2 from "effect/Layer";
|
|
644
|
-
import { AgentStatus } from "@dxos/ai";
|
|
645
|
-
import { Obj as Obj5 } from "@dxos/echo";
|
|
646
|
-
import { ObjectId } from "@dxos/keys";
|
|
647
|
-
import { Message } from "@dxos/types";
|
|
648
|
-
var TracingService = class _TracingService extends Context2.Tag("@dxos/functions/TracingService")() {
|
|
649
|
-
static noop = {
|
|
650
|
-
getTraceContext: () => ({}),
|
|
651
|
-
write: () => {
|
|
652
|
-
},
|
|
653
|
-
traceInvocationStart: () => Effect6.sync(() => ({
|
|
654
|
-
invocationId: ObjectId.random(),
|
|
655
|
-
invocationTraceQueue: void 0
|
|
656
|
-
})),
|
|
657
|
-
traceInvocationEnd: () => Effect6.sync(() => {
|
|
658
|
-
})
|
|
659
|
-
};
|
|
660
|
-
static layerNoop = Layer2.succeed(_TracingService, _TracingService.noop);
|
|
661
|
-
/**
|
|
662
|
-
* Creates a TracingService layer that emits events to the parent tracing service.
|
|
663
|
-
*/
|
|
664
|
-
static layerSubframe = (mapContext) => Layer2.effect(_TracingService, Effect6.gen(function* () {
|
|
665
|
-
const tracing = yield* _TracingService;
|
|
666
|
-
const context = mapContext(tracing.getTraceContext());
|
|
35
|
+
var configuredCredentialsLayer = (credentials) => Layer.succeed(Credential.CredentialsService, new ConfiguredCredentialsService(credentials));
|
|
36
|
+
var credentialsLayerConfig = (credentials) => Layer.effect(Credential.CredentialsService, Effect.gen(function* () {
|
|
37
|
+
const serviceCredentials = yield* Effect.forEach(credentials, ({ service, apiKey }) => Effect.gen(function* () {
|
|
667
38
|
return {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
traceInvocationStart: () => Effect6.die("Tracing invocation inside another invocation is not supported."),
|
|
671
|
-
traceInvocationEnd: () => Effect6.die("Tracing invocation inside another invocation is not supported.")
|
|
39
|
+
service,
|
|
40
|
+
apiKey: Redacted.value(yield* apiKey)
|
|
672
41
|
};
|
|
673
42
|
}));
|
|
674
|
-
|
|
675
|
-
* Create sublayer to trace an invocation.
|
|
676
|
-
* @param data
|
|
677
|
-
* @returns
|
|
678
|
-
*/
|
|
679
|
-
static layerInvocation = (data) => _TracingService.layerSubframe((context) => ({
|
|
680
|
-
...context,
|
|
681
|
-
currentInvocation: data
|
|
682
|
-
}));
|
|
683
|
-
/**
|
|
684
|
-
* Emit the current human-readable execution status.
|
|
685
|
-
*/
|
|
686
|
-
static emitStatus = Effect6.fnUntraced(function* (data) {
|
|
687
|
-
const tracing = yield* _TracingService;
|
|
688
|
-
tracing.write(Obj5.make(AgentStatus, {
|
|
689
|
-
parentMessage: tracing.getTraceContext().parentMessage,
|
|
690
|
-
toolCallId: tracing.getTraceContext().toolCallId,
|
|
691
|
-
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
692
|
-
...data
|
|
693
|
-
}), tracing.getTraceContext());
|
|
694
|
-
});
|
|
695
|
-
static emitConverationMessage = Effect6.fnUntraced(function* (data) {
|
|
696
|
-
const tracing = yield* _TracingService;
|
|
697
|
-
tracing.write(Obj5.make(Message.Message, {
|
|
698
|
-
parentMessage: tracing.getTraceContext().parentMessage,
|
|
699
|
-
...data,
|
|
700
|
-
properties: {
|
|
701
|
-
[MESSAGE_PROPERTY_TOOL_CALL_ID]: tracing.getTraceContext().toolCallId,
|
|
702
|
-
...data.properties
|
|
703
|
-
}
|
|
704
|
-
}), tracing.getTraceContext());
|
|
705
|
-
});
|
|
706
|
-
};
|
|
707
|
-
var MESSAGE_PROPERTY_TOOL_CALL_ID = "toolCallId";
|
|
708
|
-
|
|
709
|
-
// src/services/event-logger.ts
|
|
710
|
-
var __dxlog_file = "/__w/dxos/dxos/packages/core/functions/src/services/event-logger.ts";
|
|
711
|
-
var ComputeEventPayload = Schema9.Union(Schema9.Struct({
|
|
712
|
-
type: Schema9.Literal("begin-compute"),
|
|
713
|
-
nodeId: Schema9.String,
|
|
714
|
-
/**
|
|
715
|
-
* Names of the inputs begin computed.
|
|
716
|
-
*/
|
|
717
|
-
inputs: Schema9.Array(Schema9.String)
|
|
718
|
-
}), Schema9.Struct({
|
|
719
|
-
type: Schema9.Literal("end-compute"),
|
|
720
|
-
nodeId: Schema9.String,
|
|
721
|
-
/**
|
|
722
|
-
* Names of the outputs computed.
|
|
723
|
-
*/
|
|
724
|
-
outputs: Schema9.Array(Schema9.String)
|
|
725
|
-
}), Schema9.Struct({
|
|
726
|
-
type: Schema9.Literal("compute-input"),
|
|
727
|
-
nodeId: Schema9.String,
|
|
728
|
-
property: Schema9.String,
|
|
729
|
-
value: Schema9.Any
|
|
730
|
-
}), Schema9.Struct({
|
|
731
|
-
type: Schema9.Literal("compute-output"),
|
|
732
|
-
nodeId: Schema9.String,
|
|
733
|
-
property: Schema9.String,
|
|
734
|
-
value: Schema9.Any
|
|
735
|
-
}), Schema9.Struct({
|
|
736
|
-
type: Schema9.Literal("custom"),
|
|
737
|
-
nodeId: Schema9.String,
|
|
738
|
-
event: Schema9.Any
|
|
739
|
-
}));
|
|
740
|
-
var ComputeEvent = Schema9.Struct({
|
|
741
|
-
payload: ComputeEventPayload
|
|
742
|
-
}).pipe(Type6.object({
|
|
743
|
-
typename: "dxos.org/type/ComputeEvent",
|
|
744
|
-
version: "0.1.0"
|
|
43
|
+
return new ConfiguredCredentialsService(serviceCredentials);
|
|
745
44
|
}));
|
|
746
|
-
var
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
45
|
+
var credentialsLayerFromDatabase = ({ caching = false } = {}) => Layer.effect(Credential.CredentialsService, Effect.gen(function* () {
|
|
46
|
+
const dbService = yield* Database.Service;
|
|
47
|
+
const cache = /* @__PURE__ */ new Map();
|
|
48
|
+
const queryCredentials = async (query) => {
|
|
49
|
+
const cacheKey = JSON.stringify(query);
|
|
50
|
+
if (caching && cache.has(cacheKey)) {
|
|
51
|
+
return cache.get(cacheKey);
|
|
52
|
+
}
|
|
53
|
+
const accessTokens = await dbService.db.query(Query.type(AccessToken.AccessToken)).run();
|
|
54
|
+
const credentials = accessTokens.filter((accessToken) => accessToken.source === query.service).map((accessToken) => ({
|
|
55
|
+
service: accessToken.source,
|
|
56
|
+
apiKey: accessToken.token
|
|
57
|
+
}));
|
|
58
|
+
if (caching) {
|
|
59
|
+
cache.set(cacheKey, credentials);
|
|
60
|
+
}
|
|
61
|
+
return credentials;
|
|
751
62
|
};
|
|
752
|
-
/**
|
|
753
|
-
* Implements ComputeEventLogger using TracingService.
|
|
754
|
-
*/
|
|
755
|
-
static layerFromTracing = Layer3.effect(_ComputeEventLogger, Effect7.gen(function* () {
|
|
756
|
-
const tracing = yield* TracingService;
|
|
757
|
-
return {
|
|
758
|
-
log: (event) => {
|
|
759
|
-
tracing.write(Obj6.make(ComputeEvent, {
|
|
760
|
-
payload: event
|
|
761
|
-
}), tracing.getTraceContext());
|
|
762
|
-
},
|
|
763
|
-
nodeId: void 0
|
|
764
|
-
};
|
|
765
|
-
}));
|
|
766
|
-
};
|
|
767
|
-
var logCustomEvent = (data) => Effect7.gen(function* () {
|
|
768
|
-
const logger = yield* ComputeEventLogger;
|
|
769
|
-
if (!logger.nodeId) {
|
|
770
|
-
throw new Error("logCustomEvent must be called within a node compute function");
|
|
771
|
-
}
|
|
772
|
-
logger.log({
|
|
773
|
-
type: "custom",
|
|
774
|
-
nodeId: logger.nodeId,
|
|
775
|
-
event: data
|
|
776
|
-
});
|
|
777
|
-
});
|
|
778
|
-
var createDefectLogger = () => Effect7.catchAll((error) => Effect7.gen(function* () {
|
|
779
|
-
log2.error("unhandled effect error", {
|
|
780
|
-
error
|
|
781
|
-
}, {
|
|
782
|
-
F: __dxlog_file,
|
|
783
|
-
L: 102,
|
|
784
|
-
S: this,
|
|
785
|
-
C: (f, a) => f(...a)
|
|
786
|
-
});
|
|
787
|
-
throw error;
|
|
788
|
-
}));
|
|
789
|
-
var createEventLogger = (level, message = "event") => {
|
|
790
|
-
const logFunction = {
|
|
791
|
-
[LogLevel.WARN]: log2.warn,
|
|
792
|
-
[LogLevel.VERBOSE]: log2.verbose,
|
|
793
|
-
[LogLevel.DEBUG]: log2.debug,
|
|
794
|
-
[LogLevel.INFO]: log2.info,
|
|
795
|
-
[LogLevel.ERROR]: log2.error
|
|
796
|
-
}[level];
|
|
797
|
-
invariant(logFunction, void 0, {
|
|
798
|
-
F: __dxlog_file,
|
|
799
|
-
L: 120,
|
|
800
|
-
S: void 0,
|
|
801
|
-
A: [
|
|
802
|
-
"logFunction",
|
|
803
|
-
""
|
|
804
|
-
]
|
|
805
|
-
});
|
|
806
63
|
return {
|
|
807
|
-
|
|
808
|
-
|
|
64
|
+
getCredential: async (query) => {
|
|
65
|
+
const credentials = await queryCredentials(query);
|
|
66
|
+
if (credentials.length === 0) {
|
|
67
|
+
throw new Error(`Credential not found for service: ${query.service}`);
|
|
68
|
+
}
|
|
69
|
+
return credentials[0];
|
|
809
70
|
},
|
|
810
|
-
|
|
71
|
+
queryCredentials: async (query) => {
|
|
72
|
+
return queryCredentials(query);
|
|
73
|
+
}
|
|
811
74
|
};
|
|
812
|
-
};
|
|
75
|
+
}));
|
|
813
76
|
|
|
814
77
|
// src/services/function-invocation-service.ts
|
|
815
|
-
import * as
|
|
816
|
-
import * as
|
|
817
|
-
import * as
|
|
818
|
-
var FunctionInvocationService = class _FunctionInvocationService extends
|
|
819
|
-
static layerNotAvailable =
|
|
820
|
-
invokeFunction: () =>
|
|
821
|
-
resolveFunction: () =>
|
|
78
|
+
import * as Context from "effect/Context";
|
|
79
|
+
import * as Effect2 from "effect/Effect";
|
|
80
|
+
import * as Layer2 from "effect/Layer";
|
|
81
|
+
var FunctionInvocationService = class _FunctionInvocationService extends Context.Tag("@dxos/functions/FunctionInvocationService")() {
|
|
82
|
+
static layerNotAvailable = Layer2.succeed(_FunctionInvocationService, {
|
|
83
|
+
invokeFunction: () => Effect2.die("FunctionInvocationService is not avaialble."),
|
|
84
|
+
resolveFunction: () => Effect2.die("FunctionInvocationService is not available.")
|
|
822
85
|
});
|
|
823
|
-
static invokeFunction = (functionDef, input) =>
|
|
824
|
-
static resolveFunction = (key) =>
|
|
86
|
+
static invokeFunction = (functionDef, input) => Effect2.serviceFunctionEffect(_FunctionInvocationService, (service) => service.invokeFunction)(functionDef, input);
|
|
87
|
+
static resolveFunction = (key) => Effect2.serviceFunctionEffect(_FunctionInvocationService, (service) => service.resolveFunction)(key);
|
|
825
88
|
};
|
|
826
89
|
|
|
827
90
|
// src/services/queues.ts
|
|
828
|
-
import
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
var
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
throw new Error("Queues not available");
|
|
839
|
-
}
|
|
840
|
-
},
|
|
841
|
-
queue: void 0
|
|
842
|
-
});
|
|
843
|
-
static make = (queues, queue) => {
|
|
844
|
-
return {
|
|
845
|
-
queues,
|
|
846
|
-
queue
|
|
847
|
-
};
|
|
848
|
-
};
|
|
849
|
-
static layer = (queues, queue) => Layer5.succeed(_QueueService, _QueueService.make(queues, queue));
|
|
850
|
-
/**
|
|
851
|
-
* Gets a queue by its DXN.
|
|
852
|
-
*/
|
|
853
|
-
static getQueue = (dxn) => _QueueService.pipe(Effect9.map(({ queues }) => queues.get(dxn)));
|
|
854
|
-
/**
|
|
855
|
-
* Creates a new queue.
|
|
856
|
-
*/
|
|
857
|
-
static createQueue = (options) => _QueueService.pipe(Effect9.map(({ queues }) => queues.create(options)));
|
|
858
|
-
static append = (queue, objects) => Effect9.promise(() => queue.append(objects));
|
|
91
|
+
import { ContextQueueService, QueueService, feedServiceFromQueueServiceLayer } from "@dxos/echo-db";
|
|
92
|
+
|
|
93
|
+
// src/services/tracing.ts
|
|
94
|
+
var MESSAGE_PROPERTY_TOOL_CALL_ID = "toolCallId";
|
|
95
|
+
|
|
96
|
+
// src/types/url.ts
|
|
97
|
+
var FUNCTIONS_META_KEY = "org.dxos.service.function";
|
|
98
|
+
var FUNCTIONS_PRESET_META_KEY = "org.dxos.service.function-preset";
|
|
99
|
+
var getUserFunctionIdInMetadata = (meta) => {
|
|
100
|
+
return meta.keys.find((key) => key.source === FUNCTIONS_META_KEY)?.id;
|
|
859
101
|
};
|
|
860
|
-
var
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
102
|
+
var setUserFunctionIdInMetadata = (meta, functionId) => {
|
|
103
|
+
const key = meta.keys.find((key2) => key2.source === FUNCTIONS_META_KEY);
|
|
104
|
+
if (key) {
|
|
105
|
+
if (key.id !== functionId) {
|
|
106
|
+
throw new Error("Metadata mismatch");
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
meta.keys.push({
|
|
110
|
+
source: FUNCTIONS_META_KEY,
|
|
111
|
+
id: functionId
|
|
112
|
+
});
|
|
113
|
+
}
|
|
864
114
|
};
|
|
865
115
|
|
|
866
116
|
// src/protocol/protocol.ts
|
|
867
117
|
import * as AnthropicClient from "@effect/ai-anthropic/AnthropicClient";
|
|
868
|
-
import * as
|
|
869
|
-
import * as
|
|
870
|
-
import * as
|
|
871
|
-
import * as
|
|
872
|
-
import
|
|
118
|
+
import * as Effect4 from "effect/Effect";
|
|
119
|
+
import * as Layer4 from "effect/Layer";
|
|
120
|
+
import * as Option from "effect/Option";
|
|
121
|
+
import * as Schema from "effect/Schema";
|
|
122
|
+
import * as SchemaAST from "effect/SchemaAST";
|
|
123
|
+
import { AiModelResolver, AiService, OpaqueToolkit } from "@dxos/ai";
|
|
873
124
|
import { AnthropicResolver } from "@dxos/ai/resolvers";
|
|
125
|
+
import { FunctionError, InvalidOperationInputError, InvalidOperationOutputError, Operation, OperationRegistry, Trace } from "@dxos/compute";
|
|
874
126
|
import { LifecycleState, Resource } from "@dxos/context";
|
|
875
|
-
import { Database as Database2,
|
|
127
|
+
import { Database as Database2, Feed, JsonSchema, Ref } from "@dxos/echo";
|
|
128
|
+
import { createFeedServiceLayer, EchoClient } from "@dxos/echo-db";
|
|
876
129
|
import { refFromEncodedReference } from "@dxos/echo/internal";
|
|
877
|
-
import { EchoClient } from "@dxos/echo-db";
|
|
878
130
|
import { runAndForwardErrors } from "@dxos/effect";
|
|
879
|
-
import { assertState, failedInvariant
|
|
131
|
+
import { assertState, failedInvariant, invariant } from "@dxos/invariant";
|
|
880
132
|
import { PublicKey } from "@dxos/keys";
|
|
133
|
+
import { log as log2 } from "@dxos/log";
|
|
134
|
+
import { ErrorCodec as ErrorCodec2 } from "@dxos/protocols";
|
|
881
135
|
|
|
882
136
|
// src/protocol/functions-ai-http-client.ts
|
|
883
137
|
import * as Headers from "@effect/platform/Headers";
|
|
884
138
|
import * as HttpClient2 from "@effect/platform/HttpClient";
|
|
885
139
|
import * as HttpClientError from "@effect/platform/HttpClientError";
|
|
886
140
|
import * as HttpClientResponse from "@effect/platform/HttpClientResponse";
|
|
887
|
-
import * as
|
|
141
|
+
import * as Effect3 from "effect/Effect";
|
|
888
142
|
import * as FiberRef from "effect/FiberRef";
|
|
889
|
-
import * as
|
|
143
|
+
import * as Layer3 from "effect/Layer";
|
|
890
144
|
import * as Stream from "effect/Stream";
|
|
891
|
-
import {
|
|
145
|
+
import { FunctionsAiMemoizationMissError, FunctionsAiUpstreamError } from "@dxos/compute";
|
|
146
|
+
import { log } from "@dxos/log";
|
|
892
147
|
import { ErrorCodec } from "@dxos/protocols";
|
|
893
|
-
var
|
|
148
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/core/compute/functions/src/protocol/functions-ai-http-client.ts";
|
|
894
149
|
var requestInitTagKey = "@effect/platform/FetchHttpClient/FetchOptions";
|
|
895
150
|
var FunctionsAiHttpClient = class _FunctionsAiHttpClient {
|
|
896
151
|
static make = (service) => HttpClient2.make((request, url, signal, fiber) => {
|
|
897
152
|
const context = fiber.getFiberRef(FiberRef.currentContext);
|
|
898
153
|
const options = context.unsafeMap.get(requestInitTagKey) ?? {};
|
|
899
154
|
const headers = options.headers ? Headers.merge(Headers.fromInput(options.headers), request.headers) : request.headers;
|
|
900
|
-
const send = (body) =>
|
|
155
|
+
const send = (body) => Effect3.tryPromise({
|
|
901
156
|
try: () => service.fetch(new Request(url, {
|
|
902
157
|
...options,
|
|
903
158
|
method: request.method,
|
|
@@ -905,21 +160,21 @@ var FunctionsAiHttpClient = class _FunctionsAiHttpClient {
|
|
|
905
160
|
body
|
|
906
161
|
})),
|
|
907
162
|
catch: (cause) => {
|
|
908
|
-
|
|
163
|
+
log.error("Failed to fetch", {
|
|
909
164
|
errorSerialized: ErrorCodec.encode(cause)
|
|
910
|
-
}, {
|
|
911
|
-
F: __dxlog_file2,
|
|
912
|
-
L: 43,
|
|
913
|
-
S: this,
|
|
914
|
-
C: (f, a) => f(...a)
|
|
915
|
-
});
|
|
165
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 31, S: this });
|
|
916
166
|
return new HttpClientError.RequestError({
|
|
917
167
|
request,
|
|
918
168
|
reason: "Transport",
|
|
919
169
|
cause
|
|
920
170
|
});
|
|
921
171
|
}
|
|
922
|
-
}).pipe(
|
|
172
|
+
}).pipe(Effect3.flatMap((response) => (
|
|
173
|
+
// Inspect the body before handing the response to `@effect/ai` so that structured
|
|
174
|
+
// upstream errors surface as typed defects (`FunctionsAiUpstreamError` and friends)
|
|
175
|
+
// rather than as the generic `HttpResponseError` from `@effect/ai/AiError`.
|
|
176
|
+
Effect3.flatMap(Effect3.promise(() => parseUpstreamError(response)), (typedError) => typedError ? Effect3.die(typedError) : Effect3.succeed(HttpClientResponse.fromWeb(request, response)))
|
|
177
|
+
)));
|
|
923
178
|
switch (request.body._tag) {
|
|
924
179
|
case "Raw":
|
|
925
180
|
case "Uint8Array":
|
|
@@ -927,14 +182,54 @@ var FunctionsAiHttpClient = class _FunctionsAiHttpClient {
|
|
|
927
182
|
case "FormData":
|
|
928
183
|
return send(request.body.formData);
|
|
929
184
|
case "Stream":
|
|
930
|
-
return Stream.toReadableStreamEffect(request.body.stream).pipe(
|
|
185
|
+
return Stream.toReadableStreamEffect(request.body.stream).pipe(Effect3.flatMap(send));
|
|
931
186
|
}
|
|
932
187
|
return send(void 0);
|
|
933
188
|
});
|
|
934
|
-
static layer = (service) =>
|
|
189
|
+
static layer = (service) => Layer3.succeed(HttpClient2.HttpClient, _FunctionsAiHttpClient.make(service));
|
|
190
|
+
};
|
|
191
|
+
var parseUpstreamError = async (response) => {
|
|
192
|
+
if (response.ok) {
|
|
193
|
+
return void 0;
|
|
194
|
+
}
|
|
195
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
196
|
+
if (!contentType.toLowerCase().includes("application/json")) {
|
|
197
|
+
return void 0;
|
|
198
|
+
}
|
|
199
|
+
let body;
|
|
200
|
+
try {
|
|
201
|
+
body = await response.clone().json();
|
|
202
|
+
} catch {
|
|
203
|
+
return void 0;
|
|
204
|
+
}
|
|
205
|
+
if (!body || body.type !== "error" || typeof body.error !== "object" || body.error === null) {
|
|
206
|
+
return void 0;
|
|
207
|
+
}
|
|
208
|
+
const inner = body.error;
|
|
209
|
+
const message = inner.message ?? `Upstream AI service responded with HTTP ${response.status}`;
|
|
210
|
+
if (inner.type === "memoization_miss" && typeof inner.cacheKey === "string") {
|
|
211
|
+
return new FunctionsAiMemoizationMissError({
|
|
212
|
+
message,
|
|
213
|
+
context: {
|
|
214
|
+
cacheKey: inner.cacheKey,
|
|
215
|
+
status: response.status
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
return new FunctionsAiUpstreamError({
|
|
220
|
+
message,
|
|
221
|
+
context: {
|
|
222
|
+
type: inner.type,
|
|
223
|
+
status: response.status,
|
|
224
|
+
...inner.cacheKey ? {
|
|
225
|
+
cacheKey: inner.cacheKey
|
|
226
|
+
} : {}
|
|
227
|
+
}
|
|
228
|
+
});
|
|
935
229
|
};
|
|
936
230
|
|
|
937
231
|
// src/protocol/protocol.ts
|
|
232
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/compute/functions/src/protocol/protocol.ts";
|
|
938
233
|
function _ts_add_disposable_resource(env, value2, async) {
|
|
939
234
|
if (value2 !== null && value2 !== void 0) {
|
|
940
235
|
if (typeof value2 !== "object" && typeof value2 !== "function") throw new TypeError("Object expected.");
|
|
@@ -1000,22 +295,22 @@ function _ts_dispose_resources(env) {
|
|
|
1000
295
|
return next();
|
|
1001
296
|
})(env);
|
|
1002
297
|
}
|
|
1003
|
-
var
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
throw new TypeError("Invalid function definition");
|
|
298
|
+
var wrapFunctionHandler = (func, opts = {}) => {
|
|
299
|
+
if (!Operation.isOperationWithHandler(func)) {
|
|
300
|
+
throw new TypeError("Expected operation with handler");
|
|
1007
301
|
}
|
|
302
|
+
const serviceTags = func.services.map((service) => service.key);
|
|
1008
303
|
return {
|
|
1009
304
|
meta: {
|
|
1010
|
-
key: func.key,
|
|
1011
|
-
name: func.name,
|
|
1012
|
-
description: func.description,
|
|
1013
|
-
inputSchema:
|
|
1014
|
-
outputSchema: func.
|
|
1015
|
-
services: func.services
|
|
305
|
+
key: func.meta.key,
|
|
306
|
+
name: func.meta.name,
|
|
307
|
+
description: func.meta.description,
|
|
308
|
+
inputSchema: JsonSchema.toJsonSchema(func.input),
|
|
309
|
+
outputSchema: func.output === void 0 ? void 0 : JsonSchema.toJsonSchema(func.output),
|
|
310
|
+
services: func.services.map((service) => service.key)
|
|
1016
311
|
},
|
|
1017
312
|
handler: async ({ data, context }) => {
|
|
1018
|
-
if ((
|
|
313
|
+
if ((serviceTags.includes(Database2.Service.key) || serviceTags.includes(QueueService.key) || serviceTags.includes(Feed.FeedService.key)) && (!context.services.dataService || !context.services.queryService)) {
|
|
1019
314
|
throw new FunctionError({
|
|
1020
315
|
message: "Services not provided: dataService, queryService"
|
|
1021
316
|
});
|
|
@@ -1027,40 +322,43 @@ var wrapFunctionHandler = (func) => {
|
|
|
1027
322
|
hasError: false
|
|
1028
323
|
};
|
|
1029
324
|
try {
|
|
1030
|
-
if (!
|
|
325
|
+
if (!SchemaAST.isAnyKeyword(func.input.ast)) {
|
|
1031
326
|
try {
|
|
1032
|
-
|
|
327
|
+
Schema.validateSync(func.input, {
|
|
328
|
+
onExcessProperty: "error"
|
|
329
|
+
})(data);
|
|
1033
330
|
} catch (error) {
|
|
1034
|
-
throw new
|
|
1035
|
-
message:
|
|
331
|
+
throw new InvalidOperationInputError({
|
|
332
|
+
message: `Operation input did not match schema (${func.meta.key}): ${error.message}`,
|
|
1036
333
|
cause: error
|
|
1037
334
|
});
|
|
1038
335
|
}
|
|
1039
336
|
}
|
|
1040
|
-
const funcContext = _ts_add_disposable_resource(env, await new FunctionContext(context).open(), true);
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
"'Database is required for functions with types'"
|
|
1049
|
-
]
|
|
1050
|
-
});
|
|
1051
|
-
await funcContext.db.graph.schemaRegistry.register(func.types);
|
|
337
|
+
const funcContext = _ts_add_disposable_resource(env, await new FunctionContext(context, opts).open(), true);
|
|
338
|
+
const types = [
|
|
339
|
+
...opts.types ?? [],
|
|
340
|
+
...func.types ?? []
|
|
341
|
+
];
|
|
342
|
+
if (types.length > 0) {
|
|
343
|
+
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'"] });
|
|
344
|
+
await funcContext.db.graph.schemaRegistry.register(types);
|
|
1052
345
|
}
|
|
1053
|
-
const dataWithDecodedRefs = funcContext.db && !
|
|
1054
|
-
let result = await func.handler(
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
data: dataWithDecodedRefs
|
|
1058
|
-
});
|
|
1059
|
-
if (Effect11.isEffect(result)) {
|
|
1060
|
-
result = await runAndForwardErrors(result.pipe(Effect11.orDie, Effect11.provide(funcContext.createLayer())));
|
|
346
|
+
const dataWithDecodedRefs = funcContext.db && !SchemaAST.isAnyKeyword(func.input.ast) ? decodeRefsFromSchema(func.input.ast, data, funcContext.db) : data;
|
|
347
|
+
let result = await func.handler(dataWithDecodedRefs);
|
|
348
|
+
if (Effect4.isEffect(result)) {
|
|
349
|
+
result = await runAndForwardErrors(result.pipe(Effect4.orDie, Effect4.provide(funcContext.createLayer())));
|
|
1061
350
|
}
|
|
1062
|
-
if (func.
|
|
1063
|
-
|
|
351
|
+
if (func.output && !SchemaAST.isAnyKeyword(func.output.ast)) {
|
|
352
|
+
try {
|
|
353
|
+
Schema.validateSync(func.output, {
|
|
354
|
+
onExcessProperty: "error"
|
|
355
|
+
})(result);
|
|
356
|
+
} catch (error) {
|
|
357
|
+
throw new InvalidOperationOutputError({
|
|
358
|
+
message: `Operation output did not match schema (${func.meta.key}): ${error.message}`,
|
|
359
|
+
cause: error
|
|
360
|
+
});
|
|
361
|
+
}
|
|
1064
362
|
}
|
|
1065
363
|
return result;
|
|
1066
364
|
} catch (e) {
|
|
@@ -1081,9 +379,11 @@ var FunctionContext = class extends Resource {
|
|
|
1081
379
|
client;
|
|
1082
380
|
db;
|
|
1083
381
|
queues;
|
|
1084
|
-
|
|
382
|
+
opts;
|
|
383
|
+
constructor(context, opts) {
|
|
1085
384
|
super();
|
|
1086
385
|
this.context = context;
|
|
386
|
+
this.opts = opts;
|
|
1087
387
|
if (context.services.dataService && context.services.queryService) {
|
|
1088
388
|
this.client = new EchoClient().connectToService({
|
|
1089
389
|
dataService: context.services.dataService,
|
|
@@ -1095,12 +395,12 @@ var FunctionContext = class extends Resource {
|
|
|
1095
395
|
async _open() {
|
|
1096
396
|
await this.client?.open();
|
|
1097
397
|
this.db = this.client && this.context.spaceId ? this.client.constructDatabase({
|
|
1098
|
-
spaceId: this.context.spaceId ??
|
|
1099
|
-
spaceKey: PublicKey.fromHex(this.context.spaceKey ??
|
|
398
|
+
spaceId: this.context.spaceId ?? failedInvariant(),
|
|
399
|
+
spaceKey: PublicKey.fromHex(this.context.spaceKey ?? failedInvariant("spaceKey missing in context")),
|
|
1100
400
|
reactiveSchemaQuery: false,
|
|
1101
401
|
preloadSchemaOnOpen: false
|
|
1102
402
|
}) : void 0;
|
|
1103
|
-
await this.db?.setSpaceRoot(this.context.spaceRootUrl ??
|
|
403
|
+
await this.db?.setSpaceRoot(this.context.spaceRootUrl ?? failedInvariant("spaceRootUrl missing in context"));
|
|
1104
404
|
await this.db?.open();
|
|
1105
405
|
this.queues = this.client && this.context.spaceId ? this.client.constructQueueFactory(this.context.spaceId) : void 0;
|
|
1106
406
|
}
|
|
@@ -1112,29 +412,111 @@ var FunctionContext = class extends Resource {
|
|
|
1112
412
|
assertState(this._lifecycleState === LifecycleState.OPEN, "FunctionContext is not open");
|
|
1113
413
|
const dbLayer = this.db ? Database2.layer(this.db) : Database2.notAvailable;
|
|
1114
414
|
const queuesLayer = this.queues ? QueueService.layer(this.queues) : QueueService.notAvailable;
|
|
1115
|
-
const
|
|
415
|
+
const feedLayer = this.queues ? createFeedServiceLayer(this.queues) : Feed.notAvailable;
|
|
416
|
+
const credentials = dbLayer ? credentialsLayerFromDatabase({
|
|
1116
417
|
caching: true
|
|
1117
|
-
}).pipe(
|
|
1118
|
-
const
|
|
1119
|
-
const
|
|
1120
|
-
const
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
418
|
+
}).pipe(Layer4.provide(dbLayer)) : configuredCredentialsLayer([]);
|
|
419
|
+
const aiLayer = this.context.services.functionsAiService ? InternalAiServiceLayer(this.context.services.functionsAiService) : AiService.notAvailable;
|
|
420
|
+
const operationServiceLayer = this.context.services.functionsService ? makeOperationServiceLayer(this.context.services.functionsService) : unavailableOperationServiceLayer;
|
|
421
|
+
const operationRegistryLayer = this.context.services.functionsService ? makeOperationRegistryLayer(this.context.services.functionsService, this.context.spaceId) : emptyOperationRegistryLayer;
|
|
422
|
+
const traceWriterLayer = this.context.services.traceService ? makeTraceWriterLayer(this.context.services.traceService) : Trace.writerLayerNoop;
|
|
423
|
+
log2("Creating function context layer", {
|
|
424
|
+
traceService: !!this.context.services.traceService,
|
|
425
|
+
functionsService: !!this.context.services.functionsService,
|
|
426
|
+
functionsAiService: !!this.context.services.functionsAiService,
|
|
427
|
+
spaceId: this.context.spaceId,
|
|
428
|
+
spaceRootUrl: this.context.spaceRootUrl,
|
|
429
|
+
toolkits: this.opts.toolkits?.length ?? 0,
|
|
430
|
+
types: this.opts.types?.length ?? 0
|
|
431
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 220, S: this });
|
|
432
|
+
return Layer4.mergeAll(
|
|
433
|
+
dbLayer,
|
|
434
|
+
queuesLayer,
|
|
435
|
+
feedLayer,
|
|
436
|
+
credentials,
|
|
437
|
+
operationServiceLayer,
|
|
438
|
+
operationRegistryLayer,
|
|
439
|
+
aiLayer,
|
|
440
|
+
OpaqueToolkit.providerLayer(OpaqueToolkit.merge(...this.opts.toolkits ?? [])),
|
|
441
|
+
traceWriterLayer,
|
|
442
|
+
// `FunctionInvocationService` is deprecated; new code should yield `Operation.Service`.
|
|
443
|
+
// The cloudflare wrapper provides only the unavailable layer to satisfy the (still-present)
|
|
444
|
+
// type union — handlers that yield it will die at invocation time.
|
|
445
|
+
FunctionInvocationService.layerNotAvailable
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
var makeTraceWriterLayer = (traceService) => Layer4.succeed(Trace.TraceService, {
|
|
450
|
+
write: (eventType, payload) => {
|
|
451
|
+
log2("Writing trace event", {
|
|
452
|
+
eventType: eventType.key
|
|
453
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 240, S: void 0 });
|
|
454
|
+
traceService.write([
|
|
455
|
+
{
|
|
456
|
+
key: eventType.key,
|
|
457
|
+
isEphemeral: eventType.isEphemeral,
|
|
458
|
+
data: payload
|
|
459
|
+
}
|
|
460
|
+
]);
|
|
1125
461
|
}
|
|
462
|
+
});
|
|
463
|
+
var InternalAiServiceLayer = (functionsAiService) => AiModelResolver.AiModelResolver.buildAiService.pipe(Layer4.provide(AnthropicResolver.make().pipe(Layer4.provide(AnthropicClient.layer({
|
|
464
|
+
// Note: It doesn't matter what is base url here, it will be proxied to ai gateway in edge.
|
|
465
|
+
apiUrl: "http://internal/provider/anthropic"
|
|
466
|
+
}).pipe(Layer4.provide(FunctionsAiHttpClient.layer(functionsAiService)))))));
|
|
467
|
+
var makeOperationServiceLayer = (functionsService) => {
|
|
468
|
+
const invokeRemote = async (op, input, options) => {
|
|
469
|
+
invariant(op.meta.deployedId, `Operation '${op.meta.key}' has no deployedId; cannot invoke remotely.`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 264, S: void 0, A: ["op.meta.deployedId", "`Operation '${op.meta.key}' has no deployedId; cannot invoke remotely.`"] });
|
|
470
|
+
const result = await functionsService.invoke(op.meta.deployedId, input, {
|
|
471
|
+
spaceId: options?.spaceId
|
|
472
|
+
});
|
|
473
|
+
if (result._kind === "success") {
|
|
474
|
+
return {
|
|
475
|
+
data: result.data
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
return {
|
|
479
|
+
error: ErrorCodec2.decode(result.error)
|
|
480
|
+
};
|
|
481
|
+
};
|
|
482
|
+
return Layer4.succeed(Operation.Service, {
|
|
483
|
+
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))),
|
|
484
|
+
schedule: (op, input) => Effect4.sync(() => {
|
|
485
|
+
invariant(op.meta.deployedId, `Operation '${op.meta.key}' has no deployedId; cannot schedule remotely.`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 280, S: void 0, A: ["op.meta.deployedId", "`Operation '${op.meta.key}' has no deployedId; cannot schedule remotely.`"] });
|
|
486
|
+
void functionsService.invoke(op.meta.deployedId, input).catch(() => {
|
|
487
|
+
});
|
|
488
|
+
}),
|
|
489
|
+
invokePromise: (op, input, options) => invokeRemote(op, input, options).catch((error) => ({
|
|
490
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
491
|
+
}))
|
|
492
|
+
});
|
|
1126
493
|
};
|
|
1127
|
-
var
|
|
1128
|
-
|
|
1129
|
-
|
|
494
|
+
var unavailableOperationServiceLayer = Layer4.succeed(Operation.Service, {
|
|
495
|
+
invoke: () => Effect4.die("Operation.Service is not available: missing functionsService in EDGE context."),
|
|
496
|
+
schedule: () => Effect4.die("Operation.Service is not available: missing functionsService in EDGE context."),
|
|
497
|
+
invokePromise: async () => ({
|
|
498
|
+
error: new Error("Operation.Service is not available: missing functionsService in EDGE context.")
|
|
499
|
+
})
|
|
500
|
+
});
|
|
501
|
+
var makeOperationRegistryLayer = (functionsService, spaceId) => Layer4.succeed(OperationRegistry.Service, {
|
|
502
|
+
resolve: (key) => Effect4.gen(function* () {
|
|
503
|
+
const records = yield* Effect4.tryPromise(() => functionsService.query({
|
|
504
|
+
spaceId
|
|
505
|
+
})).pipe(Effect4.orDie);
|
|
506
|
+
const match = records.find((record) => record.key === key);
|
|
507
|
+
return match ? Option.some(Operation.deserialize(match)) : Option.none();
|
|
508
|
+
})
|
|
509
|
+
});
|
|
510
|
+
var emptyOperationRegistryLayer = Layer4.succeed(OperationRegistry.Service, {
|
|
511
|
+
resolve: () => Effect4.succeed(Option.none())
|
|
1130
512
|
});
|
|
1131
513
|
var decodeRefsFromSchema = (ast, value2, db) => {
|
|
1132
514
|
if (value2 == null) {
|
|
1133
515
|
return value2;
|
|
1134
516
|
}
|
|
1135
|
-
const encoded =
|
|
1136
|
-
if (
|
|
1137
|
-
if (
|
|
517
|
+
const encoded = SchemaAST.encodedBoundAST(ast);
|
|
518
|
+
if (Ref.isRefType(encoded)) {
|
|
519
|
+
if (Ref.isRef(value2)) {
|
|
1138
520
|
return value2;
|
|
1139
521
|
}
|
|
1140
522
|
if (typeof value2 === "object" && value2 !== null && typeof value2["/"] === "string") {
|
|
@@ -1155,7 +537,7 @@ var decodeRefsFromSchema = (ast, value2, db) => {
|
|
|
1155
537
|
const result = {
|
|
1156
538
|
...value2
|
|
1157
539
|
};
|
|
1158
|
-
for (const prop of
|
|
540
|
+
for (const prop of SchemaAST.getPropertySignatures(encoded)) {
|
|
1159
541
|
const key = prop.name.toString();
|
|
1160
542
|
if (key in result) {
|
|
1161
543
|
result[key] = decodeRefsFromSchema(prop.type, result[key], db);
|
|
@@ -1174,7 +556,7 @@ var decodeRefsFromSchema = (ast, value2, db) => {
|
|
|
1174
556
|
return value2;
|
|
1175
557
|
}
|
|
1176
558
|
case "Union": {
|
|
1177
|
-
const nonUndefined = encoded.types.filter((t) => !
|
|
559
|
+
const nonUndefined = encoded.types.filter((t) => !SchemaAST.isUndefinedKeyword(t));
|
|
1178
560
|
if (nonUndefined.length === 1) {
|
|
1179
561
|
return decodeRefsFromSchema(nonUndefined[0], value2, db);
|
|
1180
562
|
}
|
|
@@ -1192,37 +574,19 @@ var decodeRefsFromSchema = (ast, value2, db) => {
|
|
|
1192
574
|
}
|
|
1193
575
|
};
|
|
1194
576
|
export {
|
|
1195
|
-
ComputeEvent,
|
|
1196
|
-
ComputeEventLogger,
|
|
1197
|
-
ComputeEventPayload,
|
|
1198
577
|
ConfiguredCredentialsService,
|
|
1199
578
|
ContextQueueService,
|
|
1200
|
-
CredentialsService,
|
|
1201
|
-
Example,
|
|
1202
579
|
FUNCTIONS_META_KEY,
|
|
1203
580
|
FUNCTIONS_PRESET_META_KEY,
|
|
1204
|
-
Function_exports as Function,
|
|
1205
|
-
FunctionDefinition,
|
|
1206
|
-
FunctionError,
|
|
1207
581
|
FunctionInvocationService,
|
|
1208
|
-
FunctionNotFoundError,
|
|
1209
582
|
MESSAGE_PROPERTY_TOOL_CALL_ID,
|
|
1210
583
|
QueueService,
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
TriggerEvent_exports as TriggerEvent,
|
|
1216
|
-
TriggerStateNotFoundError,
|
|
1217
|
-
createDefectLogger,
|
|
1218
|
-
createEventLogger,
|
|
1219
|
-
defineFunction,
|
|
1220
|
-
deserializeFunction,
|
|
584
|
+
configuredCredentialsLayer,
|
|
585
|
+
credentialsLayerConfig,
|
|
586
|
+
credentialsLayerFromDatabase,
|
|
587
|
+
feedServiceFromQueueServiceLayer,
|
|
1221
588
|
getUserFunctionIdInMetadata,
|
|
1222
|
-
logCustomEvent,
|
|
1223
|
-
serializeFunction,
|
|
1224
589
|
setUserFunctionIdInMetadata,
|
|
1225
|
-
toOperation,
|
|
1226
590
|
withAuthorization,
|
|
1227
591
|
wrapFunctionHandler
|
|
1228
592
|
};
|