neoagent 2.3.1-beta.63 → 2.3.1-beta.64
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/flutter_app/lib/main.dart +1 -0
- package/flutter_app/lib/main_account_settings.dart +50 -22
- package/flutter_app/lib/main_admin.dart +24 -10
- package/flutter_app/lib/main_app_shell.dart +10 -9
- package/flutter_app/lib/main_chat.dart +433 -309
- package/flutter_app/lib/main_controller.dart +2 -1
- package/flutter_app/lib/main_integrations.dart +15 -7
- package/flutter_app/lib/main_models.dart +116 -7
- package/flutter_app/lib/main_navigation.dart +27 -18
- package/flutter_app/lib/main_operations.dart +162 -91
- package/flutter_app/lib/main_settings.dart +268 -71
- package/flutter_app/lib/main_shared.dart +4 -6
- package/flutter_app/lib/main_unified.dart +388 -0
- package/package.json +1 -1
- package/server/db/database.js +52 -0
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +77499 -76627
- package/server/routes/agents.js +2 -1
- package/server/routes/memory.js +75 -3
- package/server/routes/widgets.js +4 -4
- package/server/services/ai/engine.js +86 -0
- package/server/services/ai/runEvents.js +100 -0
- package/server/services/memory/manager.js +242 -26
- package/server/services/websocket.js +3 -1
- package/server/services/widgets/focus_widget.js +126 -0
- package/server/services/widgets/service.js +130 -2
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
part of 'main.dart';
|
|
2
|
+
|
|
3
|
+
enum _ToolsPageTab { integrations, mcp, skills }
|
|
4
|
+
|
|
5
|
+
enum _RunsPageTab { runs, logs }
|
|
6
|
+
|
|
7
|
+
enum _SettingsWorkspaceSection { app, account, security }
|
|
8
|
+
|
|
9
|
+
class ToolsPanel extends StatefulWidget {
|
|
10
|
+
const ToolsPanel({super.key, required this.controller});
|
|
11
|
+
|
|
12
|
+
final NeoAgentController controller;
|
|
13
|
+
|
|
14
|
+
@override
|
|
15
|
+
State<ToolsPanel> createState() => _ToolsPanelState();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class _ToolsPanelState extends State<ToolsPanel>
|
|
19
|
+
with SingleTickerProviderStateMixin {
|
|
20
|
+
late final TabController _tabController;
|
|
21
|
+
|
|
22
|
+
@override
|
|
23
|
+
void initState() {
|
|
24
|
+
super.initState();
|
|
25
|
+
_tabController = TabController(
|
|
26
|
+
length: _ToolsPageTab.values.length,
|
|
27
|
+
vsync: this,
|
|
28
|
+
initialIndex: _tabForSection(widget.controller.selectedSection).index,
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@override
|
|
33
|
+
void didUpdateWidget(covariant ToolsPanel oldWidget) {
|
|
34
|
+
super.didUpdateWidget(oldWidget);
|
|
35
|
+
final selectedSection = widget.controller.selectedSection;
|
|
36
|
+
if (selectedSection != oldWidget.controller.selectedSection &&
|
|
37
|
+
(selectedSection == AppSection.integrations ||
|
|
38
|
+
selectedSection == AppSection.mcp ||
|
|
39
|
+
selectedSection == AppSection.skills)) {
|
|
40
|
+
final targetIndex = _tabForSection(selectedSection).index;
|
|
41
|
+
if (_tabController.index != targetIndex) {
|
|
42
|
+
_tabController.index = targetIndex;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@override
|
|
48
|
+
void dispose() {
|
|
49
|
+
_tabController.dispose();
|
|
50
|
+
super.dispose();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
_ToolsPageTab _tabForSection(AppSection section) {
|
|
54
|
+
switch (section) {
|
|
55
|
+
case AppSection.mcp:
|
|
56
|
+
return _ToolsPageTab.mcp;
|
|
57
|
+
case AppSection.skills:
|
|
58
|
+
return _ToolsPageTab.skills;
|
|
59
|
+
default:
|
|
60
|
+
return _ToolsPageTab.integrations;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@override
|
|
65
|
+
Widget build(BuildContext context) {
|
|
66
|
+
final controller = widget.controller;
|
|
67
|
+
final visibleIntegrations = controller.officialIntegrations
|
|
68
|
+
.where(
|
|
69
|
+
(item) =>
|
|
70
|
+
item.env.configured ||
|
|
71
|
+
item.env.setupMode == 'user' ||
|
|
72
|
+
item.isConnected,
|
|
73
|
+
)
|
|
74
|
+
.length;
|
|
75
|
+
return Padding(
|
|
76
|
+
padding: _pagePadding(context),
|
|
77
|
+
child: Column(
|
|
78
|
+
children: <Widget>[
|
|
79
|
+
const _PageTitle(
|
|
80
|
+
title: 'Tools',
|
|
81
|
+
subtitle:
|
|
82
|
+
'Manage official integrations, MCP servers, and reusable skills in one place.',
|
|
83
|
+
),
|
|
84
|
+
const SizedBox(height: 12),
|
|
85
|
+
Container(
|
|
86
|
+
decoration: BoxDecoration(
|
|
87
|
+
color: _bgSecondary,
|
|
88
|
+
borderRadius: BorderRadius.circular(14),
|
|
89
|
+
border: Border.all(color: _border),
|
|
90
|
+
),
|
|
91
|
+
child: TabBar(
|
|
92
|
+
controller: _tabController,
|
|
93
|
+
dividerColor: Colors.transparent,
|
|
94
|
+
indicatorSize: TabBarIndicatorSize.tab,
|
|
95
|
+
labelStyle: const TextStyle(fontWeight: FontWeight.w700),
|
|
96
|
+
tabs: <Widget>[
|
|
97
|
+
Tab(text: 'Integrations ($visibleIntegrations)'),
|
|
98
|
+
Tab(text: 'MCP (${controller.mcpServers.length})'),
|
|
99
|
+
Tab(text: 'Skills (${controller.skills.length})'),
|
|
100
|
+
],
|
|
101
|
+
),
|
|
102
|
+
),
|
|
103
|
+
const SizedBox(height: 12),
|
|
104
|
+
Expanded(
|
|
105
|
+
child: TabBarView(
|
|
106
|
+
controller: _tabController,
|
|
107
|
+
children: <Widget>[
|
|
108
|
+
IntegrationsPanel(controller: controller, embedded: true),
|
|
109
|
+
McpPanel(controller: controller, embedded: true),
|
|
110
|
+
SkillsPanel(controller: controller, embedded: true),
|
|
111
|
+
],
|
|
112
|
+
),
|
|
113
|
+
),
|
|
114
|
+
],
|
|
115
|
+
),
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
class RunsAndLogsPanel extends StatefulWidget {
|
|
121
|
+
const RunsAndLogsPanel({super.key, required this.controller});
|
|
122
|
+
|
|
123
|
+
final NeoAgentController controller;
|
|
124
|
+
|
|
125
|
+
@override
|
|
126
|
+
State<RunsAndLogsPanel> createState() => _RunsAndLogsPanelState();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
class _RunsAndLogsPanelState extends State<RunsAndLogsPanel>
|
|
130
|
+
with SingleTickerProviderStateMixin {
|
|
131
|
+
late final TabController _tabController;
|
|
132
|
+
|
|
133
|
+
@override
|
|
134
|
+
void initState() {
|
|
135
|
+
super.initState();
|
|
136
|
+
_tabController = TabController(
|
|
137
|
+
length: _RunsPageTab.values.length,
|
|
138
|
+
vsync: this,
|
|
139
|
+
initialIndex: _tabForSection(widget.controller.selectedSection).index,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@override
|
|
144
|
+
void didUpdateWidget(covariant RunsAndLogsPanel oldWidget) {
|
|
145
|
+
super.didUpdateWidget(oldWidget);
|
|
146
|
+
final selectedSection = widget.controller.selectedSection;
|
|
147
|
+
if (selectedSection != oldWidget.controller.selectedSection &&
|
|
148
|
+
(selectedSection == AppSection.runs ||
|
|
149
|
+
selectedSection == AppSection.logs)) {
|
|
150
|
+
final targetIndex = _tabForSection(selectedSection).index;
|
|
151
|
+
if (_tabController.index != targetIndex) {
|
|
152
|
+
_tabController.index = targetIndex;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@override
|
|
158
|
+
void dispose() {
|
|
159
|
+
_tabController.dispose();
|
|
160
|
+
super.dispose();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
_RunsPageTab _tabForSection(AppSection section) {
|
|
164
|
+
switch (section) {
|
|
165
|
+
case AppSection.logs:
|
|
166
|
+
return _RunsPageTab.logs;
|
|
167
|
+
default:
|
|
168
|
+
return _RunsPageTab.runs;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@override
|
|
173
|
+
Widget build(BuildContext context) {
|
|
174
|
+
final controller = widget.controller;
|
|
175
|
+
return Padding(
|
|
176
|
+
padding: _pagePadding(context),
|
|
177
|
+
child: Column(
|
|
178
|
+
children: <Widget>[
|
|
179
|
+
const _PageTitle(
|
|
180
|
+
title: 'Runs & Logs',
|
|
181
|
+
subtitle:
|
|
182
|
+
'Inspect execution history, failures, tool traces, and diagnostics from one workspace.',
|
|
183
|
+
),
|
|
184
|
+
const SizedBox(height: 12),
|
|
185
|
+
Container(
|
|
186
|
+
decoration: BoxDecoration(
|
|
187
|
+
color: _bgSecondary,
|
|
188
|
+
borderRadius: BorderRadius.circular(14),
|
|
189
|
+
border: Border.all(color: _border),
|
|
190
|
+
),
|
|
191
|
+
child: TabBar(
|
|
192
|
+
controller: _tabController,
|
|
193
|
+
dividerColor: Colors.transparent,
|
|
194
|
+
indicatorSize: TabBarIndicatorSize.tab,
|
|
195
|
+
labelStyle: const TextStyle(fontWeight: FontWeight.w700),
|
|
196
|
+
tabs: <Widget>[
|
|
197
|
+
Tab(text: 'Runs (${controller.recentRuns.length})'),
|
|
198
|
+
Tab(text: 'Logs (${controller.logs.length})'),
|
|
199
|
+
],
|
|
200
|
+
),
|
|
201
|
+
),
|
|
202
|
+
const SizedBox(height: 12),
|
|
203
|
+
Expanded(
|
|
204
|
+
child: TabBarView(
|
|
205
|
+
controller: _tabController,
|
|
206
|
+
children: <Widget>[
|
|
207
|
+
RunsPanel(controller: controller, embedded: true),
|
|
208
|
+
LogsPanel(controller: controller, embedded: true),
|
|
209
|
+
],
|
|
210
|
+
),
|
|
211
|
+
),
|
|
212
|
+
],
|
|
213
|
+
),
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
class SettingsWorkspacePanel extends StatefulWidget {
|
|
219
|
+
const SettingsWorkspacePanel({super.key, required this.controller});
|
|
220
|
+
|
|
221
|
+
final NeoAgentController controller;
|
|
222
|
+
|
|
223
|
+
@override
|
|
224
|
+
State<SettingsWorkspacePanel> createState() => _SettingsWorkspacePanelState();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
class _SettingsWorkspacePanelState extends State<SettingsWorkspacePanel> {
|
|
228
|
+
late _SettingsWorkspaceSection _selectedSection;
|
|
229
|
+
|
|
230
|
+
@override
|
|
231
|
+
void initState() {
|
|
232
|
+
super.initState();
|
|
233
|
+
_selectedSection =
|
|
234
|
+
widget.controller.selectedSection == AppSection.accountSettings
|
|
235
|
+
? _SettingsWorkspaceSection.account
|
|
236
|
+
: _SettingsWorkspaceSection.app;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
@override
|
|
240
|
+
void didUpdateWidget(covariant SettingsWorkspacePanel oldWidget) {
|
|
241
|
+
super.didUpdateWidget(oldWidget);
|
|
242
|
+
if (widget.controller.selectedSection == AppSection.settings &&
|
|
243
|
+
_selectedSection != _SettingsWorkspaceSection.app) {
|
|
244
|
+
_selectedSection = _SettingsWorkspaceSection.app;
|
|
245
|
+
}
|
|
246
|
+
if (widget.controller.selectedSection == AppSection.accountSettings &&
|
|
247
|
+
_selectedSection == _SettingsWorkspaceSection.app) {
|
|
248
|
+
_selectedSection = _SettingsWorkspaceSection.account;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
@override
|
|
253
|
+
Widget build(BuildContext context) {
|
|
254
|
+
final compact = MediaQuery.sizeOf(context).width < 960;
|
|
255
|
+
return Padding(
|
|
256
|
+
padding: _pagePadding(context),
|
|
257
|
+
child: Column(
|
|
258
|
+
children: <Widget>[
|
|
259
|
+
const _PageTitle(
|
|
260
|
+
title: 'Settings',
|
|
261
|
+
subtitle:
|
|
262
|
+
'Workspace configuration and account security in one place.',
|
|
263
|
+
),
|
|
264
|
+
const SizedBox(height: 12),
|
|
265
|
+
Expanded(
|
|
266
|
+
child: Card(
|
|
267
|
+
child: Padding(
|
|
268
|
+
padding: const EdgeInsets.all(20),
|
|
269
|
+
child: compact
|
|
270
|
+
? Column(
|
|
271
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
272
|
+
children: <Widget>[
|
|
273
|
+
_SettingsWorkspaceNav(
|
|
274
|
+
selected: _selectedSection,
|
|
275
|
+
compact: true,
|
|
276
|
+
onSelected: _selectSection,
|
|
277
|
+
),
|
|
278
|
+
const SizedBox(height: 16),
|
|
279
|
+
Expanded(child: _buildContent()),
|
|
280
|
+
],
|
|
281
|
+
)
|
|
282
|
+
: Row(
|
|
283
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
284
|
+
children: <Widget>[
|
|
285
|
+
SizedBox(
|
|
286
|
+
width: 220,
|
|
287
|
+
child: _SettingsWorkspaceNav(
|
|
288
|
+
selected: _selectedSection,
|
|
289
|
+
compact: false,
|
|
290
|
+
onSelected: _selectSection,
|
|
291
|
+
),
|
|
292
|
+
),
|
|
293
|
+
const SizedBox(width: 24),
|
|
294
|
+
Expanded(child: _buildContent()),
|
|
295
|
+
],
|
|
296
|
+
),
|
|
297
|
+
),
|
|
298
|
+
),
|
|
299
|
+
),
|
|
300
|
+
],
|
|
301
|
+
),
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
void _selectSection(_SettingsWorkspaceSection section) {
|
|
306
|
+
setState(() => _selectedSection = section);
|
|
307
|
+
if (section == _SettingsWorkspaceSection.app) {
|
|
308
|
+
widget.controller.setSelectedSection(AppSection.settings);
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
widget.controller.setSelectedSection(AppSection.accountSettings);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
Widget _buildContent() {
|
|
315
|
+
switch (_selectedSection) {
|
|
316
|
+
case _SettingsWorkspaceSection.app:
|
|
317
|
+
return SettingsPanel(controller: widget.controller, embedded: true);
|
|
318
|
+
case _SettingsWorkspaceSection.account:
|
|
319
|
+
return AccountSettingsPanel(
|
|
320
|
+
controller: widget.controller,
|
|
321
|
+
embedded: true,
|
|
322
|
+
initialTab: AccountSettingsTab.account,
|
|
323
|
+
);
|
|
324
|
+
case _SettingsWorkspaceSection.security:
|
|
325
|
+
return AccountSettingsPanel(
|
|
326
|
+
controller: widget.controller,
|
|
327
|
+
embedded: true,
|
|
328
|
+
initialTab: AccountSettingsTab.security,
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
class _SettingsWorkspaceNav extends StatelessWidget {
|
|
335
|
+
const _SettingsWorkspaceNav({
|
|
336
|
+
required this.selected,
|
|
337
|
+
required this.compact,
|
|
338
|
+
required this.onSelected,
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
final _SettingsWorkspaceSection selected;
|
|
342
|
+
final bool compact;
|
|
343
|
+
final ValueChanged<_SettingsWorkspaceSection> onSelected;
|
|
344
|
+
|
|
345
|
+
@override
|
|
346
|
+
Widget build(BuildContext context) {
|
|
347
|
+
final items = <Widget>[
|
|
348
|
+
_navButton(
|
|
349
|
+
section: _SettingsWorkspaceSection.app,
|
|
350
|
+
icon: Icons.tune,
|
|
351
|
+
label: 'App Settings',
|
|
352
|
+
),
|
|
353
|
+
_navButton(
|
|
354
|
+
section: _SettingsWorkspaceSection.account,
|
|
355
|
+
icon: Icons.person_outline,
|
|
356
|
+
label: 'Account',
|
|
357
|
+
),
|
|
358
|
+
_navButton(
|
|
359
|
+
section: _SettingsWorkspaceSection.security,
|
|
360
|
+
icon: Icons.security_outlined,
|
|
361
|
+
label: 'Security',
|
|
362
|
+
),
|
|
363
|
+
];
|
|
364
|
+
return compact
|
|
365
|
+
? Wrap(spacing: 8, runSpacing: 8, children: items)
|
|
366
|
+
: Column(
|
|
367
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
368
|
+
children: items,
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
Widget _navButton({
|
|
373
|
+
required _SettingsWorkspaceSection section,
|
|
374
|
+
required IconData icon,
|
|
375
|
+
required String label,
|
|
376
|
+
}) {
|
|
377
|
+
final button = _SidebarButton(
|
|
378
|
+
label: label,
|
|
379
|
+
icon: icon,
|
|
380
|
+
active: selected == section,
|
|
381
|
+
onTap: () => onSelected(section),
|
|
382
|
+
);
|
|
383
|
+
if (compact) {
|
|
384
|
+
return button;
|
|
385
|
+
}
|
|
386
|
+
return Padding(padding: const EdgeInsets.only(bottom: 8), child: button);
|
|
387
|
+
}
|
|
388
|
+
}
|
package/package.json
CHANGED
package/server/db/database.js
CHANGED
|
@@ -442,6 +442,9 @@ db.exec(`
|
|
|
442
442
|
user_id INTEGER NOT NULL,
|
|
443
443
|
agent_id TEXT,
|
|
444
444
|
name TEXT NOT NULL,
|
|
445
|
+
widget_kind TEXT DEFAULT 'custom',
|
|
446
|
+
system_key TEXT,
|
|
447
|
+
is_system INTEGER DEFAULT 0,
|
|
445
448
|
template TEXT NOT NULL,
|
|
446
449
|
layout_variant TEXT NOT NULL,
|
|
447
450
|
definition_json TEXT DEFAULT '{}',
|
|
@@ -493,6 +496,13 @@ db.exec(`
|
|
|
493
496
|
user_id INTEGER NOT NULL,
|
|
494
497
|
agent_id TEXT,
|
|
495
498
|
category TEXT DEFAULT 'episodic',
|
|
499
|
+
scope_type TEXT DEFAULT 'agent',
|
|
500
|
+
scope_id TEXT,
|
|
501
|
+
source_type TEXT,
|
|
502
|
+
source_id TEXT,
|
|
503
|
+
source_label TEXT,
|
|
504
|
+
stale_after_days INTEGER,
|
|
505
|
+
metadata_json TEXT DEFAULT '{}',
|
|
496
506
|
content TEXT NOT NULL,
|
|
497
507
|
importance INTEGER DEFAULT 5,
|
|
498
508
|
embedding TEXT,
|
|
@@ -517,6 +527,36 @@ db.exec(`
|
|
|
517
527
|
CREATE INDEX IF NOT EXISTS idx_memories_user ON memories(user_id, archived, updated_at DESC);
|
|
518
528
|
CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(user_id, category, archived);
|
|
519
529
|
|
|
530
|
+
CREATE TABLE IF NOT EXISTS assistant_self_state (
|
|
531
|
+
user_id INTEGER NOT NULL,
|
|
532
|
+
agent_id TEXT NOT NULL,
|
|
533
|
+
identity_json TEXT DEFAULT '{}',
|
|
534
|
+
focus_json TEXT DEFAULT '{}',
|
|
535
|
+
updated_at TEXT DEFAULT (datetime('now')),
|
|
536
|
+
PRIMARY KEY (user_id, agent_id),
|
|
537
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
538
|
+
FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE
|
|
539
|
+
);
|
|
540
|
+
|
|
541
|
+
CREATE TABLE IF NOT EXISTS agent_run_events (
|
|
542
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
543
|
+
run_id TEXT NOT NULL,
|
|
544
|
+
user_id INTEGER NOT NULL,
|
|
545
|
+
agent_id TEXT,
|
|
546
|
+
event_type TEXT NOT NULL,
|
|
547
|
+
request_id TEXT,
|
|
548
|
+
step_id TEXT,
|
|
549
|
+
sequence_index INTEGER DEFAULT 0,
|
|
550
|
+
payload_json TEXT DEFAULT '{}',
|
|
551
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
552
|
+
FOREIGN KEY (run_id) REFERENCES agent_runs(id) ON DELETE CASCADE,
|
|
553
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
554
|
+
FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE SET NULL
|
|
555
|
+
);
|
|
556
|
+
|
|
557
|
+
CREATE INDEX IF NOT EXISTS idx_agent_run_events_run ON agent_run_events(run_id, sequence_index, id);
|
|
558
|
+
CREATE INDEX IF NOT EXISTS idx_agent_run_events_user ON agent_run_events(user_id, created_at DESC);
|
|
559
|
+
|
|
520
560
|
CREATE TABLE IF NOT EXISTS agent_settings (
|
|
521
561
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
522
562
|
user_id INTEGER NOT NULL,
|
|
@@ -837,6 +877,16 @@ for (const col of [
|
|
|
837
877
|
"ALTER TABLE conversation_history ADD COLUMN agent_id TEXT",
|
|
838
878
|
"ALTER TABLE memories ADD COLUMN agent_id TEXT",
|
|
839
879
|
"ALTER TABLE core_memory ADD COLUMN agent_id TEXT",
|
|
880
|
+
"ALTER TABLE ai_widgets ADD COLUMN widget_kind TEXT DEFAULT 'custom'",
|
|
881
|
+
"ALTER TABLE ai_widgets ADD COLUMN system_key TEXT",
|
|
882
|
+
"ALTER TABLE ai_widgets ADD COLUMN is_system INTEGER DEFAULT 0",
|
|
883
|
+
"ALTER TABLE memories ADD COLUMN scope_type TEXT DEFAULT 'agent'",
|
|
884
|
+
"ALTER TABLE memories ADD COLUMN scope_id TEXT",
|
|
885
|
+
"ALTER TABLE memories ADD COLUMN source_type TEXT",
|
|
886
|
+
"ALTER TABLE memories ADD COLUMN source_id TEXT",
|
|
887
|
+
"ALTER TABLE memories ADD COLUMN source_label TEXT",
|
|
888
|
+
"ALTER TABLE memories ADD COLUMN stale_after_days INTEGER",
|
|
889
|
+
"ALTER TABLE memories ADD COLUMN metadata_json TEXT DEFAULT '{}'",
|
|
840
890
|
"ALTER TABLE scheduled_tasks ADD COLUMN run_at TEXT",
|
|
841
891
|
"ALTER TABLE scheduled_tasks ADD COLUMN one_time INTEGER DEFAULT 0",
|
|
842
892
|
"ALTER TABLE scheduled_tasks ADD COLUMN execution_mode TEXT DEFAULT 'prompt'",
|
|
@@ -895,7 +945,9 @@ function createAgentScopedIndexes() {
|
|
|
895
945
|
['scheduled_tasks', 'CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_agent ON scheduled_tasks(user_id, agent_id)'],
|
|
896
946
|
['conversation_history', 'CREATE INDEX IF NOT EXISTS idx_conv_history_agent ON conversation_history(user_id, agent_id, created_at DESC)'],
|
|
897
947
|
['memories', 'CREATE INDEX IF NOT EXISTS idx_memories_agent ON memories(user_id, agent_id, archived, updated_at DESC)'],
|
|
948
|
+
['memories', 'CREATE INDEX IF NOT EXISTS idx_memories_scope ON memories(user_id, agent_id, scope_type, scope_id, archived, updated_at DESC)'],
|
|
898
949
|
['core_memory', 'CREATE INDEX IF NOT EXISTS idx_core_memory_agent ON core_memory(user_id, agent_id, key)'],
|
|
950
|
+
['ai_widgets', 'CREATE UNIQUE INDEX IF NOT EXISTS idx_ai_widgets_system_key ON ai_widgets(user_id, agent_id, system_key) WHERE system_key IS NOT NULL'],
|
|
899
951
|
];
|
|
900
952
|
for (const [table, statement] of statements) {
|
|
901
953
|
if (!tableHasColumn(table, 'agent_id')) continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
041b637a102d15b05aa2cd1af9c6e61e
|
|
Binary file
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"42d3d75a56efe1a2e9902f52dc8006099c45d9
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "4064509463" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|