@dxos/assistant-toolkit 0.8.4-main.ae835ea → 0.8.4-main.bc674ce

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/browser/chunk-J5LGTIGS.mjs +10 -0
  2. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +1091 -692
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +43 -0
  7. package/dist/lib/browser/testing/index.mjs.map +7 -0
  8. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  9. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +1090 -692
  11. package/dist/lib/node-esm/index.mjs.map +4 -4
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing/index.mjs +44 -0
  14. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  15. package/dist/types/src/blueprints/design/design-blueprint.d.ts +17 -3
  16. package/dist/types/src/blueprints/design/design-blueprint.d.ts.map +1 -1
  17. package/dist/types/src/blueprints/design/index.d.ts +1 -1
  18. package/dist/types/src/blueprints/design/index.d.ts.map +1 -1
  19. package/dist/types/src/blueprints/discord/discord-blueprint.d.ts +13 -13
  20. package/dist/types/src/blueprints/discord/discord-blueprint.d.ts.map +1 -1
  21. package/dist/types/src/blueprints/discord/index.d.ts +1 -1
  22. package/dist/types/src/blueprints/discord/index.d.ts.map +1 -1
  23. package/dist/types/src/blueprints/linear/index.d.ts +1 -1
  24. package/dist/types/src/blueprints/linear/index.d.ts.map +1 -1
  25. package/dist/types/src/blueprints/linear/linear-blueprint.d.ts +13 -13
  26. package/dist/types/src/blueprints/linear/linear-blueprint.d.ts.map +1 -1
  27. package/dist/types/src/blueprints/planning/index.d.ts +1 -1
  28. package/dist/types/src/blueprints/planning/index.d.ts.map +1 -1
  29. package/dist/types/src/blueprints/planning/planning-blueprint.d.ts +17 -3
  30. package/dist/types/src/blueprints/planning/planning-blueprint.d.ts.map +1 -1
  31. package/dist/types/src/blueprints/research/index.d.ts +1 -1
  32. package/dist/types/src/blueprints/research/index.d.ts.map +1 -1
  33. package/dist/types/src/blueprints/research/research-blueprint.d.ts +17 -3
  34. package/dist/types/src/blueprints/research/research-blueprint.d.ts.map +1 -1
  35. package/dist/types/src/blueprints/testing.d.ts +2 -2
  36. package/dist/types/src/blueprints/testing.d.ts.map +1 -1
  37. package/dist/types/src/blueprints/websearch/index.d.ts +1 -1
  38. package/dist/types/src/blueprints/websearch/index.d.ts.map +1 -1
  39. package/dist/types/src/blueprints/websearch/websearch-blueprint.d.ts +17 -3
  40. package/dist/types/src/blueprints/websearch/websearch-blueprint.d.ts.map +1 -1
  41. package/dist/types/src/blueprints/websearch/websearch-toolkit.d.ts +1 -0
  42. package/dist/types/src/blueprints/websearch/websearch-toolkit.d.ts.map +1 -1
  43. package/dist/types/src/{functions/research → crud}/graph.d.ts +14 -11
  44. package/dist/types/src/crud/graph.d.ts.map +1 -0
  45. package/dist/types/src/crud/graph.test.d.ts.map +1 -0
  46. package/dist/types/src/crud/index.d.ts +2 -0
  47. package/dist/types/src/crud/index.d.ts.map +1 -0
  48. package/dist/types/src/functions/agent/prompt.d.ts +73 -8
  49. package/dist/types/src/functions/agent/prompt.d.ts.map +1 -1
  50. package/dist/types/src/functions/discord/fetch-messages.d.ts +1 -1
  51. package/dist/types/src/functions/discord/index.d.ts +1 -1
  52. package/dist/types/src/functions/discord/index.d.ts.map +1 -1
  53. package/dist/types/src/functions/document/index.d.ts +3 -2
  54. package/dist/types/src/functions/document/index.d.ts.map +1 -1
  55. package/dist/types/src/functions/document/read.d.ts +1 -1
  56. package/dist/types/src/functions/document/read.d.ts.map +1 -1
  57. package/dist/types/src/functions/document/update.d.ts +1 -1
  58. package/dist/types/src/functions/document/update.d.ts.map +1 -1
  59. package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts +126 -125
  60. package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts.map +1 -1
  61. package/dist/types/src/functions/entity-extraction/index.d.ts +126 -125
  62. package/dist/types/src/functions/entity-extraction/index.d.ts.map +1 -1
  63. package/dist/types/src/functions/exa/data/exa-search-1748337321991.d.ts.map +1 -0
  64. package/dist/types/src/functions/exa/data/exa-search-1748337331526.d.ts.map +1 -0
  65. package/dist/types/src/functions/exa/data/exa-search-1748337344119.d.ts.map +1 -0
  66. package/dist/types/src/functions/exa/data/index.d.ts.map +1 -0
  67. package/dist/types/src/functions/exa/exa.d.ts +1 -1
  68. package/dist/types/src/functions/exa/mock.d.ts +1 -1
  69. package/dist/types/src/functions/github/fetch-prs.d.ts +1 -1
  70. package/dist/types/src/functions/github/fetch-prs.d.ts.map +1 -1
  71. package/dist/types/src/functions/linear/index.d.ts +2 -2
  72. package/dist/types/src/functions/linear/index.d.ts.map +1 -1
  73. package/dist/types/src/functions/linear/sync-issues.d.ts +2 -2
  74. package/dist/types/src/functions/linear/sync-issues.d.ts.map +1 -1
  75. package/dist/types/src/functions/research/document-create.d.ts +9 -0
  76. package/dist/types/src/functions/research/document-create.d.ts.map +1 -0
  77. package/dist/types/src/functions/research/index.d.ts +8 -6
  78. package/dist/types/src/functions/research/index.d.ts.map +1 -1
  79. package/dist/types/src/functions/research/research-graph.d.ts +9 -8
  80. package/dist/types/src/functions/research/research-graph.d.ts.map +1 -1
  81. package/dist/types/src/functions/research/research.d.ts +4 -3
  82. package/dist/types/src/functions/research/research.d.ts.map +1 -1
  83. package/dist/types/src/functions/research/types.d.ts +2 -380
  84. package/dist/types/src/functions/research/types.d.ts.map +1 -1
  85. package/dist/types/src/functions/tasks/index.d.ts +2 -2
  86. package/dist/types/src/functions/tasks/index.d.ts.map +1 -1
  87. package/dist/types/src/functions/tasks/read.d.ts +1 -1
  88. package/dist/types/src/functions/tasks/read.d.ts.map +1 -1
  89. package/dist/types/src/functions/tasks/update.d.ts +1 -1
  90. package/dist/types/src/functions/tasks/update.d.ts.map +1 -1
  91. package/dist/types/src/index.d.ts +2 -1
  92. package/dist/types/src/index.d.ts.map +1 -1
  93. package/dist/types/src/initiative/Initiative.d.ts +84 -0
  94. package/dist/types/src/initiative/Initiative.d.ts.map +1 -0
  95. package/dist/types/src/initiative/InitiativeSchema.d.ts +19 -0
  96. package/dist/types/src/initiative/InitiativeSchema.d.ts.map +1 -0
  97. package/dist/types/src/initiative/functions/agent.d.ts +37 -0
  98. package/dist/types/src/initiative/functions/agent.d.ts.map +1 -0
  99. package/dist/types/src/initiative/functions/getContext.d.ts +17 -0
  100. package/dist/types/src/initiative/functions/getContext.d.ts.map +1 -0
  101. package/dist/types/src/initiative/functions/index.d.ts +4 -0
  102. package/dist/types/src/initiative/functions/index.d.ts.map +1 -0
  103. package/dist/types/src/{functions/research/create-document.d.ts → initiative/functions/update.d.ts} +3 -3
  104. package/dist/types/src/initiative/functions/update.d.ts.map +1 -0
  105. package/dist/types/src/initiative/index.d.ts +1 -0
  106. package/dist/types/src/initiative/index.d.ts.map +1 -0
  107. package/dist/types/src/initiative/initiative.test.d.ts +2 -0
  108. package/dist/types/src/initiative/initiative.test.d.ts.map +1 -0
  109. package/dist/types/src/sync/sync.d.ts +3 -3
  110. package/dist/types/src/sync/sync.d.ts.map +1 -1
  111. package/dist/types/src/testing/index.d.ts +1 -1
  112. package/dist/types/src/testing/index.d.ts.map +1 -1
  113. package/dist/types/src/testing/plugins.d.ts +19 -0
  114. package/dist/types/src/testing/plugins.d.ts.map +1 -0
  115. package/dist/types/src/toolkits/AssistantToolkit.d.ts +43 -0
  116. package/dist/types/src/toolkits/AssistantToolkit.d.ts.map +1 -0
  117. package/dist/types/src/toolkits/AssistantToolkit.test.d.ts +2 -0
  118. package/dist/types/src/toolkits/AssistantToolkit.test.d.ts.map +1 -0
  119. package/dist/types/src/toolkits/SystemToolkit.d.ts +99 -0
  120. package/dist/types/src/toolkits/SystemToolkit.d.ts.map +1 -0
  121. package/dist/types/src/toolkits/index.d.ts +3 -0
  122. package/dist/types/src/toolkits/index.d.ts.map +1 -0
  123. package/dist/types/tsconfig.tsbuildinfo +1 -1
  124. package/package.json +49 -33
  125. package/src/blueprints/design/design-blueprint.test.ts +17 -20
  126. package/src/blueprints/design/design-blueprint.ts +4 -6
  127. package/src/blueprints/design/index.ts +1 -1
  128. package/src/blueprints/discord/discord-blueprint.ts +4 -6
  129. package/src/blueprints/discord/index.ts +1 -1
  130. package/src/blueprints/linear/index.ts +1 -1
  131. package/src/blueprints/linear/linear-blueprint.ts +4 -6
  132. package/src/blueprints/planning/index.ts +1 -1
  133. package/src/blueprints/planning/planning-blueprint.test.ts +17 -20
  134. package/src/blueprints/planning/planning-blueprint.ts +4 -6
  135. package/src/blueprints/research/index.ts +1 -1
  136. package/src/blueprints/research/research-blueprint.ts +25 -19
  137. package/src/blueprints/testing.ts +2 -2
  138. package/src/blueprints/websearch/index.ts +2 -1
  139. package/src/blueprints/websearch/websearch-blueprint.ts +4 -6
  140. package/src/crud/graph.test.ts +46 -0
  141. package/src/{functions/research → crud}/graph.ts +32 -40
  142. package/src/crud/index.ts +5 -0
  143. package/src/experimental/feed.test.ts +12 -9
  144. package/src/functions/agent/prompt.ts +39 -22
  145. package/src/functions/discord/fetch-messages.test.ts +6 -7
  146. package/src/functions/discord/fetch-messages.ts +11 -10
  147. package/src/functions/document/index.ts +1 -0
  148. package/src/functions/document/read.ts +4 -3
  149. package/src/functions/document/update.ts +7 -4
  150. package/src/functions/entity-extraction/entity-extraction.conversations.json +6597 -1
  151. package/src/functions/entity-extraction/entity-extraction.test.ts +16 -23
  152. package/src/functions/entity-extraction/entity-extraction.ts +51 -31
  153. package/src/functions/exa/mock.ts +1 -1
  154. package/src/functions/github/fetch-prs.ts +3 -2
  155. package/src/functions/linear/linear.test.ts +18 -20
  156. package/src/functions/linear/sync-issues.ts +14 -12
  157. package/src/functions/research/document-create.ts +76 -0
  158. package/src/functions/research/index.ts +1 -2
  159. package/src/functions/research/research-graph.ts +13 -11
  160. package/src/functions/research/{instructions-research.tpl → research-instructions.tpl} +14 -6
  161. package/src/functions/research/research.conversations.json +1 -10714
  162. package/src/functions/research/research.test.ts +92 -161
  163. package/src/functions/research/research.ts +88 -54
  164. package/src/functions/research/types.ts +14 -12
  165. package/src/functions/tasks/read.ts +4 -3
  166. package/src/functions/tasks/update.ts +4 -3
  167. package/src/index.ts +2 -1
  168. package/src/initiative/Initiative.ts +99 -0
  169. package/src/initiative/InitiativeSchema.ts +37 -0
  170. package/src/initiative/functions/agent.ts +57 -0
  171. package/src/initiative/functions/getContext.ts +74 -0
  172. package/src/initiative/functions/index.ts +7 -0
  173. package/src/initiative/functions/update.ts +63 -0
  174. package/src/initiative/index.ts +3 -0
  175. package/src/initiative/initiative.conversations.json +1 -0
  176. package/src/initiative/initiative.test.ts +485 -0
  177. package/src/sync/sync.ts +38 -30
  178. package/src/testing/index.ts +1 -1
  179. package/src/{plugins.tsx → testing/plugins.tsx} +15 -15
  180. package/src/toolkits/AssistantToolkit.conversations.json +1 -0
  181. package/src/toolkits/AssistantToolkit.test.ts +94 -0
  182. package/src/toolkits/AssistantToolkit.ts +70 -0
  183. package/src/toolkits/SystemToolkit.ts +299 -0
  184. package/src/toolkits/index.ts +6 -0
  185. package/dist/types/src/functions/research/create-document.d.ts.map +0 -1
  186. package/dist/types/src/functions/research/graph.d.ts.map +0 -1
  187. package/dist/types/src/functions/research/graph.test.d.ts.map +0 -1
  188. package/dist/types/src/plugins.d.ts +0 -19
  189. package/dist/types/src/plugins.d.ts.map +0 -1
  190. package/dist/types/src/testing/data/exa-search-1748337321991.d.ts.map +0 -1
  191. package/dist/types/src/testing/data/exa-search-1748337331526.d.ts.map +0 -1
  192. package/dist/types/src/testing/data/exa-search-1748337344119.d.ts.map +0 -1
  193. package/dist/types/src/testing/data/index.d.ts.map +0 -1
  194. package/src/functions/research/create-document.ts +0 -69
  195. package/src/functions/research/graph.test.ts +0 -69
  196. /package/dist/types/src/{functions/research → crud}/graph.test.d.ts +0 -0
  197. /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337321991.d.ts +0 -0
  198. /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337331526.d.ts +0 -0
  199. /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337344119.d.ts +0 -0
  200. /package/dist/types/src/{testing → functions/exa}/data/index.d.ts +0 -0
  201. /package/src/{testing → functions/exa}/data/exa-search-1748337321991.ts +0 -0
  202. /package/src/{testing → functions/exa}/data/exa-search-1748337331526.ts +0 -0
  203. /package/src/{testing → functions/exa}/data/exa-search-1748337344119.ts +0 -0
  204. /package/src/{testing → functions/exa}/data/index.ts +0 -0
