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

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 (204) hide show
  1. package/dist/lib/neutral/index.mjs +1229 -0
  2. package/dist/lib/neutral/index.mjs.map +7 -0
  3. package/dist/lib/neutral/meta.json +1 -0
  4. package/dist/types/src/errors.d.ts +44 -60
  5. package/dist/types/src/errors.d.ts.map +1 -1
  6. package/dist/types/src/{examples → example}/fib.d.ts +1 -1
  7. package/dist/types/src/example/fib.d.ts.map +1 -0
  8. package/dist/types/src/example/forex-effect.d.ts +3 -0
  9. package/dist/types/src/example/forex-effect.d.ts.map +1 -0
  10. package/dist/types/src/example/index.d.ts +12 -0
  11. package/dist/types/src/example/index.d.ts.map +1 -0
  12. package/dist/types/src/{examples → example}/reply.d.ts +1 -1
  13. package/dist/types/src/example/reply.d.ts.map +1 -0
  14. package/dist/types/src/{examples → example}/sleep.d.ts +1 -1
  15. package/dist/types/src/example/sleep.d.ts.map +1 -0
  16. package/dist/types/src/index.d.ts +4 -8
  17. package/dist/types/src/index.d.ts.map +1 -1
  18. package/dist/types/src/operation-compatibility.test.d.ts +2 -0
  19. package/dist/types/src/operation-compatibility.test.d.ts.map +1 -0
  20. package/dist/types/src/protocol/functions-ai-http-client.d.ts +12 -0
  21. package/dist/types/src/protocol/functions-ai-http-client.d.ts.map +1 -0
  22. package/dist/types/src/protocol/index.d.ts +2 -0
  23. package/dist/types/src/protocol/index.d.ts.map +1 -0
  24. package/dist/types/src/protocol/protocol.d.ts +7 -0
  25. package/dist/types/src/protocol/protocol.d.ts.map +1 -0
  26. package/dist/types/src/protocol/protocol.test.d.ts +2 -0
  27. package/dist/types/src/protocol/protocol.test.d.ts.map +1 -0
  28. package/dist/types/src/sdk.d.ts +114 -0
  29. package/dist/types/src/sdk.d.ts.map +1 -0
  30. package/dist/types/src/services/credentials.d.ts +6 -4
  31. package/dist/types/src/services/credentials.d.ts.map +1 -1
  32. package/dist/types/src/services/event-logger.d.ts +33 -27
  33. package/dist/types/src/services/event-logger.d.ts.map +1 -1
  34. package/dist/types/src/services/function-invocation-service.d.ts +7 -19
  35. package/dist/types/src/services/function-invocation-service.d.ts.map +1 -1
  36. package/dist/types/src/services/index.d.ts +2 -4
  37. package/dist/types/src/services/index.d.ts.map +1 -1
  38. package/dist/types/src/services/queues.d.ts +4 -4
  39. package/dist/types/src/services/queues.d.ts.map +1 -1
  40. package/dist/types/src/services/tracing.d.ts +41 -12
  41. package/dist/types/src/services/tracing.d.ts.map +1 -1
  42. package/dist/types/src/types/Function.d.ts +52 -0
  43. package/dist/types/src/types/Function.d.ts.map +1 -0
  44. package/dist/types/src/types/Script.d.ts +21 -0
  45. package/dist/types/src/types/Script.d.ts.map +1 -0
  46. package/dist/types/src/types/Trigger.d.ts +121 -0
  47. package/dist/types/src/types/Trigger.d.ts.map +1 -0
  48. package/dist/types/src/types/TriggerEvent.d.ts +74 -0
  49. package/dist/types/src/types/TriggerEvent.d.ts.map +1 -0
  50. package/dist/types/src/types/index.d.ts +6 -0
  51. package/dist/types/src/types/index.d.ts.map +1 -0
  52. package/dist/types/src/types/url.d.ts +13 -0
  53. package/dist/types/src/types/url.d.ts.map +1 -0
  54. package/dist/types/tsconfig.tsbuildinfo +1 -1
  55. package/package.json +24 -63
  56. package/src/errors.ts +4 -4
  57. package/src/{examples → example}/fib.ts +1 -1
  58. package/src/example/forex-effect.ts +40 -0
  59. package/src/example/index.ts +13 -0
  60. package/src/{examples → example}/reply.ts +1 -1
  61. package/src/{examples → example}/sleep.ts +1 -1
  62. package/src/index.ts +4 -8
  63. package/src/operation-compatibility.test.ts +185 -0
  64. package/src/protocol/functions-ai-http-client.ts +67 -0
  65. package/src/{executor → protocol}/index.ts +1 -1
  66. package/src/protocol/protocol.test.ts +59 -0
  67. package/src/protocol/protocol.ts +262 -0
  68. package/src/sdk.ts +289 -0
  69. package/src/services/credentials.ts +32 -17
  70. package/src/services/event-logger.ts +10 -4
  71. package/src/services/function-invocation-service.ts +23 -70
  72. package/src/services/index.ts +2 -4
  73. package/src/services/queues.ts +5 -7
  74. package/src/services/tracing.ts +68 -44
  75. package/src/types/Function.ts +82 -0
  76. package/src/types/Script.ts +34 -0
  77. package/src/types/Trigger.ts +143 -0
  78. package/src/types/TriggerEvent.ts +62 -0
  79. package/src/types/index.ts +9 -0
  80. package/src/types/url.ts +32 -0
  81. package/dist/lib/browser/bundler/index.mjs +0 -269
  82. package/dist/lib/browser/bundler/index.mjs.map +0 -7
  83. package/dist/lib/browser/chunk-J5LGTIGS.mjs +0 -10
  84. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +0 -7
  85. package/dist/lib/browser/chunk-LKYT2SAL.mjs +0 -665
  86. package/dist/lib/browser/chunk-LKYT2SAL.mjs.map +0 -7
  87. package/dist/lib/browser/edge/index.mjs +0 -83
  88. package/dist/lib/browser/edge/index.mjs.map +0 -7
  89. package/dist/lib/browser/index.mjs +0 -1395
  90. package/dist/lib/browser/index.mjs.map +0 -7
  91. package/dist/lib/browser/meta.json +0 -1
  92. package/dist/lib/browser/testing/index.mjs +0 -131
  93. package/dist/lib/browser/testing/index.mjs.map +0 -7
  94. package/dist/lib/node-esm/bundler/index.mjs +0 -270
  95. package/dist/lib/node-esm/bundler/index.mjs.map +0 -7
  96. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  97. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +0 -7
  98. package/dist/lib/node-esm/chunk-NAQIKLZB.mjs +0 -667
  99. package/dist/lib/node-esm/chunk-NAQIKLZB.mjs.map +0 -7
  100. package/dist/lib/node-esm/edge/index.mjs +0 -84
  101. package/dist/lib/node-esm/edge/index.mjs.map +0 -7
  102. package/dist/lib/node-esm/index.mjs +0 -1396
  103. package/dist/lib/node-esm/index.mjs.map +0 -7
  104. package/dist/lib/node-esm/meta.json +0 -1
  105. package/dist/lib/node-esm/testing/index.mjs +0 -132
  106. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  107. package/dist/types/src/bundler/bundler.d.ts +0 -49
  108. package/dist/types/src/bundler/bundler.d.ts.map +0 -1
  109. package/dist/types/src/bundler/bundler.test.d.ts +0 -2
  110. package/dist/types/src/bundler/bundler.test.d.ts.map +0 -1
  111. package/dist/types/src/bundler/index.d.ts +0 -2
  112. package/dist/types/src/bundler/index.d.ts.map +0 -1
  113. package/dist/types/src/edge/functions.d.ts +0 -17
  114. package/dist/types/src/edge/functions.d.ts.map +0 -1
  115. package/dist/types/src/edge/index.d.ts +0 -2
  116. package/dist/types/src/edge/index.d.ts.map +0 -1
  117. package/dist/types/src/examples/fib.d.ts.map +0 -1
  118. package/dist/types/src/examples/index.d.ts +0 -4
  119. package/dist/types/src/examples/index.d.ts.map +0 -1
  120. package/dist/types/src/examples/reply.d.ts.map +0 -1
  121. package/dist/types/src/examples/sleep.d.ts.map +0 -1
  122. package/dist/types/src/executor/executor.d.ts +0 -14
  123. package/dist/types/src/executor/executor.d.ts.map +0 -1
  124. package/dist/types/src/executor/index.d.ts +0 -2
  125. package/dist/types/src/executor/index.d.ts.map +0 -1
  126. package/dist/types/src/handler.d.ts +0 -109
  127. package/dist/types/src/handler.d.ts.map +0 -1
  128. package/dist/types/src/schema.d.ts +0 -43
  129. package/dist/types/src/schema.d.ts.map +0 -1
  130. package/dist/types/src/services/database.d.ts +0 -67
  131. package/dist/types/src/services/database.d.ts.map +0 -1
  132. package/dist/types/src/services/function-invocation-service.test.d.ts +0 -2
  133. package/dist/types/src/services/function-invocation-service.test.d.ts.map +0 -1
  134. package/dist/types/src/services/local-function-execution.d.ts +0 -34
  135. package/dist/types/src/services/local-function-execution.d.ts.map +0 -1
  136. package/dist/types/src/services/remote-function-execution-service.d.ts +0 -22
  137. package/dist/types/src/services/remote-function-execution-service.d.ts.map +0 -1
  138. package/dist/types/src/services/service-container.d.ts +0 -57
  139. package/dist/types/src/services/service-container.d.ts.map +0 -1
  140. package/dist/types/src/services/service-registry.d.ts +0 -31
  141. package/dist/types/src/services/service-registry.d.ts.map +0 -1
  142. package/dist/types/src/services/service-registry.test.d.ts +0 -2
  143. package/dist/types/src/services/service-registry.test.d.ts.map +0 -1
  144. package/dist/types/src/testing/index.d.ts +0 -3
  145. package/dist/types/src/testing/index.d.ts.map +0 -1
  146. package/dist/types/src/testing/layer.d.ts +0 -18
  147. package/dist/types/src/testing/layer.d.ts.map +0 -1
  148. package/dist/types/src/testing/logger.d.ts +0 -5
  149. package/dist/types/src/testing/logger.d.ts.map +0 -1
  150. package/dist/types/src/testing/persist-database.test.d.ts +0 -2
  151. package/dist/types/src/testing/persist-database.test.d.ts.map +0 -1
  152. package/dist/types/src/testing/services.d.ts +0 -59
  153. package/dist/types/src/testing/services.d.ts.map +0 -1
  154. package/dist/types/src/trace.d.ts +0 -122
  155. package/dist/types/src/trace.d.ts.map +0 -1
  156. package/dist/types/src/translations.d.ts +0 -12
  157. package/dist/types/src/translations.d.ts.map +0 -1
  158. package/dist/types/src/triggers/index.d.ts +0 -4
  159. package/dist/types/src/triggers/index.d.ts.map +0 -1
  160. package/dist/types/src/triggers/input-builder.d.ts +0 -3
  161. package/dist/types/src/triggers/input-builder.d.ts.map +0 -1
  162. package/dist/types/src/triggers/invocation-tracer.d.ts +0 -37
  163. package/dist/types/src/triggers/invocation-tracer.d.ts.map +0 -1
  164. package/dist/types/src/triggers/trigger-dispatcher.d.ts +0 -78
  165. package/dist/types/src/triggers/trigger-dispatcher.d.ts.map +0 -1
  166. package/dist/types/src/triggers/trigger-dispatcher.test.d.ts +0 -2
  167. package/dist/types/src/triggers/trigger-dispatcher.test.d.ts.map +0 -1
  168. package/dist/types/src/triggers/trigger-state-store.d.ts +0 -28
  169. package/dist/types/src/triggers/trigger-state-store.d.ts.map +0 -1
  170. package/dist/types/src/types.d.ts +0 -230
  171. package/dist/types/src/types.d.ts.map +0 -1
  172. package/dist/types/src/url.d.ts +0 -21
  173. package/dist/types/src/url.d.ts.map +0 -1
  174. package/src/bundler/bundler.test.ts +0 -58
  175. package/src/bundler/bundler.ts +0 -295
  176. package/src/bundler/index.ts +0 -5
  177. package/src/edge/functions.ts +0 -67
  178. package/src/edge/index.ts +0 -9
  179. package/src/examples/index.ts +0 -7
  180. package/src/executor/executor.ts +0 -58
  181. package/src/handler.ts +0 -225
  182. package/src/schema.ts +0 -71
  183. package/src/services/database.ts +0 -175
  184. package/src/services/function-invocation-service.test.ts +0 -81
  185. package/src/services/local-function-execution.ts +0 -153
  186. package/src/services/remote-function-execution-service.ts +0 -63
  187. package/src/services/service-container.ts +0 -115
  188. package/src/services/service-registry.test.ts +0 -45
  189. package/src/services/service-registry.ts +0 -63
  190. package/src/testing/index.ts +0 -6
  191. package/src/testing/layer.ts +0 -114
  192. package/src/testing/logger.ts +0 -17
  193. package/src/testing/persist-database.test.ts +0 -87
  194. package/src/testing/services.ts +0 -115
  195. package/src/trace.ts +0 -178
  196. package/src/translations.ts +0 -20
  197. package/src/triggers/index.ts +0 -7
  198. package/src/triggers/input-builder.ts +0 -35
  199. package/src/triggers/invocation-tracer.ts +0 -101
  200. package/src/triggers/trigger-dispatcher.test.ts +0 -665
  201. package/src/triggers/trigger-dispatcher.ts +0 -533
  202. package/src/triggers/trigger-state-store.ts +0 -61
  203. package/src/types.ts +0 -218
  204. package/src/url.ts +0 -55
