@sesamespace/hivemind 0.4.2 → 0.4.3
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/README.md +116 -0
- package/dist/{chunk-RXCV57H3.js → chunk-CGSXJVSS.js} +2 -2
- package/dist/{chunk-OQ272HKA.js → chunk-O257FXSX.js} +2 -2
- package/dist/{chunk-YEOAEJ62.js → chunk-S3RVZBPZ.js} +2 -2
- package/dist/chunk-YHRGEWAZ.js +2326 -0
- package/dist/chunk-YHRGEWAZ.js.map +1 -0
- package/dist/commands/fleet.js +3 -4
- package/dist/commands/init.js +0 -1
- package/dist/commands/service.js +0 -1
- package/dist/commands/start.js +3 -4
- package/dist/commands/upgrade.js +0 -1
- package/dist/config/TEAM-CHARTER.md +87 -0
- package/dist/config/default.toml +39 -0
- package/dist/index.js +2 -3
- package/dist/main.js +4 -5
- package/dist/main.js.map +1 -1
- package/dist/package.json +26 -0
- package/dist/start.js +1 -2
- package/dist/start.js.map +1 -1
- package/npm-package.json +1 -3
- package/package.json +3 -2
- package/packages/runtime/package.json +1 -1
- package/packages/runtime/src/config.ts +1 -1
- package/scripts/build-npm.sh +1 -3
- package/tsup.config.ts +1 -1
- package/dist/chunk-7D4SUZUM.js +0 -38
- package/dist/chunk-7D4SUZUM.js.map +0 -1
- package/dist/chunk-LRK64BAK.js +0 -3601
- package/dist/chunk-LRK64BAK.js.map +0 -1
- /package/dist/{chunk-RXCV57H3.js.map → chunk-CGSXJVSS.js.map} +0 -0
- /package/dist/{chunk-OQ272HKA.js.map → chunk-O257FXSX.js.map} +0 -0
- /package/dist/{chunk-YEOAEJ62.js.map → chunk-S3RVZBPZ.js.map} +0 -0
package/dist/chunk-LRK64BAK.js
DELETED
|
@@ -1,3601 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SesameClient
|
|
3
|
-
} from "./chunk-GPI4RU7N.js";
|
|
4
|
-
import {
|
|
5
|
-
__commonJS,
|
|
6
|
-
__require,
|
|
7
|
-
__toESM
|
|
8
|
-
} from "./chunk-7D4SUZUM.js";
|
|
9
|
-
|
|
10
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/parser.js
|
|
11
|
-
var require_parser = __commonJS({
|
|
12
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/parser.js"(exports2, module2) {
|
|
13
|
-
"use strict";
|
|
14
|
-
var ParserEND = 1114112;
|
|
15
|
-
var ParserError = class _ParserError extends Error {
|
|
16
|
-
/* istanbul ignore next */
|
|
17
|
-
constructor(msg, filename, linenumber) {
|
|
18
|
-
super("[ParserError] " + msg, filename, linenumber);
|
|
19
|
-
this.name = "ParserError";
|
|
20
|
-
this.code = "ParserError";
|
|
21
|
-
if (Error.captureStackTrace) Error.captureStackTrace(this, _ParserError);
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
var State = class {
|
|
25
|
-
constructor(parser) {
|
|
26
|
-
this.parser = parser;
|
|
27
|
-
this.buf = "";
|
|
28
|
-
this.returned = null;
|
|
29
|
-
this.result = null;
|
|
30
|
-
this.resultTable = null;
|
|
31
|
-
this.resultArr = null;
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
var Parser = class {
|
|
35
|
-
constructor() {
|
|
36
|
-
this.pos = 0;
|
|
37
|
-
this.col = 0;
|
|
38
|
-
this.line = 0;
|
|
39
|
-
this.obj = {};
|
|
40
|
-
this.ctx = this.obj;
|
|
41
|
-
this.stack = [];
|
|
42
|
-
this._buf = "";
|
|
43
|
-
this.char = null;
|
|
44
|
-
this.ii = 0;
|
|
45
|
-
this.state = new State(this.parseStart);
|
|
46
|
-
}
|
|
47
|
-
parse(str) {
|
|
48
|
-
if (str.length === 0 || str.length == null) return;
|
|
49
|
-
this._buf = String(str);
|
|
50
|
-
this.ii = -1;
|
|
51
|
-
this.char = -1;
|
|
52
|
-
let getNext;
|
|
53
|
-
while (getNext === false || this.nextChar()) {
|
|
54
|
-
getNext = this.runOne();
|
|
55
|
-
}
|
|
56
|
-
this._buf = null;
|
|
57
|
-
}
|
|
58
|
-
nextChar() {
|
|
59
|
-
if (this.char === 10) {
|
|
60
|
-
++this.line;
|
|
61
|
-
this.col = -1;
|
|
62
|
-
}
|
|
63
|
-
++this.ii;
|
|
64
|
-
this.char = this._buf.codePointAt(this.ii);
|
|
65
|
-
++this.pos;
|
|
66
|
-
++this.col;
|
|
67
|
-
return this.haveBuffer();
|
|
68
|
-
}
|
|
69
|
-
haveBuffer() {
|
|
70
|
-
return this.ii < this._buf.length;
|
|
71
|
-
}
|
|
72
|
-
runOne() {
|
|
73
|
-
return this.state.parser.call(this, this.state.returned);
|
|
74
|
-
}
|
|
75
|
-
finish() {
|
|
76
|
-
this.char = ParserEND;
|
|
77
|
-
let last;
|
|
78
|
-
do {
|
|
79
|
-
last = this.state.parser;
|
|
80
|
-
this.runOne();
|
|
81
|
-
} while (this.state.parser !== last);
|
|
82
|
-
this.ctx = null;
|
|
83
|
-
this.state = null;
|
|
84
|
-
this._buf = null;
|
|
85
|
-
return this.obj;
|
|
86
|
-
}
|
|
87
|
-
next(fn) {
|
|
88
|
-
if (typeof fn !== "function") throw new ParserError("Tried to set state to non-existent state: " + JSON.stringify(fn));
|
|
89
|
-
this.state.parser = fn;
|
|
90
|
-
}
|
|
91
|
-
goto(fn) {
|
|
92
|
-
this.next(fn);
|
|
93
|
-
return this.runOne();
|
|
94
|
-
}
|
|
95
|
-
call(fn, returnWith) {
|
|
96
|
-
if (returnWith) this.next(returnWith);
|
|
97
|
-
this.stack.push(this.state);
|
|
98
|
-
this.state = new State(fn);
|
|
99
|
-
}
|
|
100
|
-
callNow(fn, returnWith) {
|
|
101
|
-
this.call(fn, returnWith);
|
|
102
|
-
return this.runOne();
|
|
103
|
-
}
|
|
104
|
-
return(value) {
|
|
105
|
-
if (this.stack.length === 0) throw this.error(new ParserError("Stack underflow"));
|
|
106
|
-
if (value === void 0) value = this.state.buf;
|
|
107
|
-
this.state = this.stack.pop();
|
|
108
|
-
this.state.returned = value;
|
|
109
|
-
}
|
|
110
|
-
returnNow(value) {
|
|
111
|
-
this.return(value);
|
|
112
|
-
return this.runOne();
|
|
113
|
-
}
|
|
114
|
-
consume() {
|
|
115
|
-
if (this.char === ParserEND) throw this.error(new ParserError("Unexpected end-of-buffer"));
|
|
116
|
-
this.state.buf += this._buf[this.ii];
|
|
117
|
-
}
|
|
118
|
-
error(err) {
|
|
119
|
-
err.line = this.line;
|
|
120
|
-
err.col = this.col;
|
|
121
|
-
err.pos = this.pos;
|
|
122
|
-
return err;
|
|
123
|
-
}
|
|
124
|
-
/* istanbul ignore next */
|
|
125
|
-
parseStart() {
|
|
126
|
-
throw new ParserError("Must declare a parseStart method");
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
Parser.END = ParserEND;
|
|
130
|
-
Parser.Error = ParserError;
|
|
131
|
-
module2.exports = Parser;
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-datetime.js
|
|
136
|
-
var require_create_datetime = __commonJS({
|
|
137
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-datetime.js"(exports2, module2) {
|
|
138
|
-
"use strict";
|
|
139
|
-
module2.exports = (value) => {
|
|
140
|
-
const date = new Date(value);
|
|
141
|
-
if (isNaN(date)) {
|
|
142
|
-
throw new TypeError("Invalid Datetime");
|
|
143
|
-
} else {
|
|
144
|
-
return date;
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/format-num.js
|
|
151
|
-
var require_format_num = __commonJS({
|
|
152
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/format-num.js"(exports2, module2) {
|
|
153
|
-
"use strict";
|
|
154
|
-
module2.exports = (d, num) => {
|
|
155
|
-
num = String(num);
|
|
156
|
-
while (num.length < d) num = "0" + num;
|
|
157
|
-
return num;
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-datetime-float.js
|
|
163
|
-
var require_create_datetime_float = __commonJS({
|
|
164
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-datetime-float.js"(exports2, module2) {
|
|
165
|
-
"use strict";
|
|
166
|
-
var f = require_format_num();
|
|
167
|
-
var FloatingDateTime = class extends Date {
|
|
168
|
-
constructor(value) {
|
|
169
|
-
super(value + "Z");
|
|
170
|
-
this.isFloating = true;
|
|
171
|
-
}
|
|
172
|
-
toISOString() {
|
|
173
|
-
const date = `${this.getUTCFullYear()}-${f(2, this.getUTCMonth() + 1)}-${f(2, this.getUTCDate())}`;
|
|
174
|
-
const time = `${f(2, this.getUTCHours())}:${f(2, this.getUTCMinutes())}:${f(2, this.getUTCSeconds())}.${f(3, this.getUTCMilliseconds())}`;
|
|
175
|
-
return `${date}T${time}`;
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
module2.exports = (value) => {
|
|
179
|
-
const date = new FloatingDateTime(value);
|
|
180
|
-
if (isNaN(date)) {
|
|
181
|
-
throw new TypeError("Invalid Datetime");
|
|
182
|
-
} else {
|
|
183
|
-
return date;
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-date.js
|
|
190
|
-
var require_create_date = __commonJS({
|
|
191
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-date.js"(exports2, module2) {
|
|
192
|
-
"use strict";
|
|
193
|
-
var f = require_format_num();
|
|
194
|
-
var DateTime = global.Date;
|
|
195
|
-
var Date2 = class extends DateTime {
|
|
196
|
-
constructor(value) {
|
|
197
|
-
super(value);
|
|
198
|
-
this.isDate = true;
|
|
199
|
-
}
|
|
200
|
-
toISOString() {
|
|
201
|
-
return `${this.getUTCFullYear()}-${f(2, this.getUTCMonth() + 1)}-${f(2, this.getUTCDate())}`;
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
module2.exports = (value) => {
|
|
205
|
-
const date = new Date2(value);
|
|
206
|
-
if (isNaN(date)) {
|
|
207
|
-
throw new TypeError("Invalid Datetime");
|
|
208
|
-
} else {
|
|
209
|
-
return date;
|
|
210
|
-
}
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-time.js
|
|
216
|
-
var require_create_time = __commonJS({
|
|
217
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-time.js"(exports2, module2) {
|
|
218
|
-
"use strict";
|
|
219
|
-
var f = require_format_num();
|
|
220
|
-
var Time = class extends Date {
|
|
221
|
-
constructor(value) {
|
|
222
|
-
super(`0000-01-01T${value}Z`);
|
|
223
|
-
this.isTime = true;
|
|
224
|
-
}
|
|
225
|
-
toISOString() {
|
|
226
|
-
return `${f(2, this.getUTCHours())}:${f(2, this.getUTCMinutes())}:${f(2, this.getUTCSeconds())}.${f(3, this.getUTCMilliseconds())}`;
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
module2.exports = (value) => {
|
|
230
|
-
const date = new Time(value);
|
|
231
|
-
if (isNaN(date)) {
|
|
232
|
-
throw new TypeError("Invalid Datetime");
|
|
233
|
-
} else {
|
|
234
|
-
return date;
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/toml-parser.js
|
|
241
|
-
var require_toml_parser = __commonJS({
|
|
242
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/toml-parser.js"(exports, module) {
|
|
243
|
-
"use strict";
|
|
244
|
-
module.exports = makeParserClass(require_parser());
|
|
245
|
-
module.exports.makeParserClass = makeParserClass;
|
|
246
|
-
var TomlError = class _TomlError extends Error {
|
|
247
|
-
constructor(msg) {
|
|
248
|
-
super(msg);
|
|
249
|
-
this.name = "TomlError";
|
|
250
|
-
if (Error.captureStackTrace) Error.captureStackTrace(this, _TomlError);
|
|
251
|
-
this.fromTOML = true;
|
|
252
|
-
this.wrapped = null;
|
|
253
|
-
}
|
|
254
|
-
};
|
|
255
|
-
TomlError.wrap = (err) => {
|
|
256
|
-
const terr = new TomlError(err.message);
|
|
257
|
-
terr.code = err.code;
|
|
258
|
-
terr.wrapped = err;
|
|
259
|
-
return terr;
|
|
260
|
-
};
|
|
261
|
-
module.exports.TomlError = TomlError;
|
|
262
|
-
var createDateTime = require_create_datetime();
|
|
263
|
-
var createDateTimeFloat = require_create_datetime_float();
|
|
264
|
-
var createDate = require_create_date();
|
|
265
|
-
var createTime = require_create_time();
|
|
266
|
-
var CTRL_I = 9;
|
|
267
|
-
var CTRL_J = 10;
|
|
268
|
-
var CTRL_M = 13;
|
|
269
|
-
var CTRL_CHAR_BOUNDARY = 31;
|
|
270
|
-
var CHAR_SP = 32;
|
|
271
|
-
var CHAR_QUOT = 34;
|
|
272
|
-
var CHAR_NUM = 35;
|
|
273
|
-
var CHAR_APOS = 39;
|
|
274
|
-
var CHAR_PLUS = 43;
|
|
275
|
-
var CHAR_COMMA = 44;
|
|
276
|
-
var CHAR_HYPHEN = 45;
|
|
277
|
-
var CHAR_PERIOD = 46;
|
|
278
|
-
var CHAR_0 = 48;
|
|
279
|
-
var CHAR_1 = 49;
|
|
280
|
-
var CHAR_7 = 55;
|
|
281
|
-
var CHAR_9 = 57;
|
|
282
|
-
var CHAR_COLON = 58;
|
|
283
|
-
var CHAR_EQUALS = 61;
|
|
284
|
-
var CHAR_A = 65;
|
|
285
|
-
var CHAR_E = 69;
|
|
286
|
-
var CHAR_F = 70;
|
|
287
|
-
var CHAR_T = 84;
|
|
288
|
-
var CHAR_U = 85;
|
|
289
|
-
var CHAR_Z = 90;
|
|
290
|
-
var CHAR_LOWBAR = 95;
|
|
291
|
-
var CHAR_a = 97;
|
|
292
|
-
var CHAR_b = 98;
|
|
293
|
-
var CHAR_e = 101;
|
|
294
|
-
var CHAR_f = 102;
|
|
295
|
-
var CHAR_i = 105;
|
|
296
|
-
var CHAR_l = 108;
|
|
297
|
-
var CHAR_n = 110;
|
|
298
|
-
var CHAR_o = 111;
|
|
299
|
-
var CHAR_r = 114;
|
|
300
|
-
var CHAR_s = 115;
|
|
301
|
-
var CHAR_t = 116;
|
|
302
|
-
var CHAR_u = 117;
|
|
303
|
-
var CHAR_x = 120;
|
|
304
|
-
var CHAR_z = 122;
|
|
305
|
-
var CHAR_LCUB = 123;
|
|
306
|
-
var CHAR_RCUB = 125;
|
|
307
|
-
var CHAR_LSQB = 91;
|
|
308
|
-
var CHAR_BSOL = 92;
|
|
309
|
-
var CHAR_RSQB = 93;
|
|
310
|
-
var CHAR_DEL = 127;
|
|
311
|
-
var SURROGATE_FIRST = 55296;
|
|
312
|
-
var SURROGATE_LAST = 57343;
|
|
313
|
-
var escapes = {
|
|
314
|
-
[CHAR_b]: "\b",
|
|
315
|
-
[CHAR_t]: " ",
|
|
316
|
-
[CHAR_n]: "\n",
|
|
317
|
-
[CHAR_f]: "\f",
|
|
318
|
-
[CHAR_r]: "\r",
|
|
319
|
-
[CHAR_QUOT]: '"',
|
|
320
|
-
[CHAR_BSOL]: "\\"
|
|
321
|
-
};
|
|
322
|
-
function isDigit(cp) {
|
|
323
|
-
return cp >= CHAR_0 && cp <= CHAR_9;
|
|
324
|
-
}
|
|
325
|
-
function isHexit(cp) {
|
|
326
|
-
return cp >= CHAR_A && cp <= CHAR_F || cp >= CHAR_a && cp <= CHAR_f || cp >= CHAR_0 && cp <= CHAR_9;
|
|
327
|
-
}
|
|
328
|
-
function isBit(cp) {
|
|
329
|
-
return cp === CHAR_1 || cp === CHAR_0;
|
|
330
|
-
}
|
|
331
|
-
function isOctit(cp) {
|
|
332
|
-
return cp >= CHAR_0 && cp <= CHAR_7;
|
|
333
|
-
}
|
|
334
|
-
function isAlphaNumQuoteHyphen(cp) {
|
|
335
|
-
return cp >= CHAR_A && cp <= CHAR_Z || cp >= CHAR_a && cp <= CHAR_z || cp >= CHAR_0 && cp <= CHAR_9 || cp === CHAR_APOS || cp === CHAR_QUOT || cp === CHAR_LOWBAR || cp === CHAR_HYPHEN;
|
|
336
|
-
}
|
|
337
|
-
function isAlphaNumHyphen(cp) {
|
|
338
|
-
return cp >= CHAR_A && cp <= CHAR_Z || cp >= CHAR_a && cp <= CHAR_z || cp >= CHAR_0 && cp <= CHAR_9 || cp === CHAR_LOWBAR || cp === CHAR_HYPHEN;
|
|
339
|
-
}
|
|
340
|
-
var _type = /* @__PURE__ */ Symbol("type");
|
|
341
|
-
var _declared = /* @__PURE__ */ Symbol("declared");
|
|
342
|
-
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
343
|
-
var defineProperty = Object.defineProperty;
|
|
344
|
-
var descriptor = { configurable: true, enumerable: true, writable: true, value: void 0 };
|
|
345
|
-
function hasKey(obj, key) {
|
|
346
|
-
if (hasOwnProperty.call(obj, key)) return true;
|
|
347
|
-
if (key === "__proto__") defineProperty(obj, "__proto__", descriptor);
|
|
348
|
-
return false;
|
|
349
|
-
}
|
|
350
|
-
var INLINE_TABLE = /* @__PURE__ */ Symbol("inline-table");
|
|
351
|
-
function InlineTable() {
|
|
352
|
-
return Object.defineProperties({}, {
|
|
353
|
-
[_type]: { value: INLINE_TABLE }
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
function isInlineTable(obj) {
|
|
357
|
-
if (obj === null || typeof obj !== "object") return false;
|
|
358
|
-
return obj[_type] === INLINE_TABLE;
|
|
359
|
-
}
|
|
360
|
-
var TABLE = /* @__PURE__ */ Symbol("table");
|
|
361
|
-
function Table() {
|
|
362
|
-
return Object.defineProperties({}, {
|
|
363
|
-
[_type]: { value: TABLE },
|
|
364
|
-
[_declared]: { value: false, writable: true }
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
function isTable(obj) {
|
|
368
|
-
if (obj === null || typeof obj !== "object") return false;
|
|
369
|
-
return obj[_type] === TABLE;
|
|
370
|
-
}
|
|
371
|
-
var _contentType = /* @__PURE__ */ Symbol("content-type");
|
|
372
|
-
var INLINE_LIST = /* @__PURE__ */ Symbol("inline-list");
|
|
373
|
-
function InlineList(type) {
|
|
374
|
-
return Object.defineProperties([], {
|
|
375
|
-
[_type]: { value: INLINE_LIST },
|
|
376
|
-
[_contentType]: { value: type }
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
function isInlineList(obj) {
|
|
380
|
-
if (obj === null || typeof obj !== "object") return false;
|
|
381
|
-
return obj[_type] === INLINE_LIST;
|
|
382
|
-
}
|
|
383
|
-
var LIST = /* @__PURE__ */ Symbol("list");
|
|
384
|
-
function List() {
|
|
385
|
-
return Object.defineProperties([], {
|
|
386
|
-
[_type]: { value: LIST }
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
function isList(obj) {
|
|
390
|
-
if (obj === null || typeof obj !== "object") return false;
|
|
391
|
-
return obj[_type] === LIST;
|
|
392
|
-
}
|
|
393
|
-
var _custom;
|
|
394
|
-
try {
|
|
395
|
-
const utilInspect = eval("require('util').inspect");
|
|
396
|
-
_custom = utilInspect.custom;
|
|
397
|
-
} catch (_) {
|
|
398
|
-
}
|
|
399
|
-
var _inspect = _custom || "inspect";
|
|
400
|
-
var BoxedBigInt = class {
|
|
401
|
-
constructor(value) {
|
|
402
|
-
try {
|
|
403
|
-
this.value = global.BigInt.asIntN(64, value);
|
|
404
|
-
} catch (_) {
|
|
405
|
-
this.value = null;
|
|
406
|
-
}
|
|
407
|
-
Object.defineProperty(this, _type, { value: INTEGER });
|
|
408
|
-
}
|
|
409
|
-
isNaN() {
|
|
410
|
-
return this.value === null;
|
|
411
|
-
}
|
|
412
|
-
/* istanbul ignore next */
|
|
413
|
-
toString() {
|
|
414
|
-
return String(this.value);
|
|
415
|
-
}
|
|
416
|
-
/* istanbul ignore next */
|
|
417
|
-
[_inspect]() {
|
|
418
|
-
return `[BigInt: ${this.toString()}]}`;
|
|
419
|
-
}
|
|
420
|
-
valueOf() {
|
|
421
|
-
return this.value;
|
|
422
|
-
}
|
|
423
|
-
};
|
|
424
|
-
var INTEGER = /* @__PURE__ */ Symbol("integer");
|
|
425
|
-
function Integer(value) {
|
|
426
|
-
let num = Number(value);
|
|
427
|
-
if (Object.is(num, -0)) num = 0;
|
|
428
|
-
if (global.BigInt && !Number.isSafeInteger(num)) {
|
|
429
|
-
return new BoxedBigInt(value);
|
|
430
|
-
} else {
|
|
431
|
-
return Object.defineProperties(new Number(num), {
|
|
432
|
-
isNaN: { value: function() {
|
|
433
|
-
return isNaN(this);
|
|
434
|
-
} },
|
|
435
|
-
[_type]: { value: INTEGER },
|
|
436
|
-
[_inspect]: { value: () => `[Integer: ${value}]` }
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
function isInteger(obj) {
|
|
441
|
-
if (obj === null || typeof obj !== "object") return false;
|
|
442
|
-
return obj[_type] === INTEGER;
|
|
443
|
-
}
|
|
444
|
-
var FLOAT = /* @__PURE__ */ Symbol("float");
|
|
445
|
-
function Float(value) {
|
|
446
|
-
return Object.defineProperties(new Number(value), {
|
|
447
|
-
[_type]: { value: FLOAT },
|
|
448
|
-
[_inspect]: { value: () => `[Float: ${value}]` }
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
function isFloat(obj) {
|
|
452
|
-
if (obj === null || typeof obj !== "object") return false;
|
|
453
|
-
return obj[_type] === FLOAT;
|
|
454
|
-
}
|
|
455
|
-
function tomlType(value) {
|
|
456
|
-
const type = typeof value;
|
|
457
|
-
if (type === "object") {
|
|
458
|
-
if (value === null) return "null";
|
|
459
|
-
if (value instanceof Date) return "datetime";
|
|
460
|
-
if (_type in value) {
|
|
461
|
-
switch (value[_type]) {
|
|
462
|
-
case INLINE_TABLE:
|
|
463
|
-
return "inline-table";
|
|
464
|
-
case INLINE_LIST:
|
|
465
|
-
return "inline-list";
|
|
466
|
-
/* istanbul ignore next */
|
|
467
|
-
case TABLE:
|
|
468
|
-
return "table";
|
|
469
|
-
/* istanbul ignore next */
|
|
470
|
-
case LIST:
|
|
471
|
-
return "list";
|
|
472
|
-
case FLOAT:
|
|
473
|
-
return "float";
|
|
474
|
-
case INTEGER:
|
|
475
|
-
return "integer";
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
return type;
|
|
480
|
-
}
|
|
481
|
-
function makeParserClass(Parser) {
|
|
482
|
-
class TOMLParser extends Parser {
|
|
483
|
-
constructor() {
|
|
484
|
-
super();
|
|
485
|
-
this.ctx = this.obj = Table();
|
|
486
|
-
}
|
|
487
|
-
/* MATCH HELPER */
|
|
488
|
-
atEndOfWord() {
|
|
489
|
-
return this.char === CHAR_NUM || this.char === CTRL_I || this.char === CHAR_SP || this.atEndOfLine();
|
|
490
|
-
}
|
|
491
|
-
atEndOfLine() {
|
|
492
|
-
return this.char === Parser.END || this.char === CTRL_J || this.char === CTRL_M;
|
|
493
|
-
}
|
|
494
|
-
parseStart() {
|
|
495
|
-
if (this.char === Parser.END) {
|
|
496
|
-
return null;
|
|
497
|
-
} else if (this.char === CHAR_LSQB) {
|
|
498
|
-
return this.call(this.parseTableOrList);
|
|
499
|
-
} else if (this.char === CHAR_NUM) {
|
|
500
|
-
return this.call(this.parseComment);
|
|
501
|
-
} else if (this.char === CTRL_J || this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) {
|
|
502
|
-
return null;
|
|
503
|
-
} else if (isAlphaNumQuoteHyphen(this.char)) {
|
|
504
|
-
return this.callNow(this.parseAssignStatement);
|
|
505
|
-
} else {
|
|
506
|
-
throw this.error(new TomlError(`Unknown character "${this.char}"`));
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
// HELPER, this strips any whitespace and comments to the end of the line
|
|
510
|
-
// then RETURNS. Last state in a production.
|
|
511
|
-
parseWhitespaceToEOL() {
|
|
512
|
-
if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) {
|
|
513
|
-
return null;
|
|
514
|
-
} else if (this.char === CHAR_NUM) {
|
|
515
|
-
return this.goto(this.parseComment);
|
|
516
|
-
} else if (this.char === Parser.END || this.char === CTRL_J) {
|
|
517
|
-
return this.return();
|
|
518
|
-
} else {
|
|
519
|
-
throw this.error(new TomlError("Unexpected character, expected only whitespace or comments till end of line"));
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
/* ASSIGNMENT: key = value */
|
|
523
|
-
parseAssignStatement() {
|
|
524
|
-
return this.callNow(this.parseAssign, this.recordAssignStatement);
|
|
525
|
-
}
|
|
526
|
-
recordAssignStatement(kv) {
|
|
527
|
-
let target = this.ctx;
|
|
528
|
-
let finalKey = kv.key.pop();
|
|
529
|
-
for (let kw of kv.key) {
|
|
530
|
-
if (hasKey(target, kw) && (!isTable(target[kw]) || target[kw][_declared])) {
|
|
531
|
-
throw this.error(new TomlError("Can't redefine existing key"));
|
|
532
|
-
}
|
|
533
|
-
target = target[kw] = target[kw] || Table();
|
|
534
|
-
}
|
|
535
|
-
if (hasKey(target, finalKey)) {
|
|
536
|
-
throw this.error(new TomlError("Can't redefine existing key"));
|
|
537
|
-
}
|
|
538
|
-
if (isInteger(kv.value) || isFloat(kv.value)) {
|
|
539
|
-
target[finalKey] = kv.value.valueOf();
|
|
540
|
-
} else {
|
|
541
|
-
target[finalKey] = kv.value;
|
|
542
|
-
}
|
|
543
|
-
return this.goto(this.parseWhitespaceToEOL);
|
|
544
|
-
}
|
|
545
|
-
/* ASSSIGNMENT expression, key = value possibly inside an inline table */
|
|
546
|
-
parseAssign() {
|
|
547
|
-
return this.callNow(this.parseKeyword, this.recordAssignKeyword);
|
|
548
|
-
}
|
|
549
|
-
recordAssignKeyword(key) {
|
|
550
|
-
if (this.state.resultTable) {
|
|
551
|
-
this.state.resultTable.push(key);
|
|
552
|
-
} else {
|
|
553
|
-
this.state.resultTable = [key];
|
|
554
|
-
}
|
|
555
|
-
return this.goto(this.parseAssignKeywordPreDot);
|
|
556
|
-
}
|
|
557
|
-
parseAssignKeywordPreDot() {
|
|
558
|
-
if (this.char === CHAR_PERIOD) {
|
|
559
|
-
return this.next(this.parseAssignKeywordPostDot);
|
|
560
|
-
} else if (this.char !== CHAR_SP && this.char !== CTRL_I) {
|
|
561
|
-
return this.goto(this.parseAssignEqual);
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
parseAssignKeywordPostDot() {
|
|
565
|
-
if (this.char !== CHAR_SP && this.char !== CTRL_I) {
|
|
566
|
-
return this.callNow(this.parseKeyword, this.recordAssignKeyword);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
parseAssignEqual() {
|
|
570
|
-
if (this.char === CHAR_EQUALS) {
|
|
571
|
-
return this.next(this.parseAssignPreValue);
|
|
572
|
-
} else {
|
|
573
|
-
throw this.error(new TomlError('Invalid character, expected "="'));
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
parseAssignPreValue() {
|
|
577
|
-
if (this.char === CHAR_SP || this.char === CTRL_I) {
|
|
578
|
-
return null;
|
|
579
|
-
} else {
|
|
580
|
-
return this.callNow(this.parseValue, this.recordAssignValue);
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
recordAssignValue(value) {
|
|
584
|
-
return this.returnNow({ key: this.state.resultTable, value });
|
|
585
|
-
}
|
|
586
|
-
/* COMMENTS: #...eol */
|
|
587
|
-
parseComment() {
|
|
588
|
-
do {
|
|
589
|
-
if (this.char === Parser.END || this.char === CTRL_J) {
|
|
590
|
-
return this.return();
|
|
591
|
-
}
|
|
592
|
-
} while (this.nextChar());
|
|
593
|
-
}
|
|
594
|
-
/* TABLES AND LISTS, [foo] and [[foo]] */
|
|
595
|
-
parseTableOrList() {
|
|
596
|
-
if (this.char === CHAR_LSQB) {
|
|
597
|
-
this.next(this.parseList);
|
|
598
|
-
} else {
|
|
599
|
-
return this.goto(this.parseTable);
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
/* TABLE [foo.bar.baz] */
|
|
603
|
-
parseTable() {
|
|
604
|
-
this.ctx = this.obj;
|
|
605
|
-
return this.goto(this.parseTableNext);
|
|
606
|
-
}
|
|
607
|
-
parseTableNext() {
|
|
608
|
-
if (this.char === CHAR_SP || this.char === CTRL_I) {
|
|
609
|
-
return null;
|
|
610
|
-
} else {
|
|
611
|
-
return this.callNow(this.parseKeyword, this.parseTableMore);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
parseTableMore(keyword) {
|
|
615
|
-
if (this.char === CHAR_SP || this.char === CTRL_I) {
|
|
616
|
-
return null;
|
|
617
|
-
} else if (this.char === CHAR_RSQB) {
|
|
618
|
-
if (hasKey(this.ctx, keyword) && (!isTable(this.ctx[keyword]) || this.ctx[keyword][_declared])) {
|
|
619
|
-
throw this.error(new TomlError("Can't redefine existing key"));
|
|
620
|
-
} else {
|
|
621
|
-
this.ctx = this.ctx[keyword] = this.ctx[keyword] || Table();
|
|
622
|
-
this.ctx[_declared] = true;
|
|
623
|
-
}
|
|
624
|
-
return this.next(this.parseWhitespaceToEOL);
|
|
625
|
-
} else if (this.char === CHAR_PERIOD) {
|
|
626
|
-
if (!hasKey(this.ctx, keyword)) {
|
|
627
|
-
this.ctx = this.ctx[keyword] = Table();
|
|
628
|
-
} else if (isTable(this.ctx[keyword])) {
|
|
629
|
-
this.ctx = this.ctx[keyword];
|
|
630
|
-
} else if (isList(this.ctx[keyword])) {
|
|
631
|
-
this.ctx = this.ctx[keyword][this.ctx[keyword].length - 1];
|
|
632
|
-
} else {
|
|
633
|
-
throw this.error(new TomlError("Can't redefine existing key"));
|
|
634
|
-
}
|
|
635
|
-
return this.next(this.parseTableNext);
|
|
636
|
-
} else {
|
|
637
|
-
throw this.error(new TomlError("Unexpected character, expected whitespace, . or ]"));
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
/* LIST [[a.b.c]] */
|
|
641
|
-
parseList() {
|
|
642
|
-
this.ctx = this.obj;
|
|
643
|
-
return this.goto(this.parseListNext);
|
|
644
|
-
}
|
|
645
|
-
parseListNext() {
|
|
646
|
-
if (this.char === CHAR_SP || this.char === CTRL_I) {
|
|
647
|
-
return null;
|
|
648
|
-
} else {
|
|
649
|
-
return this.callNow(this.parseKeyword, this.parseListMore);
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
parseListMore(keyword) {
|
|
653
|
-
if (this.char === CHAR_SP || this.char === CTRL_I) {
|
|
654
|
-
return null;
|
|
655
|
-
} else if (this.char === CHAR_RSQB) {
|
|
656
|
-
if (!hasKey(this.ctx, keyword)) {
|
|
657
|
-
this.ctx[keyword] = List();
|
|
658
|
-
}
|
|
659
|
-
if (isInlineList(this.ctx[keyword])) {
|
|
660
|
-
throw this.error(new TomlError("Can't extend an inline array"));
|
|
661
|
-
} else if (isList(this.ctx[keyword])) {
|
|
662
|
-
const next = Table();
|
|
663
|
-
this.ctx[keyword].push(next);
|
|
664
|
-
this.ctx = next;
|
|
665
|
-
} else {
|
|
666
|
-
throw this.error(new TomlError("Can't redefine an existing key"));
|
|
667
|
-
}
|
|
668
|
-
return this.next(this.parseListEnd);
|
|
669
|
-
} else if (this.char === CHAR_PERIOD) {
|
|
670
|
-
if (!hasKey(this.ctx, keyword)) {
|
|
671
|
-
this.ctx = this.ctx[keyword] = Table();
|
|
672
|
-
} else if (isInlineList(this.ctx[keyword])) {
|
|
673
|
-
throw this.error(new TomlError("Can't extend an inline array"));
|
|
674
|
-
} else if (isInlineTable(this.ctx[keyword])) {
|
|
675
|
-
throw this.error(new TomlError("Can't extend an inline table"));
|
|
676
|
-
} else if (isList(this.ctx[keyword])) {
|
|
677
|
-
this.ctx = this.ctx[keyword][this.ctx[keyword].length - 1];
|
|
678
|
-
} else if (isTable(this.ctx[keyword])) {
|
|
679
|
-
this.ctx = this.ctx[keyword];
|
|
680
|
-
} else {
|
|
681
|
-
throw this.error(new TomlError("Can't redefine an existing key"));
|
|
682
|
-
}
|
|
683
|
-
return this.next(this.parseListNext);
|
|
684
|
-
} else {
|
|
685
|
-
throw this.error(new TomlError("Unexpected character, expected whitespace, . or ]"));
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
parseListEnd(keyword) {
|
|
689
|
-
if (this.char === CHAR_RSQB) {
|
|
690
|
-
return this.next(this.parseWhitespaceToEOL);
|
|
691
|
-
} else {
|
|
692
|
-
throw this.error(new TomlError("Unexpected character, expected whitespace, . or ]"));
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
/* VALUE string, number, boolean, inline list, inline object */
|
|
696
|
-
parseValue() {
|
|
697
|
-
if (this.char === Parser.END) {
|
|
698
|
-
throw this.error(new TomlError("Key without value"));
|
|
699
|
-
} else if (this.char === CHAR_QUOT) {
|
|
700
|
-
return this.next(this.parseDoubleString);
|
|
701
|
-
}
|
|
702
|
-
if (this.char === CHAR_APOS) {
|
|
703
|
-
return this.next(this.parseSingleString);
|
|
704
|
-
} else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
|
|
705
|
-
return this.goto(this.parseNumberSign);
|
|
706
|
-
} else if (this.char === CHAR_i) {
|
|
707
|
-
return this.next(this.parseInf);
|
|
708
|
-
} else if (this.char === CHAR_n) {
|
|
709
|
-
return this.next(this.parseNan);
|
|
710
|
-
} else if (isDigit(this.char)) {
|
|
711
|
-
return this.goto(this.parseNumberOrDateTime);
|
|
712
|
-
} else if (this.char === CHAR_t || this.char === CHAR_f) {
|
|
713
|
-
return this.goto(this.parseBoolean);
|
|
714
|
-
} else if (this.char === CHAR_LSQB) {
|
|
715
|
-
return this.call(this.parseInlineList, this.recordValue);
|
|
716
|
-
} else if (this.char === CHAR_LCUB) {
|
|
717
|
-
return this.call(this.parseInlineTable, this.recordValue);
|
|
718
|
-
} else {
|
|
719
|
-
throw this.error(new TomlError("Unexpected character, expecting string, number, datetime, boolean, inline array or inline table"));
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
recordValue(value) {
|
|
723
|
-
return this.returnNow(value);
|
|
724
|
-
}
|
|
725
|
-
parseInf() {
|
|
726
|
-
if (this.char === CHAR_n) {
|
|
727
|
-
return this.next(this.parseInf2);
|
|
728
|
-
} else {
|
|
729
|
-
throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"'));
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
parseInf2() {
|
|
733
|
-
if (this.char === CHAR_f) {
|
|
734
|
-
if (this.state.buf === "-") {
|
|
735
|
-
return this.return(-Infinity);
|
|
736
|
-
} else {
|
|
737
|
-
return this.return(Infinity);
|
|
738
|
-
}
|
|
739
|
-
} else {
|
|
740
|
-
throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"'));
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
parseNan() {
|
|
744
|
-
if (this.char === CHAR_a) {
|
|
745
|
-
return this.next(this.parseNan2);
|
|
746
|
-
} else {
|
|
747
|
-
throw this.error(new TomlError('Unexpected character, expected "nan"'));
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
parseNan2() {
|
|
751
|
-
if (this.char === CHAR_n) {
|
|
752
|
-
return this.return(NaN);
|
|
753
|
-
} else {
|
|
754
|
-
throw this.error(new TomlError('Unexpected character, expected "nan"'));
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
/* KEYS, barewords or basic, literal, or dotted */
|
|
758
|
-
parseKeyword() {
|
|
759
|
-
if (this.char === CHAR_QUOT) {
|
|
760
|
-
return this.next(this.parseBasicString);
|
|
761
|
-
} else if (this.char === CHAR_APOS) {
|
|
762
|
-
return this.next(this.parseLiteralString);
|
|
763
|
-
} else {
|
|
764
|
-
return this.goto(this.parseBareKey);
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
/* KEYS: barewords */
|
|
768
|
-
parseBareKey() {
|
|
769
|
-
do {
|
|
770
|
-
if (this.char === Parser.END) {
|
|
771
|
-
throw this.error(new TomlError("Key ended without value"));
|
|
772
|
-
} else if (isAlphaNumHyphen(this.char)) {
|
|
773
|
-
this.consume();
|
|
774
|
-
} else if (this.state.buf.length === 0) {
|
|
775
|
-
throw this.error(new TomlError("Empty bare keys are not allowed"));
|
|
776
|
-
} else {
|
|
777
|
-
return this.returnNow();
|
|
778
|
-
}
|
|
779
|
-
} while (this.nextChar());
|
|
780
|
-
}
|
|
781
|
-
/* STRINGS, single quoted (literal) */
|
|
782
|
-
parseSingleString() {
|
|
783
|
-
if (this.char === CHAR_APOS) {
|
|
784
|
-
return this.next(this.parseLiteralMultiStringMaybe);
|
|
785
|
-
} else {
|
|
786
|
-
return this.goto(this.parseLiteralString);
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
parseLiteralString() {
|
|
790
|
-
do {
|
|
791
|
-
if (this.char === CHAR_APOS) {
|
|
792
|
-
return this.return();
|
|
793
|
-
} else if (this.atEndOfLine()) {
|
|
794
|
-
throw this.error(new TomlError("Unterminated string"));
|
|
795
|
-
} else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I) {
|
|
796
|
-
throw this.errorControlCharInString();
|
|
797
|
-
} else {
|
|
798
|
-
this.consume();
|
|
799
|
-
}
|
|
800
|
-
} while (this.nextChar());
|
|
801
|
-
}
|
|
802
|
-
parseLiteralMultiStringMaybe() {
|
|
803
|
-
if (this.char === CHAR_APOS) {
|
|
804
|
-
return this.next(this.parseLiteralMultiString);
|
|
805
|
-
} else {
|
|
806
|
-
return this.returnNow();
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
parseLiteralMultiString() {
|
|
810
|
-
if (this.char === CTRL_M) {
|
|
811
|
-
return null;
|
|
812
|
-
} else if (this.char === CTRL_J) {
|
|
813
|
-
return this.next(this.parseLiteralMultiStringContent);
|
|
814
|
-
} else {
|
|
815
|
-
return this.goto(this.parseLiteralMultiStringContent);
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
parseLiteralMultiStringContent() {
|
|
819
|
-
do {
|
|
820
|
-
if (this.char === CHAR_APOS) {
|
|
821
|
-
return this.next(this.parseLiteralMultiEnd);
|
|
822
|
-
} else if (this.char === Parser.END) {
|
|
823
|
-
throw this.error(new TomlError("Unterminated multi-line string"));
|
|
824
|
-
} else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M) {
|
|
825
|
-
throw this.errorControlCharInString();
|
|
826
|
-
} else {
|
|
827
|
-
this.consume();
|
|
828
|
-
}
|
|
829
|
-
} while (this.nextChar());
|
|
830
|
-
}
|
|
831
|
-
parseLiteralMultiEnd() {
|
|
832
|
-
if (this.char === CHAR_APOS) {
|
|
833
|
-
return this.next(this.parseLiteralMultiEnd2);
|
|
834
|
-
} else {
|
|
835
|
-
this.state.buf += "'";
|
|
836
|
-
return this.goto(this.parseLiteralMultiStringContent);
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
parseLiteralMultiEnd2() {
|
|
840
|
-
if (this.char === CHAR_APOS) {
|
|
841
|
-
return this.return();
|
|
842
|
-
} else {
|
|
843
|
-
this.state.buf += "''";
|
|
844
|
-
return this.goto(this.parseLiteralMultiStringContent);
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
/* STRINGS double quoted */
|
|
848
|
-
parseDoubleString() {
|
|
849
|
-
if (this.char === CHAR_QUOT) {
|
|
850
|
-
return this.next(this.parseMultiStringMaybe);
|
|
851
|
-
} else {
|
|
852
|
-
return this.goto(this.parseBasicString);
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
parseBasicString() {
|
|
856
|
-
do {
|
|
857
|
-
if (this.char === CHAR_BSOL) {
|
|
858
|
-
return this.call(this.parseEscape, this.recordEscapeReplacement);
|
|
859
|
-
} else if (this.char === CHAR_QUOT) {
|
|
860
|
-
return this.return();
|
|
861
|
-
} else if (this.atEndOfLine()) {
|
|
862
|
-
throw this.error(new TomlError("Unterminated string"));
|
|
863
|
-
} else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I) {
|
|
864
|
-
throw this.errorControlCharInString();
|
|
865
|
-
} else {
|
|
866
|
-
this.consume();
|
|
867
|
-
}
|
|
868
|
-
} while (this.nextChar());
|
|
869
|
-
}
|
|
870
|
-
recordEscapeReplacement(replacement) {
|
|
871
|
-
this.state.buf += replacement;
|
|
872
|
-
return this.goto(this.parseBasicString);
|
|
873
|
-
}
|
|
874
|
-
parseMultiStringMaybe() {
|
|
875
|
-
if (this.char === CHAR_QUOT) {
|
|
876
|
-
return this.next(this.parseMultiString);
|
|
877
|
-
} else {
|
|
878
|
-
return this.returnNow();
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
parseMultiString() {
|
|
882
|
-
if (this.char === CTRL_M) {
|
|
883
|
-
return null;
|
|
884
|
-
} else if (this.char === CTRL_J) {
|
|
885
|
-
return this.next(this.parseMultiStringContent);
|
|
886
|
-
} else {
|
|
887
|
-
return this.goto(this.parseMultiStringContent);
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
parseMultiStringContent() {
|
|
891
|
-
do {
|
|
892
|
-
if (this.char === CHAR_BSOL) {
|
|
893
|
-
return this.call(this.parseMultiEscape, this.recordMultiEscapeReplacement);
|
|
894
|
-
} else if (this.char === CHAR_QUOT) {
|
|
895
|
-
return this.next(this.parseMultiEnd);
|
|
896
|
-
} else if (this.char === Parser.END) {
|
|
897
|
-
throw this.error(new TomlError("Unterminated multi-line string"));
|
|
898
|
-
} else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M) {
|
|
899
|
-
throw this.errorControlCharInString();
|
|
900
|
-
} else {
|
|
901
|
-
this.consume();
|
|
902
|
-
}
|
|
903
|
-
} while (this.nextChar());
|
|
904
|
-
}
|
|
905
|
-
errorControlCharInString() {
|
|
906
|
-
let displayCode = "\\u00";
|
|
907
|
-
if (this.char < 16) {
|
|
908
|
-
displayCode += "0";
|
|
909
|
-
}
|
|
910
|
-
displayCode += this.char.toString(16);
|
|
911
|
-
return this.error(new TomlError(`Control characters (codes < 0x1f and 0x7f) are not allowed in strings, use ${displayCode} instead`));
|
|
912
|
-
}
|
|
913
|
-
recordMultiEscapeReplacement(replacement) {
|
|
914
|
-
this.state.buf += replacement;
|
|
915
|
-
return this.goto(this.parseMultiStringContent);
|
|
916
|
-
}
|
|
917
|
-
parseMultiEnd() {
|
|
918
|
-
if (this.char === CHAR_QUOT) {
|
|
919
|
-
return this.next(this.parseMultiEnd2);
|
|
920
|
-
} else {
|
|
921
|
-
this.state.buf += '"';
|
|
922
|
-
return this.goto(this.parseMultiStringContent);
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
parseMultiEnd2() {
|
|
926
|
-
if (this.char === CHAR_QUOT) {
|
|
927
|
-
return this.return();
|
|
928
|
-
} else {
|
|
929
|
-
this.state.buf += '""';
|
|
930
|
-
return this.goto(this.parseMultiStringContent);
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
parseMultiEscape() {
|
|
934
|
-
if (this.char === CTRL_M || this.char === CTRL_J) {
|
|
935
|
-
return this.next(this.parseMultiTrim);
|
|
936
|
-
} else if (this.char === CHAR_SP || this.char === CTRL_I) {
|
|
937
|
-
return this.next(this.parsePreMultiTrim);
|
|
938
|
-
} else {
|
|
939
|
-
return this.goto(this.parseEscape);
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
parsePreMultiTrim() {
|
|
943
|
-
if (this.char === CHAR_SP || this.char === CTRL_I) {
|
|
944
|
-
return null;
|
|
945
|
-
} else if (this.char === CTRL_M || this.char === CTRL_J) {
|
|
946
|
-
return this.next(this.parseMultiTrim);
|
|
947
|
-
} else {
|
|
948
|
-
throw this.error(new TomlError("Can't escape whitespace"));
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
parseMultiTrim() {
|
|
952
|
-
if (this.char === CTRL_J || this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) {
|
|
953
|
-
return null;
|
|
954
|
-
} else {
|
|
955
|
-
return this.returnNow();
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
parseEscape() {
|
|
959
|
-
if (this.char in escapes) {
|
|
960
|
-
return this.return(escapes[this.char]);
|
|
961
|
-
} else if (this.char === CHAR_u) {
|
|
962
|
-
return this.call(this.parseSmallUnicode, this.parseUnicodeReturn);
|
|
963
|
-
} else if (this.char === CHAR_U) {
|
|
964
|
-
return this.call(this.parseLargeUnicode, this.parseUnicodeReturn);
|
|
965
|
-
} else {
|
|
966
|
-
throw this.error(new TomlError("Unknown escape character: " + this.char));
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
parseUnicodeReturn(char) {
|
|
970
|
-
try {
|
|
971
|
-
const codePoint = parseInt(char, 16);
|
|
972
|
-
if (codePoint >= SURROGATE_FIRST && codePoint <= SURROGATE_LAST) {
|
|
973
|
-
throw this.error(new TomlError("Invalid unicode, character in range 0xD800 - 0xDFFF is reserved"));
|
|
974
|
-
}
|
|
975
|
-
return this.returnNow(String.fromCodePoint(codePoint));
|
|
976
|
-
} catch (err) {
|
|
977
|
-
throw this.error(TomlError.wrap(err));
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
parseSmallUnicode() {
|
|
981
|
-
if (!isHexit(this.char)) {
|
|
982
|
-
throw this.error(new TomlError("Invalid character in unicode sequence, expected hex"));
|
|
983
|
-
} else {
|
|
984
|
-
this.consume();
|
|
985
|
-
if (this.state.buf.length >= 4) return this.return();
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
parseLargeUnicode() {
|
|
989
|
-
if (!isHexit(this.char)) {
|
|
990
|
-
throw this.error(new TomlError("Invalid character in unicode sequence, expected hex"));
|
|
991
|
-
} else {
|
|
992
|
-
this.consume();
|
|
993
|
-
if (this.state.buf.length >= 8) return this.return();
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
/* NUMBERS */
|
|
997
|
-
parseNumberSign() {
|
|
998
|
-
this.consume();
|
|
999
|
-
return this.next(this.parseMaybeSignedInfOrNan);
|
|
1000
|
-
}
|
|
1001
|
-
parseMaybeSignedInfOrNan() {
|
|
1002
|
-
if (this.char === CHAR_i) {
|
|
1003
|
-
return this.next(this.parseInf);
|
|
1004
|
-
} else if (this.char === CHAR_n) {
|
|
1005
|
-
return this.next(this.parseNan);
|
|
1006
|
-
} else {
|
|
1007
|
-
return this.callNow(this.parseNoUnder, this.parseNumberIntegerStart);
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
parseNumberIntegerStart() {
|
|
1011
|
-
if (this.char === CHAR_0) {
|
|
1012
|
-
this.consume();
|
|
1013
|
-
return this.next(this.parseNumberIntegerExponentOrDecimal);
|
|
1014
|
-
} else {
|
|
1015
|
-
return this.goto(this.parseNumberInteger);
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
parseNumberIntegerExponentOrDecimal() {
|
|
1019
|
-
if (this.char === CHAR_PERIOD) {
|
|
1020
|
-
this.consume();
|
|
1021
|
-
return this.call(this.parseNoUnder, this.parseNumberFloat);
|
|
1022
|
-
} else if (this.char === CHAR_E || this.char === CHAR_e) {
|
|
1023
|
-
this.consume();
|
|
1024
|
-
return this.next(this.parseNumberExponentSign);
|
|
1025
|
-
} else {
|
|
1026
|
-
return this.returnNow(Integer(this.state.buf));
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
parseNumberInteger() {
|
|
1030
|
-
if (isDigit(this.char)) {
|
|
1031
|
-
this.consume();
|
|
1032
|
-
} else if (this.char === CHAR_LOWBAR) {
|
|
1033
|
-
return this.call(this.parseNoUnder);
|
|
1034
|
-
} else if (this.char === CHAR_E || this.char === CHAR_e) {
|
|
1035
|
-
this.consume();
|
|
1036
|
-
return this.next(this.parseNumberExponentSign);
|
|
1037
|
-
} else if (this.char === CHAR_PERIOD) {
|
|
1038
|
-
this.consume();
|
|
1039
|
-
return this.call(this.parseNoUnder, this.parseNumberFloat);
|
|
1040
|
-
} else {
|
|
1041
|
-
const result = Integer(this.state.buf);
|
|
1042
|
-
if (result.isNaN()) {
|
|
1043
|
-
throw this.error(new TomlError("Invalid number"));
|
|
1044
|
-
} else {
|
|
1045
|
-
return this.returnNow(result);
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
parseNoUnder() {
|
|
1050
|
-
if (this.char === CHAR_LOWBAR || this.char === CHAR_PERIOD || this.char === CHAR_E || this.char === CHAR_e) {
|
|
1051
|
-
throw this.error(new TomlError("Unexpected character, expected digit"));
|
|
1052
|
-
} else if (this.atEndOfWord()) {
|
|
1053
|
-
throw this.error(new TomlError("Incomplete number"));
|
|
1054
|
-
}
|
|
1055
|
-
return this.returnNow();
|
|
1056
|
-
}
|
|
1057
|
-
parseNoUnderHexOctBinLiteral() {
|
|
1058
|
-
if (this.char === CHAR_LOWBAR || this.char === CHAR_PERIOD) {
|
|
1059
|
-
throw this.error(new TomlError("Unexpected character, expected digit"));
|
|
1060
|
-
} else if (this.atEndOfWord()) {
|
|
1061
|
-
throw this.error(new TomlError("Incomplete number"));
|
|
1062
|
-
}
|
|
1063
|
-
return this.returnNow();
|
|
1064
|
-
}
|
|
1065
|
-
parseNumberFloat() {
|
|
1066
|
-
if (this.char === CHAR_LOWBAR) {
|
|
1067
|
-
return this.call(this.parseNoUnder, this.parseNumberFloat);
|
|
1068
|
-
} else if (isDigit(this.char)) {
|
|
1069
|
-
this.consume();
|
|
1070
|
-
} else if (this.char === CHAR_E || this.char === CHAR_e) {
|
|
1071
|
-
this.consume();
|
|
1072
|
-
return this.next(this.parseNumberExponentSign);
|
|
1073
|
-
} else {
|
|
1074
|
-
return this.returnNow(Float(this.state.buf));
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
parseNumberExponentSign() {
|
|
1078
|
-
if (isDigit(this.char)) {
|
|
1079
|
-
return this.goto(this.parseNumberExponent);
|
|
1080
|
-
} else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
|
|
1081
|
-
this.consume();
|
|
1082
|
-
this.call(this.parseNoUnder, this.parseNumberExponent);
|
|
1083
|
-
} else {
|
|
1084
|
-
throw this.error(new TomlError("Unexpected character, expected -, + or digit"));
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
parseNumberExponent() {
|
|
1088
|
-
if (isDigit(this.char)) {
|
|
1089
|
-
this.consume();
|
|
1090
|
-
} else if (this.char === CHAR_LOWBAR) {
|
|
1091
|
-
return this.call(this.parseNoUnder);
|
|
1092
|
-
} else {
|
|
1093
|
-
return this.returnNow(Float(this.state.buf));
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
/* NUMBERS or DATETIMES */
|
|
1097
|
-
parseNumberOrDateTime() {
|
|
1098
|
-
if (this.char === CHAR_0) {
|
|
1099
|
-
this.consume();
|
|
1100
|
-
return this.next(this.parseNumberBaseOrDateTime);
|
|
1101
|
-
} else {
|
|
1102
|
-
return this.goto(this.parseNumberOrDateTimeOnly);
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
parseNumberOrDateTimeOnly() {
|
|
1106
|
-
if (this.char === CHAR_LOWBAR) {
|
|
1107
|
-
return this.call(this.parseNoUnder, this.parseNumberInteger);
|
|
1108
|
-
} else if (isDigit(this.char)) {
|
|
1109
|
-
this.consume();
|
|
1110
|
-
if (this.state.buf.length > 4) this.next(this.parseNumberInteger);
|
|
1111
|
-
} else if (this.char === CHAR_E || this.char === CHAR_e) {
|
|
1112
|
-
this.consume();
|
|
1113
|
-
return this.next(this.parseNumberExponentSign);
|
|
1114
|
-
} else if (this.char === CHAR_PERIOD) {
|
|
1115
|
-
this.consume();
|
|
1116
|
-
return this.call(this.parseNoUnder, this.parseNumberFloat);
|
|
1117
|
-
} else if (this.char === CHAR_HYPHEN) {
|
|
1118
|
-
return this.goto(this.parseDateTime);
|
|
1119
|
-
} else if (this.char === CHAR_COLON) {
|
|
1120
|
-
return this.goto(this.parseOnlyTimeHour);
|
|
1121
|
-
} else {
|
|
1122
|
-
return this.returnNow(Integer(this.state.buf));
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
parseDateTimeOnly() {
|
|
1126
|
-
if (this.state.buf.length < 4) {
|
|
1127
|
-
if (isDigit(this.char)) {
|
|
1128
|
-
return this.consume();
|
|
1129
|
-
} else if (this.char === CHAR_COLON) {
|
|
1130
|
-
return this.goto(this.parseOnlyTimeHour);
|
|
1131
|
-
} else {
|
|
1132
|
-
throw this.error(new TomlError("Expected digit while parsing year part of a date"));
|
|
1133
|
-
}
|
|
1134
|
-
} else {
|
|
1135
|
-
if (this.char === CHAR_HYPHEN) {
|
|
1136
|
-
return this.goto(this.parseDateTime);
|
|
1137
|
-
} else {
|
|
1138
|
-
throw this.error(new TomlError("Expected hyphen (-) while parsing year part of date"));
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
parseNumberBaseOrDateTime() {
|
|
1143
|
-
if (this.char === CHAR_b) {
|
|
1144
|
-
this.consume();
|
|
1145
|
-
return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerBin);
|
|
1146
|
-
} else if (this.char === CHAR_o) {
|
|
1147
|
-
this.consume();
|
|
1148
|
-
return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerOct);
|
|
1149
|
-
} else if (this.char === CHAR_x) {
|
|
1150
|
-
this.consume();
|
|
1151
|
-
return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerHex);
|
|
1152
|
-
} else if (this.char === CHAR_PERIOD) {
|
|
1153
|
-
return this.goto(this.parseNumberInteger);
|
|
1154
|
-
} else if (isDigit(this.char)) {
|
|
1155
|
-
return this.goto(this.parseDateTimeOnly);
|
|
1156
|
-
} else {
|
|
1157
|
-
return this.returnNow(Integer(this.state.buf));
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
parseIntegerHex() {
|
|
1161
|
-
if (isHexit(this.char)) {
|
|
1162
|
-
this.consume();
|
|
1163
|
-
} else if (this.char === CHAR_LOWBAR) {
|
|
1164
|
-
return this.call(this.parseNoUnderHexOctBinLiteral);
|
|
1165
|
-
} else {
|
|
1166
|
-
const result = Integer(this.state.buf);
|
|
1167
|
-
if (result.isNaN()) {
|
|
1168
|
-
throw this.error(new TomlError("Invalid number"));
|
|
1169
|
-
} else {
|
|
1170
|
-
return this.returnNow(result);
|
|
1171
|
-
}
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
parseIntegerOct() {
|
|
1175
|
-
if (isOctit(this.char)) {
|
|
1176
|
-
this.consume();
|
|
1177
|
-
} else if (this.char === CHAR_LOWBAR) {
|
|
1178
|
-
return this.call(this.parseNoUnderHexOctBinLiteral);
|
|
1179
|
-
} else {
|
|
1180
|
-
const result = Integer(this.state.buf);
|
|
1181
|
-
if (result.isNaN()) {
|
|
1182
|
-
throw this.error(new TomlError("Invalid number"));
|
|
1183
|
-
} else {
|
|
1184
|
-
return this.returnNow(result);
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
parseIntegerBin() {
|
|
1189
|
-
if (isBit(this.char)) {
|
|
1190
|
-
this.consume();
|
|
1191
|
-
} else if (this.char === CHAR_LOWBAR) {
|
|
1192
|
-
return this.call(this.parseNoUnderHexOctBinLiteral);
|
|
1193
|
-
} else {
|
|
1194
|
-
const result = Integer(this.state.buf);
|
|
1195
|
-
if (result.isNaN()) {
|
|
1196
|
-
throw this.error(new TomlError("Invalid number"));
|
|
1197
|
-
} else {
|
|
1198
|
-
return this.returnNow(result);
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1202
|
-
/* DATETIME */
|
|
1203
|
-
parseDateTime() {
|
|
1204
|
-
if (this.state.buf.length < 4) {
|
|
1205
|
-
throw this.error(new TomlError("Years less than 1000 must be zero padded to four characters"));
|
|
1206
|
-
}
|
|
1207
|
-
this.state.result = this.state.buf;
|
|
1208
|
-
this.state.buf = "";
|
|
1209
|
-
return this.next(this.parseDateMonth);
|
|
1210
|
-
}
|
|
1211
|
-
parseDateMonth() {
|
|
1212
|
-
if (this.char === CHAR_HYPHEN) {
|
|
1213
|
-
if (this.state.buf.length < 2) {
|
|
1214
|
-
throw this.error(new TomlError("Months less than 10 must be zero padded to two characters"));
|
|
1215
|
-
}
|
|
1216
|
-
this.state.result += "-" + this.state.buf;
|
|
1217
|
-
this.state.buf = "";
|
|
1218
|
-
return this.next(this.parseDateDay);
|
|
1219
|
-
} else if (isDigit(this.char)) {
|
|
1220
|
-
this.consume();
|
|
1221
|
-
} else {
|
|
1222
|
-
throw this.error(new TomlError("Incomplete datetime"));
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
parseDateDay() {
|
|
1226
|
-
if (this.char === CHAR_T || this.char === CHAR_SP) {
|
|
1227
|
-
if (this.state.buf.length < 2) {
|
|
1228
|
-
throw this.error(new TomlError("Days less than 10 must be zero padded to two characters"));
|
|
1229
|
-
}
|
|
1230
|
-
this.state.result += "-" + this.state.buf;
|
|
1231
|
-
this.state.buf = "";
|
|
1232
|
-
return this.next(this.parseStartTimeHour);
|
|
1233
|
-
} else if (this.atEndOfWord()) {
|
|
1234
|
-
return this.returnNow(createDate(this.state.result + "-" + this.state.buf));
|
|
1235
|
-
} else if (isDigit(this.char)) {
|
|
1236
|
-
this.consume();
|
|
1237
|
-
} else {
|
|
1238
|
-
throw this.error(new TomlError("Incomplete datetime"));
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
parseStartTimeHour() {
|
|
1242
|
-
if (this.atEndOfWord()) {
|
|
1243
|
-
return this.returnNow(createDate(this.state.result));
|
|
1244
|
-
} else {
|
|
1245
|
-
return this.goto(this.parseTimeHour);
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
parseTimeHour() {
|
|
1249
|
-
if (this.char === CHAR_COLON) {
|
|
1250
|
-
if (this.state.buf.length < 2) {
|
|
1251
|
-
throw this.error(new TomlError("Hours less than 10 must be zero padded to two characters"));
|
|
1252
|
-
}
|
|
1253
|
-
this.state.result += "T" + this.state.buf;
|
|
1254
|
-
this.state.buf = "";
|
|
1255
|
-
return this.next(this.parseTimeMin);
|
|
1256
|
-
} else if (isDigit(this.char)) {
|
|
1257
|
-
this.consume();
|
|
1258
|
-
} else {
|
|
1259
|
-
throw this.error(new TomlError("Incomplete datetime"));
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
parseTimeMin() {
|
|
1263
|
-
if (this.state.buf.length < 2 && isDigit(this.char)) {
|
|
1264
|
-
this.consume();
|
|
1265
|
-
} else if (this.state.buf.length === 2 && this.char === CHAR_COLON) {
|
|
1266
|
-
this.state.result += ":" + this.state.buf;
|
|
1267
|
-
this.state.buf = "";
|
|
1268
|
-
return this.next(this.parseTimeSec);
|
|
1269
|
-
} else {
|
|
1270
|
-
throw this.error(new TomlError("Incomplete datetime"));
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
parseTimeSec() {
|
|
1274
|
-
if (isDigit(this.char)) {
|
|
1275
|
-
this.consume();
|
|
1276
|
-
if (this.state.buf.length === 2) {
|
|
1277
|
-
this.state.result += ":" + this.state.buf;
|
|
1278
|
-
this.state.buf = "";
|
|
1279
|
-
return this.next(this.parseTimeZoneOrFraction);
|
|
1280
|
-
}
|
|
1281
|
-
} else {
|
|
1282
|
-
throw this.error(new TomlError("Incomplete datetime"));
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
parseOnlyTimeHour() {
|
|
1286
|
-
if (this.char === CHAR_COLON) {
|
|
1287
|
-
if (this.state.buf.length < 2) {
|
|
1288
|
-
throw this.error(new TomlError("Hours less than 10 must be zero padded to two characters"));
|
|
1289
|
-
}
|
|
1290
|
-
this.state.result = this.state.buf;
|
|
1291
|
-
this.state.buf = "";
|
|
1292
|
-
return this.next(this.parseOnlyTimeMin);
|
|
1293
|
-
} else {
|
|
1294
|
-
throw this.error(new TomlError("Incomplete time"));
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
parseOnlyTimeMin() {
|
|
1298
|
-
if (this.state.buf.length < 2 && isDigit(this.char)) {
|
|
1299
|
-
this.consume();
|
|
1300
|
-
} else if (this.state.buf.length === 2 && this.char === CHAR_COLON) {
|
|
1301
|
-
this.state.result += ":" + this.state.buf;
|
|
1302
|
-
this.state.buf = "";
|
|
1303
|
-
return this.next(this.parseOnlyTimeSec);
|
|
1304
|
-
} else {
|
|
1305
|
-
throw this.error(new TomlError("Incomplete time"));
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
parseOnlyTimeSec() {
|
|
1309
|
-
if (isDigit(this.char)) {
|
|
1310
|
-
this.consume();
|
|
1311
|
-
if (this.state.buf.length === 2) {
|
|
1312
|
-
return this.next(this.parseOnlyTimeFractionMaybe);
|
|
1313
|
-
}
|
|
1314
|
-
} else {
|
|
1315
|
-
throw this.error(new TomlError("Incomplete time"));
|
|
1316
|
-
}
|
|
1317
|
-
}
|
|
1318
|
-
parseOnlyTimeFractionMaybe() {
|
|
1319
|
-
this.state.result += ":" + this.state.buf;
|
|
1320
|
-
if (this.char === CHAR_PERIOD) {
|
|
1321
|
-
this.state.buf = "";
|
|
1322
|
-
this.next(this.parseOnlyTimeFraction);
|
|
1323
|
-
} else {
|
|
1324
|
-
return this.return(createTime(this.state.result));
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
parseOnlyTimeFraction() {
|
|
1328
|
-
if (isDigit(this.char)) {
|
|
1329
|
-
this.consume();
|
|
1330
|
-
} else if (this.atEndOfWord()) {
|
|
1331
|
-
if (this.state.buf.length === 0) throw this.error(new TomlError("Expected digit in milliseconds"));
|
|
1332
|
-
return this.returnNow(createTime(this.state.result + "." + this.state.buf));
|
|
1333
|
-
} else {
|
|
1334
|
-
throw this.error(new TomlError("Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z"));
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1337
|
-
parseTimeZoneOrFraction() {
|
|
1338
|
-
if (this.char === CHAR_PERIOD) {
|
|
1339
|
-
this.consume();
|
|
1340
|
-
this.next(this.parseDateTimeFraction);
|
|
1341
|
-
} else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
|
|
1342
|
-
this.consume();
|
|
1343
|
-
this.next(this.parseTimeZoneHour);
|
|
1344
|
-
} else if (this.char === CHAR_Z) {
|
|
1345
|
-
this.consume();
|
|
1346
|
-
return this.return(createDateTime(this.state.result + this.state.buf));
|
|
1347
|
-
} else if (this.atEndOfWord()) {
|
|
1348
|
-
return this.returnNow(createDateTimeFloat(this.state.result + this.state.buf));
|
|
1349
|
-
} else {
|
|
1350
|
-
throw this.error(new TomlError("Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z"));
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
parseDateTimeFraction() {
|
|
1354
|
-
if (isDigit(this.char)) {
|
|
1355
|
-
this.consume();
|
|
1356
|
-
} else if (this.state.buf.length === 1) {
|
|
1357
|
-
throw this.error(new TomlError("Expected digit in milliseconds"));
|
|
1358
|
-
} else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
|
|
1359
|
-
this.consume();
|
|
1360
|
-
this.next(this.parseTimeZoneHour);
|
|
1361
|
-
} else if (this.char === CHAR_Z) {
|
|
1362
|
-
this.consume();
|
|
1363
|
-
return this.return(createDateTime(this.state.result + this.state.buf));
|
|
1364
|
-
} else if (this.atEndOfWord()) {
|
|
1365
|
-
return this.returnNow(createDateTimeFloat(this.state.result + this.state.buf));
|
|
1366
|
-
} else {
|
|
1367
|
-
throw this.error(new TomlError("Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z"));
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
parseTimeZoneHour() {
|
|
1371
|
-
if (isDigit(this.char)) {
|
|
1372
|
-
this.consume();
|
|
1373
|
-
if (/\d\d$/.test(this.state.buf)) return this.next(this.parseTimeZoneSep);
|
|
1374
|
-
} else {
|
|
1375
|
-
throw this.error(new TomlError("Unexpected character in datetime, expected digit"));
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
parseTimeZoneSep() {
|
|
1379
|
-
if (this.char === CHAR_COLON) {
|
|
1380
|
-
this.consume();
|
|
1381
|
-
this.next(this.parseTimeZoneMin);
|
|
1382
|
-
} else {
|
|
1383
|
-
throw this.error(new TomlError("Unexpected character in datetime, expected colon"));
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1386
|
-
parseTimeZoneMin() {
|
|
1387
|
-
if (isDigit(this.char)) {
|
|
1388
|
-
this.consume();
|
|
1389
|
-
if (/\d\d$/.test(this.state.buf)) return this.return(createDateTime(this.state.result + this.state.buf));
|
|
1390
|
-
} else {
|
|
1391
|
-
throw this.error(new TomlError("Unexpected character in datetime, expected digit"));
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
/* BOOLEAN */
|
|
1395
|
-
parseBoolean() {
|
|
1396
|
-
if (this.char === CHAR_t) {
|
|
1397
|
-
this.consume();
|
|
1398
|
-
return this.next(this.parseTrue_r);
|
|
1399
|
-
} else if (this.char === CHAR_f) {
|
|
1400
|
-
this.consume();
|
|
1401
|
-
return this.next(this.parseFalse_a);
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
parseTrue_r() {
|
|
1405
|
-
if (this.char === CHAR_r) {
|
|
1406
|
-
this.consume();
|
|
1407
|
-
return this.next(this.parseTrue_u);
|
|
1408
|
-
} else {
|
|
1409
|
-
throw this.error(new TomlError("Invalid boolean, expected true or false"));
|
|
1410
|
-
}
|
|
1411
|
-
}
|
|
1412
|
-
parseTrue_u() {
|
|
1413
|
-
if (this.char === CHAR_u) {
|
|
1414
|
-
this.consume();
|
|
1415
|
-
return this.next(this.parseTrue_e);
|
|
1416
|
-
} else {
|
|
1417
|
-
throw this.error(new TomlError("Invalid boolean, expected true or false"));
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
parseTrue_e() {
|
|
1421
|
-
if (this.char === CHAR_e) {
|
|
1422
|
-
return this.return(true);
|
|
1423
|
-
} else {
|
|
1424
|
-
throw this.error(new TomlError("Invalid boolean, expected true or false"));
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
parseFalse_a() {
|
|
1428
|
-
if (this.char === CHAR_a) {
|
|
1429
|
-
this.consume();
|
|
1430
|
-
return this.next(this.parseFalse_l);
|
|
1431
|
-
} else {
|
|
1432
|
-
throw this.error(new TomlError("Invalid boolean, expected true or false"));
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
parseFalse_l() {
|
|
1436
|
-
if (this.char === CHAR_l) {
|
|
1437
|
-
this.consume();
|
|
1438
|
-
return this.next(this.parseFalse_s);
|
|
1439
|
-
} else {
|
|
1440
|
-
throw this.error(new TomlError("Invalid boolean, expected true or false"));
|
|
1441
|
-
}
|
|
1442
|
-
}
|
|
1443
|
-
parseFalse_s() {
|
|
1444
|
-
if (this.char === CHAR_s) {
|
|
1445
|
-
this.consume();
|
|
1446
|
-
return this.next(this.parseFalse_e);
|
|
1447
|
-
} else {
|
|
1448
|
-
throw this.error(new TomlError("Invalid boolean, expected true or false"));
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
parseFalse_e() {
|
|
1452
|
-
if (this.char === CHAR_e) {
|
|
1453
|
-
return this.return(false);
|
|
1454
|
-
} else {
|
|
1455
|
-
throw this.error(new TomlError("Invalid boolean, expected true or false"));
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
/* INLINE LISTS */
|
|
1459
|
-
parseInlineList() {
|
|
1460
|
-
if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M || this.char === CTRL_J) {
|
|
1461
|
-
return null;
|
|
1462
|
-
} else if (this.char === Parser.END) {
|
|
1463
|
-
throw this.error(new TomlError("Unterminated inline array"));
|
|
1464
|
-
} else if (this.char === CHAR_NUM) {
|
|
1465
|
-
return this.call(this.parseComment);
|
|
1466
|
-
} else if (this.char === CHAR_RSQB) {
|
|
1467
|
-
return this.return(this.state.resultArr || InlineList());
|
|
1468
|
-
} else {
|
|
1469
|
-
return this.callNow(this.parseValue, this.recordInlineListValue);
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
recordInlineListValue(value) {
|
|
1473
|
-
if (this.state.resultArr) {
|
|
1474
|
-
const listType = this.state.resultArr[_contentType];
|
|
1475
|
-
const valueType = tomlType(value);
|
|
1476
|
-
if (listType !== valueType) {
|
|
1477
|
-
throw this.error(new TomlError(`Inline lists must be a single type, not a mix of ${listType} and ${valueType}`));
|
|
1478
|
-
}
|
|
1479
|
-
} else {
|
|
1480
|
-
this.state.resultArr = InlineList(tomlType(value));
|
|
1481
|
-
}
|
|
1482
|
-
if (isFloat(value) || isInteger(value)) {
|
|
1483
|
-
this.state.resultArr.push(value.valueOf());
|
|
1484
|
-
} else {
|
|
1485
|
-
this.state.resultArr.push(value);
|
|
1486
|
-
}
|
|
1487
|
-
return this.goto(this.parseInlineListNext);
|
|
1488
|
-
}
|
|
1489
|
-
parseInlineListNext() {
|
|
1490
|
-
if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M || this.char === CTRL_J) {
|
|
1491
|
-
return null;
|
|
1492
|
-
} else if (this.char === CHAR_NUM) {
|
|
1493
|
-
return this.call(this.parseComment);
|
|
1494
|
-
} else if (this.char === CHAR_COMMA) {
|
|
1495
|
-
return this.next(this.parseInlineList);
|
|
1496
|
-
} else if (this.char === CHAR_RSQB) {
|
|
1497
|
-
return this.goto(this.parseInlineList);
|
|
1498
|
-
} else {
|
|
1499
|
-
throw this.error(new TomlError("Invalid character, expected whitespace, comma (,) or close bracket (])"));
|
|
1500
|
-
}
|
|
1501
|
-
}
|
|
1502
|
-
/* INLINE TABLE */
|
|
1503
|
-
parseInlineTable() {
|
|
1504
|
-
if (this.char === CHAR_SP || this.char === CTRL_I) {
|
|
1505
|
-
return null;
|
|
1506
|
-
} else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) {
|
|
1507
|
-
throw this.error(new TomlError("Unterminated inline array"));
|
|
1508
|
-
} else if (this.char === CHAR_RCUB) {
|
|
1509
|
-
return this.return(this.state.resultTable || InlineTable());
|
|
1510
|
-
} else {
|
|
1511
|
-
if (!this.state.resultTable) this.state.resultTable = InlineTable();
|
|
1512
|
-
return this.callNow(this.parseAssign, this.recordInlineTableValue);
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
|
-
recordInlineTableValue(kv) {
|
|
1516
|
-
let target = this.state.resultTable;
|
|
1517
|
-
let finalKey = kv.key.pop();
|
|
1518
|
-
for (let kw of kv.key) {
|
|
1519
|
-
if (hasKey(target, kw) && (!isTable(target[kw]) || target[kw][_declared])) {
|
|
1520
|
-
throw this.error(new TomlError("Can't redefine existing key"));
|
|
1521
|
-
}
|
|
1522
|
-
target = target[kw] = target[kw] || Table();
|
|
1523
|
-
}
|
|
1524
|
-
if (hasKey(target, finalKey)) {
|
|
1525
|
-
throw this.error(new TomlError("Can't redefine existing key"));
|
|
1526
|
-
}
|
|
1527
|
-
if (isInteger(kv.value) || isFloat(kv.value)) {
|
|
1528
|
-
target[finalKey] = kv.value.valueOf();
|
|
1529
|
-
} else {
|
|
1530
|
-
target[finalKey] = kv.value;
|
|
1531
|
-
}
|
|
1532
|
-
return this.goto(this.parseInlineTableNext);
|
|
1533
|
-
}
|
|
1534
|
-
parseInlineTableNext() {
|
|
1535
|
-
if (this.char === CHAR_SP || this.char === CTRL_I) {
|
|
1536
|
-
return null;
|
|
1537
|
-
} else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) {
|
|
1538
|
-
throw this.error(new TomlError("Unterminated inline array"));
|
|
1539
|
-
} else if (this.char === CHAR_COMMA) {
|
|
1540
|
-
return this.next(this.parseInlineTable);
|
|
1541
|
-
} else if (this.char === CHAR_RCUB) {
|
|
1542
|
-
return this.goto(this.parseInlineTable);
|
|
1543
|
-
} else {
|
|
1544
|
-
throw this.error(new TomlError("Invalid character, expected whitespace, comma (,) or close bracket (])"));
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1548
|
-
return TOMLParser;
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
|
-
});
|
|
1552
|
-
|
|
1553
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-pretty-error.js
|
|
1554
|
-
var require_parse_pretty_error = __commonJS({
|
|
1555
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-pretty-error.js"(exports2, module2) {
|
|
1556
|
-
"use strict";
|
|
1557
|
-
module2.exports = prettyError;
|
|
1558
|
-
function prettyError(err, buf) {
|
|
1559
|
-
if (err.pos == null || err.line == null) return err;
|
|
1560
|
-
let msg = err.message;
|
|
1561
|
-
msg += ` at row ${err.line + 1}, col ${err.col + 1}, pos ${err.pos}:
|
|
1562
|
-
`;
|
|
1563
|
-
if (buf && buf.split) {
|
|
1564
|
-
const lines = buf.split(/\n/);
|
|
1565
|
-
const lineNumWidth = String(Math.min(lines.length, err.line + 3)).length;
|
|
1566
|
-
let linePadding = " ";
|
|
1567
|
-
while (linePadding.length < lineNumWidth) linePadding += " ";
|
|
1568
|
-
for (let ii = Math.max(0, err.line - 1); ii < Math.min(lines.length, err.line + 2); ++ii) {
|
|
1569
|
-
let lineNum = String(ii + 1);
|
|
1570
|
-
if (lineNum.length < lineNumWidth) lineNum = " " + lineNum;
|
|
1571
|
-
if (err.line === ii) {
|
|
1572
|
-
msg += lineNum + "> " + lines[ii] + "\n";
|
|
1573
|
-
msg += linePadding + " ";
|
|
1574
|
-
for (let hh = 0; hh < err.col; ++hh) {
|
|
1575
|
-
msg += " ";
|
|
1576
|
-
}
|
|
1577
|
-
msg += "^\n";
|
|
1578
|
-
} else {
|
|
1579
|
-
msg += lineNum + ": " + lines[ii] + "\n";
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
err.message = msg + "\n";
|
|
1584
|
-
return err;
|
|
1585
|
-
}
|
|
1586
|
-
}
|
|
1587
|
-
});
|
|
1588
|
-
|
|
1589
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-string.js
|
|
1590
|
-
var require_parse_string = __commonJS({
|
|
1591
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-string.js"(exports2, module2) {
|
|
1592
|
-
"use strict";
|
|
1593
|
-
module2.exports = parseString;
|
|
1594
|
-
var TOMLParser = require_toml_parser();
|
|
1595
|
-
var prettyError = require_parse_pretty_error();
|
|
1596
|
-
function parseString(str) {
|
|
1597
|
-
if (global.Buffer && global.Buffer.isBuffer(str)) {
|
|
1598
|
-
str = str.toString("utf8");
|
|
1599
|
-
}
|
|
1600
|
-
const parser = new TOMLParser();
|
|
1601
|
-
try {
|
|
1602
|
-
parser.parse(str);
|
|
1603
|
-
return parser.finish();
|
|
1604
|
-
} catch (err) {
|
|
1605
|
-
throw prettyError(err, str);
|
|
1606
|
-
}
|
|
1607
|
-
}
|
|
1608
|
-
}
|
|
1609
|
-
});
|
|
1610
|
-
|
|
1611
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-async.js
|
|
1612
|
-
var require_parse_async = __commonJS({
|
|
1613
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-async.js"(exports2, module2) {
|
|
1614
|
-
"use strict";
|
|
1615
|
-
module2.exports = parseAsync;
|
|
1616
|
-
var TOMLParser = require_toml_parser();
|
|
1617
|
-
var prettyError = require_parse_pretty_error();
|
|
1618
|
-
function parseAsync(str, opts) {
|
|
1619
|
-
if (!opts) opts = {};
|
|
1620
|
-
const index = 0;
|
|
1621
|
-
const blocksize = opts.blocksize || 40960;
|
|
1622
|
-
const parser = new TOMLParser();
|
|
1623
|
-
return new Promise((resolve4, reject) => {
|
|
1624
|
-
setImmediate(parseAsyncNext, index, blocksize, resolve4, reject);
|
|
1625
|
-
});
|
|
1626
|
-
function parseAsyncNext(index2, blocksize2, resolve4, reject) {
|
|
1627
|
-
if (index2 >= str.length) {
|
|
1628
|
-
try {
|
|
1629
|
-
return resolve4(parser.finish());
|
|
1630
|
-
} catch (err) {
|
|
1631
|
-
return reject(prettyError(err, str));
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
try {
|
|
1635
|
-
parser.parse(str.slice(index2, index2 + blocksize2));
|
|
1636
|
-
setImmediate(parseAsyncNext, index2 + blocksize2, blocksize2, resolve4, reject);
|
|
1637
|
-
} catch (err) {
|
|
1638
|
-
reject(prettyError(err, str));
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
});
|
|
1644
|
-
|
|
1645
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-stream.js
|
|
1646
|
-
var require_parse_stream = __commonJS({
|
|
1647
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-stream.js"(exports2, module2) {
|
|
1648
|
-
"use strict";
|
|
1649
|
-
module2.exports = parseStream;
|
|
1650
|
-
var stream = __require("stream");
|
|
1651
|
-
var TOMLParser = require_toml_parser();
|
|
1652
|
-
function parseStream(stm) {
|
|
1653
|
-
if (stm) {
|
|
1654
|
-
return parseReadable(stm);
|
|
1655
|
-
} else {
|
|
1656
|
-
return parseTransform(stm);
|
|
1657
|
-
}
|
|
1658
|
-
}
|
|
1659
|
-
function parseReadable(stm) {
|
|
1660
|
-
const parser = new TOMLParser();
|
|
1661
|
-
stm.setEncoding("utf8");
|
|
1662
|
-
return new Promise((resolve4, reject) => {
|
|
1663
|
-
let readable;
|
|
1664
|
-
let ended = false;
|
|
1665
|
-
let errored = false;
|
|
1666
|
-
function finish() {
|
|
1667
|
-
ended = true;
|
|
1668
|
-
if (readable) return;
|
|
1669
|
-
try {
|
|
1670
|
-
resolve4(parser.finish());
|
|
1671
|
-
} catch (err) {
|
|
1672
|
-
reject(err);
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
function error(err) {
|
|
1676
|
-
errored = true;
|
|
1677
|
-
reject(err);
|
|
1678
|
-
}
|
|
1679
|
-
stm.once("end", finish);
|
|
1680
|
-
stm.once("error", error);
|
|
1681
|
-
readNext();
|
|
1682
|
-
function readNext() {
|
|
1683
|
-
readable = true;
|
|
1684
|
-
let data;
|
|
1685
|
-
while ((data = stm.read()) !== null) {
|
|
1686
|
-
try {
|
|
1687
|
-
parser.parse(data);
|
|
1688
|
-
} catch (err) {
|
|
1689
|
-
return error(err);
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
readable = false;
|
|
1693
|
-
if (ended) return finish();
|
|
1694
|
-
if (errored) return;
|
|
1695
|
-
stm.once("readable", readNext);
|
|
1696
|
-
}
|
|
1697
|
-
});
|
|
1698
|
-
}
|
|
1699
|
-
function parseTransform() {
|
|
1700
|
-
const parser = new TOMLParser();
|
|
1701
|
-
return new stream.Transform({
|
|
1702
|
-
objectMode: true,
|
|
1703
|
-
transform(chunk, encoding, cb) {
|
|
1704
|
-
try {
|
|
1705
|
-
parser.parse(chunk.toString(encoding));
|
|
1706
|
-
} catch (err) {
|
|
1707
|
-
this.emit("error", err);
|
|
1708
|
-
}
|
|
1709
|
-
cb();
|
|
1710
|
-
},
|
|
1711
|
-
flush(cb) {
|
|
1712
|
-
try {
|
|
1713
|
-
this.push(parser.finish());
|
|
1714
|
-
} catch (err) {
|
|
1715
|
-
this.emit("error", err);
|
|
1716
|
-
}
|
|
1717
|
-
cb();
|
|
1718
|
-
}
|
|
1719
|
-
});
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
|
-
});
|
|
1723
|
-
|
|
1724
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse.js
|
|
1725
|
-
var require_parse = __commonJS({
|
|
1726
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse.js"(exports2, module2) {
|
|
1727
|
-
"use strict";
|
|
1728
|
-
module2.exports = require_parse_string();
|
|
1729
|
-
module2.exports.async = require_parse_async();
|
|
1730
|
-
module2.exports.stream = require_parse_stream();
|
|
1731
|
-
module2.exports.prettyError = require_parse_pretty_error();
|
|
1732
|
-
}
|
|
1733
|
-
});
|
|
1734
|
-
|
|
1735
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/stringify.js
|
|
1736
|
-
var require_stringify = __commonJS({
|
|
1737
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/stringify.js"(exports2, module2) {
|
|
1738
|
-
"use strict";
|
|
1739
|
-
module2.exports = stringify;
|
|
1740
|
-
module2.exports.value = stringifyInline;
|
|
1741
|
-
function stringify(obj) {
|
|
1742
|
-
if (obj === null) throw typeError("null");
|
|
1743
|
-
if (obj === void 0) throw typeError("undefined");
|
|
1744
|
-
if (typeof obj !== "object") throw typeError(typeof obj);
|
|
1745
|
-
if (typeof obj.toJSON === "function") obj = obj.toJSON();
|
|
1746
|
-
if (obj == null) return null;
|
|
1747
|
-
const type = tomlType2(obj);
|
|
1748
|
-
if (type !== "table") throw typeError(type);
|
|
1749
|
-
return stringifyObject("", "", obj);
|
|
1750
|
-
}
|
|
1751
|
-
function typeError(type) {
|
|
1752
|
-
return new Error("Can only stringify objects, not " + type);
|
|
1753
|
-
}
|
|
1754
|
-
function arrayOneTypeError() {
|
|
1755
|
-
return new Error("Array values can't have mixed types");
|
|
1756
|
-
}
|
|
1757
|
-
function getInlineKeys(obj) {
|
|
1758
|
-
return Object.keys(obj).filter((key) => isInline(obj[key]));
|
|
1759
|
-
}
|
|
1760
|
-
function getComplexKeys(obj) {
|
|
1761
|
-
return Object.keys(obj).filter((key) => !isInline(obj[key]));
|
|
1762
|
-
}
|
|
1763
|
-
function toJSON(obj) {
|
|
1764
|
-
let nobj = Array.isArray(obj) ? [] : Object.prototype.hasOwnProperty.call(obj, "__proto__") ? { ["__proto__"]: void 0 } : {};
|
|
1765
|
-
for (let prop of Object.keys(obj)) {
|
|
1766
|
-
if (obj[prop] && typeof obj[prop].toJSON === "function" && !("toISOString" in obj[prop])) {
|
|
1767
|
-
nobj[prop] = obj[prop].toJSON();
|
|
1768
|
-
} else {
|
|
1769
|
-
nobj[prop] = obj[prop];
|
|
1770
|
-
}
|
|
1771
|
-
}
|
|
1772
|
-
return nobj;
|
|
1773
|
-
}
|
|
1774
|
-
function stringifyObject(prefix, indent, obj) {
|
|
1775
|
-
obj = toJSON(obj);
|
|
1776
|
-
var inlineKeys;
|
|
1777
|
-
var complexKeys;
|
|
1778
|
-
inlineKeys = getInlineKeys(obj);
|
|
1779
|
-
complexKeys = getComplexKeys(obj);
|
|
1780
|
-
var result = [];
|
|
1781
|
-
var inlineIndent = indent || "";
|
|
1782
|
-
inlineKeys.forEach((key) => {
|
|
1783
|
-
var type = tomlType2(obj[key]);
|
|
1784
|
-
if (type !== "undefined" && type !== "null") {
|
|
1785
|
-
result.push(inlineIndent + stringifyKey(key) + " = " + stringifyAnyInline(obj[key], true));
|
|
1786
|
-
}
|
|
1787
|
-
});
|
|
1788
|
-
if (result.length > 0) result.push("");
|
|
1789
|
-
var complexIndent = prefix && inlineKeys.length > 0 ? indent + " " : "";
|
|
1790
|
-
complexKeys.forEach((key) => {
|
|
1791
|
-
result.push(stringifyComplex(prefix, complexIndent, key, obj[key]));
|
|
1792
|
-
});
|
|
1793
|
-
return result.join("\n");
|
|
1794
|
-
}
|
|
1795
|
-
function isInline(value) {
|
|
1796
|
-
switch (tomlType2(value)) {
|
|
1797
|
-
case "undefined":
|
|
1798
|
-
case "null":
|
|
1799
|
-
case "integer":
|
|
1800
|
-
case "nan":
|
|
1801
|
-
case "float":
|
|
1802
|
-
case "boolean":
|
|
1803
|
-
case "string":
|
|
1804
|
-
case "datetime":
|
|
1805
|
-
return true;
|
|
1806
|
-
case "array":
|
|
1807
|
-
return value.length === 0 || tomlType2(value[0]) !== "table";
|
|
1808
|
-
case "table":
|
|
1809
|
-
return Object.keys(value).length === 0;
|
|
1810
|
-
/* istanbul ignore next */
|
|
1811
|
-
default:
|
|
1812
|
-
return false;
|
|
1813
|
-
}
|
|
1814
|
-
}
|
|
1815
|
-
function tomlType2(value) {
|
|
1816
|
-
if (value === void 0) {
|
|
1817
|
-
return "undefined";
|
|
1818
|
-
} else if (value === null) {
|
|
1819
|
-
return "null";
|
|
1820
|
-
} else if (typeof value === "bigint" || Number.isInteger(value) && !Object.is(value, -0)) {
|
|
1821
|
-
return "integer";
|
|
1822
|
-
} else if (typeof value === "number") {
|
|
1823
|
-
return "float";
|
|
1824
|
-
} else if (typeof value === "boolean") {
|
|
1825
|
-
return "boolean";
|
|
1826
|
-
} else if (typeof value === "string") {
|
|
1827
|
-
return "string";
|
|
1828
|
-
} else if ("toISOString" in value) {
|
|
1829
|
-
return isNaN(value) ? "undefined" : "datetime";
|
|
1830
|
-
} else if (Array.isArray(value)) {
|
|
1831
|
-
return "array";
|
|
1832
|
-
} else {
|
|
1833
|
-
return "table";
|
|
1834
|
-
}
|
|
1835
|
-
}
|
|
1836
|
-
function stringifyKey(key) {
|
|
1837
|
-
var keyStr = String(key);
|
|
1838
|
-
if (/^[-A-Za-z0-9_]+$/.test(keyStr)) {
|
|
1839
|
-
return keyStr;
|
|
1840
|
-
} else {
|
|
1841
|
-
return stringifyBasicString(keyStr);
|
|
1842
|
-
}
|
|
1843
|
-
}
|
|
1844
|
-
function stringifyBasicString(str) {
|
|
1845
|
-
return '"' + escapeString(str).replace(/"/g, '\\"') + '"';
|
|
1846
|
-
}
|
|
1847
|
-
function stringifyLiteralString(str) {
|
|
1848
|
-
return "'" + str + "'";
|
|
1849
|
-
}
|
|
1850
|
-
function numpad(num, str) {
|
|
1851
|
-
while (str.length < num) str = "0" + str;
|
|
1852
|
-
return str;
|
|
1853
|
-
}
|
|
1854
|
-
function escapeString(str) {
|
|
1855
|
-
return str.replace(/\\/g, "\\\\").replace(/[\b]/g, "\\b").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\f/g, "\\f").replace(/\r/g, "\\r").replace(/([\u0000-\u001f\u007f])/, (c) => "\\u" + numpad(4, c.codePointAt(0).toString(16)));
|
|
1856
|
-
}
|
|
1857
|
-
function stringifyMultilineString(str) {
|
|
1858
|
-
let escaped = str.split(/\n/).map((str2) => {
|
|
1859
|
-
return escapeString(str2).replace(/"(?="")/g, '\\"');
|
|
1860
|
-
}).join("\n");
|
|
1861
|
-
if (escaped.slice(-1) === '"') escaped += "\\\n";
|
|
1862
|
-
return '"""\n' + escaped + '"""';
|
|
1863
|
-
}
|
|
1864
|
-
function stringifyAnyInline(value, multilineOk) {
|
|
1865
|
-
let type = tomlType2(value);
|
|
1866
|
-
if (type === "string") {
|
|
1867
|
-
if (multilineOk && /\n/.test(value)) {
|
|
1868
|
-
type = "string-multiline";
|
|
1869
|
-
} else if (!/[\b\t\n\f\r']/.test(value) && /"/.test(value)) {
|
|
1870
|
-
type = "string-literal";
|
|
1871
|
-
}
|
|
1872
|
-
}
|
|
1873
|
-
return stringifyInline(value, type);
|
|
1874
|
-
}
|
|
1875
|
-
function stringifyInline(value, type) {
|
|
1876
|
-
if (!type) type = tomlType2(value);
|
|
1877
|
-
switch (type) {
|
|
1878
|
-
case "string-multiline":
|
|
1879
|
-
return stringifyMultilineString(value);
|
|
1880
|
-
case "string":
|
|
1881
|
-
return stringifyBasicString(value);
|
|
1882
|
-
case "string-literal":
|
|
1883
|
-
return stringifyLiteralString(value);
|
|
1884
|
-
case "integer":
|
|
1885
|
-
return stringifyInteger(value);
|
|
1886
|
-
case "float":
|
|
1887
|
-
return stringifyFloat(value);
|
|
1888
|
-
case "boolean":
|
|
1889
|
-
return stringifyBoolean(value);
|
|
1890
|
-
case "datetime":
|
|
1891
|
-
return stringifyDatetime(value);
|
|
1892
|
-
case "array":
|
|
1893
|
-
return stringifyInlineArray(value.filter((_) => tomlType2(_) !== "null" && tomlType2(_) !== "undefined" && tomlType2(_) !== "nan"));
|
|
1894
|
-
case "table":
|
|
1895
|
-
return stringifyInlineTable(value);
|
|
1896
|
-
/* istanbul ignore next */
|
|
1897
|
-
default:
|
|
1898
|
-
throw typeError(type);
|
|
1899
|
-
}
|
|
1900
|
-
}
|
|
1901
|
-
function stringifyInteger(value) {
|
|
1902
|
-
return String(value).replace(/\B(?=(\d{3})+(?!\d))/g, "_");
|
|
1903
|
-
}
|
|
1904
|
-
function stringifyFloat(value) {
|
|
1905
|
-
if (value === Infinity) {
|
|
1906
|
-
return "inf";
|
|
1907
|
-
} else if (value === -Infinity) {
|
|
1908
|
-
return "-inf";
|
|
1909
|
-
} else if (Object.is(value, NaN)) {
|
|
1910
|
-
return "nan";
|
|
1911
|
-
} else if (Object.is(value, -0)) {
|
|
1912
|
-
return "-0.0";
|
|
1913
|
-
}
|
|
1914
|
-
var chunks = String(value).split(".");
|
|
1915
|
-
var int = chunks[0];
|
|
1916
|
-
var dec = chunks[1] || 0;
|
|
1917
|
-
return stringifyInteger(int) + "." + dec;
|
|
1918
|
-
}
|
|
1919
|
-
function stringifyBoolean(value) {
|
|
1920
|
-
return String(value);
|
|
1921
|
-
}
|
|
1922
|
-
function stringifyDatetime(value) {
|
|
1923
|
-
return value.toISOString();
|
|
1924
|
-
}
|
|
1925
|
-
function isNumber(type) {
|
|
1926
|
-
return type === "float" || type === "integer";
|
|
1927
|
-
}
|
|
1928
|
-
function arrayType(values) {
|
|
1929
|
-
var contentType = tomlType2(values[0]);
|
|
1930
|
-
if (values.every((_) => tomlType2(_) === contentType)) return contentType;
|
|
1931
|
-
if (values.every((_) => isNumber(tomlType2(_)))) return "float";
|
|
1932
|
-
return "mixed";
|
|
1933
|
-
}
|
|
1934
|
-
function validateArray(values) {
|
|
1935
|
-
const type = arrayType(values);
|
|
1936
|
-
if (type === "mixed") {
|
|
1937
|
-
throw arrayOneTypeError();
|
|
1938
|
-
}
|
|
1939
|
-
return type;
|
|
1940
|
-
}
|
|
1941
|
-
function stringifyInlineArray(values) {
|
|
1942
|
-
values = toJSON(values);
|
|
1943
|
-
const type = validateArray(values);
|
|
1944
|
-
var result = "[";
|
|
1945
|
-
var stringified = values.map((_) => stringifyInline(_, type));
|
|
1946
|
-
if (stringified.join(", ").length > 60 || /\n/.test(stringified)) {
|
|
1947
|
-
result += "\n " + stringified.join(",\n ") + "\n";
|
|
1948
|
-
} else {
|
|
1949
|
-
result += " " + stringified.join(", ") + (stringified.length > 0 ? " " : "");
|
|
1950
|
-
}
|
|
1951
|
-
return result + "]";
|
|
1952
|
-
}
|
|
1953
|
-
function stringifyInlineTable(value) {
|
|
1954
|
-
value = toJSON(value);
|
|
1955
|
-
var result = [];
|
|
1956
|
-
Object.keys(value).forEach((key) => {
|
|
1957
|
-
result.push(stringifyKey(key) + " = " + stringifyAnyInline(value[key], false));
|
|
1958
|
-
});
|
|
1959
|
-
return "{ " + result.join(", ") + (result.length > 0 ? " " : "") + "}";
|
|
1960
|
-
}
|
|
1961
|
-
function stringifyComplex(prefix, indent, key, value) {
|
|
1962
|
-
var valueType = tomlType2(value);
|
|
1963
|
-
if (valueType === "array") {
|
|
1964
|
-
return stringifyArrayOfTables(prefix, indent, key, value);
|
|
1965
|
-
} else if (valueType === "table") {
|
|
1966
|
-
return stringifyComplexTable(prefix, indent, key, value);
|
|
1967
|
-
} else {
|
|
1968
|
-
throw typeError(valueType);
|
|
1969
|
-
}
|
|
1970
|
-
}
|
|
1971
|
-
function stringifyArrayOfTables(prefix, indent, key, values) {
|
|
1972
|
-
values = toJSON(values);
|
|
1973
|
-
validateArray(values);
|
|
1974
|
-
var firstValueType = tomlType2(values[0]);
|
|
1975
|
-
if (firstValueType !== "table") throw typeError(firstValueType);
|
|
1976
|
-
var fullKey = prefix + stringifyKey(key);
|
|
1977
|
-
var result = "";
|
|
1978
|
-
values.forEach((table) => {
|
|
1979
|
-
if (result.length > 0) result += "\n";
|
|
1980
|
-
result += indent + "[[" + fullKey + "]]\n";
|
|
1981
|
-
result += stringifyObject(fullKey + ".", indent, table);
|
|
1982
|
-
});
|
|
1983
|
-
return result;
|
|
1984
|
-
}
|
|
1985
|
-
function stringifyComplexTable(prefix, indent, key, value) {
|
|
1986
|
-
var fullKey = prefix + stringifyKey(key);
|
|
1987
|
-
var result = "";
|
|
1988
|
-
if (getInlineKeys(value).length > 0) {
|
|
1989
|
-
result += indent + "[" + fullKey + "]\n";
|
|
1990
|
-
}
|
|
1991
|
-
return result + stringifyObject(fullKey + ".", indent, value);
|
|
1992
|
-
}
|
|
1993
|
-
}
|
|
1994
|
-
});
|
|
1995
|
-
|
|
1996
|
-
// node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/toml.js
|
|
1997
|
-
var require_toml = __commonJS({
|
|
1998
|
-
"node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/toml.js"(exports2) {
|
|
1999
|
-
"use strict";
|
|
2000
|
-
exports2.parse = require_parse();
|
|
2001
|
-
exports2.stringify = require_stringify();
|
|
2002
|
-
}
|
|
2003
|
-
});
|
|
2004
|
-
|
|
2005
|
-
// packages/runtime/src/llm-client.ts
|
|
2006
|
-
var LLMClient = class {
|
|
2007
|
-
baseUrl;
|
|
2008
|
-
model;
|
|
2009
|
-
maxTokens;
|
|
2010
|
-
temperature;
|
|
2011
|
-
apiKey;
|
|
2012
|
-
constructor(config) {
|
|
2013
|
-
this.baseUrl = config.base_url;
|
|
2014
|
-
this.model = config.model;
|
|
2015
|
-
this.maxTokens = config.max_tokens;
|
|
2016
|
-
this.temperature = config.temperature;
|
|
2017
|
-
this.apiKey = config.api_key ?? "";
|
|
2018
|
-
}
|
|
2019
|
-
async chat(messages) {
|
|
2020
|
-
const resp = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
2021
|
-
method: "POST",
|
|
2022
|
-
headers: {
|
|
2023
|
-
"Content-Type": "application/json",
|
|
2024
|
-
...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
|
|
2025
|
-
},
|
|
2026
|
-
body: JSON.stringify({
|
|
2027
|
-
model: this.model,
|
|
2028
|
-
messages,
|
|
2029
|
-
max_tokens: this.maxTokens,
|
|
2030
|
-
temperature: this.temperature
|
|
2031
|
-
})
|
|
2032
|
-
});
|
|
2033
|
-
if (!resp.ok) {
|
|
2034
|
-
const body = await resp.text();
|
|
2035
|
-
throw new Error(`LLM request failed: ${resp.status} ${body}`);
|
|
2036
|
-
}
|
|
2037
|
-
const data = await resp.json();
|
|
2038
|
-
return {
|
|
2039
|
-
content: data.choices[0].message.content,
|
|
2040
|
-
model: data.model,
|
|
2041
|
-
usage: data.usage
|
|
2042
|
-
};
|
|
2043
|
-
}
|
|
2044
|
-
};
|
|
2045
|
-
|
|
2046
|
-
// packages/runtime/src/memory-client.ts
|
|
2047
|
-
var MemoryClient = class {
|
|
2048
|
-
baseUrl;
|
|
2049
|
-
topK;
|
|
2050
|
-
constructor(config) {
|
|
2051
|
-
this.baseUrl = config.daemon_url;
|
|
2052
|
-
this.topK = config.top_k;
|
|
2053
|
-
}
|
|
2054
|
-
async storeEpisode(input) {
|
|
2055
|
-
const resp = await fetch(`${this.baseUrl}/episodes`, {
|
|
2056
|
-
method: "POST",
|
|
2057
|
-
headers: { "Content-Type": "application/json" },
|
|
2058
|
-
body: JSON.stringify(input)
|
|
2059
|
-
});
|
|
2060
|
-
if (!resp.ok) {
|
|
2061
|
-
throw new Error(`Memory store failed: ${resp.status} ${await resp.text()}`);
|
|
2062
|
-
}
|
|
2063
|
-
return resp.json();
|
|
2064
|
-
}
|
|
2065
|
-
async search(query, context, limit) {
|
|
2066
|
-
const params = new URLSearchParams({ q: query });
|
|
2067
|
-
if (context) params.set("context", context);
|
|
2068
|
-
params.set("limit", String(limit ?? this.topK));
|
|
2069
|
-
const resp = await fetch(`${this.baseUrl}/search?${params}`);
|
|
2070
|
-
if (!resp.ok) {
|
|
2071
|
-
throw new Error(`Memory search failed: ${resp.status} ${await resp.text()}`);
|
|
2072
|
-
}
|
|
2073
|
-
const data = await resp.json();
|
|
2074
|
-
return data.episodes;
|
|
2075
|
-
}
|
|
2076
|
-
async getContext(name) {
|
|
2077
|
-
const resp = await fetch(`${this.baseUrl}/contexts/${encodeURIComponent(name)}`);
|
|
2078
|
-
if (!resp.ok) {
|
|
2079
|
-
throw new Error(`Get context failed: ${resp.status} ${await resp.text()}`);
|
|
2080
|
-
}
|
|
2081
|
-
return resp.json();
|
|
2082
|
-
}
|
|
2083
|
-
async createContext(name, description = "") {
|
|
2084
|
-
const resp = await fetch(`${this.baseUrl}/contexts`, {
|
|
2085
|
-
method: "POST",
|
|
2086
|
-
headers: { "Content-Type": "application/json" },
|
|
2087
|
-
body: JSON.stringify({ name, description })
|
|
2088
|
-
});
|
|
2089
|
-
if (!resp.ok) {
|
|
2090
|
-
throw new Error(`Create context failed: ${resp.status} ${await resp.text()}`);
|
|
2091
|
-
}
|
|
2092
|
-
}
|
|
2093
|
-
async deleteContext(name) {
|
|
2094
|
-
const resp = await fetch(`${this.baseUrl}/contexts/${encodeURIComponent(name)}`, {
|
|
2095
|
-
method: "DELETE"
|
|
2096
|
-
});
|
|
2097
|
-
if (!resp.ok) {
|
|
2098
|
-
throw new Error(`Delete context failed: ${resp.status} ${await resp.text()}`);
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
async listContexts() {
|
|
2102
|
-
const resp = await fetch(`${this.baseUrl}/contexts`);
|
|
2103
|
-
if (!resp.ok) {
|
|
2104
|
-
throw new Error(`List contexts failed: ${resp.status} ${await resp.text()}`);
|
|
2105
|
-
}
|
|
2106
|
-
const data = await resp.json();
|
|
2107
|
-
return data.contexts;
|
|
2108
|
-
}
|
|
2109
|
-
async searchCrossContext(query, limit) {
|
|
2110
|
-
const params = new URLSearchParams({ q: query });
|
|
2111
|
-
params.set("limit", String(limit ?? this.topK));
|
|
2112
|
-
const resp = await fetch(`${this.baseUrl}/search/cross-context?${params}`);
|
|
2113
|
-
if (!resp.ok) {
|
|
2114
|
-
throw new Error(`Cross-context search failed: ${resp.status} ${await resp.text()}`);
|
|
2115
|
-
}
|
|
2116
|
-
const data = await resp.json();
|
|
2117
|
-
return data.results;
|
|
2118
|
-
}
|
|
2119
|
-
async shareEpisode(episodeId, targetContext) {
|
|
2120
|
-
const resp = await fetch(`${this.baseUrl}/episodes/${encodeURIComponent(episodeId)}/share`, {
|
|
2121
|
-
method: "POST",
|
|
2122
|
-
headers: { "Content-Type": "application/json" },
|
|
2123
|
-
body: JSON.stringify({ target_context: targetContext })
|
|
2124
|
-
});
|
|
2125
|
-
if (!resp.ok) {
|
|
2126
|
-
throw new Error(`Share episode failed: ${resp.status} ${await resp.text()}`);
|
|
2127
|
-
}
|
|
2128
|
-
}
|
|
2129
|
-
async runPromotion(contextName) {
|
|
2130
|
-
const params = new URLSearchParams();
|
|
2131
|
-
if (contextName) params.set("context", contextName);
|
|
2132
|
-
const resp = await fetch(`${this.baseUrl}/promotion/run?${params}`, {
|
|
2133
|
-
method: "POST"
|
|
2134
|
-
});
|
|
2135
|
-
if (!resp.ok) {
|
|
2136
|
-
throw new Error(`Promotion failed: ${resp.status} ${await resp.text()}`);
|
|
2137
|
-
}
|
|
2138
|
-
return resp.json();
|
|
2139
|
-
}
|
|
2140
|
-
async getL3Knowledge(contextName) {
|
|
2141
|
-
const resp = await fetch(
|
|
2142
|
-
`${this.baseUrl}/promotion/l3?context=${encodeURIComponent(contextName)}`
|
|
2143
|
-
);
|
|
2144
|
-
if (!resp.ok) {
|
|
2145
|
-
throw new Error(`Get L3 failed: ${resp.status} ${await resp.text()}`);
|
|
2146
|
-
}
|
|
2147
|
-
const data = await resp.json();
|
|
2148
|
-
return data.entries;
|
|
2149
|
-
}
|
|
2150
|
-
async setContextScoring(contextName, halfLifeHours) {
|
|
2151
|
-
const resp = await fetch(
|
|
2152
|
-
`${this.baseUrl}/contexts/${encodeURIComponent(contextName)}/scoring`,
|
|
2153
|
-
{
|
|
2154
|
-
method: "POST",
|
|
2155
|
-
headers: { "Content-Type": "application/json" },
|
|
2156
|
-
body: JSON.stringify({ half_life_hours: halfLifeHours })
|
|
2157
|
-
}
|
|
2158
|
-
);
|
|
2159
|
-
if (!resp.ok) {
|
|
2160
|
-
throw new Error(`Set scoring failed: ${resp.status} ${await resp.text()}`);
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
|
-
async recordAccess(episodeId) {
|
|
2164
|
-
const resp = await fetch(`${this.baseUrl}/episodes/${encodeURIComponent(episodeId)}/access`, {
|
|
2165
|
-
method: "POST"
|
|
2166
|
-
});
|
|
2167
|
-
if (!resp.ok) {
|
|
2168
|
-
throw new Error(`Record access failed: ${resp.status} ${await resp.text()}`);
|
|
2169
|
-
}
|
|
2170
|
-
}
|
|
2171
|
-
async recordCoAccess(episodeIds) {
|
|
2172
|
-
const resp = await fetch(`${this.baseUrl}/episodes/co-access`, {
|
|
2173
|
-
method: "POST",
|
|
2174
|
-
headers: { "Content-Type": "application/json" },
|
|
2175
|
-
body: JSON.stringify({ episode_ids: episodeIds })
|
|
2176
|
-
});
|
|
2177
|
-
if (!resp.ok) {
|
|
2178
|
-
throw new Error(`Co-access failed: ${resp.status} ${await resp.text()}`);
|
|
2179
|
-
}
|
|
2180
|
-
}
|
|
2181
|
-
// Task engine methods
|
|
2182
|
-
async createTask(input) {
|
|
2183
|
-
const resp = await fetch(`${this.baseUrl}/tasks`, {
|
|
2184
|
-
method: "POST",
|
|
2185
|
-
headers: { "Content-Type": "application/json" },
|
|
2186
|
-
body: JSON.stringify(input)
|
|
2187
|
-
});
|
|
2188
|
-
if (!resp.ok) {
|
|
2189
|
-
throw new Error(`Create task failed: ${resp.status} ${await resp.text()}`);
|
|
2190
|
-
}
|
|
2191
|
-
return resp.json();
|
|
2192
|
-
}
|
|
2193
|
-
async listTasks(contextName, status) {
|
|
2194
|
-
const params = new URLSearchParams({ context: contextName });
|
|
2195
|
-
if (status) params.set("status", status);
|
|
2196
|
-
const resp = await fetch(`${this.baseUrl}/tasks?${params}`);
|
|
2197
|
-
if (!resp.ok) {
|
|
2198
|
-
throw new Error(`List tasks failed: ${resp.status} ${await resp.text()}`);
|
|
2199
|
-
}
|
|
2200
|
-
const data = await resp.json();
|
|
2201
|
-
return data.tasks;
|
|
2202
|
-
}
|
|
2203
|
-
async updateTask(taskId, updates) {
|
|
2204
|
-
const resp = await fetch(`${this.baseUrl}/tasks/${encodeURIComponent(taskId)}`, {
|
|
2205
|
-
method: "PATCH",
|
|
2206
|
-
headers: { "Content-Type": "application/json" },
|
|
2207
|
-
body: JSON.stringify(updates)
|
|
2208
|
-
});
|
|
2209
|
-
if (!resp.ok) {
|
|
2210
|
-
throw new Error(`Update task failed: ${resp.status} ${await resp.text()}`);
|
|
2211
|
-
}
|
|
2212
|
-
return resp.json();
|
|
2213
|
-
}
|
|
2214
|
-
async getNextTask(contextName) {
|
|
2215
|
-
const resp = await fetch(`${this.baseUrl}/tasks/next?context=${encodeURIComponent(contextName)}`);
|
|
2216
|
-
if (!resp.ok) {
|
|
2217
|
-
if (resp.status === 404) return null;
|
|
2218
|
-
throw new Error(`Get next task failed: ${resp.status} ${await resp.text()}`);
|
|
2219
|
-
}
|
|
2220
|
-
return resp.json();
|
|
2221
|
-
}
|
|
2222
|
-
async healthCheck() {
|
|
2223
|
-
try {
|
|
2224
|
-
const resp = await fetch(`${this.baseUrl}/health`);
|
|
2225
|
-
return resp.ok;
|
|
2226
|
-
} catch {
|
|
2227
|
-
return false;
|
|
2228
|
-
}
|
|
2229
|
-
}
|
|
2230
|
-
};
|
|
2231
|
-
|
|
2232
|
-
// packages/runtime/src/context.ts
|
|
2233
|
-
var SWITCH_PATTERNS = [
|
|
2234
|
-
/^switch\s+to\s+(\S+)/i,
|
|
2235
|
-
/^context:\s*(\S+)/i,
|
|
2236
|
-
/^@(\S+)\s/,
|
|
2237
|
-
/^working\s+on\s+(\S+)/i
|
|
2238
|
-
];
|
|
2239
|
-
var ContextManager = class {
|
|
2240
|
-
contexts = /* @__PURE__ */ new Map();
|
|
2241
|
-
activeContext = "global";
|
|
2242
|
-
memory;
|
|
2243
|
-
constructor(memory) {
|
|
2244
|
-
this.memory = memory;
|
|
2245
|
-
this.contexts.set("global", {
|
|
2246
|
-
name: "global",
|
|
2247
|
-
description: "Global context \u2014 identity, preferences, cross-cutting knowledge",
|
|
2248
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2249
|
-
last_active: (/* @__PURE__ */ new Date()).toISOString()
|
|
2250
|
-
});
|
|
2251
|
-
}
|
|
2252
|
-
async createContext(name, description = "") {
|
|
2253
|
-
if (this.contexts.has(name)) {
|
|
2254
|
-
return this.contexts.get(name);
|
|
2255
|
-
}
|
|
2256
|
-
const metadata = {
|
|
2257
|
-
name,
|
|
2258
|
-
description,
|
|
2259
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2260
|
-
last_active: (/* @__PURE__ */ new Date()).toISOString()
|
|
2261
|
-
};
|
|
2262
|
-
this.contexts.set(name, metadata);
|
|
2263
|
-
try {
|
|
2264
|
-
await this.memory.createContext(name, description);
|
|
2265
|
-
} catch (err) {
|
|
2266
|
-
console.error(`Failed to register context '${name}' with daemon:`, err.message);
|
|
2267
|
-
}
|
|
2268
|
-
return metadata;
|
|
2269
|
-
}
|
|
2270
|
-
async deleteContext(name) {
|
|
2271
|
-
if (name === "global") {
|
|
2272
|
-
console.error("Cannot delete global context");
|
|
2273
|
-
return false;
|
|
2274
|
-
}
|
|
2275
|
-
if (!this.contexts.has(name)) {
|
|
2276
|
-
return false;
|
|
2277
|
-
}
|
|
2278
|
-
this.contexts.delete(name);
|
|
2279
|
-
if (this.activeContext === name) {
|
|
2280
|
-
this.activeContext = "global";
|
|
2281
|
-
}
|
|
2282
|
-
try {
|
|
2283
|
-
await this.memory.deleteContext(name);
|
|
2284
|
-
} catch (err) {
|
|
2285
|
-
console.error(`Failed to delete context '${name}' from daemon:`, err.message);
|
|
2286
|
-
}
|
|
2287
|
-
return true;
|
|
2288
|
-
}
|
|
2289
|
-
listContexts() {
|
|
2290
|
-
return Array.from(this.contexts.values());
|
|
2291
|
-
}
|
|
2292
|
-
getContext(name) {
|
|
2293
|
-
return this.contexts.get(name);
|
|
2294
|
-
}
|
|
2295
|
-
getActiveContext() {
|
|
2296
|
-
return this.activeContext;
|
|
2297
|
-
}
|
|
2298
|
-
switchContext(name) {
|
|
2299
|
-
const previousContext = this.activeContext;
|
|
2300
|
-
const isNew = !this.contexts.has(name);
|
|
2301
|
-
if (isNew) {
|
|
2302
|
-
this.contexts.set(name, {
|
|
2303
|
-
name,
|
|
2304
|
-
description: "",
|
|
2305
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2306
|
-
last_active: (/* @__PURE__ */ new Date()).toISOString()
|
|
2307
|
-
});
|
|
2308
|
-
}
|
|
2309
|
-
this.activeContext = name;
|
|
2310
|
-
this.touchContext(name);
|
|
2311
|
-
return { previousContext, activeContext: name, isNew };
|
|
2312
|
-
}
|
|
2313
|
-
/**
|
|
2314
|
-
* Parse a message and determine if it's a context switch command.
|
|
2315
|
-
* Returns the context name if a switch is detected, null otherwise.
|
|
2316
|
-
*/
|
|
2317
|
-
parseContextSwitch(message) {
|
|
2318
|
-
for (const pattern of SWITCH_PATTERNS) {
|
|
2319
|
-
const match = message.match(pattern);
|
|
2320
|
-
if (match) {
|
|
2321
|
-
return match[1].toLowerCase();
|
|
2322
|
-
}
|
|
2323
|
-
}
|
|
2324
|
-
return null;
|
|
2325
|
-
}
|
|
2326
|
-
/**
|
|
2327
|
-
* Infer context from message content by checking known context names.
|
|
2328
|
-
* Returns the best matching context or current active context.
|
|
2329
|
-
*/
|
|
2330
|
-
inferContext(message) {
|
|
2331
|
-
const lower = message.toLowerCase();
|
|
2332
|
-
for (const [name] of this.contexts) {
|
|
2333
|
-
if (name === "global") continue;
|
|
2334
|
-
if (lower.includes(name.toLowerCase())) {
|
|
2335
|
-
return name;
|
|
2336
|
-
}
|
|
2337
|
-
}
|
|
2338
|
-
return this.activeContext;
|
|
2339
|
-
}
|
|
2340
|
-
/**
|
|
2341
|
-
* Route a message: check for explicit switch, then infer context.
|
|
2342
|
-
* Returns the resolved context name and whether a switch happened.
|
|
2343
|
-
*/
|
|
2344
|
-
routeMessage(message) {
|
|
2345
|
-
const switchTarget = this.parseContextSwitch(message);
|
|
2346
|
-
if (switchTarget) {
|
|
2347
|
-
const result = this.switchContext(switchTarget);
|
|
2348
|
-
return { context: switchTarget, switched: true, switchedTo: result.activeContext };
|
|
2349
|
-
}
|
|
2350
|
-
const inferred = this.inferContext(message);
|
|
2351
|
-
if (inferred !== this.activeContext) {
|
|
2352
|
-
this.touchContext(inferred);
|
|
2353
|
-
return { context: inferred, switched: false };
|
|
2354
|
-
}
|
|
2355
|
-
this.touchContext(this.activeContext);
|
|
2356
|
-
return { context: this.activeContext, switched: false };
|
|
2357
|
-
}
|
|
2358
|
-
/**
|
|
2359
|
-
* Returns contexts that should be searched: active context + global.
|
|
2360
|
-
*/
|
|
2361
|
-
getSearchContexts() {
|
|
2362
|
-
const contexts = [this.activeContext];
|
|
2363
|
-
if (this.activeContext !== "global") {
|
|
2364
|
-
contexts.push("global");
|
|
2365
|
-
}
|
|
2366
|
-
return contexts;
|
|
2367
|
-
}
|
|
2368
|
-
hasContext(name) {
|
|
2369
|
-
return this.contexts.has(name);
|
|
2370
|
-
}
|
|
2371
|
-
touchContext(name) {
|
|
2372
|
-
const ctx = this.contexts.get(name);
|
|
2373
|
-
if (ctx) {
|
|
2374
|
-
ctx.last_active = (/* @__PURE__ */ new Date()).toISOString();
|
|
2375
|
-
}
|
|
2376
|
-
}
|
|
2377
|
-
};
|
|
2378
|
-
|
|
2379
|
-
// packages/runtime/src/task-engine.ts
|
|
2380
|
-
var TaskEngine = class {
|
|
2381
|
-
contextName;
|
|
2382
|
-
memory;
|
|
2383
|
-
constructor(options) {
|
|
2384
|
-
this.contextName = options.contextName;
|
|
2385
|
-
this.memory = options.memory;
|
|
2386
|
-
}
|
|
2387
|
-
async addTask(title, description, blockedBy = []) {
|
|
2388
|
-
return this.memory.createTask({
|
|
2389
|
-
context_name: this.contextName,
|
|
2390
|
-
title,
|
|
2391
|
-
description,
|
|
2392
|
-
status: "planned",
|
|
2393
|
-
blocked_by: blockedBy
|
|
2394
|
-
});
|
|
2395
|
-
}
|
|
2396
|
-
async listTasks(status) {
|
|
2397
|
-
return this.memory.listTasks(this.contextName, status);
|
|
2398
|
-
}
|
|
2399
|
-
async startTask(taskId) {
|
|
2400
|
-
return this.memory.updateTask(taskId, { status: "active" });
|
|
2401
|
-
}
|
|
2402
|
-
async completeTask(taskId) {
|
|
2403
|
-
return this.memory.updateTask(taskId, { status: "complete" });
|
|
2404
|
-
}
|
|
2405
|
-
async archiveTask(taskId) {
|
|
2406
|
-
return this.memory.updateTask(taskId, { status: "archived" });
|
|
2407
|
-
}
|
|
2408
|
-
async getNextTask() {
|
|
2409
|
-
return this.memory.getNextTask(this.contextName);
|
|
2410
|
-
}
|
|
2411
|
-
async pickAndStartNextTask() {
|
|
2412
|
-
const next = await this.getNextTask();
|
|
2413
|
-
if (next) {
|
|
2414
|
-
return this.startTask(next.id);
|
|
2415
|
-
}
|
|
2416
|
-
return null;
|
|
2417
|
-
}
|
|
2418
|
-
setContext(contextName) {
|
|
2419
|
-
this.contextName = contextName;
|
|
2420
|
-
}
|
|
2421
|
-
/**
|
|
2422
|
-
* Parse a task command from a chat message.
|
|
2423
|
-
* Returns the action and parsed parameters, or null if not a task command.
|
|
2424
|
-
*/
|
|
2425
|
-
static parseTaskCommand(message) {
|
|
2426
|
-
const lower = message.trim().toLowerCase();
|
|
2427
|
-
const addMatch = message.match(/^(?:add|create)\s+task[:\s]+(.+)/i);
|
|
2428
|
-
if (addMatch) {
|
|
2429
|
-
return { action: "add", title: addMatch[1].trim() };
|
|
2430
|
-
}
|
|
2431
|
-
if (/^list\s+tasks/i.test(lower)) {
|
|
2432
|
-
const statusMatch = lower.match(/list\s+tasks\s+(\w+)/);
|
|
2433
|
-
return { action: "list", statusFilter: statusMatch?.[1] };
|
|
2434
|
-
}
|
|
2435
|
-
const completeMatch = message.match(/^complete\s+task\s+(\S+)/i);
|
|
2436
|
-
if (completeMatch) {
|
|
2437
|
-
return { action: "complete", taskId: completeMatch[1] };
|
|
2438
|
-
}
|
|
2439
|
-
const startMatch = message.match(/^start\s+task\s+(\S+)/i);
|
|
2440
|
-
if (startMatch) {
|
|
2441
|
-
return { action: "start", taskId: startMatch[1] };
|
|
2442
|
-
}
|
|
2443
|
-
if (/^next\s+task/i.test(lower)) {
|
|
2444
|
-
return { action: "next" };
|
|
2445
|
-
}
|
|
2446
|
-
const archiveMatch = message.match(/^archive\s+task\s+(\S+)/i);
|
|
2447
|
-
if (archiveMatch) {
|
|
2448
|
-
return { action: "archive", taskId: archiveMatch[1] };
|
|
2449
|
-
}
|
|
2450
|
-
return null;
|
|
2451
|
-
}
|
|
2452
|
-
};
|
|
2453
|
-
|
|
2454
|
-
// packages/runtime/src/prompt.ts
|
|
2455
|
-
import { readFileSync, existsSync, readdirSync } from "fs";
|
|
2456
|
-
import { resolve } from "path";
|
|
2457
|
-
var charterCache = null;
|
|
2458
|
-
function loadCharter(path) {
|
|
2459
|
-
if (charterCache && charterCache.path === path) return charterCache.content;
|
|
2460
|
-
if (!existsSync(path)) return "";
|
|
2461
|
-
const content = readFileSync(path, "utf-8");
|
|
2462
|
-
charterCache = { path, content };
|
|
2463
|
-
return content;
|
|
2464
|
-
}
|
|
2465
|
-
var WORKSPACE_FILE_PRIORITY = [
|
|
2466
|
-
"SOUL.md",
|
|
2467
|
-
// Who the agent is (personality, values)
|
|
2468
|
-
"IDENTITY.md",
|
|
2469
|
-
// Name, avatar, creature type
|
|
2470
|
-
"AGENTS.md",
|
|
2471
|
-
// Operating instructions
|
|
2472
|
-
"USER.md",
|
|
2473
|
-
// About the human(s)
|
|
2474
|
-
"TOOLS.md"
|
|
2475
|
-
// Tool-specific notes
|
|
2476
|
-
];
|
|
2477
|
-
var workspaceCache = null;
|
|
2478
|
-
var WORKSPACE_CACHE_TTL_MS = 6e4;
|
|
2479
|
-
function loadWorkspaceFiles(dir) {
|
|
2480
|
-
const now = Date.now();
|
|
2481
|
-
if (workspaceCache && workspaceCache.dir === dir && now - workspaceCache.loadedAt < WORKSPACE_CACHE_TTL_MS) {
|
|
2482
|
-
return workspaceCache.files;
|
|
2483
|
-
}
|
|
2484
|
-
const files = /* @__PURE__ */ new Map();
|
|
2485
|
-
if (!existsSync(dir)) return files;
|
|
2486
|
-
for (const filename of WORKSPACE_FILE_PRIORITY) {
|
|
2487
|
-
const filePath = resolve(dir, filename);
|
|
2488
|
-
if (existsSync(filePath)) {
|
|
2489
|
-
try {
|
|
2490
|
-
files.set(filename, readFileSync(filePath, "utf-8"));
|
|
2491
|
-
} catch {
|
|
2492
|
-
}
|
|
2493
|
-
}
|
|
2494
|
-
}
|
|
2495
|
-
try {
|
|
2496
|
-
const entries = readdirSync(dir);
|
|
2497
|
-
for (const entry of entries) {
|
|
2498
|
-
if (entry.endsWith(".md") && !files.has(entry) && !entry.startsWith(".")) {
|
|
2499
|
-
const filePath = resolve(dir, entry);
|
|
2500
|
-
try {
|
|
2501
|
-
files.set(entry, readFileSync(filePath, "utf-8"));
|
|
2502
|
-
} catch {
|
|
2503
|
-
}
|
|
2504
|
-
}
|
|
2505
|
-
}
|
|
2506
|
-
} catch {
|
|
2507
|
-
}
|
|
2508
|
-
workspaceCache = { dir, files, loadedAt: now };
|
|
2509
|
-
const names = [...files.keys()].join(", ");
|
|
2510
|
-
if (files.size > 0) {
|
|
2511
|
-
console.log(`[workspace] Loaded ${files.size} files: ${names}`);
|
|
2512
|
-
}
|
|
2513
|
-
return files;
|
|
2514
|
-
}
|
|
2515
|
-
function buildSystemPrompt(config, episodes, contextName = "global", l3Knowledge = []) {
|
|
2516
|
-
let prompt = `You are ${config.name}. ${config.personality}
|
|
2517
|
-
`;
|
|
2518
|
-
if (config.workspace) {
|
|
2519
|
-
const wsFiles = loadWorkspaceFiles(config.workspace);
|
|
2520
|
-
if (wsFiles.size > 0) {
|
|
2521
|
-
prompt += "\n# Workspace Context\n";
|
|
2522
|
-
for (const [filename, content] of wsFiles) {
|
|
2523
|
-
prompt += `
|
|
2524
|
-
## ${filename}
|
|
2525
|
-
${content}
|
|
2526
|
-
`;
|
|
2527
|
-
}
|
|
2528
|
-
}
|
|
2529
|
-
}
|
|
2530
|
-
if (config.team_charter && !config.workspace) {
|
|
2531
|
-
const charter = loadCharter(config.team_charter);
|
|
2532
|
-
if (charter) {
|
|
2533
|
-
prompt += `
|
|
2534
|
-
${charter}
|
|
2535
|
-
`;
|
|
2536
|
-
}
|
|
2537
|
-
}
|
|
2538
|
-
prompt += `
|
|
2539
|
-
## Communication
|
|
2540
|
-
Messages are prefixed with [sender_handle]: or [sender_handle in group chat]: to tell you who's talking.
|
|
2541
|
-
In group chats, multiple people (humans and agents) may be present. Address them by name when relevant.
|
|
2542
|
-
Don't repeat or quote these prefixes in your responses \u2014 just respond naturally.
|
|
2543
|
-
If you decide not to respond to a group message, reply with exactly: __SKIP__
|
|
2544
|
-
`;
|
|
2545
|
-
if (contextName !== "global") {
|
|
2546
|
-
prompt += `
|
|
2547
|
-
## Active Context: ${contextName}
|
|
2548
|
-
You are currently working in the "${contextName}" project context.
|
|
2549
|
-
`;
|
|
2550
|
-
}
|
|
2551
|
-
if (l3Knowledge.length > 0) {
|
|
2552
|
-
prompt += "\n## Established Knowledge (learned patterns)\n\n";
|
|
2553
|
-
for (const entry of l3Knowledge) {
|
|
2554
|
-
prompt += `- ${entry.content}
|
|
2555
|
-
`;
|
|
2556
|
-
}
|
|
2557
|
-
}
|
|
2558
|
-
if (episodes.length > 0) {
|
|
2559
|
-
prompt += "\n## Relevant memories from previous conversations\n\n";
|
|
2560
|
-
for (const ep of episodes) {
|
|
2561
|
-
const timeAgo = formatTimeAgo(ep.timestamp);
|
|
2562
|
-
const ctxLabel = ep.context_name !== contextName ? ` [from: ${ep.context_name}]` : "";
|
|
2563
|
-
prompt += `[${timeAgo}]${ctxLabel} ${ep.role}: ${ep.content}
|
|
2564
|
-
`;
|
|
2565
|
-
}
|
|
2566
|
-
prompt += "\nUse these memories naturally \u2014 reference past conversations when relevant, but don't force it.\n";
|
|
2567
|
-
}
|
|
2568
|
-
return prompt;
|
|
2569
|
-
}
|
|
2570
|
-
function buildMessages(systemPrompt, conversationHistory, currentMessage) {
|
|
2571
|
-
return [
|
|
2572
|
-
{ role: "system", content: systemPrompt },
|
|
2573
|
-
...conversationHistory,
|
|
2574
|
-
{ role: "user", content: currentMessage }
|
|
2575
|
-
];
|
|
2576
|
-
}
|
|
2577
|
-
function formatTimeAgo(timestamp) {
|
|
2578
|
-
const date = new Date(timestamp);
|
|
2579
|
-
const now = /* @__PURE__ */ new Date();
|
|
2580
|
-
const diffMs = now.getTime() - date.getTime();
|
|
2581
|
-
const diffMins = Math.floor(diffMs / 6e4);
|
|
2582
|
-
const diffHours = Math.floor(diffMs / 36e5);
|
|
2583
|
-
const diffDays = Math.floor(diffMs / 864e5);
|
|
2584
|
-
if (diffMins < 1) return "just now";
|
|
2585
|
-
if (diffMins < 60) return `${diffMins}m ago`;
|
|
2586
|
-
if (diffHours < 24) return `${diffHours}h ago`;
|
|
2587
|
-
if (diffDays < 7) return `${diffDays}d ago`;
|
|
2588
|
-
return date.toLocaleDateString();
|
|
2589
|
-
}
|
|
2590
|
-
|
|
2591
|
-
// packages/runtime/src/agent.ts
|
|
2592
|
-
var Agent = class {
|
|
2593
|
-
config;
|
|
2594
|
-
llm;
|
|
2595
|
-
memory;
|
|
2596
|
-
contextManager;
|
|
2597
|
-
// Per-context conversation histories
|
|
2598
|
-
conversationHistories = /* @__PURE__ */ new Map();
|
|
2599
|
-
messageCount = 0;
|
|
2600
|
-
PROMOTION_INTERVAL = 10;
|
|
2601
|
-
// Run promotion every N messages
|
|
2602
|
-
constructor(config, contextName = "global") {
|
|
2603
|
-
this.config = config;
|
|
2604
|
-
this.llm = new LLMClient(config.llm);
|
|
2605
|
-
this.memory = new MemoryClient(config.memory);
|
|
2606
|
-
this.contextManager = new ContextManager(this.memory);
|
|
2607
|
-
if (contextName !== "global") {
|
|
2608
|
-
this.contextManager.switchContext(contextName);
|
|
2609
|
-
}
|
|
2610
|
-
}
|
|
2611
|
-
async processMessage(userMessage) {
|
|
2612
|
-
const specialResult = await this.handleSpecialCommand(userMessage);
|
|
2613
|
-
if (specialResult) return specialResult;
|
|
2614
|
-
const routing = this.contextManager.routeMessage(userMessage);
|
|
2615
|
-
const contextName = routing.context;
|
|
2616
|
-
if (routing.switched) {
|
|
2617
|
-
try {
|
|
2618
|
-
await this.memory.createContext(contextName);
|
|
2619
|
-
} catch {
|
|
2620
|
-
}
|
|
2621
|
-
}
|
|
2622
|
-
if (!this.conversationHistories.has(contextName)) {
|
|
2623
|
-
this.conversationHistories.set(contextName, []);
|
|
2624
|
-
}
|
|
2625
|
-
const conversationHistory = this.conversationHistories.get(contextName);
|
|
2626
|
-
const relevantEpisodes = await this.memory.search(userMessage, contextName, this.config.memory.top_k).catch((err) => {
|
|
2627
|
-
console.error("Memory search failed, continuing without context:", err.message);
|
|
2628
|
-
return [];
|
|
2629
|
-
});
|
|
2630
|
-
if (relevantEpisodes.length > 0) {
|
|
2631
|
-
const episodeIds = relevantEpisodes.map((e) => e.id);
|
|
2632
|
-
this.memory.recordCoAccess(episodeIds).catch(() => {
|
|
2633
|
-
});
|
|
2634
|
-
for (const ep of relevantEpisodes) {
|
|
2635
|
-
this.memory.recordAccess(ep.id).catch(() => {
|
|
2636
|
-
});
|
|
2637
|
-
}
|
|
2638
|
-
}
|
|
2639
|
-
const l3Knowledge = await this.memory.getL3Knowledge(contextName).catch(() => []);
|
|
2640
|
-
const systemPrompt = buildSystemPrompt(this.config.agent, relevantEpisodes, contextName, l3Knowledge);
|
|
2641
|
-
const messages = buildMessages(systemPrompt, conversationHistory, userMessage);
|
|
2642
|
-
const response = await this.llm.chat(messages);
|
|
2643
|
-
conversationHistory.push(
|
|
2644
|
-
{ role: "user", content: userMessage },
|
|
2645
|
-
{ role: "assistant", content: response.content }
|
|
2646
|
-
);
|
|
2647
|
-
if (conversationHistory.length > 40) {
|
|
2648
|
-
const trimmed = conversationHistory.slice(-40);
|
|
2649
|
-
this.conversationHistories.set(contextName, trimmed);
|
|
2650
|
-
}
|
|
2651
|
-
await this.storeEpisodes(contextName, userMessage, response.content);
|
|
2652
|
-
this.messageCount++;
|
|
2653
|
-
if (this.messageCount % this.PROMOTION_INTERVAL === 0) {
|
|
2654
|
-
this.memory.runPromotion(contextName).catch((err) => {
|
|
2655
|
-
console.error("Promotion run failed:", err.message);
|
|
2656
|
-
});
|
|
2657
|
-
}
|
|
2658
|
-
return {
|
|
2659
|
-
content: response.content,
|
|
2660
|
-
model: response.model,
|
|
2661
|
-
context: contextName,
|
|
2662
|
-
contextSwitched: routing.switched
|
|
2663
|
-
};
|
|
2664
|
-
}
|
|
2665
|
-
async storeEpisodes(contextName, userMessage, assistantResponse) {
|
|
2666
|
-
try {
|
|
2667
|
-
await Promise.all([
|
|
2668
|
-
this.memory.storeEpisode({
|
|
2669
|
-
context_name: contextName,
|
|
2670
|
-
role: "user",
|
|
2671
|
-
content: userMessage
|
|
2672
|
-
}),
|
|
2673
|
-
this.memory.storeEpisode({
|
|
2674
|
-
context_name: contextName,
|
|
2675
|
-
role: "assistant",
|
|
2676
|
-
content: assistantResponse
|
|
2677
|
-
})
|
|
2678
|
-
]);
|
|
2679
|
-
} catch (err) {
|
|
2680
|
-
console.error("Failed to store episodes:", err.message);
|
|
2681
|
-
}
|
|
2682
|
-
}
|
|
2683
|
-
async handleSpecialCommand(message) {
|
|
2684
|
-
const activeCtx = this.contextManager.getActiveContext();
|
|
2685
|
-
const searchAllMatch = message.match(/^(?:search\s+all|cross-context\s+search)[:\s]+(.+)/i);
|
|
2686
|
-
if (searchAllMatch) {
|
|
2687
|
-
const query = searchAllMatch[1].trim();
|
|
2688
|
-
try {
|
|
2689
|
-
const results = await this.memory.searchCrossContext(query);
|
|
2690
|
-
let response = "## Cross-Context Search Results\n\n";
|
|
2691
|
-
if (results.length === 0) {
|
|
2692
|
-
response += "No results found across any context.";
|
|
2693
|
-
} else {
|
|
2694
|
-
for (const group of results) {
|
|
2695
|
-
response += `### Context: ${group.context}
|
|
2696
|
-
`;
|
|
2697
|
-
for (const ep of group.episodes) {
|
|
2698
|
-
response += `- [${ep.role}] ${ep.content.slice(0, 200)}${ep.content.length > 200 ? "..." : ""} (score: ${ep.score.toFixed(3)})
|
|
2699
|
-
`;
|
|
2700
|
-
}
|
|
2701
|
-
response += "\n";
|
|
2702
|
-
}
|
|
2703
|
-
}
|
|
2704
|
-
return { content: response, model: "system", context: activeCtx };
|
|
2705
|
-
} catch (err) {
|
|
2706
|
-
return { content: `Cross-context search failed: ${err.message}`, model: "system", context: activeCtx };
|
|
2707
|
-
}
|
|
2708
|
-
}
|
|
2709
|
-
const shareMatch = message.match(/^share\s+(\S+)\s+with\s+(\S+)/i);
|
|
2710
|
-
if (shareMatch) {
|
|
2711
|
-
const episodeId = shareMatch[1];
|
|
2712
|
-
const targetContext = shareMatch[2];
|
|
2713
|
-
try {
|
|
2714
|
-
await this.memory.shareEpisode(episodeId, targetContext);
|
|
2715
|
-
return { content: `Shared episode ${episodeId} with context "${targetContext}".`, model: "system", context: activeCtx };
|
|
2716
|
-
} catch (err) {
|
|
2717
|
-
return { content: `Failed to share: ${err.message}`, model: "system", context: activeCtx };
|
|
2718
|
-
}
|
|
2719
|
-
}
|
|
2720
|
-
const taskCmd = TaskEngine.parseTaskCommand(message);
|
|
2721
|
-
if (taskCmd) {
|
|
2722
|
-
const engine = new TaskEngine({ contextName: activeCtx, memory: this.memory });
|
|
2723
|
-
try {
|
|
2724
|
-
switch (taskCmd.action) {
|
|
2725
|
-
case "add": {
|
|
2726
|
-
const task = await engine.addTask(taskCmd.title || "Untitled", taskCmd.description || "");
|
|
2727
|
-
return { content: `Task created: [${task.id.slice(0, 8)}] ${task.title} (status: ${task.status})`, model: "system", context: activeCtx };
|
|
2728
|
-
}
|
|
2729
|
-
case "list": {
|
|
2730
|
-
const tasks = await engine.listTasks(taskCmd.statusFilter);
|
|
2731
|
-
if (tasks.length === 0) {
|
|
2732
|
-
return { content: `No tasks${taskCmd.statusFilter ? ` with status "${taskCmd.statusFilter}"` : ""} in context "${activeCtx}".`, model: "system", context: activeCtx };
|
|
2733
|
-
}
|
|
2734
|
-
let response = `## Tasks in ${activeCtx}
|
|
2735
|
-
|
|
2736
|
-
`;
|
|
2737
|
-
for (const t of tasks) {
|
|
2738
|
-
const blockedBy = Array.isArray(t.blocked_by) ? t.blocked_by : JSON.parse(String(t.blocked_by) || "[]");
|
|
2739
|
-
const blockedStr = blockedBy.length > 0 ? ` (blocked by: ${blockedBy.map((b) => b.slice(0, 8)).join(", ")})` : "";
|
|
2740
|
-
response += `- [${t.status}] ${t.id.slice(0, 8)}: ${t.title}${blockedStr}
|
|
2741
|
-
`;
|
|
2742
|
-
}
|
|
2743
|
-
return { content: response, model: "system", context: activeCtx };
|
|
2744
|
-
}
|
|
2745
|
-
case "start": {
|
|
2746
|
-
const task = await engine.startTask(taskCmd.taskId);
|
|
2747
|
-
return { content: task ? `Task ${taskCmd.taskId.slice(0, 8)} started.` : "Task not found.", model: "system", context: activeCtx };
|
|
2748
|
-
}
|
|
2749
|
-
case "complete": {
|
|
2750
|
-
const task = await engine.completeTask(taskCmd.taskId);
|
|
2751
|
-
return { content: task ? `Task ${taskCmd.taskId.slice(0, 8)} completed.` : "Task not found.", model: "system", context: activeCtx };
|
|
2752
|
-
}
|
|
2753
|
-
case "archive": {
|
|
2754
|
-
const task = await engine.archiveTask(taskCmd.taskId);
|
|
2755
|
-
return { content: task ? `Task ${taskCmd.taskId.slice(0, 8)} archived.` : "Task not found.", model: "system", context: activeCtx };
|
|
2756
|
-
}
|
|
2757
|
-
case "next": {
|
|
2758
|
-
const task = await engine.pickAndStartNextTask();
|
|
2759
|
-
if (task) {
|
|
2760
|
-
return { content: `Picked up next task: [${task.id.slice(0, 8)}] ${task.title}`, model: "system", context: activeCtx };
|
|
2761
|
-
}
|
|
2762
|
-
return { content: "No available tasks to pick up.", model: "system", context: activeCtx };
|
|
2763
|
-
}
|
|
2764
|
-
}
|
|
2765
|
-
} catch (err) {
|
|
2766
|
-
return { content: `Task command failed: ${err.message}`, model: "system", context: activeCtx };
|
|
2767
|
-
}
|
|
2768
|
-
}
|
|
2769
|
-
return null;
|
|
2770
|
-
}
|
|
2771
|
-
getMemoryClient() {
|
|
2772
|
-
return this.memory;
|
|
2773
|
-
}
|
|
2774
|
-
getContextManager() {
|
|
2775
|
-
return this.contextManager;
|
|
2776
|
-
}
|
|
2777
|
-
setContext(name) {
|
|
2778
|
-
this.contextManager.switchContext(name);
|
|
2779
|
-
}
|
|
2780
|
-
getActiveContext() {
|
|
2781
|
-
return this.contextManager.getActiveContext();
|
|
2782
|
-
}
|
|
2783
|
-
};
|
|
2784
|
-
|
|
2785
|
-
// packages/runtime/src/config.ts
|
|
2786
|
-
var import_toml = __toESM(require_toml(), 1);
|
|
2787
|
-
import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
|
|
2788
|
-
import { resolve as resolve2, dirname } from "path";
|
|
2789
|
-
function defaultWorkerConfig() {
|
|
2790
|
-
return {
|
|
2791
|
-
enabled: false,
|
|
2792
|
-
primary_url: "http://localhost:3000",
|
|
2793
|
-
worker_port: 3100,
|
|
2794
|
-
worker_id: `worker-${process.pid}`,
|
|
2795
|
-
max_contexts: 4,
|
|
2796
|
-
task_poll_interval_ms: 5e3,
|
|
2797
|
-
status_report_interval_ms: 15e3
|
|
2798
|
-
};
|
|
2799
|
-
}
|
|
2800
|
-
function deepMerge(target, source) {
|
|
2801
|
-
const result = { ...target };
|
|
2802
|
-
for (const key of Object.keys(source)) {
|
|
2803
|
-
if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key]) && target[key] && typeof target[key] === "object") {
|
|
2804
|
-
result[key] = deepMerge(target[key], source[key]);
|
|
2805
|
-
} else if (source[key] !== void 0 && source[key] !== "") {
|
|
2806
|
-
result[key] = source[key];
|
|
2807
|
-
}
|
|
2808
|
-
}
|
|
2809
|
-
return result;
|
|
2810
|
-
}
|
|
2811
|
-
function loadConfig(path) {
|
|
2812
|
-
const raw = readFileSync2(path, "utf-8");
|
|
2813
|
-
let parsed = (0, import_toml.parse)(raw);
|
|
2814
|
-
const configDir = dirname(path);
|
|
2815
|
-
const localPath = resolve2(configDir, "local.toml");
|
|
2816
|
-
if (existsSync2(localPath)) {
|
|
2817
|
-
const localRaw = readFileSync2(localPath, "utf-8");
|
|
2818
|
-
const localParsed = (0, import_toml.parse)(localRaw);
|
|
2819
|
-
parsed = deepMerge(parsed, localParsed);
|
|
2820
|
-
console.log(`[config] Merged overrides from ${localPath}`);
|
|
2821
|
-
}
|
|
2822
|
-
if (process.env.AGENT_NAME) {
|
|
2823
|
-
parsed.agent.name = process.env.AGENT_NAME;
|
|
2824
|
-
}
|
|
2825
|
-
if (process.env.LLM_API_KEY) {
|
|
2826
|
-
parsed.llm.api_key = process.env.LLM_API_KEY;
|
|
2827
|
-
}
|
|
2828
|
-
if (process.env.LLM_BASE_URL) {
|
|
2829
|
-
parsed.llm.base_url = process.env.LLM_BASE_URL;
|
|
2830
|
-
}
|
|
2831
|
-
if (process.env.SESAME_API_KEY) {
|
|
2832
|
-
parsed.sesame.api_key = process.env.SESAME_API_KEY;
|
|
2833
|
-
}
|
|
2834
|
-
if (process.env.MEMORY_DAEMON_URL) {
|
|
2835
|
-
parsed.memory.daemon_url = process.env.MEMORY_DAEMON_URL;
|
|
2836
|
-
}
|
|
2837
|
-
if (process.env.WORKER_PRIMARY_URL) {
|
|
2838
|
-
if (!parsed.worker) parsed.worker = defaultWorkerConfig();
|
|
2839
|
-
parsed.worker.primary_url = process.env.WORKER_PRIMARY_URL;
|
|
2840
|
-
}
|
|
2841
|
-
if (process.env.WORKER_PORT) {
|
|
2842
|
-
if (!parsed.worker) parsed.worker = defaultWorkerConfig();
|
|
2843
|
-
parsed.worker.worker_port = parseInt(process.env.WORKER_PORT, 10);
|
|
2844
|
-
}
|
|
2845
|
-
if (process.env.WORKER_ID) {
|
|
2846
|
-
if (!parsed.worker) parsed.worker = defaultWorkerConfig();
|
|
2847
|
-
parsed.worker.worker_id = process.env.WORKER_ID;
|
|
2848
|
-
}
|
|
2849
|
-
if (parsed.agent.workspace && !parsed.agent.workspace.startsWith("/")) {
|
|
2850
|
-
const configDir2 = dirname(path);
|
|
2851
|
-
parsed.agent.workspace = resolve2(configDir2, "..", parsed.agent.workspace);
|
|
2852
|
-
}
|
|
2853
|
-
return parsed;
|
|
2854
|
-
}
|
|
2855
|
-
|
|
2856
|
-
// packages/runtime/src/sesame.ts
|
|
2857
|
-
import { readFileSync as readFileSync3 } from "fs";
|
|
2858
|
-
import { resolve as resolve3, dirname as dirname2 } from "path";
|
|
2859
|
-
import { fileURLToPath } from "url";
|
|
2860
|
-
var RUNTIME_VERSION = "unknown";
|
|
2861
|
-
try {
|
|
2862
|
-
const __dirname = dirname2(fileURLToPath(import.meta.url));
|
|
2863
|
-
const pkg = JSON.parse(readFileSync3(resolve3(__dirname, "../package.json"), "utf-8"));
|
|
2864
|
-
RUNTIME_VERSION = pkg.version ?? "unknown";
|
|
2865
|
-
} catch {
|
|
2866
|
-
}
|
|
2867
|
-
var SesameClient2 = class {
|
|
2868
|
-
config;
|
|
2869
|
-
sdk;
|
|
2870
|
-
messageHandler = null;
|
|
2871
|
-
upgradeHandler = null;
|
|
2872
|
-
agentId = null;
|
|
2873
|
-
channels = /* @__PURE__ */ new Map();
|
|
2874
|
-
typingIntervals = /* @__PURE__ */ new Map();
|
|
2875
|
-
constructor(config) {
|
|
2876
|
-
this.config = config;
|
|
2877
|
-
this.sdk = new SesameClient({
|
|
2878
|
-
apiUrl: config.api_url.replace(/\/api\/v1$/, ""),
|
|
2879
|
-
wsUrl: config.ws_url,
|
|
2880
|
-
apiKey: config.api_key
|
|
2881
|
-
});
|
|
2882
|
-
}
|
|
2883
|
-
onMessage(handler) {
|
|
2884
|
-
this.messageHandler = handler;
|
|
2885
|
-
}
|
|
2886
|
-
onUpgrade(handler) {
|
|
2887
|
-
this.upgradeHandler = handler;
|
|
2888
|
-
}
|
|
2889
|
-
async connect() {
|
|
2890
|
-
const manifest = await this.sdk.getManifest();
|
|
2891
|
-
this.agentId = manifest.agent.id;
|
|
2892
|
-
console.log(`[sesame] Authenticated as ${manifest.agent.handle} (${this.agentId})`);
|
|
2893
|
-
for (const ch of manifest.channels) {
|
|
2894
|
-
this.channels.set(ch.id, { kind: ch.kind, name: ch.name ?? void 0 });
|
|
2895
|
-
const label = ch.name || ch.id.slice(0, 8);
|
|
2896
|
-
console.log(`[sesame] Channel: ${label} (${ch.kind})`);
|
|
2897
|
-
}
|
|
2898
|
-
this.updatePresence("online", { emoji: "\u{1F7E2}" });
|
|
2899
|
-
this.sdk.on("upgrade.request", (event) => {
|
|
2900
|
-
console.log(`[sesame] Upgrade request received: ${event.packageName}@${event.targetVersion}`);
|
|
2901
|
-
if (this.upgradeHandler) {
|
|
2902
|
-
this.upgradeHandler({
|
|
2903
|
-
targetVersion: event.targetVersion,
|
|
2904
|
-
packageName: event.packageName,
|
|
2905
|
-
requestedBy: event.requestedBy,
|
|
2906
|
-
requestId: event.requestId
|
|
2907
|
-
});
|
|
2908
|
-
}
|
|
2909
|
-
});
|
|
2910
|
-
this.sdk.on("control", (event) => {
|
|
2911
|
-
console.log(`[sesame] Control event: ${event.action}`, event.payload);
|
|
2912
|
-
});
|
|
2913
|
-
this.sdk.on("message", (event) => {
|
|
2914
|
-
const msg = event.data || event.message || event;
|
|
2915
|
-
const senderId = msg.senderId || msg.sender?.id;
|
|
2916
|
-
if (senderId === this.agentId) return;
|
|
2917
|
-
if (!this.messageHandler || !msg.content) return;
|
|
2918
|
-
const channelInfo = this.channels.get(msg.channelId);
|
|
2919
|
-
this.messageHandler({
|
|
2920
|
-
id: msg.id || "unknown",
|
|
2921
|
-
channelId: msg.channelId || "unknown",
|
|
2922
|
-
channelKind: channelInfo?.kind || "dm",
|
|
2923
|
-
content: msg.content,
|
|
2924
|
-
author: {
|
|
2925
|
-
id: senderId || "unknown",
|
|
2926
|
-
handle: msg.senderHandle || msg.metadata?.senderHandle || "unknown"
|
|
2927
|
-
},
|
|
2928
|
-
timestamp: msg.createdAt || (/* @__PURE__ */ new Date()).toISOString()
|
|
2929
|
-
});
|
|
2930
|
-
});
|
|
2931
|
-
await this.sdk.connect();
|
|
2932
|
-
console.log("[sesame] WebSocket connected");
|
|
2933
|
-
const ws = this.sdk.ws;
|
|
2934
|
-
if (ws?.readyState === 1) {
|
|
2935
|
-
ws.send(JSON.stringify({ type: "meta", runtime: "hivemind", version: RUNTIME_VERSION }));
|
|
2936
|
-
console.log(`[sesame] Reported version: hivemind@${RUNTIME_VERSION}`);
|
|
2937
|
-
}
|
|
2938
|
-
}
|
|
2939
|
-
// ── Typing Indicators ──
|
|
2940
|
-
/**
|
|
2941
|
-
* Start sending typing indicators for a channel.
|
|
2942
|
-
* Sends immediately, then every 2.5s until stopTyping() is called.
|
|
2943
|
-
*/
|
|
2944
|
-
startTyping(channelId) {
|
|
2945
|
-
if (this.typingIntervals.has(channelId)) return;
|
|
2946
|
-
this.sdk.sendTyping(channelId);
|
|
2947
|
-
const interval = setInterval(() => {
|
|
2948
|
-
this.sdk.sendTyping(channelId);
|
|
2949
|
-
}, 2500);
|
|
2950
|
-
this.typingIntervals.set(channelId, interval);
|
|
2951
|
-
}
|
|
2952
|
-
/**
|
|
2953
|
-
* Stop sending typing indicators for a channel.
|
|
2954
|
-
*/
|
|
2955
|
-
stopTyping(channelId) {
|
|
2956
|
-
const interval = this.typingIntervals.get(channelId);
|
|
2957
|
-
if (interval) {
|
|
2958
|
-
clearInterval(interval);
|
|
2959
|
-
this.typingIntervals.delete(channelId);
|
|
2960
|
-
}
|
|
2961
|
-
}
|
|
2962
|
-
/**
|
|
2963
|
-
* Stop all active typing indicators.
|
|
2964
|
-
*/
|
|
2965
|
-
stopAllTyping() {
|
|
2966
|
-
for (const [channelId, interval] of this.typingIntervals) {
|
|
2967
|
-
clearInterval(interval);
|
|
2968
|
-
}
|
|
2969
|
-
this.typingIntervals.clear();
|
|
2970
|
-
}
|
|
2971
|
-
// ── Presence ──
|
|
2972
|
-
/**
|
|
2973
|
-
* Update agent presence/status.
|
|
2974
|
-
* @param status - "online" | "thinking" | "working" | "idle" | "offline"
|
|
2975
|
-
* @param options - Optional detail text, progress (0-100), emoji
|
|
2976
|
-
*/
|
|
2977
|
-
updatePresence(status, options) {
|
|
2978
|
-
if (typeof this.sdk.updatePresence === "function") {
|
|
2979
|
-
this.sdk.updatePresence(status, options);
|
|
2980
|
-
} else {
|
|
2981
|
-
const ws = this.sdk.ws;
|
|
2982
|
-
if (ws?.readyState === 1) {
|
|
2983
|
-
ws.send(JSON.stringify({ type: "status", status, ...options }));
|
|
2984
|
-
}
|
|
2985
|
-
}
|
|
2986
|
-
}
|
|
2987
|
-
// ── Read Receipts ──
|
|
2988
|
-
/**
|
|
2989
|
-
* Mark a channel as read up to a given sequence number.
|
|
2990
|
-
*/
|
|
2991
|
-
async markRead(channelId, seq) {
|
|
2992
|
-
await this.sdk.markRead(channelId, seq);
|
|
2993
|
-
}
|
|
2994
|
-
// ── Messages ──
|
|
2995
|
-
async sendMessage(channelId, content) {
|
|
2996
|
-
await this.sdk.sendMessage(channelId, { content });
|
|
2997
|
-
}
|
|
2998
|
-
getAgentId() {
|
|
2999
|
-
return this.agentId;
|
|
3000
|
-
}
|
|
3001
|
-
getChannelInfo(channelId) {
|
|
3002
|
-
return this.channels.get(channelId);
|
|
3003
|
-
}
|
|
3004
|
-
disconnect() {
|
|
3005
|
-
this.stopAllTyping();
|
|
3006
|
-
this.updatePresence("offline");
|
|
3007
|
-
this.sdk.disconnect();
|
|
3008
|
-
}
|
|
3009
|
-
};
|
|
3010
|
-
|
|
3011
|
-
// packages/runtime/src/pipeline.ts
|
|
3012
|
-
import { execSync } from "child_process";
|
|
3013
|
-
async function startPipeline(configPath) {
|
|
3014
|
-
const config = loadConfig(configPath);
|
|
3015
|
-
console.log(`[hivemind] Starting ${config.agent.name} (pid ${process.pid})`);
|
|
3016
|
-
const memory = new MemoryClient(config.memory);
|
|
3017
|
-
const memoryOk = await memory.healthCheck();
|
|
3018
|
-
if (!memoryOk) {
|
|
3019
|
-
console.warn("[hivemind] Memory daemon unreachable at", config.memory.daemon_url);
|
|
3020
|
-
console.warn("[hivemind] Continuing without persistent memory \u2014 episodes will not be stored");
|
|
3021
|
-
} else {
|
|
3022
|
-
console.log("[hivemind] Memory daemon connected");
|
|
3023
|
-
}
|
|
3024
|
-
const agent = new Agent(config);
|
|
3025
|
-
console.log(`[hivemind] Context manager initialized (active: ${agent.getActiveContext()})`);
|
|
3026
|
-
if (config.sesame.api_key) {
|
|
3027
|
-
await startSesameLoop(config, agent);
|
|
3028
|
-
} else {
|
|
3029
|
-
console.log("[hivemind] No Sesame API key configured \u2014 running in stdin mode");
|
|
3030
|
-
await startStdinLoop(agent);
|
|
3031
|
-
}
|
|
3032
|
-
}
|
|
3033
|
-
async function startSesameLoop(config, agent) {
|
|
3034
|
-
const sesame = new SesameClient2(config.sesame);
|
|
3035
|
-
let shuttingDown = false;
|
|
3036
|
-
const shutdown = (signal) => {
|
|
3037
|
-
if (shuttingDown) return;
|
|
3038
|
-
shuttingDown = true;
|
|
3039
|
-
console.log(`
|
|
3040
|
-
[hivemind] Received ${signal}, shutting down...`);
|
|
3041
|
-
try {
|
|
3042
|
-
sesame.updatePresence("offline", { emoji: "\u2B58" });
|
|
3043
|
-
sesame.disconnect();
|
|
3044
|
-
console.log("[hivemind] Sesame disconnected cleanly");
|
|
3045
|
-
} catch (err) {
|
|
3046
|
-
console.error("[hivemind] Error during disconnect:", err.message);
|
|
3047
|
-
}
|
|
3048
|
-
process.exit(0);
|
|
3049
|
-
};
|
|
3050
|
-
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
3051
|
-
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
3052
|
-
sesame.onUpgrade(async (req) => {
|
|
3053
|
-
console.log(`[hivemind] Upgrade requested: ${req.packageName}@${req.targetVersion} (by ${req.requestedBy})`);
|
|
3054
|
-
sesame.updatePresence("working", { detail: `Upgrading to ${req.targetVersion}`, emoji: "\u2B06\uFE0F" });
|
|
3055
|
-
try {
|
|
3056
|
-
const target = req.targetVersion === "latest" ? req.packageName : `${req.packageName}@${req.targetVersion}`;
|
|
3057
|
-
console.log(`[hivemind] Running: npm install -g ${target}`);
|
|
3058
|
-
execSync(`npm install -g ${target}`, { stdio: "inherit", timeout: 12e4 });
|
|
3059
|
-
console.log("[hivemind] Package updated successfully");
|
|
3060
|
-
console.log(`[hivemind] Upgrade to ${req.targetVersion} complete. Restarting...`);
|
|
3061
|
-
sesame.updatePresence("working", { detail: "Restarting after upgrade", emoji: "\u{1F504}" });
|
|
3062
|
-
try {
|
|
3063
|
-
execSync("launchctl kickstart -k gui/$(id -u)/com.hivemind.agent", { timeout: 1e4 });
|
|
3064
|
-
} catch {
|
|
3065
|
-
console.log("[hivemind] Exiting for restart...");
|
|
3066
|
-
process.exit(0);
|
|
3067
|
-
}
|
|
3068
|
-
} catch (err) {
|
|
3069
|
-
console.error(`[hivemind] Upgrade failed: ${err.message}`);
|
|
3070
|
-
sesame.updatePresence("online", { detail: "Upgrade failed", emoji: "\u274C" });
|
|
3071
|
-
}
|
|
3072
|
-
});
|
|
3073
|
-
sesame.onMessage(async (msg) => {
|
|
3074
|
-
if (shuttingDown) return;
|
|
3075
|
-
console.log(`[sesame] ${msg.author.handle} (${msg.channelKind}): ${msg.content}`);
|
|
3076
|
-
sesame.startTyping(msg.channelId);
|
|
3077
|
-
sesame.updatePresence("thinking", { detail: `Replying to ${msg.author.handle}`, emoji: "\u{1F4AD}" });
|
|
3078
|
-
try {
|
|
3079
|
-
const prefix = msg.channelKind === "group" ? `[${msg.author.handle} in group chat]: ` : `[${msg.author.handle}]: `;
|
|
3080
|
-
const response = await agent.processMessage(prefix + msg.content);
|
|
3081
|
-
sesame.stopTyping(msg.channelId);
|
|
3082
|
-
if (response.content.trim() === "__SKIP__") {
|
|
3083
|
-
console.log(`[sesame] ${config.agent.name}: skipped (${msg.author.handle} in ${msg.channelKind})`);
|
|
3084
|
-
sesame.updatePresence("online", { emoji: "\u{1F7E2}" });
|
|
3085
|
-
return;
|
|
3086
|
-
}
|
|
3087
|
-
const ctxPrefix = response.contextSwitched ? `[switched to ${response.context}] ` : "";
|
|
3088
|
-
await sesame.sendMessage(msg.channelId, ctxPrefix + response.content);
|
|
3089
|
-
console.log(`[sesame] ${config.agent.name} (${response.context}): ${response.content.slice(0, 100)}...`);
|
|
3090
|
-
sesame.updatePresence("online", { emoji: "\u{1F7E2}" });
|
|
3091
|
-
} catch (err) {
|
|
3092
|
-
sesame.stopTyping(msg.channelId);
|
|
3093
|
-
sesame.updatePresence("online", { emoji: "\u{1F7E2}" });
|
|
3094
|
-
console.error("[sesame] Error processing message:", err.message);
|
|
3095
|
-
}
|
|
3096
|
-
});
|
|
3097
|
-
await sesame.connect();
|
|
3098
|
-
console.log("[hivemind] Listening for Sesame messages");
|
|
3099
|
-
await new Promise(() => {
|
|
3100
|
-
});
|
|
3101
|
-
}
|
|
3102
|
-
async function startStdinLoop(agent) {
|
|
3103
|
-
const readline = await import("readline");
|
|
3104
|
-
const rl = readline.createInterface({
|
|
3105
|
-
input: process.stdin,
|
|
3106
|
-
output: process.stdout
|
|
3107
|
-
});
|
|
3108
|
-
console.log("[hivemind] Ready. Type a message (Ctrl+C to exit)");
|
|
3109
|
-
console.log("[hivemind] Commands: 'switch to <name>', 'list contexts', 'create context <name>'\n");
|
|
3110
|
-
rl.on("line", async (line) => {
|
|
3111
|
-
const input = line.trim();
|
|
3112
|
-
if (!input) return;
|
|
3113
|
-
if (input.toLowerCase() === "list contexts") {
|
|
3114
|
-
const contexts = agent.getContextManager().listContexts();
|
|
3115
|
-
console.log("\nContexts:");
|
|
3116
|
-
for (const ctx of contexts) {
|
|
3117
|
-
const active = ctx.name === agent.getActiveContext() ? " (active)" : "";
|
|
3118
|
-
console.log(` - ${ctx.name}${active}: ${ctx.description || "(no description)"}`);
|
|
3119
|
-
}
|
|
3120
|
-
console.log();
|
|
3121
|
-
return;
|
|
3122
|
-
}
|
|
3123
|
-
const createMatch = input.match(/^create context (\S+)\s*(.*)?$/i);
|
|
3124
|
-
if (createMatch) {
|
|
3125
|
-
const name = createMatch[1];
|
|
3126
|
-
const desc = createMatch[2] || "";
|
|
3127
|
-
await agent.getContextManager().createContext(name, desc);
|
|
3128
|
-
console.log(`
|
|
3129
|
-
Created context: ${name}
|
|
3130
|
-
`);
|
|
3131
|
-
return;
|
|
3132
|
-
}
|
|
3133
|
-
try {
|
|
3134
|
-
const response = await agent.processMessage(input);
|
|
3135
|
-
if (response.contextSwitched) {
|
|
3136
|
-
console.log(`
|
|
3137
|
-
[switched to context: ${response.context}]`);
|
|
3138
|
-
}
|
|
3139
|
-
console.log(`
|
|
3140
|
-
${response.content}
|
|
3141
|
-
`);
|
|
3142
|
-
} catch (err) {
|
|
3143
|
-
console.error("Error:", err.message);
|
|
3144
|
-
}
|
|
3145
|
-
});
|
|
3146
|
-
return new Promise((resolve4) => {
|
|
3147
|
-
rl.on("close", resolve4);
|
|
3148
|
-
});
|
|
3149
|
-
}
|
|
3150
|
-
|
|
3151
|
-
// packages/runtime/src/fleet/worker-server.ts
|
|
3152
|
-
import { createServer } from "http";
|
|
3153
|
-
var WorkerServer = class {
|
|
3154
|
-
server = null;
|
|
3155
|
-
workerId;
|
|
3156
|
-
port;
|
|
3157
|
-
startTime;
|
|
3158
|
-
assignedContexts = /* @__PURE__ */ new Map();
|
|
3159
|
-
activeContext = null;
|
|
3160
|
-
currentTask = null;
|
|
3161
|
-
maxContexts;
|
|
3162
|
-
memoryDaemonUrl;
|
|
3163
|
-
ollamaUrl;
|
|
3164
|
-
onAssignCallback = null;
|
|
3165
|
-
onSyncPushCallback = null;
|
|
3166
|
-
constructor(opts) {
|
|
3167
|
-
this.workerId = opts.workerId;
|
|
3168
|
-
this.port = opts.port;
|
|
3169
|
-
this.startTime = Date.now();
|
|
3170
|
-
this.maxContexts = opts.maxContexts ?? 4;
|
|
3171
|
-
this.memoryDaemonUrl = opts.memoryDaemonUrl ?? null;
|
|
3172
|
-
this.ollamaUrl = opts.ollamaUrl ?? null;
|
|
3173
|
-
}
|
|
3174
|
-
/** Start listening. */
|
|
3175
|
-
async start() {
|
|
3176
|
-
return new Promise((resolve4, reject) => {
|
|
3177
|
-
this.server = createServer((req, res) => this.handleRequest(req, res));
|
|
3178
|
-
this.server.on("error", reject);
|
|
3179
|
-
this.server.listen(this.port, () => resolve4());
|
|
3180
|
-
});
|
|
3181
|
-
}
|
|
3182
|
-
/** Stop the server. */
|
|
3183
|
-
async stop() {
|
|
3184
|
-
return new Promise((resolve4) => {
|
|
3185
|
-
if (!this.server) {
|
|
3186
|
-
resolve4();
|
|
3187
|
-
return;
|
|
3188
|
-
}
|
|
3189
|
-
this.server.close(() => resolve4());
|
|
3190
|
-
});
|
|
3191
|
-
}
|
|
3192
|
-
getPort() {
|
|
3193
|
-
return this.port;
|
|
3194
|
-
}
|
|
3195
|
-
getAssignedContexts() {
|
|
3196
|
-
return Array.from(this.assignedContexts.keys());
|
|
3197
|
-
}
|
|
3198
|
-
setActiveContext(name) {
|
|
3199
|
-
this.activeContext = name;
|
|
3200
|
-
}
|
|
3201
|
-
setCurrentTask(taskId) {
|
|
3202
|
-
this.currentTask = taskId;
|
|
3203
|
-
}
|
|
3204
|
-
/** Register a callback for when a new context is assigned. */
|
|
3205
|
-
onContextAssigned(cb) {
|
|
3206
|
-
this.onAssignCallback = cb;
|
|
3207
|
-
}
|
|
3208
|
-
/** Register a handler for incoming sync push requests from Primary. */
|
|
3209
|
-
onSyncPush(cb) {
|
|
3210
|
-
this.onSyncPushCallback = cb;
|
|
3211
|
-
}
|
|
3212
|
-
// --- Request Router ---
|
|
3213
|
-
async handleRequest(req, res) {
|
|
3214
|
-
const url = new URL(req.url ?? "/", `http://localhost:${this.port}`);
|
|
3215
|
-
const path = url.pathname;
|
|
3216
|
-
const method = req.method ?? "GET";
|
|
3217
|
-
try {
|
|
3218
|
-
if (method === "GET" && path === "/health") {
|
|
3219
|
-
return this.handleHealth(res);
|
|
3220
|
-
}
|
|
3221
|
-
if (method === "POST" && path === "/assign") {
|
|
3222
|
-
const body = await readBody(req);
|
|
3223
|
-
return this.handleAssign(body, res);
|
|
3224
|
-
}
|
|
3225
|
-
if (method === "DELETE" && path.startsWith("/assign/")) {
|
|
3226
|
-
const contextName = decodeURIComponent(path.slice("/assign/".length));
|
|
3227
|
-
return this.handleUnassign(contextName, res);
|
|
3228
|
-
}
|
|
3229
|
-
if (method === "GET" && path === "/status") {
|
|
3230
|
-
return this.handleStatus(res);
|
|
3231
|
-
}
|
|
3232
|
-
if (method === "POST" && path === "/sync/push") {
|
|
3233
|
-
const body = await readBody(req);
|
|
3234
|
-
return this.handleSyncPush(body, res);
|
|
3235
|
-
}
|
|
3236
|
-
sendJson(res, 404, { error: "Not found" });
|
|
3237
|
-
} catch (err) {
|
|
3238
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
3239
|
-
sendJson(res, 500, { error: msg });
|
|
3240
|
-
}
|
|
3241
|
-
}
|
|
3242
|
-
// --- Handlers ---
|
|
3243
|
-
handleHealth(res) {
|
|
3244
|
-
const uptimeMs = Date.now() - this.startTime;
|
|
3245
|
-
const body = {
|
|
3246
|
-
worker_id: this.workerId,
|
|
3247
|
-
status: "healthy",
|
|
3248
|
-
uptime_seconds: Math.floor(uptimeMs / 1e3),
|
|
3249
|
-
assigned_contexts: Array.from(this.assignedContexts.keys()),
|
|
3250
|
-
active_context: this.activeContext,
|
|
3251
|
-
memory_daemon_ok: this.memoryDaemonUrl !== null,
|
|
3252
|
-
ollama_ok: this.ollamaUrl !== null
|
|
3253
|
-
};
|
|
3254
|
-
sendJson(res, 200, body);
|
|
3255
|
-
}
|
|
3256
|
-
handleAssign(raw, res) {
|
|
3257
|
-
const req = JSON.parse(raw);
|
|
3258
|
-
if (this.assignedContexts.size >= this.maxContexts) {
|
|
3259
|
-
const body2 = {
|
|
3260
|
-
context_name: req.context_name,
|
|
3261
|
-
accepted: false,
|
|
3262
|
-
reason: "Worker at max context capacity"
|
|
3263
|
-
};
|
|
3264
|
-
sendJson(res, 200, body2);
|
|
3265
|
-
return;
|
|
3266
|
-
}
|
|
3267
|
-
const assignment = {
|
|
3268
|
-
context_name: req.context_name,
|
|
3269
|
-
context_description: req.context_description,
|
|
3270
|
-
assigned_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
3271
|
-
};
|
|
3272
|
-
this.assignedContexts.set(req.context_name, assignment);
|
|
3273
|
-
if (this.onAssignCallback) {
|
|
3274
|
-
this.onAssignCallback(req.context_name, req.context_description);
|
|
3275
|
-
}
|
|
3276
|
-
const body = {
|
|
3277
|
-
context_name: req.context_name,
|
|
3278
|
-
accepted: true
|
|
3279
|
-
};
|
|
3280
|
-
sendJson(res, 200, body);
|
|
3281
|
-
}
|
|
3282
|
-
handleUnassign(contextName, res) {
|
|
3283
|
-
const existed = this.assignedContexts.delete(contextName);
|
|
3284
|
-
if (this.activeContext === contextName) {
|
|
3285
|
-
this.activeContext = null;
|
|
3286
|
-
this.currentTask = null;
|
|
3287
|
-
}
|
|
3288
|
-
sendJson(res, existed ? 200 : 404, {
|
|
3289
|
-
context_name: contextName,
|
|
3290
|
-
removed: existed
|
|
3291
|
-
});
|
|
3292
|
-
}
|
|
3293
|
-
handleStatus(res) {
|
|
3294
|
-
const report = {
|
|
3295
|
-
activity: this.currentTask ? "working" : "idle",
|
|
3296
|
-
current_context: this.activeContext,
|
|
3297
|
-
current_task: this.currentTask
|
|
3298
|
-
};
|
|
3299
|
-
sendJson(res, 200, report);
|
|
3300
|
-
}
|
|
3301
|
-
async handleSyncPush(raw, res) {
|
|
3302
|
-
if (!this.onSyncPushCallback) {
|
|
3303
|
-
sendJson(res, 501, { error: "Sync push handler not registered" });
|
|
3304
|
-
return;
|
|
3305
|
-
}
|
|
3306
|
-
const req = JSON.parse(raw);
|
|
3307
|
-
const result = await this.onSyncPushCallback(req);
|
|
3308
|
-
sendJson(res, 200, result);
|
|
3309
|
-
}
|
|
3310
|
-
};
|
|
3311
|
-
function readBody(req) {
|
|
3312
|
-
return new Promise((resolve4, reject) => {
|
|
3313
|
-
const chunks = [];
|
|
3314
|
-
req.on("data", (chunk) => chunks.push(chunk));
|
|
3315
|
-
req.on("end", () => resolve4(Buffer.concat(chunks).toString("utf-8")));
|
|
3316
|
-
req.on("error", reject);
|
|
3317
|
-
});
|
|
3318
|
-
}
|
|
3319
|
-
function sendJson(res, status, body) {
|
|
3320
|
-
const payload = JSON.stringify(body);
|
|
3321
|
-
res.writeHead(status, {
|
|
3322
|
-
"Content-Type": "application/json",
|
|
3323
|
-
"Content-Length": Buffer.byteLength(payload)
|
|
3324
|
-
});
|
|
3325
|
-
res.end(payload);
|
|
3326
|
-
}
|
|
3327
|
-
|
|
3328
|
-
// packages/runtime/src/fleet/worker-protocol.ts
|
|
3329
|
-
var WORKER_API_PREFIX = "/workers";
|
|
3330
|
-
var PRIMARY_ROUTES = {
|
|
3331
|
-
register: `${WORKER_API_PREFIX}/register`,
|
|
3332
|
-
status: (workerId) => `${WORKER_API_PREFIX}/${encodeURIComponent(workerId)}/status`,
|
|
3333
|
-
syncPull: `${WORKER_API_PREFIX}/sync/pull`
|
|
3334
|
-
};
|
|
3335
|
-
var WORKER_ROUTES = {
|
|
3336
|
-
health: "/health",
|
|
3337
|
-
assign: "/assign",
|
|
3338
|
-
unassign: (contextName) => `/assign/${encodeURIComponent(contextName)}`,
|
|
3339
|
-
status: "/status",
|
|
3340
|
-
syncPush: "/sync/push"
|
|
3341
|
-
};
|
|
3342
|
-
var DEFAULT_HEALTH_INTERVAL_MS = 3e4;
|
|
3343
|
-
var HEALTH_TIMEOUT_MS = 5e3;
|
|
3344
|
-
var DEFAULT_SYNC_INTERVAL_MS = 6e4;
|
|
3345
|
-
|
|
3346
|
-
// packages/runtime/src/worker.ts
|
|
3347
|
-
var WorkerRuntime = class {
|
|
3348
|
-
config;
|
|
3349
|
-
workerConfig;
|
|
3350
|
-
server;
|
|
3351
|
-
memory;
|
|
3352
|
-
agent;
|
|
3353
|
-
taskPollTimer = null;
|
|
3354
|
-
statusReportTimer = null;
|
|
3355
|
-
registeredWorkerId = null;
|
|
3356
|
-
running = false;
|
|
3357
|
-
executing = false;
|
|
3358
|
-
constructor(opts) {
|
|
3359
|
-
this.config = opts.config;
|
|
3360
|
-
this.workerConfig = opts.workerConfig;
|
|
3361
|
-
this.server = new WorkerServer({
|
|
3362
|
-
workerId: this.workerConfig.worker_id,
|
|
3363
|
-
port: this.workerConfig.worker_port,
|
|
3364
|
-
maxContexts: this.workerConfig.max_contexts,
|
|
3365
|
-
memoryDaemonUrl: this.config.memory.daemon_url,
|
|
3366
|
-
ollamaUrl: this.config.ollama.base_url
|
|
3367
|
-
});
|
|
3368
|
-
this.memory = new MemoryClient(this.config.memory);
|
|
3369
|
-
this.agent = new Agent(this.config);
|
|
3370
|
-
}
|
|
3371
|
-
/**
|
|
3372
|
-
* Start the worker: HTTP server, register with Primary, begin task loop.
|
|
3373
|
-
*/
|
|
3374
|
-
async start() {
|
|
3375
|
-
this.running = true;
|
|
3376
|
-
this.server.onContextAssigned((contextName, description) => {
|
|
3377
|
-
console.log(`[worker] Context assigned: "${contextName}" \u2014 ${description || "(no description)"}`);
|
|
3378
|
-
this.memory.createContext(contextName, description).catch((err) => {
|
|
3379
|
-
console.warn(`[worker] Failed to create context "${contextName}" in daemon:`, err.message);
|
|
3380
|
-
});
|
|
3381
|
-
});
|
|
3382
|
-
await this.server.start();
|
|
3383
|
-
console.log(`[worker] HTTP server listening on port ${this.workerConfig.worker_port}`);
|
|
3384
|
-
const memoryOk = await this.memory.healthCheck();
|
|
3385
|
-
if (memoryOk) {
|
|
3386
|
-
console.log("[worker] Local memory daemon connected");
|
|
3387
|
-
} else {
|
|
3388
|
-
console.warn("[worker] Memory daemon unreachable at", this.config.memory.daemon_url);
|
|
3389
|
-
console.warn("[worker] Continuing \u2014 episodes will not be stored until daemon is available");
|
|
3390
|
-
}
|
|
3391
|
-
await this.registerWithPrimary();
|
|
3392
|
-
this.startTaskLoop();
|
|
3393
|
-
this.startStatusReporting();
|
|
3394
|
-
console.log("[worker] Ready \u2014 waiting for context assignments");
|
|
3395
|
-
}
|
|
3396
|
-
/**
|
|
3397
|
-
* Stop the worker gracefully.
|
|
3398
|
-
*/
|
|
3399
|
-
async stop() {
|
|
3400
|
-
this.running = false;
|
|
3401
|
-
if (this.taskPollTimer) {
|
|
3402
|
-
clearInterval(this.taskPollTimer);
|
|
3403
|
-
this.taskPollTimer = null;
|
|
3404
|
-
}
|
|
3405
|
-
if (this.statusReportTimer) {
|
|
3406
|
-
clearInterval(this.statusReportTimer);
|
|
3407
|
-
this.statusReportTimer = null;
|
|
3408
|
-
}
|
|
3409
|
-
await this.server.stop();
|
|
3410
|
-
console.log("[worker] Stopped");
|
|
3411
|
-
}
|
|
3412
|
-
/**
|
|
3413
|
-
* Register this worker with the Primary node.
|
|
3414
|
-
*/
|
|
3415
|
-
async registerWithPrimary() {
|
|
3416
|
-
const workerUrl = `http://localhost:${this.workerConfig.worker_port}`;
|
|
3417
|
-
const registration = {
|
|
3418
|
-
url: workerUrl,
|
|
3419
|
-
capabilities: {
|
|
3420
|
-
max_contexts: this.workerConfig.max_contexts,
|
|
3421
|
-
has_ollama: true,
|
|
3422
|
-
has_memory_daemon: true,
|
|
3423
|
-
available_models: [this.config.memory.embedding_model]
|
|
3424
|
-
}
|
|
3425
|
-
};
|
|
3426
|
-
try {
|
|
3427
|
-
const resp = await fetch(
|
|
3428
|
-
`${this.workerConfig.primary_url}${PRIMARY_ROUTES.register}`,
|
|
3429
|
-
{
|
|
3430
|
-
method: "POST",
|
|
3431
|
-
headers: { "Content-Type": "application/json" },
|
|
3432
|
-
body: JSON.stringify(registration)
|
|
3433
|
-
}
|
|
3434
|
-
);
|
|
3435
|
-
if (!resp.ok) {
|
|
3436
|
-
console.error(`[worker] Registration failed: ${resp.status} ${await resp.text()}`);
|
|
3437
|
-
return null;
|
|
3438
|
-
}
|
|
3439
|
-
const result = await resp.json();
|
|
3440
|
-
this.registeredWorkerId = result.worker_id;
|
|
3441
|
-
console.log(`[worker] Registered with Primary as ${result.worker_id}`);
|
|
3442
|
-
return result;
|
|
3443
|
-
} catch (err) {
|
|
3444
|
-
console.error("[worker] Could not reach Primary at", this.workerConfig.primary_url);
|
|
3445
|
-
console.error("[worker] Will continue in standalone mode \u2014 retry registration manually");
|
|
3446
|
-
return null;
|
|
3447
|
-
}
|
|
3448
|
-
}
|
|
3449
|
-
/**
|
|
3450
|
-
* Start the task execution polling loop.
|
|
3451
|
-
* Iterates assigned contexts and picks up tasks from each queue.
|
|
3452
|
-
*/
|
|
3453
|
-
startTaskLoop() {
|
|
3454
|
-
this.taskPollTimer = setInterval(() => {
|
|
3455
|
-
if (!this.running || this.executing) return;
|
|
3456
|
-
this.executeNextTask().catch((err) => {
|
|
3457
|
-
console.error("[worker] Task execution error:", err.message);
|
|
3458
|
-
});
|
|
3459
|
-
}, this.workerConfig.task_poll_interval_ms);
|
|
3460
|
-
}
|
|
3461
|
-
/**
|
|
3462
|
-
* Find and execute the next available task across all assigned contexts.
|
|
3463
|
-
*/
|
|
3464
|
-
async executeNextTask() {
|
|
3465
|
-
const contexts = this.server.getAssignedContexts();
|
|
3466
|
-
if (contexts.length === 0) return;
|
|
3467
|
-
for (const contextName of contexts) {
|
|
3468
|
-
const engine = new TaskEngine({ contextName, memory: this.memory });
|
|
3469
|
-
const task = await engine.getNextTask();
|
|
3470
|
-
if (task) {
|
|
3471
|
-
this.executing = true;
|
|
3472
|
-
try {
|
|
3473
|
-
this.server.setActiveContext(contextName);
|
|
3474
|
-
this.server.setCurrentTask(task.id);
|
|
3475
|
-
console.log(`[worker] Executing task [${task.id.slice(0, 8)}] "${task.title}" in context "${contextName}"`);
|
|
3476
|
-
await engine.startTask(task.id);
|
|
3477
|
-
this.agent.setContext(contextName);
|
|
3478
|
-
try {
|
|
3479
|
-
await this.memory.createContext(contextName);
|
|
3480
|
-
} catch {
|
|
3481
|
-
}
|
|
3482
|
-
const taskPrompt = buildTaskPrompt(task.title, task.description);
|
|
3483
|
-
const response = await this.agent.processMessage(taskPrompt);
|
|
3484
|
-
console.log(`[worker] Task [${task.id.slice(0, 8)}] completed. Response: ${response.content.slice(0, 100)}...`);
|
|
3485
|
-
await engine.completeTask(task.id);
|
|
3486
|
-
await this.reportStatus("working", contextName, task.id);
|
|
3487
|
-
} catch (err) {
|
|
3488
|
-
console.error(`[worker] Task [${task.id.slice(0, 8)}] failed:`, err.message);
|
|
3489
|
-
await this.reportStatus("error", contextName, task.id, err.message);
|
|
3490
|
-
} finally {
|
|
3491
|
-
this.executing = false;
|
|
3492
|
-
this.server.setCurrentTask(null);
|
|
3493
|
-
}
|
|
3494
|
-
return;
|
|
3495
|
-
}
|
|
3496
|
-
}
|
|
3497
|
-
if (this.server.getAssignedContexts().length > 0) {
|
|
3498
|
-
this.server.setActiveContext(null);
|
|
3499
|
-
this.server.setCurrentTask(null);
|
|
3500
|
-
}
|
|
3501
|
-
}
|
|
3502
|
-
/**
|
|
3503
|
-
* Periodically report status back to Primary.
|
|
3504
|
-
*/
|
|
3505
|
-
startStatusReporting() {
|
|
3506
|
-
this.statusReportTimer = setInterval(() => {
|
|
3507
|
-
if (!this.running || !this.registeredWorkerId) return;
|
|
3508
|
-
const contexts = this.server.getAssignedContexts();
|
|
3509
|
-
if (contexts.length === 0) return;
|
|
3510
|
-
this.reportStatus(
|
|
3511
|
-
this.executing ? "working" : "idle",
|
|
3512
|
-
this.executing ? contexts[0] : null,
|
|
3513
|
-
null
|
|
3514
|
-
).catch(() => {
|
|
3515
|
-
});
|
|
3516
|
-
}, this.workerConfig.status_report_interval_ms);
|
|
3517
|
-
}
|
|
3518
|
-
/**
|
|
3519
|
-
* Send a status report to the Primary.
|
|
3520
|
-
*/
|
|
3521
|
-
async reportStatus(activity, currentContext, currentTask, error) {
|
|
3522
|
-
if (!this.registeredWorkerId) return;
|
|
3523
|
-
const report = {
|
|
3524
|
-
activity,
|
|
3525
|
-
current_context: currentContext,
|
|
3526
|
-
current_task: currentTask,
|
|
3527
|
-
error
|
|
3528
|
-
};
|
|
3529
|
-
try {
|
|
3530
|
-
const statusUrl = `${this.workerConfig.primary_url}${PRIMARY_ROUTES.status(this.registeredWorkerId)}`;
|
|
3531
|
-
await fetch(statusUrl, {
|
|
3532
|
-
method: "POST",
|
|
3533
|
-
headers: { "Content-Type": "application/json" },
|
|
3534
|
-
body: JSON.stringify(report)
|
|
3535
|
-
});
|
|
3536
|
-
} catch {
|
|
3537
|
-
}
|
|
3538
|
-
}
|
|
3539
|
-
// --- Accessors for testing ---
|
|
3540
|
-
getServer() {
|
|
3541
|
-
return this.server;
|
|
3542
|
-
}
|
|
3543
|
-
getAgent() {
|
|
3544
|
-
return this.agent;
|
|
3545
|
-
}
|
|
3546
|
-
getMemoryClient() {
|
|
3547
|
-
return this.memory;
|
|
3548
|
-
}
|
|
3549
|
-
isRunning() {
|
|
3550
|
-
return this.running;
|
|
3551
|
-
}
|
|
3552
|
-
isExecuting() {
|
|
3553
|
-
return this.executing;
|
|
3554
|
-
}
|
|
3555
|
-
getRegisteredWorkerId() {
|
|
3556
|
-
return this.registeredWorkerId;
|
|
3557
|
-
}
|
|
3558
|
-
};
|
|
3559
|
-
function buildTaskPrompt(title, description) {
|
|
3560
|
-
let prompt = `[TASK] ${title}`;
|
|
3561
|
-
if (description) {
|
|
3562
|
-
prompt += `
|
|
3563
|
-
|
|
3564
|
-
${description}`;
|
|
3565
|
-
}
|
|
3566
|
-
prompt += "\n\nPlease work on this task. Use your memory and knowledge to provide a thorough response.";
|
|
3567
|
-
return prompt;
|
|
3568
|
-
}
|
|
3569
|
-
async function startWorker(config) {
|
|
3570
|
-
if (!config.worker || !config.worker.enabled) {
|
|
3571
|
-
throw new Error("Worker mode is not enabled in config. Set [worker] enabled = true.");
|
|
3572
|
-
}
|
|
3573
|
-
const runtime = new WorkerRuntime({
|
|
3574
|
-
config,
|
|
3575
|
-
workerConfig: config.worker
|
|
3576
|
-
});
|
|
3577
|
-
await runtime.start();
|
|
3578
|
-
return runtime;
|
|
3579
|
-
}
|
|
3580
|
-
|
|
3581
|
-
export {
|
|
3582
|
-
LLMClient,
|
|
3583
|
-
MemoryClient,
|
|
3584
|
-
ContextManager,
|
|
3585
|
-
TaskEngine,
|
|
3586
|
-
buildSystemPrompt,
|
|
3587
|
-
buildMessages,
|
|
3588
|
-
Agent,
|
|
3589
|
-
loadConfig,
|
|
3590
|
-
SesameClient2 as SesameClient,
|
|
3591
|
-
startPipeline,
|
|
3592
|
-
PRIMARY_ROUTES,
|
|
3593
|
-
WORKER_ROUTES,
|
|
3594
|
-
DEFAULT_HEALTH_INTERVAL_MS,
|
|
3595
|
-
HEALTH_TIMEOUT_MS,
|
|
3596
|
-
DEFAULT_SYNC_INTERVAL_MS,
|
|
3597
|
-
WorkerServer,
|
|
3598
|
-
WorkerRuntime,
|
|
3599
|
-
startWorker
|
|
3600
|
-
};
|
|
3601
|
-
//# sourceMappingURL=chunk-LRK64BAK.js.map
|