@@ -11,28 +11,23 @@ import * as Option from 'effect/Option';
11
11
  import * as Schema from 'effect/Schema';
12
12
  import * as SchemaAST from 'effect/SchemaAST';
13
13
 
14
- import { Obj, type Relation } from '@dxos/echo';
15
- import { Filter, Query } from '@dxos/echo';
14
+ import { Entity, Filter, Obj, Query, Type } from '@dxos/echo';
15
+ import { Database } from '@dxos/echo';
16
16
  import {
17
- EntityKind,
18
- ObjectId,
19
17
  ReferenceAnnotationId,
20
18
  RelationSourceDXNId,
21
19
  RelationSourceId,
22
20
  RelationTargetDXNId,
23
21
  RelationTargetId,
24
- create,
25
- getEntityKind,
26
- getSchemaDXN,
27
- getSchemaTypename,
22
+ createObject,
28
23
  getTypeAnnotation,
29
24
  getTypeIdentifierAnnotation,
30
25
  } from '@dxos/echo/internal';
31
- import { type EchoDatabase, type Queue } from '@dxos/echo-db';
26
+ import { type Queue } from '@dxos/echo-db';
32
27
  import { isEncodedReference } from '@dxos/echo-protocol';
33
28
  import { mapAst } from '@dxos/effect';
