oh-my-knowledge 0.52.0 → 0.52.1

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.
@@ -61,6 +61,16 @@ const LANE_LABELS = {
61
61
  en: { title: 'Results', detail: 'Tool returns and call status', empty: 'No tool results observed' },
62
62
  },
63
63
  };
64
+ const SOURCE_RECORD_PARTIAL_LABELS = {
65
+ zh: {
66
+ records: '原始日志归档不完整:已保留 {retained} 条,省略 {omitted} 条。',
67
+ content: '部分原始日志内容已按归档上限截断。',
68
+ },
69
+ en: {
70
+ records: 'The raw-log archive is partial: {retained} retained, {omitted} omitted.',
71
+ content: 'Some raw-log content was truncated by the archive limit.',
72
+ },
73
+ };
64
74
  export function renderKnowledgeDebuggerPage(model, lang = DEFAULT_LANG, options = {}) {
65
75
  const zh = lang === 'zh';
66
76
  const projection = projectReplay(model, lang, { pendingToolResults: Boolean(options.live) });
@@ -398,7 +408,8 @@ export function renderKnowledgeDebuggerPage(model, lang = DEFAULT_LANG, options
398
408
  redacted: zh ? '【不透明加密载荷已省略】' : '[Opaque encrypted payload omitted]',
399
409
  truncated: zh ? '【该记录已按归档上限截断】' : '[Record truncated by archive limit]',
400
410
  loadFailed: zh ? '原始日志读取失败。可以切换视图后重试。' : 'Raw logs could not be loaded. Switch views and retry.',
401
- partial: zh ? '原始日志归档不完整:已保留 {retained} 条,省略 {omitted} 条。' : 'The raw-log archive is partial: {retained} retained, {omitted} omitted.',
411
+ partialRecords: SOURCE_RECORD_PARTIAL_LABELS[lang].records,
412
+ partialContent: SOURCE_RECORD_PARTIAL_LABELS[lang].content,
402
413
  })};
403
414
  const cardLane = (card) => card.closest('.trajectory-lane')?.dataset.lane || '';
404
415
  const operationIds = semanticPanels.map((panel) => panel.dataset.trajectorySemanticPanel).filter(Boolean);
@@ -919,9 +930,12 @@ export function renderKnowledgeDebuggerPage(model, lang = DEFAULT_LANG, options
919
930
  if (archive.status === 'partial') {
920
931
  const notice = document.createElement('div');
921
932
  notice.className = 'trajectory-record-notice';
922
- notice.textContent = sourceRecordLabels.partial
923
- .replace('{retained}', String(archive.recordCount ?? archive.records?.length ?? 0))
924
- .replace('{omitted}', String(archive.omittedRecordCount ?? 0));
933
+ const omittedRecordCount = Number(archive.omittedRecordCount ?? 0);
934
+ notice.textContent = omittedRecordCount > 0
935
+ ? sourceRecordLabels.partialRecords
936
+ .replace('{retained}', String(archive.recordCount ?? archive.records?.length ?? 0))
937
+ .replace('{omitted}', String(omittedRecordCount))
938
+ : sourceRecordLabels.partialContent;
925
939
  sourceRecordList.append(notice);
926
940
  }
927
941
  (Array.isArray(archive.records) ? archive.records : []).forEach(appendSourceRecord);
@@ -1527,9 +1541,10 @@ function buildOperationLayout(steps, startTimestamp, lang, pendingToolResults) {
1527
1541
  previousEndMs = eventTimes.length > 0 ? Math.max(...eventTimes) : startMs ?? previousEndMs;
1528
1542
  });
1529
1543
  const tickStride = Math.max(1, Math.ceil(steps.length / 9));
1530
- const axisTicks = steps.flatMap((step, index) => (index === 0 || index === steps.length - 1 || index % tickStride === 0
1544
+ const axisTickCandidates = steps.flatMap((step, index) => (index === 0 || index === steps.length - 1 || index % tickStride === 0
1531
1545
  ? [{ position: positions[index] ?? TRACK_START_PADDING, label: formatRelativeTimestamp(step.timestamp, startTimestamp) }]
1532
1546
  : []));
1547
+ const axisTicks = axisTickCandidates.filter((tick, index) => index === 0 || tick.label !== axisTickCandidates[index - 1]?.label);
1533
1548
  const lastPosition = positions.at(-1) ?? TRACK_START_PADDING;
1534
1549
  const lastWidth = steps.length > 0 ? replayCardWidth(steps[steps.length - 1], lang, pendingToolResults) : REPLAY_CARD_WIDTH;
1535
1550
  const occupiedRight = Math.max(lastPosition + lastWidth, ...rightEdgeByTrack.values());
@@ -1696,10 +1711,8 @@ function renderSourceRecordList(model, startTimestamp, lang, sourceRecordsEndpoi
1696
1711
  const zh = lang === 'zh';
1697
1712
  const source = model.sourceRecords;
1698
1713
  const lazy = Boolean(sourceRecordsEndpoint && source.status !== 'unavailable' && source.recordCount > 0 && source.records.length === 0);
1699
- const statusNotice = source.status === 'partial'
1700
- ? `<div class="trajectory-record-notice">${zh
1701
- ? `原始日志归档不完整:已保留 ${source.recordCount} 条,省略 ${source.omittedRecordCount} 条。`
1702
- : `The raw-log archive is partial: ${source.recordCount} retained, ${source.omittedRecordCount} omitted.`}</div>`
1714
+ const statusNotice = !lazy && source.status === 'partial'
1715
+ ? `<div class="trajectory-record-notice">${e(sourceRecordPartialNotice(source.recordCount, source.omittedRecordCount, lang))}</div>`
1703
1716
  : '';
1704
1717
  const rows = source.records.map((record) => {
1705
1718
  const preview = compactText(record.raw || (zh ? '空记录' : 'Empty record'), 180);
@@ -1720,6 +1733,13 @@ function renderSourceRecordList(model, startTimestamp, lang, sourceRecordsEndpoi
1720
1733
  const start = startTimestamp ? ` data-source-records-start="${e(startTimestamp)}"` : '';
1721
1734
  return `<section class="trajectory-raw-list" data-event-view="source"${endpoint}${start} data-source-records-loaded="${lazy ? 'false' : 'true'}" aria-label="${zh ? '按来源顺序排列的原始日志' : 'Raw logs in source order'}"><header class="trajectory-raw-head"><span>${zh ? '时间' : 'Time'}</span><span>${zh ? '来源类型' : 'Source type'}</span><span>${zh ? '原始 JSONL' : 'Raw JSONL'}</span><span>${zh ? '来源位置' : 'Source position'}</span></header>${statusNotice}${rows}${unavailable}${loading}</section>`;
1722
1735
  }
1736
+ function sourceRecordPartialNotice(recordCount, omittedRecordCount, lang) {
1737
+ if (omittedRecordCount === 0)
1738
+ return SOURCE_RECORD_PARTIAL_LABELS[lang].content;
1739
+ return SOURCE_RECORD_PARTIAL_LABELS[lang].records
1740
+ .replace('{retained}', String(recordCount))
1741
+ .replace('{omitted}', String(omittedRecordCount));
1742
+ }
1723
1743
  function sourceRecordUnavailableLabel(reason, lang) {
1724
1744
  const zh = lang === 'zh';
1725
1745
  if (reason === 'source_missing')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-knowledge",
3
- "version": "0.52.0",
3
+ "version": "0.52.1",
4
4
  "packageManager": "yarn@4.16.0",
5
5
  "description": "OMK — Observe. Measure. Know. Evidence-backed knowledge changes for AI applications.",
6
6
  "type": "module",