@theokit/sdk 4.6.1 → 4.7.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.7.1
4
+
5
+ ### Patch Changes
6
+
7
+ - ef7e172: M35 review follow-ups (fail-fast, no silent drop): a `{ url }` `SDKImage` is now forwarded as an `image_url` with the URL directly on OpenAI/OpenRouter (previously silently dropped in `buildUserContent`); and the ollama-native provider throws a typed `ConfigurationError` on an image part instead of silently discarding it (images require an OpenAI/OpenRouter model). `LlmImagePart.source` gains a `{ type: "url" }` variant.
8
+
9
+ ## 4.7.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 6871152: M35 (multimodal) — implement image input end-to-end. `agent.send({ text, images })` (the `SDKUserMessage` form) previously carried the `images` TYPE but the runtime dropped them (only `.text` was used). Now `prepareRunContext` carries the images, the agent loop attaches them as `image` content parts (new `LlmImagePart`), and the provider adapters serialize them: OpenAI/OpenRouter to a content-array with an `image_url` data URL, Anthropic to a native base64 image block. Text-only turns are byte-unchanged (back-compat). Zero new dependencies.
14
+
3
15
  ## 4.6.1
4
16
 
5
17
  ### Patch Changes
package/dist/cron.cjs CHANGED
@@ -4370,7 +4370,8 @@ function applyExtraRunFields(base, script) {
4370
4370
  // src/internal/runtime/fixtures/fixture-run-base.ts
4371
4371
  function prepareRunContext(message) {
4372
4372
  const userText = typeof message === "string" ? message : message.text;
4373
- return { userText, id: generateRunId(), startTime: Date.now() };
4373
+ const userImages = typeof message === "string" ? void 0 : message.images;
4374
+ return { userText, userImages, id: generateRunId(), startTime: Date.now() };
4374
4375
  }
4375
4376
  var FixtureRunBase = class {
4376
4377
  id;
@@ -9491,6 +9492,15 @@ function buildAssistantTurn(text, toolCalls) {
9491
9492
  }
9492
9493
 
9493
9494
  // src/internal/agent-loop/loop-context-init.ts
9495
+ function buildUserContent(text, images) {
9496
+ const content = [{ type: "text", text }];
9497
+ for (const img of images ?? []) {
9498
+ content.push(
9499
+ "data" in img ? { type: "image", source: { type: "base64", media_type: img.mimeType, data: img.data } } : { type: "image", source: { type: "url", url: img.url } }
9500
+ );
9501
+ }
9502
+ return content;
9503
+ }
9494
9504
  function buildAgentRef(inputs) {
9495
9505
  return {
9496
9506
  agentId: inputs.agentId,
@@ -9578,7 +9588,7 @@ async function initLoopContext(inputs) {
9578
9588
  conversation: [],
9579
9589
  messages: [
9580
9590
  ...priorMessages,
9581
- { role: "user", content: [{ type: "text", text: inputs.userMessage }] }
9591
+ { role: "user", content: buildUserContent(inputs.userMessage, inputs.userImages) }
9582
9592
  ],
9583
9593
  tools,
9584
9594
  finalText: "",
@@ -11599,6 +11609,9 @@ function toAnthropicWireMessage(message) {
11599
11609
  if (part.type === "tool_use") {
11600
11610
  return { type: "tool_use", id: part.id, name: part.name, input: part.input };
11601
11611
  }
11612
+ if (part.type === "image") {
11613
+ return { type: "image", source: part.source };
11614
+ }
11602
11615
  return {
11603
11616
  type: "tool_result",
11604
11617
  tool_use_id: part.toolUseId,
@@ -12142,6 +12155,9 @@ function readOpenAiContent(body) {
12142
12155
  return void 0;
12143
12156
  }
12144
12157
 
12158
+ // src/internal/llm/ollama-native.ts
12159
+ init_errors();
12160
+
12145
12161
  // src/internal/error-mappers/ollama.ts
12146
12162
  init_errors();
12147
12163
  function mapOllamaTransportError(args) {
@@ -12409,6 +12425,12 @@ function toOllamaMessages(message) {
12409
12425
  return [{ role: "system", content: joinTextParts(message) }];
12410
12426
  }
12411
12427
  if (message.role === "user") {
12428
+ if (message.content.some((p) => p.type === "image")) {
12429
+ throw new ConfigurationError(
12430
+ "image input is not supported on the ollama-native provider; use an OpenAI/OpenRouter model for multimodal turns",
12431
+ { code: "ollama_image_unsupported" }
12432
+ );
12433
+ }
12412
12434
  const out = [];
12413
12435
  for (const part of message.content) {
12414
12436
  if (part.type === "tool_result") {
@@ -12900,7 +12922,20 @@ function userOrToolMessages(message) {
12900
12922
  }
12901
12923
  }
12902
12924
  const userText = joinTextParts2(message);
12903
- if (userText.length > 0) out.push({ role: "user", content: userText });
12925
+ const imageParts = message.content.filter(
12926
+ (p) => p.type === "image"
12927
+ );
12928
+ if (imageParts.length > 0) {
12929
+ const content = [];
12930
+ if (userText.length > 0) content.push({ type: "text", text: userText });
12931
+ for (const img of imageParts) {
12932
+ const url = img.source.type === "base64" ? `data:${img.source.media_type};base64,${img.source.data}` : img.source.url;
12933
+ content.push({ type: "image_url", image_url: { url } });
12934
+ }
12935
+ out.push({ role: "user", content });
12936
+ } else if (userText.length > 0) {
12937
+ out.push({ role: "user", content: userText });
12938
+ }
12904
12939
  return out;
12905
12940
  }
12906
12941
  function assistantMessage(message) {
@@ -14086,7 +14121,7 @@ function buildCustomToolsInput(agentOptions, sendOptions, pluginManager, persona
14086
14121
 
14087
14122
  // src/internal/local-agent/real-local-run.ts
14088
14123
  function createRealLocalRun(options) {
14089
- const { userText, id, startTime } = prepareRunContext(options.message);
14124
+ const { userText, userImages, id, startTime } = prepareRunContext(options.message);
14090
14125
  const supported = /* @__PURE__ */ new Set(["stream", "wait", "cancel", "conversation"]);
14091
14126
  const runScript = {
14092
14127
  events: [],
@@ -14105,7 +14140,7 @@ function createRealLocalRun(options) {
14105
14140
  supportedOps: supported,
14106
14141
  startTime
14107
14142
  },
14108
- () => buildLoopInputs(options, id, userText)
14143
+ () => buildLoopInputs(options, id, userText, userImages)
14109
14144
  );
14110
14145
  handle.bootstrap();
14111
14146
  registerRun(handle);
@@ -14138,7 +14173,7 @@ function mergeExplicitApiKey(pools, primary, apiKey) {
14138
14173
  if (existing !== void 0 && existing.length > 0) return pools;
14139
14174
  return { ...pools ?? {}, [primary]: [apiKey] };
14140
14175
  }
14141
- function buildLoopInputs(options, runId, userText) {
14176
+ function buildLoopInputs(options, runId, userText, userImages) {
14142
14177
  const maxIterations = options.sendOptions.maxIterations;
14143
14178
  if (maxIterations !== void 0 && (!Number.isInteger(maxIterations) || maxIterations < 1)) {
14144
14179
  throw new ConfigurationError(
@@ -14177,6 +14212,7 @@ function buildLoopInputs(options, runId, userText) {
14177
14212
  ...options.model?.params !== void 0 ? { params: options.model.params } : {}
14178
14213
  },
14179
14214
  userMessage: userText,
14215
+ ...userImages !== void 0 ? { userImages } : {},
14180
14216
  llm,
14181
14217
  mcp: buildMcpMap(options),
14182
14218
  hooks: options.hooks,