@sixb/core 0.1.3 → 0.1.5

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 (271) hide show
  1. package/dist/actions/index.d.ts +2 -2
  2. package/dist/actions/index.d.ts.map +1 -1
  3. package/dist/actions/index.js +17 -18
  4. package/dist/actions/index.js.map +1 -1
  5. package/dist/actions/read-facade.d.ts +10 -2
  6. package/dist/actions/read-facade.d.ts.map +1 -1
  7. package/dist/actions/types/context.d.ts +45 -2
  8. package/dist/actions/types/context.d.ts.map +1 -1
  9. package/dist/actions/worker.js +4 -4
  10. package/dist/actions/worker.js.map +1 -1
  11. package/dist/agents/context-compaction.d.ts +40 -0
  12. package/dist/agents/context-compaction.d.ts.map +1 -0
  13. package/dist/agents/ids.d.ts +2 -0
  14. package/dist/agents/ids.d.ts.map +1 -1
  15. package/dist/agents/index.d.ts +6 -5
  16. package/dist/agents/index.d.ts.map +1 -1
  17. package/dist/agents/index.js +42 -37
  18. package/dist/agents/index.js.map +1 -1
  19. package/dist/agents/streams.d.ts +17 -1
  20. package/dist/agents/streams.d.ts.map +1 -1
  21. package/dist/agents/streams.js +4 -2
  22. package/dist/agents/streams.js.map +1 -1
  23. package/dist/agents/types.d.ts +11 -0
  24. package/dist/agents/types.d.ts.map +1 -1
  25. package/dist/agents/validation.d.ts +1 -1
  26. package/dist/agents/validation.d.ts.map +1 -1
  27. package/dist/auth/index.js +7 -3
  28. package/dist/auth/index.js.map +1 -1
  29. package/dist/authorization/index.js +6 -2
  30. package/dist/authorization/index.js.map +1 -1
  31. package/dist/bootstrap/index.js +30 -31
  32. package/dist/bootstrap/index.js.map +1 -1
  33. package/dist/{chunk-d6y2wsfg.js → chunk-1q02e95s.js} +12 -7
  34. package/dist/{chunk-d6y2wsfg.js.map → chunk-1q02e95s.js.map} +4 -3
  35. package/dist/{chunk-c6cfqydk.js → chunk-4h947jd8.js} +1 -1
  36. package/dist/{chunk-gqdd7508.js → chunk-4rh2m6zg.js} +1 -1
  37. package/dist/{chunk-f1cyvnrk.js → chunk-6d5xdj1q.js} +259 -9
  38. package/dist/chunk-6d5xdj1q.js.map +14 -0
  39. package/dist/{chunk-fmx1sz2h.js → chunk-72q2y8hn.js} +3 -3
  40. package/dist/{chunk-fmx1sz2h.js.map → chunk-72q2y8hn.js.map} +3 -3
  41. package/dist/{chunk-ttba8x6z.js → chunk-78c6xvyr.js} +68 -3
  42. package/dist/chunk-78c6xvyr.js.map +15 -0
  43. package/dist/{chunk-wb4051cx.js → chunk-819wnjz8.js} +11 -5
  44. package/dist/chunk-819wnjz8.js.map +12 -0
  45. package/dist/{chunk-177ed2mp.js → chunk-84h6qhmp.js} +233 -97
  46. package/dist/{chunk-177ed2mp.js.map → chunk-84h6qhmp.js.map} +9 -9
  47. package/dist/{chunk-pxtrxm3p.js → chunk-a09jx26t.js} +1 -1
  48. package/dist/{chunk-bv41fmjn.js → chunk-am6eczah.js} +59 -22
  49. package/dist/{chunk-bv41fmjn.js.map → chunk-am6eczah.js.map} +8 -7
  50. package/dist/{chunk-zpw39qhj.js → chunk-dm72y8wt.js} +25 -2
  51. package/dist/chunk-dm72y8wt.js.map +10 -0
  52. package/dist/{chunk-kqxgf6kv.js → chunk-drjqm1aa.js} +16 -1
  53. package/dist/{chunk-kqxgf6kv.js.map → chunk-drjqm1aa.js.map} +3 -3
  54. package/dist/chunk-dysw7nsm.js.map +1 -1
  55. package/dist/{chunk-4p9rh7jj.js → chunk-ea73pzk7.js} +1 -1
  56. package/dist/{chunk-4aw0jwk0.js → chunk-f6erf2vv.js} +1 -1
  57. package/dist/{chunk-4z3n1dzt.js → chunk-f83ka50g.js} +131 -25
  58. package/dist/chunk-f83ka50g.js.map +23 -0
  59. package/dist/{chunk-c8bw2b6c.js → chunk-gadsm794.js} +2 -2
  60. package/dist/{chunk-1ywq4hzk.js → chunk-h6h91mfy.js} +8 -10
  61. package/dist/{chunk-1ywq4hzk.js.map → chunk-h6h91mfy.js.map} +2 -2
  62. package/dist/{chunk-n5x5y80a.js → chunk-nzw7sm3b.js} +2 -2
  63. package/dist/{chunk-63te770v.js → chunk-qewtks41.js} +8 -8
  64. package/dist/{chunk-63te770v.js.map → chunk-qewtks41.js.map} +2 -2
  65. package/dist/{chunk-261ag4t4.js → chunk-r0rry8dn.js} +3 -3
  66. package/dist/{chunk-88ppkr54.js → chunk-rte5sm3z.js} +26 -2
  67. package/dist/chunk-rte5sm3z.js.map +12 -0
  68. package/dist/chunk-t0jjkep3.js.map +1 -1
  69. package/dist/{chunk-ettb0cy4.js → chunk-tbv03sx2.js} +59 -29
  70. package/dist/{chunk-ettb0cy4.js.map → chunk-tbv03sx2.js.map} +5 -5
  71. package/dist/{chunk-d2adj15j.js → chunk-tkdscva6.js} +1 -1
  72. package/dist/{chunk-xmggaxg4.js → chunk-v0egge8b.js} +201 -38
  73. package/dist/{chunk-xmggaxg4.js.map → chunk-v0egge8b.js.map} +8 -6
  74. package/dist/{chunk-z8j83gzd.js → chunk-x2yw73hy.js} +1 -1
  75. package/dist/{chunk-qer6am8w.js → chunk-xdf9yswn.js} +1 -1
  76. package/dist/{chunk-3rsf30p4.js → chunk-z3ga9q5m.js} +18 -21
  77. package/dist/{chunk-3rsf30p4.js.map → chunk-z3ga9q5m.js.map} +4 -5
  78. package/dist/{chunk-km4rkj4t.js → chunk-zp2v2rv6.js} +3 -3
  79. package/dist/execution/agent.js +26 -27
  80. package/dist/execution/agent.js.map +1 -1
  81. package/dist/execution/primitive.js +26 -27
  82. package/dist/execution/primitive.js.map +2 -2
  83. package/dist/execution/request.js +27 -28
  84. package/dist/execution/request.js.map +2 -2
  85. package/dist/http/index.js +1 -1
  86. package/dist/index.d.ts +6 -5
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +54 -55
  89. package/dist/index.js.map +1 -1
  90. package/dist/lake-storage/types.d.ts +2 -1
  91. package/dist/lake-storage/types.d.ts.map +1 -1
  92. package/dist/materializer/index.js +15 -16
  93. package/dist/materializer/index.js.map +1 -1
  94. package/dist/models/index.d.ts +40 -0
  95. package/dist/models/index.d.ts.map +1 -0
  96. package/dist/objects/execution.d.ts +6 -1
  97. package/dist/objects/execution.d.ts.map +1 -1
  98. package/dist/objects/index.js +19 -20
  99. package/dist/objects/index.js.map +1 -1
  100. package/dist/objects/link/endpoints.d.ts.map +1 -1
  101. package/dist/objects/query/executor.d.ts +1 -0
  102. package/dist/objects/query/executor.d.ts.map +1 -1
  103. package/dist/objects/query/explain.d.ts +1 -0
  104. package/dist/objects/query/explain.d.ts.map +1 -1
  105. package/dist/objects/query/index.d.ts +3 -1
  106. package/dist/objects/query/index.d.ts.map +1 -1
  107. package/dist/objects/query/index.js +30 -5
  108. package/dist/objects/query/index.js.map +1 -1
  109. package/dist/objects/query/ir.d.ts +14 -1
  110. package/dist/objects/query/ir.d.ts.map +1 -1
  111. package/dist/objects/query/links.d.ts +25 -0
  112. package/dist/objects/query/links.d.ts.map +1 -0
  113. package/dist/objects/query/normalize.d.ts.map +1 -1
  114. package/dist/objects/query/planner.d.ts.map +1 -1
  115. package/dist/objects/query/validate.d.ts +1 -0
  116. package/dist/objects/query/validate.d.ts.map +1 -1
  117. package/dist/ontology/internal.d.ts +1 -1
  118. package/dist/ontology/internal.d.ts.map +1 -1
  119. package/dist/ontology/internal.js +14 -6
  120. package/dist/ontology/internal.js.map +3 -3
  121. package/dist/ontology/json-schema.d.ts +10 -0
  122. package/dist/ontology/json-schema.d.ts.map +1 -1
  123. package/dist/pipelines/index.js +15 -16
  124. package/dist/pipelines/index.js.map +1 -1
  125. package/dist/projections/builders.d.ts +33 -4
  126. package/dist/projections/builders.d.ts.map +1 -1
  127. package/dist/projections/index.d.ts +1 -1
  128. package/dist/projections/index.d.ts.map +1 -1
  129. package/dist/projections/internal.js +15 -16
  130. package/dist/projections/internal.js.map +1 -1
  131. package/dist/projections/run-dispatch.d.ts +1 -0
  132. package/dist/projections/run-dispatch.d.ts.map +1 -1
  133. package/dist/projections/types.d.ts +12 -9
  134. package/dist/projections/types.d.ts.map +1 -1
  135. package/dist/projections/validation.d.ts +6 -5
  136. package/dist/projections/validation.d.ts.map +1 -1
  137. package/dist/query.d.ts +2 -1
  138. package/dist/query.d.ts.map +1 -1
  139. package/dist/query.js +2 -2
  140. package/dist/runtime/create.d.ts +3 -0
  141. package/dist/runtime/create.d.ts.map +1 -1
  142. package/dist/runtime/definitions.d.ts +3 -0
  143. package/dist/runtime/definitions.d.ts.map +1 -1
  144. package/dist/runtime/host.d.ts +2 -0
  145. package/dist/runtime/host.d.ts.map +1 -1
  146. package/dist/runtime/resolve-definitions.d.ts +2 -0
  147. package/dist/runtime/resolve-definitions.d.ts.map +1 -1
  148. package/dist/storage/agents/in-memory.d.ts +4 -0
  149. package/dist/storage/agents/in-memory.d.ts.map +1 -1
  150. package/dist/storage/agents/provider.js +9 -5
  151. package/dist/storage/agents/provider.js.map +1 -1
  152. package/dist/storage/agents/types.d.ts +5 -0
  153. package/dist/storage/agents/types.d.ts.map +1 -1
  154. package/dist/storage/ai-cost/provider.js +1 -1
  155. package/dist/storage/ai-usage/in-memory.d.ts +2 -1
  156. package/dist/storage/ai-usage/in-memory.d.ts.map +1 -1
  157. package/dist/storage/ai-usage/index.d.ts +1 -1
  158. package/dist/storage/ai-usage/index.d.ts.map +1 -1
  159. package/dist/storage/ai-usage/types.d.ts +6 -0
  160. package/dist/storage/ai-usage/types.d.ts.map +1 -1
  161. package/dist/storage/index.d.ts +3 -2
  162. package/dist/storage/index.d.ts.map +1 -1
  163. package/dist/storage/index.js +19 -14
  164. package/dist/storage/index.js.map +1 -1
  165. package/dist/storage/objects/in-memory.d.ts +6 -3
  166. package/dist/storage/objects/in-memory.d.ts.map +1 -1
  167. package/dist/storage/objects/index.d.ts +3 -1
  168. package/dist/storage/objects/index.d.ts.map +1 -1
  169. package/dist/storage/objects/keys.d.ts +16 -0
  170. package/dist/storage/objects/keys.d.ts.map +1 -0
  171. package/dist/storage/objects/types.d.ts +33 -6
  172. package/dist/storage/objects/types.d.ts.map +1 -1
  173. package/dist/storage/ontology/provider.js +1 -1
  174. package/dist/storage/workflow-runs/provider.js +9 -5
  175. package/dist/storage/workflow-runs/provider.js.map +1 -1
  176. package/dist/syncs/index.js +15 -16
  177. package/dist/syncs/index.js.map +1 -1
  178. package/dist/testing/agent-storage-contract.d.ts.map +1 -1
  179. package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -1
  180. package/dist/testing/effective-storage-contract.d.ts +1 -1
  181. package/dist/testing/effective-storage-contract.d.ts.map +1 -1
  182. package/dist/testing/index.js +455 -40
  183. package/dist/testing/index.js.map +7 -7
  184. package/dist/testing/lake-storage-contract.d.ts.map +1 -1
  185. package/dist/testing/object-query-contract.d.ts +1 -1
  186. package/dist/testing/object-query-contract.d.ts.map +1 -1
  187. package/dist/webhooks/internal.js +13 -14
  188. package/dist/webhooks/internal.js.map +2 -2
  189. package/dist/workflows/index.js +27 -28
  190. package/dist/workflows/index.js.map +1 -1
  191. package/package.json +1 -1
  192. package/src/actions/index.ts +10 -1
  193. package/src/actions/read-facade.ts +125 -3
  194. package/src/actions/types/context.ts +69 -2
  195. package/src/agents/builders.ts +3 -3
  196. package/src/agents/context-compaction.ts +261 -0
  197. package/src/agents/ids.ts +5 -0
  198. package/src/agents/index.ts +18 -9
  199. package/src/agents/streams.ts +56 -0
  200. package/src/agents/types.ts +12 -0
  201. package/src/agents/validation.ts +39 -5
  202. package/src/http/api-routes.ts +7 -7
  203. package/src/index.ts +19 -0
  204. package/src/lake-storage/types.ts +2 -1
  205. package/src/materializer/telemetry/append.ts +33 -16
  206. package/src/models/index.ts +71 -0
  207. package/src/objects/execution.ts +20 -0
  208. package/src/objects/link/endpoints.ts +2 -1
  209. package/src/objects/query/executor.ts +42 -11
  210. package/src/objects/query/explain.ts +11 -0
  211. package/src/objects/query/index.ts +6 -0
  212. package/src/objects/query/ir.ts +16 -0
  213. package/src/objects/query/links.ts +308 -0
  214. package/src/objects/query/normalize.ts +40 -1
  215. package/src/objects/query/planner.ts +5 -0
  216. package/src/objects/query/validate.ts +58 -2
  217. package/src/ontology/internal.ts +1 -1
  218. package/src/ontology/json-schema.ts +27 -5
  219. package/src/projections/builders.ts +220 -15
  220. package/src/projections/index.ts +1 -0
  221. package/src/projections/ownership.ts +5 -5
  222. package/src/projections/registry.ts +9 -3
  223. package/src/projections/revision.ts +31 -5
  224. package/src/projections/run-dispatch.ts +10 -1
  225. package/src/projections/types.ts +13 -9
  226. package/src/projections/validation.ts +61 -19
  227. package/src/query.ts +2 -0
  228. package/src/runtime/create.ts +4 -0
  229. package/src/runtime/definitions.ts +3 -0
  230. package/src/runtime/host.ts +2 -0
  231. package/src/runtime/resolve-definitions.ts +28 -0
  232. package/src/storage/agents/in-memory.ts +15 -0
  233. package/src/storage/agents/types.ts +5 -0
  234. package/src/storage/ai-usage/in-memory.ts +23 -0
  235. package/src/storage/ai-usage/index.ts +1 -0
  236. package/src/storage/ai-usage/types.ts +10 -0
  237. package/src/storage/index.ts +11 -0
  238. package/src/storage/objects/in-memory.ts +103 -16
  239. package/src/storage/objects/index.ts +9 -0
  240. package/src/storage/objects/keys.ts +36 -0
  241. package/src/storage/objects/types.ts +34 -6
  242. package/src/storage/ontology/provider-header-validation.ts +2 -2
  243. package/src/storage/timeseries/store.ts +6 -6
  244. package/src/testing/agent-storage-contract.ts +12 -0
  245. package/src/testing/ai-usage-storage-contract.ts +35 -0
  246. package/src/testing/effective-storage-contract.ts +194 -4
  247. package/src/testing/lake-storage-contract.ts +56 -0
  248. package/src/testing/object-query-contract.ts +208 -1
  249. package/dist/agents/prompt.d.ts +0 -21
  250. package/dist/agents/prompt.d.ts.map +0 -1
  251. package/dist/chunk-4z3n1dzt.js.map +0 -23
  252. package/dist/chunk-6wetht33.js +0 -89
  253. package/dist/chunk-6wetht33.js.map +0 -10
  254. package/dist/chunk-88ppkr54.js.map +0 -12
  255. package/dist/chunk-f1cyvnrk.js.map +0 -13
  256. package/dist/chunk-ttba8x6z.js.map +0 -15
  257. package/dist/chunk-wb4051cx.js.map +0 -12
  258. package/dist/chunk-zpw39qhj.js.map +0 -10
  259. package/src/agents/prompt.ts +0 -85
  260. /package/dist/{chunk-c6cfqydk.js.map → chunk-4h947jd8.js.map} +0 -0
  261. /package/dist/{chunk-gqdd7508.js.map → chunk-4rh2m6zg.js.map} +0 -0
  262. /package/dist/{chunk-pxtrxm3p.js.map → chunk-a09jx26t.js.map} +0 -0
  263. /package/dist/{chunk-4p9rh7jj.js.map → chunk-ea73pzk7.js.map} +0 -0
  264. /package/dist/{chunk-4aw0jwk0.js.map → chunk-f6erf2vv.js.map} +0 -0
  265. /package/dist/{chunk-c8bw2b6c.js.map → chunk-gadsm794.js.map} +0 -0
  266. /package/dist/{chunk-n5x5y80a.js.map → chunk-nzw7sm3b.js.map} +0 -0
  267. /package/dist/{chunk-261ag4t4.js.map → chunk-r0rry8dn.js.map} +0 -0
  268. /package/dist/{chunk-d2adj15j.js.map → chunk-tkdscva6.js.map} +0 -0
  269. /package/dist/{chunk-z8j83gzd.js.map → chunk-x2yw73hy.js.map} +0 -0
  270. /package/dist/{chunk-qer6am8w.js.map → chunk-xdf9yswn.js.map} +0 -0
  271. /package/dist/{chunk-km4rkj4t.js.map → chunk-zp2v2rv6.js.map} +0 -0
