hoomanjs 1.45.4 → 1.47.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 (227) hide show
  1. package/README.md +7 -5
  2. package/dist/acp/acp-agent.d.ts +42 -0
  3. package/dist/acp/acp-agent.js +337 -53
  4. package/dist/acp/acp-agent.js.map +1 -1
  5. package/dist/acp/prompt-invoke.d.ts +2 -1
  6. package/dist/acp/prompt-invoke.js +20 -95
  7. package/dist/acp/prompt-invoke.js.map +1 -1
  8. package/dist/acp/session-config.d.ts +2 -2
  9. package/dist/acp/session-config.js +24 -20
  10. package/dist/acp/session-config.js.map +1 -1
  11. package/dist/acp/utils/tool-kind.js +2 -0
  12. package/dist/acp/utils/tool-kind.js.map +1 -1
  13. package/dist/chat/app.js +93 -20
  14. package/dist/chat/app.js.map +1 -1
  15. package/dist/chat/components/ApprovalPrompt.js +7 -6
  16. package/dist/chat/components/ApprovalPrompt.js.map +1 -1
  17. package/dist/chat/components/BackgroundJobsPanel.d.ts +10 -0
  18. package/dist/chat/components/BackgroundJobsPanel.js +15 -0
  19. package/dist/chat/components/BackgroundJobsPanel.js.map +1 -0
  20. package/dist/chat/components/BottomChrome.d.ts +7 -2
  21. package/dist/chat/components/BottomChrome.js +3 -2
  22. package/dist/chat/components/BottomChrome.js.map +1 -1
  23. package/dist/chat/components/ChromePicker.d.ts +7 -2
  24. package/dist/chat/components/ChromePicker.js +18 -2
  25. package/dist/chat/components/ChromePicker.js.map +1 -1
  26. package/dist/chat/components/Composer.js +3 -2
  27. package/dist/chat/components/Composer.js.map +1 -1
  28. package/dist/chat/components/DownloadPanel.d.ts +1 -1
  29. package/dist/chat/components/DownloadPanel.js +3 -2
  30. package/dist/chat/components/DownloadPanel.js.map +1 -1
  31. package/dist/chat/components/EmptyChatBanner.js +2 -1
  32. package/dist/chat/components/EmptyChatBanner.js.map +1 -1
  33. package/dist/chat/components/PromptInput.js +2 -1
  34. package/dist/chat/components/PromptInput.js.map +1 -1
  35. package/dist/chat/components/QuestionPrompt.js +5 -4
  36. package/dist/chat/components/QuestionPrompt.js.map +1 -1
  37. package/dist/chat/components/QueuedPrompts.js +3 -2
  38. package/dist/chat/components/QueuedPrompts.js.map +1 -1
  39. package/dist/chat/components/ReasoningStrip.js +2 -1
  40. package/dist/chat/components/ReasoningStrip.js.map +1 -1
  41. package/dist/chat/components/RetryEvent.js +2 -1
  42. package/dist/chat/components/RetryEvent.js.map +1 -1
  43. package/dist/chat/components/SelectPicker.js +2 -1
  44. package/dist/chat/components/SelectPicker.js.map +1 -1
  45. package/dist/chat/components/ShellToolEvent.d.ts +12 -0
  46. package/dist/chat/components/ShellToolEvent.js +94 -0
  47. package/dist/chat/components/ShellToolEvent.js.map +1 -0
  48. package/dist/chat/components/SlashCommands.js +2 -1
  49. package/dist/chat/components/SlashCommands.js.map +1 -1
  50. package/dist/chat/components/Spinner.js +2 -1
  51. package/dist/chat/components/Spinner.js.map +1 -1
  52. package/dist/chat/components/StatusBar.js +17 -16
  53. package/dist/chat/components/StatusBar.js.map +1 -1
  54. package/dist/chat/components/ThinkingStatus.js +2 -1
  55. package/dist/chat/components/ThinkingStatus.js.map +1 -1
  56. package/dist/chat/components/ThoughtEvent.js +2 -1
  57. package/dist/chat/components/ThoughtEvent.js.map +1 -1
  58. package/dist/chat/components/TodoPanel.js +2 -1
  59. package/dist/chat/components/TodoPanel.js.map +1 -1
  60. package/dist/chat/components/ToolEvent.d.ts +2 -1
  61. package/dist/chat/components/ToolEvent.js +9 -2
  62. package/dist/chat/components/ToolEvent.js.map +1 -1
  63. package/dist/chat/components/ToolEventFileResult.js +8 -7
  64. package/dist/chat/components/ToolEventFileResult.js.map +1 -1
  65. package/dist/chat/components/Transcript.d.ts +4 -2
  66. package/dist/chat/components/Transcript.js +4 -4
  67. package/dist/chat/components/Transcript.js.map +1 -1
  68. package/dist/chat/components/markdown/BlockRenderer.js +3 -2
  69. package/dist/chat/components/markdown/BlockRenderer.js.map +1 -1
  70. package/dist/chat/components/markdown/CodeBlock.js +3 -2
  71. package/dist/chat/components/markdown/CodeBlock.js.map +1 -1
  72. package/dist/chat/components/markdown/InlineRenderer.js +6 -5
  73. package/dist/chat/components/markdown/InlineRenderer.js.map +1 -1
  74. package/dist/chat/components/shared.js +7 -6
  75. package/dist/chat/components/shared.js.map +1 -1
  76. package/dist/chat/types.d.ts +4 -0
  77. package/dist/cli.js +5 -2
  78. package/dist/cli.js.map +1 -1
  79. package/dist/configure/app.js +292 -0
  80. package/dist/configure/app.js.map +1 -1
  81. package/dist/configure/components/BusyScreen.js +2 -1
  82. package/dist/configure/components/BusyScreen.js.map +1 -1
  83. package/dist/configure/components/MenuScreen.js +3 -2
  84. package/dist/configure/components/MenuScreen.js.map +1 -1
  85. package/dist/configure/components/PromptForm.js +2 -1
  86. package/dist/configure/components/PromptForm.js.map +1 -1
  87. package/dist/configure/components/SelectMenuItem.js +4 -3
  88. package/dist/configure/components/SelectMenuItem.js.map +1 -1
  89. package/dist/configure/utils.js +4 -3
  90. package/dist/configure/utils.js.map +1 -1
  91. package/dist/core/agent/gitignore-guard-plugin.d.ts +2 -0
  92. package/dist/core/agent/gitignore-guard-plugin.js +79 -0
  93. package/dist/core/agent/gitignore-guard-plugin.js.map +1 -0
  94. package/dist/core/agent/index.js +5 -1
  95. package/dist/core/agent/index.js.map +1 -1
  96. package/dist/core/config.d.ts +39 -6
  97. package/dist/core/config.js +5 -2
  98. package/dist/core/config.js.map +1 -1
  99. package/dist/core/index.js +19 -1
  100. package/dist/core/index.js.map +1 -1
  101. package/dist/core/models/anthropic.js +10 -4
  102. package/dist/core/models/anthropic.js.map +1 -1
  103. package/dist/core/models/azure.js +2 -1
  104. package/dist/core/models/azure.js.map +1 -1
  105. package/dist/core/models/bedrock.js +1 -0
  106. package/dist/core/models/bedrock.js.map +1 -1
  107. package/dist/core/models/google.js +1 -0
  108. package/dist/core/models/google.js.map +1 -1
  109. package/dist/core/models/groq.js +2 -1
  110. package/dist/core/models/groq.js.map +1 -1
  111. package/dist/core/models/llama-cpp/index.js +1 -0
  112. package/dist/core/models/llama-cpp/index.js.map +1 -1
  113. package/dist/core/models/llama-cpp/resolve-model.js +1 -1
  114. package/dist/core/models/llama-cpp/resolve-model.js.map +1 -1
  115. package/dist/core/models/minimax.js +2 -1
  116. package/dist/core/models/minimax.js.map +1 -1
  117. package/dist/core/models/mlx/index.js +2 -1
  118. package/dist/core/models/mlx/index.js.map +1 -1
  119. package/dist/core/models/mlx/resolve-model.js +1 -1
  120. package/dist/core/models/mlx/resolve-model.js.map +1 -1
  121. package/dist/core/models/mlx/strands-mlx.js +1 -1
  122. package/dist/core/models/mlx/strands-mlx.js.map +1 -1
  123. package/dist/core/models/moonshot.js +2 -1
  124. package/dist/core/models/moonshot.js.map +1 -1
  125. package/dist/core/models/ollama/index.js +7 -3
  126. package/dist/core/models/ollama/index.js.map +1 -1
  127. package/dist/core/models/openai.js +2 -1
  128. package/dist/core/models/openai.js.map +1 -1
  129. package/dist/core/models/openrouter.js +2 -1
  130. package/dist/core/models/openrouter.js.map +1 -1
  131. package/dist/core/models/types.d.ts +43 -11
  132. package/dist/core/models/types.js +15 -4
  133. package/dist/core/models/types.js.map +1 -1
  134. package/dist/core/models/xai.js +2 -1
  135. package/dist/core/models/xai.js.map +1 -1
  136. package/dist/core/modes/definitions.js +4 -0
  137. package/dist/core/modes/definitions.js.map +1 -1
  138. package/dist/core/prompts/modes/agent.md +1 -1
  139. package/dist/core/prompts/modes/plan.md +11 -7
  140. package/dist/core/prompts/static/browser.md +9 -0
  141. package/dist/core/prompts/static/shell.md +21 -1
  142. package/dist/core/prompts/system.js +3 -0
  143. package/dist/core/prompts/system.js.map +1 -1
  144. package/dist/core/ripgrep/bootstrap.js +5 -19
  145. package/dist/core/ripgrep/bootstrap.js.map +1 -1
  146. package/dist/core/shell/index.d.ts +7 -0
  147. package/dist/core/shell/index.js +6 -0
  148. package/dist/core/shell/index.js.map +1 -0
  149. package/dist/core/shell/manager.d.ts +23 -0
  150. package/dist/core/shell/manager.js +604 -0
  151. package/dist/core/shell/manager.js.map +1 -0
  152. package/dist/core/shell/output-buffer.d.ts +30 -0
  153. package/dist/core/shell/output-buffer.js +116 -0
  154. package/dist/core/shell/output-buffer.js.map +1 -0
  155. package/dist/core/shell/registry.d.ts +5 -0
  156. package/dist/core/shell/registry.js +24 -0
  157. package/dist/core/shell/registry.js.map +1 -0
  158. package/dist/core/shell/shell.d.ts +41 -0
  159. package/dist/core/{tools → shell}/shell.js +188 -24
  160. package/dist/core/shell/shell.js.map +1 -0
  161. package/dist/core/{tools/shell.d.ts → shell/terminal-backend.d.ts} +20 -18
  162. package/dist/core/shell/terminal-backend.js +18 -0
  163. package/dist/core/shell/terminal-backend.js.map +1 -0
  164. package/dist/core/shell/types.d.ts +95 -0
  165. package/dist/core/shell/types.js +2 -0
  166. package/dist/core/shell/types.js.map +1 -0
  167. package/dist/core/skills/built-in/hooman-config/SKILL.md +22 -5
  168. package/dist/core/skills/built-in/hooman-config/providers.md +14 -12
  169. package/dist/core/skills/plugin.js +5 -1
  170. package/dist/core/skills/plugin.js.map +1 -1
  171. package/dist/core/state/shell-jobs.d.ts +9 -0
  172. package/dist/core/state/shell-jobs.js +20 -0
  173. package/dist/core/state/shell-jobs.js.map +1 -0
  174. package/dist/core/state/tool-approvals.js +3 -0
  175. package/dist/core/state/tool-approvals.js.map +1 -1
  176. package/dist/core/state/turn-boundaries.d.ts +33 -0
  177. package/dist/core/state/turn-boundaries.js +49 -0
  178. package/dist/core/state/turn-boundaries.js.map +1 -0
  179. package/dist/core/theme.d.ts +14 -0
  180. package/dist/core/theme.js +14 -0
  181. package/dist/core/theme.js.map +1 -0
  182. package/dist/core/tools/filesystem.js +9 -0
  183. package/dist/core/tools/filesystem.js.map +1 -1
  184. package/dist/core/tools/index.d.ts +0 -1
  185. package/dist/core/tools/index.js +0 -1
  186. package/dist/core/tools/index.js.map +1 -1
  187. package/dist/core/utils/attachments.d.ts +4 -2
  188. package/dist/core/utils/attachments.js +10 -32
  189. package/dist/core/utils/attachments.js.map +1 -1
  190. package/dist/core/utils/command-path.d.ts +1 -0
  191. package/dist/core/utils/command-path.js +17 -0
  192. package/dist/core/utils/command-path.js.map +1 -0
  193. package/dist/core/utils/download-progress.js.map +1 -0
  194. package/dist/core/utils/gitignore.d.ts +11 -0
  195. package/dist/core/utils/gitignore.js +141 -0
  196. package/dist/core/utils/gitignore.js.map +1 -0
  197. package/dist/core/utils/hub-download.js.map +1 -0
  198. package/dist/core/utils/metadata.d.ts +65 -0
  199. package/dist/core/utils/{billing.js → metadata.js} +56 -73
  200. package/dist/core/utils/metadata.js.map +1 -0
  201. package/dist/core/utils/model-metadata.d.ts +39 -0
  202. package/dist/core/utils/model-metadata.js +222 -0
  203. package/dist/core/utils/model-metadata.js.map +1 -0
  204. package/dist/core/utils/paths.d.ts +1 -0
  205. package/dist/core/utils/paths.js +2 -0
  206. package/dist/core/utils/paths.js.map +1 -1
  207. package/dist/core/utils/reasoning-effort.d.ts +9 -1
  208. package/dist/core/{models → utils}/usage.js +1 -1
  209. package/dist/core/utils/usage.js.map +1 -0
  210. package/dist/daemon/index.d.ts +2 -0
  211. package/dist/daemon/index.js +6 -3
  212. package/dist/daemon/index.js.map +1 -1
  213. package/dist/index.d.ts +5 -5
  214. package/dist/index.js +4 -4
  215. package/dist/index.js.map +1 -1
  216. package/package.json +2 -1
  217. package/dist/core/models/download-progress.js.map +0 -1
  218. package/dist/core/models/hub-download.js.map +0 -1
  219. package/dist/core/models/usage.js.map +0 -1
  220. package/dist/core/tools/shell.js.map +0 -1
  221. package/dist/core/utils/billing.d.ts +0 -76
  222. package/dist/core/utils/billing.js.map +0 -1
  223. /package/dist/core/{models → utils}/download-progress.d.ts +0 -0
  224. /package/dist/core/{models → utils}/download-progress.js +0 -0
  225. /package/dist/core/{models → utils}/hub-download.d.ts +0 -0
  226. /package/dist/core/{models → utils}/hub-download.js +0 -0
  227. /package/dist/core/{models → utils}/usage.d.ts +0 -0
