@juli-os/ledger 0.1.2 → 0.1.3

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/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { createLedgerStore, type LifecycleStore } from './platform/ledger/store.ts';
2
2
  export type { Workflow, Step, WorkflowStatus, StepStatus, StepKind } from './contracts/entities.ts';
3
+ export { TERMINAL_WORKFLOW_STATUSES, STEP_KINDS, AGENT_STEP_KINDS, INSTRUCTABLE_STEP_KINDS, type LedgerEvent, type Run, type Prompt, type TaskView, } from './contracts/entities.ts';
3
4
  export { createUsageStore, type UsageRecord, type UsageStats, type TimelinePoint, type UsageStore, } from './platform/ledger/usage.ts';
4
5
  export { findPrice, priceUsage, type TierWhen, type PriceTier, type ModelPrice, PRICING_SOURCE, PRICING_RETRIEVED_AT, BIGMODEL_PRICES, type UsageRow, type CostBreakdown, type ModelUsageCost, type UsageCost, } from './platform/ledger/pricing.ts';
5
6
  export { emptyCaseFile, parseCaseFile, serializeCaseFile, withOriginal, appendSection, appendExecution, appendDecision, appendReference, originalEmail, type CaseDecision, type ArtifactRef, type CaseFileDoc, } from './platform/ledger/casefile.ts';
package/dist/index.js CHANGED
@@ -29,7 +29,18 @@ var TERMINAL_WORKFLOW_STATUSES = [
29
29
  "cancelled",
30
30
  "rejected"
31
31
  ];
32
+ var STEP_KINDS = [
33
+ "triage",
34
+ "gate",
35
+ "agent",
36
+ "verify",
37
+ "draft",
38
+ "send",
39
+ "llm",
40
+ "share"
41
+ ];
32
42
  var AGENT_STEP_KINDS = ["agent", "verify"];
43
+ var INSTRUCTABLE_STEP_KINDS = ["agent", "verify", "llm", "draft"];
33
44
 
34
45
  // src/contracts/statuses.ts