@@ -5,80 +5,33 @@ import * as Context from 'effect/Context';
5
5
  import * as Effect from 'effect/Effect';
6
6
  import * as Layer from 'effect/Layer';
7
7
 
8
- import { AiService } from '@dxos/ai';
9
-
10
- import { type FunctionDefinition } from '../handler';
11
-
12
- import { CredentialsService } from './credentials';
13
- import { DatabaseService } from './database';
14
- import {
15
- FunctionImplementationResolver,
16
- type InvocationServices,
17
- LocalFunctionExecutionService,
18
- } from './local-function-execution';
19
- import { QueueService } from './queues';
20
- import { RemoteFunctionExecutionService } from './remote-function-execution-service';
8
+ import type { FunctionNotFoundError } from '../errors';
9
+ import { type FunctionDefinition, type InvocationServices } from '../sdk';
21
10
 
22
11
  export class FunctionInvocationService extends Context.Tag('@dxos/functions/FunctionInvocationService')<
23
12
  FunctionInvocationService,
24
13
  {
25
- invokeFunction<I, O>(functionDef: FunctionDefinition<I, O>, input: I): Effect.Effect<O, never, InvocationServices>;
14
+ invokeFunction<I, O>(
15
+ functionDef: FunctionDefinition<I, O, any>,
16
+ input: I,
17
+ ): Effect.Effect<O, never, InvocationServices>;
18
+
19
+ resolveFunction(key: string): Effect.Effect<FunctionDefinition.Any, FunctionNotFoundError>;
26
20
  }
