@theokit/sdk 4.6.1 → 4.7.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 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.
8
+
3
9
  ## 4.6.1
4
10
 
5
11
  ### 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,18 @@ 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
+ if ("data" in img) {
9499
+ content.push({
9500
+ type: "image",
9501
+ source: { type: "base64", media_type: img.mimeType, data: img.data }
9502
+ });
9503
+ }
9504
+ }
9505
+ return content;
9506
+ }
9494
9507
  function buildAgentRef(inputs) {
9495
9508
  return {
9496
9509
  agentId: inputs.agentId,
@@ -9578,7 +9591,7 @@ async function initLoopContext(inputs) {
9578
9591
  conversation: [],
9579
9592
  messages: [
9580
9593
  ...priorMessages,
9581
- { role: "user", content: [{ type: "text", text: inputs.userMessage }] }
9594
+ { role: "user", content: buildUserContent(inputs.userMessage, inputs.userImages) }
9582
9595
  ],
9583
9596
  tools,
9584
9597
  finalText: "",
@@ -11599,6 +11612,9 @@ function toAnthropicWireMessage(message) {
11599
11612
  if (part.type === "tool_use") {
11600
11613
  return { type: "tool_use", id: part.id, name: part.name, input: part.input };
11601
11614
  }
11615
+ if (part.type === "image") {
11616
+ return { type: "image", source: part.source };
11617
+ }
11602
11618
  return {
11603
11619
  type: "tool_result",
11604
11620
  tool_use_id: part.toolUseId,
@@ -12900,7 +12916,20 @@ function userOrToolMessages(message) {
12900
12916
  }
12901
12917
  }
12902
12918
  const userText = joinTextParts2(message);
12903
- if (userText.length > 0) out.push({ role: "user", content: userText });
12919
+ const imageParts = message.content.filter((p) => p.type === "image");
12920
+ if (imageParts.length > 0) {
12921
+ const content = [];
12922
+ if (userText.length > 0) content.push({ type: "text", text: userText });
12923
+ for (const img of imageParts) {
12924
+ content.push({
12925
+ type: "image_url",
12926
+ image_url: { url: `data:${img.source.media_type};base64,${img.source.data}` }
12927
+ });
12928
+ }
12929
+ out.push({ role: "user", content });
12930
+ } else if (userText.length > 0) {
12931
+ out.push({ role: "user", content: userText });
12932
+ }
12904
12933
  return out;
12905
12934
  }
12906
12935
  function assistantMessage(message) {
@@ -14086,7 +14115,7 @@ function buildCustomToolsInput(agentOptions, sendOptions, pluginManager, persona
14086
14115
 
14087
14116
  // src/internal/local-agent/real-local-run.ts
14088
14117
  function createRealLocalRun(options) {
14089
- const { userText, id, startTime } = prepareRunContext(options.message);
14118
+ const { userText, userImages, id, startTime } = prepareRunContext(options.message);
14090
14119
  const supported = /* @__PURE__ */ new Set(["stream", "wait", "cancel", "conversation"]);
14091
14120
  const runScript = {
14092
14121
  events: [],
@@ -14105,7 +14134,7 @@ function createRealLocalRun(options) {
14105
14134
  supportedOps: supported,
14106
14135
  startTime
14107
14136
  },
14108
- () => buildLoopInputs(options, id, userText)
14137
+ () => buildLoopInputs(options, id, userText, userImages)
14109
14138
  );
14110
14139
  handle.bootstrap();
14111
14140
  registerRun(handle);
@@ -14138,7 +14167,7 @@ function mergeExplicitApiKey(pools, primary, apiKey) {
14138
14167
  if (existing !== void 0 && existing.length > 0) return pools;
14139
14168
  return { ...pools ?? {}, [primary]: [apiKey] };
14140
14169
  }
14141
- function buildLoopInputs(options, runId, userText) {
14170
+ function buildLoopInputs(options, runId, userText, userImages) {
14142
14171
  const maxIterations = options.sendOptions.maxIterations;
14143
14172
  if (maxIterations !== void 0 && (!Number.isInteger(maxIterations) || maxIterations < 1)) {
14144
14173
  throw new ConfigurationError(
@@ -14177,6 +14206,7 @@ function buildLoopInputs(options, runId, userText) {
14177
14206
  ...options.model?.params !== void 0 ? { params: options.model.params } : {}
14178
14207
  },
14179
14208
  userMessage: userText,
14209
+ ...userImages !== void 0 ? { userImages } : {},
14180
14210
  llm,
14181
14211
  mcp: buildMcpMap(options),
14182
14212
  hooks: options.hooks,