@elizaos/plugin-trajectory-logger 2.0.0-alpha.6 → 2.0.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/node/index.node.js +708 -234
- package/dist/node/index.node.js.map +5 -5
- package/package.json +2 -2
package/dist/node/index.node.js
CHANGED
|
@@ -10,7 +10,7 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
12
12
|
|
|
13
|
-
//
|
|
13
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/entity.js
|
|
14
14
|
function is(value, type) {
|
|
15
15
|
if (!value || typeof value !== "object") {
|
|
16
16
|
return false;
|
|
@@ -38,7 +38,7 @@ var init_entity = __esm(() => {
|
|
|
38
38
|
hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
//
|
|
41
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/column.js
|
|
42
42
|
var Column;
|
|
43
43
|
var init_column = __esm(() => {
|
|
44
44
|
init_entity();
|
|
@@ -92,7 +92,7 @@ var init_column = __esm(() => {
|
|
|
92
92
|
};
|
|
93
93
|
});
|
|
94
94
|
|
|
95
|
-
//
|
|
95
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/column-builder.js
|
|
96
96
|
var ColumnBuilder;
|
|
97
97
|
var init_column_builder = __esm(() => {
|
|
98
98
|
init_entity();
|
|
@@ -152,19 +152,19 @@ var init_column_builder = __esm(() => {
|
|
|
152
152
|
};
|
|
153
153
|
});
|
|
154
154
|
|
|
155
|
-
//
|
|
155
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/table.utils.js
|
|
156
156
|
var TableName;
|
|
157
157
|
var init_table_utils = __esm(() => {
|
|
158
158
|
TableName = Symbol.for("drizzle:Name");
|
|
159
159
|
});
|
|
160
160
|
|
|
161
|
-
//
|
|
161
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/tracing-utils.js
|
|
162
162
|
function iife(fn, ...args) {
|
|
163
163
|
return fn(...args);
|
|
164
164
|
}
|
|
165
165
|
var init_tracing_utils = () => {};
|
|
166
166
|
|
|
167
|
-
//
|
|
167
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/pg-core/unique-constraint.js
|
|
168
168
|
function uniqueKeyName(table, columns) {
|
|
169
169
|
return `${table[TableName]}_${columns.join("_")}_unique`;
|
|
170
170
|
}
|
|
@@ -172,7 +172,7 @@ var init_unique_constraint = __esm(() => {
|
|
|
172
172
|
init_table_utils();
|
|
173
173
|
});
|
|
174
174
|
|
|
175
|
-
//
|
|
175
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/pg-core/columns/common.js
|
|
176
176
|
var PgColumn, ExtraConfigColumn;
|
|
177
177
|
var init_common = __esm(() => {
|
|
178
178
|
init_column();
|
|
@@ -226,7 +226,7 @@ var init_common = __esm(() => {
|
|
|
226
226
|
};
|
|
227
227
|
});
|
|
228
228
|
|
|
229
|
-
//
|
|
229
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/pg-core/columns/enum.js
|
|
230
230
|
function isPgEnum(obj) {
|
|
231
231
|
return !!obj && typeof obj === "function" && isPgEnumSym in obj && obj[isPgEnumSym] === true;
|
|
232
232
|
}
|
|
@@ -261,7 +261,7 @@ var init_enum = __esm(() => {
|
|
|
261
261
|
};
|
|
262
262
|
});
|
|
263
263
|
|
|
264
|
-
//
|
|
264
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/subquery.js
|
|
265
265
|
var Subquery, WithSubquery;
|
|
266
266
|
var init_subquery = __esm(() => {
|
|
267
267
|
init_entity();
|
|
@@ -283,11 +283,11 @@ var init_subquery = __esm(() => {
|
|
|
283
283
|
};
|
|
284
284
|
});
|
|
285
285
|
|
|
286
|
-
//
|
|
286
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/version.js
|
|
287
287
|
var version = "0.45.1";
|
|
288
288
|
var init_version = () => {};
|
|
289
289
|
|
|
290
|
-
//
|
|
290
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/tracing.js
|
|
291
291
|
var otel, rawTracer, tracer;
|
|
292
292
|
var init_tracing = __esm(() => {
|
|
293
293
|
init_tracing_utils();
|
|
@@ -317,13 +317,13 @@ var init_tracing = __esm(() => {
|
|
|
317
317
|
};
|
|
318
318
|
});
|
|
319
319
|
|
|
320
|
-
//
|
|
320
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/view-common.js
|
|
321
321
|
var ViewBaseConfig;
|
|
322
322
|
var init_view_common = __esm(() => {
|
|
323
323
|
ViewBaseConfig = Symbol.for("drizzle:ViewBaseConfig");
|
|
324
324
|
});
|
|
325
325
|
|
|
326
|
-
//
|
|
326
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/table.js
|
|
327
327
|
function isTable(table) {
|
|
328
328
|
return typeof table === "object" && table !== null && IsDrizzleTable in table;
|
|
329
329
|
}
|
|
@@ -374,7 +374,7 @@ var init_table = __esm(() => {
|
|
|
374
374
|
};
|
|
375
375
|
});
|
|
376
376
|
|
|
377
|
-
//
|
|
377
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/sql/sql.js
|
|
378
378
|
function isSQLWrapper(value) {
|
|
379
379
|
return value !== null && value !== undefined && typeof value.getSQL === "function";
|
|
380
380
|
}
|
|
@@ -776,7 +776,7 @@ var init_sql = __esm(() => {
|
|
|
776
776
|
};
|
|
777
777
|
});
|
|
778
778
|
|
|
779
|
-
//
|
|
779
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/alias.js
|
|
780
780
|
function aliasedTable(table, tableAlias) {
|
|
781
781
|
return new Proxy(table, new TableAliasProxyHandler(tableAlias, false));
|
|
782
782
|
}
|
|
@@ -877,7 +877,7 @@ var init_alias = __esm(() => {
|
|
|
877
877
|
};
|
|
878
878
|
});
|
|
879
879
|
|
|
880
|
-
//
|
|
880
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/errors.js
|
|
881
881
|
var DrizzleError, DrizzleQueryError, TransactionRollbackError;
|
|
882
882
|
var init_errors = __esm(() => {
|
|
883
883
|
init_entity();
|
|
@@ -909,7 +909,7 @@ params: ${params}`);
|
|
|
909
909
|
};
|
|
910
910
|
});
|
|
911
911
|
|
|
912
|
-
//
|
|
912
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/logger.js
|
|
913
913
|
var ConsoleLogWriter, DefaultLogger, NoopLogger;
|
|
914
914
|
var init_logger = __esm(() => {
|
|
915
915
|
init_entity();
|
|
@@ -943,7 +943,7 @@ var init_logger = __esm(() => {
|
|
|
943
943
|
};
|
|
944
944
|
});
|
|
945
945
|
|
|
946
|
-
//
|
|
946
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/query-promise.js
|
|
947
947
|
var QueryPromise;
|
|
948
948
|
var init_query_promise = __esm(() => {
|
|
949
949
|
init_entity();
|
|
@@ -968,7 +968,7 @@ var init_query_promise = __esm(() => {
|
|
|
968
968
|
};
|
|
969
969
|
});
|
|
970
970
|
|
|
971
|
-
//
|
|
971
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/utils.js
|
|
972
972
|
function mapResultRow(columns, row, joinsNotNullableMap) {
|
|
973
973
|
const nullifyMap = {};
|
|
974
974
|
const result = columns.reduce((result2, { path, field }, columnIndex) => {
|
|
@@ -1134,7 +1134,7 @@ var init_utils = __esm(() => {
|
|
|
1134
1134
|
textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder;
|
|
1135
1135
|
});
|
|
1136
1136
|
|
|
1137
|
-
//
|
|
1137
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/pg-core/table.js
|
|
1138
1138
|
var InlineForeignKeys, EnableRLS, PgTable;
|
|
1139
1139
|
var init_table2 = __esm(() => {
|
|
1140
1140
|
init_entity();
|
|
@@ -1154,7 +1154,7 @@ var init_table2 = __esm(() => {
|
|
|
1154
1154
|
};
|
|
1155
1155
|
});
|
|
1156
1156
|
|
|
1157
|
-
//
|
|
1157
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/pg-core/primary-keys.js
|
|
1158
1158
|
var PrimaryKeyBuilder, PrimaryKey;
|
|
1159
1159
|
var init_primary_keys = __esm(() => {
|
|
1160
1160
|
init_entity();
|
|
@@ -1186,7 +1186,7 @@ var init_primary_keys = __esm(() => {
|
|
|
1186
1186
|
};
|
|
1187
1187
|
});
|
|
1188
1188
|
|
|
1189
|
-
//
|
|
1189
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/sql/expressions/conditions.js
|
|
1190
1190
|
function bindIfParam(value, column) {
|
|
1191
1191
|
if (isDriverValueEncoder(column) && !isSQLWrapper(value) && !is(value, Param) && !is(value, Placeholder) && !is(value, Column) && !is(value, Table) && !is(value, View)) {
|
|
1192
1192
|
return new Param(value, column);
|
|
@@ -1322,7 +1322,7 @@ var init_conditions = __esm(() => {
|
|
|
1322
1322
|
init_sql();
|
|
1323
1323
|
});
|
|
1324
1324
|
|
|
1325
|
-
//
|
|
1325
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/sql/expressions/select.js
|
|
1326
1326
|
function asc(column) {
|
|
1327
1327
|
return sql`${column} asc`;
|
|
1328
1328
|
}
|
|
@@ -1333,13 +1333,13 @@ var init_select = __esm(() => {
|
|
|
1333
1333
|
init_sql();
|
|
1334
1334
|
});
|
|
1335
1335
|
|
|
1336
|
-
//
|
|
1336
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/sql/expressions/index.js
|
|
1337
1337
|
var init_expressions = __esm(() => {
|
|
1338
1338
|
init_conditions();
|
|
1339
1339
|
init_select();
|
|
1340
1340
|
});
|
|
1341
1341
|
|
|
1342
|
-
//
|
|
1342
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/relations.js
|
|
1343
1343
|
function getOperators() {
|
|
1344
1344
|
return {
|
|
1345
1345
|
and,
|
|
@@ -1571,7 +1571,7 @@ var init_relations = __esm(() => {
|
|
|
1571
1571
|
};
|
|
1572
1572
|
});
|
|
1573
1573
|
|
|
1574
|
-
//
|
|
1574
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/sql/functions/aggregate.js
|
|
1575
1575
|
function count(expression) {
|
|
1576
1576
|
return sql`count(${expression || sql.raw("*")})`.mapWith(Number);
|
|
1577
1577
|
}
|
|
@@ -1602,7 +1602,7 @@ var init_aggregate = __esm(() => {
|
|
|
1602
1602
|
init_sql();
|
|
1603
1603
|
});
|
|
1604
1604
|
|
|
1605
|
-
//
|
|
1605
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/sql/functions/vector.js
|
|
1606
1606
|
function toSql(value) {
|
|
1607
1607
|
return JSON.stringify(value);
|
|
1608
1608
|
}
|
|
@@ -1646,20 +1646,20 @@ var init_vector = __esm(() => {
|
|
|
1646
1646
|
init_sql();
|
|
1647
1647
|
});
|
|
1648
1648
|
|
|
1649
|
-
//
|
|
1649
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/sql/functions/index.js
|
|
1650
1650
|
var init_functions = __esm(() => {
|
|
1651
1651
|
init_aggregate();
|
|
1652
1652
|
init_vector();
|
|
1653
1653
|
});
|
|
1654
1654
|
|
|
1655
|
-
//
|
|
1655
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/sql/index.js
|
|
1656
1656
|
var init_sql2 = __esm(() => {
|
|
1657
1657
|
init_expressions();
|
|
1658
1658
|
init_functions();
|
|
1659
1659
|
init_sql();
|
|
1660
1660
|
});
|
|
1661
1661
|
|
|
1662
|
-
//
|
|
1662
|
+
// ../../../node_modules/.bun/drizzle-orm@0.45.1/node_modules/drizzle-orm/index.js
|
|
1663
1663
|
var exports_drizzle_orm = {};
|
|
1664
1664
|
__export(exports_drizzle_orm, {
|
|
1665
1665
|
textDecoder: () => textDecoder,
|
|
@@ -1845,7 +1845,7 @@ function sqlLiteral(v) {
|
|
|
1845
1845
|
if (typeof v === "boolean")
|
|
1846
1846
|
return v ? "TRUE" : "FALSE";
|
|
1847
1847
|
if (typeof v === "object")
|
|
1848
|
-
return `'${JSON.stringify(v).replace(/'/g, "''")}'
|
|
1848
|
+
return `'${JSON.stringify(v).replace(/'/g, "''")}'`;
|
|
1849
1849
|
return `'${String(v).replace(/'/g, "''")}'`;
|
|
1850
1850
|
}
|
|
1851
1851
|
|
|
@@ -1854,9 +1854,9 @@ class TrajectoryLoggerService extends Service {
|
|
|
1854
1854
|
capabilityDescription = "Captures and persists LLM calls, provider accesses, and full trajectories for debugging, analysis, and RL training";
|
|
1855
1855
|
enabled = true;
|
|
1856
1856
|
initialized = false;
|
|
1857
|
-
activeTrajectories = new Map;
|
|
1858
1857
|
activeStepIds = new Map;
|
|
1859
1858
|
stepToTrajectory = new Map;
|
|
1859
|
+
writeQueues = new Map;
|
|
1860
1860
|
static async start(runtime) {
|
|
1861
1861
|
const service = new TrajectoryLoggerService(runtime);
|
|
1862
1862
|
await service.initialize();
|
|
@@ -1897,9 +1897,92 @@ class TrajectoryLoggerService extends Service {
|
|
|
1897
1897
|
return;
|
|
1898
1898
|
}
|
|
1899
1899
|
await this.ensureTablesExist();
|
|
1900
|
+
await this.backfillTrajectoriesMissingLlmCalls();
|
|
1900
1901
|
this.initialized = true;
|
|
1901
1902
|
logger2.info("[trajectory-logger] Trajectory logger service initialized");
|
|
1902
1903
|
}
|
|
1904
|
+
async getTableColumnNames(tableName) {
|
|
1905
|
+
const names = new Set;
|
|
1906
|
+
try {
|
|
1907
|
+
const result = await this.executeRawSql(`
|
|
1908
|
+
SELECT column_name
|
|
1909
|
+
FROM information_schema.columns
|
|
1910
|
+
WHERE table_name = ${sqlLiteral(tableName)}
|
|
1911
|
+
AND table_schema NOT IN ('pg_catalog', 'information_schema')
|
|
1912
|
+
`);
|
|
1913
|
+
for (const row of result.rows) {
|
|
1914
|
+
const name2 = asString(pickCell(row, "column_name"));
|
|
1915
|
+
if (name2)
|
|
1916
|
+
names.add(name2);
|
|
1917
|
+
}
|
|
1918
|
+
if (names.size > 0)
|
|
1919
|
+
return names;
|
|
1920
|
+
} catch {}
|
|
1921
|
+
const safeTableName = tableName.replace(/[^a-zA-Z0-9_]/g, "");
|
|
1922
|
+
if (!safeTableName)
|
|
1923
|
+
return names;
|
|
1924
|
+
try {
|
|
1925
|
+
const pragma = await this.executeRawSql(`PRAGMA table_info(${safeTableName})`);
|
|
1926
|
+
for (const row of pragma.rows) {
|
|
1927
|
+
const name2 = asString(pickCell(row, "name"));
|
|
1928
|
+
if (name2)
|
|
1929
|
+
names.add(name2);
|
|
1930
|
+
}
|
|
1931
|
+
} catch {}
|
|
1932
|
+
return names;
|
|
1933
|
+
}
|
|
1934
|
+
async ensureTrajectoryColumnsExist() {
|
|
1935
|
+
const columns = await this.getTableColumnNames("trajectories");
|
|
1936
|
+
const requiredColumns = [
|
|
1937
|
+
["scenario_id", "TEXT"],
|
|
1938
|
+
["episode_id", "TEXT"],
|
|
1939
|
+
["batch_id", "TEXT"],
|
|
1940
|
+
["group_index", "INTEGER"],
|
|
1941
|
+
["steps_json", "JSONB NOT NULL DEFAULT '[]'"],
|
|
1942
|
+
["reward_components_json", "JSONB NOT NULL DEFAULT '{}'"],
|
|
1943
|
+
["metrics_json", "JSONB NOT NULL DEFAULT '{}'"],
|
|
1944
|
+
["metadata_json", "JSONB NOT NULL DEFAULT '{}'"],
|
|
1945
|
+
["is_training_data", "BOOLEAN NOT NULL DEFAULT FALSE"],
|
|
1946
|
+
["is_evaluation", "BOOLEAN NOT NULL DEFAULT FALSE"],
|
|
1947
|
+
["used_in_training", "BOOLEAN NOT NULL DEFAULT FALSE"],
|
|
1948
|
+
["judged_at", "TIMESTAMPTZ"]
|
|
1949
|
+
];
|
|
1950
|
+
for (const [columnName, definition] of requiredColumns) {
|
|
1951
|
+
if (columns.has(columnName))
|
|
1952
|
+
continue;
|
|
1953
|
+
try {
|
|
1954
|
+
await this.executeRawSql(`
|
|
1955
|
+
ALTER TABLE trajectories
|
|
1956
|
+
ADD COLUMN IF NOT EXISTS ${columnName} ${definition}
|
|
1957
|
+
`);
|
|
1958
|
+
} catch (errWithIfExists) {
|
|
1959
|
+
try {
|
|
1960
|
+
await this.executeRawSql(`
|
|
1961
|
+
ALTER TABLE trajectories
|
|
1962
|
+
ADD COLUMN ${columnName} ${definition}
|
|
1963
|
+
`);
|
|
1964
|
+
} catch (errPlain) {
|
|
1965
|
+
const combinedMessage = `${errWithIfExists instanceof Error ? errWithIfExists.message : String(errWithIfExists)} | ${errPlain instanceof Error ? errPlain.message : String(errPlain)}`.toLowerCase();
|
|
1966
|
+
if (combinedMessage.includes("already exists") || combinedMessage.includes("duplicate column") || combinedMessage.includes("duplicate_column")) {
|
|
1967
|
+
continue;
|
|
1968
|
+
}
|
|
1969
|
+
logger2.warn(`[trajectory-logger] Failed to add trajectories.${columnName} (non-fatal): ${errPlain instanceof Error ? errPlain.message : String(errPlain)}`);
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
for (const statement of [
|
|
1974
|
+
`ALTER TABLE trajectories
|
|
1975
|
+
ALTER COLUMN start_time TYPE BIGINT USING start_time::BIGINT`,
|
|
1976
|
+
`ALTER TABLE trajectories
|
|
1977
|
+
ALTER COLUMN end_time TYPE BIGINT USING end_time::BIGINT`,
|
|
1978
|
+
`ALTER TABLE trajectories
|
|
1979
|
+
ALTER COLUMN duration_ms TYPE BIGINT USING duration_ms::BIGINT`
|
|
1980
|
+
]) {
|
|
1981
|
+
try {
|
|
1982
|
+
await this.executeRawSql(statement);
|
|
1983
|
+
} catch {}
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1903
1986
|
async ensureTablesExist() {
|
|
1904
1987
|
await this.executeRawSql(`
|
|
1905
1988
|
CREATE TABLE IF NOT EXISTS trajectories (
|
|
@@ -1930,89 +2013,459 @@ class TrajectoryLoggerService extends Service {
|
|
|
1930
2013
|
ai_judge_reward REAL,
|
|
1931
2014
|
ai_judge_reasoning TEXT,
|
|
1932
2015
|
judged_at TIMESTAMPTZ,
|
|
1933
|
-
created_at TIMESTAMPTZ NOT NULL DEFAULT
|
|
1934
|
-
updated_at TIMESTAMPTZ NOT NULL DEFAULT
|
|
2016
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
2017
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
2018
|
+
)
|
|
2019
|
+
`);
|
|
2020
|
+
await this.ensureTrajectoryColumnsExist();
|
|
2021
|
+
try {
|
|
2022
|
+
await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_agent_id ON trajectories(agent_id)`);
|
|
2023
|
+
await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_source ON trajectories(source)`);
|
|
2024
|
+
await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_status ON trajectories(status)`);
|
|
2025
|
+
await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_created_at ON trajectories(created_at)`);
|
|
2026
|
+
await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_scenario_id ON trajectories(scenario_id)`);
|
|
2027
|
+
await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_batch_id ON trajectories(batch_id)`);
|
|
2028
|
+
await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectories_is_training ON trajectories(is_training_data)`);
|
|
2029
|
+
} catch (e) {
|
|
2030
|
+
logger2.warn(`[trajectory-logger] Failed to create indexes (non-fatal): ${e instanceof Error ? e.message : String(e)}`);
|
|
2031
|
+
}
|
|
2032
|
+
await this.executeRawSql(`
|
|
2033
|
+
CREATE TABLE IF NOT EXISTS trajectory_step_index (
|
|
2034
|
+
step_id TEXT PRIMARY KEY,
|
|
2035
|
+
trajectory_id TEXT NOT NULL REFERENCES trajectories(id) ON DELETE CASCADE,
|
|
2036
|
+
step_number INTEGER NOT NULL DEFAULT 0,
|
|
2037
|
+
is_active BOOLEAN NOT NULL DEFAULT FALSE,
|
|
2038
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
2039
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
2040
|
+
)
|
|
2041
|
+
`);
|
|
2042
|
+
await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectory_step_index_trajectory_id ON trajectory_step_index(trajectory_id)`);
|
|
2043
|
+
await this.executeRawSql(`CREATE INDEX IF NOT EXISTS idx_trajectory_step_index_is_active ON trajectory_step_index(is_active)`);
|
|
2044
|
+
}
|
|
2045
|
+
normalizeTrajectoryStatus(value) {
|
|
2046
|
+
switch (value) {
|
|
2047
|
+
case "active":
|
|
2048
|
+
case "completed":
|
|
2049
|
+
case "error":
|
|
2050
|
+
case "timeout":
|
|
2051
|
+
case "terminated":
|
|
2052
|
+
return value;
|
|
2053
|
+
default:
|
|
2054
|
+
return "completed";
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
async backfillTrajectoriesMissingLlmCalls() {
|
|
2058
|
+
const maxRows = 2000;
|
|
2059
|
+
let fixed = 0;
|
|
2060
|
+
try {
|
|
2061
|
+
const rows = await this.executeRawSql(`
|
|
2062
|
+
SELECT id, status
|
|
2063
|
+
FROM trajectories
|
|
2064
|
+
WHERE COALESCE(llm_call_count, 0) = 0
|
|
2065
|
+
AND status <> 'active'
|
|
2066
|
+
ORDER BY created_at ASC
|
|
2067
|
+
LIMIT ${maxRows}
|
|
2068
|
+
`);
|
|
2069
|
+
for (const row of rows.rows) {
|
|
2070
|
+
const trajectoryId = asString(pickCell(row, "id"));
|
|
2071
|
+
if (!trajectoryId)
|
|
2072
|
+
continue;
|
|
2073
|
+
const status = this.normalizeTrajectoryStatus(asString(pickCell(row, "status")));
|
|
2074
|
+
await this.withTrajectoryWriteLock(trajectoryId, async () => {
|
|
2075
|
+
const trajectory = await this.getTrajectoryById(trajectoryId);
|
|
2076
|
+
if (!trajectory)
|
|
2077
|
+
return;
|
|
2078
|
+
const inserted = this.ensureAtLeastOneLlmCall(trajectory, "backfill");
|
|
2079
|
+
if (!inserted)
|
|
2080
|
+
return;
|
|
2081
|
+
await this.persistTrajectory(trajectoryId, trajectory, status);
|
|
2082
|
+
fixed += 1;
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
if (fixed > 0) {
|
|
2086
|
+
logger2.info(`[trajectory-logger] Backfilled ${fixed} completed trajectories with synthetic LLM calls`);
|
|
2087
|
+
}
|
|
2088
|
+
if (rows.rows.length >= maxRows) {
|
|
2089
|
+
logger2.warn(`[trajectory-logger] Backfill hit safety cap (${maxRows}); remaining older trajectories will be fixed lazily when touched`);
|
|
2090
|
+
}
|
|
2091
|
+
} catch (err) {
|
|
2092
|
+
logger2.warn(`[trajectory-logger] Failed to backfill trajectories missing LLM calls (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
normalizePurpose(value) {
|
|
2096
|
+
switch (value) {
|
|
2097
|
+
case "action":
|
|
2098
|
+
case "reasoning":
|
|
2099
|
+
case "evaluation":
|
|
2100
|
+
case "response":
|
|
2101
|
+
case "other":
|
|
2102
|
+
return value;
|
|
2103
|
+
default:
|
|
2104
|
+
return "other";
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
defaultEnvironmentState(timestamp = Date.now()) {
|
|
2108
|
+
return {
|
|
2109
|
+
timestamp,
|
|
2110
|
+
agentBalance: 0,
|
|
2111
|
+
agentPoints: 0,
|
|
2112
|
+
agentPnL: 0,
|
|
2113
|
+
openPositions: 0
|
|
2114
|
+
};
|
|
2115
|
+
}
|
|
2116
|
+
createPendingAction(stepTimestamp) {
|
|
2117
|
+
return {
|
|
2118
|
+
attemptId: "",
|
|
2119
|
+
timestamp: stepTimestamp,
|
|
2120
|
+
actionType: "pending",
|
|
2121
|
+
actionName: "pending",
|
|
2122
|
+
parameters: {},
|
|
2123
|
+
success: false
|
|
2124
|
+
};
|
|
2125
|
+
}
|
|
2126
|
+
createStep(stepId, stepNumber, envState) {
|
|
2127
|
+
const timestamp = envState.timestamp || Date.now();
|
|
2128
|
+
return {
|
|
2129
|
+
stepId,
|
|
2130
|
+
stepNumber,
|
|
2131
|
+
timestamp,
|
|
2132
|
+
environmentState: envState,
|
|
2133
|
+
observation: {},
|
|
2134
|
+
llmCalls: [],
|
|
2135
|
+
providerAccesses: [],
|
|
2136
|
+
action: this.createPendingAction(timestamp),
|
|
2137
|
+
reward: 0,
|
|
2138
|
+
done: false
|
|
2139
|
+
};
|
|
2140
|
+
}
|
|
2141
|
+
ensureAtLeastOneLlmCall(trajectory, source) {
|
|
2142
|
+
if (this.computeTotals(trajectory.steps).llmCallCount > 0) {
|
|
2143
|
+
return false;
|
|
2144
|
+
}
|
|
2145
|
+
const timestamp = Date.now();
|
|
2146
|
+
let step = trajectory.steps[trajectory.steps.length - 1];
|
|
2147
|
+
if (!step) {
|
|
2148
|
+
step = this.createStep(uuidv4(), 0, this.defaultEnvironmentState(timestamp));
|
|
2149
|
+
step.done = true;
|
|
2150
|
+
trajectory.steps.push(step);
|
|
2151
|
+
}
|
|
2152
|
+
if (!Array.isArray(step.llmCalls)) {
|
|
2153
|
+
step.llmCalls = [];
|
|
2154
|
+
}
|
|
2155
|
+
const syntheticCall = {
|
|
2156
|
+
callId: uuidv4(),
|
|
2157
|
+
timestamp,
|
|
2158
|
+
model: "milady/synthetic-trajectory-fallback",
|
|
2159
|
+
systemPrompt: "[synthetic] inserted by trajectory logger because no LLM calls were captured",
|
|
2160
|
+
userPrompt: "[synthetic] this trajectory completed without recorded model activity",
|
|
2161
|
+
response: "[synthetic] placeholder call inserted to enforce minimum llm_call_count=1",
|
|
2162
|
+
temperature: 0,
|
|
2163
|
+
maxTokens: 0,
|
|
2164
|
+
promptTokens: 0,
|
|
2165
|
+
completionTokens: 0,
|
|
2166
|
+
latencyMs: 0,
|
|
2167
|
+
purpose: "other",
|
|
2168
|
+
actionType: "TRAJECTORY_FALLBACK"
|
|
2169
|
+
};
|
|
2170
|
+
step.llmCalls.push(syntheticCall);
|
|
2171
|
+
if (!step.metadata)
|
|
2172
|
+
step.metadata = {};
|
|
2173
|
+
step.metadata.syntheticLlmCall = true;
|
|
2174
|
+
step.metadata.syntheticLlmCallSource = source;
|
|
2175
|
+
trajectory.metadata.syntheticLlmCall = true;
|
|
2176
|
+
trajectory.metadata.syntheticLlmCallSource = source;
|
|
2177
|
+
const existingFallbackCount = trajectory.metrics.syntheticLlmFallbackCount;
|
|
2178
|
+
trajectory.metrics.syntheticLlmFallbackCount = typeof existingFallbackCount === "number" && Number.isFinite(existingFallbackCount) ? existingFallbackCount + 1 : 1;
|
|
2179
|
+
return true;
|
|
2180
|
+
}
|
|
2181
|
+
computeTotals(steps) {
|
|
2182
|
+
let llmCallCount = 0;
|
|
2183
|
+
let providerAccessCount = 0;
|
|
2184
|
+
let totalPromptTokens = 0;
|
|
2185
|
+
let totalCompletionTokens = 0;
|
|
2186
|
+
for (const step of steps) {
|
|
2187
|
+
const llmCalls = Array.isArray(step.llmCalls) ? step.llmCalls : [];
|
|
2188
|
+
const providerAccesses = Array.isArray(step.providerAccesses) ? step.providerAccesses : [];
|
|
2189
|
+
llmCallCount += llmCalls.length;
|
|
2190
|
+
providerAccessCount += providerAccesses.length;
|
|
2191
|
+
for (const call of llmCalls) {
|
|
2192
|
+
totalPromptTokens += call.promptTokens ?? 0;
|
|
2193
|
+
totalCompletionTokens += call.completionTokens ?? 0;
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
return {
|
|
2197
|
+
stepCount: steps.length,
|
|
2198
|
+
llmCallCount,
|
|
2199
|
+
providerAccessCount,
|
|
2200
|
+
totalPromptTokens,
|
|
2201
|
+
totalCompletionTokens
|
|
2202
|
+
};
|
|
2203
|
+
}
|
|
2204
|
+
async withTrajectoryWriteLock(trajectoryId, task) {
|
|
2205
|
+
const previous = this.writeQueues.get(trajectoryId) ?? Promise.resolve();
|
|
2206
|
+
const next = previous.catch(() => {}).then(task);
|
|
2207
|
+
this.writeQueues.set(trajectoryId, next);
|
|
2208
|
+
try {
|
|
2209
|
+
await next;
|
|
2210
|
+
} finally {
|
|
2211
|
+
if (this.writeQueues.get(trajectoryId) === next) {
|
|
2212
|
+
this.writeQueues.delete(trajectoryId);
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
async getTrajectoryById(trajectoryId) {
|
|
2217
|
+
const result = await this.executeRawSql(`SELECT * FROM trajectories WHERE id = ${sqlLiteral(trajectoryId)} LIMIT 1`);
|
|
2218
|
+
if (result.rows.length === 0)
|
|
2219
|
+
return null;
|
|
2220
|
+
return this.rowToTrajectory(result.rows[0]);
|
|
2221
|
+
}
|
|
2222
|
+
async getStepIndex(stepId) {
|
|
2223
|
+
const result = await this.executeRawSql(`SELECT trajectory_id, step_number, is_active FROM trajectory_step_index WHERE step_id = ${sqlLiteral(stepId)} LIMIT 1`);
|
|
2224
|
+
const row = result.rows[0];
|
|
2225
|
+
if (!row)
|
|
2226
|
+
return null;
|
|
2227
|
+
const trajectoryId = asString(pickCell(row, "trajectory_id"));
|
|
2228
|
+
if (!trajectoryId)
|
|
2229
|
+
return null;
|
|
2230
|
+
const stepNumber = asNumber(pickCell(row, "step_number")) ?? 0;
|
|
2231
|
+
const isActiveText = asString(pickCell(row, "is_active"));
|
|
2232
|
+
const isActive = isActiveText === "true" || isActiveText === "t" || pickCell(row, "is_active") === true;
|
|
2233
|
+
return { trajectoryId, stepNumber, isActive };
|
|
2234
|
+
}
|
|
2235
|
+
async setStepIndex(stepId, trajectoryId, stepNumber, isActive) {
|
|
2236
|
+
await this.executeRawSql(`
|
|
2237
|
+
INSERT INTO trajectory_step_index (
|
|
2238
|
+
step_id, trajectory_id, step_number, is_active, updated_at
|
|
2239
|
+
) VALUES (
|
|
2240
|
+
${sqlLiteral(stepId)},
|
|
2241
|
+
${sqlLiteral(trajectoryId)},
|
|
2242
|
+
${stepNumber},
|
|
2243
|
+
${isActive ? "TRUE" : "FALSE"},
|
|
2244
|
+
CURRENT_TIMESTAMP
|
|
1935
2245
|
)
|
|
2246
|
+
ON CONFLICT (step_id) DO UPDATE SET
|
|
2247
|
+
trajectory_id = EXCLUDED.trajectory_id,
|
|
2248
|
+
step_number = EXCLUDED.step_number,
|
|
2249
|
+
is_active = EXCLUDED.is_active,
|
|
2250
|
+
updated_at = CURRENT_TIMESTAMP
|
|
1936
2251
|
`);
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
await this.executeRawSql(`
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
2252
|
+
}
|
|
2253
|
+
async markAllStepsInactive(trajectoryId) {
|
|
2254
|
+
await this.executeRawSql(`
|
|
2255
|
+
UPDATE trajectory_step_index
|
|
2256
|
+
SET is_active = FALSE, updated_at = CURRENT_TIMESTAMP
|
|
2257
|
+
WHERE trajectory_id = ${sqlLiteral(trajectoryId)}
|
|
2258
|
+
`);
|
|
2259
|
+
}
|
|
2260
|
+
async resolveTrajectoryId(stepIdOrTrajectoryId) {
|
|
2261
|
+
const cached = this.stepToTrajectory.get(stepIdOrTrajectoryId);
|
|
2262
|
+
if (cached)
|
|
2263
|
+
return cached;
|
|
2264
|
+
const byStep = await this.getStepIndex(stepIdOrTrajectoryId);
|
|
2265
|
+
if (byStep?.trajectoryId) {
|
|
2266
|
+
this.stepToTrajectory.set(stepIdOrTrajectoryId, byStep.trajectoryId);
|
|
2267
|
+
return byStep.trajectoryId;
|
|
2268
|
+
}
|
|
2269
|
+
const byId = await this.executeRawSql(`SELECT id FROM trajectories WHERE id = ${sqlLiteral(stepIdOrTrajectoryId)} LIMIT 1`);
|
|
2270
|
+
const row = byId.rows[0];
|
|
2271
|
+
const id = row ? asString(pickCell(row, "id")) : null;
|
|
2272
|
+
return id;
|
|
2273
|
+
}
|
|
2274
|
+
async getCurrentStepIdFromDb(trajectoryId) {
|
|
2275
|
+
const result = await this.executeRawSql(`
|
|
2276
|
+
SELECT step_id
|
|
2277
|
+
FROM trajectory_step_index
|
|
2278
|
+
WHERE trajectory_id = ${sqlLiteral(trajectoryId)} AND is_active = TRUE
|
|
2279
|
+
ORDER BY step_number DESC, updated_at DESC
|
|
2280
|
+
LIMIT 1
|
|
2281
|
+
`);
|
|
2282
|
+
const row = result.rows[0];
|
|
2283
|
+
return row ? asString(pickCell(row, "step_id")) : null;
|
|
2284
|
+
}
|
|
2285
|
+
async persistTrajectory(trajectoryId, trajectory, status = "active") {
|
|
2286
|
+
if (status !== "active") {
|
|
2287
|
+
this.ensureAtLeastOneLlmCall(trajectory, "finalize");
|
|
2288
|
+
}
|
|
2289
|
+
const totals = this.computeTotals(trajectory.steps);
|
|
2290
|
+
const isFinalStatus = status !== "active";
|
|
2291
|
+
const persistedEndTime = isFinalStatus ? trajectory.endTime : null;
|
|
2292
|
+
const persistedDuration = isFinalStatus ? trajectory.durationMs : null;
|
|
2293
|
+
const updatedAtIso = new Date().toISOString();
|
|
2294
|
+
try {
|
|
2295
|
+
await this.executeRawSql(`
|
|
2296
|
+
UPDATE trajectories SET
|
|
2297
|
+
status = ${sqlLiteral(status)},
|
|
2298
|
+
end_time = ${sqlLiteral(persistedEndTime)},
|
|
2299
|
+
duration_ms = ${sqlLiteral(persistedDuration)},
|
|
2300
|
+
step_count = ${totals.stepCount},
|
|
2301
|
+
llm_call_count = ${totals.llmCallCount},
|
|
2302
|
+
provider_access_count = ${totals.providerAccessCount},
|
|
2303
|
+
total_prompt_tokens = ${totals.totalPromptTokens},
|
|
2304
|
+
total_completion_tokens = ${totals.totalCompletionTokens},
|
|
2305
|
+
total_reward = ${trajectory.totalReward},
|
|
2306
|
+
steps_json = ${sqlLiteral(trajectory.steps)},
|
|
2307
|
+
reward_components_json = ${sqlLiteral(trajectory.rewardComponents)},
|
|
2308
|
+
metrics_json = ${sqlLiteral(trajectory.metrics)},
|
|
2309
|
+
metadata_json = ${sqlLiteral(trajectory.metadata)},
|
|
2310
|
+
updated_at = ${sqlLiteral(updatedAtIso)}
|
|
2311
|
+
WHERE id = ${sqlLiteral(trajectoryId)}
|
|
2312
|
+
`);
|
|
2313
|
+
} catch (modernErr) {
|
|
2314
|
+
await this.executeRawSql(`
|
|
2315
|
+
UPDATE trajectories SET
|
|
2316
|
+
status = ${sqlLiteral(status)},
|
|
2317
|
+
end_time = ${sqlLiteral(persistedEndTime)},
|
|
2318
|
+
duration_ms = ${sqlLiteral(persistedDuration)},
|
|
2319
|
+
step_count = ${totals.stepCount},
|
|
2320
|
+
llm_call_count = ${totals.llmCallCount},
|
|
2321
|
+
provider_access_count = ${totals.providerAccessCount},
|
|
2322
|
+
total_prompt_tokens = ${totals.totalPromptTokens},
|
|
2323
|
+
total_completion_tokens = ${totals.totalCompletionTokens},
|
|
2324
|
+
total_reward = ${trajectory.totalReward},
|
|
2325
|
+
steps_json = ${sqlLiteral(trajectory.steps)},
|
|
2326
|
+
metadata = ${sqlLiteral(trajectory.metadata)},
|
|
2327
|
+
updated_at = ${sqlLiteral(updatedAtIso)}
|
|
2328
|
+
WHERE id = ${sqlLiteral(trajectoryId)}
|
|
2329
|
+
`).catch((legacyErr) => {
|
|
2330
|
+
logger2.warn({ err: legacyErr, trajectoryId }, `[trajectory-logger] Failed to persist trajectory update after compatibility fallback: ${modernErr instanceof Error ? modernErr.message : String(modernErr)}`);
|
|
2331
|
+
throw legacyErr;
|
|
2332
|
+
});
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
async ensureStepExists(trajectory, stepId) {
|
|
2336
|
+
let step = trajectory.steps.find((entry) => entry.stepId === stepId);
|
|
2337
|
+
if (step) {
|
|
2338
|
+
if (!Array.isArray(step.llmCalls))
|
|
2339
|
+
step.llmCalls = [];
|
|
2340
|
+
if (!Array.isArray(step.providerAccesses))
|
|
2341
|
+
step.providerAccesses = [];
|
|
2342
|
+
return step;
|
|
2343
|
+
}
|
|
2344
|
+
const index = await this.getStepIndex(stepId);
|
|
2345
|
+
const stepNumber = index?.stepNumber ?? trajectory.steps.length;
|
|
2346
|
+
step = this.createStep(stepId, stepNumber, this.defaultEnvironmentState());
|
|
2347
|
+
trajectory.steps.push(step);
|
|
2348
|
+
trajectory.steps.sort((a, b) => a.stepNumber - b.stepNumber);
|
|
2349
|
+
return step;
|
|
1944
2350
|
}
|
|
1945
2351
|
logLlmCall(params) {
|
|
1946
2352
|
if (!this.enabled)
|
|
1947
2353
|
return;
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
2354
|
+
(async () => {
|
|
2355
|
+
const trajectoryId = await this.resolveTrajectoryId(params.stepId);
|
|
2356
|
+
if (!trajectoryId) {
|
|
2357
|
+
logger2.debug({ stepId: params.stepId }, "[trajectory-logger] No trajectory mapping for LLM call");
|
|
2358
|
+
return;
|
|
2359
|
+
}
|
|
2360
|
+
await this.withTrajectoryWriteLock(trajectoryId, async () => {
|
|
2361
|
+
const trajectory = await this.getTrajectoryById(trajectoryId);
|
|
2362
|
+
if (!trajectory)
|
|
2363
|
+
return;
|
|
2364
|
+
const step = await this.ensureStepExists(trajectory, params.stepId);
|
|
2365
|
+
const llmCall = {
|
|
2366
|
+
callId: uuidv4(),
|
|
2367
|
+
timestamp: Date.now(),
|
|
2368
|
+
model: params.model,
|
|
2369
|
+
modelVersion: params.modelVersion,
|
|
2370
|
+
systemPrompt: params.systemPrompt,
|
|
2371
|
+
userPrompt: params.userPrompt,
|
|
2372
|
+
response: params.response,
|
|
2373
|
+
reasoning: params.reasoning,
|
|
2374
|
+
temperature: params.temperature,
|
|
2375
|
+
maxTokens: params.maxTokens,
|
|
2376
|
+
purpose: this.normalizePurpose(params.purpose),
|
|
2377
|
+
actionType: params.actionType,
|
|
2378
|
+
promptTokens: params.promptTokens,
|
|
2379
|
+
completionTokens: params.completionTokens,
|
|
2380
|
+
latencyMs: params.latencyMs
|
|
2381
|
+
};
|
|
2382
|
+
step.llmCalls.push(llmCall);
|
|
2383
|
+
await this.persistTrajectory(trajectoryId, trajectory, "active");
|
|
2384
|
+
});
|
|
2385
|
+
})().catch((err) => {
|
|
2386
|
+
logger2.warn({ err, stepId: params.stepId }, "[trajectory-logger] Failed to persist LLM call");
|
|
1980
2387
|
});
|
|
1981
2388
|
}
|
|
1982
|
-
|
|
2389
|
+
logLLMCall(stepId, details) {
|
|
2390
|
+
this.logLlmCall({
|
|
2391
|
+
stepId,
|
|
2392
|
+
model: details.model,
|
|
2393
|
+
modelVersion: details.modelVersion,
|
|
2394
|
+
systemPrompt: details.systemPrompt,
|
|
2395
|
+
userPrompt: details.userPrompt,
|
|
2396
|
+
response: details.response,
|
|
2397
|
+
reasoning: details.reasoning,
|
|
2398
|
+
temperature: details.temperature,
|
|
2399
|
+
maxTokens: details.maxTokens,
|
|
2400
|
+
purpose: details.purpose,
|
|
2401
|
+
actionType: details.actionType ?? "",
|
|
2402
|
+
latencyMs: details.latencyMs ?? 0,
|
|
2403
|
+
promptTokens: details.promptTokens,
|
|
2404
|
+
completionTokens: details.completionTokens
|
|
2405
|
+
});
|
|
2406
|
+
}
|
|
2407
|
+
logProviderAccess(arg1, arg2) {
|
|
1983
2408
|
if (!this.enabled)
|
|
1984
2409
|
return;
|
|
1985
|
-
const
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
2410
|
+
const params = typeof arg1 === "string" ? {
|
|
2411
|
+
stepId: arg1,
|
|
2412
|
+
providerName: arg2?.providerName ?? "unknown",
|
|
2413
|
+
data: arg2?.data ?? {},
|
|
2414
|
+
purpose: arg2?.purpose ?? "other",
|
|
2415
|
+
query: arg2?.query
|
|
2416
|
+
} : arg1;
|
|
2417
|
+
(async () => {
|
|
2418
|
+
const trajectoryId = await this.resolveTrajectoryId(params.stepId);
|
|
2419
|
+
if (!trajectoryId) {
|
|
2420
|
+
logger2.debug({ stepId: params.stepId }, "[trajectory-logger] No trajectory mapping for provider access");
|
|
2421
|
+
return;
|
|
2422
|
+
}
|
|
2423
|
+
await this.withTrajectoryWriteLock(trajectoryId, async () => {
|
|
2424
|
+
const trajectory = await this.getTrajectoryById(trajectoryId);
|
|
2425
|
+
if (!trajectory)
|
|
2426
|
+
return;
|
|
2427
|
+
const step = await this.ensureStepExists(trajectory, params.stepId);
|
|
2428
|
+
const access = {
|
|
2429
|
+
providerId: uuidv4(),
|
|
2430
|
+
providerName: params.providerName,
|
|
2431
|
+
timestamp: Date.now(),
|
|
2432
|
+
data: params.data,
|
|
2433
|
+
query: params.query,
|
|
2434
|
+
purpose: params.purpose
|
|
2435
|
+
};
|
|
2436
|
+
step.providerAccesses.push(access);
|
|
2437
|
+
await this.persistTrajectory(trajectoryId, trajectory, "active");
|
|
2438
|
+
});
|
|
2439
|
+
})().catch((err) => {
|
|
2440
|
+
logger2.warn({ err, stepId: params.stepId }, "[trajectory-logger] Failed to persist provider access");
|
|
2441
|
+
});
|
|
2442
|
+
}
|
|
2443
|
+
logProviderAccessByTrajectoryId(trajectoryId, access) {
|
|
2444
|
+
const stepId = this.getCurrentStepId(trajectoryId);
|
|
2445
|
+
if (!stepId) {
|
|
2446
|
+
logger2.debug({ trajectoryId }, "[trajectory-logger] No active step for provider access by trajectory");
|
|
1992
2447
|
return;
|
|
1993
|
-
const currentStepId = this.activeStepIds.get(trajectoryId);
|
|
1994
|
-
const step = trajectory.steps.find((s) => s.stepId === currentStepId);
|
|
1995
|
-
if (step) {
|
|
1996
|
-
const access = {
|
|
1997
|
-
providerId: uuidv4(),
|
|
1998
|
-
providerName: params.providerName,
|
|
1999
|
-
timestamp: Date.now(),
|
|
2000
|
-
data: params.data,
|
|
2001
|
-
query: params.query,
|
|
2002
|
-
purpose: params.purpose
|
|
2003
|
-
};
|
|
2004
|
-
step.providerAccesses.push(access);
|
|
2005
2448
|
}
|
|
2449
|
+
this.logProviderAccess(stepId, access);
|
|
2006
2450
|
}
|
|
2007
|
-
|
|
2008
|
-
async startTrajectory(stepId, options) {
|
|
2451
|
+
async startTrajectory(stepIdOrAgentId, options = {}) {
|
|
2009
2452
|
if (!this.enabled)
|
|
2010
|
-
return
|
|
2453
|
+
return uuidv4();
|
|
2454
|
+
const legacyStepId = typeof options.agentId === "string" && options.agentId.length > 0 ? stepIdOrAgentId : null;
|
|
2455
|
+
const agentId = (typeof options.agentId === "string" && options.agentId.length > 0 ? options.agentId : stepIdOrAgentId) ?? stepIdOrAgentId;
|
|
2011
2456
|
const trajectoryId = uuidv4();
|
|
2012
2457
|
const now = Date.now();
|
|
2458
|
+
const timestampIso = new Date(now).toISOString();
|
|
2459
|
+
const metadata = {
|
|
2460
|
+
...options.metadata ?? {}
|
|
2461
|
+
};
|
|
2462
|
+
if (options.roomId)
|
|
2463
|
+
metadata.roomId = options.roomId;
|
|
2464
|
+
if (options.entityId)
|
|
2465
|
+
metadata.entityId = options.entityId;
|
|
2013
2466
|
const trajectory = {
|
|
2014
2467
|
trajectoryId,
|
|
2015
|
-
agentId
|
|
2468
|
+
agentId,
|
|
2016
2469
|
startTime: now,
|
|
2017
2470
|
endTime: now,
|
|
2018
2471
|
durationMs: 0,
|
|
@@ -2029,28 +2482,19 @@ class TrajectoryLoggerService extends Service {
|
|
|
2029
2482
|
},
|
|
2030
2483
|
metadata: {
|
|
2031
2484
|
source: options.source ?? "chat",
|
|
2032
|
-
|
|
2033
|
-
entityId: options.entityId,
|
|
2034
|
-
...options.metadata ?? {}
|
|
2485
|
+
...metadata
|
|
2035
2486
|
}
|
|
2036
2487
|
};
|
|
2037
|
-
|
|
2038
|
-
this.stepToTrajectory.set(stepId, trajectoryId);
|
|
2039
|
-
this.startStep(trajectoryId, {
|
|
2040
|
-
timestamp: now,
|
|
2041
|
-
agentBalance: 0,
|
|
2042
|
-
agentPoints: 0,
|
|
2043
|
-
agentPnL: 0,
|
|
2044
|
-
openPositions: 0
|
|
2045
|
-
});
|
|
2488
|
+
let persistedStart = false;
|
|
2046
2489
|
try {
|
|
2047
2490
|
await this.executeRawSql(`
|
|
2048
2491
|
INSERT INTO trajectories (
|
|
2049
2492
|
id, agent_id, source, status, start_time, scenario_id, episode_id,
|
|
2050
|
-
batch_id, group_index, metadata_json
|
|
2493
|
+
batch_id, group_index, metadata_json, steps_json, reward_components_json, metrics_json,
|
|
2494
|
+
created_at, updated_at
|
|
2051
2495
|
) VALUES (
|
|
2052
2496
|
${sqlLiteral(trajectoryId)},
|
|
2053
|
-
${sqlLiteral(
|
|
2497
|
+
${sqlLiteral(agentId)},
|
|
2054
2498
|
${sqlLiteral(options.source ?? "chat")},
|
|
2055
2499
|
'active',
|
|
2056
2500
|
${now},
|
|
@@ -2058,124 +2502,139 @@ class TrajectoryLoggerService extends Service {
|
|
|
2058
2502
|
${sqlLiteral(options.episodeId ?? null)},
|
|
2059
2503
|
${sqlLiteral(options.batchId ?? null)},
|
|
2060
2504
|
${options.groupIndex ?? "NULL"},
|
|
2061
|
-
${sqlLiteral(trajectory.metadata)}
|
|
2505
|
+
${sqlLiteral(trajectory.metadata)},
|
|
2506
|
+
${sqlLiteral([])},
|
|
2507
|
+
${sqlLiteral(trajectory.rewardComponents)},
|
|
2508
|
+
${sqlLiteral(trajectory.metrics)},
|
|
2509
|
+
${sqlLiteral(timestampIso)},
|
|
2510
|
+
${sqlLiteral(timestampIso)}
|
|
2062
2511
|
)
|
|
2063
2512
|
`);
|
|
2513
|
+
persistedStart = true;
|
|
2064
2514
|
} catch (err) {
|
|
2065
|
-
|
|
2515
|
+
try {
|
|
2516
|
+
await this.executeRawSql(`
|
|
2517
|
+
INSERT INTO trajectories (
|
|
2518
|
+
id, agent_id, source, status, start_time, steps_json, metadata, created_at, updated_at
|
|
2519
|
+
) VALUES (
|
|
2520
|
+
${sqlLiteral(trajectoryId)},
|
|
2521
|
+
${sqlLiteral(agentId)},
|
|
2522
|
+
${sqlLiteral(options.source ?? "chat")},
|
|
2523
|
+
'active',
|
|
2524
|
+
${now},
|
|
2525
|
+
${sqlLiteral([])},
|
|
2526
|
+
${sqlLiteral(trajectory.metadata)},
|
|
2527
|
+
${sqlLiteral(timestampIso)},
|
|
2528
|
+
${sqlLiteral(timestampIso)}
|
|
2529
|
+
)
|
|
2530
|
+
`);
|
|
2531
|
+
persistedStart = true;
|
|
2532
|
+
} catch (legacyErr) {
|
|
2533
|
+
logger2.warn({ err: legacyErr, trajectoryId }, "[trajectory-logger] Failed to persist trajectory start");
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
if (persistedStart && legacyStepId) {
|
|
2537
|
+
this.stepToTrajectory.set(legacyStepId, trajectoryId);
|
|
2538
|
+
try {
|
|
2539
|
+
await this.setStepIndex(legacyStepId, trajectoryId, -1, false);
|
|
2540
|
+
} catch (indexErr) {
|
|
2541
|
+
logger2.warn({ err: indexErr, trajectoryId, stepId: legacyStepId }, "[trajectory-logger] Failed to persist step index for trajectory start");
|
|
2542
|
+
}
|
|
2066
2543
|
}
|
|
2067
2544
|
return trajectoryId;
|
|
2068
2545
|
}
|
|
2069
2546
|
startStep(trajectoryId, envState) {
|
|
2547
|
+
if (!this.enabled)
|
|
2548
|
+
return uuidv4();
|
|
2070
2549
|
const stepId = uuidv4();
|
|
2071
|
-
const trajectory = this.activeTrajectories.get(trajectoryId);
|
|
2072
|
-
if (!trajectory) {
|
|
2073
|
-
logger2.warn({ trajectoryId }, "[trajectory-logger] Trajectory not found for startStep");
|
|
2074
|
-
return stepId;
|
|
2075
|
-
}
|
|
2076
|
-
const step = {
|
|
2077
|
-
stepId,
|
|
2078
|
-
stepNumber: trajectory.steps.length,
|
|
2079
|
-
timestamp: envState.timestamp || Date.now(),
|
|
2080
|
-
environmentState: envState,
|
|
2081
|
-
observation: {},
|
|
2082
|
-
llmCalls: [],
|
|
2083
|
-
providerAccesses: [],
|
|
2084
|
-
action: {
|
|
2085
|
-
attemptId: "",
|
|
2086
|
-
timestamp: 0,
|
|
2087
|
-
actionType: "pending",
|
|
2088
|
-
actionName: "pending",
|
|
2089
|
-
parameters: {},
|
|
2090
|
-
success: false
|
|
2091
|
-
},
|
|
2092
|
-
reward: 0,
|
|
2093
|
-
done: false
|
|
2094
|
-
};
|
|
2095
|
-
trajectory.steps.push(step);
|
|
2096
2550
|
this.activeStepIds.set(trajectoryId, stepId);
|
|
2551
|
+
this.stepToTrajectory.set(stepId, trajectoryId);
|
|
2552
|
+
this.withTrajectoryWriteLock(trajectoryId, async () => {
|
|
2553
|
+
const trajectory = await this.getTrajectoryById(trajectoryId);
|
|
2554
|
+
if (!trajectory) {
|
|
2555
|
+
logger2.warn({ trajectoryId }, "[trajectory-logger] Trajectory not found for startStep");
|
|
2556
|
+
return;
|
|
2557
|
+
}
|
|
2558
|
+
const step = this.createStep(stepId, trajectory.steps.length, envState);
|
|
2559
|
+
trajectory.steps.push(step);
|
|
2560
|
+
await this.markAllStepsInactive(trajectoryId);
|
|
2561
|
+
await this.setStepIndex(stepId, trajectoryId, step.stepNumber, true);
|
|
2562
|
+
await this.persistTrajectory(trajectoryId, trajectory, "active");
|
|
2563
|
+
}).catch((err) => {
|
|
2564
|
+
logger2.warn({ err, trajectoryId, stepId }, "[trajectory-logger] Failed to persist startStep");
|
|
2565
|
+
});
|
|
2097
2566
|
return stepId;
|
|
2098
2567
|
}
|
|
2099
|
-
completeStep(trajectoryId,
|
|
2100
|
-
|
|
2101
|
-
if (!trajectory)
|
|
2568
|
+
completeStep(trajectoryId, actionOrStepId, actionOrReward, maybeReward) {
|
|
2569
|
+
if (!this.enabled)
|
|
2102
2570
|
return;
|
|
2103
|
-
const
|
|
2104
|
-
const
|
|
2105
|
-
|
|
2571
|
+
const explicitStepId = typeof actionOrStepId === "string" ? actionOrStepId : null;
|
|
2572
|
+
const action = typeof actionOrStepId === "string" ? actionOrReward : actionOrStepId;
|
|
2573
|
+
const rewardInfo = typeof actionOrStepId === "string" ? maybeReward : actionOrReward;
|
|
2574
|
+
if (!action)
|
|
2106
2575
|
return;
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
...
|
|
2119
|
-
...rewardInfo.components
|
|
2576
|
+
this.withTrajectoryWriteLock(trajectoryId, async () => {
|
|
2577
|
+
const trajectory = await this.getTrajectoryById(trajectoryId);
|
|
2578
|
+
if (!trajectory)
|
|
2579
|
+
return;
|
|
2580
|
+
const stepId = explicitStepId ?? this.activeStepIds.get(trajectoryId) ?? await this.getCurrentStepIdFromDb(trajectoryId);
|
|
2581
|
+
if (!stepId)
|
|
2582
|
+
return;
|
|
2583
|
+
const step = await this.ensureStepExists(trajectory, stepId);
|
|
2584
|
+
step.action = {
|
|
2585
|
+
attemptId: uuidv4(),
|
|
2586
|
+
timestamp: Date.now(),
|
|
2587
|
+
...action
|
|
2120
2588
|
};
|
|
2121
|
-
|
|
2122
|
-
|
|
2589
|
+
step.done = true;
|
|
2590
|
+
if (rewardInfo?.reward !== undefined) {
|
|
2591
|
+
step.reward = rewardInfo.reward;
|
|
2592
|
+
trajectory.totalReward += rewardInfo.reward;
|
|
2593
|
+
}
|
|
2594
|
+
if (rewardInfo?.components) {
|
|
2595
|
+
trajectory.rewardComponents = {
|
|
2596
|
+
...trajectory.rewardComponents,
|
|
2597
|
+
...rewardInfo.components
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
await this.setStepIndex(stepId, trajectoryId, step.stepNumber, false);
|
|
2601
|
+
this.activeStepIds.delete(trajectoryId);
|
|
2602
|
+
await this.persistTrajectory(trajectoryId, trajectory, "active");
|
|
2603
|
+
}).catch((err) => {
|
|
2604
|
+
logger2.warn({ err, trajectoryId }, "[trajectory-logger] Failed to complete step");
|
|
2605
|
+
});
|
|
2123
2606
|
}
|
|
2124
|
-
async endTrajectory(stepIdOrTrajectoryId, status = "completed") {
|
|
2607
|
+
async endTrajectory(stepIdOrTrajectoryId, status = "completed", finalMetrics) {
|
|
2125
2608
|
if (!this.enabled)
|
|
2126
2609
|
return;
|
|
2127
|
-
|
|
2610
|
+
const trajectoryId = await this.resolveTrajectoryId(stepIdOrTrajectoryId);
|
|
2128
2611
|
if (!trajectoryId) {
|
|
2129
|
-
|
|
2130
|
-
}
|
|
2131
|
-
const trajectory = this.activeTrajectories.get(trajectoryId);
|
|
2132
|
-
if (!trajectory) {
|
|
2133
|
-
logger2.debug({ stepIdOrTrajectoryId }, "[trajectory-logger] No active trajectory to end");
|
|
2612
|
+
logger2.debug({ stepIdOrTrajectoryId }, "[trajectory-logger] No trajectory to end");
|
|
2134
2613
|
return;
|
|
2135
2614
|
}
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
let totalLlmCalls = 0;
|
|
2142
|
-
let totalProviderAccesses = 0;
|
|
2143
|
-
let totalPromptTokens = 0;
|
|
2144
|
-
let totalCompletionTokens = 0;
|
|
2145
|
-
for (const step of trajectory.steps) {
|
|
2146
|
-
totalLlmCalls += step.llmCalls.length;
|
|
2147
|
-
totalProviderAccesses += step.providerAccesses.length;
|
|
2148
|
-
for (const call of step.llmCalls) {
|
|
2149
|
-
totalPromptTokens += call.promptTokens ?? 0;
|
|
2150
|
-
totalCompletionTokens += call.completionTokens ?? 0;
|
|
2615
|
+
await this.withTrajectoryWriteLock(trajectoryId, async () => {
|
|
2616
|
+
const trajectory = await this.getTrajectoryById(trajectoryId);
|
|
2617
|
+
if (!trajectory) {
|
|
2618
|
+
logger2.debug({ trajectoryId }, "[trajectory-logger] Trajectory not found while ending");
|
|
2619
|
+
return;
|
|
2151
2620
|
}
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
updated_at = NOW()
|
|
2170
|
-
WHERE id = ${sqlLiteral(trajectoryId)}
|
|
2171
|
-
`);
|
|
2172
|
-
} catch (err) {
|
|
2173
|
-
logger2.warn({ err, trajectoryId }, "[trajectory-logger] Failed to persist trajectory end");
|
|
2174
|
-
}
|
|
2175
|
-
this.activeTrajectories.delete(trajectoryId);
|
|
2176
|
-
this.activeStepIds.delete(trajectoryId);
|
|
2177
|
-
for (const [stepId, trajId] of this.stepToTrajectory.entries()) {
|
|
2178
|
-
if (trajId === trajectoryId) {
|
|
2621
|
+
const now = Date.now();
|
|
2622
|
+
trajectory.endTime = now;
|
|
2623
|
+
trajectory.durationMs = now - trajectory.startTime;
|
|
2624
|
+
trajectory.metrics.finalStatus = status;
|
|
2625
|
+
trajectory.metrics.episodeLength = trajectory.steps.length;
|
|
2626
|
+
if (finalMetrics) {
|
|
2627
|
+
trajectory.metrics = {
|
|
2628
|
+
...trajectory.metrics,
|
|
2629
|
+
...finalMetrics
|
|
2630
|
+
};
|
|
2631
|
+
}
|
|
2632
|
+
await this.markAllStepsInactive(trajectoryId);
|
|
2633
|
+
this.activeStepIds.delete(trajectoryId);
|
|
2634
|
+
await this.persistTrajectory(trajectoryId, trajectory, status);
|
|
2635
|
+
});
|
|
2636
|
+
for (const [stepId, mappedTrajectoryId] of this.stepToTrajectory.entries()) {
|
|
2637
|
+
if (mappedTrajectoryId === trajectoryId) {
|
|
2179
2638
|
this.stepToTrajectory.delete(stepId);
|
|
2180
2639
|
}
|
|
2181
2640
|
}
|
|
@@ -2231,23 +2690,28 @@ class TrajectoryLoggerService extends Service {
|
|
|
2231
2690
|
ORDER BY created_at DESC
|
|
2232
2691
|
LIMIT ${limit} OFFSET ${offset}
|
|
2233
2692
|
`);
|
|
2234
|
-
const trajectories = rowsResult.rows.map((row) =>
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2693
|
+
const trajectories = rowsResult.rows.map((row) => {
|
|
2694
|
+
const status = asString(pickCell(row, "status")) ?? "completed";
|
|
2695
|
+
const rawLlmCallCount = asNumber(pickCell(row, "llm_call_count")) ?? 0;
|
|
2696
|
+
const llmCallCount = status === "active" ? rawLlmCallCount : Math.max(1, rawLlmCallCount);
|
|
2697
|
+
return {
|
|
2698
|
+
id: asString(pickCell(row, "id")) ?? "",
|
|
2699
|
+
agentId: asString(pickCell(row, "agent_id")) ?? "",
|
|
2700
|
+
source: asString(pickCell(row, "source")) ?? "chat",
|
|
2701
|
+
status,
|
|
2702
|
+
startTime: asNumber(pickCell(row, "start_time")) ?? 0,
|
|
2703
|
+
endTime: asNumber(pickCell(row, "end_time")),
|
|
2704
|
+
durationMs: asNumber(pickCell(row, "duration_ms")),
|
|
2705
|
+
stepCount: asNumber(pickCell(row, "step_count")) ?? 0,
|
|
2706
|
+
llmCallCount,
|
|
2707
|
+
totalPromptTokens: asNumber(pickCell(row, "total_prompt_tokens")) ?? 0,
|
|
2708
|
+
totalCompletionTokens: asNumber(pickCell(row, "total_completion_tokens")) ?? 0,
|
|
2709
|
+
totalReward: asNumber(pickCell(row, "total_reward")) ?? 0,
|
|
2710
|
+
scenarioId: asString(pickCell(row, "scenario_id")),
|
|
2711
|
+
batchId: asString(pickCell(row, "batch_id")),
|
|
2712
|
+
createdAt: asIsoString(pickCell(row, "created_at"))
|
|
2713
|
+
};
|
|
2714
|
+
});
|
|
2251
2715
|
return { trajectories, total, offset, limit };
|
|
2252
2716
|
}
|
|
2253
2717
|
async getTrajectoryDetail(trajectoryId) {
|
|
@@ -2259,7 +2723,17 @@ class TrajectoryLoggerService extends Service {
|
|
|
2259
2723
|
if (result.rows.length === 0)
|
|
2260
2724
|
return null;
|
|
2261
2725
|
const row = result.rows[0];
|
|
2262
|
-
|
|
2726
|
+
const trajectory = this.rowToTrajectory(row);
|
|
2727
|
+
const status = this.normalizeTrajectoryStatus(asString(pickCell(row, "status")));
|
|
2728
|
+
if (status !== "active") {
|
|
2729
|
+
const inserted = this.ensureAtLeastOneLlmCall(trajectory, "backfill");
|
|
2730
|
+
if (inserted) {
|
|
2731
|
+
await this.withTrajectoryWriteLock(trajectoryId, async () => {
|
|
2732
|
+
await this.persistTrajectory(trajectoryId, trajectory, status);
|
|
2733
|
+
});
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
return trajectory;
|
|
2263
2737
|
}
|
|
2264
2738
|
async getStats() {
|
|
2265
2739
|
const runtime = this.runtime;
|
|
@@ -2455,18 +2929,18 @@ class TrajectoryLoggerService extends Service {
|
|
|
2455
2929
|
episodeId: asString(pickCell(row, "episode_id")) ?? undefined,
|
|
2456
2930
|
batchId: asString(pickCell(row, "batch_id")) ?? undefined,
|
|
2457
2931
|
groupIndex: asNumber(pickCell(row, "group_index")) ?? undefined,
|
|
2458
|
-
steps: parseJson(pickCell(row, "steps_json"), []),
|
|
2932
|
+
steps: parseJson(pickCell(row, "steps_json", "steps"), []),
|
|
2459
2933
|
totalReward: asNumber(pickCell(row, "total_reward")) ?? 0,
|
|
2460
|
-
rewardComponents: parseJson(pickCell(row, "reward_components_json"), { environmentReward: 0 }),
|
|
2461
|
-
metrics: parseJson(pickCell(row, "metrics_json"), {
|
|
2934
|
+
rewardComponents: parseJson(pickCell(row, "reward_components_json", "reward_components"), { environmentReward: 0 }),
|
|
2935
|
+
metrics: parseJson(pickCell(row, "metrics_json", "metrics"), {
|
|
2462
2936
|
episodeLength: 0,
|
|
2463
2937
|
finalStatus: "completed"
|
|
2464
2938
|
}),
|
|
2465
|
-
metadata: parseJson(pickCell(row, "metadata_json"), {})
|
|
2939
|
+
metadata: parseJson(pickCell(row, "metadata_json", "metadata"), {})
|
|
2466
2940
|
};
|
|
2467
2941
|
}
|
|
2468
2942
|
getActiveTrajectory(trajectoryId) {
|
|
2469
|
-
return
|
|
2943
|
+
return null;
|
|
2470
2944
|
}
|
|
2471
2945
|
getCurrentStepId(trajectoryId) {
|
|
2472
2946
|
return this.activeStepIds.get(trajectoryId) || null;
|
|
@@ -2935,8 +3409,8 @@ async function buildGameStateFromDB(_trajectoryId) {
|
|
|
2935
3409
|
async function recomputeTrajectoryRewards(_trajectoryIds) {}
|
|
2936
3410
|
// integration.ts
|
|
2937
3411
|
import { logger as logger4 } from "@elizaos/core";
|
|
2938
|
-
function startAutonomousTick(trajectoryLogger, context) {
|
|
2939
|
-
const trajectoryId = trajectoryLogger.startTrajectory(context.agentId, {
|
|
3412
|
+
async function startAutonomousTick(trajectoryLogger, context) {
|
|
3413
|
+
const trajectoryId = await trajectoryLogger.startTrajectory(context.agentId, {
|
|
2940
3414
|
scenarioId: context.scenarioId,
|
|
2941
3415
|
episodeId: context.episodeId,
|
|
2942
3416
|
batchId: context.batchId,
|
|
@@ -3134,4 +3608,4 @@ export {
|
|
|
3134
3608
|
RewardService
|
|
3135
3609
|
};
|
|
3136
3610
|
|
|
3137
|
-
//# debugId=
|
|
3611
|
+
//# debugId=16B8470362B4AC2364756E2164756E21
|