@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.
- package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +388 -285
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +43 -0
- package/dist/lib/browser/testing/index.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +388 -285
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +44 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/types/src/blueprints/design/design-blueprint.d.ts +17 -3
- package/dist/types/src/blueprints/design/design-blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprints/design/index.d.ts +1 -1
- package/dist/types/src/blueprints/design/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/discord/discord-blueprint.d.ts +10 -10
- package/dist/types/src/blueprints/discord/discord-blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprints/discord/index.d.ts +1 -1
- package/dist/types/src/blueprints/discord/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/linear/index.d.ts +1 -1
- package/dist/types/src/blueprints/linear/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/linear/linear-blueprint.d.ts +10 -10
- package/dist/types/src/blueprints/linear/linear-blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprints/planning/index.d.ts +1 -1
- package/dist/types/src/blueprints/planning/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/planning/planning-blueprint.d.ts +17 -3
- package/dist/types/src/blueprints/planning/planning-blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprints/research/index.d.ts +1 -1
- package/dist/types/src/blueprints/research/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/research/research-blueprint.d.ts +17 -3
- package/dist/types/src/blueprints/research/research-blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprints/testing.d.ts +2 -2
- package/dist/types/src/blueprints/testing.d.ts.map +1 -1
- package/dist/types/src/blueprints/websearch/index.d.ts +1 -1
- package/dist/types/src/blueprints/websearch/index.d.ts.map +1 -1
- package/dist/types/src/blueprints/websearch/websearch-blueprint.d.ts +17 -3
- package/dist/types/src/blueprints/websearch/websearch-blueprint.d.ts.map +1 -1
- package/dist/types/src/crud/graph.d.ts +14 -11
- package/dist/types/src/crud/graph.d.ts.map +1 -1
- package/dist/types/src/functions/agent/prompt.d.ts +71 -4
- package/dist/types/src/functions/agent/prompt.d.ts.map +1 -1
- package/dist/types/src/functions/document/read.d.ts.map +1 -1
- package/dist/types/src/functions/document/update.d.ts.map +1 -1
- package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts +100 -99
- package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts.map +1 -1
- package/dist/types/src/functions/entity-extraction/index.d.ts +100 -99
- package/dist/types/src/functions/entity-extraction/index.d.ts.map +1 -1
- package/dist/types/src/functions/exa/data/exa-search-1748337321991.d.ts.map +1 -0
- package/dist/types/src/functions/exa/data/exa-search-1748337331526.d.ts.map +1 -0
- package/dist/types/src/functions/exa/data/exa-search-1748337344119.d.ts.map +1 -0
- package/dist/types/src/functions/exa/data/index.d.ts.map +1 -0
- package/dist/types/src/functions/github/fetch-prs.d.ts.map +1 -1
- package/dist/types/src/functions/linear/index.d.ts +1 -1
- package/dist/types/src/functions/linear/sync-issues.d.ts +1 -1
- package/dist/types/src/functions/linear/sync-issues.d.ts.map +1 -1
- package/dist/types/src/functions/research/document-create.d.ts.map +1 -1
- package/dist/types/src/functions/research/research-graph.d.ts +9 -8
- package/dist/types/src/functions/research/research-graph.d.ts.map +1 -1
- package/dist/types/src/functions/research/research.d.ts.map +1 -1
- package/dist/types/src/functions/research/types.d.ts +1 -1
- package/dist/types/src/functions/research/types.d.ts.map +1 -1
- package/dist/types/src/functions/tasks/read.d.ts.map +1 -1
- package/dist/types/src/functions/tasks/update.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/initiative/Initiative.d.ts +84 -0
- package/dist/types/src/initiative/Initiative.d.ts.map +1 -0
- package/dist/types/src/initiative/InitiativeSchema.d.ts +19 -0
- package/dist/types/src/initiative/InitiativeSchema.d.ts.map +1 -0
- package/dist/types/src/initiative/functions/agent.d.ts +37 -0
- package/dist/types/src/initiative/functions/agent.d.ts.map +1 -0
- package/dist/types/src/initiative/functions/getContext.d.ts +17 -0
- package/dist/types/src/initiative/functions/getContext.d.ts.map +1 -0
- package/dist/types/src/initiative/functions/index.d.ts +4 -0
- package/dist/types/src/initiative/functions/index.d.ts.map +1 -0
- package/dist/types/src/initiative/functions/update.d.ts +7 -0
- package/dist/types/src/initiative/functions/update.d.ts.map +1 -0
- package/dist/types/src/initiative/index.d.ts +1 -0
- package/dist/types/src/initiative/index.d.ts.map +1 -0
- package/dist/types/src/initiative/initiative.test.d.ts +2 -0
- package/dist/types/src/initiative/initiative.test.d.ts.map +1 -0
- package/dist/types/src/sync/sync.d.ts +3 -3
- package/dist/types/src/sync/sync.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +1 -1
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/plugins.d.ts +19 -0
- package/dist/types/src/testing/plugins.d.ts.map +1 -0
- package/dist/types/src/toolkits/AssistantToolkit.d.ts +31 -5
- package/dist/types/src/toolkits/AssistantToolkit.d.ts.map +1 -1
- package/dist/types/src/toolkits/SystemToolkit.d.ts +42 -10
- package/dist/types/src/toolkits/SystemToolkit.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +49 -35
- package/src/blueprints/design/design-blueprint.test.ts +10 -8
- package/src/blueprints/design/design-blueprint.ts +2 -4
- package/src/blueprints/design/index.ts +1 -1
- package/src/blueprints/discord/discord-blueprint.ts +2 -4
- package/src/blueprints/discord/index.ts +1 -1
- package/src/blueprints/linear/index.ts +1 -1
- package/src/blueprints/linear/linear-blueprint.ts +2 -4
- package/src/blueprints/planning/index.ts +1 -1
- package/src/blueprints/planning/planning-blueprint.test.ts +8 -6
- package/src/blueprints/planning/planning-blueprint.ts +2 -4
- package/src/blueprints/research/index.ts +1 -1
- package/src/blueprints/research/research-blueprint.ts +2 -4
- package/src/blueprints/testing.ts +2 -2
- package/src/blueprints/websearch/index.ts +2 -1
- package/src/blueprints/websearch/websearch-blueprint.ts +2 -4
- package/src/crud/graph.test.ts +4 -27
- package/src/crud/graph.ts +32 -40
- package/src/experimental/feed.test.ts +1 -1
- package/src/functions/agent/prompt.ts +17 -13
- package/src/functions/discord/fetch-messages.test.ts +1 -1
- package/src/functions/discord/fetch-messages.ts +1 -1
- package/src/functions/document/read.ts +4 -3
- package/src/functions/document/update.ts +7 -4
- package/src/functions/entity-extraction/entity-extraction.conversations.json +6597 -1
- package/src/functions/entity-extraction/entity-extraction.test.ts +7 -6
- package/src/functions/entity-extraction/entity-extraction.ts +46 -28
- package/src/functions/exa/mock.ts +1 -1
- package/src/functions/github/fetch-prs.ts +3 -2
- package/src/functions/linear/linear.test.ts +11 -10
- package/src/functions/linear/sync-issues.ts +7 -5
- package/src/functions/research/document-create.ts +7 -6
- package/src/functions/research/research-graph.ts +13 -11
- package/src/functions/research/research.conversations.json +1 -1
- package/src/functions/research/research.test.ts +24 -32
- package/src/functions/research/research.ts +8 -9
- package/src/functions/research/types.ts +1 -1
- package/src/functions/tasks/read.ts +4 -3
- package/src/functions/tasks/update.ts +4 -3
- package/src/index.ts +0 -1
- package/src/initiative/Initiative.ts +99 -0
- package/src/initiative/InitiativeSchema.ts +37 -0
- package/src/initiative/functions/agent.ts +57 -0
- package/src/initiative/functions/getContext.ts +74 -0
- package/src/initiative/functions/index.ts +7 -0
- package/src/initiative/functions/update.ts +63 -0
- package/src/initiative/index.ts +3 -0
- package/src/initiative/initiative.conversations.json +1 -0
- package/src/initiative/initiative.test.ts +485 -0
- package/src/sync/sync.ts +38 -30
- package/src/testing/index.ts +1 -1
- package/src/{plugins.tsx → testing/plugins.tsx} +15 -15
- package/src/toolkits/AssistantToolkit.conversations.json +1 -1
- package/src/toolkits/AssistantToolkit.test.ts +17 -11
- package/src/toolkits/AssistantToolkit.ts +31 -8
- package/src/toolkits/SystemToolkit.ts +100 -32
- package/dist/types/src/plugins.d.ts +0 -19
- package/dist/types/src/plugins.d.ts.map +0 -1
- package/dist/types/src/testing/data/exa-search-1748337321991.d.ts.map +0 -1
- package/dist/types/src/testing/data/exa-search-1748337331526.d.ts.map +0 -1
- package/dist/types/src/testing/data/exa-search-1748337344119.d.ts.map +0 -1
- package/dist/types/src/testing/data/index.d.ts.map +0 -1
- /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337321991.d.ts +0 -0
- /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337331526.d.ts +0 -0
- /package/dist/types/src/{testing → functions/exa}/data/exa-search-1748337344119.d.ts +0 -0
- /package/dist/types/src/{testing → functions/exa}/data/index.d.ts +0 -0
- /package/src/{testing → functions/exa}/data/exa-search-1748337321991.ts +0 -0
- /package/src/{testing → functions/exa}/data/exa-search-1748337331526.ts +0 -0
- /package/src/{testing → functions/exa}/data/exa-search-1748337344119.ts +0 -0
- /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
|
|
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 {
|
|
23
|
-
import {
|
|
24
|
-
|
|
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
|
|
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,
|
|
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*
|
|
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*
|
|
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*
|
|
85
|
+
yield* Database.Service.flush({ indexes: true });
|
|
94
86
|
const researchGraph = yield* queryResearchGraph();
|
|
95
87
|
if (researchGraph) {
|
|
96
|
-
const data = yield*
|
|
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*
|
|
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*
|
|
123
|
-
const researchBlueprint = yield*
|
|
124
|
-
const markdownBlueprint = yield*
|
|
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
|
|
140
|
-
Query.select(Filter.
|
|
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*
|
|
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
|
|
160
|
-
Query.select(Filter.
|
|
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*
|
|
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 {
|
|
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*
|
|
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*
|
|
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) =>
|
|
141
|
-
Effect.map(Array.map((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:
|
|
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 {
|
|
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*
|
|
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*
|
|
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 {
|
|
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*
|
|
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*
|
|
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
|
@@ -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,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
|
+
});
|