@intentface/latch-core 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/agent.d.ts +200 -0
  4. package/dist/agent.d.ts.map +1 -0
  5. package/dist/agent.js +9 -0
  6. package/dist/agent.js.map +1 -0
  7. package/dist/compaction.d.ts +33 -0
  8. package/dist/compaction.d.ts.map +1 -0
  9. package/dist/compaction.js +104 -0
  10. package/dist/compaction.js.map +1 -0
  11. package/dist/connections.d.ts +16 -0
  12. package/dist/connections.d.ts.map +1 -0
  13. package/dist/connections.js +41 -0
  14. package/dist/connections.js.map +1 -0
  15. package/dist/context.d.ts +41 -0
  16. package/dist/context.d.ts.map +1 -0
  17. package/dist/context.js +25 -0
  18. package/dist/context.js.map +1 -0
  19. package/dist/current-date.d.ts +12 -0
  20. package/dist/current-date.d.ts.map +1 -0
  21. package/dist/current-date.js +25 -0
  22. package/dist/current-date.js.map +1 -0
  23. package/dist/extensions.d.ts +333 -0
  24. package/dist/extensions.d.ts.map +1 -0
  25. package/dist/extensions.js +569 -0
  26. package/dist/extensions.js.map +1 -0
  27. package/dist/harness/index.d.ts +17 -0
  28. package/dist/harness/index.d.ts.map +1 -0
  29. package/dist/harness/index.js +15 -0
  30. package/dist/harness/index.js.map +1 -0
  31. package/dist/harness/tools.d.ts +88 -0
  32. package/dist/harness/tools.d.ts.map +1 -0
  33. package/dist/harness/tools.js +296 -0
  34. package/dist/harness/tools.js.map +1 -0
  35. package/dist/harness/web-fetch.d.ts +47 -0
  36. package/dist/harness/web-fetch.d.ts.map +1 -0
  37. package/dist/harness/web-fetch.js +247 -0
  38. package/dist/harness/web-fetch.js.map +1 -0
  39. package/dist/index.d.ts +25 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +25 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/limits.d.ts +152 -0
  44. package/dist/limits.d.ts.map +1 -0
  45. package/dist/limits.js +97 -0
  46. package/dist/limits.js.map +1 -0
  47. package/dist/memory.d.ts +93 -0
  48. package/dist/memory.d.ts.map +1 -0
  49. package/dist/memory.js +13 -0
  50. package/dist/memory.js.map +1 -0
  51. package/dist/message.d.ts +46 -0
  52. package/dist/message.d.ts.map +1 -0
  53. package/dist/message.js +2 -0
  54. package/dist/message.js.map +1 -0
  55. package/dist/models/catalog.d.ts +56 -0
  56. package/dist/models/catalog.d.ts.map +1 -0
  57. package/dist/models/catalog.js +211 -0
  58. package/dist/models/catalog.js.map +1 -0
  59. package/dist/models/defaults.d.ts +23 -0
  60. package/dist/models/defaults.d.ts.map +1 -0
  61. package/dist/models/defaults.js +19 -0
  62. package/dist/models/defaults.js.map +1 -0
  63. package/dist/models/index.d.ts +23 -0
  64. package/dist/models/index.d.ts.map +1 -0
  65. package/dist/models/index.js +19 -0
  66. package/dist/models/index.js.map +1 -0
  67. package/dist/models/prompt-caching.d.ts +19 -0
  68. package/dist/models/prompt-caching.d.ts.map +1 -0
  69. package/dist/models/prompt-caching.js +18 -0
  70. package/dist/models/prompt-caching.js.map +1 -0
  71. package/dist/models/provider.d.ts +19 -0
  72. package/dist/models/provider.d.ts.map +1 -0
  73. package/dist/models/provider.js +22 -0
  74. package/dist/models/provider.js.map +1 -0
  75. package/dist/models/reasoning.d.ts +21 -0
  76. package/dist/models/reasoning.d.ts.map +1 -0
  77. package/dist/models/reasoning.js +59 -0
  78. package/dist/models/reasoning.js.map +1 -0
  79. package/dist/pricing.d.ts +52 -0
  80. package/dist/pricing.d.ts.map +1 -0
  81. package/dist/pricing.js +37 -0
  82. package/dist/pricing.js.map +1 -0
  83. package/dist/principal.d.ts +37 -0
  84. package/dist/principal.d.ts.map +1 -0
  85. package/dist/principal.js +30 -0
  86. package/dist/principal.js.map +1 -0
  87. package/dist/projections.d.ts +37 -0
  88. package/dist/projections.d.ts.map +1 -0
  89. package/dist/projections.js +128 -0
  90. package/dist/projections.js.map +1 -0
  91. package/dist/prompt-caching.d.ts +106 -0
  92. package/dist/prompt-caching.d.ts.map +1 -0
  93. package/dist/prompt-caching.js +165 -0
  94. package/dist/prompt-caching.js.map +1 -0
  95. package/dist/runtime.d.ts +670 -0
  96. package/dist/runtime.d.ts.map +1 -0
  97. package/dist/runtime.js +2425 -0
  98. package/dist/runtime.js.map +1 -0
  99. package/dist/scheduler.d.ts +31 -0
  100. package/dist/scheduler.d.ts.map +1 -0
  101. package/dist/scheduler.js +43 -0
  102. package/dist/scheduler.js.map +1 -0
  103. package/dist/storage.d.ts +389 -0
  104. package/dist/storage.d.ts.map +1 -0
  105. package/dist/storage.js +38 -0
  106. package/dist/storage.js.map +1 -0
  107. package/dist/telemetry.d.ts +155 -0
  108. package/dist/telemetry.d.ts.map +1 -0
  109. package/dist/telemetry.js +2 -0
  110. package/dist/telemetry.js.map +1 -0
  111. package/dist/vault-node.d.ts +20 -0
  112. package/dist/vault-node.d.ts.map +1 -0
  113. package/dist/vault-node.js +30 -0
  114. package/dist/vault-node.js.map +1 -0
  115. package/dist/vault.d.ts +62 -0
  116. package/dist/vault.d.ts.map +1 -0
  117. package/dist/vault.js +88 -0
  118. package/dist/vault.js.map +1 -0
  119. package/package.json +95 -0
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Prompt-caching plans: which provider options a turn should set so the model
3
+ * provider caches the stable prompt prefix (tool definitions, system prompt,
4
+ * conversation history) instead of re-billing it every step.
5
+ *
6
+ * Kept provider-generic in core: the PLATFORM decides which provider a model id
7
+ * belongs to (it owns the catalog) and calls `promptCachingPlanFor` from its
8
+ * `RuntimeConfig.resolvePromptCaching` hook; core only applies the plan in
9
+ * `buildTurn`. Providers not named here (e.g. Google: implicit caching only)
10
+ * get no plan and are untouched.
11
+ *
12
+ * Anthropic layout — three of the four allowed `cache_control` breakpoints:
13
+ * 1. The LAST function tool definition. Tools render before the system prompt
14
+ * in the request, so this keeps the (often large, MCP-heavy) tool prefix
15
+ * cached even when the system block changes mid-conversation (e.g. a
16
+ * memory-index write).
17
+ * 2. The system message that holds the agent instructions + memory block. The
18
+ * day-granular date line is a SEPARATE, unmarked system message after it,
19
+ * so the daily date flip never invalidates this breakpoint.
20
+ * 3. A request-level (top-level) `cache_control` — Anthropic's automatic
21
+ * caching: the API places a breakpoint on the last cacheable block of the
22
+ * request. The AI SDK re-sends call-level providerOptions on every step of
23
+ * the tool loop, so this breakpoint ROLLS to the newest tool result with no
24
+ * per-step code. Note: top-level cache_control is a first-party Claude API
25
+ * feature (not Bedrock/Vertex); block-level markers work everywhere. Also
26
+ * note the SDK's client-side breakpoint validator counts only block-level
27
+ * markers, so the request-level one is invisible to it — harmless.
28
+ *
29
+ * TTL is left at the provider default (5m). Agents whose turns arrive slower
30
+ * than that won't benefit — that's surfaced by the platform's caching lint,
31
+ * not worked around here.
32
+ */
33
+ /** A cache-control marker in the shape the Anthropic provider expects. */
34
+ const EPHEMERAL = { type: "ephemeral" };
35
+ /**
36
+ * The caching plan for a provider family (`"anthropic"`, `"openai"`, …).
37
+ * `cacheKeySuffix` scopes OpenAI's cache routing key beyond the agent name —
38
+ * pass a per-principal key for agents whose system prompt is per-principal
39
+ * (e.g. memory-enabled agents), so structurally different prefixes don't
40
+ * co-route to one shard.
41
+ */
42
+ export function promptCachingPlanFor(provider, opts) {
43
+ if (provider === "anthropic") {
44
+ return {
45
+ requestProviderOptions: { anthropic: { cacheControl: { ...EPHEMERAL } } },
46
+ systemProviderOptions: { anthropic: { cacheControl: { ...EPHEMERAL } } },
47
+ toolProviderOptions: { anthropic: { cacheControl: { ...EPHEMERAL } } },
48
+ };
49
+ }
50
+ if (provider === "openai") {
51
+ const key = opts.cacheKeySuffix
52
+ ? `latch:agent:${opts.agent}:${opts.cacheKeySuffix}`
53
+ : `latch:agent:${opts.agent}`;
54
+ // OpenAI caps prompt_cache_key at 64 chars and 400s the whole turn past
55
+ // it — agent names and principal keys are unbounded, so an over-long key
56
+ // collapses to a deterministic hash of the full key material (routing
57
+ // only needs stability, not readability).
58
+ const bounded = key.length <= 64 ? key : `latch:${fnv1a64(key)}`;
59
+ return { requestProviderOptions: { openai: { promptCacheKey: bounded } } };
60
+ }
61
+ return undefined;
62
+ }
63
+ /**
64
+ * The DEFAULT caching plan, used when the runtime has no `resolvePromptCaching`
65
+ * hook: derive the provider family from the model object itself — every AI SDK
66
+ * `LanguageModel` carries a `provider` string (`"anthropic.messages"`,
67
+ * `"openai.responses"`, …) — and apply {@link promptCachingPlanFor}. Measured
68
+ * on a real MCP-heavy agent, this is a ~6x difference in unit cost (a ~32k-token
69
+ * tool catalogue re-billed every step vs read from cache), which is not a
70
+ * default a customer should have to discover by reading source.
71
+ *
72
+ * Deliberately conservative: only FIRST-PARTY Anthropic/OpenAI provider ids
73
+ * match (Bedrock/Vertex ids don't contain these substrings), because the
74
+ * Anthropic plan's request-level `cache_control` is a first-party feature.
75
+ * Unknown providers get no plan and are untouched. Opt out entirely with
76
+ * `resolvePromptCaching: () => undefined`, or per turn with
77
+ * `promptCaching: false`.
78
+ */
79
+ export function defaultPromptCachingPlan(model, agent) {
80
+ const provider = typeof model === "object" && model !== null
81
+ ? String(model.provider ?? "")
82
+ : "";
83
+ const family = provider.includes("anthropic")
84
+ ? "anthropic"
85
+ : provider.includes("openai")
86
+ ? "openai"
87
+ : undefined;
88
+ return promptCachingPlanFor(family, { agent });
89
+ }
90
+ /** FNV-1a 64-bit over a string — dependency-free stable fingerprint. */
91
+ function fnv1a64(input) {
92
+ let hash = 0xcbf29ce484222325n;
93
+ const prime = 0x100000001b3n;
94
+ for (let i = 0; i < input.length; i++) {
95
+ hash ^= BigInt(input.charCodeAt(i));
96
+ hash = (hash * prime) & 0xffffffffffffffffn;
97
+ }
98
+ return hash.toString(16).padStart(16, "0");
99
+ }
100
+ /**
101
+ * One-level-deep merge of providerOptions objects (per provider key), so e.g.
102
+ * `{ anthropic: { thinking } }` from reasoning and `{ anthropic: { cacheControl } }`
103
+ * from caching coexist — a plain spread would clobber one with the other. Later
104
+ * sources win on conflicting inner keys. Returns undefined when nothing to merge.
105
+ */
106
+ export function mergeProviderOptions(...sources) {
107
+ const present = sources.filter((s) => !!s);
108
+ if (present.length === 0)
109
+ return undefined;
110
+ if (present.length === 1)
111
+ return present[0];
112
+ const out = {};
113
+ for (const source of present) {
114
+ for (const [provider, options] of Object.entries(source)) {
115
+ const prev = out[provider];
116
+ out[provider] =
117
+ prev && typeof prev === "object" && options && typeof options === "object"
118
+ ? { ...prev, ...options }
119
+ : options;
120
+ }
121
+ }
122
+ return out;
123
+ }
124
+ /**
125
+ * Stable fingerprint of a toolset (FNV-1a 64-bit over the sorted names) —
126
+ * equality is all that matters (same hash ⇔ same tool names), so a
127
+ * dependency-free non-cryptographic hash beats pulling in node:crypto (core
128
+ * stays runtime-agnostic). Stored on the run row to detect toolset churn
129
+ * across a chat's turns, one of the main prompt-cache invalidators.
130
+ */
131
+ export function toolsetHash(names) {
132
+ return fnv1a64([...names].sort().join(","));
133
+ }
134
+ /**
135
+ * Mark the LAST active function tool with the given providerOptions (in place).
136
+ * Skips provider-executed tools (`type: "provider"`, e.g. Anthropic's native
137
+ * web_search/web_fetch) — the provider silently drops `cache_control` on those —
138
+ * and, when `activeNames` is given, tools the turn filtered out via
139
+ * `activeTools` (a marker on an unsent tool would vanish). Returns the marked
140
+ * tool name, or undefined when no eligible tool exists.
141
+ */
142
+ export function markLastFunctionTool(tools, providerOptions, activeNames) {
143
+ const active = activeNames ? new Set(activeNames) : undefined;
144
+ const names = Object.keys(tools);
145
+ for (let i = names.length - 1; i >= 0; i--) {
146
+ const name = names[i];
147
+ if (active && !active.has(name))
148
+ continue;
149
+ const t = tools[name];
150
+ if (!t || typeof t !== "object")
151
+ continue;
152
+ // "provider" (and any future provider-executed variant) can't carry
153
+ // cache_control; everything else (function/dynamic) serializes as a
154
+ // client tool definition and can.
155
+ if (typeof t.type === "string" && t.type.startsWith("provider"))
156
+ continue;
157
+ tools[name] = {
158
+ ...t,
159
+ providerOptions: mergeProviderOptions(t.providerOptions, providerOptions),
160
+ };
161
+ return name;
162
+ }
163
+ return undefined;
164
+ }
165
+ //# sourceMappingURL=prompt-caching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-caching.js","sourceRoot":"","sources":["../src/prompt-caching.ts"],"names":[],"mappings":"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"}