sambanova 1.0.2 → 1.0.4

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/README.md CHANGED
@@ -33,14 +33,14 @@ async function textExample() {
33
33
  console.log(response.choices[0].message.content);
34
34
  }
35
35
 
36
- // Vision analysis
36
+ // Vision analysis (supports online image URLs and local file paths)
37
37
  async function visionExample() {
38
38
  const response = await client.chat([
39
39
  {
40
40
  role: 'user',
41
41
  content: [
42
42
  { type: 'text', text: 'What is in this image?' },
43
- { type: 'image_url', image_url: { url: 'your_image_url_here' }}
43
+ { type: 'image_url', image_url: { url: 'https://example.com/sample.jpg' }} // Online image URL
44
44
  ]
45
45
  }
46
46
  ], {
@@ -56,7 +56,7 @@ async function visionExample() {
56
56
  - TypeScript support with full type definitions
57
57
  - Error handling and automatic retries
58
58
  - Streaming support
59
- - Vision model integration
59
+ - Vision model integration with **online image URLs** and **local file paths**
60
60
 
61
61
  ## Supported Models
62
62
 
@@ -71,6 +71,44 @@ async function visionExample() {
71
71
  - `Meta-Llama-3.2-1B-Instruct`
72
72
  - `Meta-Llama-3.2-3B-Instruct`
73
73
 
74
+ ## Vision Model Details
75
+
76
+ The vision models support both **online image URLs** and **local file paths**. The client automatically converts images to base64 format before sending the request.
77
+
78
+ ### Online Image URL Example
79
+
80
+ ```javascript
81
+ const response = await client.chat([
82
+ {
83
+ role: 'user',
84
+ content: [
85
+ { type: 'text', text: 'What is in this image?' },
86
+ { type: 'image_url', image_url: { url: 'https://example.com/sample.jpg' }} // Online URL
87
+ ]
88
+ }
89
+ ], {
90
+ model: 'Llama-3.2-11B-Vision-Instruct'
91
+ });
92
+ console.log(response.choices[0].message.content);
93
+ ```
94
+
95
+ ### Local Image File Example
96
+
97
+ ```javascript
98
+ const response = await client.chat([
99
+ {
100
+ role: 'user',
101
+ content: [
102
+ { type: 'text', text: 'What is in this image?' },
103
+ { type: 'image_url', image_url: { url: './path/to/image.jpg' }} // Local file path
104
+ ]
105
+ }
106
+ ], {
107
+ model: 'Llama-3.2-11B-Vision-Instruct'
108
+ });
109
+ console.log(response.choices[0].message.content);
110
+ ```
111
+
74
112
  ## Advanced Usage
75
113
 
76
114
  ### Streaming
@@ -117,4 +155,10 @@ const client = new SambanovaClient('YOUR_API_KEY', {
117
155
  defaultRetryCount: 3,
118
156
  defaultRetryDelay: 1000
119
157
  });
120
- ```
158
+ ```
159
+
160
+ ## Changes in Vision Model Usage
161
+
162
+ - **Online Image URL Support:** Provide a direct image URL (e.g., `https://example.com/image.jpg`).
163
+ - **Local File Path Support:** Provide a local file path (e.g., `./path/to/image.jpg`).
164
+ - The client automatically processes the image, converting it to base64 format before sending the request.
package/dist/client.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SambanovaClient = void 0;
4
4
  const utils_1 = require("./utils");
5
5
  const types_1 = require("./types");
6
+ const utils_2 = require("./utils");
6
7
  class SambanovaClient {
7
8
  constructor(apiKey, options = {}) {
8
9
  this.apiKey = apiKey;
@@ -43,16 +44,32 @@ class SambanovaClient {
43
44
  throw lastError || new Error('Request failed after retries');
44
45
  }
45
46
  async chat(messages, options = {}) {
46
- var _a, _b, _c;
47
+ var _a, _b, _c, _d;
47
48
  const model = options.model || this.defaultModel;
49
+ if ((0, utils_1.isVisionModel)(model)) {
50
+ for (const msg of messages) {
51
+ if (Array.isArray(msg.content)) {
52
+ for (const content of msg.content) {
53
+ if (content.type === 'image_url' && ((_a = content.image_url) === null || _a === void 0 ? void 0 : _a.url)) {
54
+ try {
55
+ content.image_url.url = await (0, utils_2.getBase64Image)(content.image_url.url);
56
+ }
57
+ catch (error) {
58
+ throw new types_1.SambanovaError(`Failed to process image: ${error}`, 400, 'INVALID_IMAGE_FORMAT');
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
48
65
  messages.forEach(msg => (0, utils_1.validateMessage)(msg, (0, utils_1.isVisionModel)(model)));
49
66
  const payload = {
50
67
  model,
51
68
  messages,
52
- temperature: (_a = options.temperature) !== null && _a !== void 0 ? _a : 0.1,
53
- top_p: (_b = options.top_p) !== null && _b !== void 0 ? _b : 0.1,
69
+ temperature: (_b = options.temperature) !== null && _b !== void 0 ? _b : 0.1,
70
+ top_p: (_c = options.top_p) !== null && _c !== void 0 ? _c : 0.1,
54
71
  max_tokens: options.max_tokens,
55
- stream: (_c = options.stream) !== null && _c !== void 0 ? _c : false
72
+ stream: (_d = options.stream) !== null && _d !== void 0 ? _d : false
56
73
  };
57
74
  const response = await this.makeRequest('/chat/completions', payload, options.retry_count, payload.stream);
58
75
  if (payload.stream && response instanceof Response) {
package/dist/utils.d.ts CHANGED
@@ -2,3 +2,4 @@ import { ModelType, ChatMessage } from './types';
2
2
  export declare const sleep: (ms: number) => Promise<unknown>;
3
3
  export declare const isVisionModel: (model: ModelType) => boolean;
4
4
  export declare const validateMessage: (message: ChatMessage, isVision: boolean) => void;
5
+ export declare const getBase64Image: (pathOrUrl: string) => Promise<string>;
package/dist/utils.js CHANGED
@@ -1,7 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateMessage = exports.isVisionModel = exports.sleep = void 0;
6
+ exports.getBase64Image = exports.validateMessage = exports.isVisionModel = exports.sleep = void 0;
4
7
  const types_1 = require("./types");
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const axios_1 = __importDefault(require("axios"));
5
10
  const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
6
11
  exports.sleep = sleep;
7
12
  const isVisionModel = (model) => {
@@ -19,3 +24,23 @@ const validateMessage = (message, isVision) => {
19
24
  }
20
25
  };
21
26
  exports.validateMessage = validateMessage;
27
+ const getBase64Image = async (pathOrUrl) => {
28
+ try {
29
+ if (pathOrUrl.startsWith('http')) {
30
+ const response = await axios_1.default.get(pathOrUrl, { responseType: 'arraybuffer' });
31
+ const base64Image = Buffer.from(response.data, 'binary').toString('base64');
32
+ const mimeType = response.headers['content-type'];
33
+ return `data:${mimeType};base64,${base64Image}`;
34
+ }
35
+ else {
36
+ const image = fs_1.default.readFileSync(pathOrUrl);
37
+ const base64Image = image.toString('base64');
38
+ const mimeType = 'image/jpeg';
39
+ return `data:${mimeType};base64,${base64Image}`;
40
+ }
41
+ }
42
+ catch (error) {
43
+ throw new Error(`Failed to process image: ${pathOrUrl}. Error: ${error}`);
44
+ }
45
+ };
46
+ exports.getBase64Image = getBase64Image;
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "sambanova",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "TypeScript/Javascript client for Sambanova AI API with comprehensive model support",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
5
+ "main": "dist/client.js",
6
+ "types": "dist/client.d.ts",
7
7
  "scripts": {
8
8
  "build": "tsc",
9
9
  "test": "jest",
@@ -21,6 +21,7 @@
21
21
  "author": "Aaditya Srivastava",
22
22
  "license": "MIT",
23
23
  "dependencies": {
24
+ "axios": "^1.7.7",
24
25
  "node-fetch": "^2.7.0"
25
26
  },
26
27
  "devDependencies": {
package/src/client.ts CHANGED
@@ -7,6 +7,8 @@ import {
7
7
  SambanovaError
8
8
  } from './types';
9
9
 
10
+ import { getBase64Image } from './utils';
11
+
10
12
  export class SambanovaClient {
11
13
  private readonly baseUrl: string;
12
14
  private readonly defaultModel: ModelType;
@@ -79,9 +81,29 @@ export class SambanovaClient {
79
81
  options: ChatOptions = {}
80
82
  ): Promise<APIResponse> {
81
83
  const model = options.model || this.defaultModel;
82
-
84
+
85
+ if (isVisionModel(model)) {
86
+ for (const msg of messages) {
87
+ if (Array.isArray(msg.content)) {
88
+ for (const content of msg.content) {
89
+ if (content.type === 'image_url' && content.image_url?.url) {
90
+ try {
91
+ content.image_url.url = await getBase64Image(content.image_url.url);
92
+ } catch (error) {
93
+ throw new SambanovaError(
94
+ `Failed to process image: ${error}`,
95
+ 400,
96
+ 'INVALID_IMAGE_FORMAT'
97
+ );
98
+ }
99
+ }
100
+ }
101
+ }
102
+ }
103
+ }
104
+
83
105
  messages.forEach(msg => validateMessage(msg, isVisionModel(model)));
84
-
106
+
85
107
  const payload = {
86
108
  model,
87
109
  messages,
@@ -90,18 +112,18 @@ export class SambanovaClient {
90
112
  max_tokens: options.max_tokens,
91
113
  stream: options.stream ?? false
92
114
  };
93
-
115
+
94
116
  const response = await this.makeRequest(
95
117
  '/chat/completions',
96
118
  payload,
97
119
  options.retry_count,
98
120
  payload.stream
99
121
  );
100
-
122
+
101
123
  if (payload.stream && response instanceof Response) {
102
124
  throw new Error('Stream response received in chat method. Use streamChat instead.');
103
125
  }
104
-
126
+
105
127
  return response as APIResponse;
106
128
  }
107
129
 
package/src/types.ts CHANGED
@@ -16,7 +16,7 @@ export interface MessageContent {
16
16
  type: 'text' | 'image_url';
17
17
  text?: string;
18
18
  image_url?: {
19
- url: string;
19
+ url: string;
20
20
  };
21
21
  }
22
22
 
package/src/utils.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { ModelType, ChatMessage, SambanovaError } from './types';
2
+ import fs from 'fs';
3
+ import axios from 'axios';
2
4
 
3
5
  export const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
4
6
 
@@ -22,4 +24,22 @@ export const validateMessage = (message: ChatMessage, isVision: boolean) => {
22
24
  'INVALID_MESSAGE_FORMAT'
23
25
  );
24
26
  }
27
+ };
28
+
29
+ export const getBase64Image = async (pathOrUrl: string): Promise<string> => {
30
+ try {
31
+ if (pathOrUrl.startsWith('http')) {
32
+ const response = await axios.get(pathOrUrl, { responseType: 'arraybuffer' });
33
+ const base64Image = Buffer.from(response.data, 'binary').toString('base64');
34
+ const mimeType = response.headers['content-type'];
35
+ return `data:${mimeType};base64,${base64Image}`;
36
+ } else {
37
+ const image = fs.readFileSync(pathOrUrl);
38
+ const base64Image = image.toString('base64');
39
+ const mimeType = 'image/jpeg';
40
+ return `data:${mimeType};base64,${base64Image}`;
41
+ }
42
+ } catch (error) {
43
+ throw new Error(`Failed to process image: ${pathOrUrl}. Error: ${error}`);
44
+ }
25
45
  };