@dxos/assistant-toolkit 0.8.4-main.72ec0f3 → 0.8.4-main.937b3ca

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 (165) 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 +388 -285
  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 +388 -285
  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 +10 -10
  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 +10 -10
  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/crud/graph.d.ts +14 -11
  42. package/dist/types/src/crud/graph.d.ts.map +1 -1
  43. package/dist/types/src/functions/agent/prompt.d.ts +71 -4
  44. package/dist/types/src/functions/agent/prompt.d.ts.map +1 -1
  45. package/dist/types/src/functions/document/read.d.ts.map +1 -1
  46. package/dist/types/src/functions/document/update.d.ts.map +1 -1
  47. package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts +100 -99
  48. package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts.map +1 -1
  49. package/dist/types/src/functions/entity-extraction/index.d.ts +100 -99
  50. package/dist/types/src/functions/entity-extraction/index.d.ts.map +1 -1
  51. package/dist/types/src/functions/exa/data/exa-search-1748337321991.d.ts.map +1 -0
  52. package/dist/types/src/functions/exa/data/exa-search-1748337331526.d.ts.map +1 -0
  53. package/dist/types/src/functions/exa/data/exa-search-1748337344119.d.ts.map +1 -0
  54. package/dist/types/src/functions/exa/data/index.d.ts.map +1 -0
  55. package/dist/types/src/functions/github/fetch-prs.d.ts.map +1 -1
  56. package/dist/types/src/functions/linear/index.d.ts +1 -1
  57. package/dist/types/src/functions/linear/sync-issues.d.ts +1 -1
  58. package/dist/types/src/functions/linear/sync-issues.d.ts.map +1 -1
  59. package/dist/types/src/functions/research/document-create.d.ts.map +1 -1
  60. package/dist/types/src/functions/research/research-graph.d.ts +9 -8
  61. package/dist/types/src/functions/research/research-graph.d.ts.map +1 -1
  62. package/dist/types/src/functions/research/research.d.ts.map +1 -1
  63. package/dist/types/src/functions/research/types.d.ts +1 -1
  64. package/dist/types/src/functions/research/types.d.ts.map +1 -1
  65. package/dist/types/src/functions/tasks/read.d.ts.map +1 -1
  66. package/dist/types/src/functions/tasks/update.d.ts.map +1 -1
  67. package/dist/types/src/index.d.ts +0 -1
  68. package/dist/types/src/index.d.ts.map +1 -1
  69. package/dist/types/src/initiative/Initiative.d.ts +84 -0
  70. package/dist/types/src/initiative/Initiative.d.ts.map +1 -0
  71. package/dist/types/src/initiative/InitiativeSchema.d.ts +19 -0
  72. package/dist/types/src/initiative/InitiativeSchema.d.ts.map +1 -0
  73. package/dist/types/src/initiative/functions/agent.d.ts +37 -0
  74. package/dist/types/src/initiative/functions/agent.d.ts.map +1 -0
  75. package/dist/types/src/initiative/functions/getContext.d.ts +17 -0
  76. package/dist/types/src/initiative/functions/getContext.d.ts.map +1 -0
  77. package/dist/types/src/initiative/functions/index.d.ts +4 -0
  78. package/dist/types/src/initiative/functions/index.d.ts.map +1 -0
  79. package/dist/types/src/initiative/functions/update.d.ts +7 -0
  80. package/dist/types/src/initiative/functions/update.d.ts.map +1 -0
  81. package/dist/types/src/initiative/index.d.ts +1 -0
  82. package/dist/types/src/initiative/index.d.ts.map +1 -0
  83. package/dist/types/src/initiative/initiative.test.d.ts +2 -0
  84. package/dist/types/src/initiative/initiative.test.d.ts.map +1 -0
  85. package/dist/types/src/sync/sync.d.ts +3 -3
  86. package/dist/types/src/sync/sync.d.ts.map +1 -1
  87. package/dist/types/src/testing/index.d.ts +1 -1
  88. package/dist/types/src/testing/index.d.ts.map +1 -1
  89. package/dist/types/src/testing/plugins.d.ts +19 -0
  90. package/dist/types/src/testing/plugins.d.ts.map +1 -0
  91. package/dist/types/src/toolkits/AssistantToolkit.d.ts +31 -5
  92. package/dist/types/src/toolkits/AssistantToolkit.d.ts.map +1 -1
  93. package/dist/types/src/toolkits/SystemToolkit.d.ts +42 -10
  94. package/dist/types/src/toolkits/SystemToolkit.d.ts.map +1 -1
  95. package/dist/types/tsconfig.tsbuildinfo +1 -1
  96. package/package.json +49 -35
  97. package/src/blueprints/design/design-blueprint.test.ts +10 -8
  98. package/src/blueprints/design/design-blueprint.ts +2 -4
  99. package/src/blueprints/design/index.ts +1 -1
  100. package/src/blueprints/discord/discord-blueprint.ts +2 -4
  101. package/src/blueprints/discord/index.ts +1 -1
  102. package/src/blueprints/linear/index.ts +1 -1
  103. package/src/blueprints/linear/linear-blueprint.ts +2 -4
  104. package/src/blueprints/planning/index.ts +1 -1
  105. package/src/blueprints/planning/planning-blueprint.test.ts +8 -6
  106. package/src/blueprints/planning/planning-blueprint.ts +2 -4
  107. package/src/blueprints/research/index.ts +1 -1
  108. package/src/blueprints/research/research-blueprint.ts +2 -4
  109. package/src/blueprints/testing.ts +2 -2
  110. package/src/blueprints/websearch/index.ts +2 -1
  111. package/src/blueprints/websearch/websearch-blueprint.ts +2 -4
  112. package/src/crud/graph.test.ts +4 -27
  113. package/src/crud/graph.ts +32 -40
  114. package/src/experimental/feed.test.ts +1 -1
  115. package/src/functions/agent/prompt.ts +17 -13
  116. package/src/functions/discord/fetch-messages.test.ts +1 -1
  117. package/src/functions/discord/fetch-messages.ts +1 -1
  118. package/src/functions/document/read.ts +4 -3
  119. package/src/functions/document/update.ts +7 -4
  120. package/src/functions/entity-extraction/entity-extraction.conversations.json +6597 -1
  121. package/src/functions/entity-extraction/entity-extraction.test.ts +7 -6
  122. package/src/functions/entity-extraction/entity-extraction.ts +46 -28
  123. package/src/functions/exa/mock.ts +1 -1
  124. package/src/functions/github/fetch-prs.ts +3 -2
  125. package/src/functions/linear/linear.test.ts +11 -10
  126. package/src/functions/linear/sync-issues.ts +7 -5
  127. package/src/functions/research/document-create.ts +7 -6
  128. package/src/functions/research/research-graph.ts +13 -11
  129. package/src/functions/research/research.conversations.json +1 -1
  130. package/src/functions/research/research.test.ts +24 -32
  131. package/src/functions/research/research.ts +8 -9
  132. package/src/functions/research/types.ts +1 -1
  133. package/src/functions/tasks/read.ts +4 -3
  134. package/src/functions/tasks/update.ts +4 -3
  135. package/src/index.ts +0 -1
  136. package/src/initiative/Initiative.ts +99 -0
  137. package/src/initiative/InitiativeSchema.ts +37 -0
  138. package/src/initiative/functions/agent.ts +57 -0
  139. package/src/initiative/functions/getContext.ts +74 -0
  140. package/src/initiative/functions/index.ts +7 -0
  141. package/src/initiative/functions/update.ts +63 -0
  142. package/src/initiative/index.ts +3 -0
  143. package/src/initiative/initiative.conversations.json +1 -0
  144. package/src/initiative/initiative.test.ts +485 -0
  145. package/src/sync/sync.ts +38 -30
  146. package/src/testing/index.ts +1 -1
  147. package/src/{plugins.tsx → testing/plugins.tsx} +15 -15
  148. package/src/toolkits/AssistantToolkit.conversations.json +1 -1
  149. package/src/toolkits/AssistantToolkit.test.ts +17 -11
  150. package/src/toolkits/AssistantToolkit.ts +31 -8
  151. package/src/toolkits/SystemToolkit.ts +100 -32
  152. package/dist/types/src/plugins.d.ts +0 -19
  153. package/dist/types/src/plugins.d.ts.map +0 -1
  154. package/dist/types/src/testing/data/exa-search-1748337321991.d.ts.map +0 -1
  155. package/dist/types/src/testing/data/exa-search-1748337331526.d.ts.map +0 -1
  156. package/dist/types/src/testing/data/exa-search-1748337344119.d.ts.map +0 -1
  157. package/dist/types/src/testing/data/index.d.ts.map +0 -1
  158. /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337321991.d.ts +0 -0
  159. /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337331526.d.ts +0 -0
  160. /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337344119.d.ts +0 -0
  161. /package/dist/types/src/{testing → functions/exa}/data/index.d.ts +0 -0
  162. /package/src/{testing → functions/exa}/data/exa-search-1748337321991.ts +0 -0
  163. /package/src/{testing → functions/exa}/data/exa-search-1748337331526.ts +0 -0
  164. /package/src/{testing → functions/exa}/data/exa-search-1748337344119.ts +0 -0
  165. /package/src/{testing → functions/exa}/data/index.ts +0 -0
