@agimon-ai/po-log 0.0.0-alpha.113 → 0.0.0-alpha.115

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.
Files changed (41) hide show
  1. package/dist/extensions/server.cjs +110 -22
  2. package/dist/extensions/server.cjs.map +1 -1
  3. package/dist/extensions/server.mjs +111 -23
  4. package/dist/extensions/server.mjs.map +1 -1
  5. package/dist/findings-Bo4IHNpr.cjs +165 -0
  6. package/dist/findings-Bo4IHNpr.cjs.map +1 -0
  7. package/dist/findings-DAKeRG4O.mjs +160 -0
  8. package/dist/findings-DAKeRG4O.mjs.map +1 -0
  9. package/dist/http-D7IHAk6Y.mjs +29 -0
  10. package/dist/http-D7IHAk6Y.mjs.map +1 -0
  11. package/dist/http-Dhn2bpMh.cjs +40 -0
  12. package/dist/http-Dhn2bpMh.cjs.map +1 -0
  13. package/dist/index.cjs +3 -2
  14. package/dist/index.mjs +3 -1
  15. package/dist/{metrics-jCZe13Xg.cjs → metrics-Bml7TSZq.cjs} +9 -160
  16. package/dist/metrics-Bml7TSZq.cjs.map +1 -0
  17. package/dist/{metrics-DywCpDJ_.mjs → metrics-DwfV84Fy.mjs} +2 -159
  18. package/dist/metrics-DwfV84Fy.mjs.map +1 -0
  19. package/dist/metrics.cjs +3 -2
  20. package/dist/metrics.mjs +3 -1
  21. package/dist/{metricsSource-BbcKbQJq.cjs → metricsSource-CF3cp-sf.cjs} +4 -29
  22. package/dist/metricsSource-CF3cp-sf.cjs.map +1 -0
  23. package/dist/{metricsSource-BLAhNGEt.mjs → metricsSource-I5p5_t2L.mjs} +2 -27
  24. package/dist/metricsSource-I5p5_t2L.mjs.map +1 -0
  25. package/dist/metricsSource.cjs +1 -1
  26. package/dist/metricsSource.mjs +1 -1
  27. package/dist/metricsStore-CIX2ewUm.mjs +38 -0
  28. package/dist/metricsStore-CIX2ewUm.mjs.map +1 -0
  29. package/dist/metricsStore-N2UlsnN4.cjs +61 -0
  30. package/dist/metricsStore-N2UlsnN4.cjs.map +1 -0
  31. package/dist/metricsStore.cjs +474 -0
  32. package/dist/metricsStore.cjs.map +1 -0
  33. package/dist/metricsStore.d.mts +43 -0
  34. package/dist/metricsStore.d.mts.map +1 -0
  35. package/dist/metricsStore.mjs +471 -0
  36. package/dist/metricsStore.mjs.map +1 -0
  37. package/package.json +14 -9
  38. package/dist/metrics-DywCpDJ_.mjs.map +0 -1
  39. package/dist/metrics-jCZe13Xg.cjs.map +0 -1
  40. package/dist/metricsSource-BLAhNGEt.mjs.map +0 -1
  41. package/dist/metricsSource-BbcKbQJq.cjs.map +0 -1
@@ -24,7 +24,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  enumerable: true
25
25
  }) : target, mod));
26
26
  //#endregion
27
- const require_metricsSource = require("../metricsSource-BbcKbQJq.cjs");
27
+ const require_metricsSource = require("../metricsSource-CF3cp-sf.cjs");
28
+ const require_metricsStore = require("../metricsStore-N2UlsnN4.cjs");
28
29
  let _agimon_ai_po_logsink = require("@agimon-ai/po-logsink");
29
30
  let _agimon_ai_po_core_serverPlugin = require("@agimon-ai/po-core/serverPlugin");
30
31
  let _agimon_ai_po_core_extensionFile = require("@agimon-ai/po-core/extensionFile");
@@ -327,6 +328,59 @@ function createLogsinkNamespace(operations) {
327
328
  };
