@deepagents/context 0.6.0 → 0.8.0
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/index.d.ts +286 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1766 -0
- package/dist/index.js.map +7 -0
- package/dist/lib/context.d.ts +50 -0
- package/dist/lib/context.d.ts.map +1 -0
- package/dist/lib/estimate.d.ts +108 -0
- package/dist/lib/estimate.d.ts.map +1 -0
- package/dist/lib/models.generated.d.ts +3 -0
- package/dist/lib/models.generated.d.ts.map +1 -0
- package/dist/lib/renderers/abstract.renderer.d.ts +101 -0
- package/dist/lib/renderers/abstract.renderer.d.ts.map +1 -0
- package/dist/lib/store/memory.store.d.ts +11 -0
- package/dist/lib/store/memory.store.d.ts.map +1 -0
- package/dist/lib/store/sqlite.store.d.ts +33 -0
- package/dist/lib/store/sqlite.store.d.ts.map +1 -0
- package/dist/lib/store/store.d.ts +245 -0
- package/dist/lib/store/store.d.ts.map +1 -0
- package/dist/lib/visualize.d.ts +15 -0
- package/dist/lib/visualize.d.ts.map +1 -0
- package/dist/usage.d.ts +2 -0
- package/dist/usage.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import type { ContextFragment } from './lib/context.ts';
|
|
2
|
+
import { type EstimateResult } from './lib/estimate.ts';
|
|
3
|
+
import type { Models } from './lib/models.generated.ts';
|
|
4
|
+
import { type ContextRenderer } from './lib/renderers/abstract.renderer.ts';
|
|
5
|
+
import { type BranchInfo, type CheckpointInfo, ContextStore } from './lib/store/store.ts';
|
|
6
|
+
export type { ContextFragment, FragmentType } from './lib/context.ts';
|
|
7
|
+
export { isMessageFragment } from './lib/context.ts';
|
|
8
|
+
export { ContextStore, type ChatData, type ChatInfo, type MessageData, type MessageInfo, type BranchData, type BranchInfo, type CheckpointData, type CheckpointInfo, type GraphNode, type GraphBranch, type GraphCheckpoint, type GraphData, type SearchOptions, type SearchResult, } from './lib/store/store.ts';
|
|
9
|
+
export { SqliteContextStore } from './lib/store/sqlite.store.ts';
|
|
10
|
+
export { InMemoryContextStore } from './lib/store/memory.store.ts';
|
|
11
|
+
export { visualizeGraph } from './lib/visualize.ts';
|
|
12
|
+
/**
|
|
13
|
+
* Message format compatible with AI SDK's CoreMessage.
|
|
14
|
+
*/
|
|
15
|
+
export interface Message {
|
|
16
|
+
role: 'user' | 'assistant' | 'system';
|
|
17
|
+
content: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Result of resolving context - ready for AI SDK consumption.
|
|
21
|
+
*/
|
|
22
|
+
export interface ResolveResult {
|
|
23
|
+
/** Rendered non-message fragments for system prompt */
|
|
24
|
+
systemPrompt: string;
|
|
25
|
+
/** Message fragments decoded to AI SDK format */
|
|
26
|
+
messages: Message[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Options for resolve().
|
|
30
|
+
*/
|
|
31
|
+
export interface ResolveOptions {
|
|
32
|
+
/** Renderer to use for system prompt (defaults to XmlRenderer) */
|
|
33
|
+
renderer?: ContextRenderer;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Options for creating a ContextEngine.
|
|
37
|
+
*/
|
|
38
|
+
export interface ContextEngineOptions {
|
|
39
|
+
/** Store for persisting fragments (required) */
|
|
40
|
+
store: ContextStore;
|
|
41
|
+
/** Unique identifier for this chat (required) */
|
|
42
|
+
chatId: string;
|
|
43
|
+
/** Branch name (defaults to 'main') */
|
|
44
|
+
branch?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Options for creating message fragments.
|
|
48
|
+
*/
|
|
49
|
+
export interface MessageOptions {
|
|
50
|
+
/** Custom ID for the fragment. If not provided, auto-generates UUID. */
|
|
51
|
+
id?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Metadata about a chat.
|
|
55
|
+
*/
|
|
56
|
+
export interface ChatMeta {
|
|
57
|
+
/** Unique chat identifier */
|
|
58
|
+
id: string;
|
|
59
|
+
/** When the chat was created */
|
|
60
|
+
createdAt: number;
|
|
61
|
+
/** When the chat was last updated */
|
|
62
|
+
updatedAt: number;
|
|
63
|
+
/** Optional user-provided title */
|
|
64
|
+
title?: string;
|
|
65
|
+
/** Optional custom metadata */
|
|
66
|
+
metadata?: Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
export { type ContextRenderer, type RendererOptions, XmlRenderer, MarkdownRenderer, TomlRenderer, ToonRenderer, } from './lib/renderers/abstract.renderer.ts';
|
|
69
|
+
export { type ModelCost, type ModelInfo, type EstimateResult, type Tokenizer, defaultTokenizer, ModelsRegistry, getModelsRegistry, } from './lib/estimate.ts';
|
|
70
|
+
export type { Models, KnownModels } from './lib/models.generated.ts';
|
|
71
|
+
/**
|
|
72
|
+
* Context engine for managing AI conversation context with graph-based storage.
|
|
73
|
+
*
|
|
74
|
+
* The engine uses a DAG (Directed Acyclic Graph) model for messages:
|
|
75
|
+
* - Messages are immutable nodes with parentId forming the graph
|
|
76
|
+
* - Branches are pointers to head (tip) messages
|
|
77
|
+
* - Checkpoints are pointers to specific messages
|
|
78
|
+
* - History is preserved through branching (rewind creates new branch)
|
|
79
|
+
*/
|
|
80
|
+
export declare class ContextEngine {
|
|
81
|
+
#private;
|
|
82
|
+
constructor(options: ContextEngineOptions);
|
|
83
|
+
/**
|
|
84
|
+
* Get the current chat ID.
|
|
85
|
+
*/
|
|
86
|
+
get chatId(): string;
|
|
87
|
+
/**
|
|
88
|
+
* Get the current branch name.
|
|
89
|
+
*/
|
|
90
|
+
get branch(): string;
|
|
91
|
+
/**
|
|
92
|
+
* Get metadata for the current chat.
|
|
93
|
+
* Returns null if the chat hasn't been initialized yet.
|
|
94
|
+
*/
|
|
95
|
+
get chat(): ChatMeta | null;
|
|
96
|
+
/**
|
|
97
|
+
* Add fragments to the context.
|
|
98
|
+
*
|
|
99
|
+
* - Message fragments (user/assistant) are queued for persistence
|
|
100
|
+
* - Non-message fragments (role/hint) are kept in memory for system prompt
|
|
101
|
+
*/
|
|
102
|
+
set(...fragments: ContextFragment[]): this;
|
|
103
|
+
/**
|
|
104
|
+
* Render all fragments using the provided renderer.
|
|
105
|
+
* @internal Use resolve() instead for public API.
|
|
106
|
+
*/
|
|
107
|
+
render(renderer: ContextRenderer): string;
|
|
108
|
+
/**
|
|
109
|
+
* Resolve context into AI SDK-ready format.
|
|
110
|
+
*
|
|
111
|
+
* - Initializes chat and branch if needed
|
|
112
|
+
* - Loads message history from the graph (walking parent chain)
|
|
113
|
+
* - Separates context fragments for system prompt
|
|
114
|
+
* - Combines with pending messages
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts
|
|
118
|
+
* const context = new ContextEngine({ store, chatId: 'chat-1' })
|
|
119
|
+
* .set(role('You are helpful'), user('Hello'));
|
|
120
|
+
*
|
|
121
|
+
* const { systemPrompt, messages } = await context.resolve();
|
|
122
|
+
* await generateText({ system: systemPrompt, messages });
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
resolve(options?: ResolveOptions): Promise<ResolveResult>;
|
|
126
|
+
/**
|
|
127
|
+
* Save pending messages to the graph.
|
|
128
|
+
*
|
|
129
|
+
* Each message is added as a node with parentId pointing to the previous message.
|
|
130
|
+
* The branch head is updated to point to the last message.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* context.set(user('Hello'));
|
|
135
|
+
* // AI responds...
|
|
136
|
+
* context.set(assistant('Hi there!'));
|
|
137
|
+
* await context.save(); // Persist to graph
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
save(): Promise<void>;
|
|
141
|
+
/**
|
|
142
|
+
* Estimate token count and cost for the current context.
|
|
143
|
+
*
|
|
144
|
+
* @param modelId - Model ID (e.g., "openai:gpt-4o", "anthropic:claude-3-5-sonnet")
|
|
145
|
+
* @param options - Optional settings
|
|
146
|
+
* @returns Estimate result with token counts and costs
|
|
147
|
+
*/
|
|
148
|
+
estimate(modelId: Models, options?: {
|
|
149
|
+
renderer?: ContextRenderer;
|
|
150
|
+
}): Promise<EstimateResult>;
|
|
151
|
+
/**
|
|
152
|
+
* Rewind to a specific message by ID.
|
|
153
|
+
*
|
|
154
|
+
* Creates a new branch from that message, preserving the original branch.
|
|
155
|
+
* The new branch becomes active.
|
|
156
|
+
*
|
|
157
|
+
* @param messageId - The message ID to rewind to
|
|
158
|
+
* @returns The new branch info
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* context.set(user('What is 2 + 2?', { id: 'q1' }));
|
|
163
|
+
* context.set(assistant('The answer is 5.', { id: 'wrong' })); // Oops!
|
|
164
|
+
* await context.save();
|
|
165
|
+
*
|
|
166
|
+
* // Rewind to the question, creates new branch
|
|
167
|
+
* const newBranch = await context.rewind('q1');
|
|
168
|
+
*
|
|
169
|
+
* // Now add correct answer on new branch
|
|
170
|
+
* context.set(assistant('The answer is 4.'));
|
|
171
|
+
* await context.save();
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
rewind(messageId: string): Promise<BranchInfo>;
|
|
175
|
+
/**
|
|
176
|
+
* Create a checkpoint at the current position.
|
|
177
|
+
*
|
|
178
|
+
* A checkpoint is a named pointer to the current branch head.
|
|
179
|
+
* Use restore() to return to this point later.
|
|
180
|
+
*
|
|
181
|
+
* @param name - Name for the checkpoint
|
|
182
|
+
* @returns The checkpoint info
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```ts
|
|
186
|
+
* context.set(user('I want to learn a new skill.'));
|
|
187
|
+
* context.set(assistant('Would you like coding or cooking?'));
|
|
188
|
+
* await context.save();
|
|
189
|
+
*
|
|
190
|
+
* // Save checkpoint before user's choice
|
|
191
|
+
* const cp = await context.checkpoint('before-choice');
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
checkpoint(name: string): Promise<CheckpointInfo>;
|
|
195
|
+
/**
|
|
196
|
+
* Restore to a checkpoint by creating a new branch from that point.
|
|
197
|
+
*
|
|
198
|
+
* @param name - Name of the checkpoint to restore
|
|
199
|
+
* @returns The new branch info
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```ts
|
|
203
|
+
* // User chose cooking, but wants to try coding path
|
|
204
|
+
* await context.restore('before-choice');
|
|
205
|
+
*
|
|
206
|
+
* context.set(user('I want to learn coding.'));
|
|
207
|
+
* context.set(assistant('Python is a great starting language!'));
|
|
208
|
+
* await context.save();
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
restore(name: string): Promise<BranchInfo>;
|
|
212
|
+
/**
|
|
213
|
+
* Switch to a different branch by name.
|
|
214
|
+
*
|
|
215
|
+
* @param name - Branch name to switch to
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```ts
|
|
219
|
+
* // List branches (via store)
|
|
220
|
+
* const branches = await store.listBranches(context.chatId);
|
|
221
|
+
* console.log(branches); // [{name: 'main', ...}, {name: 'main-v2', ...}]
|
|
222
|
+
*
|
|
223
|
+
* // Switch to original branch
|
|
224
|
+
* await context.switchBranch('main');
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
switchBranch(name: string): Promise<void>;
|
|
228
|
+
/**
|
|
229
|
+
* Update metadata for the current chat.
|
|
230
|
+
*
|
|
231
|
+
* @param updates - Partial metadata to merge (title, metadata)
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```ts
|
|
235
|
+
* await context.updateChat({
|
|
236
|
+
* title: 'Coding Help Session',
|
|
237
|
+
* metadata: { tags: ['python', 'debugging'] }
|
|
238
|
+
* });
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
updateChat(updates: Partial<Pick<ChatMeta, 'title' | 'metadata'>>): Promise<void>;
|
|
242
|
+
/**
|
|
243
|
+
* Consolidate context fragments (no-op for now).
|
|
244
|
+
*
|
|
245
|
+
* This is a placeholder for future functionality that merges context fragments
|
|
246
|
+
* using specific rules. Currently, it does nothing.
|
|
247
|
+
*
|
|
248
|
+
* @experimental
|
|
249
|
+
*/
|
|
250
|
+
consolidate(): void;
|
|
251
|
+
}
|
|
252
|
+
export declare function hint(text: string): ContextFragment;
|
|
253
|
+
export declare function fragment(name: string, ...children: ContextFragment[]): ContextFragment;
|
|
254
|
+
/**
|
|
255
|
+
* Create a role fragment for system prompt instructions.
|
|
256
|
+
*/
|
|
257
|
+
export declare function role(content: string): ContextFragment;
|
|
258
|
+
/**
|
|
259
|
+
* Create a user message fragment.
|
|
260
|
+
* Message fragments are separated from regular fragments during resolve().
|
|
261
|
+
*
|
|
262
|
+
* @param content - The message content
|
|
263
|
+
* @param options - Optional settings (id)
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```ts
|
|
267
|
+
* context.set(user('Hello')); // Auto-generated ID
|
|
268
|
+
* context.set(user('Hello', { id: 'msg-1' })); // Custom ID
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
export declare function user(content: string, options?: MessageOptions): ContextFragment;
|
|
272
|
+
/**
|
|
273
|
+
* Create an assistant message fragment.
|
|
274
|
+
* Message fragments are separated from regular fragments during resolve().
|
|
275
|
+
*
|
|
276
|
+
* @param content - The message content
|
|
277
|
+
* @param options - Optional settings (id)
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```ts
|
|
281
|
+
* context.set(assistant('Hi there!')); // Auto-generated ID
|
|
282
|
+
* context.set(assistant('Hi there!', { id: 'resp-1' })); // Custom ID
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
285
|
+
export declare function assistant(content: string, options?: MessageOptions): ContextFragment;
|
|
286
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|