@@ -3,7 +3,7 @@ import { join } from "node:path";
3
3
  import { cachePath } from "./paths.js";
4
4
  import { LlmProvider } from "../models/types.js";
5
5
  /**
6
- * Billing metadata resolution backed by the models.dev catalog.
6
+ * Model metadata resolution backed by the models.dev catalog.
7
7
  *
8
8
  * The catalog (`https://models.dev/catalog.json`) is cached on disk under
9
9
  * `~/.hooman/cache/models-dev.json` and refreshed at most once per day; a
@@ -11,11 +11,12 @@ import { LlmProvider } from "../models/types.js";
11
11
  * offline once the catalog has been fetched at least once.
12
12
  *
13
13
  * `catalog.providers` is keyed by provider id and carries per-provider model
14
- * entries with `limit.context` and `cost` (USD per million tokens);
15
- * `catalog.models` is keyed by `lab/model-id` and identifies each model's
16
- * canonical lab. When several providers serve a matching model, the provider
17
- * whose id equals the lab (e.g. `anthropic` for `anthropic/claude-*`) wins;
18
- * otherwise the first matching provider's metrics are used.
14
+ * entries with `limit.context`, `cost` (USD per million tokens), and optional
15
+ * `modalities.input`; `catalog.models` is keyed by `lab/model-id` and
16
+ * identifies each model's canonical lab. When several providers serve a
17
+ * matching model, the provider whose id equals the lab (e.g. `anthropic` for
18
+ * `anthropic/claude-*`) wins; otherwise the first matching provider's metrics
19
+ * are used.
19
20
  */
