@bowenqt/qiniu-ai-sdk 0.14.0 → 0.16.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/dist/ai/agent-graph.d.ts +8 -0
- package/dist/ai/agent-graph.d.ts.map +1 -1
- package/dist/ai/agent-graph.js +23 -3
- package/dist/ai/agent-graph.js.map +1 -1
- package/dist/ai/agent-graph.mjs +23 -3
- package/dist/ai/create-agent.d.ts +101 -0
- package/dist/ai/create-agent.d.ts.map +1 -0
- package/dist/ai/create-agent.js +88 -0
- package/dist/ai/create-agent.js.map +1 -0
- package/dist/ai/create-agent.mjs +85 -0
- package/dist/ai/generate-object.d.ts +99 -0
- package/dist/ai/generate-object.d.ts.map +1 -0
- package/dist/ai/generate-object.js +237 -0
- package/dist/ai/generate-object.js.map +1 -0
- package/dist/ai/generate-object.mjs +201 -0
- package/dist/ai/generate-text.d.ts +13 -1
- package/dist/ai/generate-text.d.ts.map +1 -1
- package/dist/ai/generate-text.js +35 -5
- package/dist/ai/generate-text.js.map +1 -1
- package/dist/ai/generate-text.mjs +35 -5
- package/dist/ai/graph/checkpointer.d.ts +72 -2
- package/dist/ai/graph/checkpointer.d.ts.map +1 -1
- package/dist/ai/graph/checkpointer.js +99 -1
- package/dist/ai/graph/checkpointer.js.map +1 -1
- package/dist/ai/graph/checkpointer.mjs +96 -1
- package/dist/ai/graph/index.d.ts +2 -2
- package/dist/ai/graph/index.d.ts.map +1 -1
- package/dist/ai/graph/index.js +5 -1
- package/dist/ai/graph/index.js.map +1 -1
- package/dist/ai/graph/index.mjs +3 -1
- package/dist/ai/graph/postgres-checkpointer.d.ts +1 -1
- package/dist/ai/graph/postgres-checkpointer.d.ts.map +1 -1
- package/dist/ai/graph/postgres-checkpointer.js +13 -3
- package/dist/ai/graph/postgres-checkpointer.js.map +1 -1
- package/dist/ai/graph/postgres-checkpointer.mjs +13 -3
- package/dist/ai/graph/redis-checkpointer.d.ts +1 -1
- package/dist/ai/graph/redis-checkpointer.d.ts.map +1 -1
- package/dist/ai/graph/redis-checkpointer.js +6 -2
- package/dist/ai/graph/redis-checkpointer.js.map +1 -1
- package/dist/ai/graph/redis-checkpointer.mjs +6 -2
- package/dist/ai/internal-types.d.ts +14 -0
- package/dist/ai/internal-types.d.ts.map +1 -1
- package/dist/ai/internal-types.js +15 -0
- package/dist/ai/internal-types.js.map +1 -1
- package/dist/ai/internal-types.mjs +13 -0
- package/dist/ai/memory/index.d.ts +147 -0
- package/dist/ai/memory/index.d.ts.map +1 -0
- package/dist/ai/memory/index.js +240 -0
- package/dist/ai/memory/index.js.map +1 -0
- package/dist/ai/memory/index.mjs +234 -0
- package/dist/ai/nodes/execute-node.d.ts +2 -1
- package/dist/ai/nodes/execute-node.d.ts.map +1 -1
- package/dist/ai/nodes/execute-node.js +11 -33
- package/dist/ai/nodes/execute-node.js.map +1 -1
- package/dist/ai/nodes/execute-node.mjs +11 -33
- package/dist/ai/nodes/memory-node.d.ts.map +1 -1
- package/dist/ai/nodes/memory-node.js +14 -16
- package/dist/ai/nodes/memory-node.js.map +1 -1
- package/dist/ai/nodes/memory-node.mjs +15 -17
- package/dist/ai/stream-object.d.ts +109 -0
- package/dist/ai/stream-object.d.ts.map +1 -0
- package/dist/ai/stream-object.js +383 -0
- package/dist/ai/stream-object.js.map +1 -0
- package/dist/ai/stream-object.mjs +347 -0
- package/dist/ai/tool-approval.d.ts +90 -0
- package/dist/ai/tool-approval.d.ts.map +1 -0
- package/dist/ai/tool-approval.js +151 -0
- package/dist/ai/tool-approval.js.map +1 -0
- package/dist/ai/tool-approval.mjs +147 -0
- package/dist/index.d.ts +17 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -4
- package/dist/lib/capability-cache.d.ts +72 -0
- package/dist/lib/capability-cache.d.ts.map +1 -0
- package/dist/lib/capability-cache.js +117 -0
- package/dist/lib/capability-cache.js.map +1 -0
- package/dist/lib/capability-cache.mjs +113 -0
- package/dist/lib/content-converter.d.ts +33 -0
- package/dist/lib/content-converter.d.ts.map +1 -0
- package/dist/lib/content-converter.js +166 -0
- package/dist/lib/content-converter.js.map +1 -0
- package/dist/lib/content-converter.mjs +161 -0
- package/dist/lib/errors.d.ts +15 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +13 -1
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/errors.mjs +11 -0
- package/dist/lib/messages.js +4 -3
- package/dist/lib/messages.js.map +1 -1
- package/dist/lib/messages.mjs +4 -3
- package/dist/lib/partial-json-parser.d.ts +63 -0
- package/dist/lib/partial-json-parser.d.ts.map +1 -0
- package/dist/lib/partial-json-parser.js +142 -0
- package/dist/lib/partial-json-parser.js.map +1 -0
- package/dist/lib/partial-json-parser.mjs +137 -0
- package/dist/lib/token-estimator.d.ts.map +1 -1
- package/dist/lib/token-estimator.js +3 -2
- package/dist/lib/token-estimator.js.map +1 -1
- package/dist/lib/token-estimator.mjs +3 -2
- package/dist/lib/tool-registry.d.ts +21 -0
- package/dist/lib/tool-registry.d.ts.map +1 -1
- package/dist/lib/tool-registry.js.map +1 -1
- package/dist/lib/types.d.ts +20 -4
- package/dist/lib/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability cache for model feature detection.
|
|
3
|
+
* Caches model capabilities per client/baseUrl to avoid redundant probing.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* import { capabilityCache } from './capability-cache.mjs';
|
|
8
|
+
*
|
|
9
|
+
* // Check if model supports streaming JSON
|
|
10
|
+
* const supports = capabilityCache.get(client, 'gemini-2.5-flash', 'stream_json_schema');
|
|
11
|
+
*
|
|
12
|
+
* // Cache result after probing
|
|
13
|
+
* capabilityCache.set(client, 'gemini-2.5-flash', 'stream_json_schema', true);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Default TTL for cache entries (1 hour).
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_TTL_MS = 60 * 60 * 1000;
|
|
20
|
+
/**
|
|
21
|
+
* Capability cache implementation.
|
|
22
|
+
* Scoped by baseUrl + model + capability to avoid cross-provider contamination.
|
|
23
|
+
*/
|
|
24
|
+
class CapabilityCache {
|
|
25
|
+
constructor(ttlMs = DEFAULT_TTL_MS) {
|
|
26
|
+
this.cache = new Map();
|
|
27
|
+
this.ttlMs = ttlMs;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Generate cache key from client, model, and capability.
|
|
31
|
+
*/
|
|
32
|
+
getKey(client, model, capability) {
|
|
33
|
+
const baseUrl = client.getBaseUrl();
|
|
34
|
+
return `${baseUrl}:${model}:${capability}`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get cached capability status.
|
|
38
|
+
* Returns undefined if not cached or expired.
|
|
39
|
+
*/
|
|
40
|
+
get(client, model, capability) {
|
|
41
|
+
const key = this.getKey(client, model, capability);
|
|
42
|
+
const entry = this.cache.get(key);
|
|
43
|
+
if (!entry) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
// Check expiration
|
|
47
|
+
if (Date.now() - entry.timestamp > this.ttlMs) {
|
|
48
|
+
this.cache.delete(key);
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
return entry.supported;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Set capability status.
|
|
55
|
+
*/
|
|
56
|
+
set(client, model, capability, supported) {
|
|
57
|
+
const key = this.getKey(client, model, capability);
|
|
58
|
+
this.cache.set(key, {
|
|
59
|
+
supported,
|
|
60
|
+
timestamp: Date.now(),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if capability is cached and supported.
|
|
65
|
+
*/
|
|
66
|
+
isSupported(client, model, capability) {
|
|
67
|
+
return this.get(client, model, capability) === true;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if capability is cached and not supported.
|
|
71
|
+
*/
|
|
72
|
+
isNotSupported(client, model, capability) {
|
|
73
|
+
return this.get(client, model, capability) === false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Clear all cached entries.
|
|
77
|
+
*/
|
|
78
|
+
clear() {
|
|
79
|
+
this.cache.clear();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Clear entries for a specific client.
|
|
83
|
+
*/
|
|
84
|
+
clearForClient(client) {
|
|
85
|
+
const baseUrl = client.getBaseUrl();
|
|
86
|
+
const keysToDelete = [];
|
|
87
|
+
for (const key of this.cache.keys()) {
|
|
88
|
+
if (key.startsWith(baseUrl + ':')) {
|
|
89
|
+
keysToDelete.push(key);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
for (const key of keysToDelete) {
|
|
93
|
+
this.cache.delete(key);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get cache size.
|
|
98
|
+
*/
|
|
99
|
+
size() {
|
|
100
|
+
return this.cache.size;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Global capability cache instance.
|
|
105
|
+
*/
|
|
106
|
+
export const capabilityCache = new CapabilityCache();
|
|
107
|
+
/**
|
|
108
|
+
* Create a new capability cache with custom TTL (for testing).
|
|
109
|
+
*/
|
|
110
|
+
export function createCapabilityCache(ttlMs) {
|
|
111
|
+
return new CapabilityCache(ttlMs);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=capability-cache.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content converter for multimodal messages.
|
|
3
|
+
* Normalizes SDK convenience formats to API-compatible formats.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* import { normalizeContent } from './content-converter';
|
|
8
|
+
*
|
|
9
|
+
* const content: ContentPart[] = [
|
|
10
|
+
* { type: 'text', text: 'Describe this image' },
|
|
11
|
+
* { type: 'image', image: fs.readFileSync('photo.jpg') },
|
|
12
|
+
* ];
|
|
13
|
+
*
|
|
14
|
+
* const normalized = normalizeContent(content);
|
|
15
|
+
* // [{ type: 'text', text: '...' }, { type: 'image_url', image_url: { url: 'data:...' } }]
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import type { ContentPart } from './types';
|
|
19
|
+
/**
|
|
20
|
+
* Normalize content parts for API calls.
|
|
21
|
+
* Converts `image` sugar format to `image_url` API format.
|
|
22
|
+
*/
|
|
23
|
+
export declare function normalizeContent(content: string | ContentPart[]): string | ContentPart[];
|
|
24
|
+
/**
|
|
25
|
+
* Helper to convert Blob to data URL asynchronously (for browser use).
|
|
26
|
+
* Only available in browser environments.
|
|
27
|
+
*/
|
|
28
|
+
export declare function blobToDataUrl(blob: Blob): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Check if content contains any image parts that need normalization.
|
|
31
|
+
*/
|
|
32
|
+
export declare function hasImageParts(content: string | ContentPart[]): boolean;
|
|
33
|
+
//# sourceMappingURL=content-converter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-converter.d.ts","sourceRoot":"","sources":["../../src/lib/content-converter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAoC,MAAM,SAAS,CAAC;AAE7E;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,GAAG,MAAM,GAAG,WAAW,EAAE,CAQxF;AA+HD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAa/D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,GAAG,OAAO,CAKtE"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Content converter for multimodal messages.
|
|
4
|
+
* Normalizes SDK convenience formats to API-compatible formats.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { normalizeContent } from './content-converter';
|
|
9
|
+
*
|
|
10
|
+
* const content: ContentPart[] = [
|
|
11
|
+
* { type: 'text', text: 'Describe this image' },
|
|
12
|
+
* { type: 'image', image: fs.readFileSync('photo.jpg') },
|
|
13
|
+
* ];
|
|
14
|
+
*
|
|
15
|
+
* const normalized = normalizeContent(content);
|
|
16
|
+
* // [{ type: 'text', text: '...' }, { type: 'image_url', image_url: { url: 'data:...' } }]
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.normalizeContent = normalizeContent;
|
|
21
|
+
exports.blobToDataUrl = blobToDataUrl;
|
|
22
|
+
exports.hasImageParts = hasImageParts;
|
|
23
|
+
/**
|
|
24
|
+
* Normalize content parts for API calls.
|
|
25
|
+
* Converts `image` sugar format to `image_url` API format.
|
|
26
|
+
*/
|
|
27
|
+
function normalizeContent(content) {
|
|
28
|
+
// String content doesn't need normalization
|
|
29
|
+
if (typeof content === 'string') {
|
|
30
|
+
return content;
|
|
31
|
+
}
|
|
32
|
+
// Normalize each content part
|
|
33
|
+
return content.map(part => normalizeContentPart(part));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Normalize a single content part.
|
|
37
|
+
*/
|
|
38
|
+
function normalizeContentPart(part) {
|
|
39
|
+
// Already in API format
|
|
40
|
+
if (part.type === 'text' || part.type === 'image_url') {
|
|
41
|
+
return part;
|
|
42
|
+
}
|
|
43
|
+
// Convert image sugar to image_url
|
|
44
|
+
if (part.type === 'image') {
|
|
45
|
+
return {
|
|
46
|
+
type: 'image_url',
|
|
47
|
+
image_url: {
|
|
48
|
+
url: imageSourceToDataUrl(part.image),
|
|
49
|
+
detail: part.detail,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// Unknown type, return as-is
|
|
54
|
+
return part;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Convert ImageSource to data URL.
|
|
58
|
+
*/
|
|
59
|
+
function imageSourceToDataUrl(source) {
|
|
60
|
+
// Already a string (base64 or URL)
|
|
61
|
+
if (typeof source === 'string') {
|
|
62
|
+
// Check if it's already a data URL or regular URL
|
|
63
|
+
if (source.startsWith('data:') || source.startsWith('http://') || source.startsWith('https://')) {
|
|
64
|
+
return source;
|
|
65
|
+
}
|
|
66
|
+
// Assume base64, wrap in data URL
|
|
67
|
+
return `data:image/png;base64,${source}`;
|
|
68
|
+
}
|
|
69
|
+
// URL object
|
|
70
|
+
if (source instanceof URL) {
|
|
71
|
+
return source.toString();
|
|
72
|
+
}
|
|
73
|
+
// Blob (browser)
|
|
74
|
+
if (typeof Blob !== 'undefined' && source instanceof Blob) {
|
|
75
|
+
// Note: Synchronous conversion not possible for Blob
|
|
76
|
+
// For real usage, caller should pre-convert to base64
|
|
77
|
+
throw new Error('Blob must be converted to base64 before passing to normalizeContent. Use blobToDataUrl() helper.');
|
|
78
|
+
}
|
|
79
|
+
// ArrayBuffer or Uint8Array
|
|
80
|
+
if (source instanceof ArrayBuffer) {
|
|
81
|
+
return arrayBufferToDataUrl(new Uint8Array(source));
|
|
82
|
+
}
|
|
83
|
+
if (source instanceof Uint8Array) {
|
|
84
|
+
return arrayBufferToDataUrl(source);
|
|
85
|
+
}
|
|
86
|
+
throw new Error(`Unsupported image source type: ${typeof source}`);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Convert Uint8Array to data URL.
|
|
90
|
+
*/
|
|
91
|
+
function arrayBufferToDataUrl(buffer) {
|
|
92
|
+
// Detect MIME type from magic bytes
|
|
93
|
+
const mimeType = detectMimeType(buffer);
|
|
94
|
+
// Convert to base64
|
|
95
|
+
const base64 = uint8ArrayToBase64(buffer);
|
|
96
|
+
return `data:${mimeType};base64,${base64}`;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Detect image MIME type from magic bytes.
|
|
100
|
+
*/
|
|
101
|
+
function detectMimeType(buffer) {
|
|
102
|
+
if (buffer.length < 4) {
|
|
103
|
+
return 'application/octet-stream';
|
|
104
|
+
}
|
|
105
|
+
// PNG: 89 50 4E 47
|
|
106
|
+
if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4E && buffer[3] === 0x47) {
|
|
107
|
+
return 'image/png';
|
|
108
|
+
}
|
|
109
|
+
// JPEG: FF D8 FF
|
|
110
|
+
if (buffer[0] === 0xFF && buffer[1] === 0xD8 && buffer[2] === 0xFF) {
|
|
111
|
+
return 'image/jpeg';
|
|
112
|
+
}
|
|
113
|
+
// GIF: 47 49 46 38
|
|
114
|
+
if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46 && buffer[3] === 0x38) {
|
|
115
|
+
return 'image/gif';
|
|
116
|
+
}
|
|
117
|
+
// WebP: 52 49 46 46 ... 57 45 42 50
|
|
118
|
+
if (buffer[0] === 0x52 && buffer[1] === 0x49 && buffer[2] === 0x46 && buffer[3] === 0x46 &&
|
|
119
|
+
buffer.length > 11 && buffer[8] === 0x57 && buffer[9] === 0x45 && buffer[10] === 0x42 && buffer[11] === 0x50) {
|
|
120
|
+
return 'image/webp';
|
|
121
|
+
}
|
|
122
|
+
return 'image/png'; // Default fallback
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Convert Uint8Array to base64 string.
|
|
126
|
+
* Works in both Node.js and browser environments.
|
|
127
|
+
*/
|
|
128
|
+
function uint8ArrayToBase64(buffer) {
|
|
129
|
+
// Node.js environment
|
|
130
|
+
if (typeof Buffer !== 'undefined') {
|
|
131
|
+
return Buffer.from(buffer).toString('base64');
|
|
132
|
+
}
|
|
133
|
+
// Browser environment
|
|
134
|
+
let binary = '';
|
|
135
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
136
|
+
binary += String.fromCharCode(buffer[i]);
|
|
137
|
+
}
|
|
138
|
+
return btoa(binary);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Helper to convert Blob to data URL asynchronously (for browser use).
|
|
142
|
+
* Only available in browser environments.
|
|
143
|
+
*/
|
|
144
|
+
async function blobToDataUrl(blob) {
|
|
145
|
+
// Check if FileReader is available (browser environment)
|
|
146
|
+
const FR = globalThis.FileReader;
|
|
147
|
+
if (!FR) {
|
|
148
|
+
throw new Error('blobToDataUrl is only available in browser environments');
|
|
149
|
+
}
|
|
150
|
+
return new Promise((resolve, reject) => {
|
|
151
|
+
const reader = new FR();
|
|
152
|
+
reader.onloadend = () => resolve(reader.result);
|
|
153
|
+
reader.onerror = reject;
|
|
154
|
+
reader.readAsDataURL(blob);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if content contains any image parts that need normalization.
|
|
159
|
+
*/
|
|
160
|
+
function hasImageParts(content) {
|
|
161
|
+
if (typeof content === 'string') {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
return content.some(part => part.type === 'image');
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=content-converter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-converter.js","sourceRoot":"","sources":["../../src/lib/content-converter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content converter for multimodal messages.
|
|
3
|
+
* Normalizes SDK convenience formats to API-compatible formats.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* import { normalizeContent } from './content-converter.mjs';
|
|
8
|
+
*
|
|
9
|
+
* const content: ContentPart[] = [
|
|
10
|
+
* { type: 'text', text: 'Describe this image' },
|
|
11
|
+
* { type: 'image', image: fs.readFileSync('photo.jpg') },
|
|
12
|
+
* ];
|
|
13
|
+
*
|
|
14
|
+
* const normalized = normalizeContent(content);
|
|
15
|
+
* // [{ type: 'text', text: '...' }, { type: 'image_url', image_url: { url: 'data:...' } }]
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Normalize content parts for API calls.
|
|
20
|
+
* Converts `image` sugar format to `image_url` API format.
|
|
21
|
+
*/
|
|
22
|
+
export function normalizeContent(content) {
|
|
23
|
+
// String content doesn't need normalization
|
|
24
|
+
if (typeof content === 'string') {
|
|
25
|
+
return content;
|
|
26
|
+
}
|
|
27
|
+
// Normalize each content part
|
|
28
|
+
return content.map(part => normalizeContentPart(part));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Normalize a single content part.
|
|
32
|
+
*/
|
|
33
|
+
function normalizeContentPart(part) {
|
|
34
|
+
// Already in API format
|
|
35
|
+
if (part.type === 'text' || part.type === 'image_url') {
|
|
36
|
+
return part;
|
|
37
|
+
}
|
|
38
|
+
// Convert image sugar to image_url
|
|
39
|
+
if (part.type === 'image') {
|
|
40
|
+
return {
|
|
41
|
+
type: 'image_url',
|
|
42
|
+
image_url: {
|
|
43
|
+
url: imageSourceToDataUrl(part.image),
|
|
44
|
+
detail: part.detail,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Unknown type, return as-is
|
|
49
|
+
return part;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Convert ImageSource to data URL.
|
|
53
|
+
*/
|
|
54
|
+
function imageSourceToDataUrl(source) {
|
|
55
|
+
// Already a string (base64 or URL)
|
|
56
|
+
if (typeof source === 'string') {
|
|
57
|
+
// Check if it's already a data URL or regular URL
|
|
58
|
+
if (source.startsWith('data:') || source.startsWith('http://') || source.startsWith('https://')) {
|
|
59
|
+
return source;
|
|
60
|
+
}
|
|
61
|
+
// Assume base64, wrap in data URL
|
|
62
|
+
return `data:image/png;base64,${source}`;
|
|
63
|
+
}
|
|
64
|
+
// URL object
|
|
65
|
+
if (source instanceof URL) {
|
|
66
|
+
return source.toString();
|
|
67
|
+
}
|
|
68
|
+
// Blob (browser)
|
|
69
|
+
if (typeof Blob !== 'undefined' && source instanceof Blob) {
|
|
70
|
+
// Note: Synchronous conversion not possible for Blob
|
|
71
|
+
// For real usage, caller should pre-convert to base64
|
|
72
|
+
throw new Error('Blob must be converted to base64 before passing to normalizeContent. Use blobToDataUrl() helper.');
|
|
73
|
+
}
|
|
74
|
+
// ArrayBuffer or Uint8Array
|
|
75
|
+
if (source instanceof ArrayBuffer) {
|
|
76
|
+
return arrayBufferToDataUrl(new Uint8Array(source));
|
|
77
|
+
}
|
|
78
|
+
if (source instanceof Uint8Array) {
|
|
79
|
+
return arrayBufferToDataUrl(source);
|
|
80
|
+
}
|
|
81
|
+
throw new Error(`Unsupported image source type: ${typeof source}`);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Convert Uint8Array to data URL.
|
|
85
|
+
*/
|
|
86
|
+
function arrayBufferToDataUrl(buffer) {
|
|
87
|
+
// Detect MIME type from magic bytes
|
|
88
|
+
const mimeType = detectMimeType(buffer);
|
|
89
|
+
// Convert to base64
|
|
90
|
+
const base64 = uint8ArrayToBase64(buffer);
|
|
91
|
+
return `data:${mimeType};base64,${base64}`;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Detect image MIME type from magic bytes.
|
|
95
|
+
*/
|
|
96
|
+
function detectMimeType(buffer) {
|
|
97
|
+
if (buffer.length < 4) {
|
|
98
|
+
return 'application/octet-stream';
|
|
99
|
+
}
|
|
100
|
+
// PNG: 89 50 4E 47
|
|
101
|
+
if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4E && buffer[3] === 0x47) {
|
|
102
|
+
return 'image/png';
|
|
103
|
+
}
|
|
104
|
+
// JPEG: FF D8 FF
|
|
105
|
+
if (buffer[0] === 0xFF && buffer[1] === 0xD8 && buffer[2] === 0xFF) {
|
|
106
|
+
return 'image/jpeg';
|
|
107
|
+
}
|
|
108
|
+
// GIF: 47 49 46 38
|
|
109
|
+
if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46 && buffer[3] === 0x38) {
|
|
110
|
+
return 'image/gif';
|
|
111
|
+
}
|
|
112
|
+
// WebP: 52 49 46 46 ... 57 45 42 50
|
|
113
|
+
if (buffer[0] === 0x52 && buffer[1] === 0x49 && buffer[2] === 0x46 && buffer[3] === 0x46 &&
|
|
114
|
+
buffer.length > 11 && buffer[8] === 0x57 && buffer[9] === 0x45 && buffer[10] === 0x42 && buffer[11] === 0x50) {
|
|
115
|
+
return 'image/webp';
|
|
116
|
+
}
|
|
117
|
+
return 'image/png'; // Default fallback
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Convert Uint8Array to base64 string.
|
|
121
|
+
* Works in both Node.js and browser environments.
|
|
122
|
+
*/
|
|
123
|
+
function uint8ArrayToBase64(buffer) {
|
|
124
|
+
// Node.js environment
|
|
125
|
+
if (typeof Buffer !== 'undefined') {
|
|
126
|
+
return Buffer.from(buffer).toString('base64');
|
|
127
|
+
}
|
|
128
|
+
// Browser environment
|
|
129
|
+
let binary = '';
|
|
130
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
131
|
+
binary += String.fromCharCode(buffer[i]);
|
|
132
|
+
}
|
|
133
|
+
return btoa(binary);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Helper to convert Blob to data URL asynchronously (for browser use).
|
|
137
|
+
* Only available in browser environments.
|
|
138
|
+
*/
|
|
139
|
+
export async function blobToDataUrl(blob) {
|
|
140
|
+
// Check if FileReader is available (browser environment)
|
|
141
|
+
const FR = globalThis.FileReader;
|
|
142
|
+
if (!FR) {
|
|
143
|
+
throw new Error('blobToDataUrl is only available in browser environments');
|
|
144
|
+
}
|
|
145
|
+
return new Promise((resolve, reject) => {
|
|
146
|
+
const reader = new FR();
|
|
147
|
+
reader.onloadend = () => resolve(reader.result);
|
|
148
|
+
reader.onerror = reject;
|
|
149
|
+
reader.readAsDataURL(blob);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Check if content contains any image parts that need normalization.
|
|
154
|
+
*/
|
|
155
|
+
export function hasImageParts(content) {
|
|
156
|
+
if (typeof content === 'string') {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
return content.some(part => part.type === 'image');
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=content-converter.js.map
|
package/dist/lib/errors.d.ts
CHANGED
|
@@ -9,4 +9,19 @@ export declare class MaxStepsExceededError extends AIError {
|
|
|
9
9
|
maxSteps: number;
|
|
10
10
|
constructor(maxSteps: number);
|
|
11
11
|
}
|
|
12
|
+
/** Validation error details */
|
|
13
|
+
export interface ValidationErrorItem {
|
|
14
|
+
path: (string | number)[];
|
|
15
|
+
message: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Error thrown when structured output validation fails.
|
|
19
|
+
*/
|
|
20
|
+
export declare class StructuredOutputError extends AIError {
|
|
21
|
+
/** Raw LLM output before validation */
|
|
22
|
+
raw: string;
|
|
23
|
+
/** Validation errors */
|
|
24
|
+
validationErrors: ValidationErrorItem[];
|
|
25
|
+
constructor(message: string, raw: string, validationErrors: ValidationErrorItem[]);
|
|
26
|
+
}
|
|
12
27
|
//# sourceMappingURL=errors.d.ts.map
|
package/dist/lib/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,OAAQ,SAAQ,KAAK;gBAClB,OAAO,EAAE,MAAM;CAI9B;AAED,qBAAa,kBAAmB,SAAQ,OAAO;IAC3C,QAAQ,EAAE,MAAM,CAAC;gBAEL,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAKhD;AAED,qBAAa,qBAAsB,SAAQ,OAAO;IAC9C,QAAQ,EAAE,MAAM,CAAC;gBAEL,QAAQ,EAAE,MAAM;CAK/B"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,OAAQ,SAAQ,KAAK;gBAClB,OAAO,EAAE,MAAM;CAI9B;AAED,qBAAa,kBAAmB,SAAQ,OAAO;IAC3C,QAAQ,EAAE,MAAM,CAAC;gBAEL,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAKhD;AAED,qBAAa,qBAAsB,SAAQ,OAAO;IAC9C,QAAQ,EAAE,MAAM,CAAC;gBAEL,QAAQ,EAAE,MAAM;CAK/B;AAED,+BAA+B;AAC/B,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,OAAO;IAC9C,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,wBAAwB;IACxB,gBAAgB,EAAE,mBAAmB,EAAE,CAAC;gBAE5B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,gBAAgB,EAAE,mBAAmB,EAAE;CAMpF"}
|
package/dist/lib/errors.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MaxStepsExceededError = exports.ToolExecutionError = exports.AIError = void 0;
|
|
3
|
+
exports.StructuredOutputError = exports.MaxStepsExceededError = exports.ToolExecutionError = exports.AIError = void 0;
|
|
4
4
|
class AIError extends Error {
|
|
5
5
|
constructor(message) {
|
|
6
6
|
super(message);
|
|
@@ -24,4 +24,16 @@ class MaxStepsExceededError extends AIError {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
exports.MaxStepsExceededError = MaxStepsExceededError;
|
|
27
|
+
/**
|
|
28
|
+
* Error thrown when structured output validation fails.
|
|
29
|
+
*/
|
|
30
|
+
class StructuredOutputError extends AIError {
|
|
31
|
+
constructor(message, raw, validationErrors) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = 'StructuredOutputError';
|
|
34
|
+
this.raw = raw;
|
|
35
|
+
this.validationErrors = validationErrors;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.StructuredOutputError = StructuredOutputError;
|
|
27
39
|
//# sourceMappingURL=errors.js.map
|
package/dist/lib/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":";;;AAAA,MAAa,OAAQ,SAAQ,KAAK;IAC9B,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IAC1B,CAAC;CACJ;AALD,0BAKC;AAED,MAAa,kBAAmB,SAAQ,OAAO;IAG3C,YAAY,QAAgB,EAAE,OAAe;QACzC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;CACJ;AARD,gDAQC;AAED,MAAa,qBAAsB,SAAQ,OAAO;IAG9C,YAAY,QAAgB;QACxB,KAAK,CAAC,cAAc,QAAQ,uCAAuC,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;CACJ;AARD,sDAQC"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":";;;AAAA,MAAa,OAAQ,SAAQ,KAAK;IAC9B,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IAC1B,CAAC;CACJ;AALD,0BAKC;AAED,MAAa,kBAAmB,SAAQ,OAAO;IAG3C,YAAY,QAAgB,EAAE,OAAe;QACzC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;CACJ;AARD,gDAQC;AAED,MAAa,qBAAsB,SAAQ,OAAO;IAG9C,YAAY,QAAgB;QACxB,KAAK,CAAC,cAAc,QAAQ,uCAAuC,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;CACJ;AARD,sDAQC;AAQD;;GAEG;AACH,MAAa,qBAAsB,SAAQ,OAAO;IAM9C,YAAY,OAAe,EAAE,GAAW,EAAE,gBAAuC;QAC7E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC7C,CAAC;CACJ;AAZD,sDAYC"}
|
package/dist/lib/errors.mjs
CHANGED
|
@@ -18,4 +18,15 @@ export class MaxStepsExceededError extends AIError {
|
|
|
18
18
|
this.maxSteps = maxSteps;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Error thrown when structured output validation fails.
|
|
23
|
+
*/
|
|
24
|
+
export class StructuredOutputError extends AIError {
|
|
25
|
+
constructor(message, raw, validationErrors) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = 'StructuredOutputError';
|
|
28
|
+
this.raw = raw;
|
|
29
|
+
this.validationErrors = validationErrors;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
21
32
|
//# sourceMappingURL=errors.js.map
|
package/dist/lib/messages.js
CHANGED
|
@@ -49,10 +49,11 @@ function estimateMessageTokens(message) {
|
|
|
49
49
|
return 0;
|
|
50
50
|
}
|
|
51
51
|
function estimateTokensFromPart(part) {
|
|
52
|
-
if (part.type === 'text') {
|
|
53
|
-
return estimateTokensFromText(part.text
|
|
52
|
+
if (part.type === 'text' && 'text' in part) {
|
|
53
|
+
return estimateTokensFromText(part.text);
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
// Both image_url (API format) and image (SDK sugar) count as image tokens
|
|
56
|
+
if (part.type === 'image_url' || part.type === 'image') {
|
|
56
57
|
return 50;
|
|
57
58
|
}
|
|
58
59
|
return 0;
|
package/dist/lib/messages.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/lib/messages.ts"],"names":[],"mappings":";;AAaA,wCAMC;AAMD,0CAqCC;AApDD;;GAEG;AACH,SAAgB,cAAc,CAC1B,OAAsB,EACtB,UAAuC;IAEvC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAC3B,QAAuB,EACvB,SAAiB,EACjB,UAA2B,EAAE;IAE7B,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACjB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC;IAC/C,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE7F,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,UAAU,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1C,SAAS;QACb,CAAC;QAED,MAAM,aAAa,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,WAAW,GAAG,aAAa,GAAG,SAAS,EAAE,CAAC;YAC1C,MAAM;QACV,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,WAAW,IAAI,aAAa,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,OAAO,EAAE,CAAC;IAElB,IAAI,aAAa,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACpD,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAoB;IAC/C,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,sBAAsB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACxF,CAAC;IAED,OAAO,CAAC,CAAC;AACb,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAiB;IAC7C,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/lib/messages.ts"],"names":[],"mappings":";;AAaA,wCAMC;AAMD,0CAqCC;AApDD;;GAEG;AACH,SAAgB,cAAc,CAC1B,OAAsB,EACtB,UAAuC;IAEvC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAC3B,QAAuB,EACvB,SAAiB,EACjB,UAA2B,EAAE;IAE7B,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACjB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC;IAC/C,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE7F,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,UAAU,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1C,SAAS;QACb,CAAC;QAED,MAAM,aAAa,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,WAAW,GAAG,aAAa,GAAG,SAAS,EAAE,CAAC;YAC1C,MAAM;QACV,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,WAAW,IAAI,aAAa,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,OAAO,EAAE,CAAC;IAElB,IAAI,aAAa,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACpD,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAoB;IAC/C,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,sBAAsB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACxF,CAAC;IAED,OAAO,CAAC,CAAC;AACb,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAiB;IAC7C,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACzC,OAAO,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,0EAA0E;IAC1E,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACrD,OAAO,EAAE,CAAC;IACd,CAAC;IAED,OAAO,CAAC,CAAC;AACb,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAY;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,CAAC,CAAC;IACb,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACtC,CAAC"}
|
package/dist/lib/messages.mjs
CHANGED
|
@@ -45,10 +45,11 @@ function estimateMessageTokens(message) {
|
|
|
45
45
|
return 0;
|
|
46
46
|
}
|
|
47
47
|
function estimateTokensFromPart(part) {
|
|
48
|
-
if (part.type === 'text') {
|
|
49
|
-
return estimateTokensFromText(part.text
|
|
48
|
+
if (part.type === 'text' && 'text' in part) {
|
|
49
|
+
return estimateTokensFromText(part.text);
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
// Both image_url (API format) and image (SDK sugar) count as image tokens
|
|
52
|
+
if (part.type === 'image_url' || part.type === 'image') {
|
|
52
53
|
return 50;
|
|
53
54
|
}
|
|
54
55
|
return 0;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental JSON parser for streaming structured output.
|
|
3
|
+
* Parses partial JSON strings as they arrive, returning the most complete object possible.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* const parser = new PartialJsonParser();
|
|
8
|
+
*
|
|
9
|
+
* parser.append('{"title": "Hello');
|
|
10
|
+
* console.log(parser.getPartial()); // { title: 'Hello' }
|
|
11
|
+
*
|
|
12
|
+
* parser.append('", "done": true}');
|
|
13
|
+
* console.log(parser.getPartial()); // { title: 'Hello', done: true }
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Result of parsing attempt.
|
|
18
|
+
*/
|
|
19
|
+
export interface ParseResult<T = unknown> {
|
|
20
|
+
/** Whether the JSON is complete and valid */
|
|
21
|
+
complete: boolean;
|
|
22
|
+
/** The parsed partial object (may be incomplete) */
|
|
23
|
+
value: T | null;
|
|
24
|
+
/** Parsing error if any */
|
|
25
|
+
error?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Incremental JSON parser that handles partial JSON strings.
|
|
29
|
+
*/
|
|
30
|
+
export declare class PartialJsonParser {
|
|
31
|
+
private buffer;
|
|
32
|
+
/**
|
|
33
|
+
* Append new content to the buffer.
|
|
34
|
+
*/
|
|
35
|
+
append(chunk: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Get the current buffer content.
|
|
38
|
+
*/
|
|
39
|
+
getBuffer(): string;
|
|
40
|
+
/**
|
|
41
|
+
* Reset the parser.
|
|
42
|
+
*/
|
|
43
|
+
reset(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Try to parse the current buffer as complete JSON.
|
|
46
|
+
*/
|
|
47
|
+
parseComplete<T = unknown>(): ParseResult<T>;
|
|
48
|
+
/**
|
|
49
|
+
* Parse the current buffer, attempting to complete partial JSON.
|
|
50
|
+
* Returns the most complete object possible.
|
|
51
|
+
*/
|
|
52
|
+
parsePartial<T = unknown>(): ParseResult<T>;
|
|
53
|
+
/**
|
|
54
|
+
* Attempt to complete partial JSON by adding missing closing brackets.
|
|
55
|
+
*/
|
|
56
|
+
private completePartialJson;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Parse a partial JSON string, returning the most complete object possible.
|
|
60
|
+
* Convenience function for one-shot parsing.
|
|
61
|
+
*/
|
|
62
|
+
export declare function parsePartialJson<T = unknown>(json: string): ParseResult<T>;
|
|
63
|
+
//# sourceMappingURL=partial-json-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partial-json-parser.d.ts","sourceRoot":"","sources":["../../src/lib/partial-json-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACpC,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAChB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,MAAM,CAAM;IAEpB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI3B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,aAAa,CAAC,CAAC,GAAG,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC;IAS5C;;;OAGG;IACH,YAAY,CAAC,CAAC,GAAG,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC;IAqB3C;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAwD9B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAI1E"}
|