@agentuity/runtime 0.0.106 → 0.0.108
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/_metadata.d.ts.map +1 -1
- package/dist/_metadata.js +7 -0
- package/dist/_metadata.js.map +1 -1
- package/dist/_standalone.d.ts.map +1 -1
- package/dist/_standalone.js +25 -9
- package/dist/_standalone.js.map +1 -1
- package/dist/bun-s3-patch.d.ts +13 -2
- package/dist/bun-s3-patch.d.ts.map +1 -1
- package/dist/bun-s3-patch.js +82 -8
- package/dist/bun-s3-patch.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +7 -4
- package/dist/middleware.js.map +1 -1
- package/dist/services/thread/local.d.ts.map +1 -1
- package/dist/services/thread/local.js +106 -25
- package/dist/services/thread/local.js.map +1 -1
- package/dist/session.d.ts +206 -27
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +386 -69
- package/dist/session.js.map +1 -1
- package/package.json +5 -5
- package/src/_metadata.ts +11 -0
- package/src/_standalone.ts +25 -9
- package/src/bun-s3-patch.ts +138 -10
- package/src/index.ts +6 -0
- package/src/middleware.ts +8 -4
- package/src/services/thread/local.ts +119 -30
- package/src/session.ts +599 -90
|
@@ -51,30 +51,37 @@ export class LocalThreadProvider implements ThreadProvider {
|
|
|
51
51
|
const threadId = await this.threadIDProvider.getThreadId(this.appState, ctx);
|
|
52
52
|
validateThreadIdOrThrow(threadId);
|
|
53
53
|
|
|
54
|
-
//
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
54
|
+
// Create a restore function for lazy loading
|
|
55
|
+
const restoreFn = async (): Promise<{
|
|
56
|
+
state: Map<string, unknown>;
|
|
57
|
+
metadata: Record<string, unknown>;
|
|
58
|
+
}> => {
|
|
59
|
+
if (!this.db) {
|
|
60
|
+
return { state: new Map(), metadata: {} };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const row = this.db
|
|
64
|
+
.query<{ state: string }, [string]>('SELECT state FROM threads WHERE id = ?')
|
|
65
|
+
.get(threadId);
|
|
66
|
+
|
|
67
|
+
const { flatStateJson, metadata } = parseThreadData(row?.state);
|
|
68
|
+
|
|
69
|
+
const state = new Map<string, unknown>();
|
|
70
|
+
if (flatStateJson) {
|
|
71
|
+
try {
|
|
72
|
+
const data = JSON.parse(flatStateJson);
|
|
73
|
+
for (const [key, value] of Object.entries(data)) {
|
|
74
|
+
state.set(key, value);
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
// Continue with empty state if parsing fails
|
|
71
78
|
}
|
|
72
|
-
} catch {
|
|
73
|
-
// Continue with empty state if parsing fails
|
|
74
79
|
}
|
|
75
|
-
}
|
|
76
80
|
|
|
77
|
-
|
|
81
|
+
return { state, metadata: metadata || {} };
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
return new DefaultThread(this, threadId, restoreFn);
|
|
78
85
|
}
|
|
79
86
|
|
|
80
87
|
async save(thread: Thread): Promise<void> {
|
|
@@ -82,20 +89,102 @@ export class LocalThreadProvider implements ThreadProvider {
|
|
|
82
89
|
return;
|
|
83
90
|
}
|
|
84
91
|
|
|
85
|
-
|
|
86
|
-
if (
|
|
92
|
+
const saveMode = thread.getSaveMode();
|
|
93
|
+
if (saveMode === 'none') {
|
|
87
94
|
return;
|
|
88
95
|
}
|
|
89
96
|
|
|
90
|
-
const stateJson = thread.getSerializedState();
|
|
91
97
|
const now = Date.now();
|
|
92
98
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
if (saveMode === 'merge') {
|
|
100
|
+
// For merge, we need to load existing state, apply operations, then save
|
|
101
|
+
const operations = thread.getPendingOperations();
|
|
102
|
+
const metadata = thread.getMetadataForSave();
|
|
103
|
+
|
|
104
|
+
// Load existing state
|
|
105
|
+
const row = this.db
|
|
106
|
+
.query<{ state: string }, [string]>('SELECT state FROM threads WHERE id = ?')
|
|
107
|
+
.get(thread.id);
|
|
108
|
+
|
|
109
|
+
const { flatStateJson, metadata: existingMetadata } = parseThreadData(row?.state);
|
|
110
|
+
|
|
111
|
+
const state: Record<string, unknown> = {};
|
|
112
|
+
if (flatStateJson) {
|
|
113
|
+
try {
|
|
114
|
+
Object.assign(state, JSON.parse(flatStateJson));
|
|
115
|
+
} catch {
|
|
116
|
+
// Continue with empty state if parsing fails
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Apply operations
|
|
121
|
+
for (const op of operations) {
|
|
122
|
+
switch (op.op) {
|
|
123
|
+
case 'clear':
|
|
124
|
+
for (const key of Object.keys(state)) {
|
|
125
|
+
delete state[key];
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
case 'set':
|
|
129
|
+
if (op.key !== undefined) {
|
|
130
|
+
state[op.key] = op.value;
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
case 'delete':
|
|
134
|
+
if (op.key !== undefined) {
|
|
135
|
+
delete state[op.key];
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
case 'push':
|
|
139
|
+
if (op.key !== undefined) {
|
|
140
|
+
const existing = state[op.key];
|
|
141
|
+
let arr: unknown[];
|
|
142
|
+
if (Array.isArray(existing)) {
|
|
143
|
+
existing.push(op.value);
|
|
144
|
+
arr = existing;
|
|
145
|
+
} else if (existing === undefined) {
|
|
146
|
+
arr = [op.value];
|
|
147
|
+
state[op.key] = arr;
|
|
148
|
+
} else {
|
|
149
|
+
// If non-array, silently skip
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// Apply maxRecords limit
|
|
153
|
+
if (op.maxRecords !== undefined && arr.length > op.maxRecords) {
|
|
154
|
+
state[op.key] = arr.slice(arr.length - op.maxRecords);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Build final data
|
|
162
|
+
const finalMetadata = metadata || existingMetadata || {};
|
|
163
|
+
const hasState = Object.keys(state).length > 0;
|
|
164
|
+
const hasMetadata = Object.keys(finalMetadata).length > 0;
|
|
165
|
+
|
|
166
|
+
let stateJson = '';
|
|
167
|
+
if (hasState || hasMetadata) {
|
|
168
|
+
const data: { state?: Record<string, unknown>; metadata?: Record<string, unknown> } = {};
|
|
169
|
+
if (hasState) data.state = state;
|
|
170
|
+
if (hasMetadata) data.metadata = finalMetadata;
|
|
171
|
+
stateJson = JSON.stringify(data);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
this.db.run(
|
|
175
|
+
`INSERT INTO threads (id, state, updated_at) VALUES (?, ?, ?)
|
|
176
|
+
ON CONFLICT(id) DO UPDATE SET state = ?, updated_at = ?`,
|
|
177
|
+
[thread.id, stateJson, now, stateJson, now]
|
|
178
|
+
);
|
|
179
|
+
} else {
|
|
180
|
+
// Full save
|
|
181
|
+
const stateJson = await thread.getSerializedState();
|
|
182
|
+
this.db.run(
|
|
183
|
+
`INSERT INTO threads (id, state, updated_at) VALUES (?, ?, ?)
|
|
184
|
+
ON CONFLICT(id) DO UPDATE SET state = ?, updated_at = ?`,
|
|
185
|
+
[thread.id, stateJson, now, stateJson, now]
|
|
186
|
+
);
|
|
187
|
+
}
|
|
99
188
|
}
|
|
100
189
|
|
|
101
190
|
async destroy(thread: Thread): Promise<void> {
|