@elizaos/plugin-trajectory-logger 2.0.0-alpha.11 → 2.0.0-alpha.13

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.
@@ -1,3064 +1,193 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, {
5
- get: all[name],
6
- enumerable: true,
7
- configurable: true,
8
- set: (newValue) => all[name] = () => newValue
9
- });
10
- };
11
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
12
-
13
- // ../node_modules/drizzle-orm/entity.js
14
- function is(value, type) {
15
- if (!value || typeof value !== "object") {
16
- return false;
17
- }
18
- if (value instanceof type) {
19
- return true;
20
- }
21
- if (!Object.prototype.hasOwnProperty.call(type, entityKind)) {
22
- throw new Error(`Class "${type.name ?? "<unknown>"}" doesn't look like a Drizzle entity. If this is incorrect and the class is provided by Drizzle, please report this as a bug.`);
23
- }
24
- let cls = Object.getPrototypeOf(value).constructor;
25
- if (cls) {
26
- while (cls) {
27
- if (entityKind in cls && cls[entityKind] === type[entityKind]) {
28
- return true;
29
- }
30
- cls = Object.getPrototypeOf(cls);
31
- }
32
- }
33
- return false;
34
- }
35
- var entityKind, hasOwnEntityKind;
36
- var init_entity = __esm(() => {
37
- entityKind = Symbol.for("drizzle:entityKind");
38
- hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
39
- });
40
-
41
- // ../node_modules/drizzle-orm/column.js
42
- var Column;
43
- var init_column = __esm(() => {
44
- init_entity();
45
- Column = class Column {
46
- constructor(table, config) {
47
- this.table = table;
48
- this.config = config;
49
- this.name = config.name;
50
- this.keyAsName = config.keyAsName;
51
- this.notNull = config.notNull;
52
- this.default = config.default;
53
- this.defaultFn = config.defaultFn;
54
- this.onUpdateFn = config.onUpdateFn;
55
- this.hasDefault = config.hasDefault;
56
- this.primary = config.primaryKey;
57
- this.isUnique = config.isUnique;
58
- this.uniqueName = config.uniqueName;
59
- this.uniqueType = config.uniqueType;
60
- this.dataType = config.dataType;
61
- this.columnType = config.columnType;
62
- this.generated = config.generated;
63
- this.generatedIdentity = config.generatedIdentity;
64
- }
65
- static [entityKind] = "Column";
66
- name;
67
- keyAsName;
68
- primary;
69
- notNull;
70
- default;
71
- defaultFn;
72
- onUpdateFn;
73
- hasDefault;
74
- isUnique;
75
- uniqueName;
76
- uniqueType;
77
- dataType;
78
- columnType;
79
- enumValues = undefined;
80
- generated = undefined;
81
- generatedIdentity = undefined;
82
- config;
83
- mapFromDriverValue(value) {
84
- return value;
85
- }
86
- mapToDriverValue(value) {
87
- return value;
88
- }
89
- shouldDisableInsert() {
90
- return this.config.generated !== undefined && this.config.generated.type !== "byDefault";
91
- }
92
- };
93
- });
94
-
95
- // ../node_modules/drizzle-orm/column-builder.js
96
- var ColumnBuilder;
97
- var init_column_builder = __esm(() => {
98
- init_entity();
99
- ColumnBuilder = class ColumnBuilder {
100
- static [entityKind] = "ColumnBuilder";
101
- config;
102
- constructor(name, dataType, columnType) {
103
- this.config = {
104
- name,
105
- keyAsName: name === "",
106
- notNull: false,
107
- default: undefined,
108
- hasDefault: false,
109
- primaryKey: false,
110
- isUnique: false,
111
- uniqueName: undefined,
112
- uniqueType: undefined,
113
- dataType,
114
- columnType,
115
- generated: undefined
116
- };
117
- }
118
- $type() {
119
- return this;
120
- }
121
- notNull() {
122
- this.config.notNull = true;
123
- return this;
124
- }
125
- default(value) {
126
- this.config.default = value;
127
- this.config.hasDefault = true;
128
- return this;
129
- }
130
- $defaultFn(fn) {
131
- this.config.defaultFn = fn;
132
- this.config.hasDefault = true;
133
- return this;
134
- }
135
- $default = this.$defaultFn;
136
- $onUpdateFn(fn) {
137
- this.config.onUpdateFn = fn;
138
- this.config.hasDefault = true;
139
- return this;
140
- }
141
- $onUpdate = this.$onUpdateFn;
142
- primaryKey() {
143
- this.config.primaryKey = true;
144
- this.config.notNull = true;
145
- return this;
146
- }
147
- setName(name) {
148
- if (this.config.name !== "")
149
- return;
150
- this.config.name = name;
151
- }
152
- };
153
- });
154
-
155
- // ../node_modules/drizzle-orm/table.utils.js
156
- var TableName;
157
- var init_table_utils = __esm(() => {
158
- TableName = Symbol.for("drizzle:Name");
159
- });
160
-
161
- // ../node_modules/drizzle-orm/tracing-utils.js
162
- function iife(fn, ...args) {
163
- return fn(...args);
164
- }
165
- var init_tracing_utils = () => {};
166
-
167
- // ../node_modules/drizzle-orm/pg-core/unique-constraint.js
168
- function uniqueKeyName(table, columns) {
169
- return `${table[TableName]}_${columns.join("_")}_unique`;
170
- }
171
- var init_unique_constraint = __esm(() => {
172
- init_table_utils();
173
- });
174
-
175
- // ../node_modules/drizzle-orm/pg-core/columns/common.js
176
- var PgColumn, ExtraConfigColumn;
177
- var init_common = __esm(() => {
178
- init_column();
179
- init_entity();
180
- init_unique_constraint();
181
- PgColumn = class PgColumn extends Column {
182
- constructor(table, config) {
183
- if (!config.uniqueName) {
184
- config.uniqueName = uniqueKeyName(table, [config.name]);
185
- }
186
- super(table, config);
187
- this.table = table;
188
- }
189
- static [entityKind] = "PgColumn";
190
- };
191
- ExtraConfigColumn = class ExtraConfigColumn extends PgColumn {
192
- static [entityKind] = "ExtraConfigColumn";
193
- getSQLType() {
194
- return this.getSQLType();
195
- }
196
- indexConfig = {
197
- order: this.config.order ?? "asc",
198
- nulls: this.config.nulls ?? "last",
199
- opClass: this.config.opClass
200
- };
201
- defaultConfig = {
202
- order: "asc",
203
- nulls: "last",
204
- opClass: undefined
205
- };
206
- asc() {
207
- this.indexConfig.order = "asc";
208
- return this;
209
- }
210
- desc() {
211
- this.indexConfig.order = "desc";
212
- return this;
213
- }
214
- nullsFirst() {
215
- this.indexConfig.nulls = "first";
216
- return this;
217
- }
218
- nullsLast() {
219
- this.indexConfig.nulls = "last";
220
- return this;
221
- }
222
- op(opClass) {
223
- this.indexConfig.opClass = opClass;
224
- return this;
225
- }
226
- };
227
- });
228
-
229
- // ../node_modules/drizzle-orm/pg-core/columns/enum.js
230
- function isPgEnum(obj) {
231
- return !!obj && typeof obj === "function" && isPgEnumSym in obj && obj[isPgEnumSym] === true;
232
- }
233
- var PgEnumObjectColumn, isPgEnumSym, PgEnumColumn;
234
- var init_enum = __esm(() => {
235
- init_entity();
236
- init_common();
237
- PgEnumObjectColumn = class PgEnumObjectColumn extends PgColumn {
238
- static [entityKind] = "PgEnumObjectColumn";
239
- enum;
240
- enumValues = this.config.enum.enumValues;
241
- constructor(table, config) {
242
- super(table, config);
243
- this.enum = config.enum;
244
- }
245
- getSQLType() {
246
- return this.enum.enumName;
247
- }
248
- };
249
- isPgEnumSym = Symbol.for("drizzle:isPgEnum");
250
- PgEnumColumn = class PgEnumColumn extends PgColumn {
251
- static [entityKind] = "PgEnumColumn";
252
- enum = this.config.enum;
253
- enumValues = this.config.enum.enumValues;
254
- constructor(table, config) {
255
- super(table, config);
256
- this.enum = config.enum;
257
- }
258
- getSQLType() {
259
- return this.enum.enumName;
260
- }
261
- };
262
- });
263
-
264
- // ../node_modules/drizzle-orm/subquery.js
265
- var Subquery, WithSubquery;
266
- var init_subquery = __esm(() => {
267
- init_entity();
268
- Subquery = class Subquery {
269
- static [entityKind] = "Subquery";
270
- constructor(sql, fields, alias, isWith = false, usedTables = []) {
271
- this._ = {
272
- brand: "Subquery",
273
- sql,
274
- selectedFields: fields,
275
- alias,
276
- isWith,
277
- usedTables
278
- };
279
- }
280
- };
281
- WithSubquery = class WithSubquery extends Subquery {
282
- static [entityKind] = "WithSubquery";
283
- };
284
- });
285
-
286
- // ../node_modules/drizzle-orm/version.js
287
- var version = "0.45.1";
288
- var init_version = () => {};
289
-
290
- // ../node_modules/drizzle-orm/tracing.js
291
- var otel, rawTracer, tracer;
292
- var init_tracing = __esm(() => {
293
- init_tracing_utils();
294
- init_version();
295
- tracer = {
296
- startActiveSpan(name, fn) {
297
- if (!otel) {
298
- return fn();
299
- }
300
- if (!rawTracer) {
301
- rawTracer = otel.trace.getTracer("drizzle-orm", version);
302
- }
303
- return iife((otel2, rawTracer2) => rawTracer2.startActiveSpan(name, (span) => {
304
- try {
305
- return fn(span);
306
- } catch (e) {
307
- span.setStatus({
308
- code: otel2.SpanStatusCode.ERROR,
309
- message: e instanceof Error ? e.message : "Unknown error"
310
- });
311
- throw e;
312
- } finally {
313
- span.end();
314
- }
315
- }), otel, rawTracer);
316
- }
317
- };
318
- });
319
-
320
- // ../node_modules/drizzle-orm/view-common.js
321
- var ViewBaseConfig;
322
- var init_view_common = __esm(() => {
323
- ViewBaseConfig = Symbol.for("drizzle:ViewBaseConfig");
324
- });
325
-
326
- // ../node_modules/drizzle-orm/table.js
327
- function isTable(table) {
328
- return typeof table === "object" && table !== null && IsDrizzleTable in table;
329
- }
330
- function getTableName(table) {
331
- return table[TableName];
332
- }
333
- function getTableUniqueName(table) {
334
- return `${table[Schema] ?? "public"}.${table[TableName]}`;
335
- }
336
- var Schema, Columns, ExtraConfigColumns, OriginalName, BaseName, IsAlias, ExtraConfigBuilder, IsDrizzleTable, Table;
337
- var init_table = __esm(() => {
338
- init_entity();
339
- init_table_utils();
340
- Schema = Symbol.for("drizzle:Schema");
341
- Columns = Symbol.for("drizzle:Columns");
342
- ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
343
- OriginalName = Symbol.for("drizzle:OriginalName");
344
- BaseName = Symbol.for("drizzle:BaseName");
345
- IsAlias = Symbol.for("drizzle:IsAlias");
346
- ExtraConfigBuilder = Symbol.for("drizzle:ExtraConfigBuilder");
347
- IsDrizzleTable = Symbol.for("drizzle:IsDrizzleTable");
348
- Table = class Table {
349
- static [entityKind] = "Table";
350
- static Symbol = {
351
- Name: TableName,
352
- Schema,
353
- OriginalName,
354
- Columns,
355
- ExtraConfigColumns,
356
- BaseName,
357
- IsAlias,
358
- ExtraConfigBuilder
359
- };
360
- [TableName];
361
- [OriginalName];
362
- [Schema];
363
- [Columns];
364
- [ExtraConfigColumns];
365
- [BaseName];
366
- [IsAlias] = false;
367
- [IsDrizzleTable] = true;
368
- [ExtraConfigBuilder] = undefined;
369
- constructor(name, schema, baseName) {
370
- this[TableName] = this[OriginalName] = name;
371
- this[Schema] = schema;
372
- this[BaseName] = baseName;
373
- }
374
- };
375
- });
376
-
377
- // ../node_modules/drizzle-orm/sql/sql.js
378
- function isSQLWrapper(value) {
379
- return value !== null && value !== undefined && typeof value.getSQL === "function";
380
- }
381
- function mergeQueries(queries) {
382
- const result = { sql: "", params: [] };
383
- for (const query of queries) {
384
- result.sql += query.sql;
385
- result.params.push(...query.params);
386
- if (query.typings?.length) {
387
- if (!result.typings) {
388
- result.typings = [];
389
- }
390
- result.typings.push(...query.typings);
391
- }
392
- }
393
- return result;
394
- }
395
- function name(value) {
396
- return new Name(value);
397
- }
398
- function isDriverValueEncoder(value) {
399
- return typeof value === "object" && value !== null && "mapToDriverValue" in value && typeof value.mapToDriverValue === "function";
400
- }
401
- function param(value, encoder) {
402
- return new Param(value, encoder);
403
- }
404
- function sql(strings, ...params) {
405
- const queryChunks = [];
406
- if (params.length > 0 || strings.length > 0 && strings[0] !== "") {
407
- queryChunks.push(new StringChunk(strings[0]));
408
- }
409
- for (const [paramIndex, param2] of params.entries()) {
410
- queryChunks.push(param2, new StringChunk(strings[paramIndex + 1]));
411
- }
412
- return new SQL(queryChunks);
413
- }
414
- function placeholder(name2) {
415
- return new Placeholder(name2);
416
- }
417
- function fillPlaceholders(params, values) {
418
- return params.map((p) => {
419
- if (is(p, Placeholder)) {
420
- if (!(p.name in values)) {
421
- throw new Error(`No value for placeholder "${p.name}" was provided`);
422
- }
423
- return values[p.name];
424
- }
425
- if (is(p, Param) && is(p.value, Placeholder)) {
426
- if (!(p.value.name in values)) {
427
- throw new Error(`No value for placeholder "${p.value.name}" was provided`);
428
- }
429
- return p.encoder.mapToDriverValue(values[p.value.name]);
430
- }
431
- return p;
432
- });
433
- }
434
- function isView(view) {
435
- return typeof view === "object" && view !== null && IsDrizzleView in view;
436
- }
437
- function getViewName(view) {
438
- return view[ViewBaseConfig].name;
439
- }
440
- var FakePrimitiveParam, StringChunk, SQL, Name, noopDecoder, noopEncoder, noopMapper, Param, Placeholder, IsDrizzleView, View;
441
- var init_sql = __esm(() => {
442
- init_entity();
443
- init_enum();
444
- init_subquery();
445
- init_tracing();
446
- init_view_common();
447
- init_column();
448
- init_table();
449
- FakePrimitiveParam = class FakePrimitiveParam {
450
- static [entityKind] = "FakePrimitiveParam";
451
- };
452
- StringChunk = class StringChunk {
453
- static [entityKind] = "StringChunk";
454
- value;
455
- constructor(value) {
456
- this.value = Array.isArray(value) ? value : [value];
457
- }
458
- getSQL() {
459
- return new SQL([this]);
460
- }
461
- };
462
- SQL = class SQL {
463
- constructor(queryChunks) {
464
- this.queryChunks = queryChunks;
465
- for (const chunk of queryChunks) {
466
- if (is(chunk, Table)) {
467
- const schemaName = chunk[Table.Symbol.Schema];
468
- this.usedTables.push(schemaName === undefined ? chunk[Table.Symbol.Name] : schemaName + "." + chunk[Table.Symbol.Name]);
469
- }
470
- }
471
- }
472
- static [entityKind] = "SQL";
473
- decoder = noopDecoder;
474
- shouldInlineParams = false;
475
- usedTables = [];
476
- append(query) {
477
- this.queryChunks.push(...query.queryChunks);
478
- return this;
479
- }
480
- toQuery(config) {
481
- return tracer.startActiveSpan("drizzle.buildSQL", (span) => {
482
- const query = this.buildQueryFromSourceParams(this.queryChunks, config);
483
- span?.setAttributes({
484
- "drizzle.query.text": query.sql,
485
- "drizzle.query.params": JSON.stringify(query.params)
486
- });
487
- return query;
488
- });
489
- }
490
- buildQueryFromSourceParams(chunks, _config) {
491
- const config = Object.assign({}, _config, {
492
- inlineParams: _config.inlineParams || this.shouldInlineParams,
493
- paramStartIndex: _config.paramStartIndex || { value: 0 }
494
- });
495
- const {
496
- casing,
497
- escapeName,
498
- escapeParam,
499
- prepareTyping,
500
- inlineParams,
501
- paramStartIndex
502
- } = config;
503
- return mergeQueries(chunks.map((chunk) => {
504
- if (is(chunk, StringChunk)) {
505
- return { sql: chunk.value.join(""), params: [] };
506
- }
507
- if (is(chunk, Name)) {
508
- return { sql: escapeName(chunk.value), params: [] };
509
- }
510
- if (chunk === undefined) {
511
- return { sql: "", params: [] };
512
- }
513
- if (Array.isArray(chunk)) {
514
- const result = [new StringChunk("(")];
515
- for (const [i, p] of chunk.entries()) {
516
- result.push(p);
517
- if (i < chunk.length - 1) {
518
- result.push(new StringChunk(", "));
519
- }
520
- }
521
- result.push(new StringChunk(")"));
522
- return this.buildQueryFromSourceParams(result, config);
523
- }
524
- if (is(chunk, SQL)) {
525
- return this.buildQueryFromSourceParams(chunk.queryChunks, {
526
- ...config,
527
- inlineParams: inlineParams || chunk.shouldInlineParams
528
- });
529
- }
530
- if (is(chunk, Table)) {
531
- const schemaName = chunk[Table.Symbol.Schema];
532
- const tableName = chunk[Table.Symbol.Name];
533
- return {
534
- sql: schemaName === undefined || chunk[IsAlias] ? escapeName(tableName) : escapeName(schemaName) + "." + escapeName(tableName),
535
- params: []
536
- };
537
- }
538
- if (is(chunk, Column)) {
539
- const columnName = casing.getColumnCasing(chunk);
540
- if (_config.invokeSource === "indexes") {
541
- return { sql: escapeName(columnName), params: [] };
542
- }
543
- const schemaName = chunk.table[Table.Symbol.Schema];
544
- return {
545
- sql: chunk.table[IsAlias] || schemaName === undefined ? escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName) : escapeName(schemaName) + "." + escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName),
546
- params: []
547
- };
548
- }
549
- if (is(chunk, View)) {
550
- const schemaName = chunk[ViewBaseConfig].schema;
551
- const viewName = chunk[ViewBaseConfig].name;
552
- return {
553
- sql: schemaName === undefined || chunk[ViewBaseConfig].isAlias ? escapeName(viewName) : escapeName(schemaName) + "." + escapeName(viewName),
554
- params: []
555
- };
556
- }
557
- if (is(chunk, Param)) {
558
- if (is(chunk.value, Placeholder)) {
559
- return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
560
- }
561
- const mappedValue = chunk.value === null ? null : chunk.encoder.mapToDriverValue(chunk.value);
562
- if (is(mappedValue, SQL)) {
563
- return this.buildQueryFromSourceParams([mappedValue], config);
564
- }
565
- if (inlineParams) {
566
- return { sql: this.mapInlineParam(mappedValue, config), params: [] };
567
- }
568
- let typings = ["none"];
569
- if (prepareTyping) {
570
- typings = [prepareTyping(chunk.encoder)];
571
- }
572
- return { sql: escapeParam(paramStartIndex.value++, mappedValue), params: [mappedValue], typings };
573
- }
574
- if (is(chunk, Placeholder)) {
575
- return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
576
- }
577
- if (is(chunk, SQL.Aliased) && chunk.fieldAlias !== undefined) {
578
- return { sql: escapeName(chunk.fieldAlias), params: [] };
579
- }
580
- if (is(chunk, Subquery)) {
581
- if (chunk._.isWith) {
582
- return { sql: escapeName(chunk._.alias), params: [] };
583
- }
584
- return this.buildQueryFromSourceParams([
585
- new StringChunk("("),
586
- chunk._.sql,
587
- new StringChunk(") "),
588
- new Name(chunk._.alias)
589
- ], config);
590
- }
591
- if (isPgEnum(chunk)) {
592
- if (chunk.schema) {
593
- return { sql: escapeName(chunk.schema) + "." + escapeName(chunk.enumName), params: [] };
594
- }
595
- return { sql: escapeName(chunk.enumName), params: [] };
596
- }
597
- if (isSQLWrapper(chunk)) {
598
- if (chunk.shouldOmitSQLParens?.()) {
599
- return this.buildQueryFromSourceParams([chunk.getSQL()], config);
600
- }
601
- return this.buildQueryFromSourceParams([
602
- new StringChunk("("),
603
- chunk.getSQL(),
604
- new StringChunk(")")
605
- ], config);
606
- }
607
- if (inlineParams) {
608
- return { sql: this.mapInlineParam(chunk, config), params: [] };
609
- }
610
- return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
611
- }));
612
- }
613
- mapInlineParam(chunk, { escapeString }) {
614
- if (chunk === null) {
615
- return "null";
616
- }
617
- if (typeof chunk === "number" || typeof chunk === "boolean") {
618
- return chunk.toString();
619
- }
620
- if (typeof chunk === "string") {
621
- return escapeString(chunk);
622
- }
623
- if (typeof chunk === "object") {
624
- const mappedValueAsString = chunk.toString();
625
- if (mappedValueAsString === "[object Object]") {
626
- return escapeString(JSON.stringify(chunk));
627
- }
628
- return escapeString(mappedValueAsString);
629
- }
630
- throw new Error("Unexpected param value: " + chunk);
631
- }
632
- getSQL() {
633
- return this;
634
- }
635
- as(alias) {
636
- if (alias === undefined) {
637
- return this;
638
- }
639
- return new SQL.Aliased(this, alias);
640
- }
641
- mapWith(decoder) {
642
- this.decoder = typeof decoder === "function" ? { mapFromDriverValue: decoder } : decoder;
643
- return this;
644
- }
645
- inlineParams() {
646
- this.shouldInlineParams = true;
647
- return this;
648
- }
649
- if(condition) {
650
- return condition ? this : undefined;
651
- }
652
- };
653
- Name = class Name {
654
- constructor(value) {
655
- this.value = value;
656
- }
657
- static [entityKind] = "Name";
658
- brand;
659
- getSQL() {
660
- return new SQL([this]);
661
- }
662
- };
663
- noopDecoder = {
664
- mapFromDriverValue: (value) => value
665
- };
666
- noopEncoder = {
667
- mapToDriverValue: (value) => value
668
- };
669
- noopMapper = {
670
- ...noopDecoder,
671
- ...noopEncoder
672
- };
673
- Param = class Param {
674
- constructor(value, encoder = noopEncoder) {
675
- this.value = value;
676
- this.encoder = encoder;
677
- }
678
- static [entityKind] = "Param";
679
- brand;
680
- getSQL() {
681
- return new SQL([this]);
682
- }
683
- };
684
- ((sql2) => {
685
- function empty() {
686
- return new SQL([]);
687
- }
688
- sql2.empty = empty;
689
- function fromList(list) {
690
- return new SQL(list);
691
- }
692
- sql2.fromList = fromList;
693
- function raw(str) {
694
- return new SQL([new StringChunk(str)]);
695
- }
696
- sql2.raw = raw;
697
- function join(chunks, separator) {
698
- const result = [];
699
- for (const [i, chunk] of chunks.entries()) {
700
- if (i > 0 && separator !== undefined) {
701
- result.push(separator);
702
- }
703
- result.push(chunk);
704
- }
705
- return new SQL(result);
706
- }
707
- sql2.join = join;
708
- function identifier(value) {
709
- return new Name(value);
710
- }
711
- sql2.identifier = identifier;
712
- function placeholder2(name2) {
713
- return new Placeholder(name2);
714
- }
715
- sql2.placeholder = placeholder2;
716
- function param2(value, encoder) {
717
- return new Param(value, encoder);
718
- }
719
- sql2.param = param2;
720
- })(sql || (sql = {}));
721
- ((SQL2) => {
722
-
723
- class Aliased {
724
- constructor(sql2, fieldAlias) {
725
- this.sql = sql2;
726
- this.fieldAlias = fieldAlias;
727
- }
728
- static [entityKind] = "SQL.Aliased";
729
- isSelectionField = false;
730
- getSQL() {
731
- return this.sql;
732
- }
733
- clone() {
734
- return new Aliased(this.sql, this.fieldAlias);
735
- }
736
- }
737
- SQL2.Aliased = Aliased;
738
- })(SQL || (SQL = {}));
739
- Placeholder = class Placeholder {
740
- constructor(name2) {
741
- this.name = name2;
742
- }
743
- static [entityKind] = "Placeholder";
744
- getSQL() {
745
- return new SQL([this]);
746
- }
747
- };
748
- IsDrizzleView = Symbol.for("drizzle:IsDrizzleView");
749
- View = class View {
750
- static [entityKind] = "View";
751
- [ViewBaseConfig];
752
- [IsDrizzleView] = true;
753
- constructor({ name: name2, schema, selectedFields, query }) {
754
- this[ViewBaseConfig] = {
755
- name: name2,
756
- originalName: name2,
757
- schema,
758
- selectedFields,
759
- query,
760
- isExisting: !query,
761
- isAlias: false
762
- };
763
- }
764
- getSQL() {
765
- return new SQL([this]);
766
- }
767
- };
768
- Column.prototype.getSQL = function() {
769
- return new SQL([this]);
770
- };
771
- Table.prototype.getSQL = function() {
772
- return new SQL([this]);
773
- };
774
- Subquery.prototype.getSQL = function() {
775
- return new SQL([this]);
776
- };
777
- });
778
-
779
- // ../node_modules/drizzle-orm/alias.js
780
- function aliasedTable(table, tableAlias) {
781
- return new Proxy(table, new TableAliasProxyHandler(tableAlias, false));
782
- }
783
- function aliasedRelation(relation, tableAlias) {
784
- return new Proxy(relation, new RelationTableAliasProxyHandler(tableAlias));
785
- }
786
- function aliasedTableColumn(column, tableAlias) {
787
- return new Proxy(column, new ColumnAliasProxyHandler(new Proxy(column.table, new TableAliasProxyHandler(tableAlias, false))));
788
- }
789
- function mapColumnsInAliasedSQLToAlias(query, alias) {
790
- return new SQL.Aliased(mapColumnsInSQLToAlias(query.sql, alias), query.fieldAlias);
791
- }
792
- function mapColumnsInSQLToAlias(query, alias) {
793
- return sql.join(query.queryChunks.map((c) => {
794
- if (is(c, Column)) {
795
- return aliasedTableColumn(c, alias);
796
- }
797
- if (is(c, SQL)) {
798
- return mapColumnsInSQLToAlias(c, alias);
799
- }
800
- if (is(c, SQL.Aliased)) {
801
- return mapColumnsInAliasedSQLToAlias(c, alias);
802
- }
803
- return c;
804
- }));
805
- }
806
- var ColumnAliasProxyHandler, TableAliasProxyHandler, RelationTableAliasProxyHandler;
807
- var init_alias = __esm(() => {
808
- init_column();
809
- init_entity();
810
- init_sql();
811
- init_table();
812
- init_view_common();
813
- ColumnAliasProxyHandler = class ColumnAliasProxyHandler {
814
- constructor(table) {
815
- this.table = table;
816
- }
817
- static [entityKind] = "ColumnAliasProxyHandler";
818
- get(columnObj, prop) {
819
- if (prop === "table") {
820
- return this.table;
821
- }
822
- return columnObj[prop];
823
- }
824
- };
825
- TableAliasProxyHandler = class TableAliasProxyHandler {
826
- constructor(alias, replaceOriginalName) {
827
- this.alias = alias;
828
- this.replaceOriginalName = replaceOriginalName;
829
- }
830
- static [entityKind] = "TableAliasProxyHandler";
831
- get(target, prop) {
832
- if (prop === Table.Symbol.IsAlias) {
833
- return true;
834
- }
835
- if (prop === Table.Symbol.Name) {
836
- return this.alias;
837
- }
838
- if (this.replaceOriginalName && prop === Table.Symbol.OriginalName) {
839
- return this.alias;
840
- }
841
- if (prop === ViewBaseConfig) {
842
- return {
843
- ...target[ViewBaseConfig],
844
- name: this.alias,
845
- isAlias: true
846
- };
847
- }
848
- if (prop === Table.Symbol.Columns) {
849
- const columns = target[Table.Symbol.Columns];
850
- if (!columns) {
851
- return columns;
852
- }
853
- const proxiedColumns = {};
854
- Object.keys(columns).map((key) => {
855
- proxiedColumns[key] = new Proxy(columns[key], new ColumnAliasProxyHandler(new Proxy(target, this)));
856
- });
857
- return proxiedColumns;
858
- }
859
- const value = target[prop];
860
- if (is(value, Column)) {
861
- return new Proxy(value, new ColumnAliasProxyHandler(new Proxy(target, this)));
862
- }
863
- return value;
864
- }
865
- };
866
- RelationTableAliasProxyHandler = class RelationTableAliasProxyHandler {
867
- constructor(alias) {
868
- this.alias = alias;
869
- }
870
- static [entityKind] = "RelationTableAliasProxyHandler";
871
- get(target, prop) {
872
- if (prop === "sourceTable") {
873
- return aliasedTable(target.sourceTable, this.alias);
874
- }
875
- return target[prop];
876
- }
877
- };
878
- });
879
-
880
- // ../node_modules/drizzle-orm/errors.js
881
- var DrizzleError, DrizzleQueryError, TransactionRollbackError;
882
- var init_errors = __esm(() => {
883
- init_entity();
884
- DrizzleError = class DrizzleError extends Error {
885
- static [entityKind] = "DrizzleError";
886
- constructor({ message, cause }) {
887
- super(message);
888
- this.name = "DrizzleError";
889
- this.cause = cause;
890
- }
891
- };
892
- DrizzleQueryError = class DrizzleQueryError extends Error {
893
- constructor(query, params, cause) {
894
- super(`Failed query: ${query}
895
- params: ${params}`);
896
- this.query = query;
897
- this.params = params;
898
- this.cause = cause;
899
- Error.captureStackTrace(this, DrizzleQueryError);
900
- if (cause)
901
- this.cause = cause;
902
- }
903
- };
904
- TransactionRollbackError = class TransactionRollbackError extends DrizzleError {
905
- static [entityKind] = "TransactionRollbackError";
906
- constructor() {
907
- super({ message: "Rollback" });
908
- }
909
- };
910
- });
911
-
912
- // ../node_modules/drizzle-orm/logger.js
913
- var ConsoleLogWriter, DefaultLogger, NoopLogger;
914
- var init_logger = __esm(() => {
915
- init_entity();
916
- ConsoleLogWriter = class ConsoleLogWriter {
917
- static [entityKind] = "ConsoleLogWriter";
918
- write(message) {
919
- console.log(message);
920
- }
921
- };
922
- DefaultLogger = class DefaultLogger {
923
- static [entityKind] = "DefaultLogger";
924
- writer;
925
- constructor(config) {
926
- this.writer = config?.writer ?? new ConsoleLogWriter;
927
- }
928
- logQuery(query, params) {
929
- const stringifiedParams = params.map((p) => {
930
- try {
931
- return JSON.stringify(p);
932
- } catch {
933
- return String(p);
934
- }
935
- });
936
- const paramsStr = stringifiedParams.length ? ` -- params: [${stringifiedParams.join(", ")}]` : "";
937
- this.writer.write(`Query: ${query}${paramsStr}`);
938
- }
939
- };
940
- NoopLogger = class NoopLogger {
941
- static [entityKind] = "NoopLogger";
942
- logQuery() {}
943
- };
944
- });
945
-
946
- // ../node_modules/drizzle-orm/query-promise.js
947
- var QueryPromise;
948
- var init_query_promise = __esm(() => {
949
- init_entity();
950
- QueryPromise = class QueryPromise {
951
- static [entityKind] = "QueryPromise";
952
- [Symbol.toStringTag] = "QueryPromise";
953
- catch(onRejected) {
954
- return this.then(undefined, onRejected);
955
- }
956
- finally(onFinally) {
957
- return this.then((value) => {
958
- onFinally?.();
959
- return value;
960
- }, (reason) => {
961
- onFinally?.();
962
- throw reason;
963
- });
964
- }
965
- then(onFulfilled, onRejected) {
966
- return this.execute().then(onFulfilled, onRejected);
967
- }
968
- };
969
- });
970
-
971
- // ../node_modules/drizzle-orm/utils.js
972
- function mapResultRow(columns, row, joinsNotNullableMap) {
973
- const nullifyMap = {};
974
- const result = columns.reduce((result2, { path, field }, columnIndex) => {
975
- let decoder;
976
- if (is(field, Column)) {
977
- decoder = field;
978
- } else if (is(field, SQL)) {
979
- decoder = field.decoder;
980
- } else if (is(field, Subquery)) {
981
- decoder = field._.sql.decoder;
982
- } else {
983
- decoder = field.sql.decoder;
984
- }
985
- let node = result2;
986
- for (const [pathChunkIndex, pathChunk] of path.entries()) {
987
- if (pathChunkIndex < path.length - 1) {
988
- if (!(pathChunk in node)) {
989
- node[pathChunk] = {};
990
- }
991
- node = node[pathChunk];
992
- } else {
993
- const rawValue = row[columnIndex];
994
- const value = node[pathChunk] = rawValue === null ? null : decoder.mapFromDriverValue(rawValue);
995
- if (joinsNotNullableMap && is(field, Column) && path.length === 2) {
996
- const objectName = path[0];
997
- if (!(objectName in nullifyMap)) {
998
- nullifyMap[objectName] = value === null ? getTableName(field.table) : false;
999
- } else if (typeof nullifyMap[objectName] === "string" && nullifyMap[objectName] !== getTableName(field.table)) {
1000
- nullifyMap[objectName] = false;
1001
- }
1002
- }
1003
- }
1004
- }
1005
- return result2;
1006
- }, {});
1007
- if (joinsNotNullableMap && Object.keys(nullifyMap).length > 0) {
1008
- for (const [objectName, tableName] of Object.entries(nullifyMap)) {
1009
- if (typeof tableName === "string" && !joinsNotNullableMap[tableName]) {
1010
- result[objectName] = null;
1011
- }
1012
- }
1013
- }
1014
- return result;
1015
- }
1016
- function orderSelectedFields(fields, pathPrefix) {
1017
- return Object.entries(fields).reduce((result, [name2, field]) => {
1018
- if (typeof name2 !== "string") {
1019
- return result;
1020
- }
1021
- const newPath = pathPrefix ? [...pathPrefix, name2] : [name2];
1022
- if (is(field, Column) || is(field, SQL) || is(field, SQL.Aliased) || is(field, Subquery)) {
1023
- result.push({ path: newPath, field });
1024
- } else if (is(field, Table)) {
1025
- result.push(...orderSelectedFields(field[Table.Symbol.Columns], newPath));
1026
- } else {
1027
- result.push(...orderSelectedFields(field, newPath));
1028
- }
1029
- return result;
1030
- }, []);
1031
- }
1032
- function haveSameKeys(left, right) {
1033
- const leftKeys = Object.keys(left);
1034
- const rightKeys = Object.keys(right);
1035
- if (leftKeys.length !== rightKeys.length) {
1036
- return false;
1037
- }
1038
- for (const [index, key] of leftKeys.entries()) {
1039
- if (key !== rightKeys[index]) {
1040
- return false;
1041
- }
1042
- }
1043
- return true;
1044
- }
1045
- function mapUpdateSet(table, values) {
1046
- const entries = Object.entries(values).filter(([, value]) => value !== undefined).map(([key, value]) => {
1047
- if (is(value, SQL) || is(value, Column)) {
1048
- return [key, value];
1049
- } else {
1050
- return [key, new Param(value, table[Table.Symbol.Columns][key])];
1051
- }
1052
- });
1053
- if (entries.length === 0) {
1054
- throw new Error("No values to set");
1055
- }
1056
- return Object.fromEntries(entries);
1057
- }
1058
- function applyMixins(baseClass, extendedClasses) {
1059
- for (const extendedClass of extendedClasses) {
1060
- for (const name2 of Object.getOwnPropertyNames(extendedClass.prototype)) {
1061
- if (name2 === "constructor")
1062
- continue;
1063
- Object.defineProperty(baseClass.prototype, name2, Object.getOwnPropertyDescriptor(extendedClass.prototype, name2) || /* @__PURE__ */ Object.create(null));
1064
- }
1065
- }
1066
- }
1067
- function getTableColumns(table) {
1068
- return table[Table.Symbol.Columns];
1069
- }
1070
- function getViewSelectedFields(view) {
1071
- return view[ViewBaseConfig].selectedFields;
1072
- }
1073
- function getTableLikeName(table) {
1074
- return is(table, Subquery) ? table._.alias : is(table, View) ? table[ViewBaseConfig].name : is(table, SQL) ? undefined : table[Table.Symbol.IsAlias] ? table[Table.Symbol.Name] : table[Table.Symbol.BaseName];
1075
- }
1076
- function getColumnNameAndConfig(a, b) {
1077
- return {
1078
- name: typeof a === "string" && a.length > 0 ? a : "",
1079
- config: typeof a === "object" ? a : b
1080
- };
1081
- }
1082
- function isConfig(data) {
1083
- if (typeof data !== "object" || data === null)
1084
- return false;
1085
- if (data.constructor.name !== "Object")
1086
- return false;
1087
- if ("logger" in data) {
1088
- const type = typeof data["logger"];
1089
- if (type !== "boolean" && (type !== "object" || typeof data["logger"]["logQuery"] !== "function") && type !== "undefined")
1090
- return false;
1091
- return true;
1092
- }
1093
- if ("schema" in data) {
1094
- const type = typeof data["schema"];
1095
- if (type !== "object" && type !== "undefined")
1096
- return false;
1097
- return true;
1098
- }
1099
- if ("casing" in data) {
1100
- const type = typeof data["casing"];
1101
- if (type !== "string" && type !== "undefined")
1102
- return false;
1103
- return true;
1104
- }
1105
- if ("mode" in data) {
1106
- if (data["mode"] !== "default" || data["mode"] !== "planetscale" || data["mode"] !== undefined)
1107
- return false;
1108
- return true;
1109
- }
1110
- if ("connection" in data) {
1111
- const type = typeof data["connection"];
1112
- if (type !== "string" && type !== "object" && type !== "undefined")
1113
- return false;
1114
- return true;
1115
- }
1116
- if ("client" in data) {
1117
- const type = typeof data["client"];
1118
- if (type !== "object" && type !== "function" && type !== "undefined")
1119
- return false;
1120
- return true;
1121
- }
1122
- if (Object.keys(data).length === 0)
1123
- return true;
1124
- return false;
1125
- }
1126
- var textDecoder;
1127
- var init_utils = __esm(() => {
1128
- init_column();
1129
- init_entity();
1130
- init_sql();
1131
- init_subquery();
1132
- init_table();
1133
- init_view_common();
1134
- textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder;
1135
- });
1136
-
1137
- // ../node_modules/drizzle-orm/pg-core/table.js
1138
- var InlineForeignKeys, EnableRLS, PgTable;
1139
- var init_table2 = __esm(() => {
1140
- init_entity();
1141
- init_table();
1142
- InlineForeignKeys = Symbol.for("drizzle:PgInlineForeignKeys");
1143
- EnableRLS = Symbol.for("drizzle:EnableRLS");
1144
- PgTable = class PgTable extends Table {
1145
- static [entityKind] = "PgTable";
1146
- static Symbol = Object.assign({}, Table.Symbol, {
1147
- InlineForeignKeys,
1148
- EnableRLS
1149
- });
1150
- [InlineForeignKeys] = [];
1151
- [EnableRLS] = false;
1152
- [Table.Symbol.ExtraConfigBuilder] = undefined;
1153
- [Table.Symbol.ExtraConfigColumns] = {};
1154
- };
1155
- });
1156
-
1157
- // ../node_modules/drizzle-orm/pg-core/primary-keys.js
1158
- var PrimaryKeyBuilder, PrimaryKey;
1159
- var init_primary_keys = __esm(() => {
1160
- init_entity();
1161
- init_table2();
1162
- PrimaryKeyBuilder = class PrimaryKeyBuilder {
1163
- static [entityKind] = "PgPrimaryKeyBuilder";
1164
- columns;
1165
- name;
1166
- constructor(columns, name2) {
1167
- this.columns = columns;
1168
- this.name = name2;
1169
- }
1170
- build(table) {
1171
- return new PrimaryKey(table, this.columns, this.name);
1172
- }
1173
- };
1174
- PrimaryKey = class PrimaryKey {
1175
- constructor(table, columns, name2) {
1176
- this.table = table;
1177
- this.columns = columns;
1178
- this.name = name2;
1179
- }
1180
- static [entityKind] = "PgPrimaryKey";
1181
- columns;
1182
- name;
1183
- getName() {
1184
- return this.name ?? `${this.table[PgTable.Symbol.Name]}_${this.columns.map((column) => column.name).join("_")}_pk`;
1185
- }
1186
- };
1187
- });
1188
-
1189
- // ../node_modules/drizzle-orm/sql/expressions/conditions.js
1190
- function bindIfParam(value, column) {
1191
- if (isDriverValueEncoder(column) && !isSQLWrapper(value) && !is(value, Param) && !is(value, Placeholder) && !is(value, Column) && !is(value, Table) && !is(value, View)) {
1192
- return new Param(value, column);
1193
- }
1194
- return value;
1195
- }
1196
- function and(...unfilteredConditions) {
1197
- const conditions = unfilteredConditions.filter((c) => c !== undefined);
1198
- if (conditions.length === 0) {
1199
- return;
1200
- }
1201
- if (conditions.length === 1) {
1202
- return new SQL(conditions);
1203
- }
1204
- return new SQL([
1205
- new StringChunk("("),
1206
- sql.join(conditions, new StringChunk(" and ")),
1207
- new StringChunk(")")
1208
- ]);
1209
- }
1210
- function or(...unfilteredConditions) {
1211
- const conditions = unfilteredConditions.filter((c) => c !== undefined);
1212
- if (conditions.length === 0) {
1213
- return;
1214
- }
1215
- if (conditions.length === 1) {
1216
- return new SQL(conditions);
1217
- }
1218
- return new SQL([
1219
- new StringChunk("("),
1220
- sql.join(conditions, new StringChunk(" or ")),
1221
- new StringChunk(")")
1222
- ]);
1223
- }
1224
- function not(condition) {
1225
- return sql`not ${condition}`;
1226
- }
1227
- function inArray(column, values) {
1228
- if (Array.isArray(values)) {
1229
- if (values.length === 0) {
1230
- return sql`false`;
1231
- }
1232
- return sql`${column} in ${values.map((v) => bindIfParam(v, column))}`;
1233
- }
1234
- return sql`${column} in ${bindIfParam(values, column)}`;
1235
- }
1236
- function notInArray(column, values) {
1237
- if (Array.isArray(values)) {
1238
- if (values.length === 0) {
1239
- return sql`true`;
1240
- }
1241
- return sql`${column} not in ${values.map((v) => bindIfParam(v, column))}`;
1242
- }
1243
- return sql`${column} not in ${bindIfParam(values, column)}`;
1244
- }
1245
- function isNull(value) {
1246
- return sql`${value} is null`;
1247
- }
1248
- function isNotNull(value) {
1249
- return sql`${value} is not null`;
1250
- }
1251
- function exists(subquery) {
1252
- return sql`exists ${subquery}`;
1253
- }
1254
- function notExists(subquery) {
1255
- return sql`not exists ${subquery}`;
1256
- }
1257
- function between(column, min, max) {
1258
- return sql`${column} between ${bindIfParam(min, column)} and ${bindIfParam(max, column)}`;
1259
- }
1260
- function notBetween(column, min, max) {
1261
- return sql`${column} not between ${bindIfParam(min, column)} and ${bindIfParam(max, column)}`;
1262
- }
1263
- function like(column, value) {
1264
- return sql`${column} like ${value}`;
1265
- }
1266
- function notLike(column, value) {
1267
- return sql`${column} not like ${value}`;
1268
- }
1269
- function ilike(column, value) {
1270
- return sql`${column} ilike ${value}`;
1271
- }
1272
- function notIlike(column, value) {
1273
- return sql`${column} not ilike ${value}`;
1274
- }
1275
- function arrayContains(column, values) {
1276
- if (Array.isArray(values)) {
1277
- if (values.length === 0) {
1278
- throw new Error("arrayContains requires at least one value");
1279
- }
1280
- const array = sql`${bindIfParam(values, column)}`;
1281
- return sql`${column} @> ${array}`;
1282
- }
1283
- return sql`${column} @> ${bindIfParam(values, column)}`;
1284
- }
1285
- function arrayContained(column, values) {
1286
- if (Array.isArray(values)) {
1287
- if (values.length === 0) {
1288
- throw new Error("arrayContained requires at least one value");
1289
- }
1290
- const array = sql`${bindIfParam(values, column)}`;
1291
- return sql`${column} <@ ${array}`;
1292
- }
1293
- return sql`${column} <@ ${bindIfParam(values, column)}`;
1294
- }
1295
- function arrayOverlaps(column, values) {
1296
- if (Array.isArray(values)) {
1297
- if (values.length === 0) {
1298
- throw new Error("arrayOverlaps requires at least one value");
1299
- }
1300
- const array = sql`${bindIfParam(values, column)}`;
1301
- return sql`${column} && ${array}`;
1302
- }
1303
- return sql`${column} && ${bindIfParam(values, column)}`;
1304
- }
1305
- var eq = (left, right) => {
1306
- return sql`${left} = ${bindIfParam(right, left)}`;
1307
- }, ne = (left, right) => {
1308
- return sql`${left} <> ${bindIfParam(right, left)}`;
1309
- }, gt = (left, right) => {
1310
- return sql`${left} > ${bindIfParam(right, left)}`;
1311
- }, gte = (left, right) => {
1312
- return sql`${left} >= ${bindIfParam(right, left)}`;
1313
- }, lt = (left, right) => {
1314
- return sql`${left} < ${bindIfParam(right, left)}`;
1315
- }, lte = (left, right) => {
1316
- return sql`${left} <= ${bindIfParam(right, left)}`;
1317
- };
1318
- var init_conditions = __esm(() => {
1319
- init_column();
1320
- init_entity();
1321
- init_table();
1322
- init_sql();
1323
- });
1324
-
1325
- // ../node_modules/drizzle-orm/sql/expressions/select.js
1326
- function asc(column) {
1327
- return sql`${column} asc`;
1328
- }
1329
- function desc(column) {
1330
- return sql`${column} desc`;
1331
- }
1332
- var init_select = __esm(() => {
1333
- init_sql();
1334
- });
1335
-
1336
- // ../node_modules/drizzle-orm/sql/expressions/index.js
1337
- var init_expressions = __esm(() => {
1338
- init_conditions();
1339
- init_select();
1340
- });
1341
-
1342
- // ../node_modules/drizzle-orm/relations.js
1343
- function getOperators() {
1344
- return {
1345
- and,
1346
- between,
1347
- eq,
1348
- exists,
1349
- gt,
1350
- gte,
1351
- ilike,
1352
- inArray,
1353
- isNull,
1354
- isNotNull,
1355
- like,
1356
- lt,
1357
- lte,
1358
- ne,
1359
- not,
1360
- notBetween,
1361
- notExists,
1362
- notLike,
1363
- notIlike,
1364
- notInArray,
1365
- or,
1366
- sql
1367
- };
1368
- }
1369
- function getOrderByOperators() {
1370
- return {
1371
- sql,
1372
- asc,
1373
- desc
1374
- };
1375
- }
1376
- function extractTablesRelationalConfig(schema, configHelpers) {
1377
- if (Object.keys(schema).length === 1 && "default" in schema && !is(schema["default"], Table)) {
1378
- schema = schema["default"];
1379
- }
1380
- const tableNamesMap = {};
1381
- const relationsBuffer = {};
1382
- const tablesConfig = {};
1383
- for (const [key, value] of Object.entries(schema)) {
1384
- if (is(value, Table)) {
1385
- const dbName = getTableUniqueName(value);
1386
- const bufferedRelations = relationsBuffer[dbName];
1387
- tableNamesMap[dbName] = key;
1388
- tablesConfig[key] = {
1389
- tsName: key,
1390
- dbName: value[Table.Symbol.Name],
1391
- schema: value[Table.Symbol.Schema],
1392
- columns: value[Table.Symbol.Columns],
1393
- relations: bufferedRelations?.relations ?? {},
1394
- primaryKey: bufferedRelations?.primaryKey ?? []
1395
- };
1396
- for (const column of Object.values(value[Table.Symbol.Columns])) {
1397
- if (column.primary) {
1398
- tablesConfig[key].primaryKey.push(column);
1399
- }
1400
- }
1401
- const extraConfig = value[Table.Symbol.ExtraConfigBuilder]?.(value[Table.Symbol.ExtraConfigColumns]);
1402
- if (extraConfig) {
1403
- for (const configEntry of Object.values(extraConfig)) {
1404
- if (is(configEntry, PrimaryKeyBuilder)) {
1405
- tablesConfig[key].primaryKey.push(...configEntry.columns);
1406
- }
1407
- }
1408
- }
1409
- } else if (is(value, Relations)) {
1410
- const dbName = getTableUniqueName(value.table);
1411
- const tableName = tableNamesMap[dbName];
1412
- const relations2 = value.config(configHelpers(value.table));
1413
- let primaryKey;
1414
- for (const [relationName, relation] of Object.entries(relations2)) {
1415
- if (tableName) {
1416
- const tableConfig = tablesConfig[tableName];
1417
- tableConfig.relations[relationName] = relation;
1418
- if (primaryKey) {
1419
- tableConfig.primaryKey.push(...primaryKey);
1420
- }
1421
- } else {
1422
- if (!(dbName in relationsBuffer)) {
1423
- relationsBuffer[dbName] = {
1424
- relations: {},
1425
- primaryKey
1426
- };
1427
- }
1428
- relationsBuffer[dbName].relations[relationName] = relation;
1429
- }
1430
- }
1431
- }
1432
- }
1433
- return { tables: tablesConfig, tableNamesMap };
1434
- }
1435
- function relations(table, relations2) {
1436
- return new Relations(table, (helpers) => Object.fromEntries(Object.entries(relations2(helpers)).map(([key, value]) => [
1437
- key,
1438
- value.withFieldName(key)
1439
- ])));
1440
- }
1441
- function createOne(sourceTable) {
1442
- return function one(table, config) {
1443
- return new One(sourceTable, table, config, config?.fields.reduce((res, f) => res && f.notNull, true) ?? false);
1444
- };
1445
- }
1446
- function createMany(sourceTable) {
1447
- return function many(referencedTable, config) {
1448
- return new Many(sourceTable, referencedTable, config);
1449
- };
1450
- }
1451
- function normalizeRelation(schema, tableNamesMap, relation) {
1452
- if (is(relation, One) && relation.config) {
1453
- return {
1454
- fields: relation.config.fields,
1455
- references: relation.config.references
1456
- };
1457
- }
1458
- const referencedTableTsName = tableNamesMap[getTableUniqueName(relation.referencedTable)];
1459
- if (!referencedTableTsName) {
1460
- throw new Error(`Table "${relation.referencedTable[Table.Symbol.Name]}" not found in schema`);
1461
- }
1462
- const referencedTableConfig = schema[referencedTableTsName];
1463
- if (!referencedTableConfig) {
1464
- throw new Error(`Table "${referencedTableTsName}" not found in schema`);
1465
- }
1466
- const sourceTable = relation.sourceTable;
1467
- const sourceTableTsName = tableNamesMap[getTableUniqueName(sourceTable)];
1468
- if (!sourceTableTsName) {
1469
- throw new Error(`Table "${sourceTable[Table.Symbol.Name]}" not found in schema`);
1470
- }
1471
- const reverseRelations = [];
1472
- for (const referencedTableRelation of Object.values(referencedTableConfig.relations)) {
1473
- if (relation.relationName && relation !== referencedTableRelation && referencedTableRelation.relationName === relation.relationName || !relation.relationName && referencedTableRelation.referencedTable === relation.sourceTable) {
1474
- reverseRelations.push(referencedTableRelation);
1475
- }
1476
- }
1477
- if (reverseRelations.length > 1) {
1478
- throw relation.relationName ? new Error(`There are multiple relations with name "${relation.relationName}" in table "${referencedTableTsName}"`) : new Error(`There are multiple relations between "${referencedTableTsName}" and "${relation.sourceTable[Table.Symbol.Name]}". Please specify relation name`);
1479
- }
1480
- if (reverseRelations[0] && is(reverseRelations[0], One) && reverseRelations[0].config) {
1481
- return {
1482
- fields: reverseRelations[0].config.references,
1483
- references: reverseRelations[0].config.fields
1484
- };
1485
- }
1486
- throw new Error(`There is not enough information to infer relation "${sourceTableTsName}.${relation.fieldName}"`);
1487
- }
1488
- function createTableRelationsHelpers(sourceTable) {
1489
- return {
1490
- one: createOne(sourceTable),
1491
- many: createMany(sourceTable)
1492
- };
1493
- }
1494
- function mapRelationalRow(tablesConfig, tableConfig, row, buildQueryResultSelection, mapColumnValue = (value) => value) {
1495
- const result = {};
1496
- for (const [
1497
- selectionItemIndex,
1498
- selectionItem
1499
- ] of buildQueryResultSelection.entries()) {
1500
- if (selectionItem.isJson) {
1501
- const relation = tableConfig.relations[selectionItem.tsKey];
1502
- const rawSubRows = row[selectionItemIndex];
1503
- const subRows = typeof rawSubRows === "string" ? JSON.parse(rawSubRows) : rawSubRows;
1504
- result[selectionItem.tsKey] = is(relation, One) ? subRows && mapRelationalRow(tablesConfig, tablesConfig[selectionItem.relationTableTsKey], subRows, selectionItem.selection, mapColumnValue) : subRows.map((subRow) => mapRelationalRow(tablesConfig, tablesConfig[selectionItem.relationTableTsKey], subRow, selectionItem.selection, mapColumnValue));
1505
- } else {
1506
- const value = mapColumnValue(row[selectionItemIndex]);
1507
- const field = selectionItem.field;
1508
- let decoder;
1509
- if (is(field, Column)) {
1510
- decoder = field;
1511
- } else if (is(field, SQL)) {
1512
- decoder = field.decoder;
1513
- } else {
1514
- decoder = field.sql.decoder;
1515
- }
1516
- result[selectionItem.tsKey] = value === null ? null : decoder.mapFromDriverValue(value);
1517
- }
1518
- }
1519
- return result;
1520
- }
1521
- var Relation, Relations, One, Many;
1522
- var init_relations = __esm(() => {
1523
- init_table();
1524
- init_column();
1525
- init_entity();
1526
- init_primary_keys();
1527
- init_expressions();
1528
- init_sql();
1529
- Relation = class Relation {
1530
- constructor(sourceTable, referencedTable, relationName) {
1531
- this.sourceTable = sourceTable;
1532
- this.referencedTable = referencedTable;
1533
- this.relationName = relationName;
1534
- this.referencedTableName = referencedTable[Table.Symbol.Name];
1535
- }
1536
- static [entityKind] = "Relation";
1537
- referencedTableName;
1538
- fieldName;
1539
- };
1540
- Relations = class Relations {
1541
- constructor(table, config) {
1542
- this.table = table;
1543
- this.config = config;
1544
- }
1545
- static [entityKind] = "Relations";
1546
- };
1547
- One = class One extends Relation {
1548
- constructor(sourceTable, referencedTable, config, isNullable) {
1549
- super(sourceTable, referencedTable, config?.relationName);
1550
- this.config = config;
1551
- this.isNullable = isNullable;
1552
- }
1553
- static [entityKind] = "One";
1554
- withFieldName(fieldName) {
1555
- const relation = new One(this.sourceTable, this.referencedTable, this.config, this.isNullable);
1556
- relation.fieldName = fieldName;
1557
- return relation;
1558
- }
1559
- };
1560
- Many = class Many extends Relation {
1561
- constructor(sourceTable, referencedTable, config) {
1562
- super(sourceTable, referencedTable, config?.relationName);
1563
- this.config = config;
1564
- }
1565
- static [entityKind] = "Many";
1566
- withFieldName(fieldName) {
1567
- const relation = new Many(this.sourceTable, this.referencedTable, this.config);
1568
- relation.fieldName = fieldName;
1569
- return relation;
1570
- }
1571
- };
1572
- });
1573
-
1574
- // ../node_modules/drizzle-orm/sql/functions/aggregate.js
1575
- function count(expression) {
1576
- return sql`count(${expression || sql.raw("*")})`.mapWith(Number);
1577
- }
1578
- function countDistinct(expression) {
1579
- return sql`count(distinct ${expression})`.mapWith(Number);
1580
- }
1581
- function avg(expression) {
1582
- return sql`avg(${expression})`.mapWith(String);
1583
- }
1584
- function avgDistinct(expression) {
1585
- return sql`avg(distinct ${expression})`.mapWith(String);
1586
- }
1587
- function sum(expression) {
1588
- return sql`sum(${expression})`.mapWith(String);
1589
- }
1590
- function sumDistinct(expression) {
1591
- return sql`sum(distinct ${expression})`.mapWith(String);
1592
- }
1593
- function max(expression) {
1594
- return sql`max(${expression})`.mapWith(is(expression, Column) ? expression : String);
1595
- }
1596
- function min(expression) {
1597
- return sql`min(${expression})`.mapWith(is(expression, Column) ? expression : String);
1598
- }
1599
- var init_aggregate = __esm(() => {
1600
- init_column();
1601
- init_entity();
1602
- init_sql();
1603
- });
1604
-
1605
- // ../node_modules/drizzle-orm/sql/functions/vector.js
1606
- function toSql(value) {
1607
- return JSON.stringify(value);
1608
- }
1609
- function l2Distance(column, value) {
1610
- if (Array.isArray(value)) {
1611
- return sql`${column} <-> ${toSql(value)}`;
1612
- }
1613
- return sql`${column} <-> ${value}`;
1614
- }
1615
- function l1Distance(column, value) {
1616
- if (Array.isArray(value)) {
1617
- return sql`${column} <+> ${toSql(value)}`;
1618
- }
1619
- return sql`${column} <+> ${value}`;
1620
- }
1621
- function innerProduct(column, value) {
1622
- if (Array.isArray(value)) {
1623
- return sql`${column} <#> ${toSql(value)}`;
1624
- }
1625
- return sql`${column} <#> ${value}`;
1626
- }
1627
- function cosineDistance(column, value) {
1628
- if (Array.isArray(value)) {
1629
- return sql`${column} <=> ${toSql(value)}`;
1630
- }
1631
- return sql`${column} <=> ${value}`;
1632
- }
1633
- function hammingDistance(column, value) {
1634
- if (Array.isArray(value)) {
1635
- return sql`${column} <~> ${toSql(value)}`;
1636
- }
1637
- return sql`${column} <~> ${value}`;
1638
- }
1639
- function jaccardDistance(column, value) {
1640
- if (Array.isArray(value)) {
1641
- return sql`${column} <%> ${toSql(value)}`;
1642
- }
1643
- return sql`${column} <%> ${value}`;
1644
- }
1645
- var init_vector = __esm(() => {
1646
- init_sql();
1647
- });
1648
-
1649
- // ../node_modules/drizzle-orm/sql/functions/index.js
1650
- var init_functions = __esm(() => {
1651
- init_aggregate();
1652
- init_vector();
1653
- });
1654
-
1655
- // ../node_modules/drizzle-orm/sql/index.js
1656
- var init_sql2 = __esm(() => {
1657
- init_expressions();
1658
- init_functions();
1659
- init_sql();
1660
- });
1661
-
1662
- // ../node_modules/drizzle-orm/index.js
1663
- var exports_drizzle_orm = {};
1664
- __export(exports_drizzle_orm, {
1665
- textDecoder: () => textDecoder,
1666
- sumDistinct: () => sumDistinct,
1667
- sum: () => sum,
1668
- sql: () => sql,
1669
- relations: () => relations,
1670
- placeholder: () => placeholder,
1671
- param: () => param,
1672
- orderSelectedFields: () => orderSelectedFields,
1673
- or: () => or,
1674
- notLike: () => notLike,
1675
- notInArray: () => notInArray,
1676
- notIlike: () => notIlike,
1677
- notExists: () => notExists,
1678
- notBetween: () => notBetween,
1679
- not: () => not,
1680
- normalizeRelation: () => normalizeRelation,
1681
- noopMapper: () => noopMapper,
1682
- noopEncoder: () => noopEncoder,
1683
- noopDecoder: () => noopDecoder,
1684
- ne: () => ne,
1685
- name: () => name,
1686
- min: () => min,
1687
- max: () => max,
1688
- mapUpdateSet: () => mapUpdateSet,
1689
- mapResultRow: () => mapResultRow,
1690
- mapRelationalRow: () => mapRelationalRow,
1691
- mapColumnsInSQLToAlias: () => mapColumnsInSQLToAlias,
1692
- mapColumnsInAliasedSQLToAlias: () => mapColumnsInAliasedSQLToAlias,
1693
- lte: () => lte,
1694
- lt: () => lt,
1695
- like: () => like,
1696
- l2Distance: () => l2Distance,
1697
- l1Distance: () => l1Distance,
1698
- jaccardDistance: () => jaccardDistance,
1699
- isView: () => isView,
1700
- isTable: () => isTable,
1701
- isSQLWrapper: () => isSQLWrapper,
1702
- isNull: () => isNull,
1703
- isNotNull: () => isNotNull,
1704
- isDriverValueEncoder: () => isDriverValueEncoder,
1705
- isConfig: () => isConfig,
1706
- is: () => is,
1707
- innerProduct: () => innerProduct,
1708
- inArray: () => inArray,
1709
- ilike: () => ilike,
1710
- haveSameKeys: () => haveSameKeys,
1711
- hasOwnEntityKind: () => hasOwnEntityKind,
1712
- hammingDistance: () => hammingDistance,
1713
- gte: () => gte,
1714
- gt: () => gt,
1715
- getViewSelectedFields: () => getViewSelectedFields,
1716
- getViewName: () => getViewName,
1717
- getTableUniqueName: () => getTableUniqueName,
1718
- getTableName: () => getTableName,
1719
- getTableLikeName: () => getTableLikeName,
1720
- getTableColumns: () => getTableColumns,
1721
- getOrderByOperators: () => getOrderByOperators,
1722
- getOperators: () => getOperators,
1723
- getColumnNameAndConfig: () => getColumnNameAndConfig,
1724
- fillPlaceholders: () => fillPlaceholders,
1725
- extractTablesRelationalConfig: () => extractTablesRelationalConfig,
1726
- exists: () => exists,
1727
- eq: () => eq,
1728
- entityKind: () => entityKind,
1729
- desc: () => desc,
1730
- createTableRelationsHelpers: () => createTableRelationsHelpers,
1731
- createOne: () => createOne,
1732
- createMany: () => createMany,
1733
- countDistinct: () => countDistinct,
1734
- count: () => count,
1735
- cosineDistance: () => cosineDistance,
1736
- bindIfParam: () => bindIfParam,
1737
- between: () => between,
1738
- avgDistinct: () => avgDistinct,
1739
- avg: () => avg,
1740
- asc: () => asc,
1741
- arrayOverlaps: () => arrayOverlaps,
1742
- arrayContains: () => arrayContains,
1743
- arrayContained: () => arrayContained,
1744
- applyMixins: () => applyMixins,
1745
- and: () => and,
1746
- aliasedTableColumn: () => aliasedTableColumn,
1747
- aliasedTable: () => aliasedTable,
1748
- aliasedRelation: () => aliasedRelation,
1749
- WithSubquery: () => WithSubquery,
1750
- ViewBaseConfig: () => ViewBaseConfig,
1751
- View: () => View,
1752
- TransactionRollbackError: () => TransactionRollbackError,
1753
- TableAliasProxyHandler: () => TableAliasProxyHandler,
1754
- Table: () => Table,
1755
- Subquery: () => Subquery,
1756
- StringChunk: () => StringChunk,
1757
- Schema: () => Schema,
1758
- SQL: () => SQL,
1759
- Relations: () => Relations,
1760
- RelationTableAliasProxyHandler: () => RelationTableAliasProxyHandler,
1761
- Relation: () => Relation,
1762
- QueryPromise: () => QueryPromise,
1763
- Placeholder: () => Placeholder,
1764
- Param: () => Param,
1765
- OriginalName: () => OriginalName,
1766
- One: () => One,
1767
- NoopLogger: () => NoopLogger,
1768
- Name: () => Name,
1769
- Many: () => Many,
1770
- IsAlias: () => IsAlias,
1771
- FakePrimitiveParam: () => FakePrimitiveParam,
1772
- ExtraConfigColumns: () => ExtraConfigColumns,
1773
- ExtraConfigBuilder: () => ExtraConfigBuilder,
1774
- DrizzleQueryError: () => DrizzleQueryError,
1775
- DrizzleError: () => DrizzleError,
1776
- DefaultLogger: () => DefaultLogger,
1777
- ConsoleLogWriter: () => ConsoleLogWriter,
1778
- Columns: () => Columns,
1779
- ColumnBuilder: () => ColumnBuilder,
1780
- ColumnAliasProxyHandler: () => ColumnAliasProxyHandler,
1781
- Column: () => Column,
1782
- BaseName: () => BaseName
1783
- });
1784
- var init_drizzle_orm = __esm(() => {
1785
- init_alias();
1786
- init_column_builder();
1787
- init_column();
1788
- init_entity();
1789
- init_errors();
1790
- init_logger();
1791
- init_query_promise();
1792
- init_relations();
1793
- init_sql2();
1794
- init_subquery();
1795
- init_table();
1796
- init_utils();
1797
- init_view_common();
1798
- });
1799
-
1800
1
  // index.ts