35
46
  var WORKFLOW_STATUSES = [
@@ -107,6 +118,10 @@ var withOriginal = (cf, o, now) => ({
107
118
  ...cf,
108
119
  original: {
109
120
  from: o.from,
121
+ // Sender display name (RFC2047-decoded) — recorded into the case file with
122
+ // the original message after the 2026-10-01 Chen Lijun hallucination
123
+ // incident: the legitimate source for reply salutations, so the agent is no
124
+ // longer forced to invent a name from the address.
110
125
  ...o.fromName !== void 0 && o.fromName !== "" ? { from_name: o.fromName } : {},
111
126
  subject: o.subject,
112
127
  body: o.body,
@@ -584,9 +599,11 @@ var createLedgerStore = (dbPath, deps = {}) => {
584
599
  };
585
600
  },
586
601
  activeRunForSession: (session) => activeRunOf(session),
587
- /** 活跃去重:同 dedup_key 且工作流仍在途 → 跳过重复建流。
588
- * ⚠ ESCAPE '\' 必须与转义成对:message-id 几乎必含 `_`,漏写 ESCAPE 时
589
- * `\_` 成了"字面反斜杠+任意字符",模式永不匹配——去重整体失效(09-07 事故)。 */
602
+ /** Active dedup: same dedup_key and the workflow still in flight → skip
603
+ * creating a duplicate. ⚠ ESCAPE '\' must pair with the escaping: a
604
+ * message-id almost always contains `_`; without ESCAPE, `\_` becomes
605
+ * "literal backslash + any character", the pattern never matches — and
606
+ * dedup fails wholesale (09-07 incident). */
590
607
  hasActiveDedup(key) {
591
608
  const r = db.prepare(
592
609
  `SELECT 1 FROM workflows WHERE status IN (${sqlInList(DEDUP_WINDOW_STATUSES)})
@@ -594,8 +611,10 @@ var createLedgerStore = (dbPath, deps = {}) => {
594
611
  ).get(dedupPattern(key));
595
612
  return r !== void 0;
596
613
  },
597
- /** 已摄取去重(轮询层):同 dedup_key 存在任何非 rejected 工作流 → 这封
598
- * 邮件已被处理过(含 failed),轮询不再重复拉取。重试走步骤 retry,不走再摄取。 */
614
+ /** Ingested dedup (polling layer): any non-rejected workflow with the same
615
+ * dedup_key → this email has already been handled (failed included);
616
+ * polling won't fetch it again. Retries go through step retry, not
617
+ * re-ingestion. */
599
618
  hasSeenDedup(key) {
600
619
  const r = db.prepare(
601
620
  `SELECT 1 FROM workflows WHERE status != 'rejected'
@@ -603,11 +622,14 @@ var createLedgerStore = (dbPath, deps = {}) => {
603
622
  ).get(dedupPattern(key));
604
623
  return r !== void 0;
605
624
  },
606
- /** 自回环守卫查询(2026-09-20 断点十三):message_id 是否命中本引擎已
607
- * 发送记录——completed send 步的 output.message_id(email_sent 事件同源
608
- * 落账)。进件层据此丢弃投递副本回灌(引擎给轮询邮箱自己发信的 echo)。
609
- * LIKE 预筛 + 精确比对:JSON 编码取实际存储字节,%/_/\ 照 dedupPattern
610
- * 成对转义(message-id 几乎必含 `_`)。 */
625
+ /** Self-loop guard query (2026-09-20 breakpoint 13): does the message_id
626
+ * hit a record this engine already sent — the output.message_id of a
627
+ * completed send step (booked from the same source as email_sent events)?
628
+ * The intake layer uses this to discard delivery-copy feedback (the echo
629
+ * of the engine mailing the polling mailbox itself). LIKE prefilter +
630
+ * exact comparison: JSON-encode to the actually stored bytes; %/_/\ are
631
+ * escaped in pairs like dedupPattern (a message-id almost always contains
632
+ * `_`). */
611
633
  recordSentMessageId(messageId, meta) {
612
634
  if (messageId === "") return;
613
635
  db.prepare(
@@ -719,59 +741,61 @@ var PRICING_SOURCE = "https://docs.bigmodel.cn/cn/guide/start/pricing";
719
741
  var PRICING_RETRIEVED_AT = "2026-10-06";
720
742
  var K32 = 32e3;
721
743
  var K200 = 200;
722
- var flat = (input, cache, output, note = "\u7EDF\u4E00\u4EF7") => ({ when: {}, input, cache, output, note });
744
+ var flat = (input, cache, output, note = "flat rate") => ({ when: {}, input, cache, output, note });
723
745
  var BIGMODEL_PRICES = [
746
+ // ---- Flagship ----
724
747
  { id: "glm-5.3", label: "GLM-5.3", tiers: [flat(8, 2, 28)] },
725
748
  { id: "glm-5.3-flash", label: "GLM-5.3-Flash", tiers: [flat(0.8, 0.23, 2.8)] },
726
749
  { id: "glm-5.3-flashx", label: "GLM-5.3-FlashX", tiers: [flat(2, 0.57, 7)] },
750
+ // ---- Text ----
727
751
  { id: "glm-5.2", label: "GLM-5.2", tiers: [flat(8, 2, 28)] },
728
752
  {
729
753
  id: "glm-5.1",
730
754
  label: "GLM-5.1",
731
755
  tiers: [
732
- { when: { inputLt: K32 }, input: 6, cache: 1.3, output: 24, note: "\u5165<32K" },
733
- { when: { inputGte: K32 }, input: 8, cache: 2, output: 28, note: "\u5165\u226532K" }
756
+ { when: { inputLt: K32 }, input: 6, cache: 1.3, output: 24, note: "in<32K" },
757
+ { when: { inputGte: K32 }, input: 8, cache: 2, output: 28, note: "in>=32K" }
734
758
  ]
735
759
  },
736
760
  {
737
761
  id: "glm-5-turbo",
738
762
  label: "GLM-5-Turbo",
739
763
  tiers: [
740
- { when: { inputLt: K32 }, input: 5, cache: 1.2, output: 22, note: "\u5165<32K" },
741
- { when: { inputGte: K32 }, input: 7, cache: 1.8, output: 26, note: "\u5165\u226532K" }
764
+ { when: { inputLt: K32 }, input: 5, cache: 1.2, output: 22, note: "in<32K" },
765
+ { when: { inputGte: K32 }, input: 7, cache: 1.8, output: 26, note: "in>=32K" }
742
766
  ]
743
767
  },
744
768
  {
745
769
  id: "glm-5",
746
770
  label: "GLM-5",
747
771
  tiers: [
748
- { when: { inputLt: K32 }, input: 4, cache: 1, output: 18, note: "\u5165<32K" },
749
- { when: { inputGte: K32 }, input: 6, cache: 1.5, output: 22, note: "\u5165\u226532K" }
772
+ { when: { inputLt: K32 }, input: 4, cache: 1, output: 18, note: "in<32K" },
773
+ { when: { inputGte: K32 }, input: 6, cache: 1.5, output: 22, note: "in>=32K" }
750
774
  ]
751
775
  },
752
776
  {
753
777
  id: "glm-4.7",
754
778
  label: "GLM-4.7",
755
779
  tiers: [
756
- { when: { inputLt: K32, outputLt: K200 }, input: 2, cache: 0.4, output: 8, note: "\u5165<32K\xB7\u51FA<0.2K" },
757
- { when: { inputLt: K32, outputGte: K200 }, input: 3, cache: 0.6, output: 14, note: "\u5165<32K\xB7\u51FA\u22650.2K" },
758
- { when: { inputGte: K32 }, input: 4, cache: 0.8, output: 16, note: "\u516532K\u2013200K" }
780
+ { when: { inputLt: K32, outputLt: K200 }, input: 2, cache: 0.4, output: 8, note: "in<32K\xB7out<0.2K" },
781
+ { when: { inputLt: K32, outputGte: K200 }, input: 3, cache: 0.6, output: 14, note: "in<32K\xB7out>=0.2K" },
782
+ { when: { inputGte: K32 }, input: 4, cache: 0.8, output: 16, note: "in 32K\u2013200K" }
759
783
  ]
760
784
  },
761
785
  {
762
786
  id: "glm-4.5-air",
763
787
  label: "GLM-4.5-Air",
764
788
  tiers: [
765
- { when: { inputLt: K32, outputLt: K200 }, input: 0.8, cache: 0.16, output: 2, note: "\u5165<32K\xB7\u51FA<0.2K" },
766
- { when: { inputLt: K32, outputGte: K200 }, input: 0.8, cache: 0.16, output: 6, note: "\u5165<32K\xB7\u51FA\u22650.2K" },
767
- { when: { inputGte: K32 }, input: 1.2, cache: 0.24, output: 8, note: "\u516532K\u2013128K" }
789
+ { when: { inputLt: K32, outputLt: K200 }, input: 0.8, cache: 0.16, output: 2, note: "in<32K\xB7out<0.2K" },
790
+ { when: { inputLt: K32, outputGte: K200 }, input: 0.8, cache: 0.16, output: 6, note: "in<32K\xB7out>=0.2K" },
791
+ { when: { inputGte: K32 }, input: 1.2, cache: 0.24, output: 8, note: "in 32K\u2013128K" }
768
792
  ]
769
793
  },
770
794
  { id: "glm-4.7-flashx", label: "GLM-4.7-FlashX", tiers: [flat(0.5, 0.1, 3)] },
771
- { id: "glm-4.7-flash", label: "GLM-4.7-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, 0, 0, "\u514D\u8D39")] },
795
+ { id: "glm-4.7-flash", label: "GLM-4.7-Flash (free)", tiers: [flat(0, 0, 0, "free")] },
772
796
  { id: "glm-4-plus", label: "GLM-4-Plus", tiers: [flat(5, 2.5, 5)] },
773
797
  { id: "glm-4-air-250414", label: "GLM-4-Air-250414", tiers: [flat(0.5, 0.25, 0.5)] },
774
- { id: "glm-4-air", label: "GLM-4-Air\uFF08\u540C 250414 \u7248\u4EF7\uFF09", tiers: [flat(0.5, 0.25, 0.5)] },
798
+ { id: "glm-4-air", label: "GLM-4-Air (same price as 250414)", tiers: [flat(0.5, 0.25, 0.5)] },
775
799
  { id: "glm-4-airx", label: "GLM-4-AirX", tiers: [flat(10, null, 10)] },
776
800
  { id: "glm-4-long", label: "GLM-4-Long", tiers: [flat(1, 0.5, 1)] },
777
801
  { id: "glm-4-assistant", label: "GLM-4-Assistant", tiers: [flat(5, null, 5)] },
@@ -779,53 +803,55 @@ var BIGMODEL_PRICES = [
779
803
  { id: "glm-z1-airx", label: "GLM-Z1-AirX", tiers: [flat(5, null, 5)] },
780
804
  { id: "glm-z1-flashx", label: "GLM-Z1-FlashX", tiers: [flat(0.1, null, 0.1)] },
781
805
  { id: "glm-4-flashx-250414", label: "GLM-4-FlashX-250414", tiers: [flat(0.1, 0.05, 0.1)] },
782
- { id: "glm-4-flashx", label: "GLM-4-FlashX\uFF08\u540C 250414 \u7248\u4EF7\uFF09", tiers: [flat(0.1, 0.05, 0.1)] },
783
- { id: "glm-4-flash-250414", label: "GLM-4-Flash-250414\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, null, 0, "\u514D\u8D39\xB7\u7F13\u5B58\u4E0D\u652F\u6301")] },
784
- { id: "glm-4-flash", label: "GLM-4-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, null, 0, "\u514D\u8D39\xB7\u7F13\u5B58\u4E0D\u652F\u6301")] },
785
- { id: "glm-z1-flash", label: "GLM-Z1-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, null, 0, "\u514D\u8D39\xB7\u7F13\u5B58\u4E0D\u652F\u6301")] },
806
+ { id: "glm-4-flashx", label: "GLM-4-FlashX (same price as 250414)", tiers: [flat(0.1, 0.05, 0.1)] },
807
+ { id: "glm-4-flash-250414", label: "GLM-4-Flash-250414 (free)", tiers: [flat(0, null, 0, "free \xB7 cache unsupported")] },
808
+ { id: "glm-4-flash", label: "GLM-4-Flash (free)", tiers: [flat(0, null, 0, "free \xB7 cache unsupported")] },
809
+ { id: "glm-z1-flash", label: "GLM-Z1-Flash (free)", tiers: [flat(0, null, 0, "free \xB7 cache unsupported")] },
810
+ // ---- Vision ----
786
811
  { id: "glm-ocr", label: "GLM-OCR", tiers: [flat(0.2, null, 0.2)] },
787
812
  {
788
813
  id: "glm-5v-turbo",
789
814
  label: "GLM-5V-Turbo",
790
815
  tiers: [
791
- { when: { inputLt: K32 }, input: 5, cache: 1.2, output: 22, note: "\u5165<32K" },
792
- { when: { inputGte: K32 }, input: 7, cache: 1.8, output: 26, note: "\u5165\u226532K" }
816
+ { when: { inputLt: K32 }, input: 5, cache: 1.2, output: 22, note: "in<32K" },
817
+ { when: { inputGte: K32 }, input: 7, cache: 1.8, output: 26, note: "in>=32K" }
793
818
  ]
794
819
  },
795
820
  {
796
821
  id: "glm-4.6v",
797
822
  label: "GLM-4.6V",
798
823
  tiers: [
799
- { when: { inputLt: K32 }, input: 1, cache: 0.2, output: 3, note: "\u5165<32K" },
800
- { when: { inputGte: K32 }, input: 2, cache: 0.4, output: 6, note: "\u516532K\u2013128K\uFF08\u8D85\u4E0A\u754C\u5E76\u5165\u9AD8\u6863\uFF09" }
824
+ { when: { inputLt: K32 }, input: 1, cache: 0.2, output: 3, note: "in<32K" },
825
+ { when: { inputGte: K32 }, input: 2, cache: 0.4, output: 6, note: "in 32K\u2013128K (above the upper bound folds into the top tier)" }
801
826
  ]
802
827
  },
803
828
  {
804
829
  id: "glm-4.6v-flashx",
805
830
  label: "GLM-4.6V-FlashX",
806
831
  tiers: [
807
- { when: { inputLt: K32 }, input: 0.15, cache: 0.03, output: 1.5, note: "\u5165<32K" },
808
- { when: { inputGte: K32 }, input: 0.3, cache: 0.03, output: 3, note: "\u516532K\u2013128K\uFF08\u8D85\u4E0A\u754C\u5E76\u5165\u9AD8\u6863\uFF09" }
832
+ { when: { inputLt: K32 }, input: 0.15, cache: 0.03, output: 1.5, note: "in<32K" },
833
+ { when: { inputGte: K32 }, input: 0.3, cache: 0.03, output: 3, note: "in 32K\u2013128K (above the upper bound folds into the top tier)" }
809
834
  ]
810
835
  },
811
- { id: "glm-4.6v-flash", label: "GLM-4.6V-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, 0, 0, "\u514D\u8D39")] },
836
+ { id: "glm-4.6v-flash", label: "GLM-4.6V-Flash (free)", tiers: [flat(0, 0, 0, "free")] },
812
837
  {
813
838
  id: "glm-4.5v",
814
839
  label: "GLM-4.5V",
815
840
  tiers: [
816
- { when: { inputLt: K32 }, input: 2, cache: 0.4, output: 6, note: "\u5165<32K" },
817
- { when: { inputGte: K32 }, input: 4, cache: 0.8, output: 12, note: "\u516532K\u201364K\uFF08\u8D85\u4E0A\u754C\u5E76\u5165\u9AD8\u6863\uFF09" }
841
+ { when: { inputLt: K32 }, input: 2, cache: 0.4, output: 6, note: "in<32K" },
842
+ { when: { inputGte: K32 }, input: 4, cache: 0.8, output: 12, note: "in 32K\u201364K (above the upper bound folds into the top tier)" }
818
843
  ]
819
844
  },
820
845
  { id: "glm-4v-plus-0111", label: "GLM-4V-Plus-0111", tiers: [flat(4, 2, 4)] },
821
- { id: "glm-4v-plus", label: "GLM-4V-Plus\uFF08\u540C 0111 \u7248\u4EF7\uFF09", tiers: [flat(4, 2, 4)] },
822
- { id: "glm-4v-flash", label: "GLM-4V-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, null, 0, "\u514D\u8D39\xB7\u7F13\u5B58\u4E0D\u652F\u6301")] },
846
+ { id: "glm-4v-plus", label: "GLM-4V-Plus (same price as 0111)", tiers: [flat(4, 2, 4)] },
847
+ { id: "glm-4v-flash", label: "GLM-4V-Flash (free)", tiers: [flat(0, null, 0, "free \xB7 cache unsupported")] },
823
848
  { id: "glm-4.1v-thinking-flashx", label: "GLM-4.1V-Thinking-FlashX", tiers: [flat(2, null, 2)] },
824
- { id: "glm-4.1v-thinking-flash", label: "GLM-4.1V-Thinking-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, null, 0, "\u514D\u8D39\xB7\u7F13\u5B58\u4E0D\u652F\u6301")] },
825
- { id: "embedding-3", label: "Embedding-3", tiers: [flat(0.5, null, 0.5, "\u5355\u503C\u4EF7\u76EE\xB7input \u8BA1")] },
826
- { id: "embedding-2", label: "Embedding-2", tiers: [flat(0.5, null, 0.5, "\u5355\u503C\u4EF7\u76EE\xB7input \u8BA1")] },
827
- { id: "rerank", label: "Rerank", tiers: [flat(0.8, null, 0.8, "\u5355\u503C\u4EF7\u76EE")] },
828
- { id: "codegeex-4", label: "CodeGeeX-4", tiers: [flat(0.1, null, 0.1, "\u5355\u503C\u4EF7\u76EE")] }
849
+ { id: "glm-4.1v-thinking-flash", label: "GLM-4.1V-Thinking-Flash (free)", tiers: [flat(0, null, 0, "free \xB7 cache unsupported")] },
850
+ // ---- Embeddings / other (single-value prices are input-based; output billed at the same rate as a floor) ----
851
+ { id: "embedding-3", label: "Embedding-3", tiers: [flat(0.5, null, 0.5, "single-value \xB7 billed on input")] },
852
+ { id: "embedding-2", label: "Embedding-2", tiers: [flat(0.5, null, 0.5, "single-value \xB7 billed on input")] },
853
+ { id: "rerank", label: "Rerank", tiers: [flat(0.8, null, 0.8, "single-value")] },
854
+ { id: "codegeex-4", label: "CodeGeeX-4", tiers: [flat(0.1, null, 0.1, "single-value")] }
829
855
  ];
830
856
  var findPrice = (model) => {
831
857
  const m = model.trim().toLowerCase();
@@ -854,7 +880,7 @@ var priceUsage = (rows) => {
854
880
  const accs = /* @__PURE__ */ new Map();
855
881
  for (const r of rows) {
856
882
  if (r.inputTokens === 0 && r.outputTokens === 0) continue;
857
- const key = r.model === "" ? "\uFF08\u672A\u8BB0\u5F55\u6A21\u578B\uFF09" : r.model;
883
+ const key = r.model === "" ? "(no model recorded)" : r.model;
858
884
  let a = accs.get(key);
859
885
  if (a === void 0) {
860
886
  const p = findPrice(key);
@@ -930,9 +956,10 @@ CREATE TABLE IF NOT EXISTS prompt_usage (
930
956
  note TEXT NOT NULL DEFAULT '',
931
957
  model TEXT NOT NULL DEFAULT '',
932
958
  input_tokens INTEGER NOT NULL DEFAULT 0,
933
- -- cached_tokens\uFF1Az.ai \u53E3\u5F84\u7F13\u5B58\u547D\u4E2D\uFF08input \u5B50\u96C6\uFF0Cwf_66a9b632154d\uFF09
934
- --\uFF08\u5341\u4E09\u8DD1 R1 \u987A\u624B\u4FEE\uFF1A\u539F JS \u98CE\u683C // \u6CE8\u91CA\u5199\u5728 SQL \u4E32\u5185\uFF0CSQLite \u4E0D\u8BA4\uFF0C
935
- -- db.exec(MIGRATIONS) \u76F4\u63A5\u629B near "/": syntax error\uFF0C\u5168\u4ED3 store \u7EA7\u6D4B\u8BD5\u5C3D\u7EA2\uFF09
959
+ -- cached_tokens: z.ai-convention cache hits (subset of input, wf_66a9b632154d)
960
+ -- (fixed in passing during run-13 R1: the original JS-style // comments inside
961
+ -- the SQL string are not valid SQLite; db.exec(MIGRATIONS) threw near "/":
962
+ -- syntax error and every store-level test in the repo went red)
936
963
  cached_tokens INTEGER NOT NULL DEFAULT 0,
937
964
  output_tokens INTEGER NOT NULL DEFAULT 0,
938
965
  duration_ms INTEGER NOT NULL DEFAULT 0,
@@ -1239,9 +1266,13 @@ var parseAssistantLine = (line) => {
1239
1266
  }
1240
1267
  };
1241
1268
  export {
1269
+ AGENT_STEP_KINDS,
1242
1270
  BIGMODEL_PRICES,
1271
+ INSTRUCTABLE_STEP_KINDS,
1243
1272
  PRICING_RETRIEVED_AT,
1244
1273
  PRICING_SOURCE,
1274
+ STEP_KINDS,
1275
+ TERMINAL_WORKFLOW_STATUSES,
1245
1276
  appendDecision,
1246
1277
  appendExecution,
1247
1278
  appendReference,
@@ -553,9 +553,11 @@ var createLedgerStore = (dbPath, deps = {}) => {
553
553
  };
554
554
  },
555
555
  activeRunForSession: (session) => activeRunOf(session),
556
- /** 活跃去重:同 dedup_key 且工作流仍在途 → 跳过重复建流。
557
- * ⚠ ESCAPE '\' 必须与转义成对:message-id 几乎必含 `_`,漏写 ESCAPE 时
558
- * `\_` 成了"字面反斜杠+任意字符",模式永不匹配——去重整体失效(09-07 事故)。 */
556
+ /** Active dedup: same dedup_key and the workflow still in flight → skip
557
+ * creating a duplicate. ⚠ ESCAPE '\' must pair with the escaping: a
558
+ * message-id almost always contains `_`; without ESCAPE, `\_` becomes
559
+ * "literal backslash + any character", the pattern never matches — and
560
+ * dedup fails wholesale (09-07 incident). */
559
561
  hasActiveDedup(key) {
560
562
  const r = db.prepare(
561
563
  `SELECT 1 FROM workflows WHERE status IN (${sqlInList(DEDUP_WINDOW_STATUSES)})
@@ -563,8 +565,10 @@ var createLedgerStore = (dbPath, deps = {}) => {
563
565
  ).get(dedupPattern(key));
564
566
  return r !== void 0;
565
567
  },
566
- /** 已摄取去重(轮询层):同 dedup_key 存在任何非 rejected 工作流 → 这封
567
- * 邮件已被处理过(含 failed),轮询不再重复拉取。重试走步骤 retry,不走再摄取。 */
568
+ /** Ingested dedup (polling layer): any non-rejected workflow with the same
569
+ * dedup_key → this email has already been handled (failed included);
570
+ * polling won't fetch it again. Retries go through step retry, not
571
+ * re-ingestion. */
568
572
  hasSeenDedup(key) {
569
573
  const r = db.prepare(
570
574
  `SELECT 1 FROM workflows WHERE status != 'rejected'
@@ -572,11 +576,14 @@ var createLedgerStore = (dbPath, deps = {}) => {
572
576
  ).get(dedupPattern(key));
573
577
  return r !== void 0;
574
578
  },
575
- /** 自回环守卫查询(2026-09-20 断点十三):message_id 是否命中本引擎已
576
- * 发送记录——completed send 步的 output.message_id(email_sent 事件同源
577
- * 落账)。进件层据此丢弃投递副本回灌(引擎给轮询邮箱自己发信的 echo)。
578
- * LIKE 预筛 + 精确比对:JSON 编码取实际存储字节,%/_/\ 照 dedupPattern
579
- * 成对转义(message-id 几乎必含 `_`)。 */
579
+ /** Self-loop guard query (2026-09-20 breakpoint 13): does the message_id
580
+ * hit a record this engine already sent — the output.message_id of a
581
+ * completed send step (booked from the same source as email_sent events)?
582
+ * The intake layer uses this to discard delivery-copy feedback (the echo
583
+ * of the engine mailing the polling mailbox itself). LIKE prefilter +
584
+ * exact comparison: JSON-encode to the actually stored bytes; %/_/\ are
585
+ * escaped in pairs like dedupPattern (a message-id almost always contains
586
+ * `_`). */
580
587
  recordSentMessageId(messageId, meta) {
581
588
  if (messageId === "") return;
582
589
  db.prepare(
@@ -688,59 +695,61 @@ var PRICING_SOURCE = "https://docs.bigmodel.cn/cn/guide/start/pricing";
688
695
  var PRICING_RETRIEVED_AT = "2026-10-06";
689
696
  var K32 = 32e3;
690
697
  var K200 = 200;
691
- var flat = (input, cache, output, note = "\u7EDF\u4E00\u4EF7") => ({ when: {}, input, cache, output, note });
698
+ var flat = (input, cache, output, note = "flat rate") => ({ when: {}, input, cache, output, note });
692
699
  var BIGMODEL_PRICES = [
700
+ // ---- Flagship ----
693
701
  { id: "glm-5.3", label: "GLM-5.3", tiers: [flat(8, 2, 28)] },
694
702
  { id: "glm-5.3-flash", label: "GLM-5.3-Flash", tiers: [flat(0.8, 0.23, 2.8)] },
695
703
  { id: "glm-5.3-flashx", label: "GLM-5.3-FlashX", tiers: [flat(2, 0.57, 7)] },
704
+ // ---- Text ----
696
705
  { id: "glm-5.2", label: "GLM-5.2", tiers: [flat(8, 2, 28)] },
697
706
  {
698
707
  id: "glm-5.1",
699
708
  label: "GLM-5.1",
700
709
  tiers: [
701
- { when: { inputLt: K32 }, input: 6, cache: 1.3, output: 24, note: "\u5165<32K" },
702
- { when: { inputGte: K32 }, input: 8, cache: 2, output: 28, note: "\u5165\u226532K" }
710
+ { when: { inputLt: K32 }, input: 6, cache: 1.3, output: 24, note: "in<32K" },
711
+ { when: { inputGte: K32 }, input: 8, cache: 2, output: 28, note: "in>=32K" }
703
712
  ]
704
713
  },
705
714
  {
706
715
  id: "glm-5-turbo",
707
716
  label: "GLM-5-Turbo",
708
717
  tiers: [
709
- { when: { inputLt: K32 }, input: 5, cache: 1.2, output: 22, note: "\u5165<32K" },
710
- { when: { inputGte: K32 }, input: 7, cache: 1.8, output: 26, note: "\u5165\u226532K" }
718
+ { when: { inputLt: K32 }, input: 5, cache: 1.2, output: 22, note: "in<32K" },
719
+ { when: { inputGte: K32 }, input: 7, cache: 1.8, output: 26, note: "in>=32K" }
711
720
  ]
712
721
  },
713
722
  {
714
723
  id: "glm-5",
715
724
  label: "GLM-5",
716
725
  tiers: [
717
- { when: { inputLt: K32 }, input: 4, cache: 1, output: 18, note: "\u5165<32K" },
718
- { when: { inputGte: K32 }, input: 6, cache: 1.5, output: 22, note: "\u5165\u226532K" }
726
+ { when: { inputLt: K32 }, input: 4, cache: 1, output: 18, note: "in<32K" },
727
+ { when: { inputGte: K32 }, input: 6, cache: 1.5, output: 22, note: "in>=32K" }
719
728
  ]
720
729
  },
721
730
  {
722
731
  id: "glm-4.7",
723
732
  label: "GLM-4.7",
724
733
  tiers: [
725
- { when: { inputLt: K32, outputLt: K200 }, input: 2, cache: 0.4, output: 8, note: "\u5165<32K\xB7\u51FA<0.2K" },
726
- { when: { inputLt: K32, outputGte: K200 }, input: 3, cache: 0.6, output: 14, note: "\u5165<32K\xB7\u51FA\u22650.2K" },
727
- { when: { inputGte: K32 }, input: 4, cache: 0.8, output: 16, note: "\u516532K\u2013200K" }
734
+ { when: { inputLt: K32, outputLt: K200 }, input: 2, cache: 0.4, output: 8, note: "in<32K\xB7out<0.2K" },
735
+ { when: { inputLt: K32, outputGte: K200 }, input: 3, cache: 0.6, output: 14, note: "in<32K\xB7out>=0.2K" },
736
+ { when: { inputGte: K32 }, input: 4, cache: 0.8, output: 16, note: "in 32K\u2013200K" }
728
737
  ]
729
738
  },
730
739
  {
731
740
  id: "glm-4.5-air",
732
741
  label: "GLM-4.5-Air",
733
742
  tiers: [
734
- { when: { inputLt: K32, outputLt: K200 }, input: 0.8, cache: 0.16, output: 2, note: "\u5165<32K\xB7\u51FA<0.2K" },
735
- { when: { inputLt: K32, outputGte: K200 }, input: 0.8, cache: 0.16, output: 6, note: "\u5165<32K\xB7\u51FA\u22650.2K" },
736
- { when: { inputGte: K32 }, input: 1.2, cache: 0.24, output: 8, note: "\u516532K\u2013128K" }
743
+ { when: { inputLt: K32, outputLt: K200 }, input: 0.8, cache: 0.16, output: 2, note: "in<32K\xB7out<0.2K" },
744
+ { when: { inputLt: K32, outputGte: K200 }, input: 0.8, cache: 0.16, output: 6, note: "in<32K\xB7out>=0.2K" },
745
+ { when: { inputGte: K32 }, input: 1.2, cache: 0.24, output: 8, note: "in 32K\u2013128K" }
737
746
  ]
738
747
  },
739
748
  { id: "glm-4.7-flashx", label: "GLM-4.7-FlashX", tiers: [flat(0.5, 0.1, 3)] },
740
- { id: "glm-4.7-flash", label: "GLM-4.7-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, 0, 0, "\u514D\u8D39")] },
749
+ { id: "glm-4.7-flash", label: "GLM-4.7-Flash (free)", tiers: [flat(0, 0, 0, "free")] },
741
750
  { id: "glm-4-plus", label: "GLM-4-Plus", tiers: [flat(5, 2.5, 5)] },
742
751
  { id: "glm-4-air-250414", label: "GLM-4-Air-250414", tiers: [flat(0.5, 0.25, 0.5)] },
743
- { id: "glm-4-air", label: "GLM-4-Air\uFF08\u540C 250414 \u7248\u4EF7\uFF09", tiers: [flat(0.5, 0.25, 0.5)] },
752
+ { id: "glm-4-air", label: "GLM-4-Air (same price as 250414)", tiers: [flat(0.5, 0.25, 0.5)] },
744
753
  { id: "glm-4-airx", label: "GLM-4-AirX", tiers: [flat(10, null, 10)] },
745
754
  { id: "glm-4-long", label: "GLM-4-Long", tiers: [flat(1, 0.5, 1)] },
746
755
  { id: "glm-4-assistant", label: "GLM-4-Assistant", tiers: [flat(5, null, 5)] },
@@ -748,53 +757,55 @@ var BIGMODEL_PRICES = [
748
757
  { id: "glm-z1-airx", label: "GLM-Z1-AirX", tiers: [flat(5, null, 5)] },
749
758
  { id: "glm-z1-flashx", label: "GLM-Z1-FlashX", tiers: [flat(0.1, null, 0.1)] },
750
759
  { id: "glm-4-flashx-250414", label: "GLM-4-FlashX-250414", tiers: [flat(0.1, 0.05, 0.1)] },
751
- { id: "glm-4-flashx", label: "GLM-4-FlashX\uFF08\u540C 250414 \u7248\u4EF7\uFF09", tiers: [flat(0.1, 0.05, 0.1)] },
752
- { id: "glm-4-flash-250414", label: "GLM-4-Flash-250414\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, null, 0, "\u514D\u8D39\xB7\u7F13\u5B58\u4E0D\u652F\u6301")] },
753
- { id: "glm-4-flash", label: "GLM-4-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, null, 0, "\u514D\u8D39\xB7\u7F13\u5B58\u4E0D\u652F\u6301")] },
754
- { id: "glm-z1-flash", label: "GLM-Z1-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, null, 0, "\u514D\u8D39\xB7\u7F13\u5B58\u4E0D\u652F\u6301")] },
760
+ { id: "glm-4-flashx", label: "GLM-4-FlashX (same price as 250414)", tiers: [flat(0.1, 0.05, 0.1)] },
761
+ { id: "glm-4-flash-250414", label: "GLM-4-Flash-250414 (free)", tiers: [flat(0, null, 0, "free \xB7 cache unsupported")] },
762
+ { id: "glm-4-flash", label: "GLM-4-Flash (free)", tiers: [flat(0, null, 0, "free \xB7 cache unsupported")] },
763
+ { id: "glm-z1-flash", label: "GLM-Z1-Flash (free)", tiers: [flat(0, null, 0, "free \xB7 cache unsupported")] },
764
+ // ---- Vision ----
755
765
  { id: "glm-ocr", label: "GLM-OCR", tiers: [flat(0.2, null, 0.2)] },
756
766
  {
757
767
  id: "glm-5v-turbo",
758
768
  label: "GLM-5V-Turbo",
759
769
  tiers: [
760
- { when: { inputLt: K32 }, input: 5, cache: 1.2, output: 22, note: "\u5165<32K" },
761
- { when: { inputGte: K32 }, input: 7, cache: 1.8, output: 26, note: "\u5165\u226532K" }
770
+ { when: { inputLt: K32 }, input: 5, cache: 1.2, output: 22, note: "in<32K" },
771
+ { when: { inputGte: K32 }, input: 7, cache: 1.8, output: 26, note: "in>=32K" }
762
772
  ]
763
773
  },
764
774
  {
765
775
  id: "glm-4.6v",
766
776
  label: "GLM-4.6V",
767
777
  tiers: [
768
- { when: { inputLt: K32 }, input: 1, cache: 0.2, output: 3, note: "\u5165<32K" },
769
- { when: { inputGte: K32 }, input: 2, cache: 0.4, output: 6, note: "\u516532K\u2013128K\uFF08\u8D85\u4E0A\u754C\u5E76\u5165\u9AD8\u6863\uFF09" }
778
+ { when: { inputLt: K32 }, input: 1, cache: 0.2, output: 3, note: "in<32K" },
779
+ { when: { inputGte: K32 }, input: 2, cache: 0.4, output: 6, note: "in 32K\u2013128K (above the upper bound folds into the top tier)" }
770
780
  ]
771
781
  },
772
782
  {
773
783
  id: "glm-4.6v-flashx",
774
784
  label: "GLM-4.6V-FlashX",
775
785
  tiers: [
776
- { when: { inputLt: K32 }, input: 0.15, cache: 0.03, output: 1.5, note: "\u5165<32K" },
777
- { when: { inputGte: K32 }, input: 0.3, cache: 0.03, output: 3, note: "\u516532K\u2013128K\uFF08\u8D85\u4E0A\u754C\u5E76\u5165\u9AD8\u6863\uFF09" }
786
+ { when: { inputLt: K32 }, input: 0.15, cache: 0.03, output: 1.5, note: "in<32K" },
787
+ { when: { inputGte: K32 }, input: 0.3, cache: 0.03, output: 3, note: "in 32K\u2013128K (above the upper bound folds into the top tier)" }
778
788
  ]
779
789
  },
780
- { id: "glm-4.6v-flash", label: "GLM-4.6V-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, 0, 0, "\u514D\u8D39")] },
790
+ { id: "glm-4.6v-flash", label: "GLM-4.6V-Flash (free)", tiers: [flat(0, 0, 0, "free")] },
781
791
  {
782
792
  id: "glm-4.5v",
783
793
  label: "GLM-4.5V",
784
794
  tiers: [
785
- { when: { inputLt: K32 }, input: 2, cache: 0.4, output: 6, note: "\u5165<32K" },
786
- { when: { inputGte: K32 }, input: 4, cache: 0.8, output: 12, note: "\u516532K\u201364K\uFF08\u8D85\u4E0A\u754C\u5E76\u5165\u9AD8\u6863\uFF09" }
795
+ { when: { inputLt: K32 }, input: 2, cache: 0.4, output: 6, note: "in<32K" },
796
+ { when: { inputGte: K32 }, input: 4, cache: 0.8, output: 12, note: "in 32K\u201364K (above the upper bound folds into the top tier)" }
787
797
  ]
788
798
  },
789
799
  { id: "glm-4v-plus-0111", label: "GLM-4V-Plus-0111", tiers: [flat(4, 2, 4)] },
790
- { id: "glm-4v-plus", label: "GLM-4V-Plus\uFF08\u540C 0111 \u7248\u4EF7\uFF09", tiers: [flat(4, 2, 4)] },
791
- { id: "glm-4v-flash", label: "GLM-4V-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, null, 0, "\u514D\u8D39\xB7\u7F13\u5B58\u4E0D\u652F\u6301")] },
800
+ { id: "glm-4v-plus", label: "GLM-4V-Plus (same price as 0111)", tiers: [flat(4, 2, 4)] },
801
+ { id: "glm-4v-flash", label: "GLM-4V-Flash (free)", tiers: [flat(0, null, 0, "free \xB7 cache unsupported")] },
792
802
  { id: "glm-4.1v-thinking-flashx", label: "GLM-4.1V-Thinking-FlashX", tiers: [flat(2, null, 2)] },
793
- { id: "glm-4.1v-thinking-flash", label: "GLM-4.1V-Thinking-Flash\uFF08\u514D\u8D39\uFF09", tiers: [flat(0, null, 0, "\u514D\u8D39\xB7\u7F13\u5B58\u4E0D\u652F\u6301")] },
794
- { id: "embedding-3", label: "Embedding-3", tiers: [flat(0.5, null, 0.5, "\u5355\u503C\u4EF7\u76EE\xB7input \u8BA1")] },
795
- { id: "embedding-2", label: "Embedding-2", tiers: [flat(0.5, null, 0.5, "\u5355\u503C\u4EF7\u76EE\xB7input \u8BA1")] },
796
- { id: "rerank", label: "Rerank", tiers: [flat(0.8, null, 0.8, "\u5355\u503C\u4EF7\u76EE")] },
797
- { id: "codegeex-4", label: "CodeGeeX-4", tiers: [flat(0.1, null, 0.1, "\u5355\u503C\u4EF7\u76EE")] }
803
+ { id: "glm-4.1v-thinking-flash", label: "GLM-4.1V-Thinking-Flash (free)", tiers: [flat(0, null, 0, "free \xB7 cache unsupported")] },
804
+ // ---- Embeddings / other (single-value prices are input-based; output billed at the same rate as a floor) ----
805
+ { id: "embedding-3", label: "Embedding-3", tiers: [flat(0.5, null, 0.5, "single-value \xB7 billed on input")] },
806
+ { id: "embedding-2", label: "Embedding-2", tiers: [flat(0.5, null, 0.5, "single-value \xB7 billed on input")] },
807
+ { id: "rerank", label: "Rerank", tiers: [flat(0.8, null, 0.8, "single-value")] },
808
+ { id: "codegeex-4", label: "CodeGeeX-4", tiers: [flat(0.1, null, 0.1, "single-value")] }
798
809
  ];
799
810
  var findPrice = (model) => {
800
811
  const m = model.trim().toLowerCase();
@@ -823,7 +834,7 @@ var priceUsage = (rows) => {
823
834
  const accs = /* @__PURE__ */ new Map();
824
835
  for (const r of rows) {
825
836
  if (r.inputTokens === 0 && r.outputTokens === 0) continue;
826
- const key = r.model === "" ? "\uFF08\u672A\u8BB0\u5F55\u6A21\u578B\uFF09" : r.model;
837
+ const key = r.model === "" ? "(no model recorded)" : r.model;
827
838
  let a = accs.get(key);
828
839
  if (a === void 0) {
829
840
  const p = findPrice(key);
@@ -899,9 +910,10 @@ CREATE TABLE IF NOT EXISTS prompt_usage (
899
910
  note TEXT NOT NULL DEFAULT '',
900
911
  model TEXT NOT NULL DEFAULT '',
901
912
  input_tokens INTEGER NOT NULL DEFAULT 0,
902
- -- cached_tokens\uFF1Az.ai \u53E3\u5F84\u7F13\u5B58\u547D\u4E2D\uFF08input \u5B50\u96C6\uFF0Cwf_66a9b632154d\uFF09
903
- --\uFF08\u5341\u4E09\u8DD1 R1 \u987A\u624B\u4FEE\uFF1A\u539F JS \u98CE\u683C // \u6CE8\u91CA\u5199\u5728 SQL \u4E32\u5185\uFF0CSQLite \u4E0D\u8BA4\uFF0C
904
- -- db.exec(MIGRATIONS) \u76F4\u63A5\u629B near "/": syntax error\uFF0C\u5168\u4ED3 store \u7EA7\u6D4B\u8BD5\u5C3D\u7EA2\uFF09
913
+ -- cached_tokens: z.ai-convention cache hits (subset of input, wf_66a9b632154d)
914
+ -- (fixed in passing during run-13 R1: the original JS-style // comments inside
915
+ -- the SQL string are not valid SQLite; db.exec(MIGRATIONS) threw near "/":
916
+ -- syntax error and every store-level test in the repo went red)
905
917
  cached_tokens INTEGER NOT NULL DEFAULT 0,
906
918
  output_tokens INTEGER NOT NULL DEFAULT 0,
907
919
  duration_ms INTEGER NOT NULL DEFAULT 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juli-os/ledger",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "juli-os L1 layer: the ledger of record for agent work — workflows, steps, case files, and token usage in one zero-dependency SQLite layer.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -30,13 +30,17 @@
30
30
  "prepublishOnly": "npm run build"
31
31
  },
32
32
  "devDependencies": {
33
+ "@types/node": "^22.0.0",
33
34
  "esbuild": "^0.24.0",
34
- "typescript": "^5.6.0",
35
- "@types/node": "^22.0.0"
35
+ "typescript": "^5.6.0"
36
36
  },
37
37
  "publishConfig": {
38
38
  "registry": "https://registry.npmjs.org/",
39
39
  "access": "public"
40
40
  },
41
- "license": "Apache-2.0"
42
- }
41
+ "license": "Apache-2.0",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/juli-os/ledger.git"
45
+ }
46
+ }