@diyor28/context 1.0.0

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 (280) hide show
  1. package/README.md +270 -0
  2. package/dist/__tests__/attachment-selector.test.d.ts +11 -0
  3. package/dist/__tests__/attachment-selector.test.d.ts.map +1 -0
  4. package/dist/__tests__/attachment-selector.test.js +449 -0
  5. package/dist/__tests__/attachment-selector.test.js.map +1 -0
  6. package/dist/__tests__/cache-breakpoints.test.d.ts +11 -0
  7. package/dist/__tests__/cache-breakpoints.test.d.ts.map +1 -0
  8. package/dist/__tests__/cache-breakpoints.test.js +398 -0
  9. package/dist/__tests__/cache-breakpoints.test.js.map +1 -0
  10. package/dist/__tests__/codecs.test.d.ts +7 -0
  11. package/dist/__tests__/codecs.test.d.ts.map +1 -0
  12. package/dist/__tests__/codecs.test.js +331 -0
  13. package/dist/__tests__/codecs.test.js.map +1 -0
  14. package/dist/__tests__/compactor.test.d.ts +11 -0
  15. package/dist/__tests__/compactor.test.d.ts.map +1 -0
  16. package/dist/__tests__/compactor.test.js +519 -0
  17. package/dist/__tests__/compactor.test.js.map +1 -0
  18. package/dist/__tests__/context-graph.test.d.ts +7 -0
  19. package/dist/__tests__/context-graph.test.d.ts.map +1 -0
  20. package/dist/__tests__/context-graph.test.js +262 -0
  21. package/dist/__tests__/context-graph.test.js.map +1 -0
  22. package/dist/__tests__/hash.test.d.ts +7 -0
  23. package/dist/__tests__/hash.test.d.ts.map +1 -0
  24. package/dist/__tests__/hash.test.js +228 -0
  25. package/dist/__tests__/hash.test.js.map +1 -0
  26. package/dist/__tests__/integration.test.d.ts +15 -0
  27. package/dist/__tests__/integration.test.d.ts.map +1 -0
  28. package/dist/__tests__/integration.test.js +728 -0
  29. package/dist/__tests__/integration.test.js.map +1 -0
  30. package/dist/__tests__/kind-order.test.d.ts +7 -0
  31. package/dist/__tests__/kind-order.test.d.ts.map +1 -0
  32. package/dist/__tests__/kind-order.test.js +243 -0
  33. package/dist/__tests__/kind-order.test.js.map +1 -0
  34. package/dist/__tests__/phase2-integration.test.d.ts +5 -0
  35. package/dist/__tests__/phase2-integration.test.d.ts.map +1 -0
  36. package/dist/__tests__/phase2-integration.test.js +222 -0
  37. package/dist/__tests__/phase2-integration.test.js.map +1 -0
  38. package/dist/__tests__/queries.test.d.ts +7 -0
  39. package/dist/__tests__/queries.test.d.ts.map +1 -0
  40. package/dist/__tests__/queries.test.js +254 -0
  41. package/dist/__tests__/queries.test.js.map +1 -0
  42. package/dist/__tests__/token-estimator.test.d.ts +7 -0
  43. package/dist/__tests__/token-estimator.test.d.ts.map +1 -0
  44. package/dist/__tests__/token-estimator.test.js +267 -0
  45. package/dist/__tests__/token-estimator.test.js.map +1 -0
  46. package/dist/adapters/anthropic-estimator.d.ts +38 -0
  47. package/dist/adapters/anthropic-estimator.d.ts.map +1 -0
  48. package/dist/adapters/anthropic-estimator.js +108 -0
  49. package/dist/adapters/anthropic-estimator.js.map +1 -0
  50. package/dist/adapters/attachment-resolver.d.ts +96 -0
  51. package/dist/adapters/attachment-resolver.d.ts.map +1 -0
  52. package/dist/adapters/attachment-resolver.js +176 -0
  53. package/dist/adapters/attachment-resolver.js.map +1 -0
  54. package/dist/adapters/attachment-selector.d.ts +59 -0
  55. package/dist/adapters/attachment-selector.d.ts.map +1 -0
  56. package/dist/adapters/attachment-selector.js +163 -0
  57. package/dist/adapters/attachment-selector.js.map +1 -0
  58. package/dist/adapters/gemini-estimator.d.ts +27 -0
  59. package/dist/adapters/gemini-estimator.d.ts.map +1 -0
  60. package/dist/adapters/gemini-estimator.js +80 -0
  61. package/dist/adapters/gemini-estimator.js.map +1 -0
  62. package/dist/adapters/index.d.ts +12 -0
  63. package/dist/adapters/index.d.ts.map +1 -0
  64. package/dist/adapters/index.js +28 -0
  65. package/dist/adapters/index.js.map +1 -0
  66. package/dist/adapters/memory-store.d.ts +139 -0
  67. package/dist/adapters/memory-store.d.ts.map +1 -0
  68. package/dist/adapters/memory-store.js +187 -0
  69. package/dist/adapters/memory-store.js.map +1 -0
  70. package/dist/adapters/openai-estimator.d.ts +35 -0
  71. package/dist/adapters/openai-estimator.d.ts.map +1 -0
  72. package/dist/adapters/openai-estimator.js +89 -0
  73. package/dist/adapters/openai-estimator.js.map +1 -0
  74. package/dist/adapters/summarizer.d.ts +121 -0
  75. package/dist/adapters/summarizer.d.ts.map +1 -0
  76. package/dist/adapters/summarizer.js +121 -0
  77. package/dist/adapters/summarizer.js.map +1 -0
  78. package/dist/adapters/token-estimator.d.ts +63 -0
  79. package/dist/adapters/token-estimator.d.ts.map +1 -0
  80. package/dist/adapters/token-estimator.js +37 -0
  81. package/dist/adapters/token-estimator.js.map +1 -0
  82. package/dist/builder/context-builder.d.ts +186 -0
  83. package/dist/builder/context-builder.d.ts.map +1 -0
  84. package/dist/builder/context-builder.js +305 -0
  85. package/dist/builder/context-builder.js.map +1 -0
  86. package/dist/builder/context-fork.d.ts +166 -0
  87. package/dist/builder/context-fork.d.ts.map +1 -0
  88. package/dist/builder/context-fork.js +282 -0
  89. package/dist/builder/context-fork.js.map +1 -0
  90. package/dist/builder/index.d.ts +6 -0
  91. package/dist/builder/index.d.ts.map +1 -0
  92. package/dist/builder/index.js +22 -0
  93. package/dist/builder/index.js.map +1 -0
  94. package/dist/codecs/base.d.ts +18 -0
  95. package/dist/codecs/base.d.ts.map +1 -0
  96. package/dist/codecs/base.js +39 -0
  97. package/dist/codecs/base.js.map +1 -0
  98. package/dist/codecs/conversation-history.codec.d.ts +81 -0
  99. package/dist/codecs/conversation-history.codec.d.ts.map +1 -0
  100. package/dist/codecs/conversation-history.codec.js +89 -0
  101. package/dist/codecs/conversation-history.codec.js.map +1 -0
  102. package/dist/codecs/index.d.ts +31 -0
  103. package/dist/codecs/index.d.ts.map +1 -0
  104. package/dist/codecs/index.js +71 -0
  105. package/dist/codecs/index.js.map +1 -0
  106. package/dist/codecs/redacted-stub.codec.d.ts +32 -0
  107. package/dist/codecs/redacted-stub.codec.d.ts.map +1 -0
  108. package/dist/codecs/redacted-stub.codec.js +64 -0
  109. package/dist/codecs/redacted-stub.codec.js.map +1 -0
  110. package/dist/codecs/structured-reference.codec.d.ts +40 -0
  111. package/dist/codecs/structured-reference.codec.d.ts.map +1 -0
  112. package/dist/codecs/structured-reference.codec.js +81 -0
  113. package/dist/codecs/structured-reference.codec.js.map +1 -0
  114. package/dist/codecs/system-rules.codec.d.ts +32 -0
  115. package/dist/codecs/system-rules.codec.d.ts.map +1 -0
  116. package/dist/codecs/system-rules.codec.js +62 -0
  117. package/dist/codecs/system-rules.codec.js.map +1 -0
  118. package/dist/codecs/tool-output.codec.d.ts +66 -0
  119. package/dist/codecs/tool-output.codec.d.ts.map +1 -0
  120. package/dist/codecs/tool-output.codec.js +95 -0
  121. package/dist/codecs/tool-output.codec.js.map +1 -0
  122. package/dist/codecs/tool-schema.codec.d.ts +36 -0
  123. package/dist/codecs/tool-schema.codec.d.ts.map +1 -0
  124. package/dist/codecs/tool-schema.codec.js +74 -0
  125. package/dist/codecs/tool-schema.codec.js.map +1 -0
  126. package/dist/codecs/unsafe-text.codec.d.ts +28 -0
  127. package/dist/codecs/unsafe-text.codec.d.ts.map +1 -0
  128. package/dist/codecs/unsafe-text.codec.js +63 -0
  129. package/dist/codecs/unsafe-text.codec.js.map +1 -0
  130. package/dist/graph/context-graph.d.ts +121 -0
  131. package/dist/graph/context-graph.d.ts.map +1 -0
  132. package/dist/graph/context-graph.js +166 -0
  133. package/dist/graph/context-graph.js.map +1 -0
  134. package/dist/graph/index.d.ts +8 -0
  135. package/dist/graph/index.d.ts.map +1 -0
  136. package/dist/graph/index.js +24 -0
  137. package/dist/graph/index.js.map +1 -0
  138. package/dist/graph/kind-order.d.ts +60 -0
  139. package/dist/graph/kind-order.d.ts.map +1 -0
  140. package/dist/graph/kind-order.js +113 -0
  141. package/dist/graph/kind-order.js.map +1 -0
  142. package/dist/graph/queries.d.ts +68 -0
  143. package/dist/graph/queries.d.ts.map +1 -0
  144. package/dist/graph/queries.js +240 -0
  145. package/dist/graph/queries.js.map +1 -0
  146. package/dist/graph/views.d.ts +90 -0
  147. package/dist/graph/views.d.ts.map +1 -0
  148. package/dist/graph/views.js +173 -0
  149. package/dist/graph/views.js.map +1 -0
  150. package/dist/index.d.ts +16 -0
  151. package/dist/index.d.ts.map +1 -0
  152. package/dist/index.js +40 -0
  153. package/dist/index.js.map +1 -0
  154. package/dist/pipeline/compactor.d.ts +128 -0
  155. package/dist/pipeline/compactor.d.ts.map +1 -0
  156. package/dist/pipeline/compactor.js +346 -0
  157. package/dist/pipeline/compactor.js.map +1 -0
  158. package/dist/pipeline/index.d.ts +6 -0
  159. package/dist/pipeline/index.d.ts.map +1 -0
  160. package/dist/pipeline/index.js +22 -0
  161. package/dist/pipeline/index.js.map +1 -0
  162. package/dist/pipeline/summarizer.d.ts +18 -0
  163. package/dist/pipeline/summarizer.d.ts.map +1 -0
  164. package/dist/pipeline/summarizer.js +68 -0
  165. package/dist/pipeline/summarizer.js.map +1 -0
  166. package/dist/policies/default-policy.d.ts +29 -0
  167. package/dist/policies/default-policy.d.ts.map +1 -0
  168. package/dist/policies/default-policy.js +58 -0
  169. package/dist/policies/default-policy.js.map +1 -0
  170. package/dist/policies/index.d.ts +5 -0
  171. package/dist/policies/index.d.ts.map +1 -0
  172. package/dist/policies/index.js +21 -0
  173. package/dist/policies/index.js.map +1 -0
  174. package/dist/providers/anthropic-compiler.d.ts +58 -0
  175. package/dist/providers/anthropic-compiler.d.ts.map +1 -0
  176. package/dist/providers/anthropic-compiler.js +182 -0
  177. package/dist/providers/anthropic-compiler.js.map +1 -0
  178. package/dist/providers/capabilities.d.ts +54 -0
  179. package/dist/providers/capabilities.d.ts.map +1 -0
  180. package/dist/providers/capabilities.js +87 -0
  181. package/dist/providers/capabilities.js.map +1 -0
  182. package/dist/providers/gemini-compiler.d.ts +51 -0
  183. package/dist/providers/gemini-compiler.d.ts.map +1 -0
  184. package/dist/providers/gemini-compiler.js +206 -0
  185. package/dist/providers/gemini-compiler.js.map +1 -0
  186. package/dist/providers/index.d.ts +8 -0
  187. package/dist/providers/index.d.ts.map +1 -0
  188. package/dist/providers/index.js +24 -0
  189. package/dist/providers/index.js.map +1 -0
  190. package/dist/providers/openai-compiler.d.ts +46 -0
  191. package/dist/providers/openai-compiler.d.ts.map +1 -0
  192. package/dist/providers/openai-compiler.js +149 -0
  193. package/dist/providers/openai-compiler.js.map +1 -0
  194. package/dist/types/attachment.d.ts +62 -0
  195. package/dist/types/attachment.d.ts.map +1 -0
  196. package/dist/types/attachment.js +6 -0
  197. package/dist/types/attachment.js.map +1 -0
  198. package/dist/types/block.d.ts +61 -0
  199. package/dist/types/block.d.ts.map +1 -0
  200. package/dist/types/block.js +8 -0
  201. package/dist/types/block.js.map +1 -0
  202. package/dist/types/codec.d.ts +58 -0
  203. package/dist/types/codec.d.ts.map +1 -0
  204. package/dist/types/codec.js +6 -0
  205. package/dist/types/codec.js.map +1 -0
  206. package/dist/types/compiled.d.ts +91 -0
  207. package/dist/types/compiled.d.ts.map +1 -0
  208. package/dist/types/compiled.js +6 -0
  209. package/dist/types/compiled.js.map +1 -0
  210. package/dist/types/hash.d.ts +24 -0
  211. package/dist/types/hash.d.ts.map +1 -0
  212. package/dist/types/hash.js +49 -0
  213. package/dist/types/hash.js.map +1 -0
  214. package/dist/types/index.d.ts +10 -0
  215. package/dist/types/index.d.ts.map +1 -0
  216. package/dist/types/index.js +26 -0
  217. package/dist/types/index.js.map +1 -0
  218. package/dist/types/policy.d.ts +128 -0
  219. package/dist/types/policy.d.ts.map +1 -0
  220. package/dist/types/policy.js +55 -0
  221. package/dist/types/policy.js.map +1 -0
  222. package/package.json +55 -0
  223. package/postcss.config.js +4 -0
  224. package/src/__tests__/attachment-selector.test.ts +559 -0
  225. package/src/__tests__/cache-breakpoints.test.ts +566 -0
  226. package/src/__tests__/codecs.test.ts +417 -0
  227. package/src/__tests__/compactor.test.ts +608 -0
  228. package/src/__tests__/context-graph.test.ts +383 -0
  229. package/src/__tests__/hash.test.ts +274 -0
  230. package/src/__tests__/integration.test.ts +866 -0
  231. package/src/__tests__/kind-order.test.ts +312 -0
  232. package/src/__tests__/phase2-integration.test.ts +253 -0
  233. package/src/__tests__/queries.test.ts +387 -0
  234. package/src/__tests__/token-estimator.test.ts +326 -0
  235. package/src/adapters/anthropic-estimator.ts +125 -0
  236. package/src/adapters/attachment-resolver.ts +295 -0
  237. package/src/adapters/attachment-selector.ts +218 -0
  238. package/src/adapters/gemini-estimator.ts +93 -0
  239. package/src/adapters/index.ts +12 -0
  240. package/src/adapters/memory-store.ts +299 -0
  241. package/src/adapters/openai-estimator.ts +105 -0
  242. package/src/adapters/summarizer.ts +250 -0
  243. package/src/adapters/token-estimator.ts +74 -0
  244. package/src/builder/context-builder.ts +467 -0
  245. package/src/builder/context-fork.ts +471 -0
  246. package/src/builder/index.ts +6 -0
  247. package/src/codecs/base.ts +36 -0
  248. package/src/codecs/conversation-history.codec.ts +108 -0
  249. package/src/codecs/index.ts +57 -0
  250. package/src/codecs/redacted-stub.codec.ts +76 -0
  251. package/src/codecs/structured-reference.codec.ts +96 -0
  252. package/src/codecs/system-rules.codec.ts +74 -0
  253. package/src/codecs/tool-output.codec.ts +109 -0
  254. package/src/codecs/tool-schema.codec.ts +87 -0
  255. package/src/codecs/unsafe-text.codec.ts +74 -0
  256. package/src/graph/context-graph.ts +205 -0
  257. package/src/graph/index.ts +8 -0
  258. package/src/graph/kind-order.ts +125 -0
  259. package/src/graph/queries.ts +306 -0
  260. package/src/graph/views.ts +255 -0
  261. package/src/index.ts +31 -0
  262. package/src/pipeline/compactor.ts +563 -0
  263. package/src/pipeline/index.ts +6 -0
  264. package/src/pipeline/summarizer.ts +76 -0
  265. package/src/policies/default-policy.ts +69 -0
  266. package/src/policies/index.ts +5 -0
  267. package/src/providers/anthropic-compiler.ts +294 -0
  268. package/src/providers/capabilities.ts +144 -0
  269. package/src/providers/gemini-compiler.ts +272 -0
  270. package/src/providers/index.ts +8 -0
  271. package/src/providers/openai-compiler.ts +191 -0
  272. package/src/types/attachment.ts +86 -0
  273. package/src/types/block.ts +84 -0
  274. package/src/types/codec.ts +68 -0
  275. package/src/types/compiled.ts +109 -0
  276. package/src/types/hash.ts +58 -0
  277. package/src/types/index.ts +10 -0
  278. package/src/types/policy.ts +194 -0
  279. package/tsconfig.json +21 -0
  280. package/vitest.config.ts +21 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Redacted stub codec (any kind).
