@ouro.bot/cli 0.1.0-alpha.318 → 0.1.0-alpha.319

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/changelog.json CHANGED
@@ -1,6 +1,12 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.319",
6
+ "changes": [
7
+ "fix(heart): use true per-message ingress time for session event timestamps instead of batch-save time"
8
+ ]
9
+ },
4
10
  {
5
11
  "version": "0.1.0-alpha.318",
6
12
  "changes": [
@@ -38,6 +38,8 @@ exports.validateSessionMessages = validateSessionMessages;
38
38
  exports.repairSessionMessages = repairSessionMessages;
39
39
  exports.migrateToolNames = migrateToolNames;
40
40
  exports.sanitizeProviderMessages = sanitizeProviderMessages;
41
+ exports.stampIngressTime = stampIngressTime;
42
+ exports.getIngressTime = getIngressTime;
41
43
  exports.projectProviderMessages = projectProviderMessages;
42
44
  exports.annotateMessageTimestamps = annotateMessageTimestamps;
43
45
  exports.bestEventTimestamp = bestEventTimestamp;
@@ -356,7 +358,14 @@ function sanitizeProviderMessages(messages) {
356
358
  }
357
359
  return migrateToolNames(stripOrphanedToolResults(repairSessionMessages(normalized.map(toProviderMessage))));
358
360
  }
359
- function createEventTime(role, recordedAt, captureKind) {
361
+ function stampIngressTime(msg) {
362
+ msg._ingressAt = new Date().toISOString();
363
+ }
364
+ function getIngressTime(msg) {
365
+ const value = msg._ingressAt;
366
+ return typeof value === "string" ? value : null;
367
+ }
368
+ function createEventTime(role, recordedAt, captureKind, ingressAt) {
360
369
  if (captureKind === "migration") {
361
370
  return {
362
371
  authoredAt: null,
@@ -371,7 +380,7 @@ function createEventTime(role, recordedAt, captureKind) {
371
380
  return {
372
381
  authoredAt: null,
373
382
  authoredAtSource: "unknown",
374
- observedAt: recordedAt,
383
+ observedAt: ingressAt ?? recordedAt,
375
384
  observedAtSource: "ingest",
376
385
  recordedAt,
377
386
  recordedAtSource: "save",
@@ -386,7 +395,7 @@ function createEventTime(role, recordedAt, captureKind) {
386
395
  recordedAtSource: "save",
387
396
  };
388
397
  }
389
- function buildEventFromMessage(message, sequence, recordedAt, captureKind, sourceMessageIndex, legacyVersion) {
398
+ function buildEventFromMessage(message, sequence, recordedAt, captureKind, sourceMessageIndex, legacyVersion, ingressAt) {
390
399
  const normalized = normalizeMessage(message);
391
400
  const role = normalized.role;
392
401
  return {
@@ -398,7 +407,7 @@ function buildEventFromMessage(message, sequence, recordedAt, captureKind, sourc
398
407
  toolCallId: role === "tool" ? normalized.toolCallId : null,
399
408
  toolCalls: role === "assistant" ? normalized.toolCalls : [],
400
409
  attachments: [],
401
- time: createEventTime(role, recordedAt, captureKind),
410
+ time: createEventTime(role, recordedAt, captureKind, ingressAt),
402
411
  relations: {
403
412
  replyToEventId: null,
404
413
  threadRootEventId: null,
@@ -666,6 +675,8 @@ function selectProjectedEventIds(currentMessages, currentEventIds, trimmedMessag
666
675
  }
667
676
  function buildCanonicalSessionEnvelope(options) {
668
677
  const existing = options.existing;
678
+ // Capture ingress timestamps before sanitization strips extra properties
679
+ const currentIngressTimes = options.currentMessages.map(getIngressTime);
669
680
  const previousMessages = sanitizeProviderMessages(options.previousMessages);
670
681
  const currentMessages = sanitizeProviderMessages(options.currentMessages);
671
682
  const trimmedMessages = sanitizeProviderMessages(options.trimmedMessages);
@@ -675,8 +686,9 @@ function buildCanonicalSessionEnvelope(options) {
675
686
  const commonPrefix = findCommonPrefixLength(previousMessages, currentMessages);
676
687
  const appendFrom = previousMessages.length === commonPrefix ? previousMessages.length : commonPrefix;
677
688
  const newMessages = currentMessages.slice(appendFrom);
689
+ const newIngressTimes = currentIngressTimes.slice(appendFrom);
678
690
  const baseSequence = existing?.events.length ?? 0;
679
- const newEvents = newMessages.map((message, index) => buildEventFromMessage(message, baseSequence + index + 1, options.recordedAt, "live", null, null));
691
+ const newEvents = newMessages.map((message, index) => buildEventFromMessage(message, baseSequence + index + 1, options.recordedAt, "live", null, null, newIngressTimes[index]));
680
692
  const events = [...(existing?.events ?? []), ...newEvents];
681
693
  const currentEventIds = [
682
694
  ...previousProjectionIds.slice(0, appendFrom),
@@ -56,6 +56,7 @@ const prompt_1 = require("../mind/prompt");
56
56
  const phrases_1 = require("../mind/phrases");
57
57
  const format_1 = require("../mind/format");
58
58
  const config_1 = require("../heart/config");
59
+ const session_events_1 = require("../heart/session-events");
59
60
  const context_1 = require("../mind/context");
60
61
  const pending_1 = require("../mind/pending");
61
62
  const commands_1 = require("./commands");
@@ -857,7 +858,9 @@ async function runCliSession(options) {
857
858
  const userContent = contentParts
858
859
  ? contentParts
859
860
  : (prefix ? `${prefix}\n\n${input}` : input);
860
- messages.push({ role: "user", content: userContent });
861
+ const userMsg = { role: "user", content: userContent };
862
+ (0, session_events_1.stampIngressTime)(userMsg);
863
+ messages.push(userMsg);
861
864
  const traceId = (0, nerves_1.createTraceId)();
862
865
  result = await (0, core_1.runAgent)(messages, cliCallbacks, options.skipSystemPromptRefresh ? undefined : "cli", currentAbort.signal, {
863
866
  toolChoiceRequired: getEffectiveToolChoiceRequired(),
@@ -353,6 +353,7 @@ async function handleInboundTurn(input) {
353
353
  }
354
354
  // Append user messages from the inbound turn
355
355
  for (const msg of input.messages) {
356
+ (0, session_events_1.stampIngressTime)(msg);
356
357
  sessionMessages.push(msg);
357
358
  }
358
359
  // Step 4b: Continuity pipeline — derive tempo, build start-of-turn packet, snapshot obligations
@@ -45,6 +45,7 @@ const path = __importStar(require("path"));
45
45
  const core_1 = require("../heart/core");
46
46
  const identity_1 = require("../heart/identity");
47
47
  const config_1 = require("../heart/config");
48
+ const session_events_1 = require("../heart/session-events");
48
49
  const context_1 = require("../mind/context");
49
50
  const prompt_1 = require("../mind/prompt");
50
51
  const channel_1 = require("../mind/friends/channel");
@@ -127,11 +128,13 @@ async function runSenseTurn(options) {
127
128
  };
128
129
  /* v8 ignore stop */
129
130
  // Run the pipeline
131
+ const userMsg = { role: "user", content: userMessage };
132
+ (0, session_events_1.stampIngressTime)(userMsg);
130
133
  await (0, pipeline_1.handleInboundTurn)({
131
134
  channel,
132
135
  sessionKey,
133
136
  capabilities,
134
- messages: [{ role: "user", content: userMessage }],
137
+ messages: [userMsg],
135
138
  callbacks,
136
139
  /* v8 ignore start — delegation wrappers; pipeline integration tested separately */
137
140
  friendResolver: { resolve: () => resolver.resolve() },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.318",
3
+ "version": "0.1.0-alpha.319",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",