27
21
  >() {
28
- static invokeFunction = Effect.serviceFunctionEffect(FunctionInvocationService, (_) => _.invokeFunction);
29
-
30
- static layer = Layer.effect(
31
- FunctionInvocationService,
32
- Effect.gen(function* () {
33
- const localExecutioner = yield* LocalFunctionExecutionService;
34
- const remoteExecutioner = yield* RemoteFunctionExecutionService;
35
-
36
- return {
37
- invokeFunction: <I, O>(
38
- functionDef: FunctionDefinition<I, O>,
39
- input: I,
40
- ): Effect.Effect<O, never, InvocationServices> =>
41
- Effect.gen(function* () {
42
- if (functionDef.meta?.deployedFunctionId) {
43
- return yield* remoteExecutioner.callFunction<I, O>(functionDef.meta.deployedFunctionId, input);
44
- }
45
-
46
- return yield* localExecutioner.invokeFunction(functionDef, input);
47
- }),
48
- } satisfies Context.Tag.Service<FunctionInvocationService>;
49
- }),
50
- );
51
-
52
- // TODO(dmaretskyi): Don't provide `FunctionImplementationResolver`.
53
- static layerTest = ({
54
- functions = [],
55
- }: {
56
- functions?: FunctionDefinition<any, any>[];
57
- } = {}): Layer.Layer<
58
- FunctionInvocationService,
59
- never,
60
- AiService.AiService | CredentialsService | DatabaseService | QueueService
61
- > =>
62
- FunctionInvocationService.layer.pipe(
63
- Layer.provide(LocalFunctionExecutionService.layerLive),
64
- Layer.provide(FunctionImplementationResolver.layerTest({ functions })),
65
- Layer.provide(RemoteFunctionExecutionService.layerMock),
66
- );
67
-
68
- // TODO(dmaretskyi): This shouldn't default to all services being not available.
69
- // TODO(dmaretskyi): Don't provide `FunctionImplementationResolver`.
70
- /**
71
- * @deprecated Use {@link layerTest} instead.
72
- */
73
- static layerTestMocked = ({
74
- functions,
75
- }: {
76
- functions: FunctionDefinition<any, any>[];
77
- }): Layer.Layer<FunctionInvocationService> =>
78
- FunctionInvocationService.layerTest({ functions }).pipe(
79
- Layer.provide(AiService.notAvailable),
80
- Layer.provide(CredentialsService.configuredLayer([])),
81
- Layer.provide(DatabaseService.notAvailable),
82
- Layer.provide(QueueService.notAvailable),
83
- );
22
+ static layerNotAvailable = Layer.succeed(FunctionInvocationService, {
23
+ invokeFunction: () => Effect.die('FunctionInvocationService is not avaialble.'),
24
+ resolveFunction: () => Effect.die('FunctionInvocationService is not available.'),
25
+ });
26
+
27
+ static invokeFunction = <I, O>(
28
+ functionDef: FunctionDefinition<I, O, any>,
29
+ input: I,
30
+ ): Effect.Effect<O, never, FunctionInvocationService | InvocationServices> =>
31
+ Effect.serviceFunctionEffect(FunctionInvocationService, (service) => service.invokeFunction)(functionDef, input);
32
+
33
+ static resolveFunction = (
34
+ key: string,
35
+ ): Effect.Effect<FunctionDefinition.Any, FunctionNotFoundError, FunctionInvocationService> =>
36
+ Effect.serviceFunctionEffect(FunctionInvocationService, (service) => service.resolveFunction)(key);
84
37
  }