3
+ *
4
+ * Placeholder for sensitive content that was removed.
5
+ */
6
+
7
+ import { z } from 'zod';
8
+ import type { BlockCodec, RenderedContent } from '../types/codec.js';
9
+ import type { ContextBlock } from '../types/block.js';
10
+ import { defaultHash, sortObjectKeys } from './base.js';
11
+
12
+ /**
13
+ * Redacted stub payload schema.
14
+ */
15
+ export const RedactedStubPayloadSchema = z.object({
16
+ /** Original block hash (for reference) */
17
+ originalBlockHash: z.string(),
18
+
19
+ /** Reason for redaction */
20
+ reason: z.string(),
21
+
22
+ /** Optional placeholder text */
23
+ placeholder: z.string().optional(),
24
+ });
25
+
26
+ export type RedactedStubPayload = z.infer<typeof RedactedStubPayloadSchema>;
27
+
28
+ /**
29
+ * Redacted stub codec implementation.
30
+ */
31
+ export const RedactedStubCodec: BlockCodec<RedactedStubPayload> = {
32
+ codecId: 'redacted-stub',
33
+ version: '1.0.0',
34
+ payloadSchema: RedactedStubPayloadSchema,
35
+
36
+ canonicalize(payload: RedactedStubPayload): unknown {
37
+ return sortObjectKeys({
38
+ originalBlockHash: payload.originalBlockHash,
39
+ reason: payload.reason,
40
+ placeholder: payload.placeholder ?? '[REDACTED]',
41
+ });
42
+ },
43
+
44
+ hash(canonicalized: unknown): string {
45
+ return defaultHash(canonicalized);
46
+ },
47
+
48
+ render(block: ContextBlock<RedactedStubPayload>): RenderedContent {
49
+ const { placeholder, reason } = block.payload;
50
+ const text = `${placeholder ?? '[REDACTED]'}\n\n*Reason: ${reason}*`;
51
+
52
+ return {
53
+ // Anthropic: user message
54
+ anthropic: {
55
+ role: 'user',
56
+ content: [{ type: 'text', text }],
57
+ },
58
+
59
+ // OpenAI: user message
60
+ openai: {
61
+ role: 'user',
62
+ content: text,
63
+ },
64
+
65
+ // Gemini: user message
66
+ gemini: {
67
+ role: 'user',
68
+ parts: [{ text }],
69
+ },
70
+ };
71
+ },
72
+
73
+ validate(payload: unknown): RedactedStubPayload {
74
+ return RedactedStubPayloadSchema.parse(payload);
75
+ },
76
+ };
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Structured reference codec (kind: 'reference').
3
+ *
4
+ * External documentation, code snippets, API responses.
5
+ */
6
+
7
+ import { z } from 'zod';
8
+ import type { BlockCodec, RenderedContent } from '../types/codec.js';
9
+ import type { ContextBlock } from '../types/block.js';
10
+ import { defaultHash, sortObjectKeys } from './base.js';
11
+
12
+ /**
13
+ * Structured reference payload schema.
14
+ */
15
+ export const StructuredReferencePayloadSchema = z.object({
16
+ /** Reference title */
17
+ title: z.string(),
18
+
19
+ /** Reference content (markdown, code, JSON, etc.) */
20
+ content: z.string(),
21
+
22
+ /** Optional source URL */
23
+ sourceUrl: z.string().optional(),
24
+
25
+ /** Optional MIME type */
26
+ mimeType: z.string().optional(),
27
+
28
+ /** Optional cache control hint */
29
+ cacheable: z.boolean().optional(),
30
+ });
31
+
32
+ export type StructuredReferencePayload = z.infer<typeof StructuredReferencePayloadSchema>;
33
+
34
+ /**
35
+ * Structured reference codec implementation.
36
+ */
37
+ export const StructuredReferenceCodec: BlockCodec<StructuredReferencePayload> = {
38
+ codecId: 'structured-reference',
39
+ version: '1.0.0',
40
+ payloadSchema: StructuredReferencePayloadSchema,
41
+
42
+ canonicalize(payload: StructuredReferencePayload): unknown {
43
+ return sortObjectKeys({
44
+ title: payload.title.trim(),
45
+ content: payload.content,
46
+ sourceUrl: payload.sourceUrl ?? null,
47
+ mimeType: payload.mimeType ?? null,
48
+ cacheable: payload.cacheable ?? false,
49
+ });
50
+ },
51
+
52
+ hash(canonicalized: unknown): string {
53
+ return defaultHash(canonicalized);
54
+ },
55
+
56
+ render(block: ContextBlock<StructuredReferencePayload>): RenderedContent {
57
+ const { title, content, sourceUrl, cacheable } = block.payload;
58
+
59
+ // Format as markdown with optional source
60
+ const formattedContent = [
61
+ `# ${title}`,
62
+ sourceUrl ? `\n*Source: ${sourceUrl}*\n` : '',
63
+ content,
64
+ ].join('\n');
65
+
66
+ return {
67
+ // Anthropic: user message with optional cache control
68
+ anthropic: {
69
+ role: 'user',
70
+ content: [
71
+ {
72
+ type: 'text',
73
+ text: formattedContent,
74
+ ...(cacheable && { cache_control: { type: 'ephemeral' } }),
75
+ },
76
+ ],
77
+ },
78
+
79
+ // OpenAI: user message
80
+ openai: {
81
+ role: 'user',
82
+ content: formattedContent,
83
+ },
84
+
85
+ // Gemini: user message
86
+ gemini: {
87
+ role: 'user',
88
+ parts: [{ text: formattedContent }],
89
+ },
90
+ };
91
+ },
92
+
93
+ validate(payload: unknown): StructuredReferencePayload {
94
+ return StructuredReferencePayloadSchema.parse(payload);
95
+ },
96
+ };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * System rules codec (kind: 'pinned').
3
+ *
4
+ * System-level instructions and constraints.
5
+ */
6
+
7
+ import { z } from 'zod';
8
+ import type { BlockCodec, RenderedContent } from '../types/codec.js';
9
+ import type { ContextBlock } from '../types/block.js';
10
+ import { defaultHash, sortObjectKeys } from './base.js';
11
+
12
+ /**
13
+ * System rules payload schema.
14
+ */
15
+ export const SystemRulesPayloadSchema = z.object({
16
+ /** System rules text */
17
+ text: z.string(),
18
+
19
+ /** Optional priority (higher = more important) */
20
+ priority: z.number().optional(),
21
+
22
+ /** Optional cache control hint */
23
+ cacheable: z.boolean().optional(),
24
+ });
25
+
26
+ export type SystemRulesPayload = z.infer<typeof SystemRulesPayloadSchema>;
27
+
28
+ /**
29
+ * System rules codec implementation.
30
+ */
31
+ export const SystemRulesCodec: BlockCodec<SystemRulesPayload> = {
32
+ codecId: 'system-rules',
33
+ version: '1.0.0',
34
+ payloadSchema: SystemRulesPayloadSchema,
35
+
36
+ canonicalize(payload: SystemRulesPayload): unknown {
37
+ // Normalize whitespace and sort keys
38
+ return sortObjectKeys({
39
+ text: payload.text.trim(),
40
+ priority: payload.priority ?? 0,
41
+ cacheable: payload.cacheable ?? false,
42
+ });
43
+ },
44
+
45
+ hash(canonicalized: unknown): string {
46
+ return defaultHash(canonicalized);
47
+ },
48
+
49
+ render(block: ContextBlock<SystemRulesPayload>): RenderedContent {
50
+ const { text, cacheable } = block.payload;
51
+
52
+ return {
53
+ // Anthropic: system message with optional cache control
54
+ anthropic: {
55
+ type: 'text',
56
+ text,
57
+ ...(cacheable && { cache_control: { type: 'ephemeral' } }),
58
+ },
59
+
60
+ // OpenAI: system message
61
+ openai: {
62
+ role: 'system',
63
+ content: text,
64
+ },
65
+
66
+ // Gemini: system instruction (string)
67
+ gemini: text,
68
+ };
69
+ },
70
+
71
+ validate(payload: unknown): SystemRulesPayload {
72
+ return SystemRulesPayloadSchema.parse(payload);
73
+ },
74
+ };
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Tool output codec (kind: 'tool_output').
3
+ *
4
+ * Results from tool execution.
5
+ */
6
+
7
+ import { z } from 'zod';
8
+ import type { BlockCodec, RenderedContent } from '../types/codec.js';
9
+ import type { ContextBlock } from '../types/block.js';
10
+ import { defaultHash, sortObjectKeys } from './base.js';
11
+
12
+ /**
13
+ * Tool output payload schema.
14
+ */
15
+ export const ToolOutputPayloadSchema = z.object({
16
+ /** Tool name */
17
+ toolName: z.string(),
18
+
19
+ /** Tool call ID (for correlation) */
20
+ toolCallId: z.string(),
21
+
22
+ /** Tool output (success or error) */
23
+ output: z.union([
24
+ z.object({
25
+ success: z.literal(true),
26
+ result: z.unknown(),
27
+ }),
28
+ z.object({
29
+ success: z.literal(false),
30
+ error: z.string(),
31
+ }),
32
+ ]),
33
+
34
+ /** Execution duration (ms) */
35
+ durationMs: z.number().optional(),
36
+ });
37
+
38
+ export type ToolOutputPayload = z.infer<typeof ToolOutputPayloadSchema>;
39
+
40
+ /**
41
+ * Tool output codec implementation.
42
+ */
43
+ export const ToolOutputCodec: BlockCodec<ToolOutputPayload> = {
44
+ codecId: 'tool-output',
45
+ version: '1.0.0',
46
+ payloadSchema: ToolOutputPayloadSchema,
47
+
48
+ canonicalize(payload: ToolOutputPayload): unknown {
49
+ return sortObjectKeys({
50
+ toolName: payload.toolName,
51
+ toolCallId: payload.toolCallId,
52
+ output: payload.output,
53
+ // Exclude durationMs from canonicalization (not content-relevant)
54
+ });
55
+ },
56
+
57
+ hash(canonicalized: unknown): string {
58
+ return defaultHash(canonicalized);
59
+ },
60
+
61
+ render(block: ContextBlock<ToolOutputPayload>): RenderedContent {
62
+ const { toolName, toolCallId, output } = block.payload;
63
+
64
+ // Format output content
65
+ const contentText = output.success
66
+ ? JSON.stringify(output.result, null, 2)
67
+ : `Error: ${output.error}`;
68
+
69
+ return {
70
+ // Anthropic: user message with tool_result
71
+ anthropic: {
72
+ role: 'user',
73
+ content: [
74
+ {
75
+ type: 'tool_result',
76
+ tool_use_id: toolCallId,
77
+ content: contentText,
78
+ is_error: !output.success,
79
+ },
80
+ ],
81
+ },
82
+
83
+ // OpenAI: tool message
84
+ openai: {
85
+ role: 'tool',
86
+ tool_call_id: toolCallId,
87
+ name: toolName,
88
+ content: contentText,
89
+ },
90
+
91
+ // Gemini: user message with function response
92
+ gemini: {
93
+ role: 'user',
94
+ parts: [
95
+ {
96
+ functionResponse: {
97
+ name: toolName,
98
+ response: output.success ? output.result : { error: output.error },
99
+ },
100
+ },
101
+ ],
102
+ },
103
+ };
104
+ },
105
+
106
+ validate(payload: unknown): ToolOutputPayload {
107
+ return ToolOutputPayloadSchema.parse(payload);
108
+ },
109
+ };
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Tool schema codec (kind: 'reference').
3
+ *
4
+ * Tool definitions for function calling.
5
+ */
6
+
7
+ import { z } from 'zod';
8
+ import type { BlockCodec, RenderedContent } from '../types/codec.js';
9
+ import type { ContextBlock } from '../types/block.js';
10
+ import { defaultHash, sortObjectKeys } from './base.js';
11
+
12
+ /**
13
+ * Tool schema payload schema (JSON Schema-like).
14
+ */
15
+ export const ToolSchemaPayloadSchema = z.object({
16
+ /** Tool name */
17
+ name: z.string(),
18
+
19
+ /** Tool description */
20
+ description: z.string(),
21
+
22
+ /** Input schema (JSON Schema) */
23
+ inputSchema: z.record(z.unknown()),
24
+
25
+ /** Optional cache control hint */
26
+ cacheable: z.boolean().optional(),
27
+ });
28
+
29
+ export type ToolSchemaPayload = z.infer<typeof ToolSchemaPayloadSchema>;
30
+
31
+ /**
32
+ * Tool schema codec implementation.
33
+ */
34
+ export const ToolSchemaCodec: BlockCodec<ToolSchemaPayload> = {
35
+ codecId: 'tool-schema',
36
+ version: '1.0.0',
37
+ payloadSchema: ToolSchemaPayloadSchema,
38
+
39
+ canonicalize(payload: ToolSchemaPayload): unknown {
40
+ // Sort keys for deterministic hashing
41
+ return sortObjectKeys({
42
+ name: payload.name,
43
+ description: payload.description.trim(),
44
+ inputSchema: sortObjectKeys(payload.inputSchema as Record<string, unknown>),
45
+ cacheable: payload.cacheable ?? false,
46
+ });
47
+ },
48
+
49
+ hash(canonicalized: unknown): string {
50
+ return defaultHash(canonicalized);
51
+ },
52
+
53
+ render(block: ContextBlock<ToolSchemaPayload>): RenderedContent {
54
+ const { name, description, inputSchema, cacheable } = block.payload;
55
+
56
+ return {
57
+ // Anthropic: tool definition
58
+ anthropic: {
59
+ name,
60
+ description,
61
+ input_schema: inputSchema,
62
+ ...(cacheable && { cache_control: { type: 'ephemeral' } }),
63
+ },
64
+
65
+ // OpenAI: function definition
66
+ openai: {
67
+ type: 'function',
68
+ function: {
69
+ name,
70
+ description,
71
+ parameters: inputSchema,
72
+ },
73
+ },
74
+
75
+ // Gemini: function declaration
76
+ gemini: {
77
+ name,
78
+ description,
79
+ parameters: inputSchema,
80
+ },
81
+ };
82
+ },
83
+
84
+ validate(payload: unknown): ToolSchemaPayload {
85
+ return ToolSchemaPayloadSchema.parse(payload);
86
+ },
87
+ };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Unsafe text codec (any kind).
3
+ *
4
+ * Raw text passthrough without validation. Use with caution.
5
+ */
6
+
7
+ import { z } from 'zod';
8
+ import type { BlockCodec, RenderedContent } from '../types/codec.js';
9
+ import type { ContextBlock } from '../types/block.js';
10
+ import { defaultHash } from './base.js';
11
+
12
+ /**
13
+ * Unsafe text payload schema.
14
+ */
15
+ export const UnsafeTextPayloadSchema = z.object({
16
+ /** Raw text content */
17
+ text: z.string(),
18
+
19
+ /** Optional role override (user, assistant, system) */
20
+ role: z.enum(['user', 'assistant', 'system']).optional(),
21
+ });
22
+
23
+ export type UnsafeTextPayload = z.infer<typeof UnsafeTextPayloadSchema>;
24
+
25
+ /**
26
+ * Unsafe text codec implementation.
27
+ */
28
+ export const UnsafeTextCodec: BlockCodec<UnsafeTextPayload> = {
29
+ codecId: 'unsafe-text',
30
+ version: '1.0.0',
31
+ payloadSchema: UnsafeTextPayloadSchema,
32
+
33
+ canonicalize(payload: UnsafeTextPayload): unknown {
34
+ // Canonicalize: trim whitespace and normalize role
35
+ return {
36
+ text: payload.text.trim(),
37
+ role: payload.role ?? 'user',
38
+ };
39
+ },
40
+
41
+ hash(canonicalized: unknown): string {
42
+ return defaultHash(canonicalized);
43
+ },
44
+
45
+ render(block: ContextBlock<UnsafeTextPayload>): RenderedContent {
46
+ const { text, role = 'user' } = block.payload;
47
+
48
+ return {
49
+ // Anthropic: message with specified role
50
+ anthropic: {
51
+ role: role === 'system' ? 'user' : role,
52
+ content: role === 'system'
53
+ ? [{ type: 'text', text }]
54
+ : text,
55
+ },
56
+
57
+ // OpenAI: message with specified role
58
+ openai: {
59
+ role: role === 'system' ? 'system' : role,
60
+ content: text,
61
+ },
62
+
63
+ // Gemini: convert role to user/model
64
+ gemini: {
65
+ role: role === 'assistant' ? 'model' : 'user',
66
+ parts: [{ text }],
67
+ },
68
+ };
69
+ },
70
+
71
+ validate(payload: unknown): UnsafeTextPayload {
72
+ return UnsafeTextPayloadSchema.parse(payload);
73
+ },
74
+ };