1801
- import {
1802
- createUniqueUuid
1803
- } from "@elizaos/core";
1804
- import crypto from "node:crypto";
2
+ import { createUniqueUuid } from "@elizaos/core";
1805
3
 
1806
4
  // TrajectoryLoggerService.ts
1807
- import { logger as logger2, Service } from "@elizaos/core";
5
+ import { asUUID, logger } from "@elizaos/core";
1808
6
  import { v4 as uuidv4 } from "uuid";
1809
- function asNumber(value) {
1810
- if (typeof value === "number" && Number.isFinite(value))
1811
- return value;
1812
- if (typeof value === "string") {
1813
- const parsed = Number(value);
1814
- return Number.isFinite(parsed) ? parsed : null;
1815
- }
1816
- return null;
1817
- }
1818
- function asString(value) {
1819
- if (typeof value === "string")
1820
- return value;
1821
- if (typeof value === "number" || typeof value === "boolean")
1822
- return String(value);
1823
- if (value instanceof Date)
1824
- return value.toISOString();
1825
- return null;
1826
- }
1827
- function asIsoString(value) {
1828
- if (value instanceof Date)
1829
- return value.toISOString();
1830
- const asText = asString(value);
1831
- if (!asText)
1832
- return new Date(0).toISOString();
1833
- const parsed = new Date(asText);
1834
- if (Number.isNaN(parsed.getTime()))
1835
- return new Date(0).toISOString();
1836
- return parsed.toISOString();
1837
- }
1838
- function pickCell(row, ...keys) {
1839
- for (const key of keys) {
1840
- if (Object.hasOwn(row, key)) {
1841
- return row[key];
1842
- }
1843
- }
1844
- return;
1845
- }
1846
- function sqlLiteral(v) {
1847
- if (v === null || v === undefined)
1848
- return "NULL";
1849
- if (typeof v === "number")
1850
- return String(v);
1851
- if (typeof v === "boolean")
1852
- return v ? "TRUE" : "FALSE";
1853
- if (typeof v === "object")
1854
- return `'${JSON.stringify(v).replace(/'/g, "''")}'`;
1855
- return `'${String(v).replace(/'/g, "''")}'`;
1856
- }
1857
7
 
