@electric-ax/agents-server 0.4.13 → 0.4.14
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/entrypoint.js +49 -36
- package/dist/index.cjs +49 -36
- package/dist/index.js +49 -36
- package/package.json +5 -5
- package/src/utils/log.ts +63 -52
package/dist/entrypoint.js
CHANGED
|
@@ -893,11 +893,11 @@ var StreamClient = class {
|
|
|
893
893
|
if (res.status === 404 || res.status === 204) return;
|
|
894
894
|
if (!res.ok) throw new Error(`Subscription delete failed: ${res.status} ${await res.text()}`);
|
|
895
895
|
}
|
|
896
|
-
async addSubscriptionStreams(subscriptionId, streams
|
|
896
|
+
async addSubscriptionStreams(subscriptionId, streams) {
|
|
897
897
|
const res = await fetch(this.subscriptionChildUrl(subscriptionId, `streams`), {
|
|
898
898
|
method: `POST`,
|
|
899
899
|
headers: await this.requestHeaders({ "content-type": `application/json` }),
|
|
900
|
-
body: JSON.stringify({ streams: streams
|
|
900
|
+
body: JSON.stringify({ streams: streams.map((stream) => this.backendSubscriptionPath(normalizeSubscriptionStreamPath(stream))) })
|
|
901
901
|
});
|
|
902
902
|
return await this.subscriptionJson(res, `Subscription stream add failed`);
|
|
903
903
|
}
|
|
@@ -1139,35 +1139,48 @@ const LOG_LEVEL = process.env.ELECTRIC_AGENTS_LOG_LEVEL ?? `info`;
|
|
|
1139
1139
|
const IS_ELECTRON_MAIN = Boolean(process.versions.electron);
|
|
1140
1140
|
const USE_FILE_LOGS = process.env.ELECTRIC_AGENTS_LOG_FILE !== `false`;
|
|
1141
1141
|
const USE_PRETTY_LOGS = LOG_LEVEL !== `silent` && !process.env.VITEST && !IS_ELECTRON_MAIN;
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
if (
|
|
1145
|
-
const streams = [];
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1142
|
+
let _logger;
|
|
1143
|
+
function getLogger() {
|
|
1144
|
+
if (_logger) return _logger;
|
|
1145
|
+
const streams = [];
|
|
1146
|
+
try {
|
|
1147
|
+
if (USE_FILE_LOGS) {
|
|
1148
|
+
const logDir = process.env.ELECTRIC_AGENTS_LOG_DIR ?? path.resolve(process.cwd(), `logs`);
|
|
1149
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
1150
|
+
const logFile = path.join(logDir, `agent-server-${Date.now()}.jsonl`);
|
|
1151
|
+
streams.push({ stream: pino.destination({
|
|
1152
|
+
dest: logFile,
|
|
1153
|
+
sync: IS_ELECTRON_MAIN
|
|
1154
|
+
}) });
|
|
1155
|
+
}
|
|
1156
|
+
} catch (err) {
|
|
1157
|
+
process.stderr.write(`[agents-server] Failed to initialize file logging: ${err instanceof Error ? err.message : err}\n`);
|
|
1158
|
+
}
|
|
1159
|
+
try {
|
|
1160
|
+
if (USE_PRETTY_LOGS) streams.push({ stream: pino.transport({
|
|
1161
|
+
target: `pino-pretty`,
|
|
1162
|
+
options: {
|
|
1163
|
+
colorize: true,
|
|
1164
|
+
ignore: `pid,hostname,name`,
|
|
1165
|
+
translateTime: `SYS:HH:MM:ss`
|
|
1166
|
+
}
|
|
1167
|
+
}) });
|
|
1168
|
+
} catch {}
|
|
1169
|
+
_logger = streams.length > 0 ? pino({
|
|
1170
|
+
base: void 0,
|
|
1171
|
+
level: LOG_LEVEL
|
|
1172
|
+
}, pino.multistream(streams)) : pino({
|
|
1173
|
+
base: void 0,
|
|
1174
|
+
enabled: false,
|
|
1175
|
+
level: LOG_LEVEL
|
|
1176
|
+
});
|
|
1177
|
+
return _logger;
|
|
1178
|
+
}
|
|
1166
1179
|
function formatArgs(args) {
|
|
1167
1180
|
const errors = [];
|
|
1168
1181
|
const parts = [];
|
|
1169
|
-
for (const
|
|
1170
|
-
else parts.push(typeof
|
|
1182
|
+
for (const value of args) if (value instanceof Error) errors.push(value);
|
|
1183
|
+
else parts.push(typeof value === `string` ? value : JSON.stringify(value));
|
|
1171
1184
|
return {
|
|
1172
1185
|
err: errors[0],
|
|
1173
1186
|
msg: parts.join(` `)
|
|
@@ -1176,20 +1189,20 @@ function formatArgs(args) {
|
|
|
1176
1189
|
const serverLog = {
|
|
1177
1190
|
info(...args) {
|
|
1178
1191
|
const { msg } = formatArgs(args);
|
|
1179
|
-
|
|
1192
|
+
getLogger().info(msg);
|
|
1180
1193
|
},
|
|
1181
1194
|
warn(...args) {
|
|
1182
1195
|
const { err, msg } = formatArgs(args);
|
|
1183
|
-
if (err)
|
|
1184
|
-
else
|
|
1196
|
+
if (err) getLogger().warn({ err }, msg);
|
|
1197
|
+
else getLogger().warn(msg);
|
|
1185
1198
|
},
|
|
1186
1199
|
error(...args) {
|
|
1187
1200
|
const { err, msg } = formatArgs(args);
|
|
1188
|
-
if (err)
|
|
1189
|
-
else
|
|
1201
|
+
if (err) getLogger().error({ err }, msg);
|
|
1202
|
+
else getLogger().error(msg);
|
|
1190
1203
|
},
|
|
1191
1204
|
event(obj, msg) {
|
|
1192
|
-
|
|
1205
|
+
getLogger().info(obj, msg);
|
|
1193
1206
|
}
|
|
1194
1207
|
};
|
|
1195
1208
|
|
|
@@ -5647,7 +5660,7 @@ async function notificationFromClaim(ctx, input) {
|
|
|
5647
5660
|
leaseExpiresAt: input.claim.lease_ttl_ms ? new Date(Date.now() + input.claim.lease_ttl_ms) : void 0
|
|
5648
5661
|
});
|
|
5649
5662
|
await ctx.entityManager.registry.updateStatus(entity.url, `running`);
|
|
5650
|
-
const streams
|
|
5663
|
+
const streams = input.claim.streams.map((stream) => ({
|
|
5651
5664
|
path: withLeadingSlash(stream.path),
|
|
5652
5665
|
offset: stream.tail_offset ?? ``
|
|
5653
5666
|
}));
|
|
@@ -5656,7 +5669,7 @@ async function notificationFromClaim(ctx, input) {
|
|
|
5656
5669
|
epoch: input.claim.generation,
|
|
5657
5670
|
wakeId: input.claim.wake_id,
|
|
5658
5671
|
streamPath: primaryStream,
|
|
5659
|
-
streams
|
|
5672
|
+
streams,
|
|
5660
5673
|
callback: appendPathToUrl(ctx.publicUrl, `/_electric/wake-callbacks/${encodeURIComponent(input.claim.wake_id)}`),
|
|
5661
5674
|
claimToken: input.claim.token,
|
|
5662
5675
|
triggerEvent: `message_received`,
|
package/dist/index.cjs
CHANGED
|
@@ -1218,35 +1218,48 @@ const LOG_LEVEL = process.env.ELECTRIC_AGENTS_LOG_LEVEL ?? `info`;
|
|
|
1218
1218
|
const IS_ELECTRON_MAIN = Boolean(process.versions.electron);
|
|
1219
1219
|
const USE_FILE_LOGS = process.env.ELECTRIC_AGENTS_LOG_FILE !== `false`;
|
|
1220
1220
|
const USE_PRETTY_LOGS = LOG_LEVEL !== `silent` && !process.env.VITEST && !IS_ELECTRON_MAIN;
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
if (
|
|
1224
|
-
const streams = [];
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1221
|
+
let _logger;
|
|
1222
|
+
function getLogger() {
|
|
1223
|
+
if (_logger) return _logger;
|
|
1224
|
+
const streams = [];
|
|
1225
|
+
try {
|
|
1226
|
+
if (USE_FILE_LOGS) {
|
|
1227
|
+
const logDir = process.env.ELECTRIC_AGENTS_LOG_DIR ?? node_path.default.resolve(process.cwd(), `logs`);
|
|
1228
|
+
node_fs.default.mkdirSync(logDir, { recursive: true });
|
|
1229
|
+
const logFile = node_path.default.join(logDir, `agent-server-${Date.now()}.jsonl`);
|
|
1230
|
+
streams.push({ stream: pino.default.destination({
|
|
1231
|
+
dest: logFile,
|
|
1232
|
+
sync: IS_ELECTRON_MAIN
|
|
1233
|
+
}) });
|
|
1234
|
+
}
|
|
1235
|
+
} catch (err) {
|
|
1236
|
+
process.stderr.write(`[agents-server] Failed to initialize file logging: ${err instanceof Error ? err.message : err}\n`);
|
|
1237
|
+
}
|
|
1238
|
+
try {
|
|
1239
|
+
if (USE_PRETTY_LOGS) streams.push({ stream: pino.default.transport({
|
|
1240
|
+
target: `pino-pretty`,
|
|
1241
|
+
options: {
|
|
1242
|
+
colorize: true,
|
|
1243
|
+
ignore: `pid,hostname,name`,
|
|
1244
|
+
translateTime: `SYS:HH:MM:ss`
|
|
1245
|
+
}
|
|
1246
|
+
}) });
|
|
1247
|
+
} catch {}
|
|
1248
|
+
_logger = streams.length > 0 ? (0, pino.default)({
|
|
1249
|
+
base: void 0,
|
|
1250
|
+
level: LOG_LEVEL
|
|
1251
|
+
}, pino.default.multistream(streams)) : (0, pino.default)({
|
|
1252
|
+
base: void 0,
|
|
1253
|
+
enabled: false,
|
|
1254
|
+
level: LOG_LEVEL
|
|
1255
|
+
});
|
|
1256
|
+
return _logger;
|
|
1257
|
+
}
|
|
1245
1258
|
function formatArgs(args) {
|
|
1246
1259
|
const errors = [];
|
|
1247
1260
|
const parts = [];
|
|
1248
|
-
for (const
|
|
1249
|
-
else parts.push(typeof
|
|
1261
|
+
for (const value of args) if (value instanceof Error) errors.push(value);
|
|
1262
|
+
else parts.push(typeof value === `string` ? value : JSON.stringify(value));
|
|
1250
1263
|
return {
|
|
1251
1264
|
err: errors[0],
|
|
1252
1265
|
msg: parts.join(` `)
|
|
@@ -1255,20 +1268,20 @@ function formatArgs(args) {
|
|
|
1255
1268
|
const serverLog = {
|
|
1256
1269
|
info(...args) {
|
|
1257
1270
|
const { msg } = formatArgs(args);
|
|
1258
|
-
|
|
1271
|
+
getLogger().info(msg);
|
|
1259
1272
|
},
|
|
1260
1273
|
warn(...args) {
|
|
1261
1274
|
const { err, msg } = formatArgs(args);
|
|
1262
|
-
if (err)
|
|
1263
|
-
else
|
|
1275
|
+
if (err) getLogger().warn({ err }, msg);
|
|
1276
|
+
else getLogger().warn(msg);
|
|
1264
1277
|
},
|
|
1265
1278
|
error(...args) {
|
|
1266
1279
|
const { err, msg } = formatArgs(args);
|
|
1267
|
-
if (err)
|
|
1268
|
-
else
|
|
1280
|
+
if (err) getLogger().error({ err }, msg);
|
|
1281
|
+
else getLogger().error(msg);
|
|
1269
1282
|
},
|
|
1270
1283
|
event(obj, msg) {
|
|
1271
|
-
|
|
1284
|
+
getLogger().info(obj, msg);
|
|
1272
1285
|
}
|
|
1273
1286
|
};
|
|
1274
1287
|
|
|
@@ -2248,11 +2261,11 @@ var StreamClient = class {
|
|
|
2248
2261
|
if (res.status === 404 || res.status === 204) return;
|
|
2249
2262
|
if (!res.ok) throw new Error(`Subscription delete failed: ${res.status} ${await res.text()}`);
|
|
2250
2263
|
}
|
|
2251
|
-
async addSubscriptionStreams(subscriptionId, streams
|
|
2264
|
+
async addSubscriptionStreams(subscriptionId, streams) {
|
|
2252
2265
|
const res = await fetch(this.subscriptionChildUrl(subscriptionId, `streams`), {
|
|
2253
2266
|
method: `POST`,
|
|
2254
2267
|
headers: await this.requestHeaders({ "content-type": `application/json` }),
|
|
2255
|
-
body: JSON.stringify({ streams: streams
|
|
2268
|
+
body: JSON.stringify({ streams: streams.map((stream) => this.backendSubscriptionPath(normalizeSubscriptionStreamPath(stream))) })
|
|
2256
2269
|
});
|
|
2257
2270
|
return await this.subscriptionJson(res, `Subscription stream add failed`);
|
|
2258
2271
|
}
|
|
@@ -7884,7 +7897,7 @@ async function notificationFromClaim(ctx, input) {
|
|
|
7884
7897
|
leaseExpiresAt: input.claim.lease_ttl_ms ? new Date(Date.now() + input.claim.lease_ttl_ms) : void 0
|
|
7885
7898
|
});
|
|
7886
7899
|
await ctx.entityManager.registry.updateStatus(entity.url, `running`);
|
|
7887
|
-
const streams
|
|
7900
|
+
const streams = input.claim.streams.map((stream) => ({
|
|
7888
7901
|
path: withLeadingSlash(stream.path),
|
|
7889
7902
|
offset: stream.tail_offset ?? ``
|
|
7890
7903
|
}));
|
|
@@ -7893,7 +7906,7 @@ async function notificationFromClaim(ctx, input) {
|
|
|
7893
7906
|
epoch: input.claim.generation,
|
|
7894
7907
|
wakeId: input.claim.wake_id,
|
|
7895
7908
|
streamPath: primaryStream,
|
|
7896
|
-
streams
|
|
7909
|
+
streams,
|
|
7897
7910
|
callback: (0, __electric_ax_agents_runtime.appendPathToUrl)(ctx.publicUrl, `/_electric/wake-callbacks/${encodeURIComponent(input.claim.wake_id)}`),
|
|
7898
7911
|
claimToken: input.claim.token,
|
|
7899
7912
|
triggerEvent: `message_received`,
|
package/dist/index.js
CHANGED
|
@@ -1189,35 +1189,48 @@ const LOG_LEVEL = process.env.ELECTRIC_AGENTS_LOG_LEVEL ?? `info`;
|
|
|
1189
1189
|
const IS_ELECTRON_MAIN = Boolean(process.versions.electron);
|
|
1190
1190
|
const USE_FILE_LOGS = process.env.ELECTRIC_AGENTS_LOG_FILE !== `false`;
|
|
1191
1191
|
const USE_PRETTY_LOGS = LOG_LEVEL !== `silent` && !process.env.VITEST && !IS_ELECTRON_MAIN;
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
if (
|
|
1195
|
-
const streams = [];
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1192
|
+
let _logger;
|
|
1193
|
+
function getLogger() {
|
|
1194
|
+
if (_logger) return _logger;
|
|
1195
|
+
const streams = [];
|
|
1196
|
+
try {
|
|
1197
|
+
if (USE_FILE_LOGS) {
|
|
1198
|
+
const logDir = process.env.ELECTRIC_AGENTS_LOG_DIR ?? path.resolve(process.cwd(), `logs`);
|
|
1199
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
1200
|
+
const logFile = path.join(logDir, `agent-server-${Date.now()}.jsonl`);
|
|
1201
|
+
streams.push({ stream: pino.destination({
|
|
1202
|
+
dest: logFile,
|
|
1203
|
+
sync: IS_ELECTRON_MAIN
|
|
1204
|
+
}) });
|
|
1205
|
+
}
|
|
1206
|
+
} catch (err) {
|
|
1207
|
+
process.stderr.write(`[agents-server] Failed to initialize file logging: ${err instanceof Error ? err.message : err}\n`);
|
|
1208
|
+
}
|
|
1209
|
+
try {
|
|
1210
|
+
if (USE_PRETTY_LOGS) streams.push({ stream: pino.transport({
|
|
1211
|
+
target: `pino-pretty`,
|
|
1212
|
+
options: {
|
|
1213
|
+
colorize: true,
|
|
1214
|
+
ignore: `pid,hostname,name`,
|
|
1215
|
+
translateTime: `SYS:HH:MM:ss`
|
|
1216
|
+
}
|
|
1217
|
+
}) });
|
|
1218
|
+
} catch {}
|
|
1219
|
+
_logger = streams.length > 0 ? pino({
|
|
1220
|
+
base: void 0,
|
|
1221
|
+
level: LOG_LEVEL
|
|
1222
|
+
}, pino.multistream(streams)) : pino({
|
|
1223
|
+
base: void 0,
|
|
1224
|
+
enabled: false,
|
|
1225
|
+
level: LOG_LEVEL
|
|
1226
|
+
});
|
|
1227
|
+
return _logger;
|
|
1228
|
+
}
|
|
1216
1229
|
function formatArgs(args) {
|
|
1217
1230
|
const errors = [];
|
|
1218
1231
|
const parts = [];
|
|
1219
|
-
for (const
|
|
1220
|
-
else parts.push(typeof
|
|
1232
|
+
for (const value of args) if (value instanceof Error) errors.push(value);
|
|
1233
|
+
else parts.push(typeof value === `string` ? value : JSON.stringify(value));
|
|
1221
1234
|
return {
|
|
1222
1235
|
err: errors[0],
|
|
1223
1236
|
msg: parts.join(` `)
|
|
@@ -1226,20 +1239,20 @@ function formatArgs(args) {
|
|
|
1226
1239
|
const serverLog = {
|
|
1227
1240
|
info(...args) {
|
|
1228
1241
|
const { msg } = formatArgs(args);
|
|
1229
|
-
|
|
1242
|
+
getLogger().info(msg);
|
|
1230
1243
|
},
|
|
1231
1244
|
warn(...args) {
|
|
1232
1245
|
const { err, msg } = formatArgs(args);
|
|
1233
|
-
if (err)
|
|
1234
|
-
else
|
|
1246
|
+
if (err) getLogger().warn({ err }, msg);
|
|
1247
|
+
else getLogger().warn(msg);
|
|
1235
1248
|
},
|
|
1236
1249
|
error(...args) {
|
|
1237
1250
|
const { err, msg } = formatArgs(args);
|
|
1238
|
-
if (err)
|
|
1239
|
-
else
|
|
1251
|
+
if (err) getLogger().error({ err }, msg);
|
|
1252
|
+
else getLogger().error(msg);
|
|
1240
1253
|
},
|
|
1241
1254
|
event(obj, msg) {
|
|
1242
|
-
|
|
1255
|
+
getLogger().info(obj, msg);
|
|
1243
1256
|
}
|
|
1244
1257
|
};
|
|
1245
1258
|
|
|
@@ -2219,11 +2232,11 @@ var StreamClient = class {
|
|
|
2219
2232
|
if (res.status === 404 || res.status === 204) return;
|
|
2220
2233
|
if (!res.ok) throw new Error(`Subscription delete failed: ${res.status} ${await res.text()}`);
|
|
2221
2234
|
}
|
|
2222
|
-
async addSubscriptionStreams(subscriptionId, streams
|
|
2235
|
+
async addSubscriptionStreams(subscriptionId, streams) {
|
|
2223
2236
|
const res = await fetch(this.subscriptionChildUrl(subscriptionId, `streams`), {
|
|
2224
2237
|
method: `POST`,
|
|
2225
2238
|
headers: await this.requestHeaders({ "content-type": `application/json` }),
|
|
2226
|
-
body: JSON.stringify({ streams: streams
|
|
2239
|
+
body: JSON.stringify({ streams: streams.map((stream) => this.backendSubscriptionPath(normalizeSubscriptionStreamPath(stream))) })
|
|
2227
2240
|
});
|
|
2228
2241
|
return await this.subscriptionJson(res, `Subscription stream add failed`);
|
|
2229
2242
|
}
|
|
@@ -7855,7 +7868,7 @@ async function notificationFromClaim(ctx, input) {
|
|
|
7855
7868
|
leaseExpiresAt: input.claim.lease_ttl_ms ? new Date(Date.now() + input.claim.lease_ttl_ms) : void 0
|
|
7856
7869
|
});
|
|
7857
7870
|
await ctx.entityManager.registry.updateStatus(entity.url, `running`);
|
|
7858
|
-
const streams
|
|
7871
|
+
const streams = input.claim.streams.map((stream) => ({
|
|
7859
7872
|
path: withLeadingSlash(stream.path),
|
|
7860
7873
|
offset: stream.tail_offset ?? ``
|
|
7861
7874
|
}));
|
|
@@ -7864,7 +7877,7 @@ async function notificationFromClaim(ctx, input) {
|
|
|
7864
7877
|
epoch: input.claim.generation,
|
|
7865
7878
|
wakeId: input.claim.wake_id,
|
|
7866
7879
|
streamPath: primaryStream,
|
|
7867
|
-
streams
|
|
7880
|
+
streams,
|
|
7868
7881
|
callback: appendPathToUrl(ctx.publicUrl, `/_electric/wake-callbacks/${encodeURIComponent(input.claim.wake_id)}`),
|
|
7869
7882
|
claimToken: input.claim.token,
|
|
7870
7883
|
triggerEvent: `message_received`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@electric-ax/agents-server",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.14",
|
|
4
4
|
"description": "Electric Agents entity runtime server",
|
|
5
5
|
"author": "Durable Stream contributors",
|
|
6
6
|
"bin": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@durable-streams/client": "^0.2.6",
|
|
40
40
|
"@durable-streams/server": "^0.3.5",
|
|
41
41
|
"@durable-streams/state": "^0.2.9",
|
|
42
|
-
"@electric-sql/client": "^1.5.
|
|
42
|
+
"@electric-sql/client": "^1.5.20",
|
|
43
43
|
"@mariozechner/pi-agent-core": "^0.70.2",
|
|
44
44
|
"@opentelemetry/api": "^1.9.1",
|
|
45
45
|
"@sinclair/typebox": "^0.34.48",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"pino-pretty": "^13.0.0",
|
|
55
55
|
"postgres": "^3.4.0",
|
|
56
56
|
"undici": "^7.24.7",
|
|
57
|
-
"@electric-ax/agents-runtime": "0.3.
|
|
57
|
+
"@electric-ax/agents-runtime": "0.3.7"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/node": "^22.19.15",
|
|
@@ -65,9 +65,9 @@
|
|
|
65
65
|
"tsx": "^4.19.0",
|
|
66
66
|
"typescript": "^5.0.0",
|
|
67
67
|
"vitest": "^4.1.0",
|
|
68
|
-
"@electric-ax/agents": "0.4.
|
|
68
|
+
"@electric-ax/agents": "0.4.11",
|
|
69
69
|
"@electric-ax/agents-server-conformance-tests": "0.1.9",
|
|
70
|
-
"@electric-ax/agents-server-ui": "0.4.
|
|
70
|
+
"@electric-ax/agents-server-ui": "0.4.14"
|
|
71
71
|
},
|
|
72
72
|
"files": [
|
|
73
73
|
"dist",
|
package/src/utils/log.ts
CHANGED
|
@@ -8,62 +8,73 @@ const USE_FILE_LOGS = process.env.ELECTRIC_AGENTS_LOG_FILE !== `false`
|
|
|
8
8
|
const USE_PRETTY_LOGS =
|
|
9
9
|
LOG_LEVEL !== `silent` && !process.env.VITEST && !IS_ELECTRON_MAIN
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
? (process.env.ELECTRIC_AGENTS_LOG_DIR ?? path.resolve(process.cwd(), `logs`))
|
|
13
|
-
: undefined
|
|
14
|
-
const LOG_FILE = LOG_DIR
|
|
15
|
-
? path.join(LOG_DIR, `agent-server-${Date.now()}.jsonl`)
|
|
16
|
-
: undefined
|
|
11
|
+
let _logger: pino.Logger | undefined
|
|
17
12
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
13
|
+
function getLogger(): pino.Logger {
|
|
14
|
+
if (_logger) return _logger
|
|
21
15
|
|
|
22
|
-
|
|
16
|
+
const streams: Array<pino.StreamEntry> = []
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
})
|
|
44
|
-
}
|
|
18
|
+
try {
|
|
19
|
+
if (USE_FILE_LOGS) {
|
|
20
|
+
const logDir =
|
|
21
|
+
process.env.ELECTRIC_AGENTS_LOG_DIR ??
|
|
22
|
+
path.resolve(process.cwd(), `logs`)
|
|
23
|
+
fs.mkdirSync(logDir, { recursive: true })
|
|
24
|
+
const logFile = path.join(logDir, `agent-server-${Date.now()}.jsonl`)
|
|
25
|
+
streams.push({
|
|
26
|
+
stream: pino.destination({
|
|
27
|
+
dest: logFile,
|
|
28
|
+
sync: IS_ELECTRON_MAIN,
|
|
29
|
+
}),
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
} catch (err) {
|
|
33
|
+
process.stderr.write(
|
|
34
|
+
`[agents-server] Failed to initialize file logging: ${err instanceof Error ? err.message : err}\n`
|
|
35
|
+
)
|
|
36
|
+
}
|
|
45
37
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
{
|
|
38
|
+
try {
|
|
39
|
+
if (USE_PRETTY_LOGS) {
|
|
40
|
+
streams.push({
|
|
41
|
+
stream: pino.transport({
|
|
42
|
+
target: `pino-pretty`,
|
|
43
|
+
options: {
|
|
44
|
+
colorize: true,
|
|
45
|
+
ignore: `pid,hostname,name`,
|
|
46
|
+
translateTime: `SYS:HH:MM:ss`,
|
|
47
|
+
},
|
|
48
|
+
}),
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
} catch {
|
|
52
|
+
// pino-pretty unavailable — continue without pretty logging
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
_logger =
|
|
56
|
+
streams.length > 0
|
|
57
|
+
? pino(
|
|
58
|
+
{
|
|
59
|
+
base: undefined,
|
|
60
|
+
level: LOG_LEVEL,
|
|
61
|
+
},
|
|
62
|
+
pino.multistream(streams)
|
|
63
|
+
)
|
|
64
|
+
: pino({
|
|
50
65
|
base: undefined,
|
|
66
|
+
enabled: false,
|
|
51
67
|
level: LOG_LEVEL,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
: pino({
|
|
56
|
-
base: undefined,
|
|
57
|
-
enabled: false,
|
|
58
|
-
level: LOG_LEVEL,
|
|
59
|
-
})
|
|
68
|
+
})
|
|
69
|
+
return _logger
|
|
70
|
+
}
|
|
60
71
|
|
|
61
72
|
function formatArgs(args: Array<unknown>): { err?: Error; msg: string } {
|
|
62
73
|
const errors: Array<Error> = []
|
|
63
74
|
const parts: Array<string> = []
|
|
64
|
-
for (const
|
|
65
|
-
if (
|
|
66
|
-
else parts.push(typeof
|
|
75
|
+
for (const value of args) {
|
|
76
|
+
if (value instanceof Error) errors.push(value)
|
|
77
|
+
else parts.push(typeof value === `string` ? value : JSON.stringify(value))
|
|
67
78
|
}
|
|
68
79
|
return {
|
|
69
80
|
err: errors[0],
|
|
@@ -74,22 +85,22 @@ function formatArgs(args: Array<unknown>): { err?: Error; msg: string } {
|
|
|
74
85
|
export const serverLog = {
|
|
75
86
|
info(...args: Array<unknown>): void {
|
|
76
87
|
const { msg } = formatArgs(args)
|
|
77
|
-
|
|
88
|
+
getLogger().info(msg)
|
|
78
89
|
},
|
|
79
90
|
|
|
80
91
|
warn(...args: Array<unknown>): void {
|
|
81
92
|
const { err, msg } = formatArgs(args)
|
|
82
|
-
if (err)
|
|
83
|
-
else
|
|
93
|
+
if (err) getLogger().warn({ err }, msg)
|
|
94
|
+
else getLogger().warn(msg)
|
|
84
95
|
},
|
|
85
96
|
|
|
86
97
|
error(...args: Array<unknown>): void {
|
|
87
98
|
const { err, msg } = formatArgs(args)
|
|
88
|
-
if (err)
|
|
89
|
-
else
|
|
99
|
+
if (err) getLogger().error({ err }, msg)
|
|
100
|
+
else getLogger().error(msg)
|
|
90
101
|
},
|
|
91
102
|
|
|
92
103
|
event(obj: Record<string, unknown>, msg: string): void {
|
|
93
|
-
|
|
104
|
+
getLogger().info(obj, msg)
|
|
94
105
|
},
|
|
95
106
|
}
|