34
- import { ContextQueueService, DatabaseService } from '@dxos/functions';
35
- import { DXN } from '@dxos/keys';
29
+ import { ContextQueueService } from '@dxos/functions';
30
+ import { DXN, ObjectId } from '@dxos/keys';
36
31
  import { log } from '@dxos/log';
37
32
  import { deepMapValues, isNonNullable, trim } from '@dxos/util';
38
33
 
@@ -45,7 +40,7 @@ export const Subgraph = Schema.Struct({
45
40
  export interface Subgraph extends Schema.Schema.Type<typeof Subgraph> {}
46
41
 
47
42
  export type RelatedSchema = {
48
- schema: Schema.Schema.AnyNoContext;
43
+ schema: Type.Entity.Any;
49
44
  kind: 'reference' | 'relation';
50
45
  };
51
46
 
@@ -56,17 +51,14 @@ export type RelatedSchema = {
56
51
  * @param schema
57
52
  * @returns
58
53
  */
59
- export const findRelatedSchema = async (
60
- db: EchoDatabase,
61
- anchor: Schema.Schema.AnyNoContext,
62
- ): Promise<RelatedSchema[]> => {
54
+ export const findRelatedSchema = async (db: Database.Database, anchor: Type.Entity.Any): Promise<RelatedSchema[]> => {
63
55
  // TODO(dmaretskyi): Query stored schemas.
64
- const allSchemas = [...db.graph.schemaRegistry.schemas];
56
+ const allSchemas = await db.graph.schemaRegistry.query().run();
65
57
 
66
58
  // TODO(dmaretskyi): Also do references.
67
59
  return allSchemas
68
60
  .filter((schema) => {
69
- if (getTypeAnnotation(schema)?.kind !== EntityKind.Relation) {
61
+ if (getTypeAnnotation(schema)?.kind !== Entity.Kind.Relation) {
70
62
  return false;
71
63
  }
72
64
 
@@ -77,8 +69,8 @@ export const findRelatedSchema = async (
77
69
  })
78
70
  .map(
79
71
  (schema): RelatedSchema => ({
80
- schema,
81
72
  kind: 'relation',
73
+ schema,
82
74
  }),
83
75
  );
84
76
  };
@@ -87,14 +79,14 @@ export const findRelatedSchema = async (
87
79
  * Non-strict DXN comparison.
88
80
  * Returns true if the DXN could be resolved to the schema.
89
81
  */
90
- const isSchemaAddressableByDxn = (schema: Schema.Schema.AnyNoContext, dxn: DXN): boolean => {
82
+ const isSchemaAddressableByDxn = (schema: Type.Entity.Any, dxn: DXN): boolean => {
91
83
  if (getTypeIdentifierAnnotation(schema) === dxn.toString()) {
92
84
  return true;
93
85
  }
94
86
 
95
87
  const t = dxn.asTypeDXN();
96
88
  if (t) {
97
- return t.type === getSchemaTypename(schema);
89
+ return t.type === Type.getTypename(schema);
98
90
  }
99
91
 
100
92
  return false;
@@ -114,13 +106,13 @@ export const LocalSearchToolkit = Toolkit.make(
114
106
  },
115
107
  success: Schema.Unknown,
116
108
  failure: Schema.Never,
117
- dependencies: [DatabaseService],
109
+ dependencies: [Database.Service],
118
110
  }),
119
111
  );
120
112
 
121
113
  export const LocalSearchHandler = LocalSearchToolkit.toLayer({
122
114
  search_local_search: Effect.fn(function* ({ query }) {
123
- const { objects } = yield* DatabaseService.runQuery(Query.select(Filter.text(query, { type: 'vector' })));
115
+ const objects = yield* Database.Service.runQuery(Query.select(Filter.text(query, { type: 'vector' })));
124
116
  const results = [...objects];
125
117
 
126
118
  const option = yield* Effect.serviceOption(ContextQueueService);
@@ -144,21 +136,21 @@ export const LocalSearchHandler = LocalSearchToolkit.toLayer({
144
136
  class GraphWriterSchema extends Context.Tag('@dxos/assistant/GraphWriterSchema')<
145
137
  GraphWriterSchema,
146
138
  {
147
- schema: Schema.Schema.AnyNoContext[];
139
+ schema: Type.Entity.Any[];
148
140
  }
149
141
  >() {}
150
142
 
151
143
  /**
152
144
  * Forms typed objects that can be written to the graph database.
153
145
  */
154
- export const makeGraphWriterToolkit = ({ schema }: { schema: Schema.Schema.AnyNoContext[] }) => {
146
+ export const makeGraphWriterToolkit = ({ schema }: { schema: Type.Entity.Any[] }) => {
155
147
  return Toolkit.make(
156
148
  Tool.make('graph_writer', {
157
149
  description: 'Write to the local graph database',
158
150
  parameters: createExtractionSchema(schema).fields,
159
151
  success: Schema.Unknown,
160
152
  failure: Schema.Never,
161
- dependencies: [DatabaseService, ContextQueueService],
153
+ dependencies: [Database.Service, ContextQueueService],
162
154
  }).annotateContext(Context.make(GraphWriterSchema, { schema })),
163
155
  );
164
156
  };
@@ -178,10 +170,10 @@ export const makeGraphWriterHandler = (
178
170
 
179
171
  return toolkit.toLayer({
180
172
  graph_writer: Effect.fn(function* (input) {
181
- const { db } = yield* DatabaseService;
173
+ const { db } = yield* Database.Service;
182
174
  const { queue } = yield* ContextQueueService;
183
175
  const data = yield* Effect.promise(() => sanitizeObjects(schema, input as any, db, queue));
184
- yield* Effect.promise(() => queue.append(data as Obj.Any[]));
176
+ yield* Effect.promise(() => queue.append(data as Obj.Unknown[]));
185
177
 
186
178
  const dxns = data.map((obj) => Obj.getDXN(obj));
187
179
  onAppend?.(dxns);
@@ -193,31 +185,31 @@ export const makeGraphWriterHandler = (
193
185
  /**
194
186
  * Create a schema for structured data extraction.
195
187
  */
196
- export const createExtractionSchema = (types: Schema.Schema.AnyNoContext[]) => {
188
+ export const createExtractionSchema = (types: Type.Entity.Any[]) => {
197
189
  return Schema.Struct({
198
190
  ...Object.fromEntries(
199
191
  types.map(preprocessSchema).map((schema, index) => [
200
192
  `objects_${getSanitizedSchemaName(types[index])}`,
201
193
  Schema.optional(Schema.Array(schema)).annotations({
202
- description: `The objects of type: ${getSchemaDXN(types[index])?.asTypeDXN()!.type}. ${SchemaAST.getDescriptionAnnotation(types[index].ast).pipe(Option.getOrElse(() => ''))}`,
194
+ description: `The objects of type: ${Type.getDXN(types[index])?.asTypeDXN()!.type}. ${SchemaAST.getDescriptionAnnotation(types[index].ast).pipe(Option.getOrElse(() => ''))}`,
203
195
  }),
204
196
  ]),
205
197
  ),
206
198
  });
207
199
  };
208
200
 
209
- export const getSanitizedSchemaName = (schema: Schema.Schema.AnyNoContext) => {
210
- return getSchemaDXN(schema)!
201
+ export const getSanitizedSchemaName = (schema: Type.Entity.Any) => {
202
+ return Type.getDXN(schema)!
211
203
  .asTypeDXN()!
212
204
  .type.replaceAll(/[^a-zA-Z0-9]+/g, '_');
213
205
  };
214
206
 
215
207
  export const sanitizeObjects = async (
216
- types: Schema.Schema.AnyNoContext[],
208
+ types: Type.Entity.Any[],
217
209
  data: Record<string, readonly unknown[]>,
218
- db: EchoDatabase,
210
+ db: Database.Database,
219
211
  queue?: Queue,
220
- ): Promise<Obj.Any[]> => {
212
+ ): Promise<Obj.Unknown[]> => {
221
213
  const entries = types
222
214
  .map(
223
215
  (type) =>
@@ -230,7 +222,7 @@ export const sanitizeObjects = async (
230
222
 
231
223
  const idMap = new Map<string, string>();
232
224
  const existingIds = new Set<ObjectId>();
233
- const enitties = new Map<ObjectId, Obj.Any | Relation.Any>();
225
+ const enitties = new Map<ObjectId, Entity.Unknown>();
234
226
 
235
227
  const resolveId = (id: string): DXN | undefined => {
236
228
  if (ObjectId.isValid(id)) {
@@ -275,7 +267,7 @@ export const sanitizeObjects = async (
275
267
  return recurse(value);
276
268
  });
277
269
 
278
- if (getEntityKind(entry.schema) === 'relation') {
270
+ if (Entity.getKind(entry.schema) === 'relation') {
279
271
  const sourceDxn = resolveId(data.source);
280
272
  if (!sourceDxn) {
281
273
  log.warn('source not found', { source: data.source });
@@ -298,7 +290,7 @@ export const sanitizeObjects = async (
298
290
  .filter((object) => !existingIds.has(object.data.id)); // TODO(dmaretskyi): This dissallows updating existing objects.
299
291
 
300
292
  // TODO(dmaretskyi): Use ref resolver.
301
- const { objects: dbObjects } = await db.query(Query.select(Filter.ids(...existingIds))).run();
293
+ const dbObjects = await db.query(Query.select(Filter.id(...existingIds))).run();
302
294
  const queueObjects = (await queue?.getObjectsById([...existingIds])) ?? [];
303
295
  const objects = [...dbObjects, ...queueObjects].filter(isNonNullable);
304
296
 
@@ -332,7 +324,7 @@ export const sanitizeObjects = async (
332
324
  }
333
325
  }
334
326
  if (!skip) {
335
- const obj = create(schema, data);
327
+ const obj = createObject(schema, data);
336
328
  enitties.set(obj.id, obj);
337
329
  return [obj];
338
330
  }
@@ -347,7 +339,7 @@ const SoftRef = Schema.Struct({
347
339
  });
348
340
 
349
341
  const preprocessSchema = (schema: Schema.Schema.AnyNoContext) => {
350
- const isRelationSchema = getEntityKind(schema) === 'relation';
342
+ const isRelationSchema = Entity.getKind(schema) === 'relation';
351
343
 
352
344
  const go = (ast: SchemaAST.AST, visited = new Set<SchemaAST.AST>()): SchemaAST.AST => {
353
345
  if (visited.has(ast)) {
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './graph';
@@ -13,9 +13,14 @@ import * as Redacted from 'effect/Redacted';
13
13
  import { AiService } from '@dxos/ai';
14
14
  import { AiServiceTestingPreset, EXA_API_KEY } from '@dxos/ai/testing';
15
15
  import { makeToolExecutionServiceFromFunctions, makeToolResolverFromFunctions } from '@dxos/assistant';
16
- import { TestHelpers } from '@dxos/effect';
17
- import { ComputeEventLogger, CredentialsService, FunctionInvocationService, TracingService } from '@dxos/functions';
18
- import { TestDatabaseLayer, testStoragePath } from '@dxos/functions/testing';
16
+ import { TestHelpers } from '@dxos/effect/testing';
17
+ import { CredentialsService, FunctionInvocationService } from '@dxos/functions';
18
+ import { TracingServiceExt } from '@dxos/functions-runtime';
19
+ import {
20
+ FunctionInvocationServiceLayerTestMocked,
21
+ TestDatabaseLayer,
22
+ testStoragePath,
23
+ } from '@dxos/functions-runtime/testing';
19
24
 
20
25
  import { Discord, Linear } from '../functions';
21
26
 
@@ -23,7 +28,6 @@ const TestLayer = Layer.mergeAll(
23
28
  AiService.model('@anthropic/claude-opus-4-0'),
24
29
  makeToolResolverFromFunctions([], Toolkit.make()),
25
30
  makeToolExecutionServiceFromFunctions(Toolkit.make() as any, Layer.empty as any),
26
- ComputeEventLogger.layerFromTracing,
27
31
  ).pipe(
28
32
  Layer.provideMerge(
29
33
  Layer.mergeAll(
@@ -38,9 +42,8 @@ const TestLayer = Layer.mergeAll(
38
42
  { service: 'discord.com', apiKey: Config.redacted('DISCORD_TOKEN') },
39
43
  { service: 'linear.app', apiKey: Config.redacted('LINEAR_API_KEY') },
40
44
  ]),
41
- FunctionInvocationService.layerTestMocked({ functions: [Linear.sync, Discord.fetch] }).pipe(
42
- Layer.provideMerge(ComputeEventLogger.layerFromTracing),
43
- Layer.provideMerge(TracingService.layerLogInfo()),
45
+ FunctionInvocationServiceLayerTestMocked({ functions: [Linear.sync, Discord.fetch] }).pipe(
46
+ Layer.provideMerge(TracingServiceExt.layerLogInfo()),
44
47
  ),
45
48
  FetchHttpClient.layer,
46
49
  ),
@@ -64,7 +67,7 @@ describe('Feed', { timeout: 600_000 }, () => {
64
67
 
65
68
  // const result = yield* AiSession.run({
66
69
  // history: [
67
- // Obj.make(DataType.Message, {
70
+ // Obj.make(Message.Message, {
68
71
  // created: new Date().toISOString(),
69
72
  // sender: { role: 'user' },
70
73
  // blocks: messages
@@ -90,7 +93,7 @@ describe('Feed', { timeout: 600_000 }, () => {
90
93
 
91
94
  // const result = yield* AiSession.run({
92
95
  // history: [
93
- // Obj.make(DataType.Message, {
96
+ // Obj.make(Message.Message, {
94
97
  // created: new Date().toISOString(),
95
98
  // sender: { role: 'user' },
96
99
  // blocks: [{ _tag: 'text', text: JSON.stringify(linearIssues) }],
@@ -5,6 +5,7 @@
5
5
  import * as Array from 'effect/Array';
6
6
  import * as Effect from 'effect/Effect';
7
7
  import * as Function from 'effect/Function';
8
+ import * as Match from 'effect/Match';
8
9
  import * as Option from 'effect/Option';
9
10
  import * as Schema from 'effect/Schema';
10
11
 
@@ -12,7 +13,8 @@ import { AiService, ConsolePrinter, ModelName } from '@dxos/ai';
12
13
  import { AiSession, GenerationObserver, createToolkit } from '@dxos/assistant';
13
14
  import { Prompt, Template } from '@dxos/blueprints';
14
15
  import { Obj, Ref, Type } from '@dxos/echo';
15
- import { DatabaseService, TracingService, defineFunction } from '@dxos/functions';
16
+ import { Database } from '@dxos/echo';
17
+ import { TracingService, defineFunction } from '@dxos/functions';
16
18
  import { log } from '@dxos/log';
17
19
 
18
20
  const DEFAULT_MODEL: ModelName = '@anthropic/claude-opus-4-0';
@@ -32,50 +34,65 @@ export default defineFunction({
32
34
  * Input object or data.
33
35
  * References get auto-resolved.
34
36
  */
35
- input: Schema.Record({ key: Schema.String, value: Schema.Any }),
37
+ input: Schema.Any.pipe(Schema.annotations({ title: 'Input' })),
36
38
  }),
37
39
  outputSchema: Schema.Any,
38
40
  handler: Effect.fnUntraced(function* ({ data }) {
39
41
  log.info('processing input', { input: data.input });
40
42
 
41
- const input = { ...data.input };
42
- for (const key of Object.keys(data.input)) {
43
- const value = data.input[key];
44
- if (Ref.isRef(value)) {
45
- const object = yield* DatabaseService.load(value);
46
- input[key] = Obj.toJSON(object);
47
- } else {
48
- input[key] = JSON.stringify(value);
49
- }
50
- }
43
+ // TODO(wittjosiah): Support templated object as input.
44
+ // Currently the object templating only supports direct pass-through or strings.
45
+ // const input = { ...data.input };
46
+ // for (const key of Object.keys(data.input)) {
47
+ // const value = data.input[key];
48
+ // if (Ref.isRef(value)) {
49
+ // const object = yield* Database.Service.load(value);
50
+ // input[key] = Obj.toJSON(object);
51
+ // } else {
52
+ // input[key] = JSON.stringify(value);
53
+ // }
54
+ // }
55
+ const input = yield* Match.value(data.input).pipe(
56
+ Match.when(
57
+ (value: any) => Ref.isRef(value),
58
+ Effect.fnUntraced(function* (ref) {
59
+ const object = yield* Database.Service.load(ref);
60
+ return Obj.toJSON(object as Obj.Unknown);
61
+ }),
62
+ ),
63
+ Match.orElse(() => Effect.succeed(data.input)),
64
+ );
51
65
 
52
- yield* DatabaseService.flush({ indexes: true });
53
- const prompt = yield* DatabaseService.load(data.prompt);
54
- const systemPrompt = data.systemPrompt ? yield* DatabaseService.load(data.systemPrompt) : undefined;
66
+ yield* Database.Service.flush({ indexes: true });
67
+ const prompt = yield* Database.Service.load(data.prompt);
68
+ const systemPrompt = data.systemPrompt ? yield* Database.Service.load(data.systemPrompt) : undefined;
55
69
  yield* TracingService.emitStatus({ message: `Running ${prompt.id}` });
56
70
 
57
- log.info('starting agent', { prompt: prompt.id, input: data.input });
71
+ log.info('starting agent', { prompt: prompt.id, input });
58
72
 
59
73
  const blueprints = yield* Function.pipe(
60
74
  prompt.blueprints,
61
75
  Array.appendAll(systemPrompt?.blueprints ?? []),
62
- Effect.forEach(DatabaseService.loadOption),
76
+ Effect.forEach(Database.Service.loadOption),
63
77
  Effect.map(Array.filter(Option.isSome)),
64
78
  Effect.map(Array.map((option) => option.value)),
65
79
  );
80
+ const toolkit = yield* createToolkit({ blueprints });
81
+
66
82
  const objects = yield* Function.pipe(
67
83
  prompt.context,
68
84
  Array.appendAll(systemPrompt?.context ?? []),
69
- Effect.forEach(DatabaseService.loadOption),
85
+ Effect.forEach(Database.Service.loadOption),
70
86
  Effect.map(Array.filter(Option.isSome)),
71
87
  Effect.map(Array.map((option) => option.value)),
72
88
  );
73
- const toolkit = yield* createToolkit({ blueprints });
74
89
 
75
- const promptInstructions = yield* DatabaseService.load(prompt.instructions.source);
90
+ const promptInstructions = yield* Database.Service.load(prompt.instructions.source);
76
91
  const promptText = Template.process(promptInstructions.content, input);
77
92
 
78
- const systemInstructions = systemPrompt ? yield* DatabaseService.load(systemPrompt.instructions.source) : undefined;
93
+ const systemInstructions = systemPrompt
94
+ ? yield* Database.Service.load(systemPrompt.instructions.source)
95
+ : undefined;
79
96
  const systemText = systemInstructions ? Template.process(systemInstructions.content, {}) : undefined;
80
97
 
81
98
  const session = new AiSession();
@@ -84,7 +101,7 @@ export default defineFunction({
84
101
  prompt: promptText,
85
102
  system: systemText,
86
103
  blueprints,
87
- objects: objects as Obj.Any[],
104
+ objects: objects as Obj.Unknown[],
88
105
  toolkit,
89
106
  observer: GenerationObserver.fromPrinter(new ConsolePrinter({ tag: 'agent' })),
90
107
  })
@@ -12,9 +12,9 @@ import * as Layer from 'effect/Layer';
12
12
  import { AiService } from '@dxos/ai';
13
13
  import { AiServiceTestingPreset } from '@dxos/ai/testing';
14
14
  import { makeToolExecutionServiceFromFunctions, makeToolResolverFromFunctions } from '@dxos/assistant';
15
- import { TestHelpers } from '@dxos/effect';
16
- import { ComputeEventLogger, CredentialsService, FunctionInvocationService, TracingService } from '@dxos/functions';
17
- import { TestDatabaseLayer } from '@dxos/functions/testing';
15
+ import { TestHelpers } from '@dxos/effect/testing';
16
+ import { CredentialsService, FunctionInvocationService, TracingService } from '@dxos/functions';
17
+ import { FunctionInvocationServiceLayerTestMocked, TestDatabaseLayer } from '@dxos/functions-runtime/testing';
18
18
 
19
19
  import { default as fetchMessages } from './fetch-messages';
20
20
 
@@ -22,7 +22,6 @@ const TestLayer = Layer.mergeAll(
22
22
  AiService.model('@anthropic/claude-opus-4-0'),
23
23
  makeToolResolverFromFunctions([], Toolkit.make()),
24
24
  makeToolExecutionServiceFromFunctions(Toolkit.make() as any, Layer.empty as any),
25
- ComputeEventLogger.layerFromTracing,
26
25
  ).pipe(
27
26
  Layer.provideMerge(
28
27
  Layer.mergeAll(
@@ -30,9 +29,8 @@ const TestLayer = Layer.mergeAll(
30
29
  TestDatabaseLayer({}),
31
30
  CredentialsService.layerConfig([{ service: 'discord.com', apiKey: Config.redacted('DISCORD_TOKEN') }]),
32
31
  FetchHttpClient.layer,
33
- FunctionInvocationService.layerTestMocked({ functions: [fetchMessages] }).pipe(
34
- Layer.provideMerge(ComputeEventLogger.layerFromTracing),
35
- Layer.provideMerge(TracingService.layerLogInfo()),
32
+ FunctionInvocationServiceLayerTestMocked({ functions: [fetchMessages] }).pipe(
33
+ Layer.provideMerge(TracingService.layerNoop),
36
34
  ),
37
35
  ),
38
36
  ),
@@ -53,6 +51,7 @@ describe('Feed', { timeout: 600_000 }, () => {
53
51
  console.log(messages);
54
52
  },
55
53
  Effect.provide(TestLayer),
54
+ TestHelpers.provideTestContext,
56
55
  TestHelpers.taggedTest('sync'),
57
56
  ),
58
57
  );
@@ -21,7 +21,7 @@ import * as Schema from 'effect/Schema';
21
21
  import { Obj } from '@dxos/echo';
22
22
  import { CredentialsService, TracingService, defineFunction } from '@dxos/functions';
23
23
  import { log } from '@dxos/log';
24
- import { DataType } from '@dxos/schema';
24
+ import { Message } from '@dxos/types';
25
25
 
26
26
  // TODO(dmaretskyi): Extract.
27
27
  const TimeRange = class extends Schema.String.pipe(Schema.pattern(/\d+(s|m|h|d)/)).annotations({
@@ -71,7 +71,7 @@ const DEFAULT_IGNORE_USERNAMES = ['GitHub', 'Needle'];
71
71
  type Thread = {
72
72
  discordChannelId: string;
73
73
  name?: string;
74
- messages: DataType.Message[];
74
+ messages: Message.Message[];
75
75
  };
76
76
 
77
77
  export default defineFunction({
@@ -133,7 +133,7 @@ export default defineFunction({
133
133
  throw new Error('no channels found');
134
134
  }
135
135
  for (const channel of channels) {
136
- console.log(channel.id, 'name' in channel ? channel.name : undefined);
136
+ log.info('channel', { id: channel.id, name: 'name' in channel ? channel.name : undefined });
137
137
  }
138
138
 
139
139
  yield* TracingService.emitStatus({ message: `Will fetch from channels: ${channels.length}` });
@@ -141,9 +141,9 @@ export default defineFunction({
141
141
  const threads = yield* Effect.forEach(
142
142
  channels,
143
143
  Effect.fnUntraced(function* (channel) {
144
- const allMessages: DataType.Message[] = [];
144
+ const allMessages: Message.Message[] = [];
145
145
 
146
- let lastMessage: Option.Option<DataType.Message> = Option.none();
146
+ let lastMessage: Option.Option<Message.Message> = Option.none();
147
147
  while (true) {
148
148
  const { id: lastId = undefined } = Function.pipe(
149
149
  lastMessage,
@@ -188,7 +188,7 @@ export default defineFunction({
188
188
  messages: allMessages
189
189
  .filter((message) => !message.sender.name || !ignoreUsernames.includes(message.sender.name))
190
190
  .filter((message) =>
191
- message.blocks.some((block) => block._tag === 'text' && block.text.trim().length > 0),
191
+ message.blocks.some((block: any) => block._tag === 'text' && block.text.trim().length > 0),
192
192
  ),
193
193
  } satisfies Thread;
194
194
  }),
@@ -222,8 +222,9 @@ const parseSnowflake = (snowflake: string): Date => {
222
222
  return new Date(Number((BigInt(snowflake) >> 22n) + discordEpoch));
223
223
  };
224
224
 
225
- const makeMessage = (message: MessageResponse): DataType.Message =>
226
- Obj.make(DataType.Message, {
225
+ // TODO(burdon): Move to @dxos/types.
226
+ const makeMessage = (message: MessageResponse): Message.Message =>
227
+ Obj.make(Message.Message, {
227
228
  [Obj.Meta]: {
228
229
  keys: [
229
230
  { id: message.id, source: 'discord.com' },
@@ -243,8 +244,8 @@ const serializeThread = (thread: Thread): string => {
243
244
  .map(
244
245
  (message) =>
245
246
  ` ${message.sender.name}: ${message.blocks
246
- .filter((block) => block._tag === 'text')
247
- .map((block) => block.text)
247
+ .filter((block: any) => block._tag === 'text')
248
+ .map((block: any) => block.text)
248
249
  .join(' ')}`,
249
250
  )
250
251
  .join('\n')}\n</thread>`;
@@ -5,6 +5,7 @@
5
5
  import { default as read$ } from './read';
6
6
  import { default as update$ } from './update';
7
7
 
8
+ /** @deprecated */
8
9
  export namespace Document {
9
10
  export const read = read$;
10
11
  export const update = update$;
@@ -6,7 +6,8 @@ import * as Effect from 'effect/Effect';
6
6
  import * as Schema from 'effect/Schema';
7
7
 
8
8
  import { ArtifactId } from '@dxos/assistant';
9
- import { DatabaseService, defineFunction } from '@dxos/functions';
9
+ import { Database } from '@dxos/echo';
10
+ import { defineFunction } from '@dxos/functions';
10
11
  import { Markdown } from '@dxos/plugin-markdown/types';
11
12
 
12
13
  export default defineFunction({
@@ -22,8 +23,8 @@ export default defineFunction({
22
23
  content: Schema.String,
23
24
  }),
24
25
  handler: Effect.fn(function* ({ data: { id } }) {
25
- const doc = yield* DatabaseService.resolve(ArtifactId.toDXN(id), Markdown.Document);
26
- const { content } = yield* DatabaseService.load(doc.content);
26
+ const doc = yield* Database.Service.resolve(ArtifactId.toDXN(id), Markdown.Document);
27
+ const { content } = yield* Database.Service.load(doc.content);
27
28
  return { content };
28
29
  }),
29
30
  });
@@ -6,7 +6,8 @@ import * as Effect from 'effect/Effect';
6
6
  import * as Schema from 'effect/Schema';
7
7
 
8
8
  import { ArtifactId } from '@dxos/assistant';
9
- import { DatabaseService, defineFunction } from '@dxos/functions';
9
+ import { Database, Obj } from '@dxos/echo';
10
+ import { defineFunction } from '@dxos/functions';
10
11
  import { Markdown } from '@dxos/plugin-markdown/types';
11
12
 
12
13
  export default defineFunction({
@@ -23,8 +24,10 @@ export default defineFunction({
23
24
  }),
24
25
  outputSchema: Schema.Void,
25
26
  handler: Effect.fn(function* ({ data: { id, content } }) {
26
- const doc = yield* DatabaseService.resolve(ArtifactId.toDXN(id), Markdown.Document);
27
- const text = yield* DatabaseService.load(doc.content);
28
- text.content = content;
27
+ const doc = yield* Database.Service.resolve(ArtifactId.toDXN(id), Markdown.Document);
28
+ const text = yield* Database.Service.load(doc.content);
29
+ Obj.change(text, (t) => {
30
+ t.content = content;
31
+ });
29
32
  }),
30
33
  });