@@ -3,11 +3,9 @@
3
3
  //
4
4
 
5
5
  export * from './credentials';
6
- export * from './database';
6
+ export { ConfiguredCredentialsService, type ServiceCredential } from './credentials';
7
7
  export * from './event-logger';
8
+ export { createEventLogger, createDefectLogger } from './event-logger';
8
9
  export * from './function-invocation-service';
9
- export * from './local-function-execution';
10
10
  export * from './queues';
11
- export * from './service-container';
12
11
  export * from './tracing';
13
- export * from './remote-function-execution-service';
@@ -6,7 +6,7 @@ import * as Context from 'effect/Context';
6
6
  import * as Effect from 'effect/Effect';
7
7
  import * as Layer from 'effect/Layer';
8
8
 
9
- import type { Obj, Relation } from '@dxos/echo';
9
+ import type { Entity } from '@dxos/echo';
10
10
  import type { Queue, QueueAPI, QueueFactory } from '@dxos/echo-db';
11
11
  import type { DXN, QueueSubspaceTag } from '@dxos/keys';
12
12
 
@@ -53,22 +53,20 @@ export class QueueService extends Context.Tag('@dxos/functions/QueueService')<
53
53
  /**
54
54
  * Gets a queue by its DXN.
55
55
  */
56
- static getQueue = <T extends Obj.Any | Relation.Any = Obj.Any | Relation.Any>(
56
+ static getQueue = <T extends Entity.Unknown = Entity.Unknown>(
57
57
  dxn: DXN,
58
58
  ): Effect.Effect<Queue<T>, never, QueueService> => QueueService.pipe(Effect.map(({ queues }) => queues.get<T>(dxn)));
59
59
 
60
60
  /**
61
61
  * Creates a new queue.
62
62
  */
63
- static createQueue = <T extends Obj.Any | Relation.Any = Obj.Any | Relation.Any>(options?: {
63
+ static createQueue = <T extends Entity.Unknown = Entity.Unknown>(options?: {
64
64
  subspaceTag?: QueueSubspaceTag;
65
65
  }): Effect.Effect<Queue<T>, never, QueueService> =>
66
66
  QueueService.pipe(Effect.map(({ queues }) => queues.create<T>(options)));
67
67
 
68
- static append = <T extends Obj.Any | Relation.Any = Obj.Any | Relation.Any>(
69
- queue: Queue<T>,
70
- objects: T[],
71
- ): Effect.Effect<void> => Effect.promise(() => queue.append(objects));
68
+ static append = <T extends Entity.Unknown = Entity.Unknown>(queue: Queue<T>, objects: T[]): Effect.Effect<void> =>
69
+ Effect.promise(() => queue.append(objects));
72
70
  }
73
71
 
74
72
  /**
@@ -7,11 +7,11 @@ import * as Effect from 'effect/Effect';
7
7
  import * as Layer from 'effect/Layer';
8
8
 
9
9
  import { AgentStatus } from '@dxos/ai';
10
- import { Obj } from '@dxos/echo';
11
- import type { ObjectId } from '@dxos/echo/internal';
12
- import type { Queue } from '@dxos/echo-db';
13
- import { log } from '@dxos/log';
14
- import { DataType } from '@dxos/schema';
10
+ import { type DXN, Obj } from '@dxos/echo';
11
+ import { ObjectId } from '@dxos/keys';
12
+ import { Message } from '@dxos/types';
13
+
14
+ import type { Trigger } from '../types';
15
15
 
16
16
  /**
17
17
  * Provides a way for compute primitives (functions, workflows, tools)
@@ -29,31 +29,34 @@ export class TracingService extends Context.Tag('@dxos/functions/TracingService'
29
29
  * Write an event to the tracing queue.
30
30
  * @param event - The event to write. Must be an a typed object.
31
31
  */
32
- write: (event: Obj.Any) => void;
32
+ write: (event: Obj.Unknown, traceContext: TracingService.TraceContext) => void;
33
+
34
+ traceInvocationStart({
35
+ payload,
36
+ target,
37
+ }: {
38
+ payload: TracingService.FunctionInvocationPayload;
39
+ target?: DXN;
40
+ }): Effect.Effect<TracingService.InvocationTraceData>;
41
+
42
+ traceInvocationEnd({
43
+ trace,
44
+ exception,
45
+ }: {
46
+ trace: TracingService.InvocationTraceData;
47
+ exception?: any;
48
+ }): Effect.Effect<void>;
33
49
  }
34
50
  >() {
35
- static noop: Context.Tag.Service<TracingService> = { write: () => {}, getTraceContext: () => ({}) };
36
-
37
- static layerNoop = Layer.succeed(TracingService, TracingService.noop);
38
-
39
- static console: Context.Tag.Service<TracingService> = {
40
- write: (event) => {
41
- console.log(event);
42
- },
51
+ static noop: Context.Tag.Service<TracingService> = {
43
52
  getTraceContext: () => ({}),
53
+ write: () => {},
54
+ traceInvocationStart: () =>
55
+ Effect.sync(() => ({ invocationId: ObjectId.random(), invocationTraceQueue: undefined })),
56
+ traceInvocationEnd: () => Effect.sync(() => {}),
44
57
  };
45
58
 
46
- static layerConsole = Layer.succeed(TracingService, TracingService.console);
47
-
48
- static layerLogInfo = () =>
49
- Layer.succeed(TracingService, {
50
- write: (event) => {
51
- if (Obj.instanceOf(AgentStatus, event)) {
52
- log.info('status', { message: event.message });
53
- }
54
- },
55
- getTraceContext: () => ({}),
56
- });
59
+ static layerNoop: Layer.Layer<TracingService> = Layer.succeed(TracingService, TracingService.noop);
57
60
 
58
61
  /**
59
62
  * Creates a TracingService layer that emits events to the parent tracing service.
@@ -65,27 +68,24 @@ export class TracingService extends Context.Tag('@dxos/functions/TracingService'
65
68
  const tracing = yield* TracingService;
66
69
  const context = mapContext(tracing.getTraceContext());
67
70
  return {
68
- write: (event) => tracing.write(event),
71
+ write: (event, context) => tracing.write(event, context),
69
72
  getTraceContext: () => context,
73
+ traceInvocationStart: () => Effect.die('Tracing invocation inside another invocation is not supported.'),
74
+ traceInvocationEnd: () => Effect.die('Tracing invocation inside another invocation is not supported.'),
70
75
  };
71
76
  }),
72
77
  );
73
78
 
74
- static layerQueue = (queue: Queue) =>
75
- Layer.effect(
76
- TracingService,
77
- Effect.gen(function* () {
78
- // TODO(dmaretskyi): Batching.
79
- return {
80
- write: (event) => queue.append([event]),
81
- getTraceContext: () => ({
82
- debugInfo: {
83
- queue: queue.dxn.toString(),
84
- },
85
- }),
86
- };
87
- }),
88
- );
79
+ /**
80
+ * Create sublayer to trace an invocation.
81
+ * @param data
82
+ * @returns
83
+ */
84
+ static layerInvocation = (data: TracingService.InvocationTraceData) =>
85
+ TracingService.layerSubframe((context) => ({
86
+ ...context,
87
+ currentInvocation: data,
88
+ }));
89
89
 
90
90
  /**
91
91
  * Emit the current human-readable execution status.
@@ -101,15 +101,16 @@ export class TracingService extends Context.Tag('@dxos/functions/TracingService'
101
101
  created: new Date().toISOString(),
102
102
  ...data,
103
103
  }),
104
+ tracing.getTraceContext(),
104
105
  );
105
106
  });
106
107
 
107
108
  static emitConverationMessage: (
108
- data: Obj.MakeProps<typeof DataType.Message>,
109
+ data: Obj.MakeProps<typeof Message.Message>,
109
110
  ) => Effect.Effect<void, never, TracingService> = Effect.fnUntraced(function* (data) {
110
111
  const tracing = yield* TracingService;
111
112
  tracing.write(
112
- Obj.make(DataType.Message, {
113
+ Obj.make(Message.Message, {
113
114
  parentMessage: tracing.getTraceContext().parentMessage,
114
115
  ...data,
115
116
  properties: {
@@ -117,12 +118,15 @@ export class TracingService extends Context.Tag('@dxos/functions/TracingService'
117
118
  ...data.properties,
118
119
  },
119
120
  }),
121
+ tracing.getTraceContext(),
120
122
  );
121
123
  });
122
124
  }
123
125
 
124
126
  export namespace TracingService {
125
127
  export interface TraceContext {
128
+ currentInvocation?: InvocationTraceData;
129
+
126
130
  /**
127
131
  * If this thread sprung from a tool call, this is the ID of the message containing the tool call.
128
132
  */
@@ -135,9 +139,29 @@ export namespace TracingService {
135
139
 
136
140
  debugInfo?: unknown;
137
141
  }
142
+
143
+ /**
144
+ * Trace data for a function/trigger invocation.
145
+ */
146
+ export interface InvocationTraceData {
147
+ invocationId: ObjectId;
148
+ invocationTraceQueue?: DXN.String;
149
+ }
150
+
151
+ /**
152
+ * Payload for a function/trigger invocation.
153
+ */
154
+ export interface FunctionInvocationPayload {
155
+ data?: any;
156
+ inputNodeId?: string;
157
+ trigger?: {
158
+ id: string;
159
+ kind: Trigger.Kind;
160
+ };
161
+ }
138
162
  }
139
163
 
140
164
  /**
141
- * Goes into {@link DataType.Message['properties']}
165
+ * Goes into {@link Message['properties']}
142
166
  */
143
167
  export const MESSAGE_PROPERTY_TOOL_CALL_ID = 'toolCallId' as const;
@@ -0,0 +1,82 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+
7
+ import { Annotation, JsonSchema, Obj, Type } from '@dxos/echo';
8
+ import { SystemTypeAnnotation } from '@dxos/echo/internal';
9
+
10
+ import { Script } from './Script';
11
+
12
+ /**
13
+ * Function deployment.
14
+ */
15
+ export const Function = Schema.Struct({
16
+ /**
17
+ * Global registry ID.
18
+ * NOTE: The `key` property refers to the original registry entry.
19
+ */
20
+ // TODO(burdon): Create Format type for DXN-like ids, such as this and schema type.
21
+ // TODO(dmaretskyi): Consider making it part of ECHO meta.
22
+ // TODO(dmaretskyi): Make required.
23
+ key: Schema.optional(Schema.String).annotations({
24
+ description: 'Unique registration key for the blueprint',
25
+ }),
26
+
27
+ name: Schema.NonEmptyString,
28
+ version: Schema.String,
29
+
30
+ description: Schema.optional(Schema.String),
31
+
32
+ /**
33
+ * ISO date string of the last deployment.
34
+ */
35
+ updated: Schema.optional(Schema.String),
36
+
37
+ // Reference to a source script if it exists within ECHO.
38
+ // TODO(burdon): Don't ref ScriptType directly (core).
39
+ source: Schema.optional(Type.Ref(Script)),
40
+
41
+ inputSchema: Schema.optional(JsonSchema.JsonSchema),
42
+ outputSchema: Schema.optional(JsonSchema.JsonSchema),
43
+
44
+ /**
45
+ * List of required services.
46
+ * Match the Context.Tag keys of the FunctionServices variants.
47
+ */
48
+ services: Schema.optional(Schema.Array(Schema.String)),
49
+
50
+ // Local binding to a function name.
51
+ binding: Schema.optional(Schema.String),
52
+ }).pipe(
53
+ Type.object({
54
+ typename: 'dxos.org/type/Function',
55
+ version: '0.1.0',
56
+ }),
57
+ Annotation.LabelAnnotation.set(['name']),
58
+ SystemTypeAnnotation.set(true),
59
+ );
60
+
61
+ export interface Function extends Schema.Schema.Type<typeof Function> {}
62
+
63
+ export const make = (props: Obj.MakeProps<typeof Function>) => Obj.make(Function, props);
64
+
65
+ /**
66
+ * Copies properties from source to target.
67
+ * @param target - Target object to copy properties to.
68
+ * @param source - Source object to copy properties from.
69
+ */
70
+ export const setFrom = (target: Function, source: Function) => {
71
+ Obj.change(target, (t) => {
72
+ t.key = source.key ?? target.key;
73
+ t.name = source.name ?? target.name;
74
+ t.version = source.version;
75
+ t.description = source.description;
76
+ t.updated = source.updated;
77
+ // TODO(dmaretskyi): A workaround for an ECHO bug.
78
+ t.inputSchema = source.inputSchema ? JSON.parse(JSON.stringify(source.inputSchema)) : undefined;
79
+ t.outputSchema = source.outputSchema ? JSON.parse(JSON.stringify(source.outputSchema)) : undefined;
80
+ Obj.getMeta(t).keys = JSON.parse(JSON.stringify(Obj.getMeta(source).keys));
81
+ });
82
+ };
@@ -0,0 +1,34 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+
7
+ import { Annotation, Obj, Ref, Type } from '@dxos/echo';
8
+ import { FormInputAnnotation } from '@dxos/echo/internal';
9
+ import { Text } from '@dxos/schema';
10
+
11
+ /**
12
+ * Source script.
13
+ */
14
+ export const Script = Schema.Struct({
15
+ name: Schema.String.pipe(Schema.optional),
16
+ description: Schema.String.pipe(Schema.optional),
17
+ // TODO(burdon): Change to hash of deployed content.
18
+ // Whether source has changed since last deploy.
19
+ changed: Schema.Boolean.pipe(FormInputAnnotation.set(false), Schema.optional),
20
+ source: Type.Ref(Text.Text).pipe(FormInputAnnotation.set(false)),
21
+ }).pipe(
22
+ Type.object({
23
+ typename: 'dxos.org/type/Script',
24
+ version: '0.1.0',
25
+ }),
26
+ Annotation.LabelAnnotation.set(['name']),
27
+ );
28
+
29
+ export interface Script extends Schema.Schema.Type<typeof Script> {}
30
+
31
+ type Props = Omit<Obj.MakeProps<typeof Script>, 'source'> & { source?: string };
32
+
33
+ export const make = ({ source = '', ...props }: Props = {}): Script =>
34
+ Obj.make(Script, { ...props, source: Ref.make(Text.make(source)) });
@@ -0,0 +1,143 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+ import * as SchemaAST from 'effect/SchemaAST';
7
+
8
+ import { Obj, QueryAST, Type } from '@dxos/echo';
9
+ import { OptionsAnnotationId, SystemTypeAnnotation } from '@dxos/echo/internal';
10
+ import { DXN } from '@dxos/keys';
11
+ import { Expando } from '@dxos/schema';
12
+
13
+ /**
14
+ * Type discriminator for TriggerType.
15
+ * Every spec has a type field of type TriggerKind that we can use to understand which type we're working with.
16
+ * https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions
17
+ */
18
+ export const Kinds = ['email', 'queue', 'subscription', 'timer', 'webhook'] as const;
19
+ export type Kind = (typeof Kinds)[number];
20
+
21
+ const kindLiteralAnnotations = { title: 'Kind' };
22
+
23
+ export const EmailSpec = Schema.Struct({
24
+ kind: Schema.Literal('email').annotations(kindLiteralAnnotations),
25
+ });
26
+ export type EmailSpec = Schema.Schema.Type<typeof EmailSpec>;
27
+
28
+ export const QueueSpec = Schema.Struct({
29
+ kind: Schema.Literal('queue').annotations(kindLiteralAnnotations),
30
+
31
+ // TODO(dmaretskyi): Change to a reference.
32
+ queue: DXN.Schema,
33
+ });
34
+ export type QueueSpec = Schema.Schema.Type<typeof QueueSpec>;
35
+
36
+ /**
37
+ * Subscription.
38
+ */
39
+ export const SubscriptionSpec = Schema.Struct({
40
+ kind: Schema.Literal('subscription').annotations(kindLiteralAnnotations),
41
+ query: Schema.Struct({
42
+ raw: Schema.optional(Schema.String.annotations({ title: 'Query' })),
43
+ ast: QueryAST.Query,
44
+ }),
45
+ options: Schema.optional(
46
+ Schema.Struct({
47
+ // Watch changes to object (not just creation).
48
+ deep: Schema.optional(Schema.Boolean.annotations({ title: 'Nested' })),
49
+ // Debounce changes (delay in ms).
50
+ delay: Schema.optional(Schema.Number.annotations({ title: 'Delay' })),
51
+ }).annotations({ title: 'Options' }),
52
+ ),
53
+ });
54
+ export type SubscriptionSpec = Schema.Schema.Type<typeof SubscriptionSpec>;
55
+
56
+ /**
57
+ * Cron timer.
58
+ */
59
+ export const TimerSpec = Schema.Struct({
60
+ kind: Schema.Literal('timer').annotations(kindLiteralAnnotations),
61
+ cron: Schema.String.annotations({
62
+ title: 'Cron',
63
+ [SchemaAST.ExamplesAnnotationId]: ['0 0 * * *'],
64
+ }),
65
+ });
66
+ export type TimerSpec = Schema.Schema.Type<typeof TimerSpec>;
67
+
68
+ /**
69
+ * Webhook.
70
+ */
71
+ export const WebhookSpec = Schema.Struct({
72
+ kind: Schema.Literal('webhook').annotations(kindLiteralAnnotations),
73
+ method: Schema.optional(
74
+ Schema.String.annotations({
75
+ title: 'Method',
76
+ [OptionsAnnotationId]: ['GET', 'POST'],
77
+ }),
78
+ ),
79
+ port: Schema.optional(
80
+ Schema.Number.annotations({
81
+ title: 'Port',
82
+ }),
83
+ ),
84
+ });
85
+ export type WebhookSpec = Schema.Schema.Type<typeof WebhookSpec>;
86
+
87
+ /**
88
+ * Trigger schema.
89
+ */
90
+ export const Spec = Schema.Union(EmailSpec, QueueSpec, SubscriptionSpec, TimerSpec, WebhookSpec).annotations({
91
+ title: 'Trigger',
92
+ });
93
+ export type Spec = Schema.Schema.Type<typeof Spec>;
94
+
95
+ /**
96
+ * Function trigger.
97
+ * Function is invoked with the `payload` passed as input data.
98
+ * The event that triggers the function is available in the function context.
99
+ */
100
+ const TriggerSchema = Schema.Struct({
101
+ /**
102
+ * Function or workflow to invoke.
103
+ */
104
+ // TODO(dmaretskyi): Can be a Ref(FunctionType) or Ref(ComputeGraphType).
105
+ function: Schema.optional(Type.Ref(Expando.Expando).annotations({ title: 'Function' })),
106
+
107
+ /**
108
+ * Only used for workflowSchema.
109
+ * Specifies the input node in the circuit.
110
+ * @deprecated Remove and enforce a single input node in all compute graphSchema.
111
+ */
112
+ inputNodeId: Schema.optional(Schema.String.annotations({ title: 'Input Node ID' })),
113
+
114
+ // TODO(burdon): NO BOOLEAN PROPERTIES (enabld/disabled/paused, etc.)
115
+ // Need lint rule; or agent rule to require PR review for "boolean" key word.
116
+ enabled: Schema.optional(Schema.Boolean.annotations({ title: 'Enabled' })),
117
+
118
+ spec: Schema.optional(Spec),
119
+
120
+ /**
121
+ * Passed as the input data to the function.
122
+ * Must match the function's input schema.
123
+ *
124
+ * @example
125
+ * {
126
+ * item: '{{$.trigger.event}}',
127
+ * instructions: 'Summarize and perform entity-extraction'
128
+ * mailbox: { '/': 'dxn:echo:AAA:ZZZ' }
129
+ * }
130
+ */
131
+ input: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.Any })),
132
+ }).pipe(
133
+ Type.object({
134
+ typename: 'dxos.org/type/Trigger',
135
+ version: '0.1.0',
136
+ }),
137
+ SystemTypeAnnotation.set(true),
138
+ );
139
+
140
+ export interface Trigger extends Schema.Schema.Type<typeof TriggerSchema> {}
141
+ export const Trigger: Type.Obj<Trigger> = TriggerSchema as any;
142
+
143
+ export const make = (props: Obj.MakeProps<typeof Trigger>) => Obj.make(Trigger, props);
@@ -0,0 +1,62 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+
7
+ import { DXN, Type } from '@dxos/echo';
8
+
9
+ // TODO(wittjosiah): Review this type.
10
+ // - Should be discriminated union.
11
+ // - Should be more consistent (e.g. subject vs item).
12
+ // - Should re-use schemas if possible.
13
+
14
+ // TODO(burdon): Reuse trigger schema from @dxos/functions (TriggerType).
15
+ export const EmailEvent = Schema.Struct({
16
+ from: Schema.String,
17
+ to: Schema.String,
18
+ subject: Schema.String,
19
+ created: Schema.String,
20
+ body: Schema.String,
21
+ });
22
+ export type EmailEvent = Schema.Schema.Type<typeof EmailEvent>;
23
+
24
+ export const QueueEvent = Schema.Struct({
25
+ queue: DXN.Schema,
26
+ item: Schema.Any,
27
+ cursor: Schema.String,
28
+ });
29
+ export type QueueEvent = Schema.Schema.Type<typeof QueueEvent>;
30
+
31
+ export const SubscriptionEvent = Schema.Struct({
32
+ /**
33
+ * Type of the mutation.
34
+ */
35
+ // TODO(dmaretskyi): Specify enum.
36
+ type: Schema.String,
37
+
38
+ /**
39
+ * Reference to the object that was changed or created.
40
+ */
41
+ subject: Type.Ref(Type.Obj),
42
+
43
+ /**
44
+ * @deprecated
45
+ */
46
+ changedObjectId: Schema.optional(Schema.String),
47
+ });
48
+ export type SubscriptionEvent = Schema.Schema.Type<typeof SubscriptionEvent>;
49
+
50
+ export const TimerEvent = Schema.Struct({ tick: Schema.Number });
51
+ export type TimerEvent = Schema.Schema.Type<typeof TimerEvent>;
52
+
53
+ export const WebhookEvent = Schema.Struct({
54
+ url: Schema.String,
55
+ method: Schema.Literal('GET', 'POST'),
56
+ headers: Schema.Record({ key: Schema.String, value: Schema.String }),
57
+ bodyText: Schema.String,
58
+ });
59
+ export type WebhookEvent = Schema.Schema.Type<typeof WebhookEvent>;
60
+
61
+ export const TriggerEvent = Schema.Union(EmailEvent, QueueEvent, SubscriptionEvent, TimerEvent, WebhookEvent);
62
+ export type TriggerEvent = Schema.Schema.Type<typeof TriggerEvent>;
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * as Function from './Function';
6
+ export * as Script from './Script';
7
+ export * as Trigger from './Trigger';
8
+ export * as TriggerEvent from './TriggerEvent';
9
+ export * from './url';