20
21
  const CATALOG_URL = "https://models.dev/catalog.json";
21
22
  const CACHE_FILE = "models-dev.json";
@@ -67,11 +68,6 @@ async function writeDiskCache(envelope) {
67
68
  /* best effort */
68
69
  }
69
70
  }
70
- /**
71
- * Load the models.dev catalog: in-memory copy while fresh, then the disk
72
- * cache (refreshed once older than a day), then the network. Returns `null`
73
- * when nothing has ever been fetched and the network is unavailable.
74
- */
75
71
  async function loadCatalog() {
76
72
  if (memory && isFresh(memory.envelope)) {
77
73
  return memory.envelope.catalog;
@@ -114,14 +110,12 @@ async function loadCatalog() {
114
110
  inflight = null;
115
111
  }
116
112
  }
117
- /** Collapse separators so `claude-haiku-4.5` matches models.dev's `claude-haiku-4-5`. */
118
113
  function normalizeModelId(value) {
119
114
  return value
120
115
  .toLowerCase()
121
116
  .replace(/[^a-z0-9]+/g, "-")
122
117
  .replace(/^-+|-+$/g, "");
123
118
  }
124
- /** Candidate forms of the billing name: as-is plus the last `/` segment (OpenRouter-style ids). */
125
119
  function targetForms(name) {
126
120
  const forms = new Set();
127
121
  const normalized = normalizeModelId(name);
@@ -137,12 +131,6 @@ function targetForms(name) {
137
131
  }
138
132
  return [...forms];
139
133
  }
140
- /**
141
- * Match quality between the billing name and a catalog model id.
142
- * Tier 1: normalized equality. Tier 2: one normalized id contains the other
143
- * (e.g. a Bedrock region-prefixed id vs. the catalog's bare id); the length
144
- * difference breaks ties toward the closest candidate.
145
- */
146
134
  function matchModelId(targets, candidateId) {
147
135
  const candidate = normalizeModelId(candidateId);
148
136
  if (!candidate) {
@@ -155,9 +143,6 @@ function matchModelId(targets, candidateId) {
155
143
  }
156
144
  const shorter = target.length < candidate.length ? target : candidate;
157
145
  const longer = target.length < candidate.length ? candidate : target;
158
- // Containment only counts on separator boundaries, so `gpt-5` does not
159
- // swallow `gpt-5-mini` but `anthropic-claude-haiku-4-5-...-v1-0` still
160
- // matches a `us.`-prefixed configured id.
161
146
  if (shorter.length >= 4 && longer.includes(shorter)) {
162
147
  const index = longer.indexOf(shorter);
163
148
  const before = index === 0 || longer[index - 1] === "-";
@@ -173,7 +158,26 @@ function matchModelId(targets, candidateId) {
173
158
  }
174
159
  return best;
175
160
  }
176
- function catalogEntryToBilling(model) {
161
+ function catalogModalitiesToResolved(modalities) {
162
+ const inputs = new Set((modalities?.input ?? []).map((value) => value.toLowerCase()));
163
+ return {
164
+ text: inputs.size === 0 || inputs.has("text"),
165
+ image: inputs.has("image"),
166
+ pdf: inputs.has("pdf"),
167
+ audio: inputs.has("audio"),
168
+ video: inputs.has("video"),
169
+ };
170
+ }
171
+ function mergeResolvedModality(configured, resolved) {
172
+ return {
173
+ text: configured?.text ?? resolved?.text ?? true,
174
+ image: configured?.image ?? resolved?.image ?? false,
175
+ pdf: configured?.pdf ?? resolved?.pdf ?? false,
176
+ audio: configured?.audio ?? resolved?.audio ?? false,
177
+ video: configured?.video ?? resolved?.video ?? false,
178
+ };
179
+ }
180
+ function catalogEntryToMetadata(model) {
177
181
  const context = typeof model.limit?.context === "number" && model.limit.context > 0
178
182
  ? model.limit.context
179
183
  : undefined;
@@ -190,16 +194,14 @@ function catalogEntryToBilling(model) {
190
194
  outputPerM: cost.output,
191
195
  }
192
196
  : undefined;
193
- return { context, costs };
197
+ return {
198
+ context,
199
+ costs,
200
+ modality: catalogModalitiesToResolved(model.modalities),
201
+ };
194
202
  }
195
- /**
196
- * Find the best models.dev entry for a billing name. Providers are ranked by
197
- * match tier, then by whether the provider is the model's canonical lab
198
- * (`catalog.models` is keyed `lab/model-id`), then by closeness of the id
199
- * match, then by catalog order.
200
- */
201
- function lookupInCatalog(catalog, billingName) {
202
- const targets = targetForms(billingName);
203
+ function lookupInCatalog(catalog, metadataName) {
204
+ const targets = targetForms(metadataName);
203
205
  if (targets.length === 0) {
204
206
  return null;
205
207
  }
@@ -230,9 +232,9 @@ function lookupInCatalog(catalog, billingName) {
230
232
  const candidates = matches.filter((match) => match.tier === bestTier);
231
233
  const preferred = candidates.find((match) => labs.has(match.providerId)) ??
232
234
  candidates.reduce((best, match) => match.lengthDiff < best.lengthDiff ? match : best);
233
- const resolved = catalogEntryToBilling(preferred.model);
235
+ const resolved = catalogEntryToMetadata(preferred.model);
234
236
  return resolved.context === undefined && resolved.costs === undefined
235
- ? null
237
+ ? { ...resolved, modality: resolved.modality }
236
238
  : resolved;
237
239
  }
238
240
  function configCostsToResolved(costs) {
@@ -242,26 +244,11 @@ function configCostsToResolved(costs) {
242
244
  outputPerM: costs["output/m"],
243
245
  };
244
246
  }
245
- /**
246
- * Providers that run inference locally: their token usage costs nothing, so
247
- * catalog prices (which belong to the hosted API serving the same model)
248
- * must never be applied to them.
249
- */
250
247
  const LOCAL_PROVIDERS = new Set([
251
248
  LlmProvider.LlamaCpp,
252
249
  LlmProvider.Mlx,
253
250
  LlmProvider.Ollama,
254
251
  ]);
255
- /**
256
- * The context size configured on a resolved LLM entry, when the provider
257
- * actually honors one: for the local `llama-cpp` and `mlx` providers this is
258
- * the per-LLM `options.context` (falling back to the provider-level
259
- * `context`). Other providers' windows are fixed server-side, so config
260
- * context is ignored for them. Feed the result into
261
- * {@link resolveLlmBilling}'s `configuredContext` so the context gauge
262
- * reflects the actual runtime window rather than the catalog's training
263
- * window.
264
- */
265
252
  export function configuredLlmContext(llm) {
266
253
  if (llm.provider !== LlmProvider.LlamaCpp &&
267
254
  llm.provider !== LlmProvider.Mlx) {
@@ -271,27 +258,33 @@ export function configuredLlmContext(llm) {
271
258
  return llm.llmOptions.context ?? providerContext;
272
259
  }
273
260
  /**
274
- * Resolve billing metadata for a model: config-provided `billing` fields win,
275
- * anything missing is filled from the models.dev catalog, and the billing
276
- * name defaults to the raw model id when no `billing` block is configured.
261
+ * Resolve model metadata: config-provided `metadata` fields win, anything
262
+ * missing is filled from the models.dev catalog, and the metadata name
263
+ * defaults to the raw model id when no `metadata` block is configured.
277
264
  * Returns `null` when neither source yields a context size nor prices — in
278
- * that case nothing billing-related should be reported or displayed.
265
+ * that case nothing cost/context-related should be reported or displayed.
279
266
  *
280
267
  * When `provider` is a local provider (llama.cpp, Ollama), catalog costs are
281
268
  * discarded — the catalog prices the hosted API for the same model id, not
282
269
  * the free local inference — so only the context window resolves (config
283
- * `billing.costs`, if explicitly set, is still honored).
270
+ * `metadata.costs`, if explicitly set, is still honored).
284
271
  *
285
272
  * `configuredContext` (the runtime context actually configured on the LLM
286
273
  * entry — see {@link configuredLlmContext}) sits between the two sources:
287
- * an explicit `billing.context` wins over it, and it wins over the catalog.
274
+ * an explicit `metadata.context` wins over it, and it wins over the catalog.
275
+ * Modality always resolves, defaulting to text-only when unset.
288
276
  */
289
- export async function resolveLlmBilling(billing, modelId, provider, configuredContext) {
290
- const name = billing?.name ?? modelId;
277
+ export async function resolveLlmMetadata(metadata, modelId, provider, configuredContext) {
278
+ const name = metadata?.name ?? modelId;
291
279
  const isLocal = provider !== undefined && LOCAL_PROVIDERS.has(provider);
292
- let context = billing?.context ?? configuredContext;
293
- let costs = billing?.costs ? configCostsToResolved(billing.costs) : undefined;
294
- if (context === undefined || (costs === undefined && !isLocal)) {
280
+ let context = metadata?.context ?? configuredContext;
281
+ let costs = metadata?.costs
282
+ ? configCostsToResolved(metadata.costs)
283
+ : undefined;
284
+ let modality = mergeResolvedModality(metadata?.modality);
285
+ if (context === undefined ||
286
+ (costs === undefined && !isLocal) ||
287
+ metadata?.modality === undefined) {
295
288
  const catalog = await loadCatalog();
296
289
  const fromCatalog = catalog ? lookupInCatalog(catalog, name) : null;
297
290
  if (fromCatalog) {
@@ -299,19 +292,14 @@ export async function resolveLlmBilling(billing, modelId, provider, configuredCo
299
292
  if (!isLocal) {
300
293
  costs ??= fromCatalog.costs;
301
294
  }
295
+ modality = mergeResolvedModality(metadata?.modality, fromCatalog.modality);
302
296
  }
303
297
  }
304
298
  if (context === undefined && costs === undefined) {
305
299
  return null;
306
300
  }
307
- return { name, context, costs };
301
+ return { name, context, costs, modality };
308
302
  }
309
- /**
310
- * USD cost of one request's token usage. Expects usage already normalized to
311
- * the additive shape (see `toAdditiveUsage`): cache reads/writes are separate
312
- * from `inputTokens`. Cache tiers without an explicit price fall back to the
313
- * plain input rate.
314
- */
315
303
  export function computeUsageCostUsd(usage, costs) {
316
304
  const input = usage.inputTokens ?? 0;
317
305
  const output = usage.outputTokens ?? 0;
@@ -323,14 +311,9 @@ export function computeUsageCostUsd(usage, costs) {
323
311
  output * costs.outputPerM) /
324
312
  1_000_000);
325
313
  }
326
- /**
327
- * Context tokens occupied by a request, from its additive-shape usage: the
328
- * full prompt (uncached input + cache reads/writes). Used as the "tokens
329
- * currently in context" figure for context-window utilization.
330
- */
331
314
  export function contextTokensFromUsage(usage) {
332
315
  return ((usage.inputTokens ?? 0) +
333
316
  (usage.cacheReadInputTokens ?? 0) +
334
317
  (usage.cacheWriteInputTokens ?? 0));
335
318
  }
336
- //# sourceMappingURL=billing.js.map
319
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../src/core/utils/metadata.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { DocumentBlock, ImageBlock, TextBlock, VideoBlock, type DocumentFormat, type ImageFormat, type VideoFormat } from "@strands-agents/sdk";
2
+ import type { BlobResourceContents } from "@agentclientprotocol/sdk";
3
+ import type { ResolvedLlmMetadata } from "./metadata.js";
4
+ export type LlmInputModality = {
5
+ text?: boolean;
6
+ image?: boolean;
7
+ pdf?: boolean;
8
+ audio?: boolean;
9
+ video?: boolean;
10
+ };
11
+ export type ResolvedLlmInputModality = {
12
+ text: boolean;
13
+ image: boolean;
14
+ pdf: boolean;
15
+ audio: boolean;
16
+ video: boolean;
17
+ };
18
+ export type SupportedPromptBlock = TextBlock | ImageBlock | VideoBlock | DocumentBlock;
19
+ export type BinaryPromptTarget = {
20
+ bytes: Uint8Array;
21
+ label: string;
22
+ mimeType?: string;
23
+ sizeBytes: number;
24
+ path?: string;
25
+ context?: string;
26
+ };
27
+ export declare function resolveInputModality(metadata?: Pick<ResolvedLlmMetadata, "modality"> | null): ResolvedLlmInputModality;
28
+ export declare function imageFormatFromMime(mime: string): ImageFormat;
29
+ export declare function videoFormatFromMime(mime: string): VideoFormat | undefined;
30
+ export declare function documentFormatFromMime(mime: string): DocumentFormat;
31
+ export declare function binaryTargetToPromptBlocks(target: BinaryPromptTarget, modality?: Pick<ResolvedLlmMetadata, "modality"> | null): SupportedPromptBlock[];
32
+ export declare function attachmentPathToPromptBlocks(args: {
33
+ path: string;
34
+ bytes: Uint8Array;
35
+ sizeBytes: number;
36
+ metadata?: Pick<ResolvedLlmMetadata, "modality"> | null;
37
+ includeMetadata?: boolean;
38
+ }): SupportedPromptBlock[];
39
+ export declare function blobResourceToPromptBlocks(resource: BlobResourceContents, metadata?: Pick<ResolvedLlmMetadata, "modality"> | null): SupportedPromptBlock[];
@@ -0,0 +1,222 @@
1
+ import { basename } from "node:path";
2
+ import { DocumentBlock, ImageBlock, TextBlock, VideoBlock, } from "@strands-agents/sdk";
3
+ import { detectDocumentFormat, detectImageFormat, detectVideoFormat, } from "./file-formats.js";
4
+ const DEFAULT_MODALITY = {
5
+ text: true,
6
+ image: false,
7
+ pdf: false,
8
+ audio: false,
9
+ video: false,
10
+ };
11
+ export function resolveInputModality(metadata) {
12
+ return {
13
+ ...DEFAULT_MODALITY,
14
+ ...(metadata?.modality ?? {}),
15
+ };
16
+ }
17
+ export function imageFormatFromMime(mime) {
18
+ const m = mime.toLowerCase();
19
+ if (m.includes("jpeg") || m.includes("jpg"))
20
+ return "jpeg";
21
+ if (m.includes("gif"))
22
+ return "gif";
23
+ if (m.includes("webp"))
24
+ return "webp";
25
+ return "png";
26
+ }
27
+ export function videoFormatFromMime(mime) {
28
+ const m = mime.toLowerCase();
29
+ if (m.includes("mp4"))
30
+ return "mp4";
31
+ if (m.includes("webm"))
32
+ return "webm";
33
+ if (m.includes("quicktime") || m.includes("mov"))
34
+ return "mov";
35
+ if (m.includes("matroska") || m.includes("mkv"))
36
+ return "mkv";
37
+ if (m.includes("mpeg") || m.includes("mpg"))
38
+ return "mpeg";
39
+ if (m.includes("flv"))
40
+ return "flv";
41
+ if (m.includes("wmv"))
42
+ return "wmv";
43
+ if (m.includes("3gp"))
44
+ return "3gp";
45
+ return undefined;
46
+ }
47
+ export function documentFormatFromMime(mime) {
48
+ const m = mime.toLowerCase();
49
+ if (m.includes("pdf"))
50
+ return "pdf";
51
+ if (m.includes("csv"))
52
+ return "csv";
53
+ if (m.includes("wordprocessingml") || m.endsWith("/docx"))
54
+ return "docx";
55
+ if (m.includes("msword") || m.endsWith("/doc"))
56
+ return "doc";
57
+ if (m.includes("spreadsheetml") || m.endsWith("/xlsx"))
58
+ return "xlsx";
59
+ if (m.includes("ms-excel") || m.endsWith("/xls"))
60
+ return "xls";
61
+ if (m.includes("html"))
62
+ return "html";
63
+ if (m.includes("markdown") || m.endsWith("/md"))
64
+ return "md";
65
+ if (m.includes("json"))
66
+ return "json";
67
+ if (m.includes("xml"))
68
+ return "xml";
69
+ return "txt";
70
+ }
71
+ function fallbackText(target, reason, kind) {
72
+ const details = [
73
+ `Attached ${kind} not forwarded natively to the model:`,
74
+ `- label: ${target.label}`,
75
+ ...(target.path ? [`- path: ${target.path}`] : []),
76
+ ...(target.context ? [`- context: ${target.context}`] : []),
77
+ ...(target.mimeType ? [`- mime: ${target.mimeType}`] : []),
78
+ `- size_bytes: ${target.sizeBytes}`,
79
+ `- reason: ${reason}`,
80
+ "You can inspect this file using tools if needed.",
81
+ ];
82
+ return new TextBlock(details.join("\n"));
83
+ }
84
+ export function binaryTargetToPromptBlocks(target, modality) {
85
+ const resolved = resolveInputModality(modality);
86
+ const mime = (target.mimeType ?? "application/octet-stream").toLowerCase();
87
+ if (mime.startsWith("image/")) {
88
+ if (resolved.image) {
89
+ return [
90
+ new ImageBlock({
91
+ format: imageFormatFromMime(mime),
92
+ source: { bytes: target.bytes },
93
+ }),
94
+ ];
95
+ }
96
+ return [
97
+ fallbackText(target, "Current model does not support image input.", "image"),
98
+ ];
99
+ }
100
+ if (mime === "application/pdf") {
101
+ if (resolved.pdf) {
102
+ return [
103
+ new DocumentBlock({
104
+ format: "pdf",
105
+ name: target.label,
106
+ source: { bytes: target.bytes },
107
+ ...(target.context ? { context: target.context } : {}),
108
+ }),
109
+ ];
110
+ }
111
+ return [
112
+ fallbackText(target, "Current model does not support PDF input.", "pdf"),
113
+ ];
114
+ }
115
+ if (mime.startsWith("video/")) {
116
+ const format = videoFormatFromMime(mime);
117
+ if (resolved.video && format) {
118
+ return [new VideoBlock({ format, source: { bytes: target.bytes } })];
119
+ }
120
+ return [
121
+ fallbackText(target, "Current model does not support video input.", "video"),
122
+ ];
123
+ }
124
+ if (mime.startsWith("audio/")) {
125
+ return [
126
+ fallbackText(target, resolved.audio
127
+ ? "Audio input is not supported by the current Strands block mapping."
128
+ : "Current model does not support audio input.", "audio"),
129
+ ];
130
+ }
131
+ return [
132
+ fallbackText(target, "Unsupported binary type for native prompt forwarding.", "file"),
133
+ ];
134
+ }
135
+ export function attachmentPathToPromptBlocks(args) {
136
+ const { path, bytes, sizeBytes, metadata, includeMetadata = true } = args;
137
+ const imageFormat = detectImageFormat(path);
138
+ if (imageFormat) {
139
+ const blocks = binaryTargetToPromptBlocks({
140
+ bytes,
141
+ label: basename(path),
142
+ path,
143
+ sizeBytes,
144
+ mimeType: `image/${imageFormat === "jpeg" ? "jpeg" : imageFormat}`,
145
+ }, metadata);
146
+ return includeMetadata
147
+ ? [
148
+ new TextBlock(JSON.stringify({
149
+ path,
150
+ kind: "image",
151
+ format: imageFormat,
152
+ size_bytes: sizeBytes,
153
+ })),
154
+ ...blocks,
155
+ ]
156
+ : blocks;
157
+ }
158
+ const videoFormat = detectVideoFormat(path);
159
+ if (videoFormat) {
160
+ const blocks = binaryTargetToPromptBlocks({
161
+ bytes,
162
+ label: basename(path),
163
+ path,
164
+ sizeBytes,
165
+ mimeType: `video/${videoFormat === "mov" ? "quicktime" : videoFormat}`,
166
+ }, metadata);
167
+ return includeMetadata
168
+ ? [
169
+ new TextBlock(JSON.stringify({
170
+ path,
171
+ kind: "video",
172
+ format: videoFormat,
173
+ size_bytes: sizeBytes,
174
+ })),
175
+ ...blocks,
176
+ ]
177
+ : blocks;
178
+ }
179
+ const documentFormat = detectDocumentFormat(path);
180
+ if (documentFormat) {
181
+ const mimeType = documentFormat === "pdf"
182
+ ? "application/pdf"
183
+ : `application/${documentFormat}`;
184
+ const blocks = binaryTargetToPromptBlocks({
185
+ bytes,
186
+ label: basename(path),
187
+ path,
188
+ sizeBytes,
189
+ mimeType,
190
+ }, metadata);
191
+ return includeMetadata
192
+ ? [
193
+ new TextBlock(JSON.stringify({
194
+ path,
195
+ kind: "document",
196
+ format: documentFormat,
197
+ size_bytes: sizeBytes,
198
+ })),
199
+ ...blocks,
200
+ ]
201
+ : blocks;
202
+ }
203
+ return [
204
+ fallbackText({
205
+ bytes,
206
+ label: basename(path),
207
+ path,
208
+ sizeBytes,
209
+ }, "Unsupported attachment format.", "file"),
210
+ ];
211
+ }
212
+ export function blobResourceToPromptBlocks(resource, metadata) {
213
+ const bytes = new Uint8Array(Buffer.from(resource.blob, "base64"));
214
+ return binaryTargetToPromptBlocks({
215
+ bytes,
216
+ label: basename(resource.uri),
217
+ ...(resource.mimeType ? { mimeType: resource.mimeType } : {}),
218
+ sizeBytes: bytes.byteLength,
219
+ context: resource.uri,
220
+ }, metadata);
221
+ }
222
+ //# sourceMappingURL=model-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-metadata.js","sourceRoot":"","sources":["../../../src/core/utils/model-metadata.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ export declare const offloadedContentPath: () => string;
11
11
  export declare const attachmentsPath: () => string;
12
12
  export declare const plansPath: () => string;
13
13
  export declare const skillsPath: () => string;
14
+ export declare const localSkillsPath: (cwd?: string) => string;
14
15
  export declare const cachePath: () => string;
15
16
  export declare const binPath: () => string;
16
17
  export declare const ripgrepPath: () => string;
@@ -1,5 +1,6 @@
1
1
  import { homedir } from "os";
2
2
  import { join } from "path";
3
+ import { getCwd } from "./cwd-context.js";
3
4
  import { projectPath } from "./project-registry.js";
4
5
  export const APP_FOLDER = ".hooman";
5
6
  const HOOMAN_HOME_ENV = "HOOMAN_HOME";
@@ -24,6 +25,7 @@ export const offloadedContentPath = () => join(projectPath(), "offloaded-content
24
25
  export const attachmentsPath = () => join(projectPath(), "attachments");
25
26
  export const plansPath = () => join(projectPath(), "plans");
26
27
  export const skillsPath = () => join(basePath(), "skills");
28
+ export const localSkillsPath = (cwd = getCwd()) => join(cwd, APP_FOLDER, "skills");
27
29
  export const cachePath = () => join(basePath(), "cache");
28
30
  export const binPath = () => join(basePath(), "bin");
29
31
  export const ripgrepPath = () => join(binPath(), process.platform === "win32" ? "rg.exe" : "rg");
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/core/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC;AACpC,MAAM,eAAe,GAAG,aAAa,CAAC;AAEtC,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,EAAE;IAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC;IACtD,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,aAAa,CAAC,CAAC;AAEpE,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,iBAAiB,CAAC,CAAC;AAE5E,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,UAAU,CAAC,CAAC;AAE9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAEzE,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAE1E,+EAA+E;AAC/E,+EAA+E;AAC/E,oDAAoD;AACpD,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,UAAU,CAAC,CAAC;AAElE,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,CAAC;AAE9D,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,EAAE,CACvC,IAAI,CAAC,WAAW,EAAE,EAAE,mBAAmB,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,aAAa,CAAC,CAAC;AAExE,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;AAE3D,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;AAEzD,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;AAErD,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE,CAC9B,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/core/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC;AACpC,MAAM,eAAe,GAAG,aAAa,CAAC;AAEtC,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,EAAE;IAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC;IACtD,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,aAAa,CAAC,CAAC;AAEpE,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,iBAAiB,CAAC,CAAC;AAE5E,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,UAAU,CAAC,CAAC;AAE9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAEzE,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAE1E,+EAA+E;AAC/E,+EAA+E;AAC/E,oDAAoD;AACpD,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,UAAU,CAAC,CAAC;AAElE,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,CAAC;AAE9D,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,EAAE,CACvC,IAAI,CAAC,WAAW,EAAE,EAAE,mBAAmB,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,aAAa,CAAC,CAAC;AAExE,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;AAE3D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAc,MAAM,EAAE,EAAE,EAAE,CACxD,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AAElC,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;AAEzD,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;AAErD,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE,CAC9B,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC"}
@@ -34,11 +34,12 @@ export declare function activeLlm(config: Config): {
34
34
  options: {
35
35
  model: string;
36
36
  temperature?: number | undefined;
37
+ topP?: number | undefined;
37
38
  maxTokens?: number | undefined;
38
39
  context?: number | undefined;
39
40
  };
40
41
  default: boolean;
41
- billing?: {
42
+ metadata?: {
42
43
  name: string;
43
44
  context?: number | undefined;
44
45
  costs?: {
@@ -46,6 +47,13 @@ export declare function activeLlm(config: Config): {
46
47
  "output/m": number;
47
48
  "cache/m"?: number | undefined;
48
49
  } | undefined;
50
+ modality?: {
51
+ text?: boolean | undefined;
52
+ image?: boolean | undefined;
53
+ pdf?: boolean | undefined;
54
+ audio?: boolean | undefined;
55
+ video?: boolean | undefined;
56
+ } | undefined;
49
57
  } | null | undefined;
50
58
  } | undefined;
51
59
  /** Provider name backing the active LLM, if any is configured. */
@@ -7,7 +7,7 @@
7
7
  * - Total-inclusive (OpenAI, and every Vercel AI SDK adapter): `inputTokens`
8
8
  * is the full prompt and `cacheReadInputTokens` is a *subset* of it.
9
9
  *
10
- * Model factories register total-inclusive instances here so billing meters
10
+ * Model factories register total-inclusive instances here so metadata meters
11
11
  * can convert their usage to the additive shape before summing. This is done
12
12
  * only at the meter feed points — the raw usage must stay untouched for the
13
13
  * Strands agent loop, which uses `usage.inputTokens` as the context size for
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../src/core/utils/usage.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,MAAM,yBAAyB,GAAG,IAAI,OAAO,EAAU,CAAC;AAExD,2EAA2E;AAC3E,MAAM,UAAU,4BAA4B,CAAC,KAAa;IACxD,yBAAyB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAQ,EACR,KAAgC;IAEhC,IAAI,CAAC,KAAK,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,SAAS,GAAG,KAAK,CAAC,oBAAoB,IAAI,CAAC,CAAC;IAClD,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO;QACL,GAAG,KAAK;QACR,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI;YACrC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC;SACxD,CAAC;QACF,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI;YACrC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC;SACxD,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -1,8 +1,10 @@
1
1
  import { type Agent } from "@strands-agents/sdk";
2
2
  import type { Manager as McpManager } from "../core/mcp/index.js";
3
+ import { resolveLlmMetadata } from "../core/utils/metadata.js";
3
4
  type RunDaemonOptions = {
4
5
  agent: Agent;
5
6
  manager: McpManager;
7
+ metadata?: Awaited<ReturnType<typeof resolveLlmMetadata>>;
6
8
  session?: string;
7
9
  debug?: boolean;
8
10
  };