1858
- class TrajectoryLoggerService extends Service {
1859
- static serviceType = "trajectory_logger";
1860
- get serviceType() {
1861
- return TrajectoryLoggerService.serviceType;
1862
- }
1863
- capabilityDescription = "Captures and persists LLM calls, provider accesses, and full trajectories for debugging, analysis, and RL training";
1864
- enabled = true;
1865
- initialized = false;
8
+ class TrajectoryLoggerService {
9
+ activeTrajectories = new Map;
1866
10
  activeStepIds = new Map;
1867
- stepToTrajectory = new Map;
1868
- writeQueues = new Map;
1869
- static async start(runtime) {
1870
- const service = new this(runtime);
1871
- await service.initialize();
1872
- return service;
1873
- }
1874
- async stop() {
1875
- this.enabled = false;
1876
- }
1877
- setEnabled(enabled) {
1878
- this.enabled = enabled;
1879
- }
1880
- isEnabled() {
1881
- return this.enabled;
1882
- }
1883
- async getSqlHelper() {
1884
- const drizzle = await Promise.resolve().then(() => (init_drizzle_orm(), exports_drizzle_orm));
1885
- return drizzle.sql;
1886
- }
1887
- async executeRawSql(sqlText) {
1888
- const runtime = this.runtime;
1889
- if (!runtime?.adapter) {
1890
- throw new Error("Database adapter not available");
1891
- }
1892
- const sqlHelper = await this.getSqlHelper();
1893
- const db = runtime.adapter.db;
1894
- const query = sqlHelper.raw(sqlText);
1895
- const result = await db.execute(query);
1896
- const rows = Array.isArray(result.rows) ? result.rows : [];
1897
- const columns = result.fields && Array.isArray(result.fields) ? result.fields.map((field) => field.name) : rows.length > 0 ? Object.keys(rows[0]) : [];
1898
- return { rows, columns };
1899
- }
1900
- async initialize() {
1901
- if (this.initialized)
1902
- return;
1903
- const runtime = this.runtime;
1904
- if (!runtime?.adapter) {
1905
- logger2.warn("[trajectory-logger] No runtime adapter available, skipping initialization");
1906
- return;
1907
- }
1908
- await this.ensureTablesExist();
1909
- await this.backfillTrajectoriesMissingLlmCalls();
1910
- this.initialized = true;
1911
- logger2.info("[trajectory-logger] Trajectory logger service initialized");
1912
- }
1913
- async getTableColumnNames(tableName) {
1914
- const names = new Set;
1915
- try {
1916
- const result = await this.executeRawSql(`
1917
- SELECT column_name
1918
- FROM information_schema.columns
1919
- WHERE table_name = ${sqlLiteral(tableName)}
1920
- AND table_schema NOT IN ('pg_catalog', 'information_schema')
1921
- `);
1922
- for (const row of result.rows) {
1923
- const name2 = asString(pickCell(row, "column_name"));
1924
- if (name2)
1925
- names.add(name2);
1926
- }
1927
- if (names.size > 0)
1928
- return names;
1929
- } catch {}
1930
- const safeTableName = tableName.replace(/[^a-zA-Z0-9_]/g, "");
1931
- if (!safeTableName)
1932
- return names;
1933
- try {
1934
- const pragma = await this.executeRawSql(`PRAGMA table_info(${safeTableName})`);
1935
- for (const row of pragma.rows) {
1936
- const name2 = asString(pickCell(row, "name"));
1937
- if (name2)
1938
- names.add(name2);
1939
- }
1940
- } catch {}
1941
- return names;
1942
- }
1943
- async ensureTrajectoryColumnsExist() {
1944
- const columns = await this.getTableColumnNames("trajectories");
1945
- const requiredColumns = [
1946
- ["scenario_id", "TEXT"],
1947
- ["episode_id", "TEXT"],
1948
- ["batch_id", "TEXT"],
1949
- ["group_index", "INTEGER"],
1950
- ["steps_json", "JSONB NOT NULL DEFAULT '[]'"],
1951
- ["reward_components_json", "JSONB NOT NULL DEFAULT '{}'"],
1952
- ["metrics_json", "JSONB NOT NULL DEFAULT '{}'"],
1953
- ["metadata_json", "JSONB NOT NULL DEFAULT '{}'"],
1954
- ["is_training_data", "BOOLEAN NOT NULL DEFAULT FALSE"],
1955
- ["is_evaluation", "BOOLEAN NOT NULL DEFAULT FALSE"],
1956
- ["used_in_training", "BOOLEAN NOT NULL DEFAULT FALSE"],
1957
- ["judged_at", "TIMESTAMPTZ"]
1958
- ];
1959
- for (const [columnName, definition] of requiredColumns) {
1960
- if (columns.has(columnName))
1961
- continue;
1962
- try {
1963
- await this.executeRawSql(`
1964
- ALTER TABLE trajectories
1965
- ADD COLUMN IF NOT EXISTS ${columnName} ${definition}
1966
- `);
1967
- } catch (errWithIfExists) {
1968
- try {
1969
- await this.executeRawSql(`
1970
- ALTER TABLE trajectories
1971
- ADD COLUMN ${columnName} ${definition}
1972
- `);
1973
- } catch (errPlain) {
1974
- const combinedMessage = `${errWithIfExists instanceof Error ? errWithIfExists.message : String(errWithIfExists)} | ${errPlain instanceof Error ? errPlain.message : String(errPlain)}`.toLowerCase();
1975
- if (combinedMessage.includes("already exists") || combinedMessage.includes("duplicate column") || combinedMessage.includes("duplicate_column")) {
1976
- continue;
1977
- }
1978
- logger2.warn(`[trajectory-logger] Failed to add trajectories.${columnName} (non-fatal): ${errPlain instanceof Error ? errPlain.message : String(errPlain)}`);
1979
- }
1980
- }
1981
- }
1982
- for (const statement of [
1983
- `ALTER TABLE trajectories
1984
- ALTER COLUMN start_time TYPE BIGINT USING start_time::BIGINT`,
1985
- `ALTER TABLE trajectories
1986
- ALTER COLUMN end_time TYPE BIGINT USING end_time::BIGINT`,
1987
- `ALTER TABLE trajectories
1988
- ALTER COLUMN duration_ms TYPE BIGINT USING duration_ms::BIGINT`
1989
- ]) {
1990
- try {
1991
- await this.executeRawSql(statement);
1992
- } catch {}
1993
- }
1994
- }
1995
- async ensureTablesExist() {
1996
- await this.executeRawSql(`
1997
- CREATE TABLE IF NOT EXISTS trajectories (
1998
- id TEXT PRIMARY KEY,
1999
- agent_id TEXT NOT NULL,
2000
- source TEXT NOT NULL DEFAULT 'chat',
2001
- status TEXT NOT NULL DEFAULT 'active',
2002
- start_time BIGINT NOT NULL,
2003
- end_time BIGINT,
2004
- duration_ms BIGINT,
2005
- step_count INTEGER NOT NULL DEFAULT 0,
2006
- llm_call_count INTEGER NOT NULL DEFAULT 0,
2007
- provider_access_count INTEGER NOT NULL DEFAULT 0,
2008
- total_prompt_tokens INTEGER NOT NULL DEFAULT 0,
2009
- total_completion_tokens INTEGER NOT NULL DEFAULT 0,
2010
- total_reward REAL NOT NULL DEFAULT 0,
2011
- scenario_id TEXT,
2012
- episode_id TEXT,
2013
- batch_id TEXT,
2014
- group_index INTEGER,
2015
- steps_json JSONB NOT NULL DEFAULT '[]',
2016
- reward_components_json JSONB NOT NULL DEFAULT '{}',
2017
- metrics_json JSONB NOT NULL DEFAULT '{}',
2018
- metadata_json JSONB NOT NULL DEFAULT '{}',
2019
- is_training_data BOOLEAN NOT NULL DEFAULT FALSE,
2020
- is_evaluation BOOLEAN NOT NULL DEFAULT FALSE,
2021
- used_in_training BOOLEAN NOT NULL DEFAULT FALSE,
2022
- ai_judge_reward REAL,
2023
- ai_judge_reasoning TEXT,
2024
- judged_at TIMESTAMPTZ,
2025
- created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
2026
- updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
2027
- )
2028
- `);
2029
- await this.ensureTrajectoryColumnsExist();
2030
- try {
2031
- await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_agent_id ON trajectories(agent_id)`);
2032
- await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_source ON trajectories(source)`);
2033
- await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_status ON trajectories(status)`);
2034
- await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_created_at ON trajectories(created_at)`);
2035
- await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_scenario_id ON trajectories(scenario_id)`);
2036
- await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_batch_id ON trajectories(batch_id)`);
2037
- await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_is_training ON trajectories(is_training_data)`);
2038
- } catch (e) {
2039
- logger2.warn(`[trajectory-logger] Failed to create indexes (non-fatal): ${e instanceof Error ? e.message : String(e)}`);
2040
- }
2041
- await this.executeRawSql(`
2042
- CREATE TABLE IF NOT EXISTS trajectory_step_index (
2043
- step_id TEXT PRIMARY KEY,
2044
- trajectory_id TEXT NOT NULL REFERENCES trajectories(id) ON DELETE CASCADE,
2045
- step_number INTEGER NOT NULL DEFAULT 0,
2046
- is_active BOOLEAN NOT NULL DEFAULT FALSE,
2047
- created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
2048
- updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
2049
- )
2050
- `);
2051
- await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectory_step_index_trajectory_id ON trajectory_step_index(trajectory_id)`);
2052
- await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectory_step_index_is_active ON trajectory_step_index(is_active)`);
2053
- }
2054
- normalizeTrajectoryStatus(value) {
2055
- switch (value) {
2056
- case "active":
2057
- case "completed":
2058
- case "error":
2059
- case "timeout":
2060
- case "terminated":
2061
- return value;
2062
- default:
2063
- return "completed";
2064
- }
2065
- }
2066
- async backfillTrajectoriesMissingLlmCalls() {
2067
- const maxRows = 2000;
2068
- let fixed = 0;
2069
- try {
2070
- const rows = await this.executeRawSql(`
2071
- SELECT id, status
2072
- FROM trajectories
2073
- WHERE COALESCE(llm_call_count, 0) = 0
2074
- AND status <> 'active'
2075
- ORDER BY created_at ASC
2076
- LIMIT ${maxRows}
2077
- `);
2078
- for (const row of rows.rows) {
2079
- const trajectoryId = asString(pickCell(row, "id"));
2080
- if (!trajectoryId)
2081
- continue;
2082
- const status = this.normalizeTrajectoryStatus(asString(pickCell(row, "status")));
2083
- await this.withTrajectoryWriteLock(trajectoryId, async () => {
2084
- const trajectory = await this.getTrajectoryById(trajectoryId);
2085
- if (!trajectory)
2086
- return;
2087
- const inserted = this.ensureAtLeastOneLlmCall(trajectory, "backfill");
2088
- if (!inserted)
2089
- return;
2090
- await this.persistTrajectory(trajectoryId, trajectory, status);
2091
- fixed += 1;
2092
- });
2093
- }
2094
- if (fixed > 0) {
2095
- logger2.info(`[trajectory-logger] Backfilled ${fixed} completed trajectories with synthetic LLM calls`);
2096
- }
2097
- if (rows.rows.length >= maxRows) {
2098
- logger2.warn(`[trajectory-logger] Backfill hit safety cap (${maxRows}); remaining older trajectories will be fixed lazily when touched`);
2099
- }
2100
- } catch (err) {
2101
- logger2.warn(`[trajectory-logger] Failed to backfill trajectories missing LLM calls (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
2102
- }
2103
- }
2104
- normalizePurpose(value) {
2105
- switch (value) {
2106
- case "action":
2107
- case "reasoning":
2108
- case "evaluation":
2109
- case "response":
2110
- case "other":
2111
- return value;
2112
- default:
2113
- return "other";
2114
- }
2115
- }
2116
- defaultEnvironmentState(timestamp = Date.now()) {
2117
- return {
2118
- timestamp,
2119
- agentBalance: 0,
2120
- agentPoints: 0,
2121
- agentPnL: 0,
2122
- openPositions: 0
2123
- };
2124
- }
2125
- createPendingAction(stepTimestamp) {
2126
- return {
2127
- attemptId: "",
2128
- timestamp: stepTimestamp,
2129
- actionType: "pending",
2130
- actionName: "pending",
2131
- parameters: {},
2132
- success: false
2133
- };
2134
- }
2135
- createStep(stepId, stepNumber, envState) {
2136
- const timestamp = envState.timestamp || Date.now();
2137
- return {
2138
- stepId,
2139
- stepNumber,
2140
- timestamp,
2141
- environmentState: envState,
2142
- observation: {},
2143
- llmCalls: [],
2144
- providerAccesses: [],
2145
- action: this.createPendingAction(timestamp),
2146
- reward: 0,
2147
- done: false
2148
- };
2149
- }
2150
- ensureAtLeastOneLlmCall(trajectory, source) {
2151
- if (this.computeTotals(trajectory.steps).llmCallCount > 0) {
2152
- return false;
2153
- }
2154
- const timestamp = Date.now();
2155
- let step = trajectory.steps[trajectory.steps.length - 1];
2156
- if (!step) {
2157
- step = this.createStep(uuidv4(), 0, this.defaultEnvironmentState(timestamp));
2158
- step.done = true;
2159
- trajectory.steps.push(step);
2160
- }
2161
- if (!Array.isArray(step.llmCalls)) {
2162
- step.llmCalls = [];
2163
- }
2164
- const syntheticCall = {
2165
- callId: uuidv4(),
2166
- timestamp,
2167
- model: "milady/synthetic-trajectory-fallback",
2168
- systemPrompt: "[synthetic] inserted by trajectory logger because no LLM calls were captured",
2169
- userPrompt: "[synthetic] this trajectory completed without recorded model activity",
2170
- response: "[synthetic] placeholder call inserted to enforce minimum llm_call_count=1",
2171
- temperature: 0,
2172
- maxTokens: 0,
2173
- promptTokens: 0,
2174
- completionTokens: 0,
2175
- latencyMs: 0,
2176
- purpose: "other",
2177
- actionType: "TRAJECTORY_FALLBACK"
2178
- };
2179
- step.llmCalls.push(syntheticCall);
2180
- if (!step.metadata)
2181
- step.metadata = {};
2182
- step.metadata.syntheticLlmCall = true;
2183
- step.metadata.syntheticLlmCallSource = source;
2184
- trajectory.metadata.syntheticLlmCall = true;
2185
- trajectory.metadata.syntheticLlmCallSource = source;
2186
- const existingFallbackCount = trajectory.metrics.syntheticLlmFallbackCount;
2187
- trajectory.metrics.syntheticLlmFallbackCount = typeof existingFallbackCount === "number" && Number.isFinite(existingFallbackCount) ? existingFallbackCount + 1 : 1;
2188
- return true;
2189
- }
2190
- computeTotals(steps) {
2191
- let llmCallCount = 0;
2192
- let providerAccessCount = 0;
2193
- let totalPromptTokens = 0;
2194
- let totalCompletionTokens = 0;
2195
- for (const step of steps) {
2196
- const llmCalls = Array.isArray(step.llmCalls) ? step.llmCalls : [];
2197
- const providerAccesses = Array.isArray(step.providerAccesses) ? step.providerAccesses : [];
2198
- llmCallCount += llmCalls.length;
2199
- providerAccessCount += providerAccesses.length;
2200
- for (const call of llmCalls) {
2201
- totalPromptTokens += call.promptTokens ?? 0;
2202
- totalCompletionTokens += call.completionTokens ?? 0;
2203
- }
2204
- }
2205
- return {
2206
- stepCount: steps.length,
2207
- llmCallCount,
2208
- providerAccessCount,
2209
- totalPromptTokens,
2210
- totalCompletionTokens
2211
- };
2212
- }
2213
- async withTrajectoryWriteLock(trajectoryId, task) {
2214
- const previous = this.writeQueues.get(trajectoryId) ?? Promise.resolve();
2215
- const next = previous.catch(() => {}).then(task);
2216
- this.writeQueues.set(trajectoryId, next);
2217
- try {
2218
- await next;
2219
- } finally {
2220
- if (this.writeQueues.get(trajectoryId) === next) {
2221
- this.writeQueues.delete(trajectoryId);
2222
- }
2223
- }
2224
- }
2225
- async getTrajectoryById(trajectoryId) {
2226
- const result = await this.executeRawSql(`SELECT * FROM trajectories WHERE id = ${sqlLiteral(trajectoryId)} LIMIT 1`);
2227
- if (result.rows.length === 0)
2228
- return null;
2229
- return this.rowToTrajectory(result.rows[0]);
2230
- }
2231
- async getStepIndex(stepId) {
2232
- const result = await this.executeRawSql(`SELECT trajectory_id, step_number, is_active FROM trajectory_step_index WHERE step_id = ${sqlLiteral(stepId)} LIMIT 1`);
2233
- const row = result.rows[0];
2234
- if (!row)
2235
- return null;
2236
- const trajectoryId = asString(pickCell(row, "trajectory_id"));
2237
- if (!trajectoryId)
2238
- return null;
2239
- const stepNumber = asNumber(pickCell(row, "step_number")) ?? 0;
2240
- const isActiveText = asString(pickCell(row, "is_active"));
2241
- const isActive = isActiveText === "true" || isActiveText === "t" || pickCell(row, "is_active") === true;
2242
- return { trajectoryId, stepNumber, isActive };
2243
- }
2244
- async setStepIndex(stepId, trajectoryId, stepNumber, isActive) {
2245
- await this.executeRawSql(`
2246
- INSERT INTO trajectory_step_index (
2247
- step_id, trajectory_id, step_number, is_active, updated_at
2248
- ) VALUES (
2249
- ${sqlLiteral(stepId)},
2250
- ${sqlLiteral(trajectoryId)},
2251
- ${stepNumber},
2252
- ${isActive ? "TRUE" : "FALSE"},
2253
- CURRENT_TIMESTAMP
2254
- )
2255
- ON CONFLICT (step_id) DO UPDATE SET
2256
- trajectory_id = EXCLUDED.trajectory_id,
2257
- step_number = EXCLUDED.step_number,
2258
- is_active = EXCLUDED.is_active,
2259
- updated_at = CURRENT_TIMESTAMP
2260
- `);
2261
- }
2262
- async markAllStepsInactive(trajectoryId) {
2263
- await this.executeRawSql(`
2264
- UPDATE trajectory_step_index
2265
- SET is_active = FALSE, updated_at = CURRENT_TIMESTAMP
2266
- WHERE trajectory_id = ${sqlLiteral(trajectoryId)}
2267
- `);
2268
- }
2269
- async resolveTrajectoryId(stepIdOrTrajectoryId) {
2270
- const cached = this.stepToTrajectory.get(stepIdOrTrajectoryId);
2271
- if (cached)
2272
- return cached;
2273
- const byStep = await this.getStepIndex(stepIdOrTrajectoryId);
2274
- if (byStep?.trajectoryId) {
2275
- this.stepToTrajectory.set(stepIdOrTrajectoryId, byStep.trajectoryId);
2276
- return byStep.trajectoryId;
2277
- }
2278
- const byId = await this.executeRawSql(`SELECT id FROM trajectories WHERE id = ${sqlLiteral(stepIdOrTrajectoryId)} LIMIT 1`);
2279
- const row = byId.rows[0];
2280
- const id = row ? asString(pickCell(row, "id")) : null;
2281
- return id;
2282
- }
2283
- async getCurrentStepIdFromDb(trajectoryId) {
2284
- const result = await this.executeRawSql(`
2285
- SELECT step_id
2286
- FROM trajectory_step_index
2287
- WHERE trajectory_id = ${sqlLiteral(trajectoryId)} AND is_active = TRUE
2288
- ORDER BY step_number DESC, updated_at DESC
2289
- LIMIT 1
2290
- `);
2291
- const row = result.rows[0];
2292
- return row ? asString(pickCell(row, "step_id")) : null;
2293
- }
2294
- async persistTrajectory(trajectoryId, trajectory, status = "active") {
2295
- if (status !== "active") {
2296
- this.ensureAtLeastOneLlmCall(trajectory, "finalize");
2297
- }
2298
- const totals = this.computeTotals(trajectory.steps);
2299
- const isFinalStatus = status !== "active";
2300
- const persistedEndTime = isFinalStatus ? trajectory.endTime : null;
2301
- const persistedDuration = isFinalStatus ? trajectory.durationMs : null;
2302
- const updatedAtIso = new Date().toISOString();
2303
- try {
2304
- await this.executeRawSql(`
2305
- UPDATE trajectories SET
2306
- status = ${sqlLiteral(status)},
2307
- end_time = ${sqlLiteral(persistedEndTime)},
2308
- duration_ms = ${sqlLiteral(persistedDuration)},
2309
- step_count = ${totals.stepCount},
2310
- llm_call_count = ${totals.llmCallCount},
2311
- provider_access_count = ${totals.providerAccessCount},
2312
- total_prompt_tokens = ${totals.totalPromptTokens},
2313
- total_completion_tokens = ${totals.totalCompletionTokens},
2314
- total_reward = ${trajectory.totalReward},
2315
- steps_json = ${sqlLiteral(trajectory.steps)},
2316
- reward_components_json = ${sqlLiteral(trajectory.rewardComponents)},
2317
- metrics_json = ${sqlLiteral(trajectory.metrics)},
2318
- metadata_json = ${sqlLiteral(trajectory.metadata)},
2319
- updated_at = ${sqlLiteral(updatedAtIso)}
2320
- WHERE id = ${sqlLiteral(trajectoryId)}
2321
- `);
2322
- } catch (modernErr) {
2323
- await this.executeRawSql(`
2324
- UPDATE trajectories SET
2325
- status = ${sqlLiteral(status)},
2326
- end_time = ${sqlLiteral(persistedEndTime)},
2327
- duration_ms = ${sqlLiteral(persistedDuration)},
2328
- step_count = ${totals.stepCount},
2329
- llm_call_count = ${totals.llmCallCount},
2330
- provider_access_count = ${totals.providerAccessCount},
2331
- total_prompt_tokens = ${totals.totalPromptTokens},
2332
- total_completion_tokens = ${totals.totalCompletionTokens},
2333
- total_reward = ${trajectory.totalReward},
2334
- steps_json = ${sqlLiteral(trajectory.steps)},
2335
- metadata = ${sqlLiteral(trajectory.metadata)},
2336
- updated_at = ${sqlLiteral(updatedAtIso)}
2337
- WHERE id = ${sqlLiteral(trajectoryId)}
2338
- `).catch((legacyErr) => {
2339
- logger2.warn({ err: legacyErr, trajectoryId }, `[trajectory-logger] Failed to persist trajectory update after compatibility fallback: ${modernErr instanceof Error ? modernErr.message : String(modernErr)}`);
2340
- throw legacyErr;
2341
- });
2342
- }
2343
- }
2344
- async ensureStepExists(trajectory, stepId) {
2345
- let step = trajectory.steps.find((entry) => entry.stepId === stepId);
2346
- if (step) {
2347
- if (!Array.isArray(step.llmCalls))
2348
- step.llmCalls = [];
2349
- if (!Array.isArray(step.providerAccesses))
2350
- step.providerAccesses = [];
2351
- return step;
2352
- }
2353
- const index = await this.getStepIndex(stepId);
2354
- const stepNumber = index?.stepNumber ?? trajectory.steps.length;
2355
- step = this.createStep(stepId, stepNumber, this.defaultEnvironmentState());
2356
- trajectory.steps.push(step);
2357
- trajectory.steps.sort((a, b) => a.stepNumber - b.stepNumber);
2358
- return step;
2359
- }
2360
- logLlmCall(params) {
2361
- if (!this.enabled)
2362
- return;
2363
- (async () => {
2364
- const trajectoryId = await this.resolveTrajectoryId(params.stepId);
2365
- if (!trajectoryId) {
2366
- logger2.debug({ stepId: params.stepId }, "[trajectory-logger] No trajectory mapping for LLM call");
2367
- return;
2368
- }
2369
- await this.withTrajectoryWriteLock(trajectoryId, async () => {
2370
- const trajectory = await this.getTrajectoryById(trajectoryId);
2371
- if (!trajectory)
2372
- return;
2373
- const step = await this.ensureStepExists(trajectory, params.stepId);
2374
- const llmCall = {
2375
- callId: uuidv4(),
2376
- timestamp: Date.now(),
2377
- model: params.model,
2378
- modelVersion: params.modelVersion,
2379
- systemPrompt: params.systemPrompt,
2380
- userPrompt: params.userPrompt,
2381
- response: params.response,
2382
- reasoning: params.reasoning,
2383
- temperature: params.temperature,
2384
- maxTokens: params.maxTokens,
2385
- purpose: this.normalizePurpose(params.purpose),
2386
- actionType: params.actionType,
2387
- promptTokens: params.promptTokens,
2388
- completionTokens: params.completionTokens,
2389
- latencyMs: params.latencyMs
2390
- };
2391
- step.llmCalls.push(llmCall);
2392
- await this.persistTrajectory(trajectoryId, trajectory, "active");
2393
- });
2394
- })().catch((err) => {
2395
- logger2.warn({ err, stepId: params.stepId }, "[trajectory-logger] Failed to persist LLM call");
2396
- });
2397
- }
2398
- logLLMCall(stepId, details) {
2399
- this.logLlmCall({
2400
- stepId,
2401
- model: details.model,
2402
- modelVersion: details.modelVersion,
2403
- systemPrompt: details.systemPrompt,
2404
- userPrompt: details.userPrompt,
2405
- response: details.response,
2406
- reasoning: details.reasoning,
2407
- temperature: details.temperature,
2408
- maxTokens: details.maxTokens,
2409
- purpose: details.purpose,
2410
- actionType: details.actionType ?? "",
2411
- latencyMs: details.latencyMs ?? 0,
2412
- promptTokens: details.promptTokens,
2413
- completionTokens: details.completionTokens
2414
- });
2415
- }
2416
- logProviderAccess(arg1, arg2) {
2417
- if (!this.enabled)
2418
- return;
2419
- const params = typeof arg1 === "string" ? {
2420
- stepId: arg1,
2421
- providerName: arg2?.providerName ?? "unknown",
2422
- data: arg2?.data ?? {},
2423
- purpose: arg2?.purpose ?? "other",
2424
- query: arg2?.query
2425
- } : arg1;
2426
- (async () => {
2427
- const trajectoryId = await this.resolveTrajectoryId(params.stepId);
2428
- if (!trajectoryId) {
2429
- logger2.debug({ stepId: params.stepId }, "[trajectory-logger] No trajectory mapping for provider access");
2430
- return;
2431
- }
2432
- await this.withTrajectoryWriteLock(trajectoryId, async () => {
2433
- const trajectory = await this.getTrajectoryById(trajectoryId);
2434
- if (!trajectory)
2435
- return;
2436
- const step = await this.ensureStepExists(trajectory, params.stepId);
2437
- const access = {
2438
- providerId: uuidv4(),
2439
- providerName: params.providerName,
2440
- timestamp: Date.now(),
2441
- data: params.data,
2442
- query: params.query,
2443
- purpose: params.purpose
2444
- };
2445
- step.providerAccesses.push(access);
2446
- await this.persistTrajectory(trajectoryId, trajectory, "active");
2447
- });
2448
- })().catch((err) => {
2449
- logger2.warn({ err, stepId: params.stepId }, "[trajectory-logger] Failed to persist provider access");
2450
- });
2451
- }
2452
- logProviderAccessByTrajectoryId(trajectoryId, access) {
2453
- const stepId = this.getCurrentStepId(trajectoryId);
2454
- if (!stepId) {
2455
- logger2.debug({ trajectoryId }, "[trajectory-logger] No active step for provider access by trajectory");
2456
- return;
2457
- }
2458
- this.logProviderAccess(stepId, access);
2459
- }
2460
- async startTrajectory(stepIdOrAgentId, options = {}) {
2461
- if (!this.enabled)
2462
- return uuidv4();
2463
- const legacyStepId = typeof options.agentId === "string" && options.agentId.length > 0 ? stepIdOrAgentId : null;
2464
- const agentId = (typeof options.agentId === "string" && options.agentId.length > 0 ? options.agentId : stepIdOrAgentId) ?? stepIdOrAgentId;
11
+ startTrajectory(agentId, options = {}) {
2465
12
  const trajectoryId = uuidv4();
2466
13
  const now = Date.now();
2467
- const timestampIso = new Date(now).toISOString();
2468
- const metadata = {
2469
- ...options.metadata ?? {}
2470
- };
2471
- if (options.roomId)
2472
- metadata.roomId = options.roomId;
2473
- if (options.entityId)
2474
- metadata.entityId = options.entityId;
2475
14
  const trajectory = {
2476
- trajectoryId,
2477
- agentId,
15
+ trajectoryId: asUUID(trajectoryId),
16
+ agentId: asUUID(agentId),
2478
17
  startTime: now,
2479
18
  endTime: now,
2480
19
  durationMs: 0,
2481
- scenarioId: options.scenarioId,
2482
20
  episodeId: options.episodeId,
21
+ scenarioId: options.scenarioId,
2483
22
  batchId: options.batchId,
2484
23
  groupIndex: options.groupIndex,
2485
24
  steps: [],
2486
25
  totalReward: 0,
2487
- rewardComponents: { environmentReward: 0 },
26
+ rewardComponents: {
27
+ environmentReward: 0
28
+ },
2488
29
  metrics: {
2489
30
  episodeLength: 0,
2490
31
  finalStatus: "completed"
2491
32
  },
2492
- metadata: {
2493
- source: options.source ?? "chat",
2494
- ...metadata
2495
- }
33
+ metadata: options.metadata || {}
2496
34
  };
2497
- let persistedStart = false;
2498
- try {
2499
- await this.executeRawSql(`
2500
- INSERT INTO trajectories (
2501
- id, agent_id, source, status, start_time, scenario_id, episode_id,
2502
- batch_id, group_index, metadata_json, steps_json, reward_components_json, metrics_json,
2503
- created_at, updated_at
2504
- ) VALUES (
2505
- ${sqlLiteral(trajectoryId)},
2506
- ${sqlLiteral(agentId)},
2507
- ${sqlLiteral(options.source ?? "chat")},
2508
- 'active',
2509
- ${now},
2510
- ${sqlLiteral(options.scenarioId ?? null)},
2511
- ${sqlLiteral(options.episodeId ?? null)},
2512
- ${sqlLiteral(options.batchId ?? null)},
2513
- ${options.groupIndex ?? "NULL"},
2514
- ${sqlLiteral(trajectory.metadata)},
2515
- ${sqlLiteral([])},
2516
- ${sqlLiteral(trajectory.rewardComponents)},
2517
- ${sqlLiteral(trajectory.metrics)},
2518
- ${sqlLiteral(timestampIso)},
2519
- ${sqlLiteral(timestampIso)}
2520
- )
2521
- `);
2522
- persistedStart = true;
2523
- } catch (err) {
2524
- try {
2525
- await this.executeRawSql(`
2526
- INSERT INTO trajectories (
2527
- id, agent_id, source, status, start_time, steps_json, metadata, created_at, updated_at
2528
- ) VALUES (
2529
- ${sqlLiteral(trajectoryId)},
2530
- ${sqlLiteral(agentId)},
2531
- ${sqlLiteral(options.source ?? "chat")},
2532
- 'active',
2533
- ${now},
2534
- ${sqlLiteral([])},
2535
- ${sqlLiteral(trajectory.metadata)},
2536
- ${sqlLiteral(timestampIso)},
2537
- ${sqlLiteral(timestampIso)}
2538
- )
2539
- `);
2540
- persistedStart = true;
2541
- } catch (legacyErr) {
2542
- logger2.warn({ err: legacyErr, trajectoryId }, "[trajectory-logger] Failed to persist trajectory start");
2543
- }
2544
- }
2545
- if (persistedStart && legacyStepId) {
2546
- this.stepToTrajectory.set(legacyStepId, trajectoryId);
2547
- try {
2548
- await this.setStepIndex(legacyStepId, trajectoryId, -1, false);
2549
- } catch (indexErr) {
2550
- logger2.warn({ err: indexErr, trajectoryId, stepId: legacyStepId }, "[trajectory-logger] Failed to persist step index for trajectory start");
2551
- }
2552
- }
35
+ this.activeTrajectories.set(trajectoryId, trajectory);
2553
36
  return trajectoryId;
2554
37
  }
2555
38
  startStep(trajectoryId, envState) {
2556
- if (!this.enabled)
2557
- return uuidv4();
2558
39
  const stepId = uuidv4();
40
+ const trajectory = this.activeTrajectories.get(trajectoryId);
41
+ if (!trajectory) {
42
+ throw new Error(`Trajectory ${trajectoryId} not found`);
43
+ }
44
+ const step = {
45
+ stepId: asUUID(stepId),
46
+ stepNumber: trajectory.steps.length,
47
+ timestamp: envState.timestamp || Date.now(),
48
+ environmentState: envState,
49
+ observation: {},
50
+ llmCalls: [],
51
+ providerAccesses: [],
52
+ action: {
53
+ attemptId: "",
54
+ timestamp: 0,
55
+ actionType: "pending",
56
+ actionName: "pending",
57
+ parameters: {},
58
+ success: false
59
+ },
60
+ reward: 0,
61
+ done: false
62
+ };
63
+ trajectory.steps.push(step);
2559
64
  this.activeStepIds.set(trajectoryId, stepId);
2560
- this.stepToTrajectory.set(stepId, trajectoryId);
2561
- this.withTrajectoryWriteLock(trajectoryId, async () => {
2562
- const trajectory = await this.getTrajectoryById(trajectoryId);
2563
- if (!trajectory) {
2564
- logger2.warn({ trajectoryId }, "[trajectory-logger] Trajectory not found for startStep");
2565
- return;
2566
- }
2567
- const step = this.createStep(stepId, trajectory.steps.length, envState);
2568
- trajectory.steps.push(step);
2569
- await this.markAllStepsInactive(trajectoryId);
2570
- await this.setStepIndex(stepId, trajectoryId, step.stepNumber, true);
2571
- await this.persistTrajectory(trajectoryId, trajectory, "active");
2572
- }).catch((err) => {
2573
- logger2.warn({ err, trajectoryId, stepId }, "[trajectory-logger] Failed to persist startStep");
2574
- });
2575
65
  return stepId;
2576
66
  }
2577
- completeStep(trajectoryId, actionOrStepId, actionOrReward, maybeReward) {
2578
- if (!this.enabled)
67
+ logLLMCall(stepId, llmCall) {
68
+ const trajectory = this.findTrajectoryByStepId(stepId);
69
+ if (!trajectory) {
70
+ logger.warn({ stepId }, "Trajectory not found for LLM call");
2579
71
  return;
2580
- const explicitStepId = typeof actionOrStepId === "string" ? actionOrStepId : null;
2581
- const action = typeof actionOrStepId === "string" ? actionOrReward : actionOrStepId;
2582
- const rewardInfo = typeof actionOrStepId === "string" ? maybeReward : actionOrReward;
2583
- if (!action)
72
+ }
73
+ const step = trajectory.steps.find((s) => s.stepId === stepId);
74
+ if (!step) {
75
+ logger.warn({ stepId }, "Step not found for LLM call");
2584
76
  return;
2585
- this.withTrajectoryWriteLock(trajectoryId, async () => {
2586
- const trajectory = await this.getTrajectoryById(trajectoryId);
2587
- if (!trajectory)
2588
- return;
2589
- const stepId = explicitStepId ?? this.activeStepIds.get(trajectoryId) ?? await this.getCurrentStepIdFromDb(trajectoryId);
2590
- if (!stepId)
2591
- return;
2592
- const step = await this.ensureStepExists(trajectory, stepId);
2593
- step.action = {
2594
- attemptId: uuidv4(),
2595
- timestamp: Date.now(),
2596
- ...action
2597
- };
2598
- step.done = true;
2599
- if (rewardInfo?.reward !== undefined) {
2600
- step.reward = rewardInfo.reward;
2601
- trajectory.totalReward += rewardInfo.reward;
2602
- }
2603
- if (rewardInfo?.components) {
2604
- trajectory.rewardComponents = {
2605
- ...trajectory.rewardComponents,
2606
- ...rewardInfo.components
2607
- };
2608
- }
2609
- await this.setStepIndex(stepId, trajectoryId, step.stepNumber, false);
2610
- this.activeStepIds.delete(trajectoryId);
2611
- await this.persistTrajectory(trajectoryId, trajectory, "active");
2612
- }).catch((err) => {
2613
- logger2.warn({ err, trajectoryId }, "[trajectory-logger] Failed to complete step");
2614
- });
77
+ }
78
+ const fullLLMCall = {
79
+ callId: uuidv4(),
80
+ timestamp: Date.now(),
81
+ ...llmCall
82
+ };
83
+ step.llmCalls.push(fullLLMCall);
2615
84
  }
2616
- async endTrajectory(stepIdOrTrajectoryId, status = "completed", finalMetrics) {
2617
- if (!this.enabled)
2618
- return;
2619
- const trajectoryId = await this.resolveTrajectoryId(stepIdOrTrajectoryId);
2620
- if (!trajectoryId) {
2621
- logger2.debug({ stepIdOrTrajectoryId }, "[trajectory-logger] No trajectory to end");
85
+ logProviderAccess(stepId, access) {
86
+ const trajectory = this.findTrajectoryByStepId(stepId);
87
+ if (!trajectory) {
88
+ logger.warn({ stepId }, "Trajectory not found for provider access");
2622
89
  return;
2623
90
  }
2624
- await this.withTrajectoryWriteLock(trajectoryId, async () => {
2625
- const trajectory = await this.getTrajectoryById(trajectoryId);
2626
- if (!trajectory) {
2627
- logger2.debug({ trajectoryId }, "[trajectory-logger] Trajectory not found while ending");
2628
- return;
2629
- }
2630
- const now = Date.now();
2631
- trajectory.endTime = now;
2632
- trajectory.durationMs = now - trajectory.startTime;
2633
- trajectory.metrics.finalStatus = status;
2634
- trajectory.metrics.episodeLength = trajectory.steps.length;
2635
- if (finalMetrics) {
2636
- trajectory.metrics = {
2637
- ...trajectory.metrics,
2638
- ...finalMetrics
2639
- };
2640
- }
2641
- await this.markAllStepsInactive(trajectoryId);
2642
- this.activeStepIds.delete(trajectoryId);
2643
- await this.persistTrajectory(trajectoryId, trajectory, status);
2644
- });
2645
- for (const [stepId, mappedTrajectoryId] of this.stepToTrajectory.entries()) {
2646
- if (mappedTrajectoryId === trajectoryId) {
2647
- this.stepToTrajectory.delete(stepId);
2648
- }
91
+ const step = trajectory.steps.find((s) => s.stepId === stepId);
92
+ if (!step) {
93
+ logger.warn({ stepId }, "Step not found for provider access");
94
+ return;
2649
95
  }
96
+ const fullAccess = {
97
+ providerId: uuidv4(),
98
+ timestamp: Date.now(),
99
+ ...access
100
+ };
101
+ step.providerAccesses.push(fullAccess);
2650
102
  }
2651
- async listTrajectories(options = {}) {
2652
- const runtime = this.runtime;
2653
- if (!runtime?.adapter) {
2654
- return { trajectories: [], total: 0, offset: 0, limit: 50 };
2655
- }
2656
- const offset = Math.max(0, options.offset ?? 0);
2657
- const limit = Math.min(500, Math.max(1, options.limit ?? 50));
2658
- const whereClauses = [];
2659
- if (options.status) {
2660
- whereClauses.push(`status = ${sqlLiteral(options.status)}`);
2661
- }
2662
- if (options.source) {
2663
- whereClauses.push(`source = ${sqlLiteral(options.source)}`);
2664
- }
2665
- if (options.scenarioId) {
2666
- whereClauses.push(`scenario_id = ${sqlLiteral(options.scenarioId)}`);
2667
- }
2668
- if (options.batchId) {
2669
- whereClauses.push(`batch_id = ${sqlLiteral(options.batchId)}`);
2670
- }
2671
- if (options.isTrainingData !== undefined) {
2672
- whereClauses.push(`is_training_data = ${options.isTrainingData}`);
2673
- }
2674
- if (options.startDate) {
2675
- whereClauses.push(`created_at >= ${sqlLiteral(options.startDate)}::timestamptz`);
2676
- }
2677
- if (options.endDate) {
2678
- whereClauses.push(`created_at <= ${sqlLiteral(options.endDate)}::timestamptz`);
2679
- }
2680
- if (options.search) {
2681
- const escaped = options.search.replace(/'/g, "''").replace(/%/g, "\\%");
2682
- whereClauses.push(`(
2683
- id ILIKE '%${escaped}%' OR
2684
- agent_id ILIKE '%${escaped}%' OR
2685
- source ILIKE '%${escaped}%' OR
2686
- scenario_id ILIKE '%${escaped}%'
2687
- )`);
103
+ logLLMCallByTrajectoryId(trajectoryId, llmCall) {
104
+ const stepId = this.activeStepIds.get(trajectoryId);
105
+ if (!stepId) {
106
+ logger.warn({ trajectoryId }, "No active step for trajectory");
107
+ return;
2688
108
  }
2689
- const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
2690
- const countResult = await this.executeRawSql(`SELECT count(*)::int AS total FROM trajectories ${whereClause}`);
2691
- const total = asNumber(pickCell(countResult.rows[0] ?? {}, "total")) ?? 0;
2692
- const rowsResult = await this.executeRawSql(`
2693
- SELECT
2694
- id, agent_id, source, status, start_time, end_time, duration_ms,
2695
- step_count, llm_call_count, total_prompt_tokens, total_completion_tokens,
2696
- total_reward, scenario_id, batch_id, created_at
2697
- FROM trajectories
2698
- ${whereClause}
2699
- ORDER BY created_at DESC
2700
- LIMIT ${limit} OFFSET ${offset}
2701
- `);
2702
- const trajectories = rowsResult.rows.map((row) => {
2703
- const status = asString(pickCell(row, "status")) ?? "completed";
2704
- const rawLlmCallCount = asNumber(pickCell(row, "llm_call_count")) ?? 0;
2705
- const llmCallCount = status === "active" ? rawLlmCallCount : Math.max(1, rawLlmCallCount);
2706
- return {
2707
- id: asString(pickCell(row, "id")) ?? "",
2708
- agentId: asString(pickCell(row, "agent_id")) ?? "",
2709
- source: asString(pickCell(row, "source")) ?? "chat",
2710
- status,
2711
- startTime: asNumber(pickCell(row, "start_time")) ?? 0,
2712
- endTime: asNumber(pickCell(row, "end_time")),
2713
- durationMs: asNumber(pickCell(row, "duration_ms")),
2714
- stepCount: asNumber(pickCell(row, "step_count")) ?? 0,
2715
- llmCallCount,
2716
- totalPromptTokens: asNumber(pickCell(row, "total_prompt_tokens")) ?? 0,
2717
- totalCompletionTokens: asNumber(pickCell(row, "total_completion_tokens")) ?? 0,
2718
- totalReward: asNumber(pickCell(row, "total_reward")) ?? 0,
2719
- scenarioId: asString(pickCell(row, "scenario_id")),
2720
- batchId: asString(pickCell(row, "batch_id")),
2721
- createdAt: asIsoString(pickCell(row, "created_at"))
2722
- };
2723
- });
2724
- return { trajectories, total, offset, limit };
109
+ this.logLLMCall(stepId, llmCall);
2725
110
  }
2726
- async getTrajectoryDetail(trajectoryId) {
2727
- const runtime = this.runtime;
2728
- if (!runtime?.adapter)
2729
- return null;
2730
- const safeId = trajectoryId.replace(/'/g, "''");
2731
- const result = await this.executeRawSql(`SELECT * FROM trajectories WHERE id = '${safeId}' LIMIT 1`);
2732
- if (result.rows.length === 0)
2733
- return null;
2734
- const row = result.rows[0];
2735
- const trajectory = this.rowToTrajectory(row);
2736
- const status = this.normalizeTrajectoryStatus(asString(pickCell(row, "status")));
2737
- if (status !== "active") {
2738
- const inserted = this.ensureAtLeastOneLlmCall(trajectory, "backfill");
2739
- if (inserted) {
2740
- await this.withTrajectoryWriteLock(trajectoryId, async () => {
2741
- await this.persistTrajectory(trajectoryId, trajectory, status);
2742
- });
2743
- }
111
+ logProviderAccessByTrajectoryId(trajectoryId, access) {
112
+ const stepId = this.activeStepIds.get(trajectoryId);
113
+ if (!stepId) {
114
+ logger.warn({ trajectoryId }, "No active step for trajectory");
115
+ return;
2744
116
  }
2745
- return trajectory;
117
+ this.logProviderAccess(stepId, access);
2746
118
  }
2747
- async getStats() {
2748
- const runtime = this.runtime;
2749
- if (!runtime?.adapter) {
2750
- return {
2751
- totalTrajectories: 0,
2752
- totalSteps: 0,
2753
- totalLlmCalls: 0,
2754
- totalPromptTokens: 0,
2755
- totalCompletionTokens: 0,
2756
- averageDurationMs: 0,
2757
- averageReward: 0,
2758
- bySource: {},
2759
- byStatus: {},
2760
- byScenario: {}
2761
- };
2762
- }
2763
- const statsResult = await this.executeRawSql(`
2764
- SELECT
2765
- count(*)::int AS total_trajectories,
2766
- COALESCE(sum(step_count), 0)::int AS total_steps,
2767
- COALESCE(sum(llm_call_count), 0)::int AS total_llm_calls,
2768
- COALESCE(sum(total_prompt_tokens), 0)::int AS total_prompt_tokens,
2769
- COALESCE(sum(total_completion_tokens), 0)::int AS total_completion_tokens,
2770
- COALESCE(avg(duration_ms), 0)::int AS avg_duration_ms,
2771
- COALESCE(avg(total_reward), 0)::real AS avg_reward
2772
- FROM trajectories
2773
- `);
2774
- const sourceResult = await this.executeRawSql(`
2775
- SELECT source, count(*)::int AS cnt
2776
- FROM trajectories
2777
- GROUP BY source
2778
- `);
2779
- const statusResult = await this.executeRawSql(`
2780
- SELECT status, count(*)::int AS cnt
2781
- FROM trajectories
2782
- GROUP BY status
2783
- `);
2784
- const scenarioResult = await this.executeRawSql(`
2785
- SELECT scenario_id, count(*)::int AS cnt
2786
- FROM trajectories
2787
- WHERE scenario_id IS NOT NULL
2788
- GROUP BY scenario_id
2789
- `);
2790
- const stats = statsResult.rows[0] ?? {};
2791
- const bySource = {};
2792
- const byStatus = {};
2793
- const byScenario = {};
2794
- for (const row of sourceResult.rows) {
2795
- const source = asString(pickCell(row, "source"));
2796
- const cnt = asNumber(pickCell(row, "cnt"));
2797
- if (source && cnt !== null)
2798
- bySource[source] = cnt;
2799
- }
2800
- for (const row of statusResult.rows) {
2801
- const status = asString(pickCell(row, "status"));
2802
- const cnt = asNumber(pickCell(row, "cnt"));
2803
- if (status && cnt !== null)
2804
- byStatus[status] = cnt;
119
+ getCurrentStepId(trajectoryId) {
120
+ return this.activeStepIds.get(trajectoryId) || null;
121
+ }
122
+ completeStep(trajectoryId, stepId, action, rewardInfo) {
123
+ const trajectory = this.activeTrajectories.get(trajectoryId);
124
+ if (!trajectory) {
125
+ logger.warn({ trajectoryId }, "Trajectory not found for completeStep");
126
+ return;
2805
127
  }
2806
- for (const row of scenarioResult.rows) {
2807
- const scenario = asString(pickCell(row, "scenario_id"));
2808
- const cnt = asNumber(pickCell(row, "cnt"));
2809
- if (scenario && cnt !== null)
2810
- byScenario[scenario] = cnt;
128
+ const step = trajectory.steps.find((s) => s.stepId === stepId);
129
+ if (!step) {
130
+ logger.warn({ trajectoryId, stepId }, "Step not found for completeStep");
131
+ return;
2811
132
  }
2812
- return {
2813
- totalTrajectories: asNumber(pickCell(stats, "total_trajectories")) ?? 0,
2814
- totalSteps: asNumber(pickCell(stats, "total_steps")) ?? 0,
2815
- totalLlmCalls: asNumber(pickCell(stats, "total_llm_calls")) ?? 0,
2816
- totalPromptTokens: asNumber(pickCell(stats, "total_prompt_tokens")) ?? 0,
2817
- totalCompletionTokens: asNumber(pickCell(stats, "total_completion_tokens")) ?? 0,
2818
- averageDurationMs: asNumber(pickCell(stats, "avg_duration_ms")) ?? 0,
2819
- averageReward: asNumber(pickCell(stats, "avg_reward")) ?? 0,
2820
- bySource,
2821
- byStatus,
2822
- byScenario
2823
- };
2824
- }
2825
- async deleteTrajectories(trajectoryIds) {
2826
- const runtime = this.runtime;
2827
- if (!runtime?.adapter)
2828
- return 0;
2829
- if (trajectoryIds.length === 0)
2830
- return 0;
2831
- const ids = trajectoryIds.map(sqlLiteral).join(", ");
2832
- const result = await this.executeRawSql(`DELETE FROM trajectories WHERE id IN (${ids}) RETURNING id`);
2833
- return result.rows.length;
2834
- }
2835
- async clearAllTrajectories() {
2836
- const runtime = this.runtime;
2837
- if (!runtime?.adapter)
2838
- return 0;
2839
- const countResult = await this.executeRawSql(`SELECT count(*)::int AS cnt FROM trajectories`);
2840
- const count2 = asNumber(pickCell(countResult.rows[0] ?? {}, "cnt")) ?? 0;
2841
- await this.executeRawSql(`DELETE FROM trajectories`);
2842
- return count2;
2843
- }
2844
- sanitizeZipFolderName(value) {
2845
- const sanitized = value.trim().replace(/[^a-zA-Z0-9._-]+/g, "_").replace(/^_+|_+$/g, "");
2846
- return sanitized || "trajectory";
2847
- }
2848
- redactTrajectoryPrompts(trajectory) {
2849
- return {
2850
- ...trajectory,
2851
- steps: trajectory.steps.map((step) => ({
2852
- ...step,
2853
- llmCalls: step.llmCalls.map((call) => ({
2854
- ...call,
2855
- systemPrompt: "[redacted]",
2856
- userPrompt: "[redacted]",
2857
- response: "[redacted]"
2858
- }))
2859
- }))
133
+ step.action = {
134
+ attemptId: uuidv4(),
135
+ timestamp: Date.now(),
136
+ ...action
2860
137
  };
2861
- }
2862
- buildZipSummary(trajectory) {
2863
- const finalStatus = trajectory.metrics?.finalStatus ?? "completed";
2864
- const normalizedEndTime = typeof trajectory.endTime === "number" && trajectory.endTime > 0 ? trajectory.endTime : null;
2865
- const status = finalStatus === "timeout" || finalStatus === "terminated" || finalStatus === "error" ? "error" : finalStatus === "completed" ? "completed" : normalizedEndTime ? "completed" : "active";
2866
- let llmCallCount = 0;
2867
- let providerAccessCount = 0;
2868
- let totalPromptTokens = 0;
2869
- let totalCompletionTokens = 0;
2870
- for (const step of trajectory.steps) {
2871
- providerAccessCount += step.providerAccesses.length;
2872
- llmCallCount += step.llmCalls.length;
2873
- for (const call of step.llmCalls) {
2874
- totalPromptTokens += call.promptTokens ?? 0;
2875
- totalCompletionTokens += call.completionTokens ?? 0;
2876
- }
138
+ if (rewardInfo?.reward !== undefined) {
139
+ step.reward = rewardInfo.reward;
140
+ trajectory.totalReward += rewardInfo.reward;
141
+ }
142
+ if (rewardInfo?.components) {
143
+ trajectory.rewardComponents = {
144
+ ...trajectory.rewardComponents,
145
+ ...rewardInfo.components
146
+ };
2877
147
  }
2878
- const metadata = trajectory.metadata ?? {};
2879
- const asNullableString = (value) => typeof value === "string" ? value : null;
2880
- const source = typeof metadata.source === "string" ? metadata.source : "chat";
2881
- const normalizedDurationMs = status === "active" ? null : typeof trajectory.durationMs === "number" ? trajectory.durationMs : null;
2882
- const updatedAtMs = normalizedEndTime ?? (trajectory.startTime || Date.now());
2883
- return {
2884
- id: trajectory.trajectoryId,
2885
- agentId: trajectory.agentId,
2886
- roomId: asNullableString(metadata.roomId),
2887
- entityId: asNullableString(metadata.entityId),
2888
- conversationId: asNullableString(metadata.conversationId),
2889
- source,
2890
- status,
2891
- startTime: trajectory.startTime,
2892
- endTime: normalizedEndTime,
2893
- durationMs: normalizedDurationMs,
2894
- llmCallCount,
2895
- providerAccessCount,
2896
- totalPromptTokens,
2897
- totalCompletionTokens,
2898
- metadata,
2899
- createdAt: new Date(trajectory.startTime).toISOString(),
2900
- updatedAt: new Date(updatedAtMs).toISOString()
2901
- };
148
+ this.activeStepIds.delete(trajectoryId);
2902
149
  }
2903
- async exportTrajectoriesZip(options = {}) {
2904
- let targetIds = Array.isArray(options.trajectoryIds) ? options.trajectoryIds.filter((id) => typeof id === "string" && id.trim().length > 0) : [];
2905
- if (targetIds.length === 0) {
2906
- const list = await this.listTrajectories({
2907
- limit: 500,
2908
- startDate: options.startDate,
2909
- endDate: options.endDate,
2910
- scenarioId: options.scenarioId,
2911
- batchId: options.batchId
2912
- });
2913
- targetIds = list.trajectories.map((trajectory) => trajectory.id);
2914
- }
2915
- const entries = [];
2916
- const manifestRows = [];
2917
- for (const trajectoryId of targetIds) {
2918
- const detail = await this.getTrajectoryDetail(trajectoryId);
2919
- if (!detail)
2920
- continue;
2921
- const exportTrajectory = options.includePrompts === false ? this.redactTrajectoryPrompts(detail) : detail;
2922
- const summary = this.buildZipSummary(exportTrajectory);
2923
- const folderName = this.sanitizeZipFolderName(trajectoryId);
2924
- entries.push({
2925
- name: `${folderName}/trajectory.json`,
2926
- data: JSON.stringify(exportTrajectory, null, 2)
2927
- });
2928
- entries.push({
2929
- name: `${folderName}/summary.json`,
2930
- data: JSON.stringify(summary, null, 2)
2931
- });
2932
- manifestRows.push({
2933
- trajectoryId,
2934
- folder: folderName,
2935
- createdAt: summary.createdAt
2936
- });
150
+ completeCurrentStep(trajectoryId, action, rewardInfo) {
151
+ const stepId = this.activeStepIds.get(trajectoryId);
152
+ if (!stepId) {
153
+ logger.warn({ trajectoryId }, "No active step for trajectory");
154
+ return;
2937
155
  }
2938
- entries.unshift({
2939
- name: "manifest.json",
2940
- data: JSON.stringify({
2941
- exportedAt: new Date().toISOString(),
2942
- trajectories: manifestRows
2943
- }, null, 2)
2944
- });
2945
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
2946
- return {
2947
- filename: `trajectories-${timestamp}.zip`,
2948
- entries
2949
- };
156
+ this.completeStep(trajectoryId, stepId, action, rewardInfo);
2950
157
  }
2951
- async exportTrajectories(options) {
2952
- const runtime = this.runtime;
2953
- if (!runtime?.adapter) {
2954
- throw new Error("Database not available");
2955
- }
2956
- const whereClauses = [];
2957
- if (options.trajectoryIds && options.trajectoryIds.length > 0) {
2958
- const ids = options.trajectoryIds.map(sqlLiteral).join(", ");
2959
- whereClauses.push(`id IN (${ids})`);
2960
- }
2961
- if (options.startDate) {
2962
- whereClauses.push(`created_at >= ${sqlLiteral(options.startDate)}::timestamptz`);
2963
- }
2964
- if (options.endDate) {
2965
- whereClauses.push(`created_at <= ${sqlLiteral(options.endDate)}::timestamptz`);
2966
- }
2967
- if (options.scenarioId) {
2968
- whereClauses.push(`scenario_id = ${sqlLiteral(options.scenarioId)}`);
2969
- }
2970
- if (options.batchId) {
2971
- whereClauses.push(`batch_id = ${sqlLiteral(options.batchId)}`);
158
+ async endTrajectory(trajectoryId, status, finalMetrics) {
159
+ const trajectory = this.activeTrajectories.get(trajectoryId);
160
+ if (!trajectory) {
161
+ logger.warn({ trajectoryId }, "Trajectory not found for endTrajectory");
162
+ return;
2972
163
  }
2973
- const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
2974
- const result = await this.executeRawSql(`SELECT * FROM trajectories ${whereClause} ORDER BY created_at DESC`);
2975
- const trajectories = result.rows.map((row) => this.rowToTrajectory(row));
2976
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
2977
- if (options.format === "csv") {
2978
- const lines = [
2979
- "id,agent_id,source,status,start_time,end_time,duration_ms,step_count,llm_call_count,total_reward,scenario_id"
2980
- ];
2981
- for (const t of trajectories) {
2982
- lines.push([
2983
- t.trajectoryId,
2984
- t.agentId,
2985
- t.metadata.source ?? "chat",
2986
- t.metrics.finalStatus,
2987
- t.startTime,
2988
- t.endTime,
2989
- t.durationMs,
2990
- t.steps.length,
2991
- t.steps.reduce((sum2, s) => sum2 + s.llmCalls.length, 0),
2992
- t.totalReward,
2993
- t.scenarioId ?? ""
2994
- ].join(","));
2995
- }
2996
- return {
2997
- data: lines.join(`
2998
- `),
2999
- filename: `trajectories-${timestamp}.csv`,
3000
- mimeType: "text/csv"
164
+ trajectory.endTime = Date.now();
165
+ trajectory.durationMs = trajectory.endTime - trajectory.startTime;
166
+ trajectory.metrics.finalStatus = status;
167
+ trajectory.metrics.episodeLength = trajectory.steps.length;
168
+ if (finalMetrics) {
169
+ trajectory.metrics = {
170
+ ...trajectory.metrics,
171
+ ...finalMetrics
3001
172
  };
3002
173
  }
3003
- let exportData = trajectories;
3004
- if (!options.includePrompts) {
3005
- exportData = trajectories.map((trajectory) => this.redactTrajectoryPrompts(trajectory));
3006
- }
3007
- return {
3008
- data: JSON.stringify(exportData, null, 2),
3009
- filename: `trajectories-${timestamp}.json`,
3010
- mimeType: "application/json"
3011
- };
3012
- }
3013
- rowToTrajectory(row) {
3014
- const parseJson = (cell, fallback) => {
3015
- if (typeof cell === "string") {
3016
- try {
3017
- return JSON.parse(cell);
3018
- } catch {
3019
- return fallback;
3020
- }
3021
- }
3022
- if (typeof cell === "object" && cell !== null && !Array.isArray(cell)) {
3023
- return cell;
3024
- }
3025
- return fallback;
3026
- };
3027
- return {
3028
- trajectoryId: asString(pickCell(row, "id")) ?? "",
3029
- agentId: asString(pickCell(row, "agent_id")) ?? "",
3030
- startTime: asNumber(pickCell(row, "start_time")) ?? 0,
3031
- endTime: asNumber(pickCell(row, "end_time")) ?? 0,
3032
- durationMs: asNumber(pickCell(row, "duration_ms")) ?? 0,
3033
- scenarioId: asString(pickCell(row, "scenario_id")) ?? undefined,
3034
- episodeId: asString(pickCell(row, "episode_id")) ?? undefined,
3035
- batchId: asString(pickCell(row, "batch_id")) ?? undefined,
3036
- groupIndex: asNumber(pickCell(row, "group_index")) ?? undefined,
3037
- steps: parseJson(pickCell(row, "steps_json", "steps"), []),
3038
- totalReward: asNumber(pickCell(row, "total_reward")) ?? 0,
3039
- rewardComponents: parseJson(pickCell(row, "reward_components_json", "reward_components"), { environmentReward: 0 }),
3040
- metrics: parseJson(pickCell(row, "metrics_json", "metrics"), {
3041
- episodeLength: 0,
3042
- finalStatus: "completed"
3043
- }),
3044
- metadata: parseJson(pickCell(row, "metadata_json", "metadata"), {})
3045
- };
174
+ this.activeStepIds.delete(trajectoryId);
3046
175
  }
3047
176
  getActiveTrajectory(trajectoryId) {
3048
- return null;
3049
- }
3050
- getCurrentStepId(trajectoryId) {
3051
- return this.activeStepIds.get(trajectoryId) || null;
3052
- }
3053
- getProviderAccessLogs() {
3054
- return [];
177
+ return this.activeTrajectories.get(trajectoryId) || null;
3055
178
  }
3056
- getLlmCallLogs() {
3057
- return [];
179
+ findTrajectoryByStepId(stepId) {
180
+ for (const trajectory of this.activeTrajectories.values()) {
181
+ if (trajectory.steps.some((s) => s.stepId === stepId)) {
182
+ return trajectory;
183
+ }
184
+ }
185
+ return null;
3058
186
  }
3059
187
  }
188
+
3060
189
  // action-interceptor.ts
3061
- import { logger as logger3 } from "@elizaos/core";
190
+ import { logger as logger2 } from "@elizaos/core";
3062
191
  var trajectoryContexts = new WeakMap;
3063
192
  function setTrajectoryContext(runtime, trajectoryId, trajectoryLogger) {
3064
193
  trajectoryContexts.set(runtime, { trajectoryId, logger: trajectoryLogger });
@@ -3082,7 +211,7 @@ function wrapActionWithLogging(action, _trajectoryLogger) {
3082
211
  const { trajectoryId, logger: loggerService } = context;
3083
212
  const stepId = loggerService.getCurrentStepId(trajectoryId);
3084
213
  if (!stepId) {
3085
- logger3.warn({ action: action.name, trajectoryId }, "No active step for action execution");
214
+ logger2.warn({ action: action.name, trajectoryId }, "No active step for action execution");
3086
215
  const result = await originalHandler(runtime, message, state, options, callback);
3087
216
  return result ?? undefined;
3088
217
  }
@@ -3102,7 +231,7 @@ function wrapActionWithLogging(action, _trajectoryLogger) {
3102
231
  };
3103
232
  const errorHandler = (err) => {
3104
233
  const error = err instanceof Error ? err.message : typeof err === "string" ? err : err.message || String(err);
3105
- logger3.error({ action: action.name, trajectoryId, error }, "Action execution failed");
234
+ logger2.error({ action: action.name, trajectoryId, error }, "Action execution failed");
3106
235
  const stateSnapshot = state ? JSON.parse(JSON.stringify(state)) : null;
3107
236
  loggerService.completeStep(trajectoryId, stepId, {
3108
237
  actionType: action.name,
@@ -3145,7 +274,7 @@ function wrapPluginActions(plugin, trajectoryLogger) {
3145
274
  function logLLMCallFromAction(actionContext, trajectoryLogger, trajectoryId) {
3146
275
  const stepId = trajectoryLogger.getCurrentStepId(trajectoryId);
3147
276
  if (!stepId) {
3148
- logger3.warn({ trajectoryId }, "No active step for LLM call from action");
277
+ logger2.warn({ trajectoryId }, "No active step for LLM call from action");
3149
278
  return;
3150
279
  }
3151
280
  trajectoryLogger.logLLMCall(stepId, {
@@ -3166,7 +295,7 @@ function logLLMCallFromAction(actionContext, trajectoryLogger, trajectoryId) {
3166
295
  function logProviderFromAction(actionContext, trajectoryLogger, trajectoryId) {
3167
296
  const stepId = trajectoryLogger.getCurrentStepId(trajectoryId);
3168
297
  if (!stepId) {
3169
- logger3.warn({ trajectoryId }, "No active step for provider access from action");
298
+ logger2.warn({ trajectoryId }, "No active step for provider access from action");
3170
299
  return;
3171
300
  }
3172
301
  trajectoryLogger.logProviderAccess(stepId, {
@@ -3188,7 +317,7 @@ function wrapProviderWithLogging(provider, _trajectoryLogger) {
3188
317
  const { trajectoryId, logger: loggerService } = context;
3189
318
  const stepId = loggerService.getCurrentStepId(trajectoryId);
3190
319
  if (!stepId) {
3191
- logger3.warn({ provider: provider.name, trajectoryId }, "No active step for provider access");
320
+ logger2.warn({ provider: provider.name, trajectoryId }, "No active step for provider access");
3192
321
  return originalGet?.(runtime, message, state) || { text: "" };
3193
322
  }
3194
323
  const result = await originalGet?.(runtime, message, state) || { text: "" };
@@ -3390,14 +519,14 @@ function toARTJSONL(trajectory) {
3390
519
  return JSON.stringify(toARTTrajectory(trajectory));
3391
520
  }
3392
521
  function validateARTCompatibility(trajectory) {
3393
- const errors2 = [];
522
+ const errors = [];
3394
523
  const warnings = [];
3395
524
  if (trajectory.steps.length === 0) {
3396
- errors2.push("Trajectory has no steps");
525
+ errors.push("Trajectory has no steps");
3397
526
  }
3398
527
  for (const [idx, step] of trajectory.steps.entries()) {
3399
528
  if (step.llmCalls.length === 0) {
3400
- errors2.push(`Step ${idx} has no LLM calls - can't extract messages`);
529
+ errors.push(`Step ${idx} has no LLM calls - can't extract messages`);
3401
530
  }
3402
531
  for (const llmCall of step.llmCalls) {
3403
532
  if (!llmCall.userPrompt || llmCall.userPrompt.length < 10) {
@@ -3409,15 +538,15 @@ function validateARTCompatibility(trajectory) {
3409
538
  }
3410
539
  }
3411
540
  if (trajectory.totalReward === undefined || Number.isNaN(trajectory.totalReward)) {
3412
- errors2.push("Trajectory has no valid reward");
541
+ errors.push("Trajectory has no valid reward");
3413
542
  }
3414
543
  const artTraj = toARTTrajectory(trajectory);
3415
544
  if (artTraj.messages.length < 2) {
3416
545
  warnings.push("Trajectory converts to very few messages (< 2)");
3417
546
  }
3418
547
  return {
3419
- valid: errors2.length === 0,
3420
- errors: errors2,
548
+ valid: errors.length === 0,
549
+ errors,
3421
550
  warnings
3422
551
  };
3423
552
  }
@@ -3513,9 +642,9 @@ async function buildGameStateFromDB(_trajectoryId) {
3513
642
  }
3514
643
  async function recomputeTrajectoryRewards(_trajectoryIds) {}
3515
644
  // integration.ts
3516
- import { logger as logger4 } from "@elizaos/core";
3517
- async function startAutonomousTick(trajectoryLogger, context) {
3518
- const trajectoryId = await trajectoryLogger.startTrajectory(context.agentId, {
645
+ import { logger as logger3 } from "@elizaos/core";
646
+ function startAutonomousTick(trajectoryLogger, context) {
647
+ const trajectoryId = trajectoryLogger.startTrajectory(context.agentId, {
3519
648
  scenarioId: context.scenarioId,
3520
649
  episodeId: context.episodeId,
3521
650
  batchId: context.batchId,
@@ -3529,17 +658,17 @@ async function startAutonomousTick(trajectoryLogger, context) {
3529
658
  openPositions: 0
3530
659
  };
3531
660
  trajectoryLogger.startStep(trajectoryId, envState);
3532
- logger4.info({ trajectoryId, agentId: context.agentId }, "Started autonomous tick trajectory");
661
+ logger3.info({ trajectoryId, agentId: context.agentId }, "Started autonomous tick trajectory");
3533
662
  return trajectoryId;
3534
663
  }
3535
664
  async function endAutonomousTick(trajectoryLogger, trajectoryId, status = "completed", finalMetrics) {
3536
665
  await trajectoryLogger.endTrajectory(trajectoryId, status, finalMetrics);
3537
- logger4.info({ trajectoryId, status }, "Ended autonomous tick trajectory");
666
+ logger3.info({ trajectoryId, status }, "Ended autonomous tick trajectory");
3538
667
  }
3539
668
  async function loggedLLMCall(trajectoryLogger, trajectoryId, options, llmCallFn) {
3540
669
  const stepId = trajectoryLogger.getCurrentStepId(trajectoryId);
3541
670
  if (!stepId) {
3542
- logger4.warn({ trajectoryId }, "No active step for LLM call");
671
+ logger3.warn({ trajectoryId }, "No active step for LLM call");
3543
672
  const result2 = await llmCallFn();
3544
673
  return result2.text;
3545
674
  }
@@ -3644,13 +773,13 @@ class RewardService {
3644
773
  return (score + 1) / 2;
3645
774
  }
3646
775
  normalizeScoresForGroup(scores) {
3647
- const min2 = Math.min(...scores);
3648
- const max2 = Math.max(...scores);
3649
- const range = max2 - min2;
776
+ const min = Math.min(...scores);
777
+ const max = Math.max(...scores);
778
+ const range = max - min;
3650
779
  if (range === 0) {
3651
780
  return scores.map(() => 0.5);
3652
781
  }
3653
- return scores.map((s) => (s - min2) / range);
782
+ return scores.map((s) => (s - min) / range);
3654
783
  }
3655
784
  }
3656
785
  function createRewardService(options = {}) {
@@ -3680,18 +809,16 @@ var trajectoryLoggerPlugin = {
3680
809
  if (!message || !runtime)
3681
810
  return;
3682
811
  if (!message.metadata) {
3683
- message.metadata = {
3684
- type: "message"
3685
- };
812
+ message.metadata = { type: "message" };
3686
813
  }
3687
814
  const meta = message.metadata;
3688
- const logger5 = runtime.getService("trajectory_logger");
3689
- if (!logger5)
815
+ const logger4 = runtime.getService("trajectory_logger");
816
+ if (!logger4)
3690
817
  return;
3691
818
  let trajectoryStepId = crypto.randomUUID();
3692
819
  meta.trajectoryStepId = trajectoryStepId;
3693
820
  try {
3694
- const trajectoryId = await logger5.startTrajectory(runtime.agentId, {
821
+ const trajectoryId = await logger4.startTrajectory(runtime.agentId, {
3695
822
  source: source ?? meta.source ?? "chat",
3696
823
  metadata: {
3697
824
  roomId: message.roomId,
@@ -3703,7 +830,7 @@ var trajectoryLoggerPlugin = {
3703
830
  });
3704
831
  const normalizedTrajectoryId = typeof trajectoryId === "string" && trajectoryId.trim().length > 0 ? trajectoryId : null;
3705
832
  if (normalizedTrajectoryId) {
3706
- const runtimeStepId = logger5.startStep(normalizedTrajectoryId, {
833
+ const runtimeStepId = logger4.startStep(normalizedTrajectoryId, {
3707
834
  timestamp: Date.now(),
3708
835
  agentBalance: 0,
3709
836
  agentPoints: 0,
@@ -3714,17 +841,13 @@ var trajectoryLoggerPlugin = {
3714
841
  trajectoryStepId = normalizedStepId;
3715
842
  meta.trajectoryStepId = trajectoryStepId;
3716
843
  pendingTrajectoryEndTargetByStepId.set(trajectoryStepId, normalizedTrajectoryId);
3717
- } else {}
844
+ }
3718
845
  if (message.id) {
3719
846
  const replyId = createUniqueUuid(runtime, message.id);
3720
847
  pendingTrajectoryStepByReplyId.set(replyId, trajectoryStepId);
3721
848
  }
3722
849
  } catch (err) {
3723
- runtime.logger?.warn({
3724
- err,
3725
- src: "plugin-trajectory-logger",
3726
- roomId: message.roomId
3727
- }, "Failed to start trajectory logging");
850
+ runtime.logger?.warn({ err, src: "plugin-trajectory-logger", roomId: message.roomId }, "Failed to start trajectory logging");
3728
851
  }
3729
852
  }
3730
853
  ],
@@ -3741,18 +864,14 @@ var trajectoryLoggerPlugin = {
3741
864
  }
3742
865
  if (!trajectoryStepId)
3743
866
  return;
3744
- const logger5 = runtime.getService("trajectory_logger");
3745
- if (!logger5)
867
+ const logger4 = runtime.getService("trajectory_logger");
868
+ if (!logger4)
3746
869
  return;
3747
870
  try {
3748
871
  const endTarget = pendingTrajectoryEndTargetByStepId.get(trajectoryStepId) ?? trajectoryStepId;
3749
- await logger5.endTrajectory(endTarget, "completed");
872
+ await logger4.endTrajectory(endTarget, "completed");
3750
873
  } catch (err) {
3751
- runtime.logger?.warn({
3752
- err,
3753
- src: "plugin-trajectory-logger",
3754
- trajectoryStepId
3755
- }, "Failed to end trajectory logging");
874
+ runtime.logger?.warn({ err, src: "plugin-trajectory-logger", trajectoryStepId }, "Failed to end trajectory logging");
3756
875
  }
3757
876
  if (inReplyTo) {
3758
877
  pendingTrajectoryStepByReplyId.delete(inReplyTo);
@@ -3803,4 +922,4 @@ export {
3803
922
  RewardService
3804
923
  };
3805
924
 
3806
- //# debugId=FBBDF38FEFEB663664756E2164756E21
925
+ //# debugId=F0E0006C38150F8464756E2164756E21