@dxos/assistant-toolkit 0.8.4-main.ae835ea
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/LICENSE +8 -0
- package/README.md +3 -0
- package/dist/lib/browser/index.mjs +2481 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/node-esm/index.mjs +2483 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/types/src/blueprints/design/design-blueprint.d.ts +4 -0
- package/dist/types/src/blueprints/design/design-blueprint.d.ts.map +1 -0
- package/dist/types/src/blueprints/design/design-blueprint.test.d.ts +2 -0
- package/dist/types/src/blueprints/design/design-blueprint.test.d.ts.map +1 -0
- package/dist/types/src/blueprints/design/index.d.ts +3 -0
- package/dist/types/src/blueprints/design/index.d.ts.map +1 -0
- package/dist/types/src/blueprints/discord/discord-blueprint.d.ts +18 -0
- package/dist/types/src/blueprints/discord/discord-blueprint.d.ts.map +1 -0
- package/dist/types/src/blueprints/discord/index.d.ts +3 -0
- package/dist/types/src/blueprints/discord/index.d.ts.map +1 -0
- package/dist/types/src/blueprints/index.d.ts +7 -0
- package/dist/types/src/blueprints/index.d.ts.map +1 -0
- package/dist/types/src/blueprints/linear/index.d.ts +3 -0
- package/dist/types/src/blueprints/linear/index.d.ts.map +1 -0
- package/dist/types/src/blueprints/linear/linear-blueprint.d.ts +18 -0
- package/dist/types/src/blueprints/linear/linear-blueprint.d.ts.map +1 -0
- package/dist/types/src/blueprints/planning/index.d.ts +3 -0
- package/dist/types/src/blueprints/planning/index.d.ts.map +1 -0
- package/dist/types/src/blueprints/planning/planning-blueprint.d.ts +4 -0
- package/dist/types/src/blueprints/planning/planning-blueprint.d.ts.map +1 -0
- package/dist/types/src/blueprints/planning/planning-blueprint.test.d.ts +2 -0
- package/dist/types/src/blueprints/planning/planning-blueprint.test.d.ts.map +1 -0
- package/dist/types/src/blueprints/research/index.d.ts +3 -0
- package/dist/types/src/blueprints/research/index.d.ts.map +1 -0
- package/dist/types/src/blueprints/research/research-blueprint.d.ts +4 -0
- package/dist/types/src/blueprints/research/research-blueprint.d.ts.map +1 -0
- package/dist/types/src/blueprints/research/research-blueprint.test.d.ts +2 -0
- package/dist/types/src/blueprints/research/research-blueprint.test.d.ts.map +1 -0
- package/dist/types/src/blueprints/testing.d.ts +12 -0
- package/dist/types/src/blueprints/testing.d.ts.map +1 -0
- package/dist/types/src/blueprints/websearch/index.d.ts +4 -0
- package/dist/types/src/blueprints/websearch/index.d.ts.map +1 -0
- package/dist/types/src/blueprints/websearch/websearch-blueprint.d.ts +4 -0
- package/dist/types/src/blueprints/websearch/websearch-blueprint.d.ts.map +1 -0
- package/dist/types/src/blueprints/websearch/websearch-toolkit.d.ts +26 -0
- package/dist/types/src/blueprints/websearch/websearch-toolkit.d.ts.map +1 -0
- package/dist/types/src/experimental/feed.test.d.ts +2 -0
- package/dist/types/src/experimental/feed.test.d.ts.map +1 -0
- package/dist/types/src/functions/agent/index.d.ts +5 -0
- package/dist/types/src/functions/agent/index.d.ts.map +1 -0
- package/dist/types/src/functions/agent/prompt.d.ts +11 -0
- package/dist/types/src/functions/agent/prompt.d.ts.map +1 -0
- package/dist/types/src/functions/discord/fetch-messages.d.ts +11 -0
- package/dist/types/src/functions/discord/fetch-messages.d.ts.map +1 -0
- package/dist/types/src/functions/discord/fetch-messages.test.d.ts +2 -0
- package/dist/types/src/functions/discord/fetch-messages.test.d.ts.map +1 -0
- package/dist/types/src/functions/discord/index.d.ts +12 -0
- package/dist/types/src/functions/discord/index.d.ts.map +1 -0
- package/dist/types/src/functions/document/index.d.ts +12 -0
- package/dist/types/src/functions/document/index.d.ts.map +1 -0
- package/dist/types/src/functions/document/read.d.ts +7 -0
- package/dist/types/src/functions/document/read.d.ts.map +1 -0
- package/dist/types/src/functions/document/update.d.ts +6 -0
- package/dist/types/src/functions/document/update.d.ts.map +1 -0
- package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts +173 -0
- package/dist/types/src/functions/entity-extraction/entity-extraction.d.ts.map +1 -0
- package/dist/types/src/functions/entity-extraction/entity-extraction.test.d.ts +2 -0
- package/dist/types/src/functions/entity-extraction/entity-extraction.test.d.ts.map +1 -0
- package/dist/types/src/functions/entity-extraction/index.d.ts +174 -0
- package/dist/types/src/functions/entity-extraction/index.d.ts.map +1 -0
- package/dist/types/src/functions/exa/exa.d.ts +5 -0
- package/dist/types/src/functions/exa/exa.d.ts.map +1 -0
- package/dist/types/src/functions/exa/index.d.ts +3 -0
- package/dist/types/src/functions/exa/index.d.ts.map +1 -0
- package/dist/types/src/functions/exa/mock.d.ts +5 -0
- package/dist/types/src/functions/exa/mock.d.ts.map +1 -0
- package/dist/types/src/functions/github/fetch-prs.d.ts +6 -0
- package/dist/types/src/functions/github/fetch-prs.d.ts.map +1 -0
- package/dist/types/src/functions/index.d.ts +8 -0
- package/dist/types/src/functions/index.d.ts.map +1 -0
- package/dist/types/src/functions/linear/index.d.ts +9 -0
- package/dist/types/src/functions/linear/index.d.ts.map +1 -0
- package/dist/types/src/functions/linear/linear.test.d.ts +2 -0
- package/dist/types/src/functions/linear/linear.test.d.ts.map +1 -0
- package/dist/types/src/functions/linear/sync-issues.d.ts +12 -0
- package/dist/types/src/functions/linear/sync-issues.d.ts.map +1 -0
- package/dist/types/src/functions/research/create-document.d.ts +7 -0
- package/dist/types/src/functions/research/create-document.d.ts.map +1 -0
- package/dist/types/src/functions/research/graph.d.ts +64 -0
- package/dist/types/src/functions/research/graph.d.ts.map +1 -0
- package/dist/types/src/functions/research/graph.test.d.ts +2 -0
- package/dist/types/src/functions/research/graph.test.d.ts.map +1 -0
- package/dist/types/src/functions/research/index.d.ts +19 -0
- package/dist/types/src/functions/research/index.d.ts.map +1 -0
- package/dist/types/src/functions/research/research-graph.d.ts +18 -0
- package/dist/types/src/functions/research/research-graph.d.ts.map +1 -0
- package/dist/types/src/functions/research/research.d.ts +13 -0
- package/dist/types/src/functions/research/research.d.ts.map +1 -0
- package/dist/types/src/functions/research/research.test.d.ts +2 -0
- package/dist/types/src/functions/research/research.test.d.ts.map +1 -0
- package/dist/types/src/functions/research/types.d.ts +384 -0
- package/dist/types/src/functions/research/types.d.ts.map +1 -0
- package/dist/types/src/functions/tasks/index.d.ts +15 -0
- package/dist/types/src/functions/tasks/index.d.ts.map +1 -0
- package/dist/types/src/functions/tasks/read.d.ts +7 -0
- package/dist/types/src/functions/tasks/read.d.ts.map +1 -0
- package/dist/types/src/functions/tasks/task-list.d.ts +74 -0
- package/dist/types/src/functions/tasks/task-list.d.ts.map +1 -0
- package/dist/types/src/functions/tasks/task-list.test.d.ts +2 -0
- package/dist/types/src/functions/tasks/task-list.test.d.ts.map +1 -0
- package/dist/types/src/functions/tasks/update.d.ts +9 -0
- package/dist/types/src/functions/tasks/update.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +5 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/plugins.d.ts +19 -0
- package/dist/types/src/plugins.d.ts.map +1 -0
- package/dist/types/src/sync/index.d.ts +2 -0
- package/dist/types/src/sync/index.d.ts.map +1 -0
- package/dist/types/src/sync/sync.d.ts +15 -0
- package/dist/types/src/sync/sync.d.ts.map +1 -0
- package/dist/types/src/testing/data/exa-search-1748337321991.d.ts +38 -0
- package/dist/types/src/testing/data/exa-search-1748337321991.d.ts.map +1 -0
- package/dist/types/src/testing/data/exa-search-1748337331526.d.ts +37 -0
- package/dist/types/src/testing/data/exa-search-1748337331526.d.ts.map +1 -0
- package/dist/types/src/testing/data/exa-search-1748337344119.d.ts +58 -0
- package/dist/types/src/testing/data/exa-search-1748337344119.d.ts.map +1 -0
- package/dist/types/src/testing/data/index.d.ts +3 -0
- package/dist/types/src/testing/data/index.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/util/graphql.d.ts +22 -0
- package/dist/types/src/util/graphql.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +2 -0
- package/dist/types/src/util/index.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +67 -0
- package/src/blueprints/design/design-blueprint.test.ts +108 -0
- package/src/blueprints/design/design-blueprint.ts +33 -0
- package/src/blueprints/design/index.ts +7 -0
- package/src/blueprints/discord/discord-blueprint.ts +34 -0
- package/src/blueprints/discord/index.ts +7 -0
- package/src/blueprints/index.ts +10 -0
- package/src/blueprints/linear/index.ts +7 -0
- package/src/blueprints/linear/linear-blueprint.ts +35 -0
- package/src/blueprints/planning/index.ts +7 -0
- package/src/blueprints/planning/planning-blueprint.test.ts +129 -0
- package/src/blueprints/planning/planning-blueprint.ts +98 -0
- package/src/blueprints/research/index.ts +7 -0
- package/src/blueprints/research/research-blueprint.test.ts +7 -0
- package/src/blueprints/research/research-blueprint.ts +45 -0
- package/src/blueprints/testing.ts +34 -0
- package/src/blueprints/websearch/index.ts +8 -0
- package/src/blueprints/websearch/websearch-blueprint.ts +20 -0
- package/src/blueprints/websearch/websearch-toolkit.ts +8 -0
- package/src/experimental/feed.test.ts +108 -0
- package/src/functions/agent/index.ts +11 -0
- package/src/functions/agent/prompt.ts +101 -0
- package/src/functions/discord/fetch-messages.test.ts +59 -0
- package/src/functions/discord/fetch-messages.ts +251 -0
- package/src/functions/discord/index.ts +9 -0
- package/src/functions/document/index.ts +11 -0
- package/src/functions/document/read.ts +29 -0
- package/src/functions/document/update.ts +30 -0
- package/src/functions/entity-extraction/entity-extraction.conversations.json +1 -0
- package/src/functions/entity-extraction/entity-extraction.test.ts +100 -0
- package/src/functions/entity-extraction/entity-extraction.ts +163 -0
- package/src/functions/entity-extraction/index.ts +9 -0
- package/src/functions/exa/exa.ts +37 -0
- package/src/functions/exa/index.ts +6 -0
- package/src/functions/exa/mock.ts +71 -0
- package/src/functions/github/fetch-prs.ts +30 -0
- package/src/functions/index.ts +11 -0
- package/src/functions/linear/index.ts +9 -0
- package/src/functions/linear/linear.test.ts +86 -0
- package/src/functions/linear/sync-issues.ts +189 -0
- package/src/functions/research/create-document.ts +69 -0
- package/src/functions/research/graph.test.ts +69 -0
- package/src/functions/research/graph.ts +388 -0
- package/src/functions/research/index.ts +15 -0
- package/src/functions/research/instructions-research.tpl +98 -0
- package/src/functions/research/research-graph.ts +47 -0
- package/src/functions/research/research.conversations.json +10714 -0
- package/src/functions/research/research.test.ts +240 -0
- package/src/functions/research/research.ts +155 -0
- package/src/functions/research/types.ts +24 -0
- package/src/functions/tasks/index.ts +11 -0
- package/src/functions/tasks/read.ts +34 -0
- package/src/functions/tasks/task-list.test.ts +99 -0
- package/src/functions/tasks/task-list.ts +165 -0
- package/src/functions/tasks/update.ts +52 -0
- package/src/index.ts +8 -0
- package/src/plugins.tsx +68 -0
- package/src/sync/index.ts +5 -0
- package/src/sync/sync.ts +87 -0
- package/src/testing/data/exa-search-1748337321991.ts +131 -0
- package/src/testing/data/exa-search-1748337331526.ts +144 -0
- package/src/testing/data/exa-search-1748337344119.ts +133 -0
- package/src/testing/data/index.ts +11 -0
- package/src/testing/index.ts +5 -0
- package/src/typedefs.d.ts +8 -0
- package/src/util/graphql.ts +31 -0
- package/src/util/index.ts +5 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hierarchical Task List Manager.
|
|
7
|
+
*
|
|
8
|
+
* A framework for managing hierarchical task lists where each line is a task.
|
|
9
|
+
* Designed to work with language model agents that receive documents with line numbers.
|
|
10
|
+
*/
|
|
11
|
+
export class MarkdownTasks {
|
|
12
|
+
private _lineEndings: string;
|
|
13
|
+
private _content: string[];
|
|
14
|
+
|
|
15
|
+
constructor(initialContent: string = '') {
|
|
16
|
+
// Detect line endings.
|
|
17
|
+
this._lineEndings = initialContent.includes('\r\n') ? '\r\n' : '\n';
|
|
18
|
+
this._content = initialContent ? initialContent.split(this._lineEndings) : [];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get the current document content with line numbers prefixed.
|
|
23
|
+
*/
|
|
24
|
+
getNumberedContent(): string {
|
|
25
|
+
return this._content
|
|
26
|
+
.map((line, index) => `${(index + 1).toString().padStart(3, ' ')}→${line}`)
|
|
27
|
+
.join(this._lineEndings);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get the raw document content without line numbers.
|
|
32
|
+
*/
|
|
33
|
+
getRawContent(): string {
|
|
34
|
+
return this._content.join(this._lineEndings);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Insert a new task at the specified line number (1-based).
|
|
39
|
+
* Indentation level determines hierarchy (0, 2, 4, 6 spaces etc.)
|
|
40
|
+
*/
|
|
41
|
+
insertTask(lineNumber: number, taskText: string, completed: boolean = false, indent: number = 0): void {
|
|
42
|
+
const indentStr = ' '.repeat(indent);
|
|
43
|
+
const taskLine = completed ? `${indentStr}- [x] ${taskText}` : `${indentStr}- [ ] ${taskText}`;
|
|
44
|
+
const insertIndex = Math.max(0, Math.min(lineNumber - 1, this._content.length));
|
|
45
|
+
this._content.splice(insertIndex, 0, taskLine);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Delete a task at the specified line number (1-based).
|
|
50
|
+
*/
|
|
51
|
+
deleteTask(lineNumber: number): boolean {
|
|
52
|
+
if (lineNumber < 1 || lineNumber > this._content.length) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
this._content.splice(lineNumber - 1, 1);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Update the text of a task at the specified line number (1-based).
|
|
61
|
+
*/
|
|
62
|
+
updateTaskText(lineNumber: number, newText: string): boolean {
|
|
63
|
+
if (lineNumber < 1 || lineNumber > this._content.length) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const currentLine = this._content[lineNumber - 1];
|
|
68
|
+
const taskMatch = currentLine.match(/^(\s*- \[[x ]\] )(.*)$/);
|
|
69
|
+
|
|
70
|
+
if (taskMatch) {
|
|
71
|
+
this._content[lineNumber - 1] = `${taskMatch[1]}${newText}`;
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Mark a task as complete or incomplete at the specified line number (1-based).
|
|
79
|
+
*/
|
|
80
|
+
toggleTaskCompletion(lineNumber: number, completed?: boolean): boolean {
|
|
81
|
+
if (lineNumber < 1 || lineNumber > this._content.length) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const currentLine = this._content[lineNumber - 1];
|
|
86
|
+
const taskMatch = currentLine.match(/^(\s*- \[)([x ])(.*)$/);
|
|
87
|
+
if (taskMatch) {
|
|
88
|
+
const isCurrentlyComplete = taskMatch[2] === 'x';
|
|
89
|
+
const newStatus = completed !== undefined ? completed : !isCurrentlyComplete;
|
|
90
|
+
const statusChar = newStatus ? 'x' : ' ';
|
|
91
|
+
this._content[lineNumber - 1] = `${taskMatch[1]}${statusChar}${taskMatch[3]}`;
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Change the indentation level of a task (for hierarchy).
|
|
100
|
+
*/
|
|
101
|
+
setTaskIndent(lineNumber: number, indent: number): boolean {
|
|
102
|
+
if (lineNumber < 1 || lineNumber > this._content.length) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const currentLine = this._content[lineNumber - 1];
|
|
107
|
+
const taskMatch = currentLine.match(/^\s*- (\[[x ]\] .*)$/);
|
|
108
|
+
if (taskMatch) {
|
|
109
|
+
const indentStr = ' '.repeat(indent);
|
|
110
|
+
this._content[lineNumber - 1] = `${indentStr}- ${taskMatch[1]}`;
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Get the total number of lines in the document.
|
|
119
|
+
*/
|
|
120
|
+
getLineCount(): number {
|
|
121
|
+
return this._content.length;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Apply multiple operations atomically.
|
|
126
|
+
*/
|
|
127
|
+
applyOperations(operations: TaskOperation[]): void {
|
|
128
|
+
// Sort operations by line number in descending order to avoid index shifts.
|
|
129
|
+
const sortedOps = [...operations].sort((a, b) => {
|
|
130
|
+
const aLine = 'lineNumber' in a ? a.lineNumber : 0;
|
|
131
|
+
const bLine = 'lineNumber' in b ? b.lineNumber : 0;
|
|
132
|
+
return bLine - aLine;
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
for (const op of sortedOps) {
|
|
136
|
+
switch (op.type) {
|
|
137
|
+
case 'insertTask':
|
|
138
|
+
this.insertTask(op.lineNumber, op.text, op.completed, op.indent);
|
|
139
|
+
break;
|
|
140
|
+
case 'deleteTask':
|
|
141
|
+
this.deleteTask(op.lineNumber);
|
|
142
|
+
break;
|
|
143
|
+
case 'updateTaskText':
|
|
144
|
+
this.updateTaskText(op.lineNumber, op.text);
|
|
145
|
+
break;
|
|
146
|
+
case 'toggleTaskCompletion':
|
|
147
|
+
this.toggleTaskCompletion(op.lineNumber, op.completed);
|
|
148
|
+
break;
|
|
149
|
+
case 'setTaskIndent':
|
|
150
|
+
this.setTaskIndent(op.lineNumber, op.indent);
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Operation types for batch task updates.
|
|
159
|
+
*/
|
|
160
|
+
export type TaskOperation =
|
|
161
|
+
| { type: 'insertTask'; lineNumber: number; text: string; completed?: boolean; indent?: number }
|
|
162
|
+
| { type: 'deleteTask'; lineNumber: number }
|
|
163
|
+
| { type: 'updateTaskText'; lineNumber: number; text: string }
|
|
164
|
+
| { type: 'toggleTaskCompletion'; lineNumber: number; completed?: boolean }
|
|
165
|
+
| { type: 'setTaskIndent'; lineNumber: number; indent: number };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as Schema from 'effect/Schema';
|
|
7
|
+
|
|
8
|
+
import { ArtifactId } from '@dxos/assistant';
|
|
9
|
+
import { DatabaseService, defineFunction } from '@dxos/functions';
|
|
10
|
+
import { Markdown } from '@dxos/plugin-markdown/types';
|
|
11
|
+
|
|
12
|
+
import { MarkdownTasks, type TaskOperation } from './task-list';
|
|
13
|
+
|
|
14
|
+
export default defineFunction({
|
|
15
|
+
key: 'dxos.org/function/markdown/update-tasks',
|
|
16
|
+
name: 'Update markdown',
|
|
17
|
+
description: 'Creates and updates tasks in markdown documents.',
|
|
18
|
+
inputSchema: Schema.Struct({
|
|
19
|
+
id: ArtifactId.annotations({
|
|
20
|
+
description: 'The ID of the document to update.',
|
|
21
|
+
}),
|
|
22
|
+
operations: Schema.optional(
|
|
23
|
+
Schema.Array(
|
|
24
|
+
Schema.Any.annotations({
|
|
25
|
+
description: 'Task operations to apply.',
|
|
26
|
+
}),
|
|
27
|
+
),
|
|
28
|
+
),
|
|
29
|
+
}),
|
|
30
|
+
outputSchema: Schema.Struct({
|
|
31
|
+
content: Schema.String,
|
|
32
|
+
numberedContent: Schema.String.annotations({
|
|
33
|
+
description: 'Content with line numbers for agent reference.',
|
|
34
|
+
}),
|
|
35
|
+
}),
|
|
36
|
+
handler: Effect.fn(function* ({ data: { id, operations = [] } }) {
|
|
37
|
+
const doc = yield* DatabaseService.resolve(ArtifactId.toDXN(id), Markdown.Document);
|
|
38
|
+
|
|
39
|
+
// Create task manager and apply operations if provided.
|
|
40
|
+
const { content } = yield* DatabaseService.load(doc.content);
|
|
41
|
+
const taskManager = new MarkdownTasks(content);
|
|
42
|
+
if (operations.length > 0) {
|
|
43
|
+
taskManager.applyOperations(operations as TaskOperation[]);
|
|
44
|
+
// TODO: Update the document content when database operations are fixed.
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
content: taskManager.getRawContent(),
|
|
49
|
+
numberedContent: taskManager.getNumberedContent(),
|
|
50
|
+
};
|
|
51
|
+
}),
|
|
52
|
+
});
|
package/src/index.ts
ADDED
package/src/plugins.tsx
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { type AnyCapability, Capabilities, contributes, createSurface } from '@dxos/app-framework';
|
|
9
|
+
import { type Obj, Type } from '@dxos/echo';
|
|
10
|
+
import { JsonFilter } from '@dxos/react-ui-syntax-highlighter';
|
|
11
|
+
|
|
12
|
+
export const MapSchema = Schema.Struct({
|
|
13
|
+
coordinates: Type.Format.GeoPoint,
|
|
14
|
+
}).pipe(
|
|
15
|
+
Type.Obj({
|
|
16
|
+
typename: 'example.com/type/Map',
|
|
17
|
+
version: '0.1.0',
|
|
18
|
+
}),
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export type MapSchema = Schema.Schema.Type<typeof MapSchema>;
|
|
22
|
+
|
|
23
|
+
// TODO(burdon): Move to ECHO def.
|
|
24
|
+
export type ArtifactsContext = {
|
|
25
|
+
items: Obj.Any[];
|
|
26
|
+
getArtifacts: () => Obj.Any[];
|
|
27
|
+
addArtifact: (artifact: Obj.Any) => void;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
declare global {
|
|
31
|
+
interface ToolContextExtensions {
|
|
32
|
+
artifacts?: ArtifactsContext;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// TODO(dmaretskyi): Removed images from conductor GPT implementation.
|
|
37
|
+
const isImage = (data: any): data is any => false;
|
|
38
|
+
|
|
39
|
+
export const capabilities: AnyCapability[] = [
|
|
40
|
+
contributes(
|
|
41
|
+
Capabilities.ReactSurface,
|
|
42
|
+
createSurface({
|
|
43
|
+
id: 'plugin-image',
|
|
44
|
+
role: 'card--extrinsic',
|
|
45
|
+
filter: (data: any): data is any => isImage(data.value),
|
|
46
|
+
component: ({ data }) => (
|
|
47
|
+
<img
|
|
48
|
+
className='grow object-cover'
|
|
49
|
+
src={`data:image/jpeg;base64,${data.value.source.data}`}
|
|
50
|
+
alt={data.value.prompt ?? `Generated image [id=${data.value.id}]`}
|
|
51
|
+
/>
|
|
52
|
+
),
|
|
53
|
+
}),
|
|
54
|
+
),
|
|
55
|
+
|
|
56
|
+
//
|
|
57
|
+
// Default
|
|
58
|
+
//
|
|
59
|
+
contributes(
|
|
60
|
+
Capabilities.ReactSurface,
|
|
61
|
+
createSurface({
|
|
62
|
+
id: 'plugin-default',
|
|
63
|
+
role: 'card--extrinsic',
|
|
64
|
+
position: 'fallback',
|
|
65
|
+
component: ({ role, data }) => <JsonFilter data={data} />,
|
|
66
|
+
}),
|
|
67
|
+
),
|
|
68
|
+
];
|
package/src/sync/sync.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { Filter, Obj, Query, Ref } from '@dxos/echo';
|
|
8
|
+
import { DatabaseService } from '@dxos/functions';
|
|
9
|
+
import { failedInvariant } from '@dxos/invariant';
|
|
10
|
+
import { log } from '@dxos/log';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Syncs objects to the database.
|
|
14
|
+
* If there's an object with a matching foreign key in the database, it will be updated.
|
|
15
|
+
* Otherwise, a new object will be added.
|
|
16
|
+
* Recursively syncs top-level refs.
|
|
17
|
+
*
|
|
18
|
+
* @param opts.foreignKeyId - The key to use for matching objects.
|
|
19
|
+
*/
|
|
20
|
+
export const syncObjects: (
|
|
21
|
+
objs: Obj.Any[],
|
|
22
|
+
opts: { foreignKeyId: string },
|
|
23
|
+
) => Effect.Effect<Obj.Any[], never, DatabaseService> = Effect.fn('syncObjects')(function* (objs, { foreignKeyId }) {
|
|
24
|
+
return yield* Effect.forEach(
|
|
25
|
+
objs,
|
|
26
|
+
Effect.fnUntraced(function* (obj) {
|
|
27
|
+
// Sync referenced objects.
|
|
28
|
+
for (const key of Object.keys(obj)) {
|
|
29
|
+
if (typeof key !== 'string' || key === 'id') continue;
|
|
30
|
+
if (!Ref.isRef((obj as any)[key])) continue;
|
|
31
|
+
const ref: Ref.Any = (obj as any)[key];
|
|
32
|
+
if (!ref.target) continue;
|
|
33
|
+
if (Obj.getDXN(ref.target).isLocalObjectId()) {
|
|
34
|
+
// obj not persisted to db.
|
|
35
|
+
const [target] = yield* syncObjects([ref.target], { foreignKeyId });
|
|
36
|
+
(obj as any)[key] = Ref.make(target);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const schema = Obj.getSchema(obj) ?? failedInvariant('No schema.');
|
|
41
|
+
const foreignId = Obj.getKeys(obj, foreignKeyId)[0]?.id ?? failedInvariant('No foreign key.');
|
|
42
|
+
const {
|
|
43
|
+
objects: [existing],
|
|
44
|
+
} = yield* DatabaseService.runQuery(
|
|
45
|
+
Query.select(Filter.foreignKeys(schema, [{ source: foreignKeyId, id: foreignId }])),
|
|
46
|
+
);
|
|
47
|
+
log('sync object', {
|
|
48
|
+
type: Obj.getTypename(obj),
|
|
49
|
+
foreignId,
|
|
50
|
+
existing: existing ? Obj.getDXN(existing) : undefined,
|
|
51
|
+
});
|
|
52
|
+
if (!existing) {
|
|
53
|
+
yield* DatabaseService.add(obj);
|
|
54
|
+
return obj;
|
|
55
|
+
} else {
|
|
56
|
+
copyObjectData(existing, obj);
|
|
57
|
+
return existing;
|
|
58
|
+
}
|
|
59
|
+
}),
|
|
60
|
+
{ concurrency: 1 },
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const copyObjectData = (existing: Obj.Any, newObj: Obj.Any) => {
|
|
65
|
+
for (const key of Object.keys(newObj)) {
|
|
66
|
+
if (typeof key !== 'string' || key === 'id') continue;
|
|
67
|
+
if (
|
|
68
|
+
typeof (newObj as any)[key] !== 'string' &&
|
|
69
|
+
typeof (newObj as any)[key] !== 'number' &&
|
|
70
|
+
typeof (newObj as any)[key] !== 'boolean' &&
|
|
71
|
+
!Ref.isRef((newObj as any)[key])
|
|
72
|
+
)
|
|
73
|
+
continue;
|
|
74
|
+
(existing as any)[key] = (newObj as any)[key];
|
|
75
|
+
}
|
|
76
|
+
for (const key of Object.keys(existing)) {
|
|
77
|
+
if (typeof key !== 'string' || key === 'id') continue;
|
|
78
|
+
if (!(key in newObj)) {
|
|
79
|
+
delete (existing as any)[key];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
for (const foreignKey of Obj.getMeta(newObj).keys) {
|
|
83
|
+
Obj.deleteKeys(existing, foreignKey.source);
|
|
84
|
+
// TODO(dmaretskyi): Doesn't work: `Obj.getMeta(existing).keys.push(foreignKey);`
|
|
85
|
+
Obj.getMeta(existing).keys.push({ ...foreignKey });
|
|
86
|
+
}
|
|
87
|
+
};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
requestId: '324936368a74f4db978982172bc18a6c',
|
|
7
|
+
autopromptString: 'AI personal knowledge management tools projects 2024',
|
|
8
|
+
autoDate: '2024-01-01T00:00:00.000Z',
|
|
9
|
+
resolvedSearchType: 'neural',
|
|
10
|
+
results: [
|
|
11
|
+
{
|
|
12
|
+
id: 'https://www.open-notebook.ai/',
|
|
13
|
+
title: 'What is Open Notebook? | Open Notebook',
|
|
14
|
+
url: 'https://www.open-notebook.ai/',
|
|
15
|
+
publishedDate: '2024-01-01T00:00:00.000Z',
|
|
16
|
+
author: '',
|
|
17
|
+
score: 0.3995794951915741,
|
|
18
|
+
text: "Take Control of Your Learning. Privately. A powerful open-source, AI-powered note-taking/research platform that respects your privacy 🎙️ Podcast Generator Transform your notes into engaging podcasts with customizable voices, speakers, and episodes 🤖 AI-Powered Notes Leverage AI to summarize, generate insights, and manage your notes 🔒 Privacy Control Full control over what information AI can access 🔄 Content Integration Support for links, PDFs, TXT, PPT, YouTube, and more What is Open Notebook? Open Notebook is the cognitive partner you always wanted and could never explain why. It combines the power of AI with unwavering privacy controls. It's designed for researchers, students, and professionals who want to enhance their learning and abilities while maintaining complete control over workflows, models, and how their data gets used and exposed. Is this right for me? 📚 Learning Enthusiast You're constantly seeking knowledge and want to go beyond surface-level understanding. Learning for you is about building deep, lasting comprehension. 🤝 You want a learning partner You believe your learning process can improve by partnering with a tailor made AI. You want to be provoked to think more clearly. 🤯 Your learning backlog is way too big You have hundreds of links you would love to read, but there is no time for it all. You want to make sure those are catalogued for when you need them. ✍️ Independent Thinker You value both taking notes and forming your own ideas. You understand different viewpoints but believe in developing your own perspective. 🔒 You are privacy aware You don't want all your context, thoughts and plans to be all over Big Tech, if not necessary. 💁 You like things your way You want to decide how your content is handled, which AI models you want to interact with and help specifically it should help/challenge you. What is the plan for the future? There is much more that can be done to augment human knowledge. Open Notebook's first release is just a first step in that direction. The end goal is to build a Cognitive Partner for every person. A customized assistant that can help you develop your skills, knowledge, and opinions in a way that makes sense to you. Learn more about our long-term vision and roadmap in our Vision page.",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: 'https://www.reorproject.org/',
|
|
22
|
+
title: 'Reor',
|
|
23
|
+
url: 'https://www.reorproject.org/',
|
|
24
|
+
publishedDate: '2024-01-01T00:00:00.000Z',
|
|
25
|
+
author: 'Reor',
|
|
26
|
+
score: 0.39665618538856506,
|
|
27
|
+
text: "Private & local AI personal knowledge management app for high entropy thinkers. Q&A Chat with an LLM that has full context of your notes. Automatically connected ideas Never manually link your notes again. Semantic Search Search without having to remember exact phrasing. WYSIWYG Markdown Markdown is the language of thought. Local First LLMs, Embedding Models, Vector database. Everything runs and stores locally. Writing Assistant Write with the world's first local writing assistant. Trusted by individuals who may have heard of these companies",
|
|
28
|
+
image: 'https://reorhomepage-2-cwy0zagzg-reor-team.vercel.app/opengraph-image.jpg?a25ca70e900445ed',
|
|
29
|
+
favicon: 'https://www.reorproject.org/favicon-16x16.png',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'https://mymemo.ai/blog/best-ai-personal-knowledge-management-tools-in-2024/detail',
|
|
33
|
+
title: 'Best AI Personal Knowledge Management (PKM) tools in 2024 - My Framer Site',
|
|
34
|
+
url: 'https://mymemo.ai/blog/best-ai-personal-knowledge-management-tools-in-2024/detail',
|
|
35
|
+
publishedDate: '2025-05-21T17:17:02.000Z',
|
|
36
|
+
author: '',
|
|
37
|
+
score: 0.3811739385128021,
|
|
38
|
+
text: "In today's fast-paced world, managing and organizing knowledge has become increasingly challenging. With the rise of digital information and the need for efficient knowledge sharing, traditional methods of knowledge management are no longer sufficient. AI-powered tools have emerged as a game-changer in this domain, offering a more efficient and effective way to manage and organize knowledge. Efficiency Amplified: AI streamlines the organization and analysis of vast data sets, saving time and reducing manual effort. Insights Unearthed: Uncover hidden patterns, trends, and valuable insights within your data, providing a deeper understanding of your information. Personalized Experience: Tailor your knowledge management approach with AI, creating a personalized digital assistant that adapts to your unique needs. Stay Ahead in the Digital Era: Embrace the transformative power of AI to navigate the information overload and stay ahead in our rapidly evolving digital landscape. Here are 10 AI-powered tools for personal knowledge management with their product links: 1. MyMemo AI: - Introduction: MyMemo transforms personal data into wisdom using AI, offering features like targeted search, smart advice, and creative writing prompts. - Product Link: [MyMemo Website](https://www.mymemo.ai) - Features: - Collects digital knowledge from various sources into a single platform. - Processes collected information with AI to extract key insights. - Allows users to query MyMemoAI for specific info or insights from their knowledge base. - Offers targeted search, smart advice, and creative writing prompts for enhanced knowledge management. 2. Notion AI: - Introduction: Notion AI offers a customizable workspace for efficient knowledge sharing and management. - Product Link: [Notion AI Website](https://www.notion.so) - Features: - Customizable workspace for knowledge sharing. - Integration with various tools like Slack, Google Drive, and Microsoft Teams. - Robust search capabilities powered by AI and AI-based analytics. 3. ClickUp: - Introduction: ClickUp provides dedicated spaces for knowledge base organization and seamless integration with various tools. - Product Link: [ClickUp Website](https://clickup.com) - Features: - Dedicated spaces for Knowledge Base organization. - Integration with third-party software like Microsoft Teams, Jira, Slack, Zoho, and more. - AI-based analytics to track productivity and identify patterns. 4. MyMind: - Introduction: MyMind offers a private space to save notes, images, quotes, and highlights enhanced by AI to aid in memory recall without the need for manual categorization. - Product Link: [MyMind Website](https://www.mymind.com) - Features: - Private space for saving notes, images, quotes, and highlights. - Enhanced by AI for efficient memory recall without manual organization. - Tailored for designers, writers, researchers, developers, and visual minds of all kinds. Adding Mem.ai to the top 10 list of AI-powered tools for personal kn",
|
|
39
|
+
image: 'https://framerusercontent.com/images/xtRTZ9zRVH3uL1fvH2vqA6G60W8.png',
|
|
40
|
+
favicon: 'https://framerusercontent.com/images/XEQTxAwueP1wc7BpbB1zrouiuoA.png',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'https://mymemo.ai/',
|
|
44
|
+
title: 'MyMemo-Empower Your Mind with AI',
|
|
45
|
+
url: 'https://mymemo.ai/',
|
|
46
|
+
publishedDate: '2025-05-21T17:17:02.000Z',
|
|
47
|
+
author: '',
|
|
48
|
+
score: 0.3810442090034485,
|
|
49
|
+
text: 'End Digital Chaos with All In One Digital Space Effortlessly Access Information with AI Chat What have I uploaded about the marketing strategy? How to raise fund as a founder for startup? Write an article about the impact of AI in our society. Compliance with Global Standards MyMemo AI adheres to international data protection regulations, ensuring your data is handled with the utmost care. Secure Storage Your data is encrypted and stored on our high-security servers, ensuring that only you have access. We maintain strict privacy protocols, and even our team cannot view your information. Private Links for Your Memos MyMemo AI ensures that all links generated for your uploaded content are private and exclusively visible to you. 100 AI chat per month 100 content uploads per month 5 memo collections Powered by GPT-4o mini Up to 5 Related Memo in AI chat Single PDF file size under 5MB 10 AI writing for notes in total AI chat unlimited 1000 content uploads per month 100 Memo Collections Supports multiple AI models Up to 5 Related Memo in AI chat Single PDF file size under 30MB 100 AI writing for notes per month Custom AI summary prompt(coming soon) AI chat unlimited Unlimited content uploads Unlimited memo collections Supports multiple AI models Up to 8 Related Memo in AI chat Single PDF file size under 50MB Unlimited AI writing for notes Custom AI summary prompt(coming soon) Free access to @GPT-4o in Chat We’re excited to partner with Inkwise to bring MyMemo users an exclusive deal! Inkwise.ai is an AI-powered platform that helps users craft professional documents by extracting and integrating key information from uploaded files. It offers industry-specific templates, intelligent content extraction, and a referencing system that ensures factual accuracy. Exclusive for MyMemo Users: Get 2 months of Inkwise Pro for free with the code INKWISE2025 at checkout! MyMemo © MyMemo 2025. All rights reserved',
|
|
50
|
+
image: 'https://framerusercontent.com/images/xtRTZ9zRVH3uL1fvH2vqA6G60W8.png',
|
|
51
|
+
favicon: 'https://framerusercontent.com/images/XEQTxAwueP1wc7BpbB1zrouiuoA.png',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'https://www.personal.ai/memory',
|
|
55
|
+
title: 'Make Your Own AI with Your Unique Memory',
|
|
56
|
+
url: 'https://www.personal.ai/memory',
|
|
57
|
+
publishedDate: '2024-01-01T00:00:00.000Z',
|
|
58
|
+
author: '',
|
|
59
|
+
score: 0.3991696536540985,
|
|
60
|
+
text: "In Personal AI, version control for memory and model is managed through a systematic approach that allows users to track, manage, and revert changes made to the AI's memory and model. Memory Stack: When you store a memory in Personal AI, it goes into the memory stack for training the AI. Data Uploads: Users can add, edit, or reinforce memories by uploading authored data directly into their personal language model. The personal language model has unlimited memory and is not bound by token or context limitations. The AI's performance is as good as the memory provided to it. If it makes false statements, the memory needs to be fixed and reinforced for future learning. There will be mechanisms to download the memory and model in the future. The output of the personal AI model is entirely controlled by the user's input and training. Yes, you can automate conversations using stacked memories in your Personal AI. By leveraging the memory stacking feature, you can train your AI to recall and utilize specific information during interactions Practices for Automating Conversations: Memory Anchors: When stacking new memories, consider adding memory anchors to organize the information effectively. This practice helps structure and categorize the data within your Personal AI account. Variety of Sources: Utilize all available tools such as the chat box, document editor, file uploader, and URL uploader to stack data from various sources. This diverse input enables your AI to learn from a wide range of inputs for a more personalized experience. Application of Practices: To automate conversations effectively, ensure that you consistently add relevant information into your memory stack using different tools provided by Personal AI. By doing so, you enable your AI to access and utilize this knowledge when engaging in digital interactions on your behalf. Yes, you can absolutely use hashtags to label and recall specific memories later on with your Personal AI. When adding memories to your AI, it's beneficial to include detailed and descriptive information about the topic or subject, along with context such as people, location, and absolute time for the AI to reference. Using hashtags allows you to categorize and organize these memories effectively. By using proper placement of hashtags without spaces and maintaining uniform capitalization, you can enhance the selection of memories for generating answers. Additionally, when stacking content using the chat box or file/document uploader in Personal AI, you can utilize #hashtags for single words or :colons followed by keywords for multiple words or complete titles. This practice helps in refining the selection of memories for generating answers while ensuring effective organization and retrieval of data. Personal AI is built with a strong emphasis on data privacy and security. It operates under the principle that the data you provide is yours alone. Measures such as encryption, secure data storage, and the optio",
|
|
61
|
+
image: 'https://cdn.prod.website-files.com/5ff65c460ce39f5ec5681c6a/663d12aab1b425e1ad40d3a6_Memory-min.jpg',
|
|
62
|
+
favicon:
|
|
63
|
+
'https://cdn.prod.website-files.com/5ff65c460ce39f5ec5681c6a/5ffcbe4a31309a2dcf7d1f18_Human%20AI%20Icon%2032x32-bolder.png',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: 'https://iki.ai/',
|
|
67
|
+
title: 'IKI AI – Intelligent Knowledge Interface',
|
|
68
|
+
url: 'https://iki.ai/',
|
|
69
|
+
publishedDate: '2025-04-10T16:28:59.000Z',
|
|
70
|
+
author: '',
|
|
71
|
+
score: 0.38676750659942627,
|
|
72
|
+
text: 'Think faster. Organize deeper. All in one place. An AI-native workspace for research, strategy, and creative work An AI-native workspace for research, strategy, and creative work Backed by 500 Global Backed by 500 Global Backed by 500 Global Capture anything. Build your thinking library. Capture anything. Build your thinking library. Capture anything. Build your thinking library. AI assistant Turn long reads into clear insights. IKI summarizes, highlights, and connects the dots. AI assistant Turn long reads into clear insights. IKI summarizes, highlights, and connects the dots. AI assistant Turn long reads into clear insights. IKI summarizes, highlights, and connects the dots. AI editor AI writing with real context. Grounded in your content, not the internet. AI editor AI writing with real context. Grounded in your content, not the internet. AI editor AI writing with real context. Grounded in your content, not the internet. Team spaces Your team’s shared brain. One space for knowledge, context, and decisions. Team spaces Your team’s shared brain. One space for knowledge, context, and decisions. Team spaces Your team’s shared brain. One space for knowledge, context, and decisions. Everything you need for smarter knowledge work AI Editor Ask IKI AI Heading 1 B U I Browser extension Download extension to save webpages in one click along with notes Author Spotify Design Youtube · 3 min read Designing Data Science Tools at Spotify: Part 2 AI Summury Methods based on the relational path have shown strong, interpretable, and transferable reasoning ability. However, paths are naturally limited in capturing local evidence in graphs...Methods based on the relational path have shown strong, interpretable LLMs powered by top-tier models you trust Multi-source insights with agent context AI Digest Everything you need for smarter knowledge work AI Editor Ask IKI AI Heading 1 B U I Browser extension Download extension to save webpages in one click along with notes Author Spotify Design Youtube · 3 min read Designing Data Science Tools at Spotify: Part 2 AI Summury Methods based on the relational path have shown strong, interpretable, and transferable reasoning ability. However, paths are naturally limited in capturing local evidence in graphs...Methods based on the relational path have shown strong, interpretable LLMs powered by top-tier models you trust Multi-source insights with agent context AI Digest Everything you need for smarter knowledge work AI Editor Ask IKI AI Heading 1 B U I Browser extension Download extension to save webpages in one click along with notes Author Spotify Design Youtube · 3 min read Designing Data Science Tools at Spotify: Part 2 AI Summury Methods based on the relational path have shown strong, interpretable, and transferable reasoning ability. However, paths are naturally limited in capturing local evidence in graphs...Methods based on the relational path have shown strong, interpretable LLMs powered by',
|
|
73
|
+
image: 'https://framerusercontent.com/assets/cI6Uo7x4q0W3uxzOt2preXjv6aE.jpg',
|
|
74
|
+
favicon: 'https://framerusercontent.com/images/5NLFiJq5bLl5FXOTcVQX8vhkU.png',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: 'https://supermemory.ai/',
|
|
78
|
+
title: 'supermemory™',
|
|
79
|
+
url: 'https://supermemory.ai/',
|
|
80
|
+
publishedDate: '2025-01-01T00:00:00.000Z',
|
|
81
|
+
author: '',
|
|
82
|
+
score: 0.393942266702652,
|
|
83
|
+
text: "The universal memory API for the AI era Stop building retrieval from scratch. Personalise LLMs for your users. Built for developers who ship. Start building DOCS Context is everything Without it, even the smartest AI is just an expensive chatbot $ init vector_database Way too expensive. Time to switch. Painfully slow. Let's try another. Won't scale. Back to square one. Maintenance nightmare. Need alternatives. $ choose embedding_model Which model fits your use case? Confusing performance tradeoffs Can't keep up with new releases $ handle format_parsing Markdown: Tables break everything HTML: Scripts and styles interfere PDF: Layout ruins extraction Word docs: Unpredictable formatting $ calculate scaling_costs Costs explode at production scale Performance degrades as data grows Engineering hours pile up fast $ setup connection_sync Sync failures between data sources API rate limits during large syncs Images: Need vision models now? Audio/Video: Transcription costs soar $ init multimodal_support Websites: JS & rate limits are messy PDFs: OCR fails, extraction inconsistent Authentication tokens expire constantly $ init vector_database Way too expensive. Time to switch. Painfully slow. Let's try another. Won't scale. Back to square one. Maintenance nightmare. Need alternatives. $ choose embedding_model Which model fits your use case? Confusing performance tradeoffs Can't keep up with new releases $ handle format_parsing Markdown: Tables break everything HTML: Scripts and styles interfere PDF: Layout ruins extraction Word docs: Unpredictable formatting $ calculate scaling_costs Costs explode at production scale Performance degrades as data grows Engineering hours pile up fast $ setup connection_sync Sync failures between data sources API rate limits during large syncs Images: Need vision models now? Audio/Video: Transcription costs soar $ init multimodal_support Websites: JS & rate limits are messy PDFs: OCR fails, extraction inconsistent Authentication tokens expire constantly FEATURES • FEATURES • FEATURES Unlock the Full Potential of Your Data const response = await fetch( 'https://api.supermemory.ai/v3/memories', {\n method: 'POST',\n headers: {\n 'Authorization': 'Bearer sm_ywdhjSbiDLkLIjjVotSegR_rsq3ZZKNRJmVr12p4ItTcf' \n },\n body: JSON.stringify({\n content: 'My name is Shreyans.',\n // or https://example.com \n // or https://example.com/page.pdf \n metadata: {\n user_id: '123' \n }\n }),\n})\n const data = await response.json() const response = await fetch( 'https://api.supermemory.ai/v3/memories', {\n method: 'GET',\n headers: {\n 'Authorization': 'Bearer sm_ywdhjSbiDLkLIjjVotSegR_rsq3ZZKNRJmVr12p4ItTcf',\n },\n body: JSON.stringify({\n q: \"What's my name?\" \n })\n})\n const data = await response.json() const response = await fetch( 'https://api.supermemory.ai/v3/connections/onedrive', {\n method: 'POST',\n headers: {\n 'Authorization': 'Bearer sm_ywdhjSbiDLkLIjjVotSegR_rsq3ZZKNRJmVr12p4ItTcf',\n }\n});\n const data = await response.json(); solution • sol",
|
|
84
|
+
image: 'https://cdn.prod.website-files.com/6826235ef861ed9464b064c8/6826251d65991babe21a9a9a_Frame%2031.png',
|
|
85
|
+
favicon: 'https://cdn.prod.website-files.com/6826235ef861ed9464b064c8/682639813def380d7694f590_favicon.png',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: 'https://mykin.ai/',
|
|
89
|
+
title: 'Kin - Private, and Emotionally Intelligent, Personal AI',
|
|
90
|
+
url: 'https://mykin.ai/',
|
|
91
|
+
publishedDate: '2025-05-26T00:00:00.000Z',
|
|
92
|
+
author: '',
|
|
93
|
+
score: 0.38142070174217224,
|
|
94
|
+
text: "Clarity and confidence. Always on hand. Kin is a new kind of personal AI companion, more emotionally intelligent and private than ever. For whatever life throws at you. Available on iPhone and Android Anytime. Anywhere. Life at work is becoming increasingly challenging to navigate Think with Kin Personalized coaching can be inaccessible and expensive Talk with Kin How can Kin help? Inspiration “Whenever I need fresh ideas or just a soundboard, I know I can quickly turn to Kin.” Inspiration “Whenever I need fresh ideas or just a soundboard, I know I can quickly turn to Kin.” Planning “I use Kin to think things through, set goals, and organize my time.” Planning “I use Kin to think things through, set goals, and organize my time.” Learning “I can learn about almost any topic, with structured lessons created in seconds.” Learning “I can learn about almost any topic, with structured lessons created in seconds.” Support “Kin helps me with everything from small tasks to processing ideas and emotions.” Support “Kin helps me with everything from small tasks to processing ideas and emotions.” Guidance “I’m more aware of my strengths and I feel better prepared for tricky conversations.” Guidance “I’m more aware of my strengths and I feel better prepared for tricky conversations.” Kin remembers, so you don’t have to. The more you interact with Kin, the more Kin learns about you and your life. Because Kin understands both the big picture and its complexities, it can provide genuinely meaningful support in your day-to-day. Learn more Private & Secure Kin encrypts and stores your data securely on you device. No one else can see or access it. Powerful features. Scandinavian design. Smart journaling Share your thoughts and notes to reflect and build a better Kin. Coming soon Powered by open source models Coming soon Semantic and Episodic memory Coming soon Private, encrypted local-first storage Coming soon Intelligent reminders Stay on top of what matters with timely reminders. Coming soon Conversational voice chat Coming soon Third party integration Connect your Kin to the apps you love like Google calendar. Coming soon Proudly made in Copenhagen, Denmark Get started with simple tutorials and big ideas Frequently asked questions Product How does Kin's memory work? Kin’s memory pulls information from your messages into a database on your device so it can always reference it. Kin’s memory is automatic, so in practice, it works just by you talking with Kin. General More than anyone else. Every word you share and every reply is stored locally on your device - unless you change your settings to allow otherwise. You have full control over deleting it at any time. General Do I need a subscription to use Kin? No - Kin is currently free and without message limits for our beta users. However, we’re expecting to transition to a subscription model once we hit full release - we’ll make sure to talk a lot about that before it happens, though. Product Can I use Kin on a d",
|
|
95
|
+
image: 'https://cdn.prod.website-files.com/67b8fb50931278cabb866969/67d2a6c56ee313becd0f482d_img-opengraph.jpg',
|
|
96
|
+
favicon: 'https://cdn.prod.website-files.com/67b8fb50931278cabb866969/67c0cfc2c45ca5db9ca5c9e4_favicon.png',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: 'https://try.rememberizer.ai/blog/introducing-rememberizer-connect-knowledge-to-your-ai',
|
|
100
|
+
title: 'Introducing Rememberizer - Connect Knowledge To Your AI',
|
|
101
|
+
url: 'https://try.rememberizer.ai/blog/introducing-rememberizer-connect-knowledge-to-your-ai',
|
|
102
|
+
publishedDate: '2024-01-28T00:00:00.000Z',
|
|
103
|
+
author: '',
|
|
104
|
+
score: 0.38043755292892456,
|
|
105
|
+
text: "Introduction In the rapidly evolving world of artificial intelligence (AI), Rememberizer emerges as a revolutionary platform that profoundly changes how both developers and personal consumers interact with AI, especially Generative Pre-trained Transformers (GPT). This platform is not just another tool; it's a transformative solution, making AI interactions deeply personal, intuitive, and efficient. Let’s dive into how Rememberizer is redefining AI personalization and integration, offering unique experiences for a diverse range of users, free. Part 1: Rememberizer for Personal Consumers Why Rememberizer Matters for Personal Users Generative AI apps work better when they have access to background information. They need to know what you know. A great way to achieve that is to give them access to relevant content from the documents, data and discussions you create and use. This is what Rememberizer does. Rememberizer helps by seamlessly integrating personal data with AI applications. For OpenAI GPTs users, this means transforming your interactions with AI into something deeply personal and relevant. By indexing your data just once, Rememberizer avoids wasting time performing the same process over and over again. Empowering Personal AI Experiences Whether you’re engaging in creative projects, professional tasks, or simply exploring AI for personal curiosity, Rememberizer brings a unique value proposition. It transforms your data into a powerful AI collaborator, ensuring your interactions are tailored to your specific circumstances. Imagine an AI that feels intuitively designed for you, understanding your projects, circumstances and recent discussions. That’s the personalized AI experience Rememberizer delivers. Part 2: Rememberizer for Developers Revolutionizing AI Integration in App Development For developers, Rememberizer is a game-changer. It simplifies the integration of user data into AI applications, enhancing app functionality and user experience. Rememberizer connects directly to various data sources including Slack and Google Drive, embedding their contents semantic meaning into a vector database. This process not only elevates the AI capabilities of your app but also saves vast amounts GPU processing costs and engineering resources in backend development: it’s free! The Developer's Advantage with Rememberizer Streamlined Data Integration: Rememberizer takes care of the complex process of integrating data sources into a vector database, allowing developers to focus more on creative aspects of app development. Enhanced AI Capabilities: By leveraging Rememberizer, apps gain access to rich, personalized data, leading to more intuitive and context-aware AI interactions. Personalization and Continuous Adaptation: Apps powered by Rememberizer can offer unparalleled personalization, learning, and adapting based on the user's data, thereby improving over time. Part 3: Pricing and Accessibility for All Rememberizer is committed to democratizing ",
|
|
106
|
+
image:
|
|
107
|
+
'https://cdn.prod.website-files.com/656fc35f7b92e991c863ce0a/65b7523200497f3ac6391238_Rememberizer%20banner.png',
|
|
108
|
+
favicon: 'https://cdn.prod.website-files.com/656fc35f7b92e991c863cdc4/657acdfb9a0ba55d8f622765_Favicon.png',
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: 'https://twinmind.com/',
|
|
112
|
+
title: 'TwinMind',
|
|
113
|
+
url: 'https://twinmind.com/',
|
|
114
|
+
publishedDate: '2025-05-23T09:12:49.000Z',
|
|
115
|
+
author: '',
|
|
116
|
+
score: 0.38130462169647217,
|
|
117
|
+
text: '\n Never Forget Anything with Your Never Forget Anything with Your Never Forget Anything with Your Second Brain Memory Vault Life Copilot AI Notetaker Second Brain Second Brain Memory Vault Life Copilot AI Notetaker Second Brain Second Brain Memory Vault Life Copilot AI Notetaker Second Brain Get perfect notes, to-dos, and proactive answers during meetings, lectures, interviews, and conversations. Get perfect notes, to-dos, and proactive answers during meetings, lectures, interviews, and conversations. Watch Demo Watch Demo Watch Demo Featured in Featured in Trusted by users at Trusted by users at Capture any moment, even inside your pocket Capture any moment, even inside your pocket Transcribe everything. Forget nothing. Ask anything. Transcribe everything. Forget nothing. Ask anything. Transcribe everything. Forget nothing. Ask anything. Seamlessly switch from mobile to desktop Seamlessly switch from mobile to desktop With TwinMind for Chrome, transcribe video calls or chat with tabs, PDFs, Youtube videos, and automate your work. With the TwinMind Chrome sidebar, transcribe video calls or chat with websites, PDFs, Youtube videos, and all your memories. Works with all the products you love Works with all the products you love Ask anything with context from all your favorite websites and insert answers directly into them on Chrome. Ask anything with context from all your favorite websites and insert answers directly into them on Chrome. Transcribe video calls or capture context from all your favorite websites, and insert answers into them on Chrome browser. Get Proactive Answers Get Proactive Answers Get personalized suggestions, prepare for meetings or exams based on all your notes synced with your calendar. Get personalized suggestions, prepare for meetings or exams based on all your notes synced with your calendar. Unlock Perfect Memory Unlock Perfect Memory Your brain forgets 90% of memories in 7 days but TwinMind doesn’t. Ask TwinMind anything with Deep Memory Search. Your brain forgets 90% of memories in 7 days but TwinMind doesn’t. Ask TwinMind anything with Deep Memory Search. Summarize all my meetings Ask TwinMind Summarize all my meetings Ask TwinMind Summarize all my meetings Ask TwinMind Insert Insert Insert Automate Your Work Automate Your Work Generate follow-up emails, reports, assignments based on memories. Insert anywhere on your browser in one click. Generate follow-up emails, reports, assignments based on memories. Insert anywhere on your browser in one click. 100% privacy with offline mode 100% privacy with offline mode 100% privacy with offline mode Transcribes without recording TwinMind processes your audio on-the-fly in real-time and saves only the transcripts on-device, ensuring that your audio is never stored anywhere. Transcribes without recording TwinMind processes your audio on-the-fly in real-time and saves only the transcripts on-device, ensuring that your audio is never stored anywhere. Transcribes without recording ',
|
|
118
|
+
image: 'https://framerusercontent.com/assets/9u5tx2lerz0ndBVcB14sg4tNoKs.png',
|
|
119
|
+
favicon: 'https://framerusercontent.com/images/zDX0zsHZ6Z2PvwK2vmkOsISWBiY.svg',
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
costDollars: {
|
|
123
|
+
total: 0.015,
|
|
124
|
+
search: {
|
|
125
|
+
neural: 0.005,
|
|
126
|
+
},
|
|
127
|
+
contents: {
|
|
128
|
+
text: 0.01,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
};
|