@@ -8,8 +8,8 @@ import { describe, it } from '@effect/vitest';
8
8
  import * as Effect from 'effect/Effect';
9
9
  import * as Layer from 'effect/Layer';
10
10
 
11
- import { AiService, ConsolePrinter, MemoizedAiService } from '@dxos/ai';
12
- import { TestAiService } from '@dxos/ai/testing';
11
+ import { AiService, ConsolePrinter } from '@dxos/ai';
12
+ import { MemoizedAiService, TestAiService } from '@dxos/ai/testing';
13
13
  import {
14
14
  AiConversation,
15
15
  type ContextBinding,
@@ -18,19 +18,14 @@ import {
18
18
  makeToolResolverFromFunctions,
19
19
  } from '@dxos/assistant';
20
20
  import { Blueprint } from '@dxos/blueprints';
21
- import { Filter, Obj, Query, Ref } from '@dxos/echo';
22
- import { TestHelpers, acquireReleaseResource } from '@dxos/effect';
23
- import {
24
- CredentialsService,
25
- DatabaseService,
26
- FunctionInvocationService,
27
- QueueService,
28
- TracingService,
29
- } from '@dxos/functions';
21
+ import { Database, Filter, Obj, Query, Ref } from '@dxos/echo';
22
+ import { acquireReleaseResource } from '@dxos/effect';
23
+ import { TestHelpers } from '@dxos/effect/testing';
24
+ import { CredentialsService, FunctionInvocationService, QueueService, TracingService } from '@dxos/functions';
30
25
  import { FunctionInvocationServiceLayerTest, TestDatabaseLayer } from '@dxos/functions-runtime/testing';
31
26
  import { invariant } from '@dxos/invariant';
32
27
  import { ObjectId } from '@dxos/keys';
33
- import { MarkdownBlueprint, MarkdownFunction } from '@dxos/plugin-markdown/toolkit';
28
+ import { MarkdownBlueprint } from '@dxos/plugin-markdown/blueprints';
34
29
  import { Markdown } from '@dxos/plugin-markdown/types';
35
30
  import { HasSubject, type Message, Organization } from '@dxos/types';
36
31
 
@@ -46,15 +41,12 @@ ObjectId.dangerouslyDisableRandomness();
46
41
 
47
42
  const TestLayer = Layer.mergeAll(
48
43
  AiService.model('@anthropic/claude-opus-4-0'),
49
- makeToolResolverFromFunctions(
50
- [research, createDocument, MarkdownFunction.create, MarkdownFunction.open, MarkdownFunction.update],
51
- testToolkit,
52
- ),
44
+ makeToolResolverFromFunctions([research, createDocument, ...MarkdownBlueprint.functions], testToolkit),
53
45
  makeToolExecutionServiceFromFunctions(testToolkit, testToolkit.toLayer({}) as any),
54
46
  ).pipe(
55
47
  Layer.provideMerge(
56
48
  FunctionInvocationServiceLayerTest({
57
- functions: [research, createDocument, MarkdownFunction.create, MarkdownFunction.open, MarkdownFunction.update],
49
+ functions: [research, createDocument, ...MarkdownBlueprint.functions],
58
50
  }),
59
51
  ),
60
52
  Layer.provideMerge(
@@ -76,13 +68,13 @@ describe('Research', () => {
76
68
  'call a function to generate a research report',
77
69
  Effect.fnUntraced(
78
70
  function* (_) {
79
- yield* DatabaseService.add(
71
+ yield* Database.Service.add(
80
72
  Obj.make(Organization.Organization, {
81
73
  name: 'BlueYard',
82
74
  website: 'https://blueyard.com',
83
75
  }),
84
76
  );
85
- yield* DatabaseService.flush({ indexes: true });
77
+ yield* Database.Service.flush({ indexes: true });
86
78
  const result = yield* FunctionInvocationService.invokeFunction(research, {
87
79
  query: 'Founders and portfolio of BlueYard.',
88
80
  });
@@ -90,10 +82,10 @@ describe('Research', () => {
90
82
  console.log(inspect(result, { depth: null, colors: true }));
91
83
  console.log(JSON.stringify(result, null, 2));
92
84
 
93
- yield* DatabaseService.flush({ indexes: true });
85
+ yield* Database.Service.flush({ indexes: true });
94
86
  const researchGraph = yield* queryResearchGraph();
95
87
  if (researchGraph) {
96
- const data = yield* DatabaseService.load(researchGraph.queue).pipe(
88
+ const data = yield* Database.Service.load(researchGraph.queue).pipe(
97
89
  Effect.flatMap((queue) => Effect.promise(() => queue.queryObjects())),
98
90
  );
99
91
  console.log(inspect(data, { depth: null, colors: true }));
@@ -109,7 +101,7 @@ describe('Research', () => {
109
101
  'create and update research report',
110
102
  Effect.fnUntraced(
111
103
  function* (_) {
112
- const organization = yield* DatabaseService.add(
104
+ const organization = yield* Database.Service.add(
113
105
  Obj.make(Organization.Organization, {
114
106
  name: 'BlueYard',
115
107
  website: 'https://blueyard.com',
@@ -117,11 +109,11 @@ describe('Research', () => {
117
109
  );
118
110
 
119
111
  const queue = yield* QueueService.createQueue<Message.Message | ContextBinding>();
120
- const conversation = yield* acquireReleaseResource(() => new AiConversation(queue));
112
+ const conversation = yield* acquireReleaseResource(() => new AiConversation({ queue }));
121
113
 
122
- yield* DatabaseService.flush({ indexes: true });
123
- const researchBlueprint = yield* DatabaseService.add(Obj.clone(ResearchBlueprint));
124
- const markdownBlueprint = yield* DatabaseService.add(Obj.clone(MarkdownBlueprint));
114
+ yield* Database.Service.flush({ indexes: true });
115
+ const researchBlueprint = yield* Database.Service.add(Obj.clone(ResearchBlueprint));
116
+ const markdownBlueprint = yield* Database.Service.add(Obj.clone(MarkdownBlueprint.make()));
125
117
  yield* Effect.promise(() =>
126
118
  conversation.context.bind({
127
119
  blueprints: [Ref.make(researchBlueprint), Ref.make(markdownBlueprint)],
@@ -136,8 +128,8 @@ describe('Research', () => {
136
128
  prompt: `Create a research summary about ${organization.name}.`,
137
129
  });
138
130
  {
139
- const { objects: docs } = yield* DatabaseService.runQuery(
140
- Query.select(Filter.ids(organization.id)).targetOf(HasSubject.HasSubject).source(),
131
+ const docs = yield* Database.Service.runQuery(
132
+ Query.select(Filter.id(organization.id)).targetOf(HasSubject.HasSubject).source(),
141
133
  );
142
134
  if (docs.length !== 1) {
143
135
  throw new Error(`Expected 1 research document; got ${docs.length}: ${docs.map((_) => _.name)}`);
@@ -147,7 +139,7 @@ describe('Research', () => {
147
139
  invariant(Obj.instanceOf(Markdown.Document, doc));
148
140
  console.log({
149
141
  name: doc.name,
150
- content: yield* DatabaseService.load(doc.content).pipe(Effect.map((_) => _.content)),
142
+ content: yield* Database.Service.load(doc.content).pipe(Effect.map((_) => _.content)),
151
143
  });
152
144
  }
153
145
 
@@ -156,8 +148,8 @@ describe('Research', () => {
156
148
  prompt: 'Add a section about their portfolio.',
157
149
  });
158
150
  {
159
- const { objects: docs } = yield* DatabaseService.runQuery(
160
- Query.select(Filter.ids(organization.id)).targetOf(HasSubject.HasSubject).source(),
151
+ const docs = yield* Database.Service.runQuery(
152
+ Query.select(Filter.id(organization.id)).targetOf(HasSubject.HasSubject).source(),
161
153
  );
162
154
  if (docs.length !== 1) {
163
155
  throw new Error(`Expected 1 research document; got ${docs.length}: ${docs.map((_) => _.name)}`);
@@ -167,7 +159,7 @@ describe('Research', () => {
167
159
  invariant(Obj.instanceOf(Markdown.Document, doc));
168
160
  console.log({
169
161
  name: doc.name,
170
- content: yield* DatabaseService.load(doc.content).pipe(Effect.map((_) => _.content)),
162
+ content: yield* Database.Service.load(doc.content).pipe(Effect.map((_) => _.content)),
171
163
  });
172
164
  }
173
165
  },
@@ -21,8 +21,9 @@ import {
21
21
  makeToolResolverFromFunctions,
22
22
  } from '@dxos/assistant';
23
23
  import { Template } from '@dxos/blueprints';
24
- import { type DXN, Obj } from '@dxos/echo';
25
- import { DatabaseService, TracingService, defineFunction } from '@dxos/functions';
24
+ import { type DXN, Entity, Obj } from '@dxos/echo';
25
+ import { Database } from '@dxos/echo';
26
+ import { TracingService, defineFunction } from '@dxos/functions';
26
27
  import { FunctionInvocationServiceLayerTestMocked } from '@dxos/functions-runtime/testing';
27
28
  import { type Message, Person } from '@dxos/types';
28
29
  import { trim } from '@dxos/util';
@@ -84,7 +85,7 @@ export default defineFunction({
84
85
  handler: Effect.fnUntraced(
85
86
  function* ({ data: { query, instructions, mockSearch = false, entityExtraction = false } }) {
86
87
  if (mockSearch) {
87
- const mockPerson = yield* DatabaseService.add(
88
+ const mockPerson = yield* Database.Service.add(
88
89
  Obj.make(Person.Person, {
89
90
  preferredName: 'John Doe',
90
91
  emails: [{ value: 'john.doe@example.com' }],
@@ -101,7 +102,7 @@ export default defineFunction({
101
102
  };
102
103
  }
103
104
 
104
- yield* DatabaseService.flush({ indexes: true });
105
+ yield* Database.Service.flush({ indexes: true });
105
106
  yield* TracingService.emitStatus({ message: 'Starting research...' });
106
107
 
107
108
  const NativeWebSearch = Toolkit.make(AnthropicTool.WebSearch_20250305({}));
@@ -122,9 +123,7 @@ export default defineFunction({
122
123
  ) as any;
123
124
  }
124
125
 
125
- const finishedToolkit = yield* createToolkit({
126
- toolkit: toolkit as any,
127
- }).pipe(Effect.provide(handlers));
126
+ const finishedToolkit = yield* createToolkit({ toolkit }).pipe(Effect.provide(handlers));
128
127
 
129
128
  const session = new AiSession();
130
129
  const result = yield* session.run({
@@ -137,8 +136,8 @@ export default defineFunction({
137
136
  observer: GenerationObserver.fromPrinter(new ConsolePrinter({ tag: 'research' })),
138
137
  });
139
138
 
140
- const objects = yield* Effect.forEach(objectDXNs, (dxn) => DatabaseService.resolve(dxn)).pipe(
141
- Effect.map(Array.map((obj) => Obj.toJSON(obj))),
139
+ const objects = yield* Effect.forEach(objectDXNs, (dxn) => Database.Service.resolve(dxn)).pipe(
140
+ Effect.map(Array.map((obj) => Entity.toJSON(obj))),
142
141
  );
143
142
 
144
143
  return {
@@ -9,7 +9,7 @@ import { Event, HasConnection, HasRelationship, LegacyOrganization, LegacyPerson
9
9
  /**
10
10
  * Data types for research.
11
11
  */
12
- export const ResearchDataTypes: (Type.Obj.Any | Type.Relation.Any)[] = [
12
+ export const ResearchDataTypes: Type.Entity.Any[] = [
13
13
  // Objects
14
14
  Event.Event,
15
15
  LegacyOrganization,
@@ -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,10 +23,10 @@ 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 doc = yield* Database.Service.resolve(ArtifactId.toDXN(id), Markdown.Document);
26
27
 
27
28
  // Return content with line numbers prefixed.
28
- const { content } = yield* DatabaseService.load(doc.content);
29
+ const { content } = yield* Database.Service.load(doc.content);
29
30
  const lines = content.split('\n');
30
31
  const len = String(lines.length).length;
31
32
  const numbered = lines.map((line, i) => `${String(i + 1).padStart(len, ' ')}. ${line}`).join('\n');
@@ -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
  import { MarkdownTasks, type TaskOperation } from './task-list';
@@ -34,10 +35,10 @@ export default defineFunction({
34
35
  }),
35
36
  }),
36
37
  handler: Effect.fn(function* ({ data: { id, operations = [] } }) {
37
- const doc = yield* DatabaseService.resolve(ArtifactId.toDXN(id), Markdown.Document);
38
+ const doc = yield* Database.Service.resolve(ArtifactId.toDXN(id), Markdown.Document);
38
39
 
39
40
  // Create task manager and apply operations if provided.
40
- const { content } = yield* DatabaseService.load(doc.content);
41
+ const { content } = yield* Database.Service.load(doc.content);
41
42
  const taskManager = new MarkdownTasks(content);
42
43
  if (operations.length > 0) {
43
44
  taskManager.applyOperations(operations as TaskOperation[]);
package/src/index.ts CHANGED
@@ -4,7 +4,6 @@
4
4
 
5
5
  export * from './blueprints';
6
6
  export * from './functions';
7
- export * from './plugins';
8
7
  export * from './sync';
9
8
  export * from './crud';
10
9
  export * from './toolkits';
@@ -0,0 +1,99 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { AiContextBinder, type ContextBinding } from '@dxos/assistant';
8
+ import { Blueprint, Template } from '@dxos/blueprints';
9
+ import { Database, Obj, Ref } from '@dxos/echo';
10
+ import { QueueService } from '@dxos/functions';
11
+ import { Text } from '@dxos/schema';
12
+ import type { Message } from '@dxos/types';
13
+ import { trim } from '@dxos/util';
14
+
15
+ import { agent, getContext, update } from './functions';
16
+ import { Initiative, PLAN_ARTIFACT_NAME, SPEC_ARTIFACT_NAME } from './InitiativeSchema';
17
+
18
+ export { Initiative, PLAN_ARTIFACT_NAME, SPEC_ARTIFACT_NAME } from './InitiativeSchema';
19
+ export type { Initiative as InitiativeType } from './InitiativeSchema';
20
+
21
+ export const make = (
22
+ props: Omit<Obj.MakeProps<typeof Initiative>, 'artifacts' | 'chat'> &
23
+ Partial<Pick<Obj.MakeProps<typeof Initiative>, 'artifacts'>> & {
24
+ spec: string;
25
+ plan?: string;
26
+ blueprints?: Ref.Ref<Blueprint.Blueprint>[];
27
+ contextObjects?: Ref.Ref<Obj.Any>[];
28
+ },
29
+ ): Effect.Effect<Initiative, never, QueueService | Database.Service> =>
30
+ Effect.gen(function* () {
31
+ const initiative = Obj.make(Initiative, {
32
+ ...props,
33
+ artifacts: [
34
+ {
35
+ name: SPEC_ARTIFACT_NAME,
36
+ data: Ref.make(Text.make(props.spec)),
37
+ },
38
+ {
39
+ name: PLAN_ARTIFACT_NAME,
40
+ data: Ref.make(Text.make(props.plan ?? '')),
41
+ },
42
+ ...(props.artifacts ?? []),
43
+ ],
44
+ });
45
+ yield* Database.Service.add(initiative);
46
+ const queue = yield* QueueService.createQueue<Message.Message | ContextBinding>();
47
+ const contextBinder = new AiContextBinder({ queue });
48
+ const initiativeBlueprint = yield* Database.Service.add(Obj.clone(InitiativeBlueprint, { deep: true }));
49
+ yield* Effect.promise(() =>
50
+ contextBinder.bind({
51
+ blueprints: [Ref.make(initiativeBlueprint), ...(props.blueprints ?? [])],
52
+ objects: [Ref.make(initiative), ...(props.contextObjects ?? [])],
53
+ }),
54
+ );
55
+ Obj.change(initiative, (initiative) => {
56
+ initiative.chat = Ref.fromDXN(queue.dxn);
57
+ });
58
+
59
+ return initiative;
60
+ });
61
+
62
+ export const functions = [getContext, update, agent];
63
+
64
+ export const InitiativeBlueprint = Blueprint.make({
65
+ key: 'dxos.org/blueprint/initiative',
66
+ name: 'Initiative blueprint',
67
+ instructions: Template.make({
68
+ source: trim`
69
+ You work on an initiative. Each initiative has a spec - the goal of the initiative.
70
+ The initiative plan shows the current progress of the initiative.
71
+ Initiative has an number of associated artifacts you can read/write.
72
+ Spec and plan are also artifacts.
73
+ You can edit them if necessary.
74
+
75
+ {{#with initiative}}
76
+ Initiative spec:
77
+ {{spec.dxn}}
78
+ {{spec.content}}
79
+
80
+ Initiative plan:
81
+ {{plan.dxn}}
82
+ {{plan.content}}
83
+
84
+ All artifacts:
85
+ {{#each artifacts}}
86
+ {{name}}: {{type}} {{dxn}}
87
+ {{/each}}
88
+ {{/with}}
89
+ `,
90
+ inputs: [
91
+ {
92
+ name: 'initiative',
93
+ kind: 'function',
94
+ function: 'dxos.org/function/initiative/get-context',
95
+ },
96
+ ],
97
+ }),
98
+ tools: Blueprint.toolDefinitions({ functions: [update] }),
99
+ });
@@ -0,0 +1,37 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+
7
+ import { Type } from '@dxos/echo';
8
+ import { Queue } from '@dxos/echo-db';
9
+
10
+ /**
11
+ * Initiative schema definition.
12
+ */
13
+ export const Initiative = Schema.Struct({
14
+ name: Schema.String,
15
+ artifacts: Schema.Array(
16
+ Schema.Struct({
17
+ name: Schema.String,
18
+ data: Type.Ref(Type.Obj),
19
+ }),
20
+ ),
21
+
22
+ // TODO(dmaretskyi): Consider using chat type.
23
+ // TODO(dmaretskyi): Multiple chats.
24
+ chat: Schema.optional(Type.Ref(Queue)),
25
+
26
+ // TODO(dmaretskyi): Triggers & input queue.
27
+ }).pipe(
28
+ Type.object({
29
+ typename: 'dxos.org/type/Initiative',
30
+ version: '0.1.0',
31
+ }),
32
+ );
33
+ export interface Initiative extends Schema.Schema.Type<typeof Initiative> {}
34
+
35
+ export const SPEC_ARTIFACT_NAME = 'Spec';
36
+
37
+ export const PLAN_ARTIFACT_NAME = 'Plan';
@@ -0,0 +1,57 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Schema from 'effect/Schema';
7
+
8
+ import { AiContextService, AiConversation } from '@dxos/assistant';
9
+ import { Database, Obj, Type } from '@dxos/echo';
10
+ import { acquireReleaseResource } from '@dxos/effect';
11
+ import { TriggerEvent, defineFunction } from '@dxos/functions';
12
+ import { invariant } from '@dxos/invariant';
13
+
14
+ import * as Initiative from '../InitiativeSchema';
15
+
16
+ export default defineFunction({
17
+ key: 'dxos.org/function/initiative/agent',
18
+ name: 'Initiative Agent',
19
+ description: 'Agentic worker that drives the initiative autonomously.',
20
+ inputSchema: Schema.Struct({
21
+ initiative: Schema.suspend(() => Type.Ref(Initiative.Initiative)),
22
+ prompt: Schema.optional(Schema.String),
23
+ event: Schema.optional(TriggerEvent.TriggerEvent),
24
+ }),
25
+ outputSchema: Schema.Void,
26
+ services: [AiContextService],
27
+ handler: Effect.fnUntraced(function* ({ data }) {
28
+ const initiative = yield* Database.Service.load(data.initiative);
29
+ invariant(Obj.instanceOf(Initiative.Initiative, initiative));
30
+ invariant(initiative.chat, 'Initiative has no chat.');
31
+ const chatQueue = yield* Database.Service.load(initiative.chat!);
32
+ invariant(chatQueue, 'Initiative chat queue not found.');
33
+ const conversation = yield* acquireReleaseResource(() => new AiConversation({ queue: chatQueue as any }));
34
+
35
+ const iniativesInContext = conversation.context.getObjects().filter(Obj.instanceOf(Initiative.Initiative));
36
+ if (iniativesInContext.length !== 1) {
37
+ throw new Error('There should be exactly one initiative in context. Got: ' + iniativesInContext.length);
38
+ }
39
+
40
+ if (!data.prompt && !data.event) {
41
+ throw new Error('Either prompt or event must be provided.');
42
+ }
43
+
44
+ let input = '';
45
+ if (data.prompt) {
46
+ input += `${data.prompt}\n\n`;
47
+ }
48
+ if (data.event) {
49
+ input += `<event>\n${JSON.stringify(data.event, null, 2)}\n</event>\n\n`;
50
+ }
51
+
52
+ yield* conversation.createRequest({
53
+ prompt: input,
54
+ // observer: GenerationObserver.fromPrinter(new ConsolePrinter()),
55
+ });
56
+ }, Effect.scoped) as any, // TODO(dmaretskyi): Services don't align -- need to refactor how functions are defined.
57
+ });
@@ -0,0 +1,74 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Schema from 'effect/Schema';
7
+
8
+ import { AiContextService } from '@dxos/assistant';
9
+ import { Database, Obj } from '@dxos/echo';
10
+ import { defineFunction } from '@dxos/functions';
11
+ import { Text } from '@dxos/schema';
12
+
13
+ import * as Initiative from '../InitiativeSchema';
14
+
15
+ export default defineFunction({
16
+ key: 'dxos.org/function/initiative/get-context',
17
+ name: 'Get Initiative Context',
18
+ description: 'Get the context of an initiative.',
19
+ inputSchema: Schema.Struct({}),
20
+ outputSchema: Schema.Struct({
21
+ spec: Schema.Struct({
22
+ dxn: Schema.String,
23
+ content: Schema.String,
24
+ }),
25
+ plan: Schema.Struct({
26
+ dxn: Schema.String,
27
+ content: Schema.String,
28
+ }),
29
+ artifacts: Schema.Array(
30
+ Schema.Struct({
31
+ name: Schema.String,
32
+ type: Schema.String,
33
+ dxn: Schema.String,
34
+ }),
35
+ ),
36
+ }),
37
+ services: [AiContextService],
38
+ handler: Effect.fnUntraced(function* ({ data }) {
39
+ const { binder } = yield* AiContextService;
40
+
41
+ const initiative = binder
42
+ .getObjects()
43
+ .filter((_) => Obj.instanceOf(Initiative.Initiative, _))
44
+ .at(0);
45
+ if (!initiative) {
46
+ throw new Error('No initiative in context.');
47
+ }
48
+
49
+ const spec = initiative.artifacts.find((artifact) => artifact.name === Initiative.SPEC_ARTIFACT_NAME);
50
+ const plan = initiative.artifacts.find((artifact) => artifact.name === Initiative.PLAN_ARTIFACT_NAME);
51
+ const specObj = !spec ? undefined : yield* Database.Service.resolve(spec.data, Text.Text);
52
+ const planObj = !plan ? undefined : yield* Database.Service.resolve(plan.data, Text.Text);
53
+
54
+ return {
55
+ spec: {
56
+ dxn: spec?.data.dxn.toString(),
57
+ content: specObj?.content ?? 'No spec found.',
58
+ },
59
+ plan: {
60
+ dxn: plan?.data.dxn.toString(),
61
+ content: planObj?.content ?? 'No plan found.',
62
+ },
63
+ artifacts: yield* Effect.forEach(initiative.artifacts, (artifact) =>
64
+ Effect.gen(function* () {
65
+ return {
66
+ name: artifact.name,
67
+ type: Obj.getTypename(yield* Database.Service.load(artifact.data)),
68
+ dxn: artifact.data.dxn.toString(),
69
+ };
70
+ }),
71
+ ),
72
+ };
73
+ }) as any, // TODO(dmaretskyi): Services don't align -- need to refactor how functions are defined.
74
+ });
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export { default as getContext } from './getContext';
6
+ export { default as update } from './update';
7
+ export { default as agent } from './agent';
@@ -0,0 +1,63 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Schema from 'effect/Schema';
7
+
8
+ import { AiContextService } from '@dxos/assistant';
9
+ import { Database, Obj, Ref } from '@dxos/echo';
10
+ import { defineFunction } from '@dxos/functions';
11
+ import { Text } from '@dxos/schema';
12
+
13
+ import * as Initiative from '../InitiativeSchema';
14
+
15
+ export default defineFunction({
16
+ key: 'dxos.org/function/initiative/update',
17
+ name: 'Create or update artifact',
18
+ description: 'Updates the text artifact to have new content.',
19
+ inputSchema: Schema.Struct({
20
+ name: Schema.String.annotations({
21
+ description: 'The name of the artifact to update.',
22
+ }),
23
+ content: Schema.String.annotations({
24
+ description: 'The new content of the artifact.',
25
+ }),
26
+ create: Schema.optional(Schema.Boolean).annotations({
27
+ description: 'Whether to create the artifact if it does not exist.',
28
+ }),
29
+ }),
30
+ outputSchema: Schema.Void,
31
+ services: [AiContextService],
32
+ handler: Effect.fnUntraced(function* ({ data }) {
33
+ const { binder } = yield* AiContextService;
34
+
35
+ const initiative = binder
36
+ .getObjects()
37
+ .filter((_) => Obj.instanceOf(Initiative.Initiative, _))
38
+ .at(0);
39
+ if (!initiative) {
40
+ throw new Error('No initiative in context.');
41
+ }
42
+
43
+ const artifact = initiative.artifacts.find((artifact) => artifact.name === data.name);
44
+ if (!artifact) {
45
+ if (data.create) {
46
+ Obj.change(initiative, (initiative) => {
47
+ initiative.artifacts.push({
48
+ name: data.name,
49
+ data: Ref.make(Text.make(data.content)),
50
+ });
51
+ });
52
+ return;
53
+ } else {
54
+ throw new Error(`Artifact ${data.name} not found.`);
55
+ }
56
+ }
57
+
58
+ const artifactObj = yield* Database.Service.resolve(artifact.data, Text.Text);
59
+ Obj.change(artifactObj, (artifactObj) => {
60
+ artifactObj.content = data.content;
61
+ });
62
+ }) as any, // TODO(dmaretskyi): Services don't align -- need to refactor how functions are defined.
63
+ });
@@ -0,0 +1,3 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //