nodal-agents 0.9.1 → 0.9.2

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 (190) hide show
  1. package/cli.js +404 -47
  2. package/docs-index.json +12 -12
  3. package/migrations/0122_entities_drop_memory_curation_enabled.sql +17 -0
  4. package/migrations/meta/_journal.json +7 -0
  5. package/package.json +1 -1
  6. package/runner.js +459 -98
  7. package/web/.next/BUILD_ID +1 -1
  8. package/web/.next/build-manifest.json +2 -2
  9. package/web/.next/prerender-manifest.json +3 -3
  10. package/web/.next/server/app/(dashboard)/agents/[id]/channels/page.js +1 -1
  11. package/web/.next/server/app/(dashboard)/agents/[id]/channels/page_client-reference-manifest.js +1 -1
  12. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js +2 -2
  13. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page_client-reference-manifest.js +1 -1
  14. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page.js +1 -1
  15. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page_client-reference-manifest.js +1 -1
  16. package/web/.next/server/app/(dashboard)/agents/page.js +1 -1
  17. package/web/.next/server/app/(dashboard)/agents/page_client-reference-manifest.js +1 -1
  18. package/web/.next/server/app/(dashboard)/approvals/page.js +1 -1
  19. package/web/.next/server/app/(dashboard)/approvals/page_client-reference-manifest.js +1 -1
  20. package/web/.next/server/app/(dashboard)/automations/[id]/page.js +1 -1
  21. package/web/.next/server/app/(dashboard)/automations/[id]/page_client-reference-manifest.js +1 -1
  22. package/web/.next/server/app/(dashboard)/automations/page.js +1 -1
  23. package/web/.next/server/app/(dashboard)/automations/page_client-reference-manifest.js +1 -1
  24. package/web/.next/server/app/(dashboard)/chat/[id]/page.js +1 -1
  25. package/web/.next/server/app/(dashboard)/chat/[id]/page_client-reference-manifest.js +1 -1
  26. package/web/.next/server/app/(dashboard)/chat/page.js +1 -1
  27. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  28. package/web/.next/server/app/(dashboard)/code/[id]/page.js +1 -1
  29. package/web/.next/server/app/(dashboard)/code/[id]/page_client-reference-manifest.js +1 -1
  30. package/web/.next/server/app/(dashboard)/code/page.js +1 -1
  31. package/web/.next/server/app/(dashboard)/code/page_client-reference-manifest.js +1 -1
  32. package/web/.next/server/app/(dashboard)/connectors/page.js +1 -1
  33. package/web/.next/server/app/(dashboard)/connectors/page_client-reference-manifest.js +1 -1
  34. package/web/.next/server/app/(dashboard)/credentials/page.js +1 -1
  35. package/web/.next/server/app/(dashboard)/credentials/page_client-reference-manifest.js +1 -1
  36. package/web/.next/server/app/(dashboard)/dashboard/page.js +1 -1
  37. package/web/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  38. package/web/.next/server/app/(dashboard)/jobs/[id]/page.js +1 -1
  39. package/web/.next/server/app/(dashboard)/jobs/[id]/page_client-reference-manifest.js +1 -1
  40. package/web/.next/server/app/(dashboard)/jobs/page.js +1 -1
  41. package/web/.next/server/app/(dashboard)/jobs/page_client-reference-manifest.js +1 -1
  42. package/web/.next/server/app/(dashboard)/learned-skills/page.js +1 -1
  43. package/web/.next/server/app/(dashboard)/learned-skills/page_client-reference-manifest.js +1 -1
  44. package/web/.next/server/app/(dashboard)/llm-providers/page.js +1 -1
  45. package/web/.next/server/app/(dashboard)/llm-providers/page_client-reference-manifest.js +1 -1
  46. package/web/.next/server/app/(dashboard)/logs/page.js +1 -1
  47. package/web/.next/server/app/(dashboard)/logs/page_client-reference-manifest.js +1 -1
  48. package/web/.next/server/app/(dashboard)/mcp/page.js +1 -1
  49. package/web/.next/server/app/(dashboard)/mcp/page_client-reference-manifest.js +1 -1
  50. package/web/.next/server/app/(dashboard)/memories/page.js +1 -1
  51. package/web/.next/server/app/(dashboard)/memories/page_client-reference-manifest.js +1 -1
  52. package/web/.next/server/app/(dashboard)/page.js +1 -1
  53. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  54. package/web/.next/server/app/(dashboard)/scheduled/[id]/page.js +1 -1
  55. package/web/.next/server/app/(dashboard)/scheduled/[id]/page_client-reference-manifest.js +1 -1
  56. package/web/.next/server/app/(dashboard)/scheduled/page.js +1 -1
  57. package/web/.next/server/app/(dashboard)/scheduled/page_client-reference-manifest.js +1 -1
  58. package/web/.next/server/app/(dashboard)/settings/page.js +1 -1
  59. package/web/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  60. package/web/.next/server/app/(dashboard)/settings/root-context/page.js +1 -1
  61. package/web/.next/server/app/(dashboard)/settings/root-context/page_client-reference-manifest.js +1 -1
  62. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js +1 -1
  63. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/(dashboard)/skills/new/page.js +1 -1
  65. package/web/.next/server/app/(dashboard)/skills/new/page_client-reference-manifest.js +1 -1
  66. package/web/.next/server/app/(dashboard)/skills/page.js +1 -1
  67. package/web/.next/server/app/(dashboard)/skills/page_client-reference-manifest.js +1 -1
  68. package/web/.next/server/app/(dashboard)/spaces/[id]/files/page.js +1 -1
  69. package/web/.next/server/app/(dashboard)/spaces/[id]/files/page_client-reference-manifest.js +1 -1
  70. package/web/.next/server/app/(dashboard)/spaces/[id]/page.js +1 -1
  71. package/web/.next/server/app/(dashboard)/spaces/[id]/page_client-reference-manifest.js +1 -1
  72. package/web/.next/server/app/(dashboard)/spaces/page.js +1 -1
  73. package/web/.next/server/app/(dashboard)/spaces/page_client-reference-manifest.js +1 -1
  74. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  75. package/web/.next/server/app/_global-error.html +1 -1
  76. package/web/.next/server/app/_global-error.rsc +2 -2
  77. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  78. package/web/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +2 -2
  79. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  80. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  81. package/web/.next/server/app/_not-found.html +1 -1
  82. package/web/.next/server/app/_not-found.rsc +2 -2
  83. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  84. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  85. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  86. package/web/.next/server/app/login/page.js +1 -1
  87. package/web/.next/server/app/login/page_client-reference-manifest.js +1 -1
  88. package/web/.next/server/app/onboarding/page.js +2 -2
  89. package/web/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  90. package/web/.next/server/chunks/1960.js +1 -0
  91. package/web/.next/server/chunks/{4208.js → 2096.js} +1 -1
  92. package/web/.next/server/chunks/292.js +1 -0
  93. package/web/.next/server/chunks/3675.js +1 -1
  94. package/web/.next/server/chunks/409.js +1 -1
  95. package/web/.next/server/chunks/42.js +2 -2
  96. package/web/.next/server/chunks/494.js +1 -1
  97. package/web/.next/server/chunks/5547.js +1 -0
  98. package/web/.next/server/chunks/570.js +1 -0
  99. package/web/.next/server/chunks/5804.js +1 -1
  100. package/web/.next/server/chunks/5974.js +1 -0
  101. package/web/.next/server/chunks/6106.js +1 -0
  102. package/web/.next/server/chunks/692.js +6 -6
  103. package/web/.next/server/chunks/7134.js +3 -3
  104. package/web/.next/server/chunks/7431.js +1 -0
  105. package/web/.next/server/chunks/7533.js +1 -0
  106. package/web/.next/server/chunks/7915.js +1 -1
  107. package/web/.next/server/chunks/8022.js +1 -1
  108. package/web/.next/server/chunks/8536.js +3 -0
  109. package/web/.next/server/chunks/8974.js +13 -13
  110. package/web/.next/server/chunks/9200.js +1 -0
  111. package/web/.next/server/middleware-build-manifest.js +1 -1
  112. package/web/.next/server/middleware.js +2 -2
  113. package/web/.next/server/pages/404.html +1 -1
  114. package/web/.next/server/pages/500.html +1 -1
  115. package/web/.next/server/server-reference-manifest.js +1 -1
  116. package/web/.next/server/server-reference-manifest.json +1 -1
  117. package/web/.next/static/chunks/1054-08930540869affcc.js +1 -0
  118. package/web/.next/static/chunks/1091-6d0af9f18ddf99f6.js +1 -0
  119. package/web/.next/static/chunks/{1332-0e4a72eac08cebb9.js → 1332-c8bed6b750598652.js} +1 -1
  120. package/web/.next/static/chunks/{3051-466a9da3e351fd0d.js → 3051-26ddd67461f743c4.js} +1 -1
  121. package/web/.next/static/chunks/3159-f25525771781f5aa.js +1 -0
  122. package/web/.next/static/chunks/3775-3a5a749d63c785a1.js +3 -0
  123. package/web/.next/static/chunks/390-d6132d3a117487df.js +1 -0
  124. package/web/.next/static/chunks/4020-9778230f3cc2164a.js +1 -0
  125. package/web/.next/static/chunks/{5034-11fd1b56b43dc6e5.js → 5034-fc9997ff33a114aa.js} +1 -1
  126. package/web/.next/static/chunks/7879-67ac5a52d74c20d2.js +1 -0
  127. package/web/.next/static/chunks/9643-e9c8a744dd98813d.js +1 -0
  128. package/web/.next/static/chunks/9952-992cabfb077d287c.js +1 -0
  129. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-5ca9c1eef4d0f837.js +6 -0
  130. package/web/.next/static/chunks/app/(dashboard)/agents/page-5ffa4a2468c1f95a.js +1 -0
  131. package/web/.next/static/chunks/app/(dashboard)/approvals/{page-3de0cc34d6dbeaf5.js → page-cd46d5e439a20d3e.js} +1 -1
  132. package/web/.next/static/chunks/app/(dashboard)/automations/[id]/{page-bebc71312e736828.js → page-9ef1d76121b6030d.js} +1 -1
  133. package/web/.next/static/chunks/app/(dashboard)/automations/page-46eeaa40df9e58f8.js +1 -0
  134. package/web/.next/static/chunks/app/(dashboard)/chat/[id]/{page-faa53d8decd24a6a.js → page-25e095bf0cdd1c40.js} +1 -1
  135. package/web/.next/static/chunks/app/(dashboard)/chat/page-e2df1a328e18da7a.js +1 -0
  136. package/web/.next/static/chunks/app/(dashboard)/code/[id]/{page-52a3e2140bd0d64a.js → page-f5f7624cfbb32ee2.js} +1 -1
  137. package/web/.next/static/chunks/app/(dashboard)/connectors/page-2ecbfc5836577888.js +1 -0
  138. package/web/.next/static/chunks/app/(dashboard)/dashboard/{page-5002d088b635d8f9.js → page-7473d1190864cbd4.js} +1 -1
  139. package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/{page-5573e316921e5315.js → page-47e177ab46926fd7.js} +1 -1
  140. package/web/.next/static/chunks/app/(dashboard)/layout-0b429859260736b2.js +1 -0
  141. package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-596d973a31e774db.js +1 -0
  142. package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-ba1968c9430c4dd4.js +1 -0
  143. package/web/.next/static/chunks/app/(dashboard)/logs/page-f74da6f66116c7e7.js +1 -0
  144. package/web/.next/static/chunks/app/(dashboard)/mcp/page-07bdc6780b13cfca.js +1 -0
  145. package/web/.next/static/chunks/app/(dashboard)/memories/page-593161bc7c2a25d7.js +1 -0
  146. package/web/.next/static/chunks/app/(dashboard)/page-889d6e89a8f679f8.js +1 -0
  147. package/web/.next/static/chunks/app/(dashboard)/scheduled/[id]/{page-5573e316921e5315.js → page-47e177ab46926fd7.js} +1 -1
  148. package/web/.next/static/chunks/app/(dashboard)/settings/page-1b40e127c38affda.js +1 -0
  149. package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-6b7e1cffcad40a6a.js +1 -0
  150. package/web/.next/static/chunks/app/(dashboard)/skills/page-3ad87d1a3fbb4f05.js +1 -0
  151. package/web/.next/static/chunks/app/(dashboard)/spaces/page-9dbb35822503481b.js +1 -0
  152. package/web/.next/static/chunks/app/login/{page-031e915b40cb5be6.js → page-5357f030e5018563.js} +1 -1
  153. package/web/.next/static/chunks/app/onboarding/{page-06209a6e3a31fb73.js → page-9b6955cdd3033584.js} +2 -2
  154. package/web/.next/server/chunks/3650.js +0 -1
  155. package/web/.next/server/chunks/385.js +0 -1
  156. package/web/.next/server/chunks/4194.js +0 -1
  157. package/web/.next/server/chunks/616.js +0 -1
  158. package/web/.next/server/chunks/6724.js +0 -1
  159. package/web/.next/server/chunks/7190.js +0 -1
  160. package/web/.next/server/chunks/7273.js +0 -3
  161. package/web/.next/server/chunks/7416.js +0 -1
  162. package/web/.next/server/chunks/7975.js +0 -1
  163. package/web/.next/server/chunks/8153.js +0 -1
  164. package/web/.next/static/chunks/1054-5f8b510bbf6ff3e9.js +0 -1
  165. package/web/.next/static/chunks/1091-8f1b68252431e271.js +0 -1
  166. package/web/.next/static/chunks/3388-530c6d429c484862.js +0 -3
  167. package/web/.next/static/chunks/3815-aa88c216677b6c3f.js +0 -1
  168. package/web/.next/static/chunks/4020-dcde3e62f67473f3.js +0 -1
  169. package/web/.next/static/chunks/6883-73dc26cf02070115.js +0 -1
  170. package/web/.next/static/chunks/7039-7a3b6bdbfda78038.js +0 -1
  171. package/web/.next/static/chunks/9643-b0b049bb41a7cba4.js +0 -1
  172. package/web/.next/static/chunks/9901-24977d0da68dcf77.js +0 -1
  173. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-4594e5fc99cc04ed.js +0 -6
  174. package/web/.next/static/chunks/app/(dashboard)/agents/page-a26d15238b4c55d3.js +0 -1
  175. package/web/.next/static/chunks/app/(dashboard)/automations/page-04c38b0a633b5c94.js +0 -1
  176. package/web/.next/static/chunks/app/(dashboard)/chat/page-c45d840d7ca4faa7.js +0 -1
  177. package/web/.next/static/chunks/app/(dashboard)/connectors/page-081ca4b9bbeb2fcb.js +0 -1
  178. package/web/.next/static/chunks/app/(dashboard)/layout-b542af6fe3f7621e.js +0 -1
  179. package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-950bf08720e4b3aa.js +0 -1
  180. package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-8ada985ee9578d2f.js +0 -1
  181. package/web/.next/static/chunks/app/(dashboard)/logs/page-a2cf705f0ddb7329.js +0 -1
  182. package/web/.next/static/chunks/app/(dashboard)/mcp/page-17498336e813cd6c.js +0 -1
  183. package/web/.next/static/chunks/app/(dashboard)/memories/page-5c8fc395823f4823.js +0 -1
  184. package/web/.next/static/chunks/app/(dashboard)/page-48d1d32604854d18.js +0 -1
  185. package/web/.next/static/chunks/app/(dashboard)/settings/page-f4d50d3900c7387a.js +0 -1
  186. package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-edace0d3a7f0134a.js +0 -1
  187. package/web/.next/static/chunks/app/(dashboard)/skills/page-7dc32162faa0e762.js +0 -1
  188. package/web/.next/static/chunks/app/(dashboard)/spaces/page-b516d5b0664dffee.js +0 -1
  189. /package/web/.next/static/{bG6cdQqQw9o06-WZ6DrN2 → x5fvzE6AeZGASlemQTLwd}/_buildManifest.js +0 -0
  190. /package/web/.next/static/{bG6cdQqQw9o06-WZ6DrN2 → x5fvzE6AeZGASlemQTLwd}/_ssgManifest.js +0 -0