@@ -0,0 +1,261 @@
1
+ import { stableJsonStringify } from "../json"
2
+ import type { AgentMessageRecord } from "../storage/agents/types"
3
+ import type { AgentMessage, AgentMessagePart } from "./message"
4
+
5
+ export const AGENT_CONTEXT_ESTIMATOR_VERSION = 1 as const
6
+
7
+ const CHARS_PER_TOKEN = 4
8
+ const REQUEST_OVERHEAD_TOKENS = 8
9
+ const MESSAGE_OVERHEAD_TOKENS = 8
10
+ const TOOL_OVERHEAD_TOKENS = 16
11
+ const STEP_OVERHEAD_TOKENS = 2
12
+ const IMAGE_ALLOWANCE_TOKENS = 1_200
13
+ const FILE_TEXT_INLINE_MAX_BYTES = 50 * 1024
14
+ const FILE_TEXT_INLINE_TOTAL_MAX_BYTES = 200 * 1024
15
+ const TOOL_RESULT_SUMMARY_MAX_CHARS = 2_000
16
+
17
+ export interface AgentContextEstimateTool {
18
+ readonly name: string
19
+ readonly description: string
20
+ /** Deterministic JSON-schema serialization sent for this tool. */
21
+ readonly inputSchema: string
22
+ }
23
+
24
+ export interface EstimateAgentContextRequestTokensInput {
25
+ readonly systemPrompt: string
26
+ readonly tools: readonly AgentContextEstimateTool[]
27
+ readonly messages: readonly AgentMessage[]
28
+ }
29
+
30
+ export interface AgentContextTokenEstimate {
31
+ readonly tokens: number
32
+ readonly estimatorVersion: typeof AGENT_CONTEXT_ESTIMATOR_VERSION
33
+ }
34
+
35
+ export interface AgentContextCompactionBoundary {
36
+ readonly messagesToSummarize: readonly AgentMessageRecord[]
37
+ readonly retainedMessages: readonly AgentMessageRecord[]
38
+ readonly summarizedThroughSeq: number
39
+ }
40
+
41
+ /** Compaction begins only once the estimated request crosses the reserved input budget. */
42
+ export function shouldCompactAgentContext(input: {
43
+ readonly estimatedInputTokens: number
44
+ readonly inputBudgetTokens: number
45
+ }): boolean {
46
+ return input.estimatedInputTokens > input.inputBudgetTokens
47
+ }
48
+
49
+ /** Estimate the provider request shape with one stable, conservative character heuristic. */
50
+ export function estimateAgentContextRequestTokens(
51
+ input: EstimateAgentContextRequestTokensInput
52
+ ): AgentContextTokenEstimate {
53
+ const toolTokens = input.tools.reduce(
54
+ (total, tool) =>
55
+ total +
56
+ TOOL_OVERHEAD_TOKENS +
57
+ textTokens(tool.name) +
58
+ textTokens(tool.description) +
59
+ textTokens(tool.inputSchema),
60
+ 0
61
+ )
62
+ return {
63
+ tokens:
64
+ REQUEST_OVERHEAD_TOKENS +
65
+ textTokens(input.systemPrompt) +
66
+ toolTokens +
67
+ estimateAgentContextMessagesTokens(input.messages).tokens,
68
+ estimatorVersion: AGENT_CONTEXT_ESTIMATOR_VERSION,
69
+ }
70
+ }
71
+
72
+ /** Estimate message-only growth after a provider-usage anchor. */
73
+ export function estimateAgentContextMessagesTokens(
74
+ messages: readonly AgentMessage[]
75
+ ): AgentContextTokenEstimate {
76
+ const attachments = { textBytesRemaining: FILE_TEXT_INLINE_TOTAL_MAX_BYTES }
77
+ let tokens = 0
78
+ for (const message of messages) {
79
+ tokens += estimateMessageTokens(message, attachments)
80
+ }
81
+ return { tokens, estimatorVersion: AGENT_CONTEXT_ESTIMATOR_VERSION }
82
+ }
83
+
84
+ /** Select the safe user boundary whose retained tail is closest to the configured recent budget. */
85
+ export function selectAgentContextCompactionBoundary(input: {
86
+ readonly messages: readonly AgentMessageRecord[]
87
+ readonly keepRecentTokens: number
88
+ }): AgentContextCompactionBoundary | null {
89
+ if (input.messages.length < 2) return null
90
+
91
+ let retainedTokens = 0
92
+ let boundaryIndex: number | null = null
93
+ let closestDistance = Number.POSITIVE_INFINITY
94
+ for (let index = input.messages.length - 1; index > 0; index -= 1) {
95
+ retainedTokens += estimateAgentContextMessagesTokens([input.messages[index]!]).tokens
96
+ if (input.messages[index]?.role !== "user") continue
97
+
98
+ const distance = Math.abs(input.keepRecentTokens - retainedTokens)
99
+ if (distance <= closestDistance) {
100
+ boundaryIndex = index
101
+ closestDistance = distance
102
+ }
103
+ if (retainedTokens >= input.keepRecentTokens) break
104
+ }
105
+
106
+ if (boundaryIndex === null) return null
107
+
108
+ const summarizedThroughSeq = input.messages[boundaryIndex - 1]?.seq
109
+ if (summarizedThroughSeq === undefined) return null
110
+ return {
111
+ messagesToSummarize: input.messages.slice(0, boundaryIndex),
112
+ retainedMessages: input.messages.slice(boundaryIndex),
113
+ summarizedThroughSeq,
114
+ }
115
+ }
116
+
117
+ /** Serialize durable conversation content as escaped quoted data for the summary model. */
118
+ export function serializeAgentMessagesForSummary(messages: readonly AgentMessageRecord[]): string {
119
+ const lines = ["<sixb_conversation_history>"]
120
+ for (const message of messages) {
121
+ lines.push(
122
+ ` <message id="${escapeXml(message.id)}" seq="${message.seq}" role="${message.role}">`
123
+ )
124
+ message.parts.forEach((part, partIndex) => {
125
+ lines.push(...serializeSummaryPart(message, part, partIndex))
126
+ })
127
+ lines.push(" </message>")
128
+ }
129
+ lines.push("</sixb_conversation_history>")
130
+ return lines.join("\n")
131
+ }
132
+
133
+ function estimateMessageTokens(
134
+ message: AgentMessage,
135
+ attachments: { textBytesRemaining: number }
136
+ ): number {
137
+ let tokens = MESSAGE_OVERHEAD_TOKENS
138
+ for (const part of message.parts) {
139
+ switch (part.type) {
140
+ case "text":
141
+ case "reasoning":
142
+ tokens += textTokens(part.text)
143
+ break
144
+ case "step-start":
145
+ tokens += STEP_OVERHEAD_TOKENS
146
+ break
147
+ case "context":
148
+ tokens += textTokens(stableJsonStringify(part.context))
149
+ break
150
+ case "tool-call":
151
+ tokens +=
152
+ TOOL_OVERHEAD_TOKENS +
153
+ textTokens(part.toolName) +
154
+ textTokens(stableJsonStringify(part.input)) +
155
+ (part.state === "output-available"
156
+ ? textTokens(stableJsonStringify(part.output))
157
+ : textTokens(part.errorText))
158
+ break
159
+ case "file": {
160
+ const file = part.fileRef
161
+ tokens += textTokens(
162
+ [file.blobId, file.digest, file.fileName, file.mediaType, file.logicalPath]
163
+ .filter((value): value is string => value !== undefined)
164
+ .join(" ")
165
+ )
166
+ if (message.role !== "assistant") {
167
+ if (looksLikeImage(file.mediaType, file.fileName)) {
168
+ tokens += IMAGE_ALLOWANCE_TOKENS
169
+ } else {
170
+ const inlineBytes = Math.min(
171
+ file.sizeBytes,
172
+ FILE_TEXT_INLINE_MAX_BYTES,
173
+ attachments.textBytesRemaining
174
+ )
175
+ attachments.textBytesRemaining -= inlineBytes
176
+ tokens += Math.ceil(inlineBytes / CHARS_PER_TOKEN)
177
+ }
178
+ }
179
+ break
180
+ }
181
+ }
182
+ }
183
+ return tokens
184
+ }
185
+
186
+ function serializeSummaryPart(
187
+ message: AgentMessageRecord,
188
+ part: AgentMessagePart,
189
+ partIndex: number
190
+ ): string[] {
191
+ const indent = " "
192
+ switch (part.type) {
193
+ case "text":
194
+ return [`${indent}<text>${escapeXml(part.text)}</text>`]
195
+ case "reasoning":
196
+ case "step-start":
197
+ return []
198
+ case "context":
199
+ return part.context.kind === "object"
200
+ ? [
201
+ `${indent}<object_context origin="${part.origin}" object_type_id="${escapeXml(part.context.ref.objectTypeId)}" primary_id="${escapeXml(part.context.ref.primaryId)}" />`,
202
+ ]
203
+ : [
204
+ `${indent}<app_context origin="${part.origin}" id="${escapeXml(part.context.id)}" label="${escapeXml(part.context.label)}">`,
205
+ `${indent} <description>${escapeXml(part.context.description)}</description>`,
206
+ `${indent} <value format="json">${escapeXml(stableJsonStringify(part.context.value))}</value>`,
207
+ `${indent}</app_context>`,
208
+ ]
209
+ case "file": {
210
+ const file = part.fileRef
211
+ const attributes = [
212
+ `message_id="${escapeXml(message.id)}"`,
213
+ `part_index="${partIndex}"`,
214
+ `blob_id="${escapeXml(file.blobId)}"`,
215
+ `digest="${escapeXml(file.digest)}"`,
216
+ `size_bytes="${file.sizeBytes}"`,
217
+ ...(file.fileName === undefined ? [] : [`file_name="${escapeXml(file.fileName)}"`]),
218
+ ...(file.mediaType === undefined ? [] : [`media_type="${escapeXml(file.mediaType)}"`]),
219
+ ...(file.logicalPath === undefined
220
+ ? []
221
+ : [`logical_path="${escapeXml(file.logicalPath)}"`]),
222
+ ]
223
+ return [`${indent}<file ${attributes.join(" ")} />`]
224
+ }
225
+ case "tool-call": {
226
+ const output =
227
+ part.state === "output-available"
228
+ ? truncateToolResult(stableJsonStringify(part.output))
229
+ : truncateToolResult(part.errorText)
230
+ return [
231
+ `${indent}<tool_call id="${escapeXml(part.toolCallId)}" name="${escapeXml(part.toolName)}" state="${part.state}">`,
232
+ `${indent} <input format="json">${escapeXml(stableJsonStringify(part.input))}</input>`,
233
+ `${indent} <result>${escapeXml(output)}</result>`,
234
+ `${indent}</tool_call>`,
235
+ ]
236
+ }
237
+ }
238
+ }
239
+
240
+ function truncateToolResult(value: string): string {
241
+ if (value.length <= TOOL_RESULT_SUMMARY_MAX_CHARS) return value
242
+ return `${value.slice(0, TOOL_RESULT_SUMMARY_MAX_CHARS)}\n[truncated ${value.length - TOOL_RESULT_SUMMARY_MAX_CHARS} characters]`
243
+ }
244
+
245
+ function looksLikeImage(mediaType: string | undefined, fileName: string | undefined): boolean {
246
+ if (mediaType?.toLowerCase().startsWith("image/")) return true
247
+ return /\.(?:avif|gif|jpe?g|png|webp)$/i.test(fileName ?? "")
248
+ }
249
+
250
+ function textTokens(value: string): number {
251
+ return Math.ceil(new TextEncoder().encode(value).byteLength / CHARS_PER_TOKEN)
252
+ }
253
+
254
+ function escapeXml(value: string): string {
255
+ return value
256
+ .replaceAll("&", "&amp;")
257
+ .replaceAll("<", "&lt;")
258
+ .replaceAll(">", "&gt;")
259
+ .replaceAll('"', "&quot;")
260
+ .replaceAll("'", "&apos;")
261
+ }
package/src/agents/ids.ts CHANGED
@@ -18,6 +18,11 @@ export function createAgentMessageId(): string {
18
18
  return `agt_msg_${randomUUID()}`
19
19
  }
