@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.
- 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 +1091 -692
- 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 +1090 -692
- 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 +13 -13
- 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 +13 -13
- 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/blueprints/websearch/websearch-toolkit.d.ts +1 -0
- package/dist/types/src/blueprints/websearch/websearch-toolkit.d.ts.map +1 -1
- package/dist/types/src/{functions/research → crud}/graph.d.ts +14 -11
- package/dist/types/src/crud/graph.d.ts.map +1 -0
- package/dist/types/src/crud/graph.test.d.ts.map +1 -0
- package/dist/types/src/crud/index.d.ts +2 -0
- package/dist/types/src/crud/index.d.ts.map +1 -0
- package/dist/types/src/functions/agent/prompt.d.ts +73 -8
- package/dist/types/src/functions/agent/prompt.d.ts.map +1 -1
- package/dist/types/src/functions/discord/fetch-messages.d.ts +1 -1
- package/dist/types/src/functions/discord/index.d.ts +1 -1
- package/dist/types/src/functions/discord/index.d.ts.map +1 -1
- package/dist/types/src/functions/document/index.d.ts +3 -2
- package/dist/types/src/functions/document/index.d.ts.map +1 -1
- package/dist/types/src/functions/document/read.d.ts +1 -1
- package/dist/types/src/functions/document/read.d.ts.map +1 -1
- package/dist/types/src/functions/document/update.d.ts +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 +126 -125
- package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts.map +1 -1
- package/dist/types/src/functions/entity-extraction/index.d.ts +126 -125
- 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/exa/exa.d.ts +1 -1
- package/dist/types/src/functions/exa/mock.d.ts +1 -1
- package/dist/types/src/functions/github/fetch-prs.d.ts +1 -1
- package/dist/types/src/functions/github/fetch-prs.d.ts.map +1 -1
- package/dist/types/src/functions/linear/index.d.ts +2 -2
- package/dist/types/src/functions/linear/index.d.ts.map +1 -1
- package/dist/types/src/functions/linear/sync-issues.d.ts +2 -2
- package/dist/types/src/functions/linear/sync-issues.d.ts.map +1 -1
- package/dist/types/src/functions/research/document-create.d.ts +9 -0
- package/dist/types/src/functions/research/document-create.d.ts.map +1 -0
- package/dist/types/src/functions/research/index.d.ts +8 -6
- package/dist/types/src/functions/research/index.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 +4 -3
- package/dist/types/src/functions/research/research.d.ts.map +1 -1
- package/dist/types/src/functions/research/types.d.ts +2 -380
- package/dist/types/src/functions/research/types.d.ts.map +1 -1
- package/dist/types/src/functions/tasks/index.d.ts +2 -2
- package/dist/types/src/functions/tasks/index.d.ts.map +1 -1
- package/dist/types/src/functions/tasks/read.d.ts +1 -1
- package/dist/types/src/functions/tasks/read.d.ts.map +1 -1
- package/dist/types/src/functions/tasks/update.d.ts +1 -1
- package/dist/types/src/functions/tasks/update.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -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/{functions/research/create-document.d.ts → initiative/functions/update.d.ts} +3 -3
- 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 +43 -0
- package/dist/types/src/toolkits/AssistantToolkit.d.ts.map +1 -0
- package/dist/types/src/toolkits/AssistantToolkit.test.d.ts +2 -0
- package/dist/types/src/toolkits/AssistantToolkit.test.d.ts.map +1 -0
- package/dist/types/src/toolkits/SystemToolkit.d.ts +99 -0
- package/dist/types/src/toolkits/SystemToolkit.d.ts.map +1 -0
- package/dist/types/src/toolkits/index.d.ts +3 -0
- package/dist/types/src/toolkits/index.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +49 -33
- package/src/blueprints/design/design-blueprint.test.ts +17 -20
- package/src/blueprints/design/design-blueprint.ts +4 -6
- package/src/blueprints/design/index.ts +1 -1
- package/src/blueprints/discord/discord-blueprint.ts +4 -6
- package/src/blueprints/discord/index.ts +1 -1
- package/src/blueprints/linear/index.ts +1 -1
- package/src/blueprints/linear/linear-blueprint.ts +4 -6
- package/src/blueprints/planning/index.ts +1 -1
- package/src/blueprints/planning/planning-blueprint.test.ts +17 -20
- package/src/blueprints/planning/planning-blueprint.ts +4 -6
- package/src/blueprints/research/index.ts +1 -1
- package/src/blueprints/research/research-blueprint.ts +25 -19
- package/src/blueprints/testing.ts +2 -2
- package/src/blueprints/websearch/index.ts +2 -1
- package/src/blueprints/websearch/websearch-blueprint.ts +4 -6
- package/src/crud/graph.test.ts +46 -0
- package/src/{functions/research → crud}/graph.ts +32 -40
- package/src/crud/index.ts +5 -0
- package/src/experimental/feed.test.ts +12 -9
- package/src/functions/agent/prompt.ts +39 -22
- package/src/functions/discord/fetch-messages.test.ts +6 -7
- package/src/functions/discord/fetch-messages.ts +11 -10
- package/src/functions/document/index.ts +1 -0
- 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 +16 -23
- package/src/functions/entity-extraction/entity-extraction.ts +51 -31
- package/src/functions/exa/mock.ts +1 -1
- package/src/functions/github/fetch-prs.ts +3 -2
- package/src/functions/linear/linear.test.ts +18 -20
- package/src/functions/linear/sync-issues.ts +14 -12
- package/src/functions/research/document-create.ts +76 -0
- package/src/functions/research/index.ts +1 -2
- package/src/functions/research/research-graph.ts +13 -11
- package/src/functions/research/{instructions-research.tpl → research-instructions.tpl} +14 -6
- package/src/functions/research/research.conversations.json +1 -10714
- package/src/functions/research/research.test.ts +92 -161
- package/src/functions/research/research.ts +88 -54
- package/src/functions/research/types.ts +14 -12
- package/src/functions/tasks/read.ts +4 -3
- package/src/functions/tasks/update.ts +4 -3
- package/src/index.ts +2 -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 -0
- package/src/toolkits/AssistantToolkit.test.ts +94 -0
- package/src/toolkits/AssistantToolkit.ts +70 -0
- package/src/toolkits/SystemToolkit.ts +299 -0
- package/src/toolkits/index.ts +6 -0
- package/dist/types/src/functions/research/create-document.d.ts.map +0 -1
- package/dist/types/src/functions/research/graph.d.ts.map +0 -1
- package/dist/types/src/functions/research/graph.test.d.ts.map +0 -1
- 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/src/functions/research/create-document.ts +0 -69
- package/src/functions/research/graph.test.ts +0 -69
- /package/dist/types/src/{functions/research → crud}/graph.test.d.ts +0 -0
- /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
|
@@ -1,21 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__export
|
|
3
|
+
} from "./chunk-J5LGTIGS.mjs";
|
|
4
|
+
|
|
1
5
|
// src/blueprints/design/design-blueprint.ts
|
|
2
6
|
import { ToolId } from "@dxos/ai";
|
|
3
7
|
import { Blueprint } from "@dxos/blueprints";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
8
|
+
import { Ref as Ref6 } from "@dxos/echo";
|
|
9
|
+
import { Text as Text2 } from "@dxos/schema";
|
|
6
10
|
import { trim as trim5 } from "@dxos/util";
|
|
7
11
|
|
|
8
12
|
// src/functions/agent/prompt.ts
|
|
9
13
|
import * as Array2 from "effect/Array";
|
|
10
14
|
import * as Effect from "effect/Effect";
|
|
11
15
|
import * as Function from "effect/Function";
|
|
16
|
+
import * as Match from "effect/Match";
|
|
12
17
|
import * as Option from "effect/Option";
|
|
13
18
|
import * as Schema from "effect/Schema";
|
|
14
19
|
import { AiService, ConsolePrinter, ModelName } from "@dxos/ai";
|
|
15
20
|
import { AiSession, GenerationObserver, createToolkit } from "@dxos/assistant";
|
|
16
21
|
import { Prompt, Template } from "@dxos/blueprints";
|
|
17
22
|
import { Obj, Ref, Type } from "@dxos/echo";
|
|
18
|
-
import {
|
|
23
|
+
import { Database } from "@dxos/echo";
|
|
24
|
+
import { TracingService, defineFunction } from "@dxos/functions";
|
|
19
25
|
import { log } from "@dxos/log";
|
|
20
26
|
var __dxlog_file = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/agent/prompt.ts";
|
|
21
27
|
var DEFAULT_MODEL = "@anthropic/claude-opus-4-0";
|
|
@@ -34,10 +40,9 @@ var prompt_default = defineFunction({
|
|
|
34
40
|
* Input object or data.
|
|
35
41
|
* References get auto-resolved.
|
|
36
42
|
*/
|
|
37
|
-
input: Schema.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
})
|
|
43
|
+
input: Schema.Any.pipe(Schema.annotations({
|
|
44
|
+
title: "Input"
|
|
45
|
+
}))
|
|
41
46
|
}),
|
|
42
47
|
outputSchema: Schema.Any,
|
|
43
48
|
handler: Effect.fnUntraced(function* ({ data }) {
|
|
@@ -45,47 +50,39 @@ var prompt_default = defineFunction({
|
|
|
45
50
|
input: data.input
|
|
46
51
|
}, {
|
|
47
52
|
F: __dxlog_file,
|
|
48
|
-
L:
|
|
53
|
+
L: 41,
|
|
49
54
|
S: this,
|
|
50
55
|
C: (f, a) => f(...a)
|
|
51
56
|
});
|
|
52
|
-
const input = {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (Ref.isRef(value)) {
|
|
58
|
-
const object = yield* DatabaseService.load(value);
|
|
59
|
-
input[key] = Obj.toJSON(object);
|
|
60
|
-
} else {
|
|
61
|
-
input[key] = JSON.stringify(value);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
yield* DatabaseService.flush({
|
|
57
|
+
const input = yield* Match.value(data.input).pipe(Match.when((value2) => Ref.isRef(value2), Effect.fnUntraced(function* (ref) {
|
|
58
|
+
const object = yield* Database.Service.load(ref);
|
|
59
|
+
return Obj.toJSON(object);
|
|
60
|
+
})), Match.orElse(() => Effect.succeed(data.input)));
|
|
61
|
+
yield* Database.Service.flush({
|
|
65
62
|
indexes: true
|
|
66
63
|
});
|
|
67
|
-
const prompt = yield*
|
|
68
|
-
const systemPrompt = data.systemPrompt ? yield*
|
|
64
|
+
const prompt = yield* Database.Service.load(data.prompt);
|
|
65
|
+
const systemPrompt = data.systemPrompt ? yield* Database.Service.load(data.systemPrompt) : void 0;
|
|
69
66
|
yield* TracingService.emitStatus({
|
|
70
67
|
message: `Running ${prompt.id}`
|
|
71
68
|
});
|
|
72
69
|
log.info("starting agent", {
|
|
73
70
|
prompt: prompt.id,
|
|
74
|
-
input
|
|
71
|
+
input
|
|
75
72
|
}, {
|
|
76
73
|
F: __dxlog_file,
|
|
77
|
-
L:
|
|
74
|
+
L: 71,
|
|
78
75
|
S: this,
|
|
79
76
|
C: (f, a) => f(...a)
|
|
80
77
|
});
|
|
81
|
-
const blueprints = yield* Function.pipe(prompt.blueprints, Array2.appendAll(systemPrompt?.blueprints ?? []), Effect.forEach(
|
|
82
|
-
const objects = yield* Function.pipe(prompt.context, Array2.appendAll(systemPrompt?.context ?? []), Effect.forEach(DatabaseService.loadOption), Effect.map(Array2.filter(Option.isSome)), Effect.map(Array2.map((option) => option.value)));
|
|
78
|
+
const blueprints = yield* Function.pipe(prompt.blueprints, Array2.appendAll(systemPrompt?.blueprints ?? []), Effect.forEach(Database.Service.loadOption), Effect.map(Array2.filter(Option.isSome)), Effect.map(Array2.map((option) => option.value)));
|
|
83
79
|
const toolkit = yield* createToolkit({
|
|
84
80
|
blueprints
|
|
85
81
|
});
|
|
86
|
-
const
|
|
82
|
+
const objects = yield* Function.pipe(prompt.context, Array2.appendAll(systemPrompt?.context ?? []), Effect.forEach(Database.Service.loadOption), Effect.map(Array2.filter(Option.isSome)), Effect.map(Array2.map((option) => option.value)));
|
|
83
|
+
const promptInstructions = yield* Database.Service.load(prompt.instructions.source);
|
|
87
84
|
const promptText = Template.process(promptInstructions.content, input);
|
|
88
|
-
const systemInstructions = systemPrompt ? yield*
|
|
85
|
+
const systemInstructions = systemPrompt ? yield* Database.Service.load(systemPrompt.instructions.source) : void 0;
|
|
89
86
|
const systemText = systemInstructions ? Template.process(systemInstructions.content, {}) : void 0;
|
|
90
87
|
const session = new AiSession();
|
|
91
88
|
const result = yield* session.run({
|
|
@@ -123,7 +120,7 @@ import * as Schema2 from "effect/Schema";
|
|
|
123
120
|
import { Obj as Obj2 } from "@dxos/echo";
|
|
124
121
|
import { CredentialsService, TracingService as TracingService2, defineFunction as defineFunction2 } from "@dxos/functions";
|
|
125
122
|
import { log as log2 } from "@dxos/log";
|
|
126
|
-
import {
|
|
123
|
+
import { Message } from "@dxos/types";
|
|
127
124
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/discord/fetch-messages.ts";
|
|
128
125
|
var TimeRange = class extends Schema2.String.pipe(Schema2.pattern(/\d+(s|m|h|d)/)).annotations({
|
|
129
126
|
description: "Time range. 1d - 1 day, 2h - 2 hours, 30m - 30 minutes, 15s - 15 seconds.",
|
|
@@ -196,11 +193,11 @@ var fetch_messages_default = defineFunction2({
|
|
|
196
193
|
description: "Exclude messages from these usernames."
|
|
197
194
|
})
|
|
198
195
|
}),
|
|
199
|
-
handler: Effect2.fnUntraced(function* ({ data: { serverId, channelId, after, last, pageSize = 100, limit = DEFAULT_LIMIT, ignoreUsernames = DEFAULT_IGNORE_USERNAMES } }) {
|
|
200
|
-
if (!after && !
|
|
196
|
+
handler: Effect2.fnUntraced(function* ({ data: { serverId, channelId, after, last: last2, pageSize = 100, limit = DEFAULT_LIMIT, ignoreUsernames = DEFAULT_IGNORE_USERNAMES } }) {
|
|
197
|
+
if (!after && !last2) {
|
|
201
198
|
throw new Error("cannot specify both `after` and `last`");
|
|
202
199
|
}
|
|
203
|
-
const afterTs =
|
|
200
|
+
const afterTs = last2 ? Date.now() / 1e3 - TimeRange.toSeconds(last2) : after ?? DEFAULT_AFTER;
|
|
204
201
|
const rest = yield* DiscordREST;
|
|
205
202
|
let channels = [];
|
|
206
203
|
channels.push(...yield* rest.listGuildChannels(serverId));
|
|
@@ -213,7 +210,15 @@ var fetch_messages_default = defineFunction2({
|
|
|
213
210
|
throw new Error("no channels found");
|
|
214
211
|
}
|
|
215
212
|
for (const channel of channels) {
|
|
216
|
-
|
|
213
|
+
log2.info("channel", {
|
|
214
|
+
id: channel.id,
|
|
215
|
+
name: "name" in channel ? channel.name : void 0
|
|
216
|
+
}, {
|
|
217
|
+
F: __dxlog_file2,
|
|
218
|
+
L: 136,
|
|
219
|
+
S: this,
|
|
220
|
+
C: (f, a) => f(...a)
|
|
221
|
+
});
|
|
217
222
|
}
|
|
218
223
|
yield* TracingService2.emitStatus({
|
|
219
224
|
message: `Will fetch from channels: ${channels.length}`
|
|
@@ -274,7 +279,7 @@ var parseSnowflake = (snowflake) => {
|
|
|
274
279
|
const discordEpoch = 1420070400000n;
|
|
275
280
|
return new Date(Number((BigInt(snowflake) >> 22n) + discordEpoch));
|
|
276
281
|
};
|
|
277
|
-
var makeMessage = (message) => Obj2.make(
|
|
282
|
+
var makeMessage = (message) => Obj2.make(Message.Message, {
|
|
278
283
|
[Obj2.Meta]: {
|
|
279
284
|
keys: [
|
|
280
285
|
{
|
|
@@ -314,7 +319,8 @@ var Discord;
|
|
|
314
319
|
import * as Effect3 from "effect/Effect";
|
|
315
320
|
import * as Schema3 from "effect/Schema";
|
|
316
321
|
import { ArtifactId } from "@dxos/assistant";
|
|
317
|
-
import {
|
|
322
|
+
import { Database as Database2 } from "@dxos/echo";
|
|
323
|
+
import { defineFunction as defineFunction3 } from "@dxos/functions";
|
|
318
324
|
import { Markdown } from "@dxos/plugin-markdown/types";
|
|
319
325
|
var read_default = defineFunction3({
|
|
320
326
|
key: "dxos.org/function/markdown/read",
|
|
@@ -329,8 +335,8 @@ var read_default = defineFunction3({
|
|
|
329
335
|
content: Schema3.String
|
|
330
336
|
}),
|
|
331
337
|
handler: Effect3.fn(function* ({ data: { id } }) {
|
|
332
|
-
const doc = yield*
|
|
333
|
-
const { content } = yield*
|
|
338
|
+
const doc = yield* Database2.Service.resolve(ArtifactId.toDXN(id), Markdown.Document);
|
|
339
|
+
const { content } = yield* Database2.Service.load(doc.content);
|
|
334
340
|
return {
|
|
335
341
|
content
|
|
336
342
|
};
|
|
@@ -341,7 +347,8 @@ var read_default = defineFunction3({
|
|
|
341
347
|
import * as Effect4 from "effect/Effect";
|
|
342
348
|
import * as Schema4 from "effect/Schema";
|
|
343
349
|
import { ArtifactId as ArtifactId2 } from "@dxos/assistant";
|
|
344
|
-
import {
|
|
350
|
+
import { Database as Database3, Obj as Obj3 } from "@dxos/echo";
|
|
351
|
+
import { defineFunction as defineFunction4 } from "@dxos/functions";
|
|
345
352
|
import { Markdown as Markdown2 } from "@dxos/plugin-markdown/types";
|
|
346
353
|
var update_default = defineFunction4({
|
|
347
354
|
key: "dxos.org/function/markdown/update",
|
|
@@ -357,9 +364,11 @@ var update_default = defineFunction4({
|
|
|
357
364
|
}),
|
|
358
365
|
outputSchema: Schema4.Void,
|
|
359
366
|
handler: Effect4.fn(function* ({ data: { id, content } }) {
|
|
360
|
-
const doc = yield*
|
|
361
|
-
const text = yield*
|
|
362
|
-
text
|
|
367
|
+
const doc = yield* Database3.Service.resolve(ArtifactId2.toDXN(id), Markdown2.Document);
|
|
368
|
+
const text = yield* Database3.Service.load(doc.content);
|
|
369
|
+
Obj3.change(text, (t) => {
|
|
370
|
+
t.content = content;
|
|
371
|
+
});
|
|
363
372
|
})
|
|
364
373
|
});
|
|
365
374
|
|
|
@@ -378,97 +387,375 @@ import * as Predicate from "effect/Predicate";
|
|
|
378
387
|
import * as Schema11 from "effect/Schema";
|
|
379
388
|
import { AiService as AiService3 } from "@dxos/ai";
|
|
380
389
|
import { AiSession as AiSession3, makeToolExecutionServiceFromFunctions as makeToolExecutionServiceFromFunctions2, makeToolResolverFromFunctions as makeToolResolverFromFunctions2 } from "@dxos/assistant";
|
|
381
|
-
import { Filter as Filter2, Obj as
|
|
382
|
-
import {
|
|
390
|
+
import { Filter as Filter2, Obj as Obj8, Ref as Ref3, Type as Type4 } from "@dxos/echo";
|
|
391
|
+
import { Database as Database8 } from "@dxos/echo";
|
|
392
|
+
import { defineFunction as defineFunction9 } from "@dxos/functions";
|
|
393
|
+
import { FunctionInvocationServiceLayerTest } from "@dxos/functions-runtime/testing";
|
|
383
394
|
import { log as log5 } from "@dxos/log";
|
|
384
|
-
import {
|
|
395
|
+
import { LegacyOrganization as LegacyOrganization2, Message as Message2, Organization, Person as Person2 } from "@dxos/types";
|
|
385
396
|
import { trim as trim4 } from "@dxos/util";
|
|
386
397
|
|
|
387
|
-
// src/
|
|
398
|
+
// src/crud/graph.ts
|
|
399
|
+
import * as Tool from "@effect/ai/Tool";
|
|
400
|
+
import * as Toolkit from "@effect/ai/Toolkit";
|
|
401
|
+
import * as Context from "effect/Context";
|
|
388
402
|
import * as Effect5 from "effect/Effect";
|
|
403
|
+
import * as Function3 from "effect/Function";
|
|
404
|
+
import * as Option3 from "effect/Option";
|
|
389
405
|
import * as Schema5 from "effect/Schema";
|
|
390
|
-
import
|
|
391
|
-
import {
|
|
392
|
-
import {
|
|
406
|
+
import * as SchemaAST from "effect/SchemaAST";
|
|
407
|
+
import { Entity, Filter, Obj as Obj4, Query, Type as Type2 } from "@dxos/echo";
|
|
408
|
+
import { Database as Database4 } from "@dxos/echo";
|
|
409
|
+
import { ReferenceAnnotationId, RelationSourceDXNId, RelationSourceId, RelationTargetDXNId, RelationTargetId, createObject, getTypeAnnotation, getTypeIdentifierAnnotation } from "@dxos/echo/internal";
|
|
410
|
+
import { isEncodedReference } from "@dxos/echo-protocol";
|
|
411
|
+
import { mapAst } from "@dxos/effect";
|
|
412
|
+
import { ContextQueueService } from "@dxos/functions";
|
|
393
413
|
import { DXN, ObjectId } from "@dxos/keys";
|
|
394
414
|
import { log as log3 } from "@dxos/log";
|
|
415
|
+
import { deepMapValues, isNonNullable, trim } from "@dxos/util";
|
|
416
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/crud/graph.ts";
|
|
417
|
+
var Subgraph = Schema5.Struct({
|
|
418
|
+
/** Objects and relations. */
|
|
419
|
+
objects: Schema5.Array(Schema5.Any)
|
|
420
|
+
});
|
|
421
|
+
var findRelatedSchema = async (db, anchor) => {
|
|
422
|
+
const allSchemas = await db.graph.schemaRegistry.query().run();
|
|
423
|
+
return allSchemas.filter((schema) => {
|
|
424
|
+
if (getTypeAnnotation(schema)?.kind !== Entity.Kind.Relation) {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
return isSchemaAddressableByDxn(anchor, DXN.parse(getTypeAnnotation(schema).sourceSchema)) || isSchemaAddressableByDxn(anchor, DXN.parse(getTypeAnnotation(schema).targetSchema));
|
|
428
|
+
}).map((schema) => ({
|
|
429
|
+
kind: "relation",
|
|
430
|
+
schema
|
|
431
|
+
}));
|
|
432
|
+
};
|
|
433
|
+
var isSchemaAddressableByDxn = (schema, dxn) => {
|
|
434
|
+
if (getTypeIdentifierAnnotation(schema) === dxn.toString()) {
|
|
435
|
+
return true;
|
|
436
|
+
}
|
|
437
|
+
const t = dxn.asTypeDXN();
|
|
438
|
+
if (t) {
|
|
439
|
+
return t.type === Type2.getTypename(schema);
|
|
440
|
+
}
|
|
441
|
+
return false;
|
|
442
|
+
};
|
|
443
|
+
var LocalSearchToolkit = Toolkit.make(Tool.make("search_local_search", {
|
|
444
|
+
description: "Search the local database for information using a vector index",
|
|
445
|
+
parameters: {
|
|
446
|
+
query: Schema5.String.annotations({
|
|
447
|
+
description: "The query to search for. Could be a question or a topic or a set of keywords."
|
|
448
|
+
})
|
|
449
|
+
},
|
|
450
|
+
success: Schema5.Unknown,
|
|
451
|
+
failure: Schema5.Never,
|
|
452
|
+
dependencies: [
|
|
453
|
+
Database4.Service
|
|
454
|
+
]
|
|
455
|
+
}));
|
|
456
|
+
var LocalSearchHandler = LocalSearchToolkit.toLayer({
|
|
457
|
+
search_local_search: Effect5.fn(function* ({ query }) {
|
|
458
|
+
const objects = yield* Database4.Service.runQuery(Query.select(Filter.text(query, {
|
|
459
|
+
type: "vector"
|
|
460
|
+
})));
|
|
461
|
+
const results = [
|
|
462
|
+
...objects
|
|
463
|
+
];
|
|
464
|
+
const option = yield* Effect5.serviceOption(ContextQueueService);
|
|
465
|
+
if (Option3.isSome(option)) {
|
|
466
|
+
const queueObjects = yield* Effect5.promise(() => option.value.queue.queryObjects());
|
|
467
|
+
results.push(...queueObjects);
|
|
468
|
+
}
|
|
469
|
+
return trim`
|
|
470
|
+
<local_context>
|
|
471
|
+
${JSON.stringify(results, null, 2)}
|
|
472
|
+
</local_context>
|
|
473
|
+
`;
|
|
474
|
+
})
|
|
475
|
+
});
|
|
476
|
+
var GraphWriterSchema = class extends Context.Tag("@dxos/assistant/GraphWriterSchema")() {
|
|
477
|
+
};
|
|
478
|
+
var makeGraphWriterToolkit = ({ schema }) => {
|
|
479
|
+
return Toolkit.make(Tool.make("graph_writer", {
|
|
480
|
+
description: "Write to the local graph database",
|
|
481
|
+
parameters: createExtractionSchema(schema).fields,
|
|
482
|
+
success: Schema5.Unknown,
|
|
483
|
+
failure: Schema5.Never,
|
|
484
|
+
dependencies: [
|
|
485
|
+
Database4.Service,
|
|
486
|
+
ContextQueueService
|
|
487
|
+
]
|
|
488
|
+
}).annotateContext(Context.make(GraphWriterSchema, {
|
|
489
|
+
schema
|
|
490
|
+
})));
|
|
491
|
+
};
|
|
492
|
+
var makeGraphWriterHandler = (toolkit, { onAppend } = {}) => {
|
|
493
|
+
const { schema } = Context.get(toolkit.tools.graph_writer.annotations, GraphWriterSchema);
|
|
494
|
+
return toolkit.toLayer({
|
|
495
|
+
graph_writer: Effect5.fn(function* (input) {
|
|
496
|
+
const { db } = yield* Database4.Service;
|
|
497
|
+
const { queue } = yield* ContextQueueService;
|
|
498
|
+
const data = yield* Effect5.promise(() => sanitizeObjects(schema, input, db, queue));
|
|
499
|
+
yield* Effect5.promise(() => queue.append(data));
|
|
500
|
+
const dxns = data.map((obj) => Obj4.getDXN(obj));
|
|
501
|
+
onAppend?.(dxns);
|
|
502
|
+
return dxns;
|
|
503
|
+
})
|
|
504
|
+
});
|
|
505
|
+
};
|
|
506
|
+
var createExtractionSchema = (types) => {
|
|
507
|
+
return Schema5.Struct({
|
|
508
|
+
...Object.fromEntries(types.map(preprocessSchema).map((schema, index) => [
|
|
509
|
+
`objects_${getSanitizedSchemaName(types[index])}`,
|
|
510
|
+
Schema5.optional(Schema5.Array(schema)).annotations({
|
|
511
|
+
description: `The objects of type: ${Type2.getDXN(types[index])?.asTypeDXN().type}. ${SchemaAST.getDescriptionAnnotation(types[index].ast).pipe(Option3.getOrElse(() => ""))}`
|
|
512
|
+
})
|
|
513
|
+
]))
|
|
514
|
+
});
|
|
515
|
+
};
|
|
516
|
+
var getSanitizedSchemaName = (schema) => {
|
|
517
|
+
return Type2.getDXN(schema).asTypeDXN().type.replaceAll(/[^a-zA-Z0-9]+/g, "_");
|
|
518
|
+
};
|
|
519
|
+
var sanitizeObjects = async (types, data, db, queue) => {
|
|
520
|
+
const entries = types.map((type) => data[`objects_${getSanitizedSchemaName(type)}`]?.map((object) => ({
|
|
521
|
+
data: object,
|
|
522
|
+
schema: type
|
|
523
|
+
})) ?? []).flat();
|
|
524
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
525
|
+
const existingIds = /* @__PURE__ */ new Set();
|
|
526
|
+
const enitties = /* @__PURE__ */ new Map();
|
|
527
|
+
const resolveId = (id) => {
|
|
528
|
+
if (ObjectId.isValid(id)) {
|
|
529
|
+
existingIds.add(id);
|
|
530
|
+
return DXN.fromLocalObjectId(id);
|
|
531
|
+
}
|
|
532
|
+
const mappedId = idMap.get(id);
|
|
533
|
+
if (mappedId) {
|
|
534
|
+
return DXN.fromLocalObjectId(mappedId);
|
|
535
|
+
}
|
|
536
|
+
return void 0;
|
|
537
|
+
};
|
|
538
|
+
const res = entries.map((entry) => {
|
|
539
|
+
if (ObjectId.isValid(entry.data.id)) {
|
|
540
|
+
return entry;
|
|
541
|
+
}
|
|
542
|
+
idMap.set(entry.data.id, ObjectId.random());
|
|
543
|
+
entry.data.id = idMap.get(entry.data.id);
|
|
544
|
+
return entry;
|
|
545
|
+
}).map((entry) => {
|
|
546
|
+
const data2 = deepMapValues(entry.data, (value2, recurse) => {
|
|
547
|
+
if (isEncodedReference(value2)) {
|
|
548
|
+
const ref = value2["/"];
|
|
549
|
+
const id = resolveId(ref);
|
|
550
|
+
if (id) {
|
|
551
|
+
return {
|
|
552
|
+
"/": id.toString()
|
|
553
|
+
};
|
|
554
|
+
} else {
|
|
555
|
+
return {
|
|
556
|
+
"/": `search:?q=${encodeURIComponent(ref)}`
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return recurse(value2);
|
|
561
|
+
});
|
|
562
|
+
if (Entity.getKind(entry.schema) === "relation") {
|
|
563
|
+
const sourceDxn = resolveId(data2.source);
|
|
564
|
+
if (!sourceDxn) {
|
|
565
|
+
log3.warn("source not found", {
|
|
566
|
+
source: data2.source
|
|
567
|
+
}, {
|
|
568
|
+
F: __dxlog_file3,
|
|
569
|
+
L: 273,
|
|
570
|
+
S: void 0,
|
|
571
|
+
C: (f, a) => f(...a)
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
const targetDxn = resolveId(data2.target);
|
|
575
|
+
if (!targetDxn) {
|
|
576
|
+
log3.warn("target not found", {
|
|
577
|
+
target: data2.target
|
|
578
|
+
}, {
|
|
579
|
+
F: __dxlog_file3,
|
|
580
|
+
L: 277,
|
|
581
|
+
S: void 0,
|
|
582
|
+
C: (f, a) => f(...a)
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
delete data2.source;
|
|
586
|
+
delete data2.target;
|
|
587
|
+
data2[RelationSourceDXNId] = sourceDxn;
|
|
588
|
+
data2[RelationTargetDXNId] = targetDxn;
|
|
589
|
+
}
|
|
590
|
+
return {
|
|
591
|
+
data: data2,
|
|
592
|
+
schema: entry.schema
|
|
593
|
+
};
|
|
594
|
+
}).filter((object) => !existingIds.has(object.data.id));
|
|
595
|
+
const dbObjects = await db.query(Query.select(Filter.id(...existingIds))).run();
|
|
596
|
+
const queueObjects = await queue?.getObjectsById([
|
|
597
|
+
...existingIds
|
|
598
|
+
]) ?? [];
|
|
599
|
+
const objects = [
|
|
600
|
+
...dbObjects,
|
|
601
|
+
...queueObjects
|
|
602
|
+
].filter(isNonNullable);
|
|
603
|
+
log3.info("objects", {
|
|
604
|
+
dbObjects,
|
|
605
|
+
queueObjects,
|
|
606
|
+
existingIds
|
|
607
|
+
}, {
|
|
608
|
+
F: __dxlog_file3,
|
|
609
|
+
L: 298,
|
|
610
|
+
S: void 0,
|
|
611
|
+
C: (f, a) => f(...a)
|
|
612
|
+
});
|
|
613
|
+
const missing = Array.from(existingIds).filter((id) => !objects.some((object) => object.id === id));
|
|
614
|
+
if (missing.length > 0) {
|
|
615
|
+
throw new Error(`Object IDs do not point to existing objects: ${missing.join(", ")}`);
|
|
616
|
+
}
|
|
617
|
+
return res.flatMap(({ data: data2, schema }) => {
|
|
618
|
+
let skip = false;
|
|
619
|
+
if (RelationSourceDXNId in data2) {
|
|
620
|
+
const id = data2[RelationSourceDXNId].asEchoDXN()?.echoId;
|
|
621
|
+
const obj = objects.find((object) => object.id === id) ?? enitties.get(id);
|
|
622
|
+
if (obj) {
|
|
623
|
+
delete data2[RelationSourceDXNId];
|
|
624
|
+
data2[RelationSourceId] = obj;
|
|
625
|
+
} else {
|
|
626
|
+
skip = true;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
if (RelationTargetDXNId in data2) {
|
|
630
|
+
const id = data2[RelationTargetDXNId].asEchoDXN()?.echoId;
|
|
631
|
+
const obj = objects.find((object) => object.id === id) ?? enitties.get(id);
|
|
632
|
+
if (obj) {
|
|
633
|
+
delete data2[RelationTargetDXNId];
|
|
634
|
+
data2[RelationTargetId] = obj;
|
|
635
|
+
} else {
|
|
636
|
+
skip = true;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
if (!skip) {
|
|
640
|
+
const obj = createObject(schema, data2);
|
|
641
|
+
enitties.set(obj.id, obj);
|
|
642
|
+
return [
|
|
643
|
+
obj
|
|
644
|
+
];
|
|
645
|
+
}
|
|
646
|
+
return [];
|
|
647
|
+
});
|
|
648
|
+
};
|
|
649
|
+
var SoftRef = Schema5.Struct({
|
|
650
|
+
"/": Schema5.String
|
|
651
|
+
}).annotations({
|
|
652
|
+
description: "Reference to another object."
|
|
653
|
+
});
|
|
654
|
+
var preprocessSchema = (schema) => {
|
|
655
|
+
const isRelationSchema = Entity.getKind(schema) === "relation";
|
|
656
|
+
const go = (ast, visited = /* @__PURE__ */ new Set()) => {
|
|
657
|
+
if (visited.has(ast)) {
|
|
658
|
+
return ast;
|
|
659
|
+
}
|
|
660
|
+
visited.add(ast);
|
|
661
|
+
if (SchemaAST.getAnnotation(ast, ReferenceAnnotationId).pipe(Option3.isSome)) {
|
|
662
|
+
return SoftRef.ast;
|
|
663
|
+
}
|
|
664
|
+
return mapAst(ast, (child) => go(child, visited));
|
|
665
|
+
};
|
|
666
|
+
return Schema5.make(mapAst(schema.ast, (ast) => go(ast))).pipe(Schema5.omit("id"), Schema5.extend(Schema5.Struct({
|
|
667
|
+
id: Schema5.String.annotations({
|
|
668
|
+
description: "The id of this object. Come up with a unique id based on your judgement."
|
|
669
|
+
})
|
|
670
|
+
})), isRelationSchema ? Schema5.extend(Schema5.Struct({
|
|
671
|
+
source: Schema5.String.annotations({
|
|
672
|
+
description: "The id of the source object for this relation."
|
|
673
|
+
}),
|
|
674
|
+
target: Schema5.String.annotations({
|
|
675
|
+
description: "The id of the target object for this relation."
|
|
676
|
+
})
|
|
677
|
+
})) : Function3.identity);
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
// src/functions/research/document-create.ts
|
|
681
|
+
import * as Effect6 from "effect/Effect";
|
|
682
|
+
import * as Schema6 from "effect/Schema";
|
|
683
|
+
import { ArtifactId as ArtifactId3 } from "@dxos/assistant";
|
|
684
|
+
import { Obj as Obj5, Relation } from "@dxos/echo";
|
|
685
|
+
import { Database as Database5 } from "@dxos/echo";
|
|
686
|
+
import { TracingService as TracingService3, defineFunction as defineFunction5 } from "@dxos/functions";
|
|
687
|
+
import { log as log4 } from "@dxos/log";
|
|
395
688
|
import { Markdown as Markdown3 } from "@dxos/plugin-markdown/types";
|
|
396
|
-
import {
|
|
397
|
-
import { trim } from "@dxos/util";
|
|
398
|
-
var
|
|
399
|
-
var
|
|
400
|
-
key: "dxos.org/function/research/create
|
|
689
|
+
import { HasSubject } from "@dxos/types";
|
|
690
|
+
import { trim as trim2 } from "@dxos/util";
|
|
691
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/research/document-create.ts";
|
|
692
|
+
var document_create_default = defineFunction5({
|
|
693
|
+
key: "dxos.org/function/research/document-create",
|
|
401
694
|
name: "Create research document",
|
|
402
695
|
description: "Creates a note summarizing the research.",
|
|
403
|
-
inputSchema:
|
|
404
|
-
|
|
405
|
-
description:
|
|
696
|
+
inputSchema: Schema6.Struct({
|
|
697
|
+
subject: ArtifactId3.annotations({
|
|
698
|
+
description: trim2`
|
|
699
|
+
ID of the object (organization, contact, etc.) for which the research was performed.
|
|
700
|
+
`
|
|
406
701
|
}),
|
|
407
|
-
|
|
408
|
-
description:
|
|
702
|
+
name: Schema6.String.annotations({
|
|
703
|
+
description: "Name of the document."
|
|
704
|
+
}),
|
|
705
|
+
content: Schema6.String.annotations({
|
|
706
|
+
description: trim2`
|
|
409
707
|
Content of the note.
|
|
410
708
|
Supports (and are prefered) references to research objects using @ syntax and <object> tags (refer to research blueprint instructions).
|
|
411
709
|
`
|
|
412
|
-
}),
|
|
413
|
-
// TODO(dmaretskyi): Use a specialized type for this (e.g., ArtifactId renamed as RefFromLLM).
|
|
414
|
-
target: Schema5.String.annotations({
|
|
415
|
-
description: trim`
|
|
416
|
-
Id of the object (organization, contact, etc.) for which the research was performed.
|
|
417
|
-
This must be a ulid.
|
|
418
|
-
`
|
|
419
710
|
})
|
|
420
711
|
}),
|
|
421
|
-
outputSchema:
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
712
|
+
outputSchema: Schema6.Struct({
|
|
713
|
+
document: ArtifactId3.annotations({
|
|
714
|
+
description: "DXN of the created document."
|
|
715
|
+
})
|
|
716
|
+
}),
|
|
717
|
+
handler: Effect6.fnUntraced(function* ({ data: { subject, name, content } }) {
|
|
718
|
+
log4.info("Creating research document", {
|
|
719
|
+
subject,
|
|
425
720
|
name,
|
|
426
721
|
content
|
|
427
722
|
}, {
|
|
428
|
-
F:
|
|
723
|
+
F: __dxlog_file4,
|
|
429
724
|
L: 43,
|
|
430
725
|
S: this,
|
|
431
726
|
C: (f, a) => f(...a)
|
|
432
727
|
});
|
|
433
|
-
yield*
|
|
728
|
+
yield* Database5.Service.flush({
|
|
434
729
|
indexes: true
|
|
435
730
|
});
|
|
436
731
|
yield* TracingService3.emitStatus({
|
|
437
732
|
message: "Creating research document..."
|
|
438
733
|
});
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
L: 47,
|
|
442
|
-
S: this,
|
|
443
|
-
A: [
|
|
444
|
-
"ObjectId.isValid(target)",
|
|
445
|
-
""
|
|
446
|
-
]
|
|
447
|
-
});
|
|
448
|
-
const targetObj = yield* DatabaseService4.resolve(DXN.fromLocalObjectId(target));
|
|
449
|
-
const doc = yield* DatabaseService4.add(Markdown3.makeDocument({
|
|
734
|
+
const target = yield* Database5.Service.resolve(ArtifactId3.toDXN(subject));
|
|
735
|
+
const object = yield* Database5.Service.add(Markdown3.make({
|
|
450
736
|
name,
|
|
451
737
|
content
|
|
452
738
|
}));
|
|
453
|
-
yield*
|
|
454
|
-
[Relation.Source]:
|
|
455
|
-
[Relation.Target]:
|
|
739
|
+
yield* Database5.Service.add(Relation.make(HasSubject.HasSubject, {
|
|
740
|
+
[Relation.Source]: object,
|
|
741
|
+
[Relation.Target]: target,
|
|
456
742
|
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
457
743
|
}));
|
|
458
|
-
yield*
|
|
744
|
+
yield* Database5.Service.flush({
|
|
459
745
|
indexes: true
|
|
460
746
|
});
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
content
|
|
747
|
+
log4.info("Created research document", {
|
|
748
|
+
subject,
|
|
749
|
+
object
|
|
465
750
|
}, {
|
|
466
|
-
F:
|
|
467
|
-
L:
|
|
751
|
+
F: __dxlog_file4,
|
|
752
|
+
L: 70,
|
|
468
753
|
S: this,
|
|
469
754
|
C: (f, a) => f(...a)
|
|
470
755
|
});
|
|
471
|
-
return {
|
|
756
|
+
return {
|
|
757
|
+
document: Obj5.getDXN(object).toString()
|
|
758
|
+
};
|
|
472
759
|
})
|
|
473
760
|
});
|
|
474
761
|
|
|
@@ -477,36 +764,42 @@ import * as Toolkit2 from "@effect/ai/Toolkit";
|
|
|
477
764
|
import * as AnthropicTool from "@effect/ai-anthropic/AnthropicTool";
|
|
478
765
|
import * as Array6 from "effect/Array";
|
|
479
766
|
import * as Effect10 from "effect/Effect";
|
|
767
|
+
import * as Function4 from "effect/Function";
|
|
480
768
|
import * as Layer3 from "effect/Layer";
|
|
769
|
+
import * as Option4 from "effect/Option";
|
|
481
770
|
import * as Schema10 from "effect/Schema";
|
|
771
|
+
import * as String10 from "effect/String";
|
|
482
772
|
import { AiService as AiService2, ConsolePrinter as ConsolePrinter2 } from "@dxos/ai";
|
|
483
773
|
import { AiSession as AiSession2, GenerationObserver as GenerationObserver2, createToolkit as createToolkit2, makeToolExecutionServiceFromFunctions, makeToolResolverFromFunctions } from "@dxos/assistant";
|
|
484
|
-
import {
|
|
485
|
-
import {
|
|
486
|
-
import {
|
|
774
|
+
import { Template as Template2 } from "@dxos/blueprints";
|
|
775
|
+
import { Entity as Entity2, Obj as Obj7 } from "@dxos/echo";
|
|
776
|
+
import { Database as Database7 } from "@dxos/echo";
|
|
777
|
+
import { TracingService as TracingService4, defineFunction as defineFunction8 } from "@dxos/functions";
|
|
778
|
+
import { FunctionInvocationServiceLayerTestMocked } from "@dxos/functions-runtime/testing";
|
|
779
|
+
import { Person } from "@dxos/types";
|
|
487
780
|
import { trim as trim3 } from "@dxos/util";
|
|
488
781
|
|
|
489
782
|
// src/functions/exa/exa.ts
|
|
490
|
-
import * as
|
|
491
|
-
import * as
|
|
783
|
+
import * as Effect7 from "effect/Effect";
|
|
784
|
+
import * as Schema7 from "effect/Schema";
|
|
492
785
|
import Exa from "exa-js";
|
|
493
786
|
import { CredentialsService as CredentialsService2, defineFunction as defineFunction6 } from "@dxos/functions";
|
|
494
787
|
var exa_default = defineFunction6({
|
|
495
788
|
key: "dxos.org/function/exa",
|
|
496
789
|
name: "Exa",
|
|
497
790
|
description: "Search the web for information",
|
|
498
|
-
inputSchema:
|
|
499
|
-
query:
|
|
791
|
+
inputSchema: Schema7.Struct({
|
|
792
|
+
query: Schema7.String.annotations({
|
|
500
793
|
description: "The query to search for."
|
|
501
794
|
})
|
|
502
795
|
}),
|
|
503
|
-
outputSchema:
|
|
504
|
-
handler:
|
|
796
|
+
outputSchema: Schema7.Unknown,
|
|
797
|
+
handler: Effect7.fnUntraced(function* ({ data: { query } }) {
|
|
505
798
|
const credential = yield* CredentialsService2.getCredential({
|
|
506
799
|
service: "exa.ai"
|
|
507
800
|
});
|
|
508
801
|
const exa = new Exa(credential.apiKey);
|
|
509
|
-
const context = yield*
|
|
802
|
+
const context = yield* Effect7.promise(async () => exa.searchAndContents(query, {
|
|
510
803
|
type: "auto",
|
|
511
804
|
text: {
|
|
512
805
|
maxCharacters: 3e3
|
|
@@ -518,11 +811,11 @@ var exa_default = defineFunction6({
|
|
|
518
811
|
});
|
|
519
812
|
|
|
520
813
|
// src/functions/exa/mock.ts
|
|
521
|
-
import * as
|
|
522
|
-
import * as
|
|
814
|
+
import * as Effect8 from "effect/Effect";
|
|
815
|
+
import * as Schema8 from "effect/Schema";
|
|
523
816
|
import { defineFunction as defineFunction7 } from "@dxos/functions";
|
|
524
817
|
|
|
525
|
-
// src/
|
|
818
|
+
// src/functions/exa/data/exa-search-1748337321991.ts
|
|
526
819
|
var exa_search_1748337321991_default = {
|
|
527
820
|
requestId: "324936368a74f4db978982172bc18a6c",
|
|
528
821
|
autopromptString: "AI personal knowledge management tools projects 2024",
|
|
@@ -678,7 +971,7 @@ var exa_search_1748337321991_default = {
|
|
|
678
971
|
}
|
|
679
972
|
};
|
|
680
973
|
|
|
681
|
-
// src/
|
|
974
|
+
// src/functions/exa/data/exa-search-1748337331526.ts
|
|
682
975
|
var exa_search_1748337331526_default = {
|
|
683
976
|
requestId: "0dc12e344fa649884456960ca1a54954",
|
|
684
977
|
autopromptString: "PKM software artificial intelligence integration open source projects",
|
|
@@ -901,7 +1194,7 @@ npm run tauri dev
|
|
|
901
1194
|
}
|
|
902
1195
|
};
|
|
903
1196
|
|
|
904
|
-
// src/
|
|
1197
|
+
// src/functions/exa/data/exa-search-1748337344119.ts
|
|
905
1198
|
var exa_search_1748337344119_default = {
|
|
906
1199
|
requestId: "32df0c541f9883180b35e04caece4374",
|
|
907
1200
|
autopromptString: "open source AI knowledge management projects features comparison 2024",
|
|
@@ -1000,414 +1293,133 @@ var exa_search_1748337344119_default = {
|
|
|
1000
1293
|
author: "",
|
|
1001
1294
|
score: 0.37101393938064575,
|
|
1002
1295
|
text: "SciPhi simplifies building, deploying, and optimizing Retrieval-Augmented Generation (RAG) systems, empowering developers to focus on AI innovation. Added on: Social & Email: Platform: SciPhi SciPhi simplifies building, deploying, and optimizing Retrieval-Augmented Generation (RAG) systems, empowering developers to focus on AI innovation. Added on: Social & Email: Platform: What is SciPhi? SciPhi is an open-source platform designed to simplify the building, deploying, and scaling of Retrieval-Augmented Generation (RAG) systems. It provides an end-to-end solution for developers, enabling them to focus on AI innovation without worrying about the underlying infrastructure. With tools for automated knowledge graph extraction, document and user management, and robust observability, SciPhi ensures efficient and optimized RAG system deployment. Who will use SciPhi? Developers AI Engineers Data Scientists Tech Startups Research Institutions How to use the SciPhi? Step1: Visit the SciPhi website. Step2: Sign up for an account or log in. Step3: Access the platform's dashboard. Step4: Follow guides to build and deploy your RAG system. Step5: Use tools for knowledge graph extraction and management. Step6: Optimize and monitor your system using provided observability features. SciPhi's Core Features & Benefits The Core Features of SciPhi End-to-End RAG System Deployment Automated Knowledge Graph Extraction Document and User Management Robust Observability Tools The Benefits of SciPhi Simplifies AI Development Speeds Up Deployment Time Enhances System Optimization Reduces Infrastructure Complexity SciPhi's Main Use Cases & Applications Building RAG Systems for AI Applications Deploying Knowledge Graphs Managing Large Document Repositories Optimizing AI System Performance FAQs of SciPhi SciPhi is an open-source platform designed to simplify building, deploying, and optimizing Retrieval-Augmented Generation (RAG) systems. SciPhi is intended for developers, AI engineers, data scientists, tech startups, and research institutions. Core features include end-to-end RAG system deployment, automated knowledge graph extraction, document and user management, and robust observability tools. Visit the SciPhi website, sign up for an account, and follow the guides to build and deploy your RAG system. SciPhi supports web platforms. SciPhi simplifies AI development, speeds up deployment time, enhances system optimization, and reduces infrastructure complexity. Yes, alternatives include LangChain, LlamaIndex, Haystack, and Flower. SciPhi supports building RAG systems for AI applications, deploying knowledge graphs, managing large document repositories, and optimizing AI system performance. You can reach out to their support team via their support email provided on the website. SciPhi offers both free and paid plans. Details on pricing can be found on their website. SciPhi Company Information Website: https://www.sciphi.ai Company Name: SciPhi Support Email: [ema",
|
|
1003
|
-
image: "https://cdn-image.creati.ai/ai-tools/product-image/sciphi.webp",
|
|
1004
|
-
favicon: "https://cdn-image.creati.ai/image/Creatiai.ico"
|
|
1005
|
-
},
|
|
1006
|
-
{
|
|
1007
|
-
id: "https://helpjuice.com/blog/open-source-knowledge-base",
|
|
1008
|
-
title: "The 12 Best Open Source Knowledge Base Software for 2024",
|
|
1009
|
-
url: "https://helpjuice.com/blog/open-source-knowledge-base",
|
|
1010
|
-
author: "Zeeshan Khan",
|
|
1011
|
-
text: "\n \n \n \n \n At Helpjuice / \n \n #Software & Alternatives\n May 15 2025 \n 11m read \n \n \n \n \n On the hunt for the perfect knowledge base software that\u2019s open source? This post will walk you through the best options for your business. \n \n \n \n \n There\u2019s no denying that a knowledge base can make a major impact on your organization.\xA0 Whether it's to help provide better support to your customers or to enable your employees to find the information they need to do their job, a finely-tuned knowledge base can make all the difference when it comes to how knowledge and information flows through your business. And with plenty of options on the market out there, there\u2019s certainly no shortage of open source knowledge base software. But how can you tell you\u2019re not investing time into installing and learning new software that your team won't use anyway? How can you avoid the time and effort put into an open source option that you later determine to not be a good fit for your needs?\xA0 It\u2019s simple\u2014do a little research beforehand. We know, we know\u2014you don\u2019t have endless time to invest in that kind of thing (what with a business to run and all). That\u2019s why we\u2019ve created a helpful list of the must-consider open source knowledge base software that companies of all niches, industries, and sizes should consider.\xA0 We\u2019re even throwing in a little helpful knowledge that should equip you with the information needed to choose the right software for you\u2014like what knowledge base software is in the first place, the benefits of open source software, and how to address your unique needs as a company to choose the right software for you.\xA0 Want to skip ahead on some of the basics of open-source knowledge base software?\xA0 Be our guest.\xA0 The best open source knowledge base software includes: \n BookStack \n OpenKM \n myBase \n eXo \n PHPKB \n Documize \n DocuWiki \n phpMyFAQ \n MediaWiki \n xWiki \n TWiki \n TiddlyWiki \n What is an Open Source Knowledge Base? Before we dive into which open-source knowledge base software you should consider for your business, we should probably ensure we\u2019re on the same page about what exactly open-source knowledge base software is.\xA0 First things first, let\u2019s start with the term knowledge base. A knowledge base is a central place that allows structured storage of information where users can search for and access this information. \xA0Knowledge base software should be the key tool that helps make this process seamless, simplified, and efficient. Knowledge base software is designed to help you create and manage your knowledge base to the best of your ability. this usually includes setting up the knowledge base architecture, creating and editing documentation, searching, and analyzing your knowledge base, and more. Ideally, this is the irreplaceable piece of the puzzle that operates your entire knowledge management system that helps orchestrate, manage, and optimize the flow of knowledge within your organization.\xA0 That part seems pretty clear, right? Next, we\u2019ll move on to",
|
|
1012
|
-
image: "https://static.helpjuice.com/helpjuice_production/uploads/upload/image/4752/direct/1636499945090-Open%20Source%20Knowledge%20Base%20Software.jpg",
|
|
1013
|
-
favicon: "https://static.helpjuice.com/assets/favicon-32x32-161f2153235b710a8ed7b9233ed6b195936bdb57bf1310e720f7fea79547cf9d.png"
|
|
1014
|
-
}
|
|
1015
|
-
],
|
|
1016
|
-
costDollars: {
|
|
1017
|
-
total: 0.015,
|
|
1018
|
-
search: {
|
|
1019
|
-
neural: 5e-3
|
|
1020
|
-
},
|
|
1021
|
-
contents: {
|
|
1022
|
-
text: 0.01
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
};
|
|
1026
|
-
|
|
1027
|
-
// src/testing/data/index.ts
|
|
1028
|
-
var SEARCH_RESULTS = [
|
|
1029
|
-
exa_search_1748337321991_default,
|
|
1030
|
-
exa_search_1748337331526_default,
|
|
1031
|
-
exa_search_1748337344119_default
|
|
1032
|
-
];
|
|
1033
|
-
|
|
1034
|
-
// src/functions/exa/mock.ts
|
|
1035
|
-
var mock_default = defineFunction7({
|
|
1036
|
-
key: "dxos.org/function/exa-mock",
|
|
1037
|
-
name: "Exa mock",
|
|
1038
|
-
description: "Search the web for information",
|
|
1039
|
-
inputSchema: Schema7.Struct({
|
|
1040
|
-
query: Schema7.String.annotations({
|
|
1041
|
-
description: "The query to search for."
|
|
1042
|
-
})
|
|
1043
|
-
}),
|
|
1044
|
-
outputSchema: Schema7.Unknown,
|
|
1045
|
-
handler: Effect7.fnUntraced(function* ({ data: { query } }) {
|
|
1046
|
-
const result = SEARCH_RESULTS.reduce((closest, current) => {
|
|
1047
|
-
if (!current.autopromptString) {
|
|
1048
|
-
return closest;
|
|
1049
|
-
}
|
|
1050
|
-
if (!closest) {
|
|
1051
|
-
return current;
|
|
1052
|
-
}
|
|
1053
|
-
const dist1 = levenshteinDistance(query, current.autopromptString);
|
|
1054
|
-
const dist2 = levenshteinDistance(query, closest.autopromptString || "");
|
|
1055
|
-
const weight1 = dist1 / Math.max(query.length, current.autopromptString.length);
|
|
1056
|
-
const weight2 = dist2 / Math.max(query.length, closest.autopromptString?.length || 0);
|
|
1057
|
-
return weight1 < weight2 ? current : closest;
|
|
1058
|
-
}, null);
|
|
1059
|
-
return result;
|
|
1060
|
-
})
|
|
1061
|
-
});
|
|
1062
|
-
var levenshteinDistance = (str1, str2) => {
|
|
1063
|
-
const m = str1.length;
|
|
1064
|
-
const n = str2.length;
|
|
1065
|
-
const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0));
|
|
1066
|
-
for (let i = 0; i <= m; i++) {
|
|
1067
|
-
dp[i][0] = i;
|
|
1068
|
-
}
|
|
1069
|
-
for (let j = 0; j <= n; j++) {
|
|
1070
|
-
dp[0][j] = j;
|
|
1071
|
-
}
|
|
1072
|
-
for (let i = 1; i <= m; i++) {
|
|
1073
|
-
for (let j = 1; j <= n; j++) {
|
|
1074
|
-
dp[i][j] = str1[i - 1] === str2[j - 1] ? dp[i - 1][j - 1] : Math.min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1;
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
return dp[m][n];
|
|
1078
|
-
};
|
|
1079
|
-
|
|
1080
|
-
// src/functions/research/graph.ts
|
|
1081
|
-
import * as Tool from "@effect/ai/Tool";
|
|
1082
|
-
import * as Toolkit from "@effect/ai/Toolkit";
|
|
1083
|
-
import * as Context from "effect/Context";
|
|
1084
|
-
import * as Effect8 from "effect/Effect";
|
|
1085
|
-
import * as Function3 from "effect/Function";
|
|
1086
|
-
import * as Option3 from "effect/Option";
|
|
1087
|
-
import * as Schema8 from "effect/Schema";
|
|
1088
|
-
import * as SchemaAST from "effect/SchemaAST";
|
|
1089
|
-
import { Obj as Obj3 } from "@dxos/echo";
|
|
1090
|
-
import { Filter, Query } from "@dxos/echo";
|
|
1091
|
-
import { EntityKind, ObjectId as ObjectId2, ReferenceAnnotationId, RelationSourceDXNId, RelationSourceId, RelationTargetDXNId, RelationTargetId, create, getEntityKind, getSchemaDXN, getSchemaTypename, getTypeAnnotation, getTypeIdentifierAnnotation } from "@dxos/echo/internal";
|
|
1092
|
-
import { isEncodedReference } from "@dxos/echo-protocol";
|
|
1093
|
-
import { mapAst } from "@dxos/effect";
|
|
1094
|
-
import { ContextQueueService, DatabaseService as DatabaseService5 } from "@dxos/functions";
|
|
1095
|
-
import { DXN as DXN2 } from "@dxos/keys";
|
|
1096
|
-
import { log as log4 } from "@dxos/log";
|
|
1097
|
-
import { deepMapValues, isNonNullable, trim as trim2 } from "@dxos/util";
|
|
1098
|
-
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/research/graph.ts";
|
|
1099
|
-
var Subgraph = Schema8.Struct({
|
|
1100
|
-
/** Objects and relations. */
|
|
1101
|
-
objects: Schema8.Array(Schema8.Any)
|
|
1102
|
-
});
|
|
1103
|
-
var findRelatedSchema = async (db, anchor) => {
|
|
1104
|
-
const allSchemas = [
|
|
1105
|
-
...db.graph.schemaRegistry.schemas
|
|
1106
|
-
];
|
|
1107
|
-
return allSchemas.filter((schema) => {
|
|
1108
|
-
if (getTypeAnnotation(schema)?.kind !== EntityKind.Relation) {
|
|
1109
|
-
return false;
|
|
1110
|
-
}
|
|
1111
|
-
return isSchemaAddressableByDxn(anchor, DXN2.parse(getTypeAnnotation(schema).sourceSchema)) || isSchemaAddressableByDxn(anchor, DXN2.parse(getTypeAnnotation(schema).targetSchema));
|
|
1112
|
-
}).map((schema) => ({
|
|
1113
|
-
schema,
|
|
1114
|
-
kind: "relation"
|
|
1115
|
-
}));
|
|
1116
|
-
};
|
|
1117
|
-
var isSchemaAddressableByDxn = (schema, dxn) => {
|
|
1118
|
-
if (getTypeIdentifierAnnotation(schema) === dxn.toString()) {
|
|
1119
|
-
return true;
|
|
1120
|
-
}
|
|
1121
|
-
const t = dxn.asTypeDXN();
|
|
1122
|
-
if (t) {
|
|
1123
|
-
return t.type === getSchemaTypename(schema);
|
|
1124
|
-
}
|
|
1125
|
-
return false;
|
|
1126
|
-
};
|
|
1127
|
-
var LocalSearchToolkit = Toolkit.make(Tool.make("search_local_search", {
|
|
1128
|
-
description: "Search the local database for information using a vector index",
|
|
1129
|
-
parameters: {
|
|
1130
|
-
query: Schema8.String.annotations({
|
|
1131
|
-
description: "The query to search for. Could be a question or a topic or a set of keywords."
|
|
1132
|
-
})
|
|
1133
|
-
},
|
|
1134
|
-
success: Schema8.Unknown,
|
|
1135
|
-
failure: Schema8.Never,
|
|
1136
|
-
dependencies: [
|
|
1137
|
-
DatabaseService5
|
|
1138
|
-
]
|
|
1139
|
-
}));
|
|
1140
|
-
var LocalSearchHandler = LocalSearchToolkit.toLayer({
|
|
1141
|
-
search_local_search: Effect8.fn(function* ({ query }) {
|
|
1142
|
-
const { objects } = yield* DatabaseService5.runQuery(Query.select(Filter.text(query, {
|
|
1143
|
-
type: "vector"
|
|
1144
|
-
})));
|
|
1145
|
-
const results = [
|
|
1146
|
-
...objects
|
|
1147
|
-
];
|
|
1148
|
-
const option = yield* Effect8.serviceOption(ContextQueueService);
|
|
1149
|
-
if (Option3.isSome(option)) {
|
|
1150
|
-
const queueObjects = yield* Effect8.promise(() => option.value.queue.queryObjects());
|
|
1151
|
-
results.push(...queueObjects);
|
|
1152
|
-
}
|
|
1153
|
-
return trim2`
|
|
1154
|
-
<local_context>
|
|
1155
|
-
${JSON.stringify(results, null, 2)}
|
|
1156
|
-
</local_context>
|
|
1157
|
-
`;
|
|
1158
|
-
})
|
|
1159
|
-
});
|
|
1160
|
-
var GraphWriterSchema = class extends Context.Tag("@dxos/assistant/GraphWriterSchema")() {
|
|
1161
|
-
};
|
|
1162
|
-
var makeGraphWriterToolkit = ({ schema }) => {
|
|
1163
|
-
return Toolkit.make(Tool.make("graph_writer", {
|
|
1164
|
-
description: "Write to the local graph database",
|
|
1165
|
-
parameters: createExtractionSchema(schema).fields,
|
|
1166
|
-
success: Schema8.Unknown,
|
|
1167
|
-
failure: Schema8.Never,
|
|
1168
|
-
dependencies: [
|
|
1169
|
-
DatabaseService5,
|
|
1170
|
-
ContextQueueService
|
|
1171
|
-
]
|
|
1172
|
-
}).annotateContext(Context.make(GraphWriterSchema, {
|
|
1173
|
-
schema
|
|
1174
|
-
})));
|
|
1175
|
-
};
|
|
1176
|
-
var makeGraphWriterHandler = (toolkit, { onAppend } = {}) => {
|
|
1177
|
-
const { schema } = Context.get(toolkit.tools.graph_writer.annotations, GraphWriterSchema);
|
|
1178
|
-
return toolkit.toLayer({
|
|
1179
|
-
graph_writer: Effect8.fn(function* (input) {
|
|
1180
|
-
const { db } = yield* DatabaseService5;
|
|
1181
|
-
const { queue } = yield* ContextQueueService;
|
|
1182
|
-
const data = yield* Effect8.promise(() => sanitizeObjects(schema, input, db, queue));
|
|
1183
|
-
yield* Effect8.promise(() => queue.append(data));
|
|
1184
|
-
const dxns = data.map((obj) => Obj3.getDXN(obj));
|
|
1185
|
-
onAppend?.(dxns);
|
|
1186
|
-
return dxns;
|
|
1187
|
-
})
|
|
1188
|
-
});
|
|
1189
|
-
};
|
|
1190
|
-
var createExtractionSchema = (types) => {
|
|
1191
|
-
return Schema8.Struct({
|
|
1192
|
-
...Object.fromEntries(types.map(preprocessSchema).map((schema, index) => [
|
|
1193
|
-
`objects_${getSanitizedSchemaName(types[index])}`,
|
|
1194
|
-
Schema8.optional(Schema8.Array(schema)).annotations({
|
|
1195
|
-
description: `The objects of type: ${getSchemaDXN(types[index])?.asTypeDXN().type}. ${SchemaAST.getDescriptionAnnotation(types[index].ast).pipe(Option3.getOrElse(() => ""))}`
|
|
1196
|
-
})
|
|
1197
|
-
]))
|
|
1198
|
-
});
|
|
1199
|
-
};
|
|
1200
|
-
var getSanitizedSchemaName = (schema) => {
|
|
1201
|
-
return getSchemaDXN(schema).asTypeDXN().type.replaceAll(/[^a-zA-Z0-9]+/g, "_");
|
|
1202
|
-
};
|
|
1203
|
-
var sanitizeObjects = async (types, data, db, queue) => {
|
|
1204
|
-
const entries = types.map((type) => data[`objects_${getSanitizedSchemaName(type)}`]?.map((object) => ({
|
|
1205
|
-
data: object,
|
|
1206
|
-
schema: type
|
|
1207
|
-
})) ?? []).flat();
|
|
1208
|
-
const idMap = /* @__PURE__ */ new Map();
|
|
1209
|
-
const existingIds = /* @__PURE__ */ new Set();
|
|
1210
|
-
const enitties = /* @__PURE__ */ new Map();
|
|
1211
|
-
const resolveId = (id) => {
|
|
1212
|
-
if (ObjectId2.isValid(id)) {
|
|
1213
|
-
existingIds.add(id);
|
|
1214
|
-
return DXN2.fromLocalObjectId(id);
|
|
1215
|
-
}
|
|
1216
|
-
const mappedId = idMap.get(id);
|
|
1217
|
-
if (mappedId) {
|
|
1218
|
-
return DXN2.fromLocalObjectId(mappedId);
|
|
1219
|
-
}
|
|
1220
|
-
return void 0;
|
|
1221
|
-
};
|
|
1222
|
-
const res = entries.map((entry) => {
|
|
1223
|
-
if (ObjectId2.isValid(entry.data.id)) {
|
|
1224
|
-
return entry;
|
|
1225
|
-
}
|
|
1226
|
-
idMap.set(entry.data.id, ObjectId2.random());
|
|
1227
|
-
entry.data.id = idMap.get(entry.data.id);
|
|
1228
|
-
return entry;
|
|
1229
|
-
}).map((entry) => {
|
|
1230
|
-
const data2 = deepMapValues(entry.data, (value, recurse) => {
|
|
1231
|
-
if (isEncodedReference(value)) {
|
|
1232
|
-
const ref = value["/"];
|
|
1233
|
-
const id = resolveId(ref);
|
|
1234
|
-
if (id) {
|
|
1235
|
-
return {
|
|
1236
|
-
"/": id.toString()
|
|
1237
|
-
};
|
|
1238
|
-
} else {
|
|
1239
|
-
return {
|
|
1240
|
-
"/": `search:?q=${encodeURIComponent(ref)}`
|
|
1241
|
-
};
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
return recurse(value);
|
|
1245
|
-
});
|
|
1246
|
-
if (getEntityKind(entry.schema) === "relation") {
|
|
1247
|
-
const sourceDxn = resolveId(data2.source);
|
|
1248
|
-
if (!sourceDxn) {
|
|
1249
|
-
log4.warn("source not found", {
|
|
1250
|
-
source: data2.source
|
|
1251
|
-
}, {
|
|
1252
|
-
F: __dxlog_file4,
|
|
1253
|
-
L: 281,
|
|
1254
|
-
S: void 0,
|
|
1255
|
-
C: (f, a) => f(...a)
|
|
1256
|
-
});
|
|
1257
|
-
}
|
|
1258
|
-
const targetDxn = resolveId(data2.target);
|
|
1259
|
-
if (!targetDxn) {
|
|
1260
|
-
log4.warn("target not found", {
|
|
1261
|
-
target: data2.target
|
|
1262
|
-
}, {
|
|
1263
|
-
F: __dxlog_file4,
|
|
1264
|
-
L: 285,
|
|
1265
|
-
S: void 0,
|
|
1266
|
-
C: (f, a) => f(...a)
|
|
1267
|
-
});
|
|
1268
|
-
}
|
|
1269
|
-
delete data2.source;
|
|
1270
|
-
delete data2.target;
|
|
1271
|
-
data2[RelationSourceDXNId] = sourceDxn;
|
|
1272
|
-
data2[RelationTargetDXNId] = targetDxn;
|
|
1273
|
-
}
|
|
1274
|
-
return {
|
|
1275
|
-
data: data2,
|
|
1276
|
-
schema: entry.schema
|
|
1277
|
-
};
|
|
1278
|
-
}).filter((object) => !existingIds.has(object.data.id));
|
|
1279
|
-
const { objects: dbObjects } = await db.query(Query.select(Filter.ids(...existingIds))).run();
|
|
1280
|
-
const queueObjects = await queue?.getObjectsById([
|
|
1281
|
-
...existingIds
|
|
1282
|
-
]) ?? [];
|
|
1283
|
-
const objects = [
|
|
1284
|
-
...dbObjects,
|
|
1285
|
-
...queueObjects
|
|
1286
|
-
].filter(isNonNullable);
|
|
1287
|
-
log4.info("objects", {
|
|
1288
|
-
dbObjects,
|
|
1289
|
-
queueObjects,
|
|
1290
|
-
existingIds
|
|
1291
|
-
}, {
|
|
1292
|
-
F: __dxlog_file4,
|
|
1293
|
-
L: 306,
|
|
1294
|
-
S: void 0,
|
|
1295
|
-
C: (f, a) => f(...a)
|
|
1296
|
-
});
|
|
1297
|
-
const missing = Array.from(existingIds).filter((id) => !objects.some((object) => object.id === id));
|
|
1298
|
-
if (missing.length > 0) {
|
|
1299
|
-
throw new Error(`Object IDs do not point to existing objects: ${missing.join(", ")}`);
|
|
1300
|
-
}
|
|
1301
|
-
return res.flatMap(({ data: data2, schema }) => {
|
|
1302
|
-
let skip = false;
|
|
1303
|
-
if (RelationSourceDXNId in data2) {
|
|
1304
|
-
const id = data2[RelationSourceDXNId].asEchoDXN()?.echoId;
|
|
1305
|
-
const obj = objects.find((object) => object.id === id) ?? enitties.get(id);
|
|
1306
|
-
if (obj) {
|
|
1307
|
-
delete data2[RelationSourceDXNId];
|
|
1308
|
-
data2[RelationSourceId] = obj;
|
|
1309
|
-
} else {
|
|
1310
|
-
skip = true;
|
|
1311
|
-
}
|
|
1312
|
-
}
|
|
1313
|
-
if (RelationTargetDXNId in data2) {
|
|
1314
|
-
const id = data2[RelationTargetDXNId].asEchoDXN()?.echoId;
|
|
1315
|
-
const obj = objects.find((object) => object.id === id) ?? enitties.get(id);
|
|
1316
|
-
if (obj) {
|
|
1317
|
-
delete data2[RelationTargetDXNId];
|
|
1318
|
-
data2[RelationTargetId] = obj;
|
|
1319
|
-
} else {
|
|
1320
|
-
skip = true;
|
|
1321
|
-
}
|
|
1296
|
+
image: "https://cdn-image.creati.ai/ai-tools/product-image/sciphi.webp",
|
|
1297
|
+
favicon: "https://cdn-image.creati.ai/image/Creatiai.ico"
|
|
1298
|
+
},
|
|
1299
|
+
{
|
|
1300
|
+
id: "https://helpjuice.com/blog/open-source-knowledge-base",
|
|
1301
|
+
title: "The 12 Best Open Source Knowledge Base Software for 2024",
|
|
1302
|
+
url: "https://helpjuice.com/blog/open-source-knowledge-base",
|
|
1303
|
+
author: "Zeeshan Khan",
|
|
1304
|
+
text: "\n \n \n \n \n At Helpjuice / \n \n #Software & Alternatives\n May 15 2025 \n 11m read \n \n \n \n \n On the hunt for the perfect knowledge base software that\u2019s open source? This post will walk you through the best options for your business. \n \n \n \n \n There\u2019s no denying that a knowledge base can make a major impact on your organization.\xA0 Whether it's to help provide better support to your customers or to enable your employees to find the information they need to do their job, a finely-tuned knowledge base can make all the difference when it comes to how knowledge and information flows through your business. And with plenty of options on the market out there, there\u2019s certainly no shortage of open source knowledge base software. But how can you tell you\u2019re not investing time into installing and learning new software that your team won't use anyway? How can you avoid the time and effort put into an open source option that you later determine to not be a good fit for your needs?\xA0 It\u2019s simple\u2014do a little research beforehand. We know, we know\u2014you don\u2019t have endless time to invest in that kind of thing (what with a business to run and all). That\u2019s why we\u2019ve created a helpful list of the must-consider open source knowledge base software that companies of all niches, industries, and sizes should consider.\xA0 We\u2019re even throwing in a little helpful knowledge that should equip you with the information needed to choose the right software for you\u2014like what knowledge base software is in the first place, the benefits of open source software, and how to address your unique needs as a company to choose the right software for you.\xA0 Want to skip ahead on some of the basics of open-source knowledge base software?\xA0 Be our guest.\xA0 The best open source knowledge base software includes: \n BookStack \n OpenKM \n myBase \n eXo \n PHPKB \n Documize \n DocuWiki \n phpMyFAQ \n MediaWiki \n xWiki \n TWiki \n TiddlyWiki \n What is an Open Source Knowledge Base? Before we dive into which open-source knowledge base software you should consider for your business, we should probably ensure we\u2019re on the same page about what exactly open-source knowledge base software is.\xA0 First things first, let\u2019s start with the term knowledge base. A knowledge base is a central place that allows structured storage of information where users can search for and access this information. \xA0Knowledge base software should be the key tool that helps make this process seamless, simplified, and efficient. Knowledge base software is designed to help you create and manage your knowledge base to the best of your ability. this usually includes setting up the knowledge base architecture, creating and editing documentation, searching, and analyzing your knowledge base, and more. Ideally, this is the irreplaceable piece of the puzzle that operates your entire knowledge management system that helps orchestrate, manage, and optimize the flow of knowledge within your organization.\xA0 That part seems pretty clear, right? Next, we\u2019ll move on to",
|
|
1305
|
+
image: "https://static.helpjuice.com/helpjuice_production/uploads/upload/image/4752/direct/1636499945090-Open%20Source%20Knowledge%20Base%20Software.jpg",
|
|
1306
|
+
favicon: "https://static.helpjuice.com/assets/favicon-32x32-161f2153235b710a8ed7b9233ed6b195936bdb57bf1310e720f7fea79547cf9d.png"
|
|
1322
1307
|
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1308
|
+
],
|
|
1309
|
+
costDollars: {
|
|
1310
|
+
total: 0.015,
|
|
1311
|
+
search: {
|
|
1312
|
+
neural: 5e-3
|
|
1313
|
+
},
|
|
1314
|
+
contents: {
|
|
1315
|
+
text: 0.01
|
|
1329
1316
|
}
|
|
1330
|
-
|
|
1331
|
-
});
|
|
1317
|
+
}
|
|
1332
1318
|
};
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1319
|
+
|
|
1320
|
+
// src/functions/exa/data/index.ts
|
|
1321
|
+
var SEARCH_RESULTS = [
|
|
1322
|
+
exa_search_1748337321991_default,
|
|
1323
|
+
exa_search_1748337331526_default,
|
|
1324
|
+
exa_search_1748337344119_default
|
|
1325
|
+
];
|
|
1326
|
+
|
|
1327
|
+
// src/functions/exa/mock.ts
|
|
1328
|
+
var mock_default = defineFunction7({
|
|
1329
|
+
key: "dxos.org/function/exa-mock",
|
|
1330
|
+
name: "Exa mock",
|
|
1331
|
+
description: "Search the web for information",
|
|
1332
|
+
inputSchema: Schema8.Struct({
|
|
1333
|
+
query: Schema8.String.annotations({
|
|
1334
|
+
description: "The query to search for."
|
|
1335
|
+
})
|
|
1336
|
+
}),
|
|
1337
|
+
outputSchema: Schema8.Unknown,
|
|
1338
|
+
handler: Effect8.fnUntraced(function* ({ data: { query } }) {
|
|
1339
|
+
const result = SEARCH_RESULTS.reduce((closest, current) => {
|
|
1340
|
+
if (!current.autopromptString) {
|
|
1341
|
+
return closest;
|
|
1342
|
+
}
|
|
1343
|
+
if (!closest) {
|
|
1344
|
+
return current;
|
|
1345
|
+
}
|
|
1346
|
+
const dist1 = levenshteinDistance(query, current.autopromptString);
|
|
1347
|
+
const dist2 = levenshteinDistance(query, closest.autopromptString || "");
|
|
1348
|
+
const weight1 = dist1 / Math.max(query.length, current.autopromptString.length);
|
|
1349
|
+
const weight2 = dist2 / Math.max(query.length, closest.autopromptString?.length || 0);
|
|
1350
|
+
return weight1 < weight2 ? current : closest;
|
|
1351
|
+
}, null);
|
|
1352
|
+
return result;
|
|
1353
|
+
})
|
|
1337
1354
|
});
|
|
1338
|
-
var
|
|
1339
|
-
const
|
|
1340
|
-
const
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1355
|
+
var levenshteinDistance = (str1, str2) => {
|
|
1356
|
+
const m = str1.length;
|
|
1357
|
+
const n = str2.length;
|
|
1358
|
+
const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0));
|
|
1359
|
+
for (let i = 0; i <= m; i++) {
|
|
1360
|
+
dp[i][0] = i;
|
|
1361
|
+
}
|
|
1362
|
+
for (let j = 0; j <= n; j++) {
|
|
1363
|
+
dp[0][j] = j;
|
|
1364
|
+
}
|
|
1365
|
+
for (let i = 1; i <= m; i++) {
|
|
1366
|
+
for (let j = 1; j <= n; j++) {
|
|
1367
|
+
dp[i][j] = str1[i - 1] === str2[j - 1] ? dp[i - 1][j - 1] : Math.min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1;
|
|
1347
1368
|
}
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
return Schema8.make(mapAst(schema.ast, (ast) => go(ast))).pipe(Schema8.omit("id"), Schema8.extend(Schema8.Struct({
|
|
1351
|
-
id: Schema8.String.annotations({
|
|
1352
|
-
description: "The id of this object. Come up with a unique id based on your judgement."
|
|
1353
|
-
})
|
|
1354
|
-
})), isRelationSchema ? Schema8.extend(Schema8.Struct({
|
|
1355
|
-
source: Schema8.String.annotations({
|
|
1356
|
-
description: "The id of the source object for this relation."
|
|
1357
|
-
}),
|
|
1358
|
-
target: Schema8.String.annotations({
|
|
1359
|
-
description: "The id of the target object for this relation."
|
|
1360
|
-
})
|
|
1361
|
-
})) : Function3.identity);
|
|
1369
|
+
}
|
|
1370
|
+
return dp[m][n];
|
|
1362
1371
|
};
|
|
1363
1372
|
|
|
1364
|
-
// raw-loader:/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/research/instructions-research.tpl?raw
|
|
1365
|
-
var instructions_research_default = "You are the Research Agent.\n\nThe Research Agent is an expert assistant that conducts in-depth research using real-time web search.\nThe Research Agent outputs results in a structured format matching the schema provided.\n\nThe Research Agent is equipped with the ability to:\n\n- Generate precise and effective search queries \n- Request web pages by query (through a `web_search` tool)\n- Read the full content of retrieved pages\n- Synthesize accurate, clear, and structured answers using reliable information from the retrieved content\n- Search the local database for information using a vector index (through a `local_search` tool)\n\nThe Research Agent always follows these principles:\n\n- Relevance First: The Research Agent only returns facts supported by content in retrieved web pages. The Research Agent never fabricates or guesses information.\n- Summarize, Don't Copy: The Research Agent synthesizes and rephrases content in its own words. The Research Agent quotes only when necessary.\n- Multiple Sources: The Research Agent cross-references at least 2 sources before drawing conclusions, unless the information is directly stated and non-controversial.\n- Transparency: The Research Agent mentions which sources were used and explains how it arrived at conclusions.\n- Accuracy Over Brevity: The Research Agent prefers detailed, technically accurate explanations over shallow summaries.\n- The Research Agent admits uncertainty rather than misleading.\n- The Research Agent picks the most concrete schema types for extracted information.\n- The Research Agent fills schema fields completely with information it is confident about, and omits fields it is not confident about.\n- When outputting results, the Research Agent adds extra data that fits the schema even if not directly related to the user's question.\n- The Research Agent creates relations and references between new objects found and what's already in the database.\n- The Research Agent does not create objects that are already in the database.\n- The Research Agent re-uses existing object IDs as references when enriching existing objects.\n- The Research Agent ALWAYS calls the `graph_writer` at the end to save the data. This conversation will be deleted, so only the data written to the graph will be preserved.\n\nThe Research Agent may be asked for:\n\n- Technical explanations\n- Literature reviews \n- Comparisons\n- Emerging trends\n- Implementation strategies\n\nThe Research Agent begins by interpreting the user's request, then:\n\nThe Research Agent breaks it into sub-questions (if applicable).\n\nFor each sub-question, the Research Agent generates a clear, concise web search query.\n\nThe Research Agent uses `web_search`(query) to retrieve information.\n\nThe Research Agent extracts and synthesizes relevant answers.\n\nThe Research Agent's output includes:\n\n- A clear, structured answer to the user's question\n- A citation list or link list of sources used\n\nOptionally, the Research Agent provides follow-up suggestions or questions for deeper inquiry.\n\nHere's how the Research Agent operates:\n\n1. The Research Agent analyzes the user's request and identifies key topics to search for (3 or more), printing them out.\n2. The Research Agent performs a web search for each topic.\n3. The Research Agent reads and analyzes results, cross references information from multiple sources, and represents conflicting information as ranges of possible values.\n\n4. The Research Agent searches the local database for information using a vector index that might link to the user's question.\n6. The Research Agent creates relations and references between new objects and existing database objects when related, using existing object IDs as references.\n7. The Research Agent selects the most concrete schema types for extracted information, using multiple types as needed, and prints its decision and reasoning.\n5. The Research Agent creates a clear, structured answer to the user's question.\n8. The Research Agent submits results using the specific schema.\n\nIMPORTANT:\n\n- The Research Agent always runs the `local_search` tool to search the local database at least once before submitting results.\n- The Research Agent does not create objects that already exist in the database.\n- Ids that are not in the database are human-readable strings like `ivan_zhao_1`.\n\nStatus reporting:\n\nThe Research Agent reports its status frequently using the `<status>` tags: <status>Searching for Google Founders</status>\nThe Research Agent reports its status in-between each tool call and before submitting results.\n\n<example>\n\nBased on my research, I can now provide information about Google and it's founders.\n\nThe following objects are already in the database, I will not submit them again, but I'll re-use their IDs as references:\n\n- 01JWRDEHPB5TT2JQQQC15038BT Google\n- 01JWRDEHPA14CYW2NW9FAH6DJJ Larry Page\n- 01JWRDEHPBN0BBJP57B9S108W6 Sergey Brin\n\nI will use the following schema to construct new objects:\n\n- type:dxos.org/type/Organization for Alphabet Inc.\n- type:dxos.org/type/Person for Ivan Zhao\n- type:dxos.org/type/Person for Simon Last\n- dxn:type:dxos.org/relation/Employer for Ivan's employer\n- dxn:type:dxos.org/relation/Employer for Simon's employer\n\n<status>Formatting results</status>\n\n</example>";
|
|
1366
|
-
|
|
1367
1373
|
// src/functions/research/research-graph.ts
|
|
1368
1374
|
import * as Effect9 from "effect/Effect";
|
|
1369
1375
|
import * as Layer2 from "effect/Layer";
|
|
1370
1376
|
import * as Schema9 from "effect/Schema";
|
|
1371
|
-
import { Obj as
|
|
1377
|
+
import { Obj as Obj6, Query as Query2, Ref as Ref2, Type as Type3 } from "@dxos/echo";
|
|
1378
|
+
import { Database as Database6 } from "@dxos/echo";
|
|
1379
|
+
import { SystemTypeAnnotation } from "@dxos/echo/internal";
|
|
1372
1380
|
import { Queue } from "@dxos/echo-db";
|
|
1373
|
-
import { ContextQueueService as ContextQueueService2,
|
|
1381
|
+
import { ContextQueueService as ContextQueueService2, QueueService } from "@dxos/functions";
|
|
1374
1382
|
var ResearchGraph = Schema9.Struct({
|
|
1375
|
-
queue:
|
|
1376
|
-
}).pipe(
|
|
1383
|
+
queue: Type3.Ref(Queue)
|
|
1384
|
+
}).pipe(Type3.object({
|
|
1377
1385
|
typename: "dxos.org/type/ResearchGraph",
|
|
1378
1386
|
version: "0.1.0"
|
|
1379
|
-
}));
|
|
1387
|
+
}), SystemTypeAnnotation.set(true));
|
|
1380
1388
|
var queryResearchGraph = Effect9.fn("queryResearchGraph")(function* () {
|
|
1381
|
-
const
|
|
1389
|
+
const objects = yield* Database6.Service.runQuery(Query2.type(ResearchGraph));
|
|
1382
1390
|
return objects.at(0);
|
|
1383
1391
|
});
|
|
1384
1392
|
var createResearchGraph = Effect9.fn("createResearchGraph")(function* () {
|
|
1385
1393
|
const queue = yield* QueueService.createQueue();
|
|
1386
|
-
return yield*
|
|
1394
|
+
return yield* Database6.Service.add(Obj6.make(ResearchGraph, {
|
|
1387
1395
|
queue: Ref2.fromDXN(queue.dxn)
|
|
1388
1396
|
}));
|
|
1389
1397
|
});
|
|
1390
1398
|
var contextQueueLayerFromResearchGraph = Layer2.unwrapEffect(Effect9.gen(function* () {
|
|
1391
1399
|
const researchGraph = (yield* queryResearchGraph()) ?? (yield* createResearchGraph());
|
|
1392
|
-
const researchQueue = yield*
|
|
1400
|
+
const researchQueue = yield* Database6.Service.load(researchGraph.queue);
|
|
1393
1401
|
return ContextQueueService2.layer(researchQueue);
|
|
1394
1402
|
}));
|
|
1395
1403
|
|
|
1404
|
+
// raw-loader:/__w/dxos/dxos/packages/core/assistant-toolkit/src/functions/research/research-instructions.tpl?raw
|
|
1405
|
+
var research_instructions_default = "You are the Research Agent.\n\nThe Research Agent is an expert assistant that conducts in-depth research using real-time web search.\nThe Research Agent outputs results in a structured format matching the schema provided.\n\nThe Research Agent is equipped with the ability to:\n\n- Generate precise and effective search queries \n- Request web pages by query.\n- Synthesize accurate, clear, and structured answers using reliable information from the retrieved content\n{{#if entityExtraction}}\n- Search the local database for information using a vector index (through a `local_search` tool)\n{{/if}}\n\nThe Research Agent always follows these principles:\n\n- Relevance First: The Research Agent only returns facts supported by content in retrieved web pages. The Research Agent never fabricates or guesses information.\n- Summarize, Don't Copy: The Research Agent synthesizes and rephrases content in its own words. The Research Agent quotes only when necessary.\n- Multiple Sources: The Research Agent cross-references at least 2 sources before drawing conclusions, unless the information is directly stated and non-controversial.\n- Transparency: The Research Agent mentions which sources were used and explains how it arrived at conclusions.\n- Accuracy Over Brevity: The Research Agent prefers detailed, technically accurate explanations over shallow summaries.\n- The Research Agent admits uncertainty rather than misleading.\n{{#if entityExtraction}}\n- The Research Agent picks the most concrete schema types for extracted information.\n- The Research Agent fills schema fields completely with information it is confident about, and omits fields it is not confident about.\n- When outputting results, the Research Agent adds extra data that fits the schema even if not directly related to the user's question.\n- The Research Agent creates relations and references between new objects found and what's already in the database.\n- The Research Agent does not create objects that are already in the database.\n- The Research Agent re-uses existing object IDs as references when enriching existing objects.\n- The Research Agent ALWAYS calls the `graph_writer` at the end to save the data. This conversation will be deleted, so only the data written to the graph will be preserved.\n{{/if}}\n\nThe Research Agent may be asked for:\n\n- Technical explanations\n- Literature reviews \n- Comparisons\n- Emerging trends\n- Implementation strategies\n\nThe Research Agent begins by interpreting the user's request, then:\n\nThe Research Agent breaks it into sub-questions (if applicable).\n\nFor each sub-question, the Research Agent generates a clear, concise web search query.\n\nThe Research Agent extracts and synthesizes relevant answers.\n\nThe Research Agent's output includes:\n\n- A clear, structured answer to the user's question\n- A citation list or link list of sources used\n\nOptionally, the Research Agent provides follow-up suggestions or questions for deeper inquiry.\n\nHere's how the Research Agent operates:\n\n1. The Research Agent analyzes the user's request and identifies key topics to search for (3 or more), printing them out.\n2. The Research Agent performs a web search for each topic.\n3. The Research Agent reads and analyzes results, cross references information from multiple sources, and represents conflicting information as ranges of possible values.\n\n{{#if entityExtraction}}\n4. The Research Agent searches the local database for information using a vector index that might link to the user's question.\n6. The Research Agent creates relations and references between new objects and existing database objects when related, using existing object IDs as references.\n7. The Research Agent selects the most concrete schema types for extracted information, using multiple types as needed, and prints its decision and reasoning.\n5. The Research Agent creates a clear, structured answer to the user's question.\n8. The Research Agent submits results using the specific schema.\n{{/if}}\n\n{{#if entityExtraction}}\nIMPORTANT:\n- The Research Agent always runs the `local_search` tool to search the local database at least once before submitting results.\n- The Research Agent does not create objects that already exist in the database.\n- Ids that are not in the database are human-readable strings like `ivan_zhao_1`.\n{{/if}}\n\nStatus reporting:\n\nThe Research Agent reports its status frequently using the `<status>` tags: <status>Searching for Google Founders</status>\nThe Research Agent reports its status in-between each tool call and before submitting results.\n\n{{#if entityExtraction}}\n<example>\n\nBased on my research, I can now provide information about Google and it's founders.\n\nThe following objects are already in the database, I will not submit them again, but I'll re-use their IDs as references:\n\n- 01JWRDEHPB5TT2JQQQC15038BT Google\n- 01JWRDEHPA14CYW2NW9FAH6DJJ Larry Page\n- 01JWRDEHPBN0BBJP57B9S108W6 Sergey Brin\n\nI will use the following schema to construct new objects:\n\n- type:dxos.org/type/Organization for Alphabet Inc.\n- type:dxos.org/type/Person for Ivan Zhao\n- type:dxos.org/type/Person for Simon Last\n- dxn:type:dxos.org/relation/Employer for Ivan's employer\n- dxn:type:dxos.org/relation/Employer for Simon's employer\n\n<status>Formatting results</status>\n\n</example>\n{{/if}}\n\nLast content block is the full research note -- the result of the research.\n";
|
|
1406
|
+
|
|
1396
1407
|
// src/functions/research/types.ts
|
|
1397
|
-
import {
|
|
1408
|
+
import { Text } from "@dxos/schema";
|
|
1409
|
+
import { Event, HasConnection, HasRelationship, LegacyOrganization, LegacyPerson, Project, Task } from "@dxos/types";
|
|
1398
1410
|
var ResearchDataTypes = [
|
|
1399
1411
|
// Objects
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
DataType3.Task,
|
|
1405
|
-
DataType3.Text,
|
|
1412
|
+
Event.Event,
|
|
1413
|
+
LegacyOrganization,
|
|
1414
|
+
Task.Task,
|
|
1415
|
+
Text.Text,
|
|
1406
1416
|
// Relations
|
|
1407
|
-
// TODO(wittjosiah): Until views (e.g
|
|
1408
|
-
//
|
|
1409
|
-
|
|
1410
|
-
|
|
1417
|
+
// TODO(wittjosiah): Until views (e.g., Table) support relations this needs to be expressed via organization ref.
|
|
1418
|
+
// Employer.Employer,
|
|
1419
|
+
LegacyPerson,
|
|
1420
|
+
Project.Project,
|
|
1421
|
+
HasRelationship.HasRelationship,
|
|
1422
|
+
HasConnection.HasConnection
|
|
1411
1423
|
];
|
|
1412
1424
|
|
|
1413
1425
|
// src/functions/research/research.ts
|
|
@@ -1415,40 +1427,46 @@ var research_default = defineFunction8({
|
|
|
1415
1427
|
key: "dxos.org/function/research",
|
|
1416
1428
|
name: "Research",
|
|
1417
1429
|
description: trim3`
|
|
1418
|
-
|
|
1430
|
+
Search the web to research information about the given subject.
|
|
1419
1431
|
Inserts structured data into the research graph.
|
|
1420
|
-
|
|
1432
|
+
Creates a research summary and returns the objects created.
|
|
1421
1433
|
`,
|
|
1422
1434
|
inputSchema: Schema10.Struct({
|
|
1423
1435
|
query: Schema10.String.annotations({
|
|
1424
1436
|
description: trim3`
|
|
1425
|
-
The
|
|
1426
|
-
If doing research on an object
|
|
1437
|
+
The search query.
|
|
1438
|
+
If doing research on an object then load it first and pass it as JSON.
|
|
1427
1439
|
`
|
|
1428
1440
|
}),
|
|
1429
|
-
|
|
1441
|
+
instructions: Schema10.optional(Schema10.String).annotations({
|
|
1430
1442
|
description: trim3`
|
|
1431
1443
|
The instructions for the research agent.
|
|
1432
|
-
E.g., preference on fast responses or in-depth analysis, number of web searcher or the objects created.
|
|
1433
1444
|
`
|
|
1434
1445
|
}),
|
|
1435
1446
|
// TOOD(burdon): Move to context.
|
|
1436
1447
|
mockSearch: Schema10.optional(Schema10.Boolean).annotations({
|
|
1437
1448
|
description: "Whether to use the mock search tool.",
|
|
1438
1449
|
default: false
|
|
1450
|
+
}),
|
|
1451
|
+
entityExtraction: Schema10.optional(Schema10.Boolean).annotations({
|
|
1452
|
+
description: trim3`
|
|
1453
|
+
Whether to extract structured entities from the research.
|
|
1454
|
+
Experimental feature only enable if user explicitly requests it.
|
|
1455
|
+
`,
|
|
1456
|
+
default: false
|
|
1439
1457
|
})
|
|
1440
1458
|
}),
|
|
1441
1459
|
outputSchema: Schema10.Struct({
|
|
1442
|
-
|
|
1443
|
-
description: "
|
|
1460
|
+
document: Schema10.optional(Schema10.String).annotations({
|
|
1461
|
+
description: "The generated research document."
|
|
1444
1462
|
}),
|
|
1445
1463
|
objects: Schema10.Array(Schema10.Unknown).annotations({
|
|
1446
|
-
description: "
|
|
1464
|
+
description: "Structured objects created during the research process."
|
|
1447
1465
|
})
|
|
1448
1466
|
}),
|
|
1449
|
-
handler: Effect10.fnUntraced(function* ({ data: { query, mockSearch,
|
|
1467
|
+
handler: Effect10.fnUntraced(function* ({ data: { query, instructions: instructions6, mockSearch = false, entityExtraction = false } }) {
|
|
1450
1468
|
if (mockSearch) {
|
|
1451
|
-
const mockPerson = yield*
|
|
1469
|
+
const mockPerson = yield* Database7.Service.add(Obj7.make(Person.Person, {
|
|
1452
1470
|
preferredName: "John Doe",
|
|
1453
1471
|
emails: [
|
|
1454
1472
|
{
|
|
@@ -1462,52 +1480,52 @@ var research_default = defineFunction8({
|
|
|
1462
1480
|
]
|
|
1463
1481
|
}));
|
|
1464
1482
|
return {
|
|
1465
|
-
|
|
1466
|
-
The research
|
|
1467
|
-
|
|
1468
|
-
We reference John Doe to test reference: ${Obj5.getDXN(mockPerson)}
|
|
1483
|
+
document: trim3`
|
|
1484
|
+
The research ran in test-mode and was mocked. Proceed as usual.
|
|
1485
|
+
We reference John Doe to test reference: ${Obj7.getDXN(mockPerson)}
|
|
1469
1486
|
`,
|
|
1470
1487
|
objects: [
|
|
1471
|
-
|
|
1488
|
+
Obj7.toJSON(mockPerson)
|
|
1472
1489
|
]
|
|
1473
1490
|
};
|
|
1474
1491
|
}
|
|
1475
|
-
yield*
|
|
1492
|
+
yield* Database7.Service.flush({
|
|
1476
1493
|
indexes: true
|
|
1477
1494
|
});
|
|
1478
1495
|
yield* TracingService4.emitStatus({
|
|
1479
|
-
message: "
|
|
1480
|
-
});
|
|
1481
|
-
const objectDXNs = [];
|
|
1482
|
-
const GraphWriterToolkit = makeGraphWriterToolkit({
|
|
1483
|
-
schema: ResearchDataTypes
|
|
1484
|
-
});
|
|
1485
|
-
const GraphWriterHandler = makeGraphWriterHandler(GraphWriterToolkit, {
|
|
1486
|
-
onAppend: (dxns) => objectDXNs.push(...dxns)
|
|
1496
|
+
message: "Starting research..."
|
|
1487
1497
|
});
|
|
1488
1498
|
const NativeWebSearch = Toolkit2.make(AnthropicTool.WebSearch_20250305({}));
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1499
|
+
let toolkit = NativeWebSearch;
|
|
1500
|
+
let handlers = Layer3.empty;
|
|
1501
|
+
const objectDXNs = [];
|
|
1502
|
+
if (entityExtraction) {
|
|
1503
|
+
const GraphWriterToolkit = makeGraphWriterToolkit({
|
|
1504
|
+
schema: ResearchDataTypes
|
|
1505
|
+
});
|
|
1506
|
+
const GraphWriterHandler = makeGraphWriterHandler(GraphWriterToolkit, {
|
|
1507
|
+
onAppend: (dxns) => objectDXNs.push(...dxns)
|
|
1508
|
+
});
|
|
1509
|
+
toolkit = Toolkit2.merge(toolkit, LocalSearchToolkit, GraphWriterToolkit);
|
|
1510
|
+
handlers = Layer3.mergeAll(handlers, LocalSearchHandler, GraphWriterHandler).pipe(Layer3.provide(contextQueueLayerFromResearchGraph));
|
|
1511
|
+
}
|
|
1512
|
+
const finishedToolkit = yield* createToolkit2({
|
|
1513
|
+
toolkit
|
|
1514
|
+
}).pipe(Effect10.provide(handlers));
|
|
1496
1515
|
const session = new AiSession2();
|
|
1497
1516
|
const result = yield* session.run({
|
|
1498
1517
|
prompt: query,
|
|
1499
|
-
system:
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
toolkit,
|
|
1518
|
+
system: join(Template2.process(research_instructions_default, {
|
|
1519
|
+
entityExtraction
|
|
1520
|
+
}), instructions6 && `<instructions>${instructions6}</instructions>`),
|
|
1521
|
+
toolkit: finishedToolkit,
|
|
1503
1522
|
observer: GenerationObserver2.fromPrinter(new ConsolePrinter2({
|
|
1504
1523
|
tag: "research"
|
|
1505
1524
|
}))
|
|
1506
1525
|
});
|
|
1507
|
-
const
|
|
1508
|
-
const objects = yield* Effect10.forEach(objectDXNs, (dxn) => DatabaseService7.resolve(dxn)).pipe(Effect10.map(Array6.map((obj) => Obj5.toJSON(obj))));
|
|
1526
|
+
const objects = yield* Effect10.forEach(objectDXNs, (dxn) => Database7.Service.resolve(dxn)).pipe(Effect10.map(Array6.map((obj) => Entity2.toJSON(obj))));
|
|
1509
1527
|
return {
|
|
1510
|
-
|
|
1528
|
+
document: extractLastTextBlock(result),
|
|
1511
1529
|
objects
|
|
1512
1530
|
};
|
|
1513
1531
|
}, Effect10.provide(Layer3.mergeAll(
|
|
@@ -1520,7 +1538,7 @@ var research_default = defineFunction8({
|
|
|
1520
1538
|
makeToolExecutionServiceFromFunctions(Toolkit2.make(), Layer3.empty)
|
|
1521
1539
|
).pipe(Layer3.provide(
|
|
1522
1540
|
// TODO(dmaretskyi): This should be provided by environment.
|
|
1523
|
-
Layer3.mergeAll(
|
|
1541
|
+
Layer3.mergeAll(FunctionInvocationServiceLayerTestMocked({
|
|
1524
1542
|
functions: [
|
|
1525
1543
|
exa_default,
|
|
1526
1544
|
mock_default
|
|
@@ -1528,10 +1546,14 @@ var research_default = defineFunction8({
|
|
|
1528
1546
|
}))
|
|
1529
1547
|
))))
|
|
1530
1548
|
});
|
|
1549
|
+
var join = (...strings) => strings.filter(Boolean).join("\n\n");
|
|
1550
|
+
var extractLastTextBlock = (result) => {
|
|
1551
|
+
return Function4.pipe(result, Array6.last, Option4.map(Function4.flow((_) => _.blocks, Array6.reverse, Array6.dropWhile((_) => _._tag === "summary"), Array6.takeWhile((_) => _._tag === "text"), Array6.reverse, Array6.map((_) => _.text), Array6.reduce("", String10.concat))), Option4.getOrElse(() => ""));
|
|
1552
|
+
};
|
|
1531
1553
|
|
|
1532
1554
|
// src/functions/research/index.ts
|
|
1533
1555
|
(function(Research2) {
|
|
1534
|
-
Research2.create =
|
|
1556
|
+
Research2.create = document_create_default;
|
|
1535
1557
|
Research2.research = research_default;
|
|
1536
1558
|
})(Research || (Research = {}));
|
|
1537
1559
|
var Research;
|
|
@@ -1543,7 +1565,7 @@ var entity_extraction_default = defineFunction9({
|
|
|
1543
1565
|
name: "Entity Extraction",
|
|
1544
1566
|
description: "Extracts entities from emails and transcripts.",
|
|
1545
1567
|
inputSchema: Schema11.Struct({
|
|
1546
|
-
source:
|
|
1568
|
+
source: Message2.Message.annotations({
|
|
1547
1569
|
description: "Email or transcript to extract entities from."
|
|
1548
1570
|
}),
|
|
1549
1571
|
// TODO(dmaretskyi): Consider making this an array of blueprints instead.
|
|
@@ -1552,18 +1574,19 @@ var entity_extraction_default = defineFunction9({
|
|
|
1552
1574
|
})
|
|
1553
1575
|
}),
|
|
1554
1576
|
outputSchema: Schema11.Struct({
|
|
1555
|
-
entities: Schema11.optional(Schema11.Array(
|
|
1577
|
+
entities: Schema11.optional(Schema11.Array(Type4.Obj).annotations({
|
|
1556
1578
|
description: "Extracted entities."
|
|
1557
1579
|
}))
|
|
1558
1580
|
}),
|
|
1559
|
-
handler: Effect11.fnUntraced(function* ({ data: { source, instructions: instructions6 } }) {
|
|
1560
|
-
const
|
|
1581
|
+
handler: Effect11.fnUntraced(function* ({ data: { source: message, instructions: instructions6 } }) {
|
|
1582
|
+
const tags = Obj8.getMeta(message)?.tags;
|
|
1583
|
+
const contact = yield* extractContact(message.sender, tags);
|
|
1561
1584
|
let organization = null;
|
|
1562
1585
|
if (contact && !contact.organization) {
|
|
1563
1586
|
const created = [];
|
|
1564
1587
|
const GraphWriterToolkit = makeGraphWriterToolkit({
|
|
1565
1588
|
schema: [
|
|
1566
|
-
|
|
1589
|
+
LegacyOrganization2
|
|
1567
1590
|
]
|
|
1568
1591
|
}).pipe();
|
|
1569
1592
|
const GraphWriterHandler = makeGraphWriterHandler(GraphWriterToolkit, {
|
|
@@ -1577,7 +1600,7 @@ var entity_extraction_default = defineFunction9({
|
|
|
1577
1600
|
${instructions6 ? "<user_intructions>" + instructions6 + "</user_intructions>" : ""},
|
|
1578
1601
|
`,
|
|
1579
1602
|
prompt: JSON.stringify({
|
|
1580
|
-
source,
|
|
1603
|
+
source: message,
|
|
1581
1604
|
contact
|
|
1582
1605
|
}),
|
|
1583
1606
|
toolkit
|
|
@@ -1585,10 +1608,15 @@ var entity_extraction_default = defineFunction9({
|
|
|
1585
1608
|
if (created.length > 1) {
|
|
1586
1609
|
throw new Error("Multiple organizations created");
|
|
1587
1610
|
} else if (created.length === 1) {
|
|
1588
|
-
organization = yield*
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1611
|
+
organization = yield* Database8.Service.resolve(created[0], Organization.Organization);
|
|
1612
|
+
Obj8.change(organization, (org) => {
|
|
1613
|
+
const meta = Obj8.getMeta(org);
|
|
1614
|
+
meta.tags ??= [];
|
|
1615
|
+
meta.tags.push(...tags ?? []);
|
|
1616
|
+
});
|
|
1617
|
+
Obj8.change(contact, (c) => {
|
|
1618
|
+
c.organization = Ref3.make(organization);
|
|
1619
|
+
});
|
|
1592
1620
|
}
|
|
1593
1621
|
}
|
|
1594
1622
|
return {
|
|
@@ -1599,24 +1627,24 @@ var entity_extraction_default = defineFunction9({
|
|
|
1599
1627
|
};
|
|
1600
1628
|
}, Effect11.provide(Layer4.mergeAll(AiService3.model("@anthropic/claude-sonnet-4-0"), makeToolResolverFromFunctions2([], Toolkit3.make()), makeToolExecutionServiceFromFunctions2(Toolkit3.make(), Layer4.empty)).pipe(Layer4.provide(
|
|
1601
1629
|
// TODO(dmaretskyi): This should be provided by environment.
|
|
1602
|
-
Layer4.mergeAll(
|
|
1630
|
+
Layer4.mergeAll(FunctionInvocationServiceLayerTest())
|
|
1603
1631
|
))))
|
|
1604
1632
|
});
|
|
1605
|
-
var extractContact = Effect11.fn("extractContact")(function* (
|
|
1606
|
-
const name =
|
|
1607
|
-
const email =
|
|
1633
|
+
var extractContact = Effect11.fn("extractContact")(function* (actor, tags) {
|
|
1634
|
+
const name = actor.name;
|
|
1635
|
+
const email = actor.email;
|
|
1608
1636
|
if (!email) {
|
|
1609
1637
|
log5.warn("email is required for contact extraction", {
|
|
1610
|
-
|
|
1638
|
+
actor
|
|
1611
1639
|
}, {
|
|
1612
1640
|
F: __dxlog_file5,
|
|
1613
|
-
L:
|
|
1641
|
+
L: 112,
|
|
1614
1642
|
S: this,
|
|
1615
1643
|
C: (f, a) => f(...a)
|
|
1616
1644
|
});
|
|
1617
1645
|
return void 0;
|
|
1618
1646
|
}
|
|
1619
|
-
const
|
|
1647
|
+
const existingContacts = yield* Database8.Service.runQuery(Filter2.type(Person2.Person));
|
|
1620
1648
|
const existingContact = existingContacts.find((contact) => contact.emails?.some((contactEmail) => contactEmail.value === email));
|
|
1621
1649
|
if (existingContact) {
|
|
1622
1650
|
log5.info("Contact already exists", {
|
|
@@ -1624,25 +1652,31 @@ var extractContact = Effect11.fn("extractContact")(function* (message) {
|
|
|
1624
1652
|
existingContact
|
|
1625
1653
|
}, {
|
|
1626
1654
|
F: __dxlog_file5,
|
|
1627
|
-
L:
|
|
1655
|
+
L: 125,
|
|
1628
1656
|
S: this,
|
|
1629
1657
|
C: (f, a) => f(...a)
|
|
1630
1658
|
});
|
|
1631
1659
|
return existingContact;
|
|
1632
1660
|
}
|
|
1633
|
-
const newContact =
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1661
|
+
const newContact = Obj8.make(Person2.Person, {
|
|
1662
|
+
...tags ? {
|
|
1663
|
+
[Obj8.Meta]: {
|
|
1664
|
+
tags: [
|
|
1665
|
+
...tags
|
|
1666
|
+
]
|
|
1667
|
+
}
|
|
1668
|
+
} : {},
|
|
1637
1669
|
emails: [
|
|
1638
1670
|
{
|
|
1639
1671
|
value: email
|
|
1640
1672
|
}
|
|
1641
1673
|
]
|
|
1642
1674
|
});
|
|
1643
|
-
yield*
|
|
1675
|
+
yield* Database8.Service.add(newContact);
|
|
1644
1676
|
if (name) {
|
|
1645
|
-
newContact
|
|
1677
|
+
Obj8.change(newContact, (c) => {
|
|
1678
|
+
c.fullName = name;
|
|
1679
|
+
});
|
|
1646
1680
|
}
|
|
1647
1681
|
const emailDomain = email.split("@")[1]?.toLowerCase();
|
|
1648
1682
|
if (!emailDomain) {
|
|
@@ -1650,7 +1684,7 @@ var extractContact = Effect11.fn("extractContact")(function* (message) {
|
|
|
1650
1684
|
email
|
|
1651
1685
|
}, {
|
|
1652
1686
|
F: __dxlog_file5,
|
|
1653
|
-
L:
|
|
1687
|
+
L: 143,
|
|
1654
1688
|
S: this,
|
|
1655
1689
|
C: (f, a) => f(...a)
|
|
1656
1690
|
});
|
|
@@ -1660,11 +1694,11 @@ var extractContact = Effect11.fn("extractContact")(function* (message) {
|
|
|
1660
1694
|
emailDomain
|
|
1661
1695
|
}, {
|
|
1662
1696
|
F: __dxlog_file5,
|
|
1663
|
-
L:
|
|
1697
|
+
L: 147,
|
|
1664
1698
|
S: this,
|
|
1665
1699
|
C: (f, a) => f(...a)
|
|
1666
1700
|
});
|
|
1667
|
-
const
|
|
1701
|
+
const existingOrganisations = yield* Database8.Service.runQuery(Filter2.type(Organization.Organization));
|
|
1668
1702
|
const matchingOrg = existingOrganisations.find((org) => {
|
|
1669
1703
|
if (org.website) {
|
|
1670
1704
|
try {
|
|
@@ -1677,7 +1711,7 @@ var extractContact = Effect11.fn("extractContact")(function* (message) {
|
|
|
1677
1711
|
error: e
|
|
1678
1712
|
}, {
|
|
1679
1713
|
F: __dxlog_file5,
|
|
1680
|
-
L:
|
|
1714
|
+
L: 165,
|
|
1681
1715
|
S: this,
|
|
1682
1716
|
C: (f, a) => f(...a)
|
|
1683
1717
|
});
|
|
@@ -1691,11 +1725,13 @@ var extractContact = Effect11.fn("extractContact")(function* (message) {
|
|
|
1691
1725
|
organization: matchingOrg
|
|
1692
1726
|
}, {
|
|
1693
1727
|
F: __dxlog_file5,
|
|
1694
|
-
L:
|
|
1728
|
+
L: 176,
|
|
1695
1729
|
S: this,
|
|
1696
1730
|
C: (f, a) => f(...a)
|
|
1697
1731
|
});
|
|
1698
|
-
newContact
|
|
1732
|
+
Obj8.change(newContact, (c) => {
|
|
1733
|
+
c.organization = Ref3.make(matchingOrg);
|
|
1734
|
+
});
|
|
1699
1735
|
}
|
|
1700
1736
|
return newContact;
|
|
1701
1737
|
});
|
|
@@ -1711,17 +1747,18 @@ import * as FetchHttpClient2 from "@effect/platform/FetchHttpClient";
|
|
|
1711
1747
|
import * as HttpClient from "@effect/platform/HttpClient";
|
|
1712
1748
|
import * as Array9 from "effect/Array";
|
|
1713
1749
|
import * as Effect13 from "effect/Effect";
|
|
1714
|
-
import * as
|
|
1750
|
+
import * as Function5 from "effect/Function";
|
|
1715
1751
|
import * as Schema12 from "effect/Schema";
|
|
1716
|
-
import { Filter as Filter4, Obj as
|
|
1717
|
-
import {
|
|
1752
|
+
import { Filter as Filter4, Obj as Obj10, Query as Query4, Ref as Ref5 } from "@dxos/echo";
|
|
1753
|
+
import { Database as Database10 } from "@dxos/echo";
|
|
1754
|
+
import { CredentialsService as CredentialsService3, defineFunction as defineFunction10, withAuthorization } from "@dxos/functions";
|
|
1718
1755
|
import { log as log7 } from "@dxos/log";
|
|
1719
|
-
import {
|
|
1756
|
+
import { Person as Person3, Project as Project2, Task as Task2 } from "@dxos/types";
|
|
1720
1757
|
|
|
1721
1758
|
// src/sync/sync.ts
|
|
1722
1759
|
import * as Effect12 from "effect/Effect";
|
|
1723
|
-
import { Filter as Filter3, Obj as
|
|
1724
|
-
import {
|
|
1760
|
+
import { Filter as Filter3, Obj as Obj9, Query as Query3, Ref as Ref4 } from "@dxos/echo";
|
|
1761
|
+
import { Database as Database9 } from "@dxos/echo";
|
|
1725
1762
|
import { failedInvariant } from "@dxos/invariant";
|
|
1726
1763
|
import { log as log6 } from "@dxos/log";
|
|
1727
1764
|
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/sync/sync.ts";
|
|
@@ -1732,7 +1769,7 @@ var syncObjects = Effect12.fn("syncObjects")(function* (objs, { foreignKeyId })
|
|
|
1732
1769
|
if (!Ref4.isRef(obj[key])) continue;
|
|
1733
1770
|
const ref = obj[key];
|
|
1734
1771
|
if (!ref.target) continue;
|
|
1735
|
-
if (
|
|
1772
|
+
if (Obj9.getDXN(ref.target).isLocalObjectId()) {
|
|
1736
1773
|
const [target] = yield* syncObjects([
|
|
1737
1774
|
ref.target
|
|
1738
1775
|
], {
|
|
@@ -1741,26 +1778,26 @@ var syncObjects = Effect12.fn("syncObjects")(function* (objs, { foreignKeyId })
|
|
|
1741
1778
|
obj[key] = Ref4.make(target);
|
|
1742
1779
|
}
|
|
1743
1780
|
}
|
|
1744
|
-
const schema =
|
|
1745
|
-
const foreignId =
|
|
1746
|
-
const
|
|
1781
|
+
const schema = Obj9.getSchema(obj) ?? failedInvariant("No schema.");
|
|
1782
|
+
const foreignId = Obj9.getKeys(obj, foreignKeyId)[0]?.id ?? failedInvariant("No foreign key.");
|
|
1783
|
+
const [existing] = yield* Database9.Service.runQuery(Query3.select(Filter3.foreignKeys(schema, [
|
|
1747
1784
|
{
|
|
1748
1785
|
source: foreignKeyId,
|
|
1749
1786
|
id: foreignId
|
|
1750
1787
|
}
|
|
1751
1788
|
])));
|
|
1752
1789
|
log6("sync object", {
|
|
1753
|
-
type:
|
|
1790
|
+
type: Obj9.getTypename(obj),
|
|
1754
1791
|
foreignId,
|
|
1755
|
-
existing: existing ?
|
|
1792
|
+
existing: existing ? Obj9.getDXN(existing) : void 0
|
|
1756
1793
|
}, {
|
|
1757
1794
|
F: __dxlog_file6,
|
|
1758
|
-
L:
|
|
1795
|
+
L: 48,
|
|
1759
1796
|
S: this,
|
|
1760
1797
|
C: (f, a) => f(...a)
|
|
1761
1798
|
});
|
|
1762
1799
|
if (!existing) {
|
|
1763
|
-
yield*
|
|
1800
|
+
yield* Database9.Service.add(obj);
|
|
1764
1801
|
return obj;
|
|
1765
1802
|
} else {
|
|
1766
1803
|
copyObjectData(existing, obj);
|
|
@@ -1771,23 +1808,25 @@ var syncObjects = Effect12.fn("syncObjects")(function* (objs, { foreignKeyId })
|
|
|
1771
1808
|
});
|
|
1772
1809
|
});
|
|
1773
1810
|
var copyObjectData = (existing, newObj) => {
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
for (const key of Object.keys(existing)) {
|
|
1780
|
-
if (typeof key !== "string" || key === "id") continue;
|
|
1781
|
-
if (!(key in newObj)) {
|
|
1782
|
-
delete existing[key];
|
|
1811
|
+
Obj9.change(existing, (obj) => {
|
|
1812
|
+
for (const key of Object.keys(newObj)) {
|
|
1813
|
+
if (typeof key !== "string" || key === "id") continue;
|
|
1814
|
+
if (typeof newObj[key] !== "string" && typeof newObj[key] !== "number" && typeof newObj[key] !== "boolean" && !Ref4.isRef(newObj[key])) continue;
|
|
1815
|
+
obj[key] = newObj[key];
|
|
1783
1816
|
}
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
}
|
|
1790
|
-
|
|
1817
|
+
for (const key of Object.keys(obj)) {
|
|
1818
|
+
if (typeof key !== "string" || key === "id") continue;
|
|
1819
|
+
if (!(key in newObj)) {
|
|
1820
|
+
delete obj[key];
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
for (const foreignKey of Obj9.getMeta(newObj).keys) {
|
|
1824
|
+
Obj9.deleteKeys(obj, foreignKey.source);
|
|
1825
|
+
Obj9.getMeta(obj).keys.push({
|
|
1826
|
+
...foreignKey
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1829
|
+
});
|
|
1791
1830
|
};
|
|
1792
1831
|
|
|
1793
1832
|
// src/util/graphql.ts
|
|
@@ -1817,7 +1856,7 @@ query Issues($teamId: String!, $after: DateTimeOrDuration!) {
|
|
|
1817
1856
|
updatedAt
|
|
1818
1857
|
description
|
|
1819
1858
|
assignee { id, name }
|
|
1820
|
-
state {
|
|
1859
|
+
state {
|
|
1821
1860
|
name
|
|
1822
1861
|
}
|
|
1823
1862
|
project {
|
|
@@ -1848,15 +1887,16 @@ var sync_issues_default = defineFunction10({
|
|
|
1848
1887
|
})
|
|
1849
1888
|
}),
|
|
1850
1889
|
handler: Effect13.fnUntraced(function* ({ data }) {
|
|
1851
|
-
const
|
|
1890
|
+
const credential = yield* CredentialsService3.getCredential({
|
|
1852
1891
|
service: "linear.app"
|
|
1853
|
-
})
|
|
1854
|
-
const
|
|
1892
|
+
});
|
|
1893
|
+
const client = yield* HttpClient.HttpClient.pipe(Effect13.map(withAuthorization(credential.apiKey)));
|
|
1894
|
+
const after = yield* getLatestUpdateTimestamp(data.team, Task2.Task);
|
|
1855
1895
|
log7.info("will fetch", {
|
|
1856
1896
|
after
|
|
1857
1897
|
}, {
|
|
1858
1898
|
F: __dxlog_file7,
|
|
1859
|
-
L:
|
|
1899
|
+
L: 93,
|
|
1860
1900
|
S: this,
|
|
1861
1901
|
C: (f, a) => f(...a)
|
|
1862
1902
|
});
|
|
@@ -1874,7 +1914,7 @@ var sync_issues_default = defineFunction10({
|
|
|
1874
1914
|
count: tasks.length
|
|
1875
1915
|
}, {
|
|
1876
1916
|
F: __dxlog_file7,
|
|
1877
|
-
L:
|
|
1917
|
+
L: 106,
|
|
1878
1918
|
S: this,
|
|
1879
1919
|
C: (f, a) => f(...a)
|
|
1880
1920
|
});
|
|
@@ -1887,16 +1927,16 @@ var sync_issues_default = defineFunction10({
|
|
|
1887
1927
|
}, Effect13.provide(FetchHttpClient2.layer))
|
|
1888
1928
|
});
|
|
1889
1929
|
var getLatestUpdateTimestamp = Effect13.fnUntraced(function* (teamId, dataType) {
|
|
1890
|
-
const
|
|
1930
|
+
const existingTasks = yield* Database10.Service.runQuery(Query4.type(dataType).select(Filter4.foreignKeys(dataType, [
|
|
1891
1931
|
{
|
|
1892
1932
|
source: LINEAR_TEAM_ID_KEY,
|
|
1893
1933
|
id: teamId
|
|
1894
1934
|
}
|
|
1895
1935
|
])));
|
|
1896
|
-
return
|
|
1936
|
+
return Function5.pipe(existingTasks, Array9.map((task) => Obj10.getKeys(task, LINEAR_UPDATED_AT_KEY).at(0)?.id), Array9.filter((x) => x !== void 0), Array9.reduce("2025-01-01T00:00:00.000Z", (acc, x) => x > acc ? x : acc));
|
|
1897
1937
|
});
|
|
1898
|
-
var mapLinearPerson = (person, { teamId }) =>
|
|
1899
|
-
[
|
|
1938
|
+
var mapLinearPerson = (person, { teamId }) => Obj10.make(Person3.Person, {
|
|
1939
|
+
[Obj10.Meta]: {
|
|
1900
1940
|
keys: [
|
|
1901
1941
|
{
|
|
1902
1942
|
id: person.id,
|
|
@@ -1910,8 +1950,8 @@ var mapLinearPerson = (person, { teamId }) => Obj8.make(DataType6.Person, {
|
|
|
1910
1950
|
},
|
|
1911
1951
|
nickname: person.name
|
|
1912
1952
|
});
|
|
1913
|
-
var mapLinearIssue = (issue, { teamId }) =>
|
|
1914
|
-
[
|
|
1953
|
+
var mapLinearIssue = (issue, { teamId }) => Obj10.make(Task2.Task, {
|
|
1954
|
+
[Obj10.Meta]: {
|
|
1915
1955
|
keys: [
|
|
1916
1956
|
{
|
|
1917
1957
|
id: issue.id,
|
|
@@ -1934,8 +1974,8 @@ var mapLinearIssue = (issue, { teamId }) => Obj8.make(DataType6.Task, {
|
|
|
1934
1974
|
})),
|
|
1935
1975
|
// TODO(dmaretskyi): Sync those (+ linear team as org?).
|
|
1936
1976
|
// state: issue.state.name,
|
|
1937
|
-
project: !issue.project ? void 0 : Ref5.make(
|
|
1938
|
-
[
|
|
1977
|
+
project: !issue.project ? void 0 : Ref5.make(Project2.make({
|
|
1978
|
+
[Obj10.Meta]: {
|
|
1939
1979
|
keys: [
|
|
1940
1980
|
{
|
|
1941
1981
|
id: issue.project.id,
|
|
@@ -1960,15 +2000,16 @@ var Linear;
|
|
|
1960
2000
|
// src/functions/tasks/read.ts
|
|
1961
2001
|
import * as Effect14 from "effect/Effect";
|
|
1962
2002
|
import * as Schema13 from "effect/Schema";
|
|
1963
|
-
import { ArtifactId as
|
|
1964
|
-
import {
|
|
2003
|
+
import { ArtifactId as ArtifactId4 } from "@dxos/assistant";
|
|
2004
|
+
import { Database as Database11 } from "@dxos/echo";
|
|
2005
|
+
import { defineFunction as defineFunction11 } from "@dxos/functions";
|
|
1965
2006
|
import { Markdown as Markdown4 } from "@dxos/plugin-markdown/types";
|
|
1966
2007
|
var read_default2 = defineFunction11({
|
|
1967
2008
|
key: "dxos.org/function/markdown/read-tasks",
|
|
1968
2009
|
name: "Read",
|
|
1969
2010
|
description: "Read markdown tasks.",
|
|
1970
2011
|
inputSchema: Schema13.Struct({
|
|
1971
|
-
id:
|
|
2012
|
+
id: ArtifactId4.annotations({
|
|
1972
2013
|
description: "The ID of the document to read."
|
|
1973
2014
|
})
|
|
1974
2015
|
}),
|
|
@@ -1976,8 +2017,8 @@ var read_default2 = defineFunction11({
|
|
|
1976
2017
|
content: Schema13.String
|
|
1977
2018
|
}),
|
|
1978
2019
|
handler: Effect14.fn(function* ({ data: { id } }) {
|
|
1979
|
-
const doc = yield*
|
|
1980
|
-
const { content } = yield*
|
|
2020
|
+
const doc = yield* Database11.Service.resolve(ArtifactId4.toDXN(id), Markdown4.Document);
|
|
2021
|
+
const { content } = yield* Database11.Service.load(doc.content);
|
|
1981
2022
|
const lines = content.split("\n");
|
|
1982
2023
|
const len = String(lines.length).length;
|
|
1983
2024
|
const numbered = lines.map((line, i) => `${String(i + 1).padStart(len, " ")}. ${line}`).join("\n");
|
|
@@ -1990,8 +2031,9 @@ var read_default2 = defineFunction11({
|
|
|
1990
2031
|
// src/functions/tasks/update.ts
|
|
1991
2032
|
import * as Effect15 from "effect/Effect";
|
|
1992
2033
|
import * as Schema14 from "effect/Schema";
|
|
1993
|
-
import { ArtifactId as
|
|
1994
|
-
import {
|
|
2034
|
+
import { ArtifactId as ArtifactId5 } from "@dxos/assistant";
|
|
2035
|
+
import { Database as Database12 } from "@dxos/echo";
|
|
2036
|
+
import { defineFunction as defineFunction12 } from "@dxos/functions";
|
|
1995
2037
|
import { Markdown as Markdown5 } from "@dxos/plugin-markdown/types";
|
|
1996
2038
|
|
|
1997
2039
|
// src/functions/tasks/task-list.ts
|
|
@@ -2128,7 +2170,7 @@ var update_default2 = defineFunction12({
|
|
|
2128
2170
|
name: "Update markdown",
|
|
2129
2171
|
description: "Creates and updates tasks in markdown documents.",
|
|
2130
2172
|
inputSchema: Schema14.Struct({
|
|
2131
|
-
id:
|
|
2173
|
+
id: ArtifactId5.annotations({
|
|
2132
2174
|
description: "The ID of the document to update."
|
|
2133
2175
|
}),
|
|
2134
2176
|
operations: Schema14.optional(Schema14.Array(Schema14.Any.annotations({
|
|
@@ -2142,8 +2184,8 @@ var update_default2 = defineFunction12({
|
|
|
2142
2184
|
})
|
|
2143
2185
|
}),
|
|
2144
2186
|
handler: Effect15.fn(function* ({ data: { id, operations = [] } }) {
|
|
2145
|
-
const doc = yield*
|
|
2146
|
-
const { content } = yield*
|
|
2187
|
+
const doc = yield* Database12.Service.resolve(ArtifactId5.toDXN(id), Markdown5.Document);
|
|
2188
|
+
const { content } = yield* Database12.Service.load(doc.content);
|
|
2147
2189
|
const taskManager = new MarkdownTasks(content);
|
|
2148
2190
|
if (operations.length > 0) {
|
|
2149
2191
|
taskManager.applyOperations(operations);
|
|
@@ -2172,28 +2214,27 @@ var instructions = trim5`
|
|
|
2172
2214
|
When replying to the user, be terse with your comments about design doc handling.
|
|
2173
2215
|
Do not announce when you read or write the design spec document.
|
|
2174
2216
|
`;
|
|
2175
|
-
var blueprint =
|
|
2217
|
+
var blueprint = Blueprint.make({
|
|
2176
2218
|
key: "dxos.org/blueprint/design",
|
|
2177
2219
|
name: "Design Spec",
|
|
2178
2220
|
description: "Preserve the conversation in the design spec.",
|
|
2179
2221
|
instructions: {
|
|
2180
|
-
source: Ref6.make(
|
|
2222
|
+
source: Ref6.make(Text2.make(instructions))
|
|
2181
2223
|
},
|
|
2182
2224
|
tools: [
|
|
2183
2225
|
Document.read,
|
|
2184
2226
|
Document.update
|
|
2185
2227
|
].map((fn9) => ToolId.make(fn9.key))
|
|
2186
2228
|
});
|
|
2187
|
-
var design_blueprint_default = blueprint;
|
|
2188
2229
|
|
|
2189
2230
|
// src/blueprints/design/index.ts
|
|
2190
|
-
var design_default =
|
|
2231
|
+
var design_default = blueprint;
|
|
2191
2232
|
|
|
2192
2233
|
// src/blueprints/discord/discord-blueprint.ts
|
|
2193
2234
|
import { ToolId as ToolId2 } from "@dxos/ai";
|
|
2194
2235
|
import { Blueprint as Blueprint2 } from "@dxos/blueprints";
|
|
2195
|
-
import {
|
|
2196
|
-
import {
|
|
2236
|
+
import { Ref as Ref7 } from "@dxos/echo";
|
|
2237
|
+
import { Text as Text3 } from "@dxos/schema";
|
|
2197
2238
|
import { trim as trim6 } from "@dxos/util";
|
|
2198
2239
|
var instructions2 = trim6`
|
|
2199
2240
|
You are able to fetch messages from Discord servers.
|
|
@@ -2202,27 +2243,26 @@ var instructions2 = trim6`
|
|
|
2202
2243
|
|
|
2203
2244
|
DXOS serverId: 837138313172353095
|
|
2204
2245
|
`;
|
|
2205
|
-
var blueprint2 =
|
|
2246
|
+
var blueprint2 = Blueprint2.make({
|
|
2206
2247
|
key: "dxos.org/blueprint/discord",
|
|
2207
2248
|
name: "Discord",
|
|
2208
2249
|
description: "Discord integration.",
|
|
2209
2250
|
instructions: {
|
|
2210
|
-
source: Ref7.make(
|
|
2251
|
+
source: Ref7.make(Text3.make(instructions2))
|
|
2211
2252
|
},
|
|
2212
2253
|
tools: [
|
|
2213
2254
|
ToolId2.make(Discord.fetch.key)
|
|
2214
2255
|
]
|
|
2215
2256
|
});
|
|
2216
|
-
var discord_blueprint_default = blueprint2;
|
|
2217
2257
|
|
|
2218
2258
|
// src/blueprints/discord/index.ts
|
|
2219
|
-
var discord_default =
|
|
2259
|
+
var discord_default = blueprint2;
|
|
2220
2260
|
|
|
2221
2261
|
// src/blueprints/linear/linear-blueprint.ts
|
|
2222
2262
|
import { ToolId as ToolId3 } from "@dxos/ai";
|
|
2223
2263
|
import { Blueprint as Blueprint3 } from "@dxos/blueprints";
|
|
2224
|
-
import {
|
|
2225
|
-
import {
|
|
2264
|
+
import { Ref as Ref8 } from "@dxos/echo";
|
|
2265
|
+
import { Text as Text4 } from "@dxos/schema";
|
|
2226
2266
|
import { trim as trim7 } from "@dxos/util";
|
|
2227
2267
|
var instructions3 = trim7`
|
|
2228
2268
|
You are able to sync Linear workspaces.
|
|
@@ -2232,27 +2272,26 @@ var instructions3 = trim7`
|
|
|
2232
2272
|
|
|
2233
2273
|
DXOS teamId: 1127c63a-6f77-4725-9229-50f6cd47321c
|
|
2234
2274
|
`;
|
|
2235
|
-
var blueprint3 =
|
|
2275
|
+
var blueprint3 = Blueprint3.make({
|
|
2236
2276
|
key: "dxos.org/blueprint/linear",
|
|
2237
2277
|
name: "Linear",
|
|
2238
2278
|
description: "Syncs Linear workspaces.",
|
|
2239
2279
|
instructions: {
|
|
2240
|
-
source: Ref8.make(
|
|
2280
|
+
source: Ref8.make(Text4.make(instructions3))
|
|
2241
2281
|
},
|
|
2242
2282
|
tools: [
|
|
2243
2283
|
Linear.sync
|
|
2244
2284
|
].map((tool) => ToolId3.make(tool.key))
|
|
2245
2285
|
});
|
|
2246
|
-
var linear_blueprint_default = blueprint3;
|
|
2247
2286
|
|
|
2248
2287
|
// src/blueprints/linear/index.ts
|
|
2249
|
-
var linear_default =
|
|
2288
|
+
var linear_default = blueprint3;
|
|
2250
2289
|
|
|
2251
2290
|
// src/blueprints/planning/planning-blueprint.ts
|
|
2252
2291
|
import { ToolId as ToolId4 } from "@dxos/ai";
|
|
2253
2292
|
import { Blueprint as Blueprint4 } from "@dxos/blueprints";
|
|
2254
|
-
import {
|
|
2255
|
-
import {
|
|
2293
|
+
import { Ref as Ref9 } from "@dxos/echo";
|
|
2294
|
+
import { Text as Text5 } from "@dxos/schema";
|
|
2256
2295
|
import { trim as trim8 } from "@dxos/util";
|
|
2257
2296
|
var instructions4 = trim8`
|
|
2258
2297
|
You are a task management agent that maintains hierarchical task lists where each line is a task.
|
|
@@ -2325,81 +2364,86 @@ var instructions4 = trim8`
|
|
|
2325
2364
|
- When creating subtasks, consider the parent task's completion status
|
|
2326
2365
|
- Be precise with task descriptions and hierarchy levels
|
|
2327
2366
|
`;
|
|
2328
|
-
var blueprint4 =
|
|
2367
|
+
var blueprint4 = Blueprint4.make({
|
|
2329
2368
|
key: "dxos.org/blueprint/planning",
|
|
2330
2369
|
name: "Planning",
|
|
2331
2370
|
description: "Plans and tracks complex tasks with artifact management.",
|
|
2332
2371
|
instructions: {
|
|
2333
|
-
source: Ref9.make(
|
|
2372
|
+
source: Ref9.make(Text5.make(instructions4))
|
|
2334
2373
|
},
|
|
2335
2374
|
tools: [
|
|
2336
2375
|
Tasks.read,
|
|
2337
2376
|
Tasks.update
|
|
2338
2377
|
].map((fn9) => ToolId4.make(fn9.key))
|
|
2339
2378
|
});
|
|
2340
|
-
var planning_blueprint_default = blueprint4;
|
|
2341
2379
|
|
|
2342
2380
|
// src/blueprints/planning/index.ts
|
|
2343
|
-
var planning_default =
|
|
2381
|
+
var planning_default = blueprint4;
|
|
2344
2382
|
|
|
2345
2383
|
// src/blueprints/research/research-blueprint.ts
|
|
2346
2384
|
import { ToolId as ToolId5 } from "@dxos/ai";
|
|
2347
2385
|
import { Blueprint as Blueprint5 } from "@dxos/blueprints";
|
|
2348
|
-
import {
|
|
2349
|
-
import {
|
|
2386
|
+
import { Ref as Ref10 } from "@dxos/echo";
|
|
2387
|
+
import { Text as Text6 } from "@dxos/schema";
|
|
2350
2388
|
import { trim as trim9 } from "@dxos/util";
|
|
2351
2389
|
var instructions5 = trim9`
|
|
2352
2390
|
{{! Research }}
|
|
2353
2391
|
|
|
2354
2392
|
You are an analyst that does research tasks using tools that scrape the web and create structured data.
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
<
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2393
|
+
Structured data extraction is an experimental feature -- only enable it if the user explicitly requests it in the prompt.
|
|
2394
|
+
Prefer updating existing notes instead of creating new ones.
|
|
2395
|
+
|
|
2396
|
+
<strcutured_mode>
|
|
2397
|
+
When you are done, reply with the created objects.
|
|
2398
|
+
Do not print the data, instead reply with inline references to the created objects.
|
|
2399
|
+
Those will be later substituted with the pills representing the created objects.
|
|
2400
|
+
Print the rest of the created objects as block references after the main note.
|
|
2401
|
+
|
|
2402
|
+
<example>
|
|
2403
|
+
Based on my research, Google was founded by @dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK464FSCKVQJAB2H662M and @dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK46K31DDW62PBW9H2ZQ
|
|
2404
|
+
|
|
2405
|
+
<object><dxn>dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK464FSCKVQJAB2H662M</dxn></object>
|
|
2406
|
+
<object><dxn>dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK46K31DDW62PBW9H2ZQ</dxn></object>
|
|
2407
|
+
<object><dxn>dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK46K31DDW62PBW92333</dxn></object>
|
|
2408
|
+
</example>
|
|
2409
|
+
</structured_mode>
|
|
2410
|
+
|
|
2411
|
+
<unstructured_mode>
|
|
2412
|
+
Reply normally with the text mode of the result of your research.
|
|
2413
|
+
</unstructured_mode>
|
|
2368
2414
|
`;
|
|
2369
|
-
var blueprint5 =
|
|
2415
|
+
var blueprint5 = Blueprint5.make({
|
|
2370
2416
|
key: "dxos.org/blueprint/research",
|
|
2371
2417
|
name: "Research",
|
|
2372
2418
|
description: "Researches the web and creates structured data.",
|
|
2373
2419
|
instructions: {
|
|
2374
|
-
source: Ref10.make(
|
|
2420
|
+
source: Ref10.make(Text6.make(instructions5))
|
|
2375
2421
|
},
|
|
2376
2422
|
tools: [
|
|
2377
2423
|
Research.create,
|
|
2378
2424
|
Research.research
|
|
2379
2425
|
].map((fn9) => ToolId5.make(fn9.key))
|
|
2380
2426
|
});
|
|
2381
|
-
var research_blueprint_default = blueprint5;
|
|
2382
2427
|
|
|
2383
2428
|
// src/blueprints/research/index.ts
|
|
2384
|
-
var research_default2 =
|
|
2429
|
+
var research_default2 = blueprint5;
|
|
2385
2430
|
|
|
2386
2431
|
// src/blueprints/websearch/websearch-blueprint.ts
|
|
2387
2432
|
import { ToolId as ToolId6 } from "@dxos/ai";
|
|
2388
2433
|
import { Blueprint as Blueprint6 } from "@dxos/blueprints";
|
|
2389
|
-
import {
|
|
2390
|
-
import {
|
|
2391
|
-
var blueprint6 =
|
|
2434
|
+
import { Ref as Ref11 } from "@dxos/echo";
|
|
2435
|
+
import { Text as Text7 } from "@dxos/schema";
|
|
2436
|
+
var blueprint6 = Blueprint6.make({
|
|
2392
2437
|
key: "dxos.org/blueprint/web-search",
|
|
2393
2438
|
name: "Web Search",
|
|
2394
2439
|
description: "Search the web.",
|
|
2395
2440
|
instructions: {
|
|
2396
|
-
source: Ref11.make(
|
|
2441
|
+
source: Ref11.make(Text7.make())
|
|
2397
2442
|
},
|
|
2398
2443
|
tools: [
|
|
2399
2444
|
ToolId6.make("AnthropicWebSearch")
|
|
2400
2445
|
]
|
|
2401
2446
|
});
|
|
2402
|
-
var websearch_blueprint_default = blueprint6;
|
|
2403
2447
|
|
|
2404
2448
|
// src/blueprints/websearch/websearch-toolkit.ts
|
|
2405
2449
|
import * as Toolkit4 from "@effect/ai/Toolkit";
|
|
@@ -2407,46 +2451,402 @@ import * as AnthropicTool2 from "@effect/ai-anthropic/AnthropicTool";
|
|
|
2407
2451
|
var WebSearchToolkit = Toolkit4.make(AnthropicTool2.WebSearch_20250305({}));
|
|
2408
2452
|
|
|
2409
2453
|
// src/blueprints/websearch/index.ts
|
|
2410
|
-
var websearch_default =
|
|
2411
|
-
|
|
2412
|
-
// src/
|
|
2454
|
+
var websearch_default = blueprint6;
|
|
2455
|
+
|
|
2456
|
+
// src/toolkits/AssistantToolkit.ts
|
|
2457
|
+
var AssistantToolkit_exports = {};
|
|
2458
|
+
__export(AssistantToolkit_exports, {
|
|
2459
|
+
AssistantToolkit: () => AssistantToolkit,
|
|
2460
|
+
layer: () => layer3,
|
|
2461
|
+
tools: () => tools
|
|
2462
|
+
});
|
|
2463
|
+
import * as Tool2 from "@effect/ai/Tool";
|
|
2464
|
+
import * as Toolkit5 from "@effect/ai/Toolkit";
|
|
2465
|
+
import * as Effect16 from "effect/Effect";
|
|
2466
|
+
import * as Record from "effect/Record";
|
|
2413
2467
|
import * as Schema15 from "effect/Schema";
|
|
2414
|
-
import
|
|
2415
|
-
import {
|
|
2416
|
-
import {
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
var isImage = (data) => false;
|
|
2425
|
-
var capabilities = [
|
|
2426
|
-
contributes(Capabilities.ReactSurface, createSurface({
|
|
2427
|
-
id: "plugin-image",
|
|
2428
|
-
role: "card--extrinsic",
|
|
2429
|
-
filter: (data) => isImage(data.value),
|
|
2430
|
-
component: ({ data }) => /* @__PURE__ */ React.createElement("img", {
|
|
2431
|
-
className: "grow object-cover",
|
|
2432
|
-
src: `data:image/jpeg;base64,${data.value.source.data}`,
|
|
2433
|
-
alt: data.value.prompt ?? `Generated image [id=${data.value.id}]`
|
|
2468
|
+
import { AiContextService, ArtifactId as ArtifactId6 } from "@dxos/assistant";
|
|
2469
|
+
import { Database as Database13 } from "@dxos/echo";
|
|
2470
|
+
import { trim as trim10 } from "@dxos/util";
|
|
2471
|
+
var AssistantToolkit = Toolkit5.make(Tool2.make("context-add", {
|
|
2472
|
+
description: trim10`
|
|
2473
|
+
Adds the object to the chat context.
|
|
2474
|
+
`,
|
|
2475
|
+
parameters: {
|
|
2476
|
+
id: ArtifactId6.annotations({
|
|
2477
|
+
description: "The ID of the document to add."
|
|
2434
2478
|
})
|
|
2435
|
-
}
|
|
2479
|
+
},
|
|
2480
|
+
success: Schema15.Void,
|
|
2481
|
+
failure: Schema15.Never,
|
|
2482
|
+
dependencies: [
|
|
2483
|
+
AiContextService,
|
|
2484
|
+
Database13.Service
|
|
2485
|
+
]
|
|
2486
|
+
}), Tool2.make("context-remove", {
|
|
2487
|
+
description: trim10`
|
|
2488
|
+
Removes the object from the chat context.
|
|
2489
|
+
`,
|
|
2490
|
+
parameters: {
|
|
2491
|
+
id: ArtifactId6.annotations({
|
|
2492
|
+
description: "The ID of the document to remove."
|
|
2493
|
+
})
|
|
2494
|
+
},
|
|
2495
|
+
success: Schema15.Void,
|
|
2496
|
+
failure: Schema15.Never,
|
|
2497
|
+
dependencies: [
|
|
2498
|
+
AiContextService,
|
|
2499
|
+
Database13.Service
|
|
2500
|
+
]
|
|
2501
|
+
}));
|
|
2502
|
+
var tools = Record.keys(AssistantToolkit.tools);
|
|
2503
|
+
var layer3 = () => AssistantToolkit.toLayer({
|
|
2504
|
+
["context-add"]: Effect16.fnUntraced(function* ({ id }) {
|
|
2505
|
+
const { binder } = yield* AiContextService;
|
|
2506
|
+
const { db } = yield* Database13.Service;
|
|
2507
|
+
const ref = db.makeRef(ArtifactId6.toDXN(id, db.spaceId));
|
|
2508
|
+
yield* Effect16.promise(() => binder.bind({
|
|
2509
|
+
blueprints: [],
|
|
2510
|
+
objects: [
|
|
2511
|
+
ref
|
|
2512
|
+
]
|
|
2513
|
+
}));
|
|
2514
|
+
}),
|
|
2515
|
+
["context-remove"]: Effect16.fnUntraced(function* ({ id }) {
|
|
2516
|
+
const { binder } = yield* AiContextService;
|
|
2517
|
+
const { db } = yield* Database13.Service;
|
|
2518
|
+
const ref = db.makeRef(ArtifactId6.toDXN(id, db.spaceId));
|
|
2519
|
+
yield* Effect16.promise(() => binder.unbind({
|
|
2520
|
+
blueprints: [],
|
|
2521
|
+
objects: [
|
|
2522
|
+
ref
|
|
2523
|
+
]
|
|
2524
|
+
}));
|
|
2525
|
+
})
|
|
2526
|
+
});
|
|
2527
|
+
|
|
2528
|
+
// src/toolkits/SystemToolkit.ts
|
|
2529
|
+
var SystemToolkit_exports = {};
|
|
2530
|
+
__export(SystemToolkit_exports, {
|
|
2531
|
+
SystemToolkit: () => SystemToolkit,
|
|
2532
|
+
layer: () => layer4,
|
|
2533
|
+
tools: () => tools2
|
|
2534
|
+
});
|
|
2535
|
+
import * as Tool3 from "@effect/ai/Tool";
|
|
2536
|
+
import * as Toolkit6 from "@effect/ai/Toolkit";
|
|
2537
|
+
import * as Effect17 from "effect/Effect";
|
|
2538
|
+
import * as Record2 from "effect/Record";
|
|
2539
|
+
import * as Schema16 from "effect/Schema";
|
|
2540
|
+
import { ArtifactId as ArtifactId7 } from "@dxos/assistant";
|
|
2541
|
+
import { DXN as DXN2, Database as Database14, Entity as Entity3, Filter as Filter5, Obj as Obj11, Relation as Relation2, Tag as Tag2, Type as Type5 } from "@dxos/echo";
|
|
2542
|
+
import { invariant } from "@dxos/invariant";
|
|
2543
|
+
import { trim as trim11 } from "@dxos/util";
|
|
2544
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/core/assistant-toolkit/src/toolkits/SystemToolkit.ts";
|
|
2545
|
+
var SystemToolkit = Toolkit6.make(
|
|
2436
2546
|
//
|
|
2437
|
-
//
|
|
2547
|
+
// Schema
|
|
2438
2548
|
//
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2549
|
+
Tool3.make("schema-list", {
|
|
2550
|
+
description: trim11`
|
|
2551
|
+
Lists schemas definitions.
|
|
2552
|
+
`,
|
|
2553
|
+
parameters: {
|
|
2554
|
+
// TODO(wittjosiah): Remove this once parameter-less tools are fixed.
|
|
2555
|
+
limit: Schema16.Number
|
|
2556
|
+
},
|
|
2557
|
+
// TODO(dmaretskyi): Effect returns ({ result, encodedResult })
|
|
2558
|
+
success: Schema16.Any,
|
|
2559
|
+
failure: Schema16.Never,
|
|
2560
|
+
dependencies: [
|
|
2561
|
+
Database14.Service
|
|
2562
|
+
]
|
|
2563
|
+
}),
|
|
2564
|
+
Tool3.make("schema-add", {
|
|
2565
|
+
description: trim11`
|
|
2566
|
+
Adds a schema to the space.
|
|
2567
|
+
The name will be used when displayed to the user.
|
|
2568
|
+
The typename must be in the format of "example.com/type/Type".
|
|
2569
|
+
`,
|
|
2570
|
+
parameters: {
|
|
2571
|
+
name: Schema16.String,
|
|
2572
|
+
typename: Schema16.String,
|
|
2573
|
+
jsonSchema: Schema16.Any
|
|
2574
|
+
},
|
|
2575
|
+
success: Schema16.Any,
|
|
2576
|
+
failure: Schema16.Never,
|
|
2577
|
+
dependencies: [
|
|
2578
|
+
Database14.Service
|
|
2579
|
+
]
|
|
2580
|
+
}),
|
|
2581
|
+
//
|
|
2582
|
+
// Query
|
|
2583
|
+
//
|
|
2584
|
+
Tool3.make("query", {
|
|
2585
|
+
description: trim11`
|
|
2586
|
+
Queries objects in the space.
|
|
2587
|
+
Get the typename from the schema-list tool.
|
|
2588
|
+
`,
|
|
2589
|
+
parameters: {
|
|
2590
|
+
typename: Schema16.String
|
|
2591
|
+
},
|
|
2592
|
+
success: Schema16.Any,
|
|
2593
|
+
failure: Schema16.Never,
|
|
2594
|
+
dependencies: [
|
|
2595
|
+
Database14.Service
|
|
2596
|
+
]
|
|
2597
|
+
}),
|
|
2598
|
+
//
|
|
2599
|
+
// Objects
|
|
2600
|
+
//
|
|
2601
|
+
Tool3.make("object-create", {
|
|
2602
|
+
description: trim11`
|
|
2603
|
+
Creates a new object and adds it to the current space.
|
|
2604
|
+
Get the schema from the schema-list tool and ensure that the data matches the corresponding schema.
|
|
2605
|
+
`,
|
|
2606
|
+
parameters: {
|
|
2607
|
+
typename: Schema16.String,
|
|
2608
|
+
data: Schema16.Any
|
|
2609
|
+
},
|
|
2610
|
+
success: Schema16.Any,
|
|
2611
|
+
failure: Schema16.Never,
|
|
2612
|
+
dependencies: [
|
|
2613
|
+
Database14.Service
|
|
2614
|
+
]
|
|
2615
|
+
}),
|
|
2616
|
+
Tool3.make("object-delete", {
|
|
2617
|
+
description: trim11`
|
|
2618
|
+
Deletes the object.
|
|
2619
|
+
`,
|
|
2620
|
+
parameters: {
|
|
2621
|
+
id: ArtifactId7.annotations({
|
|
2622
|
+
description: "The ID of the object."
|
|
2623
|
+
})
|
|
2624
|
+
},
|
|
2625
|
+
success: Schema16.Any,
|
|
2626
|
+
failure: Schema16.Never,
|
|
2627
|
+
dependencies: [
|
|
2628
|
+
Database14.Service
|
|
2629
|
+
]
|
|
2630
|
+
}),
|
|
2631
|
+
Tool3.make("object-update", {
|
|
2632
|
+
description: trim11`
|
|
2633
|
+
Updates the object properties.
|
|
2634
|
+
`,
|
|
2635
|
+
parameters: {
|
|
2636
|
+
id: ArtifactId7.annotations({
|
|
2637
|
+
description: "The ID of the object."
|
|
2638
|
+
}),
|
|
2639
|
+
properties: Schema16.Record({
|
|
2640
|
+
key: Schema16.String,
|
|
2641
|
+
value: Schema16.Any
|
|
2642
|
+
})
|
|
2643
|
+
},
|
|
2644
|
+
success: Schema16.Any,
|
|
2645
|
+
failure: Schema16.Never,
|
|
2646
|
+
dependencies: [
|
|
2647
|
+
Database14.Service
|
|
2648
|
+
]
|
|
2649
|
+
}),
|
|
2650
|
+
//
|
|
2651
|
+
// Relations
|
|
2652
|
+
//
|
|
2653
|
+
Tool3.make("relation-create", {
|
|
2654
|
+
description: trim11`
|
|
2655
|
+
Creates a new relation and adds it to the current space.
|
|
2656
|
+
Get the schema from the schema-list tool and ensure that the data matches the corresponding schema.
|
|
2657
|
+
`,
|
|
2658
|
+
parameters: {
|
|
2659
|
+
typename: Schema16.String,
|
|
2660
|
+
source: ArtifactId7.annotations({
|
|
2661
|
+
description: "The ID of the source object."
|
|
2662
|
+
}),
|
|
2663
|
+
target: ArtifactId7.annotations({
|
|
2664
|
+
description: "The ID of the target object."
|
|
2665
|
+
}),
|
|
2666
|
+
data: Schema16.Any.annotations({
|
|
2667
|
+
description: "The data to be stored in the relation."
|
|
2668
|
+
})
|
|
2669
|
+
},
|
|
2670
|
+
success: Schema16.Any,
|
|
2671
|
+
failure: Schema16.Never,
|
|
2672
|
+
dependencies: [
|
|
2673
|
+
Database14.Service
|
|
2674
|
+
]
|
|
2675
|
+
}),
|
|
2676
|
+
Tool3.make("relation-delete", {
|
|
2677
|
+
description: trim11`
|
|
2678
|
+
Deletes the relation.
|
|
2679
|
+
`,
|
|
2680
|
+
parameters: {
|
|
2681
|
+
id: ArtifactId7.annotations({
|
|
2682
|
+
description: "The ID of the relation."
|
|
2683
|
+
})
|
|
2684
|
+
},
|
|
2685
|
+
success: Schema16.Any,
|
|
2686
|
+
failure: Schema16.Never,
|
|
2687
|
+
dependencies: [
|
|
2688
|
+
Database14.Service
|
|
2689
|
+
]
|
|
2690
|
+
}),
|
|
2691
|
+
//
|
|
2692
|
+
// Tags
|
|
2693
|
+
//
|
|
2694
|
+
Tool3.make("tag-add", {
|
|
2695
|
+
description: trim11`
|
|
2696
|
+
Adds a tag to an object.
|
|
2697
|
+
Tags are objects of type ${Tag2.Tag.typename}.
|
|
2698
|
+
`,
|
|
2699
|
+
parameters: {
|
|
2700
|
+
tagId: ArtifactId7.annotations({
|
|
2701
|
+
description: "The ID of the tag."
|
|
2702
|
+
}),
|
|
2703
|
+
objectId: ArtifactId7.annotations({
|
|
2704
|
+
description: "The ID of the object."
|
|
2705
|
+
})
|
|
2706
|
+
},
|
|
2707
|
+
success: Schema16.Any,
|
|
2708
|
+
failure: Schema16.Never,
|
|
2709
|
+
dependencies: [
|
|
2710
|
+
Database14.Service
|
|
2711
|
+
]
|
|
2712
|
+
}),
|
|
2713
|
+
Tool3.make("tag-remove", {
|
|
2714
|
+
description: trim11`
|
|
2715
|
+
Removes a tag from an object.
|
|
2716
|
+
Tags are objects of type ${Tag2.Tag.typename}.
|
|
2717
|
+
`,
|
|
2718
|
+
parameters: {
|
|
2719
|
+
tagId: ArtifactId7.annotations({
|
|
2720
|
+
description: "The ID of the tag."
|
|
2721
|
+
}),
|
|
2722
|
+
objectId: ArtifactId7.annotations({
|
|
2723
|
+
description: "The ID of the object."
|
|
2724
|
+
})
|
|
2725
|
+
},
|
|
2726
|
+
success: Schema16.Any,
|
|
2727
|
+
failure: Schema16.Never,
|
|
2728
|
+
dependencies: [
|
|
2729
|
+
Database14.Service
|
|
2730
|
+
]
|
|
2731
|
+
})
|
|
2732
|
+
);
|
|
2733
|
+
var tools2 = Record2.keys(SystemToolkit.tools);
|
|
2734
|
+
var layer4 = () => SystemToolkit.toLayer({
|
|
2735
|
+
["schema-list"]: Effect17.fnUntraced(function* () {
|
|
2736
|
+
const { db } = yield* Database14.Service;
|
|
2737
|
+
const schema = yield* Effect17.promise(() => db.schemaRegistry.query({
|
|
2738
|
+
location: [
|
|
2739
|
+
"database",
|
|
2740
|
+
"runtime"
|
|
2741
|
+
]
|
|
2742
|
+
}).run());
|
|
2743
|
+
return schema.map((schema2) => {
|
|
2744
|
+
const meta = Type5.getMeta(schema2);
|
|
2745
|
+
return {
|
|
2746
|
+
typename: Type5.getTypename(schema2),
|
|
2747
|
+
jsonSchema: Type5.toJsonSchema(schema2),
|
|
2748
|
+
kind: meta?.sourceSchema ? "relation" : "record"
|
|
2749
|
+
};
|
|
2750
|
+
});
|
|
2751
|
+
}),
|
|
2752
|
+
["schema-add"]: Effect17.fnUntraced(function* ({ name, typename, jsonSchema }) {
|
|
2753
|
+
const { db } = yield* Database14.Service;
|
|
2754
|
+
yield* Effect17.promise(() => db.schemaRegistry.register([
|
|
2755
|
+
{
|
|
2756
|
+
typename,
|
|
2757
|
+
version: "0.1.0",
|
|
2758
|
+
jsonSchema,
|
|
2759
|
+
name
|
|
2760
|
+
}
|
|
2761
|
+
]));
|
|
2762
|
+
}),
|
|
2763
|
+
["query"]: Effect17.fnUntraced(function* ({ typename }) {
|
|
2764
|
+
const objects = yield* Database14.Service.runQuery(Filter5.typename(typename));
|
|
2765
|
+
return objects;
|
|
2766
|
+
}),
|
|
2767
|
+
["object-create"]: Effect17.fnUntraced(function* ({ typename, data }) {
|
|
2768
|
+
const { db } = yield* Database14.Service;
|
|
2769
|
+
const schema = yield* Effect17.promise(() => db.schemaRegistry.query({
|
|
2770
|
+
typename,
|
|
2771
|
+
location: [
|
|
2772
|
+
"database",
|
|
2773
|
+
"runtime"
|
|
2774
|
+
]
|
|
2775
|
+
}).first());
|
|
2776
|
+
invariant(Type5.isObjectSchema(schema), "Schema is not an object schema", {
|
|
2777
|
+
F: __dxlog_file8,
|
|
2778
|
+
L: 238,
|
|
2779
|
+
S: this,
|
|
2780
|
+
A: [
|
|
2781
|
+
"Type.isObjectSchema(schema)",
|
|
2782
|
+
"'Schema is not an object schema'"
|
|
2783
|
+
]
|
|
2784
|
+
});
|
|
2785
|
+
const object = db.add(Obj11.make(schema, data));
|
|
2786
|
+
return object;
|
|
2787
|
+
}),
|
|
2788
|
+
["object-delete"]: Effect17.fnUntraced(function* ({ id }) {
|
|
2789
|
+
const { db } = yield* Database14.Service;
|
|
2790
|
+
const object = yield* Database14.Service.resolve(DXN2.parse(id));
|
|
2791
|
+
db.remove(object);
|
|
2792
|
+
return object;
|
|
2793
|
+
}),
|
|
2794
|
+
["object-update"]: Effect17.fnUntraced(function* ({ id, properties }) {
|
|
2795
|
+
const object = yield* Database14.Service.resolve(DXN2.parse(id));
|
|
2796
|
+
Entity3.change(object, (obj) => {
|
|
2797
|
+
for (const [key, value2] of Object.entries(properties)) {
|
|
2798
|
+
obj[key] = value2;
|
|
2799
|
+
}
|
|
2800
|
+
});
|
|
2801
|
+
return object;
|
|
2802
|
+
}),
|
|
2803
|
+
["relation-create"]: Effect17.fnUntraced(function* ({ typename, source, target, data }) {
|
|
2804
|
+
const { db } = yield* Database14.Service;
|
|
2805
|
+
const schema = yield* Effect17.promise(() => db.schemaRegistry.query({
|
|
2806
|
+
typename,
|
|
2807
|
+
location: [
|
|
2808
|
+
"database",
|
|
2809
|
+
"runtime"
|
|
2810
|
+
]
|
|
2811
|
+
}).first());
|
|
2812
|
+
invariant(Type5.isRelationSchema(schema), "Schema is not a relation schema", {
|
|
2813
|
+
F: __dxlog_file8,
|
|
2814
|
+
L: 267,
|
|
2815
|
+
S: this,
|
|
2816
|
+
A: [
|
|
2817
|
+
"Type.isRelationSchema(schema)",
|
|
2818
|
+
"'Schema is not a relation schema'"
|
|
2819
|
+
]
|
|
2820
|
+
});
|
|
2821
|
+
const sourceObj = yield* Database14.Service.resolve(DXN2.parse(source));
|
|
2822
|
+
const targetObj = yield* Database14.Service.resolve(DXN2.parse(target));
|
|
2823
|
+
const relation = db.add(Relation2.make(schema, {
|
|
2824
|
+
[Relation2.Source]: sourceObj,
|
|
2825
|
+
[Relation2.Target]: targetObj,
|
|
2826
|
+
...data
|
|
2827
|
+
}));
|
|
2828
|
+
return relation;
|
|
2829
|
+
}),
|
|
2830
|
+
["relation-delete"]: Effect17.fnUntraced(function* ({ id }) {
|
|
2831
|
+
const { db } = yield* Database14.Service;
|
|
2832
|
+
const relation = yield* Database14.Service.resolve(DXN2.parse(id));
|
|
2833
|
+
db.remove(relation);
|
|
2834
|
+
return relation;
|
|
2835
|
+
}),
|
|
2836
|
+
["tag-add"]: Effect17.fnUntraced(function* ({ tagId, objectId }) {
|
|
2837
|
+
const object = yield* Database14.Service.resolve(DXN2.parse(objectId));
|
|
2838
|
+
Entity3.change(object, (obj) => Entity3.addTag(obj, DXN2.parse(tagId).toString()));
|
|
2839
|
+
return object;
|
|
2840
|
+
}),
|
|
2841
|
+
["tag-remove"]: Effect17.fnUntraced(function* ({ tagId, objectId }) {
|
|
2842
|
+
const object = yield* Database14.Service.resolve(DXN2.parse(objectId));
|
|
2843
|
+
Entity3.change(object, (obj) => Entity3.removeTag(obj, DXN2.parse(tagId).toString()));
|
|
2844
|
+
return object;
|
|
2845
|
+
})
|
|
2846
|
+
});
|
|
2448
2847
|
export {
|
|
2449
2848
|
Agent,
|
|
2849
|
+
AssistantToolkit_exports as AssistantToolkit,
|
|
2450
2850
|
design_default as DesignBlueprint,
|
|
2451
2851
|
Discord,
|
|
2452
2852
|
discord_default as DiscordBlueprint,
|
|
@@ -2456,17 +2856,16 @@ export {
|
|
|
2456
2856
|
linear_default as LinearBlueprint,
|
|
2457
2857
|
LocalSearchHandler,
|
|
2458
2858
|
LocalSearchToolkit,
|
|
2459
|
-
MapSchema,
|
|
2460
2859
|
planning_default as PlanningBlueprint,
|
|
2461
2860
|
Research,
|
|
2462
2861
|
research_default2 as ResearchBlueprint,
|
|
2463
2862
|
ResearchDataTypes,
|
|
2464
2863
|
ResearchGraph,
|
|
2465
2864
|
Subgraph,
|
|
2865
|
+
SystemToolkit_exports as SystemToolkit,
|
|
2466
2866
|
Tasks,
|
|
2467
2867
|
websearch_default as WebSearchBlueprint,
|
|
2468
2868
|
WebSearchToolkit,
|
|
2469
|
-
capabilities,
|
|
2470
2869
|
contextQueueLayerFromResearchGraph,
|
|
2471
2870
|
createExtractionSchema,
|
|
2472
2871
|
createResearchGraph,
|