328
329
  }
329
330
  //#endregion
331
+ //#region src/services/metricsForwarder/index.ts
332
+ const RECORD_FAILED = "Metrics could not be recorded.";
333
+ const METRICS_ENTRY_ATTRIBUTES = new Set(Object.values(require_metricsStore.METRICS_ATTRIBUTE));
334
+ /** Only the fixed, scalar attributes a metrics entry may carry leave the session. */
335
+ function fixedAttributes(attributes) {
336
+ const kept = {};
337
+ for (const [key, value] of Object.entries(attributes)) {
338
+ if (!METRICS_ENTRY_ATTRIBUTES.has(key)) continue;
339
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") kept[key] = value;
340
+ }
341
+ return kept;
342
+ }
343
+ /**
344
+ * Hands a session's sanitized telemetry records to the metrics service a host bound, in batches.
345
+ *
346
+ * A host that bound none, such as one that keeps the log sink, queues nothing. Records made in the same tick
347
+ * travel together, so a session pays one call for a turn rather than one per record.
348
+ */
349
+ function createMetricsForwarder(options) {
350
+ const now = options.now ?? Date.now;
351
+ let waiting = [];
352
+ let scheduled = false;
353
+ const flush = async () => {
354
+ scheduled = false;
355
+ const batch = waiting;
356
+ waiting = [];
357
+ if (batch.length === 0) return;
358
+ const service = options.resolve();
359
+ if (service === void 0) return;
360
+ for (let start = 0; start < batch.length; start += 500) try {
361
+ await service.record(batch.slice(start, start + 500));
362
+ } catch {
363
+ options.onDiagnostic?.(RECORD_FAILED);
364
+ }
365
+ };
366
+ return {
367
+ record(name, attributes) {
368
+ if (options.resolve() === void 0) return;
369
+ waiting.push({
370
+ at: now(),
371
+ event: name,
372
+ attributes: fixedAttributes(attributes)
373
+ });
374
+ if (scheduled) return;
375
+ scheduled = true;
376
+ queueMicrotask(() => {
377
+ flush().catch(() => options.onDiagnostic?.(RECORD_FAILED));
378
+ });
379
+ },
380
+ flush
381
+ };
382
+ }
383
+ //#endregion
330
384
  //#region src/services/telemetryEnabled/index.ts