20
20
 
21
+ /** One deterministic context-checkpoint identity per conversational run. */
22
+ export function agentContextCheckpointId(runId: string): string {
23
+ return `agt_ctx_${runId}`
24
+ }
25
+
21
26
  /** A queue delivery's fencing token for writes to an `agent_runs` record. */
22
27
  export function createAgentRunExecutionToken(): string {
23
28
  return `agt_exec_${randomUUID()}`
@@ -53,6 +53,20 @@ export {
53
53
  MAX_AGENT_CONTEXT_ENTRIES,
54
54
  normalizeAgentContextEntries,
55
55
  } from "./context"
56
+ export type {
57
+ AgentContextCompactionBoundary,
58
+ AgentContextEstimateTool,
59
+ AgentContextTokenEstimate,
60
+ EstimateAgentContextRequestTokensInput,
61
+ } from "./context-compaction"
62
+ export {
63
+ AGENT_CONTEXT_ESTIMATOR_VERSION,
64
+ estimateAgentContextMessagesTokens,
65
+ estimateAgentContextRequestTokens,
66
+ selectAgentContextCompactionBoundary,
67
+ serializeAgentMessagesForSummary,
68
+ shouldCompactAgentContext,
69
+ } from "./context-compaction"
56
70
  export { serializeAgentContextForModel } from "./context-model"
57
71
  export { resolveAgentContextParts } from "./context-resolution"
58
72
  export type {
@@ -75,6 +89,7 @@ export {
75
89
  AgentToolResultValidationError,
76
90
  } from "./errors"
77
91
  export {
92
+ agentContextCheckpointId,
78
93
  createAgentMessageId,
79
94
  createAgentRunExecutionToken,
80
95
  createAgentRunId,
@@ -93,15 +108,6 @@ export {
93
108
  type AgentToolCallPart,
94
109
  type AgentToolCallState,
95
110
  } from "./message"
96
- export {
97
- type BuildAgentSystemPromptInput,
98
- type BuildWorkflowOutputFinalizerPromptInput,
99
- buildAgentSystemPrompt,
100
- buildWorkflowOutputFinalizerPrompt,
101
- DEFAULT_AGENT_SYSTEM_CONTEXT,
102
- DEFAULT_AGENT_WORKFLOW_SYSTEM_CONTEXT,
103
- DEFAULT_WORKFLOW_OUTPUT_FINALIZER_SYSTEM_CONTEXT,
104
- } from "./prompt"
105
111
  export {
106
112
  type RequestAgentRunInput,
107
113
  type RequestAgentRunResult,
@@ -109,6 +115,7 @@ export {
109
115
  retryAgentRun,
110
116
  } from "./request"
111
117
  export type {
118
+ AgentCompactionFailureCode,
112
119
  AgentRunControlStreamId,
113
120
  AgentRunFailure,
114
121
  AgentRunFinishedEvent,
@@ -116,6 +123,7 @@ export type {
116
123
  AgentRunStreamId,
117
124
  } from "./streams"
118
125
  export {
126
+ AGENT_COMPACTION_FAILURE_CODES,
119
127
  AGENT_RUN_CANCEL_RECORD,
120
128
  AGENT_RUN_STREAM_SCHEMA_VERSION,
121
129
  agentRunControlStreamDefinition,
@@ -137,6 +145,7 @@ export type {
137
145
  export { projectAgentThreadModelContext } from "./thread-context-projection"
138
146
  export { isAgentToolResult } from "./tool-result"
139
147
  export type {
148
+ AgentContextConfig,
140
149
  AgentDefinition,
141
150
  AgentLoopConfig,
142
151
  AgentReasoningLevel,
@@ -4,6 +4,7 @@ import type { SixbFailure } from "../errors/types"
4
4
  import { isJsonValue, isPlainRecord, type JsonValue } from "../json"
5
5
  import {
6
6
  AGENT_RUN_FAILURE_CODES,
7
+ type AgentContextCheckpointReason,
7
8
  type AgentRunFailureCode,
8
9
  type AgentRunRecord,
9
10
  } from "../storage/agents/types"
@@ -189,11 +190,35 @@ export async function subscribeAgentRunCancel(
189
190
  /** Exact portable failure exposed by a terminal Agent run stream event. */
190
191
  export type AgentRunFailure = SixbFailure<AgentRunFailureCode>
191
192
 
193
+ export const AGENT_COMPACTION_FAILURE_CODES = [
194
+ "context_limit_exceeded",
195
+ "summary_failed",
196
+ "checkpoint_failed",
197
+ ] as const
198
+ export type AgentCompactionFailureCode = (typeof AGENT_COMPACTION_FAILURE_CODES)[number]
199
+
192
200
  export type AgentRunStreamEvent =
193
201
  | (AgentRunStreamEventBase & {
194
202
  readonly type: "agent.run.started"
195
203
  readonly modelId?: string
196
204
  })
205
+ | (AgentRunStreamEventBase & {
206
+ readonly type: "agent.compaction.started"
207
+ readonly reason: AgentContextCheckpointReason
208
+ readonly estimatedInputTokensBefore: number
209
+ })
210
+ | (AgentRunStreamEventBase & {
211
+ readonly type: "agent.compaction.completed"
212
+ readonly reason: AgentContextCheckpointReason
213
+ readonly checkpointId: string
214
+ readonly estimatedInputTokensBefore: number
215
+ readonly estimatedInputTokensAfter: number
216
+ })
217
+ | (AgentRunStreamEventBase & {
218
+ readonly type: "agent.compaction.failed"
219
+ readonly reason: AgentContextCheckpointReason
220
+ readonly errorCode: AgentCompactionFailureCode
221
+ })
197
222
  | (AgentRunStreamEventBase & {
198
223
  readonly type: "agent.ui.chunk"
199
224
  readonly chunkIndex: number
@@ -263,6 +288,23 @@ export function isAgentRunStreamEvent(value: unknown): value is AgentRunStreamEv
263
288
  switch (value.type) {
264
289
  case "agent.run.started":
265
290
  return value.modelId === undefined || typeof value.modelId === "string"
291
+ case "agent.compaction.started":
292
+ return (
293
+ isAgentContextCheckpointReason(value.reason) &&
294
+ isTokenEstimate(value.estimatedInputTokensBefore)
295
+ )
296
+ case "agent.compaction.completed":
297
+ return (
298
+ isAgentContextCheckpointReason(value.reason) &&
299
+ typeof value.checkpointId === "string" &&
300
+ isTokenEstimate(value.estimatedInputTokensBefore) &&
301
+ isTokenEstimate(value.estimatedInputTokensAfter)
302
+ )
303
+ case "agent.compaction.failed":
304
+ return (
305
+ isAgentContextCheckpointReason(value.reason) &&
306
+ AGENT_COMPACTION_FAILURE_CODES.includes(value.errorCode as AgentCompactionFailureCode)
307
+ )
266
308
  case "agent.ui.chunk":
267
309
  return (
268
310
  Number.isInteger(value.chunkIndex) &&
@@ -282,6 +324,14 @@ export function isAgentRunStreamEvent(value: unknown): value is AgentRunStreamEv
282
324
  }
283
325
  }
284
326
 
327
+ function isAgentContextCheckpointReason(value: unknown): value is AgentContextCheckpointReason {
328
+ return value === "threshold" || value === "overflow"
329
+ }
330
+
331
+ function isTokenEstimate(value: unknown): value is number {
332
+ return Number.isSafeInteger(value) && (value as number) >= 0
333
+ }
334
+
285
335
  function isTerminalAgentRunStatus(value: unknown): value is "succeeded" | "failed" | "cancelled" {
286
336
  return value === "succeeded" || value === "failed" || value === "cancelled"
287
337
  }
@@ -305,6 +355,12 @@ export function agentRunStreamIdempotencyKey(event: AgentRunStreamEvent): string
305
355
  switch (event.type) {
306
356
  case "agent.run.started":
307
357
  return `${event.runId}:${event.attempt}:started`
358
+ case "agent.compaction.started":
359
+ return `${event.runId}:${event.attempt}:compaction:${event.reason}:started`
360
+ case "agent.compaction.completed":
361
+ return `${event.runId}:${event.attempt}:compaction:${event.checkpointId}:completed`
362
+ case "agent.compaction.failed":
363
+ return `${event.runId}:${event.attempt}:compaction:${event.reason}:failed:${event.errorCode}`
308
364
  case "agent.ui.chunk":
309
365
  return `${event.runId}:${event.attempt}:chunk:${event.chunkIndex}`
310
366
  case "agent.message.finalized":
@@ -26,6 +26,15 @@ export const AGENT_REASONING_LEVELS = [
26
26
  "xhigh",
27
27
  ] as const satisfies readonly AgentReasoningLevel[]
28
28
 
29
+ export interface AgentContextConfig {
30
+ /** Override the provider context-window size inferred by the agent worker. */
31
+ readonly windowTokens?: number
32
+ /** Tokens reserved for the next response and compaction work. */
33
+ readonly reserveTokens?: number
34
+ /** Approximate recent-message budget retained verbatim after compaction. */
35
+ readonly keepRecentTokens?: number
36
+ }
37
+
29
38
  /**
30
39
  * Loop / stop controls for an agent run.
31
40
  *
@@ -35,6 +44,9 @@ export interface AgentLoopConfig {
35
44
  readonly stopWhen?: {
36
45
  readonly maxSteps?: number
37
46
  }
47
+ readonly context?: AgentContextConfig
48
+ /** Automatic provider prompt caching. Defaults to `auto`; use `off` to opt out. */
49
+ readonly caching?: "auto" | "off"
38
50
  }
39
51
 
40
52
  type Simplify<T> = { [K in keyof T]: T[K] } & {}
@@ -10,6 +10,7 @@ import type { GroupDefinition, SecurityDefinitionCatalog } from "../security"
10
10
  import { AgentDefinitionError } from "./errors"
11
11
  import {
12
12
  AGENT_REASONING_LEVELS,
13
+ type AgentContextConfig,
13
14
  type AgentDefinition,
14
15
  type AgentLoopConfig,
15
16
  type AgentReasoningLevel,
@@ -159,14 +160,47 @@ export function validateAgentToolsAtStartup(agents: readonly AgentDefinition[]):
159
160
  }
160
161
  }
161
162
 
162
- export function assertValidLoopConfig(loop: AgentLoopConfig | undefined): void {
163
+ export function resolveAgentLoopConfig(
164
+ loop: AgentLoopConfig | undefined
165
+ ): AgentLoopConfig | undefined {
166
+ if (loop === undefined) return undefined
167
+
163
168
  const maxSteps = loop?.stopWhen?.maxSteps
164
- if (maxSteps === undefined) {
165
- return
169
+ if (maxSteps !== undefined && (!Number.isSafeInteger(maxSteps) || maxSteps <= 0)) {
170
+ throw new AgentDefinitionError(
171
+ "[Sixb] Agent loop.stopWhen.maxSteps must be a positive safe integer."
172
+ )
166
173
  }
167
- if (!Number.isInteger(maxSteps) || maxSteps <= 0) {
174
+ if (loop.caching !== undefined && loop.caching !== "auto" && loop.caching !== "off") {
175
+ throw new AgentDefinitionError("[Sixb] Agent loop.caching must be 'auto' or 'off'.")
176
+ }
177
+
178
+ const context = loop.context ? snapshotAgentContextConfig(loop.context) : undefined
179
+ return Object.freeze({
180
+ ...(loop.stopWhen === undefined
181
+ ? {}
182
+ : { stopWhen: Object.freeze({ ...(maxSteps === undefined ? {} : { maxSteps }) }) }),
183
+ ...(context === undefined ? {} : { context }),
184
+ ...(loop.caching === undefined ? {} : { caching: loop.caching }),
185
+ })
186
+ }
187
+
188
+ function snapshotAgentContextConfig(context: AgentContextConfig): AgentContextConfig {
189
+ const snapshot: Record<string, number> = {}
190
+ for (const field of ["windowTokens", "reserveTokens", "keepRecentTokens"] as const) {
191
+ const value = context[field]
192
+ if (value === undefined) continue
193
+ assertPositiveSafeInteger(value, field)
194
+ snapshot[field] = value
195
+ }
196
+
197
+ return Object.freeze(snapshot)
198
+ }
199
+
200
+ function assertPositiveSafeInteger(value: unknown, field: string): asserts value is number {
201
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) {
168
202
  throw new AgentDefinitionError(
169
- "[Sixb] Agent loop.stopWhen.maxSteps must be a positive finite integer."
203
+ `[Sixb] Agent loop.context.${field} must be a positive safe integer.`
170
204
  )
171
205
  }
172
206
  }
@@ -131,6 +131,13 @@ export const SIXB_API_ROUTES: readonly SixbApiRoute[] = [
131
131
  accessToken: true,
132
132
  agentApi: true,
133
133
  },
134
+ {
135
+ operationId: "queryObjectLinks",
136
+ method: "POST",
137
+ path: "/api/objects/query/links",
138
+ accessToken: true,
139
+ agentApi: true,
140
+ },
134
141
  {
135
142
  operationId: "countObjects",
136
143
  method: "POST",
@@ -159,13 +166,6 @@ export const SIXB_API_ROUTES: readonly SixbApiRoute[] = [
159
166
  accessToken: true,
160
167
  agentApi: true,
161
168
  },
162
- {
163
- operationId: "listObjectLinks",
164
- method: "GET",
165
- path: "/api/objects/:objectTypeId/:objectId/links",
166
- accessToken: true,
167
- agentApi: true,
168
- },
169
169
  // The four write routes. Bearer-capable because their execution facade enforces authorization
170
170
  // (`edit:object` / `append:telemetry`), which is exactly the precondition this table requires.
171
171
  // NOT agent-proxied: letting an agent turn write objects on its own is a separate decision, and
package/src/index.ts CHANGED
@@ -77,7 +77,12 @@ export type {
77
77
  ActionRuntimeFacade,
78
78
  ActionSubject,
79
79
  ActionTargetObject,
80
+ ActionTelemetryHistoryBatchInput,
81
+ ActionTelemetryHistoryBatchResult,
82
+ ActionTelemetryHistorySeriesInput,
80
83
  ActionTelemetryObjectSet,
84
+ ActionTelemetryPropertyToken,
85
+ ActionTelemetryReadFacade,
81
86
  ActionValidationContext,
82
87
  ActionValidator,
83
88
  ActionWritebackContext,
@@ -574,6 +579,7 @@ export type {
574
579
  ObjectQueryPredicateIn,
575
580
  ObjectQueryPredicateNot,
576
581
  ObjectQueryProject,
582
+ ObjectQueryRefs,
577
583
  ObjectQueryResultShape,
578
584
  ObjectQuerySet,
579
585
  ObjectQuerySetOperation,
@@ -854,6 +860,8 @@ export type {
854
860
  export type {
855
861
  ExecutionObjectByIdHandle,
856
862
  ExecutionObjectSet,
863
+ ObjectQueryLinksInput,
864
+ ObjectQueryLinksResult,
857
865
  ObjectsRuntime,
858
866
  } from "./objects/execution"
859
867
  export type { PipelineRunsRuntime, PipelinesRuntime } from "./pipelines/execution"
@@ -941,6 +949,7 @@ export type {
941
949
  // ── Agents ──────────────────────────────────────────────────
942
950
 
943
951
  export type {
952
+ AgentContextConfig,
944
953
  AgentContextEntryInput,
945
954
  AgentContextInput,
946
955
  AgentContextOrigin,
@@ -1013,6 +1022,15 @@ export {
1013
1022
  requestAgentRun,
1014
1023
  } from "./agents"
1015
1024
 
1025
+ // ── Models ──────────────────────────────────────────────────
1026
+
1027
+ export type {
1028
+ LanguageModelCatalog,
1029
+ LanguageModelEntry,
1030
+ ModelCatalog,
1031
+ ModelCatalogInput,
1032
+ } from "./models"
1033
+
1016
1034
  // ── Scheduling ──────────────────────────────────────────────
1017
1035
 
1018
1036
  export { CronValidationError } from "./schedules"
@@ -1034,6 +1052,7 @@ export type {
1034
1052
  ProjectionTargetByKind,
1035
1053
  SourceEditConflictResolution,
1036
1054
  TelemetryProjectionDefinition,
1055
+ TelemetryProjectionPropertyMapping,
1037
1056
  } from "./projections"
1038
1057
 
1039
1058
  export {
@@ -84,7 +84,8 @@ export interface DatasetWriteCommitResult extends DatasetVersion {
84
84
  * report `unchanged` and reuse it for commits that cannot change visible
85
85
  * dataset content: a snapshot whose rows equal the latest visible rows
86
86
  * (order-insensitive, with equal duplicate counts), or an append of zero
87
- * rows.
87
+ * rows. Without a latest version, an empty snapshot or append still creates
88
+ * the first addressable dataset version.
88
89
  */
89
90
  readonly outcome: "created" | "unchanged"
90
91
  }