package/cli.js CHANGED
@@ -11425,8 +11425,8 @@ function postmasterHoldsDataDir(pid, dataDir) {
11425
11425
  function processStartedAtMs(pid) {
11426
11426
  if (process.platform !== "linux") return null;
11427
11427
  try {
11428
- const stat2 = readFileSync4(`/proc/${pid}/stat`, "utf-8");
11429
- const after = stat2.slice(stat2.lastIndexOf(")") + 2).split(" ");
11428
+ const stat3 = readFileSync4(`/proc/${pid}/stat`, "utf-8");
11429
+ const after = stat3.slice(stat3.lastIndexOf(")") + 2).split(" ");
11430
11430
  const ticksSinceBoot = Number.parseInt(after[19] ?? "", 10);
11431
11431
  if (!Number.isFinite(ticksSinceBoot)) return null;
11432
11432
  const uptimeSeconds = Number.parseFloat(
@@ -13704,17 +13704,6 @@ var init_model_catalog = __esm({
13704
13704
  cacheWritePerMillionUsd: 6.25
13705
13705
  }
13706
13706
  },
13707
- {
13708
- modelId: "anthropic/claude-opus-5-fast",
13709
- label: "Claude Opus 5 (fast)",
13710
- capabilities: {
13711
- tools: true,
13712
- forcedToolChoice: true,
13713
- reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13714
- },
13715
- contextWindow: 1e6,
13716
- pricing: { inputPerMillionUsd: 10, outputPerMillionUsd: 50 }
13717
- },
13718
13707
  {
13719
13708
  modelId: "anthropic/claude-sonnet-5",
13720
13709
  label: "Claude Sonnet 5",
@@ -13747,6 +13736,34 @@ var init_model_catalog = __esm({
13747
13736
  cacheWritePerMillionUsd: 12.5
13748
13737
  }
13749
13738
  },
13739
+ {
13740
+ // The newest of the family (2026-09-01), read off /api/v1/models on
13741
+ // 2026-09-22: same window, prices and modalities as Fable 5 except the
13742
+ // cache READ price, four times lower (0.25 vs 1). Its `reasoning` object
13743
+ // says mandatory:true with efforts max/xhigh/high/medium/low, so Off is
13744
+ // hidden here — the Fable 5 entry above predates that object and still
13745
+ // offers it (#417). No always-on `reasoning` flag, as for every Claude
13746
+ // route in this file: the flag would flip openrouter.ts's default
13747
+ // injection, and a mandatory model thinks anyway.
13748
+ modelId: "anthropic/claude-fable-5.1",
13749
+ label: "Claude Fable 5.1",
13750
+ capabilities: {
13751
+ tools: true,
13752
+ forcedToolChoice: true,
13753
+ reasoningControl: {
13754
+ kind: "effort",
13755
+ levels: ["low", "medium", "high", "max"],
13756
+ mandatory: true
13757
+ }
13758
+ },
13759
+ contextWindow: 1e6,
13760
+ pricing: {
13761
+ inputPerMillionUsd: 10,
13762
+ outputPerMillionUsd: 50,
13763
+ cacheReadPerMillionUsd: 0.25,
13764
+ cacheWritePerMillionUsd: 12.5
13765
+ }
13766
+ },
13750
13767
  // ─── OpenAI ───────────────────────────────────────────────────────────────
13751
13768
  // OpenAI was absent from the OpenRouter list entirely — not a curation
13752
13769
  // choice, a gap: the native `openai` provider carried gpt-5 while anyone
@@ -13799,6 +13816,107 @@ var init_model_catalog = __esm({
13799
13816
  cacheWritePerMillionUsd: 2.5
13800
13817
  }
13801
13818
  },
13819
+ // The rest of the 5.6 series and GPT-6 Astra, read off OpenRouter's
13820
+ // /api/v1/models on 2026-09-22 — including its `reasoning` object
13821
+ // ({mandatory, default_enabled, supported_efforts}), which is what the
13822
+ // control below follows. Sol, Sol Pro and Terra: mandatory:false,
13823
+ // supported_efforts max/xhigh/high/medium/low/none → the Luna posture
13824
+ // (four levels, Off offered). Astra and Astra Pro: mandatory:true, no
13825
+ // 'none' → the same four levels with Off hidden. Prices are the
13826
+ // STANDARD OpenAI service tier, the one the list endpoint reports; the
13827
+ // endpoints list also carries a flex tier at half and a priority tier at
13828
+ // double, and an override above 272K prompt tokens — the flat catalogue
13829
+ // price is the standard tier, as for Luna and Terra Pro above. Upstream
13830
+ // copy: Sol is the 5.6 flagship, Terra the balanced tier between Sol and
13831
+ // Luna, Astra "OpenAI's flagship model for demanding end-to-end work".
13832
+ {
13833
+ modelId: "openai/gpt-5.6-terra",
13834
+ label: "GPT-5.6 Terra",
13835
+ capabilities: {
13836
+ tools: true,
13837
+ forcedToolChoice: true,
13838
+ reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13839
+ },
13840
+ contextWindow: 105e4,
13841
+ pricing: {
13842
+ inputPerMillionUsd: 2,
13843
+ outputPerMillionUsd: 12,
13844
+ cacheReadPerMillionUsd: 0.2,
13845
+ cacheWritePerMillionUsd: 2.5
13846
+ }
13847
+ },
13848
+ {
13849
+ modelId: "openai/gpt-5.6-sol",
13850
+ label: "GPT-5.6 Sol",
13851
+ capabilities: {
13852
+ tools: true,
13853
+ forcedToolChoice: true,
13854
+ reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13855
+ },
13856
+ contextWindow: 105e4,
13857
+ pricing: {
13858
+ inputPerMillionUsd: 2,
13859
+ outputPerMillionUsd: 10,
13860
+ cacheReadPerMillionUsd: 0.2,
13861
+ cacheWritePerMillionUsd: 2.5
13862
+ }
13863
+ },
13864
+ {
13865
+ modelId: "openai/gpt-5.6-sol-pro",
13866
+ label: "GPT-5.6 Sol Pro",
13867
+ capabilities: {
13868
+ tools: true,
13869
+ forcedToolChoice: true,
13870
+ reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13871
+ },
13872
+ contextWindow: 105e4,
13873
+ pricing: {
13874
+ inputPerMillionUsd: 2,
13875
+ outputPerMillionUsd: 10,
13876
+ cacheReadPerMillionUsd: 0.2,
13877
+ cacheWritePerMillionUsd: 2.5
13878
+ }
13879
+ },
13880
+ {
13881
+ modelId: "openai/gpt-6-astra",
13882
+ label: "GPT-6 Astra",
13883
+ capabilities: {
13884
+ tools: true,
13885
+ forcedToolChoice: true,
13886
+ reasoningControl: {
13887
+ kind: "effort",
13888
+ levels: ["low", "medium", "high", "max"],
13889
+ mandatory: true
13890
+ }
13891
+ },
13892
+ contextWindow: 105e4,
13893
+ pricing: {
13894
+ inputPerMillionUsd: 10,
13895
+ outputPerMillionUsd: 50,
13896
+ cacheReadPerMillionUsd: 1,
13897
+ cacheWritePerMillionUsd: 12.5
13898
+ }
13899
+ },
13900
+ {
13901
+ modelId: "openai/gpt-6-astra-pro",
13902
+ label: "GPT-6 Astra Pro",
13903
+ capabilities: {
13904
+ tools: true,
13905
+ forcedToolChoice: true,
13906
+ reasoningControl: {
13907
+ kind: "effort",
13908
+ levels: ["low", "medium", "high", "max"],
13909
+ mandatory: true
13910
+ }
13911
+ },
13912
+ contextWindow: 105e4,
13913
+ pricing: {
13914
+ inputPerMillionUsd: 10,
13915
+ outputPerMillionUsd: 50,
13916
+ cacheReadPerMillionUsd: 1,
13917
+ cacheWritePerMillionUsd: 12.5
13918
+ }
13919
+ },
13802
13920
  // Anthropic — reasoningControl WITHOUT the `reasoning` flag, on purpose:
13803
13921
  // the flag would flip openrouter.ts's always-on default injection; here
13804
13922
  // thinking is engaged only when the agent explicitly sets an effort.
@@ -13835,17 +13953,6 @@ var init_model_catalog = __esm({
13835
13953
  cacheWritePerMillionUsd: 6.25
13836
13954
  }
13837
13955
  },
13838
- {
13839
- modelId: "anthropic/claude-opus-4.7-fast",
13840
- label: "Claude Opus 4.7 (fast)",
13841
- capabilities: {
13842
- tools: true,
13843
- forcedToolChoice: true,
13844
- reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13845
- },
13846
- contextWindow: 1e6,
13847
- pricing: { inputPerMillionUsd: 30, outputPerMillionUsd: 150 }
13848
- },
13849
13956
  {
13850
13957
  modelId: "anthropic/claude-opus-4.8",
13851
13958
  label: "Claude Opus 4.8",
@@ -13862,17 +13969,6 @@ var init_model_catalog = __esm({
13862
13969
  cacheWritePerMillionUsd: 6.25
13863
13970
  }
13864
13971
  },
13865
- {
13866
- modelId: "anthropic/claude-opus-4.8-fast",
13867
- label: "Claude Opus 4.8 (fast)",
13868
- capabilities: {
13869
- tools: true,
13870
- forcedToolChoice: true,
13871
- reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13872
- },
13873
- contextWindow: 1e6,
13874
- pricing: { inputPerMillionUsd: 10, outputPerMillionUsd: 50 }
13875
- },
13876
13972
  {
13877
13973
  modelId: "anthropic/claude-sonnet-4.6",
13878
13974
  label: "Claude Sonnet 4.6",
@@ -13963,6 +14059,58 @@ var init_model_catalog = __esm({
13963
14059
  cacheReadPerMillionUsd: 0.064902
13964
14060
  }
13965
14061
  },
14062
+ {
14063
+ // "The GA release of DeepSeek V4 Pro" (upstream copy) — the dated
14064
+ // successor of the undated alias above. Pricing (DeepSeek's own
14065
+ // endpoint), context and supported_parameters read off /api/v1/models
14066
+ // on 2026-09-22. The levels follow the list endpoint's `reasoning`
14067
+ // object: supported_efforts max/high/low, mandatory:false — so no
14068
+ // 'medium', unlike the older entries above that predate that field.
14069
+ modelId: "deepseek/deepseek-v4-pro-0813",
14070
+ label: "DeepSeek V4 Pro (0813)",
14071
+ capabilities: {
14072
+ tools: true,
14073
+ forcedToolChoice: true,
14074
+ reasoning: true,
14075
+ reasoningControl: { kind: "effort", levels: ["low", "high", "max"] }
14076
+ },
14077
+ contextWindow: 1048576,
14078
+ providerOrder: ["deepseek"],
14079
+ pricing: {
14080
+ inputPerMillionUsd: 0.66,
14081
+ outputPerMillionUsd: 1.98,
14082
+ cacheReadPerMillionUsd: 0.022
14083
+ }
14084
+ },
14085
+ {
14086
+ // The newest Flash (2026-09-10), first on DeepSeek's Causal
14087
+ // Encoder-Decoder architecture. One difference from every V4 Flash
14088
+ // above: it takes IMAGE input (input_modalities: text, image), so it is
14089
+ // in VISION_MODEL_IDS. Same reasoning caveat as its siblings; levels
14090
+ // from the list endpoint's `reasoning` object (max/high/low,
14091
+ // mandatory:false, default_enabled:true). forcedToolChoice:false —
14092
+ // DeepSeek's own endpoint (the one providerOrder prefers) reports
14093
+ // supports_tool_choice.required:false; some fallbacks (DeepInfra,
14094
+ // Wafer) report true, and the runtime floor relaxes it anyway.
14095
+ // 'max' → OpenRouter 'xhigh' and Auto → 'medium' are not in this
14096
+ // model's supported_efforts; OpenRouter documents that it "will map
14097
+ // your requested effort to the nearest supported level".
14098
+ modelId: "deepseek/deepseek-v4.1-flash",
14099
+ label: "DeepSeek V4.1 Flash",
14100
+ capabilities: {
14101
+ tools: true,
14102
+ forcedToolChoice: false,
14103
+ reasoning: true,
14104
+ reasoningControl: { kind: "effort", levels: ["low", "high", "max"] }
14105
+ },
14106
+ contextWindow: 1048576,
14107
+ providerOrder: ["deepseek"],
14108
+ pricing: {
14109
+ inputPerMillionUsd: 0.15,
14110
+ outputPerMillionUsd: 0.6,
14111
+ cacheReadPerMillionUsd: 3e-3
14112
+ }
14113
+ },
13966
14114
  // Google — all three are thinking models on OpenRouter (supported_parameters
13967
14115
  // includes "reasoning", verified via openrouter.ai/google/… 2026-07-12).
13968
14116
  // reasoning:true makes the OpenRouter provider enable reasoning + round-trip
@@ -14214,6 +14362,93 @@ var init_model_catalog = __esm({
14214
14362
  cacheReadPerMillionUsd: 0.015
14215
14363
  }
14216
14364
  },
14365
+ {
14366
+ // "The high-speed variant of GLM-5.3-Flash ... up to 200 tokens/s"
14367
+ // (upstream copy, 2026-09-18). Same model family as Flash: multimodal
14368
+ // (text, image, video → VISION_MODEL_IDS), forcedToolChoice:false
14369
+ // (supports_tool_choice.required:false on its endpoint). The control
14370
+ // follows the list endpoint's `reasoning` object, read 2026-09-22:
14371
+ // mandatory:true, supported_efforts max/high/low, default max — the
14372
+ // full 5.3's posture, and the same object upstream now reports for
14373
+ // Flash too (the Flash entry above predates that field). It differs
14374
+ // from Flash on price (~5x) and context (1.05M, not 1.31M).
14375
+ modelId: "z-ai/glm-5.3-flashx",
14376
+ label: "GLM 5.3 FlashX",
14377
+ capabilities: {
14378
+ tools: true,
14379
+ forcedToolChoice: false,
14380
+ reasoning: true,
14381
+ reasoningControl: {
14382
+ kind: "effort",
14383
+ levels: ["low", "high", "max"],
14384
+ mandatory: true
14385
+ }
14386
+ },
14387
+ contextWindow: 1048576,
14388
+ pricing: {
14389
+ inputPerMillionUsd: 0.37,
14390
+ outputPerMillionUsd: 1.25,
14391
+ cacheReadPerMillionUsd: 0.075
14392
+ }
14393
+ },
14394
+ // Xiaomi MiMo-V2.6 — the three 2.6 models OpenRouter serves (2026-09-21),
14395
+ // all read off /api/v1/models and /models/<id>/endpoints on 2026-09-22:
14396
+ // 1.05M context, 131K max output, input_modalities text+image+video+audio
14397
+ // (→ VISION_MODEL_IDS), supported_parameters tools, tool_choice,
14398
+ // reasoning, include_reasoning — and NO reasoning_effort. The list
14399
+ // endpoint's `reasoning` object says only {mandatory:false}: no
14400
+ // supported_efforts, so thinking can be switched on or off and nothing
14401
+ // else — kind 'onoff', not a made-up scale. No always-on `reasoning`
14402
+ // flag: Auto keeps the provider's default. forcedToolChoice:true —
14403
+ // every endpoint reports supports_tool_choice.required:true.
14404
+ // Upstream copy: Flash = 309B MoE / 15B active; Pro = the >1T flagship;
14405
+ // Pro-UltraSpeed = the same Pro checkpoint "roughly 10x" faster, 10x the
14406
+ // price.
14407
+ {
14408
+ modelId: "xiaomi/mimo-v2.6-flash",
14409
+ label: "MiMo V2.6 Flash",
14410
+ capabilities: {
14411
+ tools: true,
14412
+ forcedToolChoice: true,
14413
+ reasoningControl: { kind: "onoff" }
14414
+ },
14415
+ contextWindow: 1048576,
14416
+ pricing: {
14417
+ inputPerMillionUsd: 0.14,
14418
+ outputPerMillionUsd: 0.28,
14419
+ cacheReadPerMillionUsd: 28e-4
14420
+ }
14421
+ },
14422
+ {
14423
+ modelId: "xiaomi/mimo-v2.6-pro",
14424
+ label: "MiMo V2.6 Pro",
14425
+ capabilities: {
14426
+ tools: true,
14427
+ forcedToolChoice: true,
14428
+ reasoningControl: { kind: "onoff" }
14429
+ },
14430
+ contextWindow: 1048576,
14431
+ pricing: {
14432
+ inputPerMillionUsd: 0.435,
14433
+ outputPerMillionUsd: 0.87,
14434
+ cacheReadPerMillionUsd: 36e-4
14435
+ }
14436
+ },
14437
+ {
14438
+ modelId: "xiaomi/mimo-v2.6-pro-ultraspeed",
14439
+ label: "MiMo V2.6 Pro UltraSpeed",
14440
+ capabilities: {
14441
+ tools: true,
14442
+ forcedToolChoice: true,
14443
+ reasoningControl: { kind: "onoff" }
14444
+ },
14445
+ contextWindow: 1048576,
14446
+ pricing: {
14447
+ inputPerMillionUsd: 4.35,
14448
+ outputPerMillionUsd: 8.7,
14449
+ cacheReadPerMillionUsd: 0.036
14450
+ }
14451
+ },
14217
14452
  // Moonshot (Kimi)
14218
14453
  {
14219
14454
  modelId: "moonshotai/kimi-k2.6",
@@ -14292,6 +14527,56 @@ var init_model_catalog = __esm({
14292
14527
  cacheReadPerMillionUsd: 0.3
14293
14528
  }
14294
14529
  },
14530
+ // Grok 4.6 (2026-08-12) and 4.7 (2026-09-21, "succeeding Grok 4.6" per
14531
+ // upstream copy): same 500K context, same text+image+file input
14532
+ // (→ VISION_MODEL_IDS), same supported_parameters as 4.5 (tools,
14533
+ // tool_choice, reasoning, reasoning_effort), read off /api/v1/models and
14534
+ // /models/<id>/endpoints on 2026-09-22. The control follows the list
14535
+ // endpoint's `reasoning` object: mandatory:true (no Off), and — unlike
14536
+ // 4.5, whose object stops at high — supported_efforts xhigh/high/medium/
14537
+ // low, so 'max' (→ xhigh) is offered. Pricing: 4.6 = 4.5; 4.7 is 20%
14538
+ // cheaper. Both double above 200K prompt tokens (an override the flat
14539
+ // price does not carry, same as 4.5).
14540
+ {
14541
+ modelId: "x-ai/grok-4.6",
14542
+ label: "Grok 4.6",
14543
+ capabilities: {
14544
+ tools: true,
14545
+ forcedToolChoice: true,
14546
+ reasoning: true,
14547
+ reasoningControl: {
14548
+ kind: "effort",
14549
+ levels: ["low", "medium", "high", "max"],
14550
+ mandatory: true
14551
+ }
14552
+ },
14553
+ contextWindow: 5e5,
14554
+ pricing: {
14555
+ inputPerMillionUsd: 2,
14556
+ outputPerMillionUsd: 6,
14557
+ cacheReadPerMillionUsd: 0.5
14558
+ }
14559
+ },
14560
+ {
14561
+ modelId: "x-ai/grok-4.7",
14562
+ label: "Grok 4.7",
14563
+ capabilities: {
14564
+ tools: true,
14565
+ forcedToolChoice: true,
14566
+ reasoning: true,
14567
+ reasoningControl: {
14568
+ kind: "effort",
14569
+ levels: ["low", "medium", "high", "max"],
14570
+ mandatory: true
14571
+ }
14572
+ },
14573
+ contextWindow: 5e5,
14574
+ pricing: {
14575
+ inputPerMillionUsd: 1.6,
14576
+ outputPerMillionUsd: 4.8,
14577
+ cacheReadPerMillionUsd: 0.4
14578
+ }
14579
+ },
14295
14580
  // Qwen — both verified via OpenRouter /api/v1/models (2026-07-20): 1M
14296
14581
  // context, tools + tool_choice + reasoning params (no native
14297
14582
  // reasoning_effort — OpenRouter's unified param drives the hybrid
@@ -14374,13 +14659,12 @@ var init_model_catalog = __esm({
14374
14659
  VISION_MODEL_IDS = /* @__PURE__ */ new Set([
14375
14660
  // OpenRouter (verified via /api/v1/models)
14376
14661
  "anthropic/claude-fable-5",
14662
+ // input_modalities ["text","image","file"] on /api/v1/models, 2026-09-22.
14663
+ "anthropic/claude-fable-5.1",
14377
14664
  "anthropic/claude-haiku-4.5",
14378
14665
  "anthropic/claude-opus-4.7",
14379
- "anthropic/claude-opus-4.7-fast",
14380
14666
  "anthropic/claude-opus-4.8",
14381
- "anthropic/claude-opus-4.8-fast",
14382
14667
  "anthropic/claude-opus-5",
14383
- "anthropic/claude-opus-5-fast",
14384
14668
  "anthropic/claude-sonnet-4.6",
14385
14669
  "anthropic/claude-sonnet-5",
14386
14670
  "google/gemini-3.1-flash-lite-preview",
@@ -14396,14 +14680,35 @@ var init_model_catalog = __esm({
14396
14680
  "openai/gpt-5.6-luna",
14397
14681
  "openai/gpt-5.6-luna-pro",
14398
14682
  "openai/gpt-5.6-terra-pro",
14683
+ // The rest of the 5.6 series and GPT-6 Astra: input_modalities
14684
+ // ["file","image","text"] on /api/v1/models, 2026-09-22.
14685
+ "openai/gpt-5.6-terra",
14686
+ "openai/gpt-5.6-sol",
14687
+ "openai/gpt-5.6-sol-pro",
14688
+ "openai/gpt-6-astra",
14689
+ "openai/gpt-6-astra-pro",
14690
+ // deepseek/deepseek-v4.1-flash reports ["text","image"] (2026-09-22) — the
14691
+ // first V4 Flash that does; v4-flash, v4-flash-0731 and both V4 Pro are
14692
+ // text-only per the same source and deliberately NOT in this set.
14693
+ "deepseek/deepseek-v4.1-flash",
14399
14694
  "qwen/qwen3.8-max",
14400
14695
  // Verified via OpenRouter /api/v1/models input_modalities on 2026-08-28:
14401
14696
  // z-ai/glm-5.3-flash reports ["text","image","video"]. The full z-ai/glm-5.3
14402
14697
  // reports ["text"] only and is deliberately NOT in this set.
14403
14698
  "z-ai/glm-5.3-flash",
14699
+ // z-ai/glm-5.3-flashx reports the same ["text","image","video"] (2026-09-22).
14700
+ "z-ai/glm-5.3-flashx",
14701
+ // Xiaomi MiMo-V2.6: all three report ["text","image","video","audio"]
14702
+ // (2026-09-22).
14703
+ "xiaomi/mimo-v2.6-flash",
14704
+ "xiaomi/mimo-v2.6-pro",
14705
+ "xiaomi/mimo-v2.6-pro-ultraspeed",
14404
14706
  // Verified via OpenRouter /api/v1/models input_modalities (2026-07-20).
14405
14707
  // qwen/qwen3.7-max is deliberately absent — text-only per the same source.
14406
14708
  "x-ai/grok-4.5",
14709
+ // 4.6 and 4.7 report the same ["text","image","file"] (2026-09-22).
14710
+ "x-ai/grok-4.6",
14711
+ "x-ai/grok-4.7",
14407
14712
  "qwen/qwen3.7-plus",
14408
14713
  // Native-provider forms
14409
14714
  "claude-fable-5",
@@ -14990,10 +15295,10 @@ var init_entities = __esm({
14990
15295
  updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow(),
14991
15296
  lastCuratorRunAt: timestamp("last_curator_run_at", { withTimezone: true }),
14992
15297
  reflectionEnabled: boolean("reflection_enabled").notNull().default(false),
14993
- // Decoupled from reflection_enabled (which gates the skill-learning loop,
14994
- // opt-in). Gates the memory curator (Phase 2 LLM pass) — ON by default so
14995
- // memory curation runs even for entities that never opted into reflection.
14996
- memoryCurationEnabled: boolean("memory_curation_enabled").notNull().default(true),
15298
+ // `memory_curation_enabled` lived here from 0.7.0 to migration 0122 (#411):
15299
+ // a per-workspace gate on the memory curator that no screen ever exposed.
15300
+ // Memory curation is now gated by the runner's MEMORY_CURATION_ENABLED
15301
+ // kill-switch only; "do not touch this fact" is the pin on the fact.
14997
15302
  // Controls whether agent-authored skills are auto-assigned to the authoring
14998
15303
  // agent ('auto') or queued for the entity owner to approve ('approval').
14999
15304
  skillAssignmentMode: text("skill_assignment_mode").notNull().default("approval").$type(),
@@ -20984,8 +21289,45 @@ var init_logs = __esm({
20984
21289
  }
20985
21290
  });
20986
21291
 
21292
+ // ../../packages/shared/src/git-binary.ts
21293
+ import { stat } from "fs/promises";
21294
+ import { delimiter as PATH_DELIMITER } from "path";
21295
+ function enBarresObliques(chemin) {
21296
+ return chemin.replace(/\\/g, "/");
21297
+ }
21298
+ async function estFichier(chemin) {
21299
+ try {
21300
+ return (await stat(chemin)).isFile();
21301
+ } catch {
21302
+ return false;
21303
+ }
21304
+ }
21305
+ async function resolveGitBinary() {
21306
+ gitBinaire ??= (async () => {
21307
+ const chemins = (process.env["PATH"] ?? "").split(PATH_DELIMITER).filter((d) => d !== "");
21308
+ const windows = process.platform === "win32";
21309
+ for (const dossier of chemins) {
21310
+ const base = `${enBarresObliques(dossier)}/git`;
21311
+ for (const ext of windows ? EXTENSIONS_WINDOWS : [""]) {
21312
+ if (await estFichier(base + ext)) return base + ext;
21313
+ }
21314
+ }
21315
+ console.warn("[git] GIT_NOT_ON_PATH");
21316
+ return null;
21317
+ })();
21318
+ return gitBinaire;
21319
+ }
21320
+ var EXTENSIONS_WINDOWS, gitBinaire;
21321
+ var init_git_binary = __esm({
21322
+ "../../packages/shared/src/git-binary.ts"() {
21323
+ "use strict";
21324
+ EXTENSIONS_WINDOWS = [".exe", ".com"];
21325
+ gitBinaire = null;
21326
+ }
21327
+ });
21328
+
20987
21329
  // ../../packages/checkpoints/src/failure.ts
20988
- import { readdir, stat } from "fs/promises";
21330
+ import { readdir, stat as stat2 } from "fs/promises";
20989
21331
  import { basename, join as join13 } from "path";
20990
21332
  function checkpointFailureCode(cause, operation) {
20991
21333
  if (cause === "git_missing") return "git_missing";
@@ -21030,7 +21372,7 @@ async function measureWorkspace(workspace, limits = {}) {
21030
21372
  }
21031
21373
  files++;
21032
21374
  try {
21033
- bytes += (await stat(join13(dir, entry.name))).size;
21375
+ bytes += (await stat2(join13(dir, entry.name))).size;
21034
21376
  } catch {
21035
21377
  }
21036
21378
  }
@@ -21170,7 +21512,13 @@ function isTimeoutError(err) {
21170
21512
  const e = err;
21171
21513
  return e.killed === true || e.code === "ETIMEDOUT";
21172
21514
  }
21515
+ async function gitBinary() {
21516
+ const binaire = await resolveGitBinary();
21517
+ if (binaire === null) throw new GitBinaryMissingError();
21518
+ return binaire;
21519
+ }
21173
21520
  function isGitMissingError(err) {
21521
+ if (err instanceof GitBinaryMissingError) return true;
21174
21522
  if (typeof err !== "object" || err === null) return false;
21175
21523
  const e = err;
21176
21524
  return e.code === "ENOENT" && typeof e.syscall === "string" && e.syscall.startsWith("spawn");
@@ -21242,7 +21590,7 @@ function gitEnv(store, workspace, indexFile) {
21242
21590
  };
21243
21591
  }
21244
21592
  async function git(store, workspace, args, indexFile, timeoutMs = storeTimeoutMs()) {
21245
- const { stdout } = await run("git", args, {
21593
+ const { stdout } = await run(await gitBinary(), args, {
21246
21594
  timeout: timeoutMs,
21247
21595
  windowsHide: true,
21248
21596
  env: gitEnv(store, workspace, indexFile)
@@ -21255,7 +21603,7 @@ async function ensureStore(store) {
21255
21603
  await writeFile(join14(store, "gitconfig"), "", { flag: "a" });
21256
21604
  if (!existsSync13(join14(gitDir, "HEAD"))) {
21257
21605
  await mkdir(gitDir, { recursive: true });
21258
- await run("git", ["init", "--bare", "--quiet", gitDir], {
21606
+ await run(await gitBinary(), ["init", "--bare", "--quiet", gitDir], {
21259
21607
  timeout: GIT_TIMEOUT_MS,
21260
21608
  windowsHide: true
21261
21609
  });
@@ -21321,14 +21669,23 @@ async function restoreCheckpoint(store, workspace, sha) {
21321
21669
  await git(store, workspace, ["checkout", "-f", sha, "--", "."]);
21322
21670
  return { restored: sha, safety };
21323
21671
  }
21324
- var run, GIT_TIMEOUT_MS, badTimeoutSaid, EXCLUDES, CHECKPOINT_COVERAGE_NOTE;
21672
+ var run, GIT_TIMEOUT_MS, badTimeoutSaid, GitBinaryMissingError, EXCLUDES, CHECKPOINT_COVERAGE_NOTE;
21325
21673
  var init_checkpoints = __esm({
21326
21674
  "../../packages/checkpoints/src/checkpoints.ts"() {
21327
21675
  "use strict";
21676
+ init_git_binary();
21328
21677
  init_failure();
21329
21678
  run = promisify(execFile);
21330
21679
  GIT_TIMEOUT_MS = 3e4;
21331
21680
  badTimeoutSaid = false;
21681
+ GitBinaryMissingError = class extends Error {
21682
+ constructor() {
21683
+ super(
21684
+ "git is not on PATH: no checkpoint can be taken or read. Install git, or make it reachable from the process PATH."
21685
+ );
21686
+ this.name = "GitBinaryMissingError";
21687
+ }
21688
+ };
21332
21689
  EXCLUDES = [
21333
21690
  ...SKIPPED_DIRS.map((dir) => `${dir}/`),
21334
21691
  ...SKIPPED_FILE_SUFFIXES.map((suffixe) => `*${suffixe}`)
package/docs-index.json CHANGED
@@ -118,7 +118,7 @@
118
118
  "pageTitle": "Memory",
119
119
  "heading": "Memory",
120
120
  "url": "/nodal-agents/docs/concepts/memory",
121
- "text": "How agents store, recall, and automatically use persistent facts across jobs. Agents accumulate facts in a persistent agent_memory table. These facts survive across sessions, restarts, and model swaps — whenever a job runs, relevant memories are already waiting in the system prompt before the first LLM call."
121
+ "text": "How an agent remembers something for later, and how the fact comes back next time it works. Agents accumulate facts in a persistent agent_memory table. These facts survive across sessions, restarts, and model swaps — whenever a job runs, relevant memories are already waiting in the system prompt before the first LLM call. When you tell an agent to remember this, to keep something for later, or to do it this way next time, a memory is what you are asking for: the fact is written once, and read back on its own every time it is needed."
122
122
  },
123
123
  {
124
124
  "page": "concepts/memory",
@@ -130,8 +130,8 @@
130
130
  {
131
131
  "page": "concepts/memory",
132
132
  "pageTitle": "Memory",
133
- "heading": "Auto-injection into every job",
134
- "url": "/nodal-agents/docs/concepts/memory#auto-injection-into-every-job",
133
+ "heading": "Auto-injection into every job — the fact is there next time",
134
+ "url": "/nodal-agents/docs/concepts/memory#auto-injection-into-every-job--the-fact-is-there-next-time",
135
135
  "text": "Before a job starts, the runner selects memories from the entity-wide pool and injects them as a frozen block inside the agent's system prompt. No tool call is needed — the agent already has context. Selection works in two stages: Candidate fetch — up to 200 non-archived, non-expired memories for the entity (MAX_CANDIDATES in packages/memory/src/inject.ts). The ordering depends on the current job: Task-relevant ranking. When the job's task is tokenizable, candidates are ordered by ts_rank against the task text (full-text relevance), with importance and recency only as a tie-break. A fact relevant to this task can surface even if it sits outside the importance/recency top tier. Fallback ranking. When the task has no usable tokens, candidates are ordered by importance DESC, then last_accessed_at DESC. Budget pack — a greedy selector fits as many as possible under a character budget derived from agents.memoryTokenBudget. In the relevance path, the FTS order is authoritative and is not re-sorted by importance. A single oversized fact is skipped rather than truncated. Memory is entity-scoped, not agent-scoped — every agent in the same entity sees the same pool. This matches the query_memory tool's behaviour: knowledge follows the user across agents, not the individual agent."
136
136
  },
137
137
  {
@@ -151,9 +151,9 @@
151
151
  {
152
152
  "page": "concepts/memory",
153
153
  "pageTitle": "Memory",
154
- "heading": "Writing memories",
155
- "url": "/nodal-agents/docs/concepts/memory#writing-memories",
156
- "text": "Agents write memories with save_memory. Duplicate detection runs on a normalized hash of the fact text — an identical (non-archived) fact already in the store is rejected before it reaches the DB, so the pool stays clean. Content is sanitized before storage to guard against injection payloads being embedded into the entity-wide pool."
154
+ "heading": "Writing memories — remember this, for later",
155
+ "url": "/nodal-agents/docs/concepts/memory#writing-memories--remember-this-for-later",
156
+ "text": "Agents write memories with save_memory — the tool behind \"remember that I prefer short answers\" and \"keep that for later\". Duplicate detection runs on a normalized hash of the fact text — an identical (non-archived) fact already in the store is rejected before it reaches the DB, so the pool stays clean. Content is sanitized before storage to guard against injection payloads being embedded into the entity-wide pool."
157
157
  },
158
158
  {
159
159
  "page": "concepts/memory",
@@ -914,9 +914,9 @@
914
914
  {
915
915
  "page": "guides/shell-commands",
916
916
  "pageTitle": "Shell commands",
917
- "heading": "How approval works",
918
- "url": "/nodal-agents/docs/guides/shell-commands#how-approval-works",
919
- "text": "When the agent calls run_command, the runner creates an approval request and suspends the job. You see the exact command in the dashboard and approve or reject it. If you approve, the runner executes the command and the job resumes with the output. If you reject, the agent receives an error and can try a different approach. On a Telegram-bound agent, the agent gets a bounded number of turns to tell you via chat that it is waiting — so you are not left wondering why it went quiet."
917
+ "heading": "How approval works — you approve a command before it runs",
918
+ "url": "/nodal-agents/docs/guides/shell-commands#how-approval-works--you-approve-a-command-before-it-runs",
919
+ "text": "When the agent calls run_command, the runner creates an approval request and suspends the job. You see the exact command in the dashboard and approve or reject it. If you approve, the runner executes the command and the job resumes with the output. If you reject, the agent receives an error and can try a different approach. Where you approve a command: the Approvals page of the dashboard, which lists every command waiting for you. By default, nothing an agent proposes runs until you approve that call. Three things let commands through without that question: a Run without asking rule on run_command for that agent, optionally confined to one of its folders — the card's Approve for this project writes exactly that rule; the workspace's autonomy level set to Autonomous, gate destructive, under which an ordinary command runs unasked while a destructive or heavy one (deleting files, installing a package, killing a process, a disk operation) stays gated; and Yolo mode, which drops the gate for every command that agent runs. On a Telegram-bound agent, the agent gets a bounded number of turns to tell you via chat that it is waiting — so you are not left wondering why it went quiet."
920
920
  },
921
921
  {
922
922
  "page": "guides/shell-commands",
@@ -1264,9 +1264,9 @@
1264
1264
  {
1265
1265
  "page": "reference/dashboard",
1266
1266
  "pageTitle": "Dashboard reference",
1267
- "heading": "Approvals — /approvals",
1268
- "url": "/nodal-agents/docs/reference/dashboard#approvals--approvals",
1269
- "text": "Everything that needs your sign-off, and everything that got it. Tabs: pending, approved, rejected, expired, all. Each card shows the tool input, the agent's stated purpose and impact, and a link to the run that asked. Approve or reject, optionally with a note. ?show=<id> opens one request on its own, whatever its decision — it is what the sidebar's Recents rows link to. The list narrows to that card and the page says so in its subtitle. See the autonomy model in Agents."
1267
+ "heading": "Approvals — approve or refuse a command, /approvals",
1268
+ "url": "/nodal-agents/docs/reference/dashboard#approvals--approve-or-refuse-a-command-approvals",
1269
+ "text": "Everything that needs your sign-off, and everything that got it. Tabs: pending, approved, rejected, expired, all. This is where you approve a command — or any other tool call an agent asked to make — and where you refuse one. Each card shows the tool input, the agent's stated purpose and impact, and a link to the run that asked. Approve or reject, optionally with a note. An approval covers that one call. To stop confirming every time, you allow the tool rather than the command: on the agent's Approvals tab, set run_command to Run without asking, for that agent, and — if you name one — only inside one of its folders. The card's Approve for this project writes that same rule for the folder the run is in. A rule never reads what the command says, so it cannot allow one command line and keep asking about another. Yolo, on the same tab, goes further: it drops the gate for every command that agent runs. A third way does not come from that tab at all: with the workspace's autonomy level set to Autonomous, gate destructive and no rule on the tool, an ordinary command runs unasked, while a destructive or heavy one (deleting files, installing a package, killing a process, a disk operation) stays gated. See Shell commands. ?show=<id> opens one request on its own, whatever its decision — it is what the sidebar's Recents rows link to. The list narrows to that card and the page says so in its subtitle. See the autonomy model in Agents."
1270
1270
  },
1271
1271
  {
1272
1272
  "page": "reference/dashboard",