@zhafron/opencode-kiro-auth 1.4.5 → 1.4.6

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.
@@ -0,0 +1,14 @@
1
+ interface UnifiedImage {
2
+ mediaType: string;
3
+ data: string;
4
+ }
5
+ interface KiroImage {
6
+ format: string;
7
+ source: {
8
+ bytes: string;
9
+ };
10
+ }
11
+ export declare function extractAllImages(content: any): UnifiedImage[];
12
+ export declare function convertImagesToKiroFormat(images: UnifiedImage[]): KiroImage[];
13
+ export declare function extractTextFromParts(parts: any[]): string;
14
+ export {};
@@ -0,0 +1,64 @@
1
+ function extractImagesFromAnthropicFormat(content) {
2
+ const images = [];
3
+ for (const item of content) {
4
+ if (item.type === 'image' && item.source?.type === 'base64') {
5
+ images.push({
6
+ mediaType: item.source.media_type || 'image/jpeg',
7
+ data: item.source.data
8
+ });
9
+ }
10
+ }
11
+ return images;
12
+ }
13
+ function extractImagesFromOpenAI(content) {
14
+ const images = [];
15
+ for (const item of content) {
16
+ if (item.type === 'image_url' && item.image_url?.url) {
17
+ const url = item.image_url.url;
18
+ if (url.startsWith('data:')) {
19
+ try {
20
+ const [header, data] = url.split(',', 2);
21
+ if (!data)
22
+ continue;
23
+ const mediaType = header.split(';')[0].replace('data:', '');
24
+ images.push({
25
+ mediaType: mediaType || 'image/jpeg',
26
+ data: data
27
+ });
28
+ }
29
+ catch (e) {
30
+ continue;
31
+ }
32
+ }
33
+ }
34
+ }
35
+ return images;
36
+ }
37
+ export function extractAllImages(content) {
38
+ if (!Array.isArray(content))
39
+ return [];
40
+ return [...extractImagesFromAnthropicFormat(content), ...extractImagesFromOpenAI(content)];
41
+ }
42
+ export function convertImagesToKiroFormat(images) {
43
+ return images.map((img) => {
44
+ const format = img.mediaType.split('/')[1] || 'png';
45
+ return {
46
+ format,
47
+ source: {
48
+ bytes: img.data
49
+ }
50
+ };
51
+ });
52
+ }
53
+ export function extractTextFromParts(parts) {
54
+ const textParts = [];
55
+ for (const part of parts) {
56
+ if (part.text && typeof part.text === 'string') {
57
+ textParts.push(part.text);
58
+ }
59
+ else if (part.type === 'text' && part.text) {
60
+ textParts.push(part.text);
61
+ }
62
+ }
63
+ return textParts.join('');
64
+ }
@@ -1,6 +1,7 @@
1
1
  import * as crypto from 'crypto';
2
2
  import * as os from 'os';
3
3
  import { KIRO_CONSTANTS } from '../constants.js';
4
+ import { convertImagesToKiroFormat, extractAllImages, extractTextFromParts } from './image-handler.js';
4
5
  import { resolveKiroModel } from './models.js';
5
6
  function truncate(s, max) {
6
7
  if (s.length <= max)
@@ -112,28 +113,26 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
112
113
  continue;
113
114
  if (m.role === 'user') {
114
115
  const uim = { content: '', modelId: resolved, origin: KIRO_CONSTANTS.ORIGIN_AI_EDITOR };
115
- const trs = [], imgs = [];
116
+ const trs = [];
116
117
  if (Array.isArray(m.content)) {
118
+ uim.content = extractTextFromParts(m.content);
117
119
  for (const p of m.content) {
118
- if (p.type === 'text')
119
- uim.content += p.text || '';
120
- else if (p.type === 'tool_result')
120
+ if (p.type === 'tool_result') {
121
121
  trs.push({
122
122
  content: [{ text: truncate(getContentText(p.content || p), toolResultLimit) }],
123
123
  status: 'success',
124
124
  toolUseId: p.tool_use_id
125
125
  });
126
- else if (p.type === 'image' && p.source)
127
- imgs.push({
128
- format: p.source.media_type?.split('/')[1] || 'png',
129
- source: { bytes: p.source.data }
130
- });
126
+ }
127
+ }
128
+ const unifiedImages = extractAllImages(m.content);
129
+ if (unifiedImages.length > 0) {
130
+ uim.images = convertImagesToKiroFormat(unifiedImages);
131
131
  }
132
132
  }
133
- else
133
+ else {
134
134
  uim.content = getContentText(m);
135
- if (imgs.length)
136
- uim.images = imgs;
135
+ }
137
136
  if (trs.length)
138
137
  uim.userInputMessageContext = { toolResults: deduplicateToolResults(trs) };
139
138
  const prev = history[history.length - 1];
@@ -227,7 +226,8 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
227
226
  if (!curMsg)
228
227
  throw new Error('Empty');
229
228
  let curContent = '';
230
- const curTrs = [], curImgs = [];
229
+ const curTrs = [];
230
+ const curImgs = [];
231
231
  if (curMsg.role === 'assistant') {
232
232
  const arm = { content: '' };
233
233
  let th = '';
@@ -290,20 +290,19 @@ export function transformToCodeWhisperer(url, body, model, auth, think = false,
290
290
  }
291
291
  }
292
292
  else if (Array.isArray(curMsg.content)) {
293
+ curContent = extractTextFromParts(curMsg.content);
293
294
  for (const p of curMsg.content) {
294
- if (p.type === 'text')
295
- curContent += p.text || '';
296
- else if (p.type === 'tool_result')
295
+ if (p.type === 'tool_result') {
297
296
  curTrs.push({
298
297
  content: [{ text: truncate(getContentText(p.content || p), toolResultLimit) }],
299
298
  status: 'success',
300
299
  toolUseId: p.tool_use_id
301
300
  });
302
- else if (p.type === 'image' && p.source)
303
- curImgs.push({
304
- format: p.source.media_type?.split('/')[1] || 'png',
305
- source: { bytes: p.source.data }
306
- });
301
+ }
302
+ }
303
+ const unifiedImages = extractAllImages(curMsg.content);
304
+ if (unifiedImages.length > 0) {
305
+ curImgs.push(...convertImagesToKiroFormat(unifiedImages));
307
306
  }
308
307
  }
309
308
  else
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhafron/opencode-kiro-auth",
3
- "version": "1.4.5",
3
+ "version": "1.4.6",
4
4
  "description": "OpenCode plugin for AWS Kiro (CodeWhisperer) providing access to Claude models",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",