331
385
  function isEnabled(value) {
332
386
  return value === "1" || value?.toLowerCase() === "true" || value?.toLowerCase() === "yes";
@@ -784,9 +838,14 @@ function createServerTelemetry(options = {}) {
784
838
  //#endregion
785
839
  //#region src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts
786
840
  const createLogServerRoot = ({ context, agent, host, signal: ownerSignal }) => {
841
+ const metrics = createMetricsForwarder({
842
+ resolve: () => (0, _agimon_ai_po_core_serverPlugin.readPoServerScope)(context)?.resolve(require_metricsStore.PO_LOG_METRICS_CONTRACT),
843
+ onDiagnostic: (message) => host.context.onNotice(message)
844
+ });
787
845
  const runtime = createServerTelemetry({
788
846
  workflowContext: (0, _agimon_ai_po_core_workflow.readPoWorkflowContextService)(context),
789
- childSessionHookRegistry: (0, _agimon_ai_po_core_childSession.readPoChildSessionHookRegistry)(context)
847
+ childSessionHookRegistry: (0, _agimon_ai_po_core_childSession.readPoChildSessionHookRegistry)(context),
848
+ metrics
790
849
  });
791
850
  const sessionId = agent?.context.sessionId;
792
851
  const logQueries = agent && sessionId ? createLogsinkOperations({
@@ -1135,6 +1194,25 @@ function toReport(report, source, dimension) {
1135
1194
  function isEmpty(report) {
1136
1195
  return report.totals.totalTokens === 0 && report.groups.length === 0 && report.tools.length === 0;
1137
1196
  }
1197
+ /**
1198
+ * A bound store answers before any sink is looked for. It claims no transport: it is neither the sink's HTTP
1199
+ * API nor its worker. The store is looked up on every query, because a host binds it after this API starts.
1200
+ */
1201
+ function preferBound(bound, sink) {
1202
+ let answeredByStore = false;
1203
+ return {
1204
+ async query(params) {
1205
+ const store = bound();
1206
+ answeredByStore = store !== void 0;
1207
+ return store === void 0 ? sink.query(params) : store.query(params);
1208
+ },
1209
+ lastTransport: () => answeredByStore ? void 0 : sink.lastTransport(),
1210
+ instance: () => sink.instance?.(),
1211
+ close: async () => {
1212
+ await sink.close?.();
1213
+ }
1214
+ };
1215
+ }
1138
1216
  function createLogHubApi(options = {}) {
1139
1217
  const app = new hono.Hono();
1140
1218
  const identity = {
@@ -1142,7 +1220,8 @@ function createLogHubApi(options = {}) {
1142
1220
  serviceName: "pi",
1143
1221
  ...options.env === void 0 ? {} : { env: options.env }
1144
1222
  };
1145
- const source = options.source ?? require_metricsSource.createMetricsSource(identity);
1223
+ const sink = options.source ?? require_metricsSource.createMetricsSource(identity);
1224
+ const source = options.metrics === void 0 ? sink : preferBound(options.metrics, sink);
1146
1225
  const issues = options.issues ?? createIssuesSource(identity);
1147
1226
  const fetchImpl = options.fetchImpl ?? globalThis.fetch;
1148
1227
  const sinkEndpoint = options.sinkEndpoint ?? (() => require_metricsSource.resolveMetricsEndpoint(identity));
@@ -1233,27 +1312,36 @@ function createLogHubApi(options = {}) {
1233
1312
  });
1234
1313
  return app;
1235
1314
  }
1315
+ /**
1316
+ * The package's API for a host. `metrics` resolves the store the host bound, if any, so a host that keeps its
1317
+ * own metrics answers from them and every other host keeps answering from the log sink.
1318
+ */
1319
+ function createLogApi(metrics) {
1320
+ return {
1321
+ basePath: "log",
1322
+ start(context) {
1323
+ const env = { ...context.environment };
1324
+ const source = require_metricsSource.createMetricsSource({
1325
+ env,
1326
+ packageName: PACKAGE_NAME$1,
1327
+ serviceName: "pi"
1328
+ });
1329
+ const app = createLogHubApi({
1330
+ source,
1331
+ env,
1332
+ ...metrics === void 0 ? {} : { metrics }
1333
+ });
1334
+ return {
1335
+ fetch: (request) => app.fetch(request),
1336
+ close: () => source.close?.()
1337
+ };
1338
+ }
1339
+ };
1340
+ }
1236
1341
  //#endregion
1237
1342
  //#region src/extensions/(backend)/api/log/route.server.ts
1238
- var route_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoute)({
1239
- basePath: "log",
1240
- start(context) {
1241
- const env = { ...context.environment };
1242
- const source = require_metricsSource.createMetricsSource({
1243
- env,
1244
- packageName: PACKAGE_NAME$1,
1245
- serviceName: "pi"
1246
- });
1247
- const app = createLogHubApi({
1248
- source,
1249
- env
1250
- });
1251
- return {
1252
- fetch: (request) => app.fetch(request),
1253
- close: () => source.close?.()
1254
- };
1255
- }
1256
- });
1343
+ /** The store is resolved per request: a host that keeps its own metrics binds it after this API mounts. */
1344
+ var route_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoute)(({ context }) => createLogApi(() => (0, _agimon_ai_po_core_serverPlugin.readPoServerScope)(context)?.resolve(require_metricsStore.PO_LOG_METRICS_CONTRACT)));
1257
1345
  //#endregion
1258
1346
  //#region src/extensions/workspaces/sessions/(backend)/command/log-metrics.server.ts
1259
1347
  var log_metrics_server_default = (0, _agimon_ai_po_core_extensionFile.defineServerCommand)((context) => context.root.commands[0]);