saico 2.3.0 → 2.4.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/README.md +287 -300
- package/index.js +1 -4
- package/itask.js +16 -3
- package/msgs.js +35 -81
- package/package.json +1 -2
- package/saico.js +307 -35
- package/sid.js +0 -248
package/sid.js
DELETED
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const Itask = require('./itask.js');
|
|
4
|
-
const { Context, createContext } = require('./msgs.js');
|
|
5
|
-
const { Store } = require('./store.js');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Sid - Session/User Context root task.
|
|
9
|
-
*
|
|
10
|
-
* Extends Itask to serve as the root of task hierarchies.
|
|
11
|
-
* Always has a conversation context attached.
|
|
12
|
-
* Provides serialization support for persistence.
|
|
13
|
-
*/
|
|
14
|
-
class Sid extends Itask {
|
|
15
|
-
constructor(opt = {}, states = []) {
|
|
16
|
-
// Normalize options
|
|
17
|
-
if (typeof opt === 'string')
|
|
18
|
-
opt = { name: opt };
|
|
19
|
-
|
|
20
|
-
// Set defaults for a session root task
|
|
21
|
-
const name = opt.name || 'session';
|
|
22
|
-
const prompt = opt.prompt || '';
|
|
23
|
-
|
|
24
|
-
// Call parent constructor with async:true to control context creation
|
|
25
|
-
super({
|
|
26
|
-
...opt,
|
|
27
|
-
name,
|
|
28
|
-
prompt,
|
|
29
|
-
store: opt.store || Store.instance || null,
|
|
30
|
-
async: true // We'll manage running ourselves
|
|
31
|
-
}, states);
|
|
32
|
-
|
|
33
|
-
// User data storage
|
|
34
|
-
this.userData = opt.userData || {};
|
|
35
|
-
|
|
36
|
-
// Session-specific configuration
|
|
37
|
-
this.sessionConfig = {
|
|
38
|
-
token_limit: opt.token_limit,
|
|
39
|
-
max_depth: opt.max_depth,
|
|
40
|
-
max_tool_repetition: opt.max_tool_repetition,
|
|
41
|
-
queue_limit: opt.queue_limit,
|
|
42
|
-
min_chat_messages: opt.min_chat_messages,
|
|
43
|
-
...opt.sessionConfig
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// Generate context_id if not already set by parent constructor
|
|
47
|
-
if (!this.context_id) {
|
|
48
|
-
const store = this._store || Store.instance;
|
|
49
|
-
this.context_id = store ? store.generateId() : require('crypto').randomBytes(8).toString('hex');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Always create a context for Sid (root session task)
|
|
53
|
-
const contextConfig = {
|
|
54
|
-
tag: this.context_id,
|
|
55
|
-
token_limit: this.sessionConfig.token_limit,
|
|
56
|
-
max_depth: this.sessionConfig.max_depth,
|
|
57
|
-
max_tool_repetition: this.sessionConfig.max_tool_repetition,
|
|
58
|
-
queue_limit: this.sessionConfig.queue_limit,
|
|
59
|
-
min_chat_messages: this.sessionConfig.min_chat_messages,
|
|
60
|
-
tool_handler: opt.tool_handler,
|
|
61
|
-
functions: opt.functions,
|
|
62
|
-
sequential_mode: opt.sequential_mode,
|
|
63
|
-
msgs: opt.msgs,
|
|
64
|
-
chat_history: opt.chat_history
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
this.context = new Context(prompt, this, contextConfig);
|
|
68
|
-
|
|
69
|
-
// Start running if not explicitly set to async
|
|
70
|
-
if (opt.async !== true && states.length > 0) {
|
|
71
|
-
process.nextTick(() => {
|
|
72
|
-
try { this._run(); } catch (e) { console.error(e); }
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Override sendMessage — new signature: sendMessage(content, functions, opts)
|
|
78
|
-
// Always sends as role='user' with '[BACKEND] ' prefix
|
|
79
|
-
async sendMessage(content, functions, opts) {
|
|
80
|
-
opts = Object.assign({}, opts, { tag: this.context_id });
|
|
81
|
-
return this.context.sendMessage('user', '[BACKEND] ' + content, functions || this.functions, opts);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Receive a user chat message (no [BACKEND] prefix)
|
|
85
|
-
async recvChatMessage(content, opts) {
|
|
86
|
-
opts = Object.assign({}, opts, { tag: this.context_id });
|
|
87
|
-
return this.context.sendMessage('user', content, null, opts);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Serialize the session for persistence
|
|
91
|
-
serialize() {
|
|
92
|
-
return JSON.stringify({
|
|
93
|
-
id: this.id,
|
|
94
|
-
name: this.name,
|
|
95
|
-
prompt: this.prompt,
|
|
96
|
-
context_id: this.context_id,
|
|
97
|
-
userData: this.userData,
|
|
98
|
-
sessionConfig: this.sessionConfig,
|
|
99
|
-
context: {
|
|
100
|
-
tag: this.context.tag,
|
|
101
|
-
msgs: this.context._msgs,
|
|
102
|
-
functions: this.context.functions,
|
|
103
|
-
chat_history: this.context.chat_history,
|
|
104
|
-
tool_digest: this.context.tool_digest
|
|
105
|
-
},
|
|
106
|
-
tm_create: this.tm_create
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Deserialize a session from stored data
|
|
111
|
-
static deserialize(data, opt = {}) {
|
|
112
|
-
const parsed = typeof data === 'string' ? JSON.parse(data) : data;
|
|
113
|
-
|
|
114
|
-
const sid = new Sid({
|
|
115
|
-
name: parsed.name,
|
|
116
|
-
prompt: parsed.prompt,
|
|
117
|
-
context_id: parsed.context_id,
|
|
118
|
-
userData: parsed.userData,
|
|
119
|
-
sessionConfig: parsed.sessionConfig,
|
|
120
|
-
tag: parsed.context?.tag,
|
|
121
|
-
tool_handler: opt.tool_handler,
|
|
122
|
-
functions: opt.functions || parsed.context?.functions,
|
|
123
|
-
chat_history: parsed.context?.chat_history,
|
|
124
|
-
store: opt.store,
|
|
125
|
-
async: true, // Don't auto-run states
|
|
126
|
-
...opt
|
|
127
|
-
}, opt.states || []);
|
|
128
|
-
|
|
129
|
-
// Restore the original ID and timestamps
|
|
130
|
-
sid.id = parsed.id;
|
|
131
|
-
sid.tm_create = parsed.tm_create;
|
|
132
|
-
|
|
133
|
-
// Restore messages to context
|
|
134
|
-
if (parsed.context?.msgs) {
|
|
135
|
-
sid.context._msgs = parsed.context.msgs;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Restore tool_digest
|
|
139
|
-
if (Array.isArray(parsed.context?.tool_digest)) {
|
|
140
|
-
sid.context.tool_digest = parsed.context.tool_digest;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Load history from store if available
|
|
144
|
-
if (opt.store && parsed.context?.chat_history) {
|
|
145
|
-
sid.context.chat_history = parsed.context.chat_history;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return sid;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Create a child task with its own context
|
|
152
|
-
spawnTaskWithContext(opt, states = []) {
|
|
153
|
-
if (typeof opt === 'string')
|
|
154
|
-
opt = { name: opt };
|
|
155
|
-
|
|
156
|
-
const childTask = new Itask({
|
|
157
|
-
...opt,
|
|
158
|
-
spawn_parent: this,
|
|
159
|
-
store: this._store,
|
|
160
|
-
async: true
|
|
161
|
-
}, states);
|
|
162
|
-
|
|
163
|
-
if (opt.prompt) {
|
|
164
|
-
const childContext = new Context(opt.prompt, childTask, {
|
|
165
|
-
tag: opt.tag || childTask.id,
|
|
166
|
-
token_limit: opt.token_limit || this.sessionConfig.token_limit,
|
|
167
|
-
max_depth: opt.max_depth || this.sessionConfig.max_depth,
|
|
168
|
-
max_tool_repetition: opt.max_tool_repetition || this.sessionConfig.max_tool_repetition,
|
|
169
|
-
queue_limit: opt.queue_limit ?? this.sessionConfig.queue_limit,
|
|
170
|
-
min_chat_messages: opt.min_chat_messages ?? this.sessionConfig.min_chat_messages,
|
|
171
|
-
tool_handler: opt.tool_handler || this.tool_handler,
|
|
172
|
-
functions: opt.functions || this.functions
|
|
173
|
-
});
|
|
174
|
-
childTask.setContext(childContext);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Start the child task
|
|
178
|
-
process.nextTick(() => {
|
|
179
|
-
try { childTask._run(); } catch (e) { console.error(e); }
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
return childTask;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Create a child task without its own context (uses parent's context)
|
|
186
|
-
spawnTask(opt, states = []) {
|
|
187
|
-
if (typeof opt === 'string')
|
|
188
|
-
opt = { name: opt };
|
|
189
|
-
|
|
190
|
-
const childTask = new Itask({
|
|
191
|
-
...opt,
|
|
192
|
-
spawn_parent: this,
|
|
193
|
-
store: this._store,
|
|
194
|
-
async: true
|
|
195
|
-
}, states);
|
|
196
|
-
|
|
197
|
-
// Start the child task
|
|
198
|
-
process.nextTick(() => {
|
|
199
|
-
try { childTask._run(); } catch (e) { console.error(e); }
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
return childTask;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Close the session - summarize context and cleanup
|
|
206
|
-
async closeSession() {
|
|
207
|
-
await this.context.close();
|
|
208
|
-
this._ecancel();
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Get session info for debugging/monitoring
|
|
212
|
-
getSessionInfo() {
|
|
213
|
-
return {
|
|
214
|
-
id: this.id,
|
|
215
|
-
name: this.name,
|
|
216
|
-
running: this.running,
|
|
217
|
-
completed: this._completed,
|
|
218
|
-
messageCount: this.context.length,
|
|
219
|
-
childCount: this.child.size,
|
|
220
|
-
userData: this.userData,
|
|
221
|
-
uptime: Date.now() - this.tm_create
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Store user data
|
|
226
|
-
setUserData(key, value) {
|
|
227
|
-
this.userData[key] = value;
|
|
228
|
-
return this;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Get user data
|
|
232
|
-
getUserData(key) {
|
|
233
|
-
return key ? this.userData[key] : this.userData;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Clear user data
|
|
237
|
-
clearUserData() {
|
|
238
|
-
this.userData = {};
|
|
239
|
-
return this;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Factory function to create a Sid instance
|
|
244
|
-
function createSid(opt = {}, states = []) {
|
|
245
|
-
return new Sid(opt, states);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
module.exports = { Sid, createSid };
|