@sudobility/shapeshyft_types 1.0.45 → 1.0.46
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 +51 -0
- package/package.json +6 -10
- package/dist/index.cjs +0 -333
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# @sudobility/shapeshyft_types
|
|
2
|
+
|
|
3
|
+
Shared TypeScript type definitions for the ShapeShyft LLM structured output platform.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @sudobility/shapeshyft_types
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import type {
|
|
15
|
+
User, Project, Endpoint, LlmProvider,
|
|
16
|
+
AiExecutionRequest, AiExecutionResponse,
|
|
17
|
+
} from '@sudobility/shapeshyft_types';
|
|
18
|
+
|
|
19
|
+
import { successResponse, errorResponse } from '@sudobility/shapeshyft_types';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Types
|
|
23
|
+
|
|
24
|
+
- **Enums**: `LlmProvider` (openai, gemini, anthropic, lm_studio), `HttpMethod`
|
|
25
|
+
- **Entities**: `User`, `LlmApiKey` / `LlmApiKeySafe`, `Project`, `Endpoint`, `UsageAnalytics`, `UserSettings`
|
|
26
|
+
- **Requests**: Create/Update types for users, keys, projects, endpoints, plus `AiExecutionRequest`
|
|
27
|
+
- **Responses**: `AiExecutionResponse`, `AiPromptResponse`, `AnalyticsResponse`, `HealthCheckData`
|
|
28
|
+
- **Query Params**: `ProjectQueryParams`, `EndpointQueryParams`, `UsageAnalyticsQueryParams`
|
|
29
|
+
- **Utilities**: `JsonSchema`, `ApiResponse<T>`, `PaginatedResponse<T>` (re-exported from `@sudobility/types`)
|
|
30
|
+
- **Helpers**: `successResponse()`, `errorResponse()` (runtime functions)
|
|
31
|
+
|
|
32
|
+
## Development
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bun run build # Build ESM + CJS
|
|
36
|
+
bun run test # Run Vitest
|
|
37
|
+
bun run typecheck # TypeScript check
|
|
38
|
+
bun run lint # ESLint
|
|
39
|
+
bun run verify # Typecheck + lint + build
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Related Packages
|
|
43
|
+
|
|
44
|
+
- `@sudobility/shapeshyft_client` -- React hooks for ShapeShyft API
|
|
45
|
+
- `@sudobility/shapeshyft_lib` -- Business logic with Zustand stores
|
|
46
|
+
- `shapeshyft_api` -- Backend API server
|
|
47
|
+
- `shapeshyft_app` -- Frontend web application
|
|
48
|
+
|
|
49
|
+
## License
|
|
50
|
+
|
|
51
|
+
BUSL-1.1
|
package/package.json
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sudobility/shapeshyft_types",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.46",
|
|
4
4
|
"description": "TypeScript types for ShapeShyft API - LLM structured output platform",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
10
|
"import": "./dist/index.js",
|
|
11
|
-
"require": "./dist/index.cjs",
|
|
12
11
|
"types": "./dist/index.d.ts"
|
|
13
12
|
}
|
|
14
13
|
},
|
|
15
14
|
"scripts": {
|
|
16
|
-
"build": "
|
|
17
|
-
"build:esm": "bunx tsc -p tsconfig.esm.json",
|
|
18
|
-
"build:cjs": "bunx tsc -p tsconfig.cjs.json && bun run build:cjs-rename && rm -rf dist-cjs",
|
|
19
|
-
"build:cjs-rename": "find dist-cjs -name '*.js' -exec sh -c 'cp \"$1\" \"dist/$(basename \"${1%.js}.cjs\")\"' _ {} \\;",
|
|
15
|
+
"build": "tsc -p tsconfig.esm.json",
|
|
20
16
|
"clean": "rm -rf dist",
|
|
21
17
|
"dev": "bunx tsc --watch",
|
|
22
18
|
"typecheck": "bunx tsc --noEmit",
|
|
@@ -43,11 +39,11 @@
|
|
|
43
39
|
"author": "Sudobility",
|
|
44
40
|
"license": "BUSL-1.1",
|
|
45
41
|
"peerDependencies": {
|
|
46
|
-
"@sudobility/types": "^1.9.
|
|
42
|
+
"@sudobility/types": "^1.9.57"
|
|
47
43
|
},
|
|
48
44
|
"devDependencies": {
|
|
49
45
|
"@eslint/js": "^9.39.2",
|
|
50
|
-
"@sudobility/types": "^1.9.
|
|
46
|
+
"@sudobility/types": "^1.9.57",
|
|
51
47
|
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
|
52
48
|
"@typescript-eslint/parser": "^8.50.0",
|
|
53
49
|
"eslint": "^9.39.2",
|
package/dist/index.cjs
DELETED
|
@@ -1,333 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @sudobility/shapeshyft_types
|
|
4
|
-
* TypeScript types for ShapeShyft API - LLM structured output platform
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.PROVIDER_MODELS = exports.LLM_PROVIDERS = void 0;
|
|
8
|
-
exports.isValidModelForProvider = isValidModelForProvider;
|
|
9
|
-
exports.detectRequiredCapabilities = detectRequiredCapabilities;
|
|
10
|
-
exports.estimateCost = estimateCost;
|
|
11
|
-
exports.estimateMultimodalCost = estimateMultimodalCost;
|
|
12
|
-
exports.formatCost = formatCost;
|
|
13
|
-
exports.formatCostPerMillion = formatCostPerMillion;
|
|
14
|
-
exports.successResponse = successResponse;
|
|
15
|
-
exports.errorResponse = errorResponse;
|
|
16
|
-
/** List of available providers */
|
|
17
|
-
exports.LLM_PROVIDERS = [
|
|
18
|
-
'openai',
|
|
19
|
-
'anthropic',
|
|
20
|
-
'gemini',
|
|
21
|
-
'mistral',
|
|
22
|
-
'cohere',
|
|
23
|
-
'groq',
|
|
24
|
-
'xai',
|
|
25
|
-
'deepseek',
|
|
26
|
-
'perplexity',
|
|
27
|
-
'lm_studio',
|
|
28
|
-
];
|
|
29
|
-
/**
|
|
30
|
-
* Mapping of each LLM provider to its known valid model IDs.
|
|
31
|
-
* Useful for both server-side validation and client-side form validation.
|
|
32
|
-
*
|
|
33
|
-
* Note: `lm_studio` has an empty list because it accepts arbitrary
|
|
34
|
-
* user-supplied model names (any string is valid).
|
|
35
|
-
*/
|
|
36
|
-
exports.PROVIDER_MODELS = {
|
|
37
|
-
openai: [
|
|
38
|
-
'gpt-4.1',
|
|
39
|
-
'gpt-4.1-mini',
|
|
40
|
-
'gpt-4.1-nano',
|
|
41
|
-
'gpt-4o',
|
|
42
|
-
'gpt-4o-mini',
|
|
43
|
-
'o3',
|
|
44
|
-
'o3-pro',
|
|
45
|
-
'o4-mini',
|
|
46
|
-
'gpt-4-turbo',
|
|
47
|
-
'o1',
|
|
48
|
-
],
|
|
49
|
-
anthropic: [
|
|
50
|
-
'claude-opus-4-5-20251124',
|
|
51
|
-
'claude-sonnet-4-5-20251124',
|
|
52
|
-
'claude-opus-4-1-20250805',
|
|
53
|
-
'claude-sonnet-4-20250514',
|
|
54
|
-
'claude-opus-4-20250514',
|
|
55
|
-
'claude-3-5-haiku-20241022',
|
|
56
|
-
],
|
|
57
|
-
gemini: [
|
|
58
|
-
'gemini-3-pro-preview',
|
|
59
|
-
'gemini-3-flash-preview',
|
|
60
|
-
'gemini-3-pro-image-preview',
|
|
61
|
-
'gemini-2.5-pro',
|
|
62
|
-
'gemini-2.5-flash',
|
|
63
|
-
'gemini-2.5-flash-lite',
|
|
64
|
-
'gemini-2.5-flash-image',
|
|
65
|
-
'gemini-2.5-flash-native-audio-preview',
|
|
66
|
-
'gemini-2.0-flash',
|
|
67
|
-
'gemini-2.0-flash-lite',
|
|
68
|
-
],
|
|
69
|
-
mistral: [
|
|
70
|
-
'mistral-large-2512',
|
|
71
|
-
'mistral-large-latest',
|
|
72
|
-
'mistral-medium-3.1',
|
|
73
|
-
'mistral-medium-latest',
|
|
74
|
-
'mistral-small-3.2',
|
|
75
|
-
'mistral-small-latest',
|
|
76
|
-
'ministral-3b-2512',
|
|
77
|
-
'ministral-8b-2512',
|
|
78
|
-
'ministral-14b-2512',
|
|
79
|
-
'codestral-2501',
|
|
80
|
-
'codestral-latest',
|
|
81
|
-
'pixtral-large-2411',
|
|
82
|
-
'pixtral-large-latest',
|
|
83
|
-
'voxtral-small',
|
|
84
|
-
'voxtral-mini',
|
|
85
|
-
'mistral-ocr-2512',
|
|
86
|
-
],
|
|
87
|
-
cohere: [
|
|
88
|
-
'command-a-03-2025',
|
|
89
|
-
'command-a-reasoning',
|
|
90
|
-
'command-a-vision',
|
|
91
|
-
'command-r-plus-08-2024',
|
|
92
|
-
'command-r-08-2024',
|
|
93
|
-
'command-r-plus',
|
|
94
|
-
'command-r',
|
|
95
|
-
],
|
|
96
|
-
groq: [
|
|
97
|
-
'llama-3.3-70b-versatile',
|
|
98
|
-
'llama-3.1-8b-instant',
|
|
99
|
-
'openai/gpt-oss-120b',
|
|
100
|
-
'openai/gpt-oss-20b',
|
|
101
|
-
'groq/compound',
|
|
102
|
-
'groq/compound-mini',
|
|
103
|
-
'meta-llama/llama-guard-4-12b',
|
|
104
|
-
'whisper-large-v3',
|
|
105
|
-
'whisper-large-v3-turbo',
|
|
106
|
-
],
|
|
107
|
-
xai: [
|
|
108
|
-
'grok-4',
|
|
109
|
-
'grok-4.1-fast',
|
|
110
|
-
'grok-3',
|
|
111
|
-
'grok-3-mini',
|
|
112
|
-
'grok-3-vision',
|
|
113
|
-
'grok-2',
|
|
114
|
-
'grok-2-vision',
|
|
115
|
-
],
|
|
116
|
-
deepseek: [
|
|
117
|
-
'deepseek-chat',
|
|
118
|
-
'deepseek-reasoner',
|
|
119
|
-
],
|
|
120
|
-
perplexity: [
|
|
121
|
-
'sonar',
|
|
122
|
-
'sonar-pro',
|
|
123
|
-
'sonar-reasoning',
|
|
124
|
-
'sonar-reasoning-pro',
|
|
125
|
-
'sonar-deep-research',
|
|
126
|
-
],
|
|
127
|
-
lm_studio: [],
|
|
128
|
-
};
|
|
129
|
-
/**
|
|
130
|
-
* Check whether a model ID is valid for the given provider.
|
|
131
|
-
* For `lm_studio`, any string is valid (returns true) since users
|
|
132
|
-
* can run arbitrary models on their local server.
|
|
133
|
-
*
|
|
134
|
-
* @param provider - The LLM provider to validate against
|
|
135
|
-
* @param model - The model ID string to check
|
|
136
|
-
* @returns true if the model is a known valid model for the provider
|
|
137
|
-
*/
|
|
138
|
-
function isValidModelForProvider(provider, model) {
|
|
139
|
-
const models = exports.PROVIDER_MODELS[provider];
|
|
140
|
-
// lm_studio accepts any model string
|
|
141
|
-
if (provider === 'lm_studio')
|
|
142
|
-
return true;
|
|
143
|
-
return models.includes(model);
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Detect media type from contentMediaType string
|
|
147
|
-
*/
|
|
148
|
-
function detectMediaType(contentMediaType) {
|
|
149
|
-
if (contentMediaType.startsWith('image/'))
|
|
150
|
-
return 'image';
|
|
151
|
-
if (contentMediaType.startsWith('audio/'))
|
|
152
|
-
return 'audio';
|
|
153
|
-
if (contentMediaType.startsWith('video/'))
|
|
154
|
-
return 'video';
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Recursively scan a JSON schema for media type properties.
|
|
159
|
-
* Returns detected media types.
|
|
160
|
-
*/
|
|
161
|
-
function scanSchemaForMediaTypes(schema, result) {
|
|
162
|
-
if (!schema || typeof schema !== 'object')
|
|
163
|
-
return;
|
|
164
|
-
// Check if this property has contentMediaType
|
|
165
|
-
const contentMediaType = schema['contentMediaType'];
|
|
166
|
-
if (typeof contentMediaType === 'string') {
|
|
167
|
-
const mediaType = detectMediaType(contentMediaType);
|
|
168
|
-
if (mediaType) {
|
|
169
|
-
result.add(mediaType);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
// Recurse into properties
|
|
173
|
-
const properties = schema['properties'];
|
|
174
|
-
if (properties && typeof properties === 'object') {
|
|
175
|
-
for (const prop of Object.values(properties)) {
|
|
176
|
-
if (prop && typeof prop === 'object') {
|
|
177
|
-
scanSchemaForMediaTypes(prop, result);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
// Recurse into array items
|
|
182
|
-
const items = schema['items'];
|
|
183
|
-
if (items && typeof items === 'object') {
|
|
184
|
-
scanSchemaForMediaTypes(items, result);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Detect required capabilities from input and output schemas.
|
|
189
|
-
* Returns which media capabilities are required.
|
|
190
|
-
*/
|
|
191
|
-
function detectRequiredCapabilities(inputSchema, outputSchema) {
|
|
192
|
-
const result = {};
|
|
193
|
-
// Scan input schema for required input capabilities
|
|
194
|
-
if (inputSchema) {
|
|
195
|
-
const inputMediaTypes = new Set();
|
|
196
|
-
scanSchemaForMediaTypes(inputSchema, inputMediaTypes);
|
|
197
|
-
if (inputMediaTypes.has('image'))
|
|
198
|
-
result.visionInput = true;
|
|
199
|
-
if (inputMediaTypes.has('audio'))
|
|
200
|
-
result.audioInput = true;
|
|
201
|
-
if (inputMediaTypes.has('video'))
|
|
202
|
-
result.videoInput = true;
|
|
203
|
-
}
|
|
204
|
-
// Scan output schema for required output capabilities
|
|
205
|
-
if (outputSchema) {
|
|
206
|
-
const outputMediaTypes = new Set();
|
|
207
|
-
scanSchemaForMediaTypes(outputSchema, outputMediaTypes);
|
|
208
|
-
if (outputMediaTypes.has('image'))
|
|
209
|
-
result.imageOutput = true;
|
|
210
|
-
if (outputMediaTypes.has('audio'))
|
|
211
|
-
result.audioOutput = true;
|
|
212
|
-
if (outputMediaTypes.has('video'))
|
|
213
|
-
result.videoOutput = true;
|
|
214
|
-
}
|
|
215
|
-
return result;
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Estimate cost in cents for token usage (text only)
|
|
219
|
-
* @param pricing - Model pricing configuration
|
|
220
|
-
* @param inputTokens - Number of input tokens
|
|
221
|
-
* @param outputTokens - Number of output tokens
|
|
222
|
-
*/
|
|
223
|
-
function estimateCost(pricing, inputTokens, outputTokens) {
|
|
224
|
-
const inputCost = (inputTokens / 1000000) * pricing.input;
|
|
225
|
-
const outputCost = (outputTokens / 1000000) * pricing.output;
|
|
226
|
-
return Math.round((inputCost + outputCost) * 100) / 100; // Round to 2 decimal places
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Estimate cost in cents for multimodal usage
|
|
230
|
-
* @param pricing - Model pricing configuration
|
|
231
|
-
* @param usage - Multimodal usage details
|
|
232
|
-
*/
|
|
233
|
-
function estimateMultimodalCost(pricing, usage) {
|
|
234
|
-
let totalCost = 0;
|
|
235
|
-
// Text token costs
|
|
236
|
-
if (usage.inputTokens) {
|
|
237
|
-
totalCost += (usage.inputTokens / 1000000) * pricing.input;
|
|
238
|
-
}
|
|
239
|
-
if (usage.outputTokens) {
|
|
240
|
-
totalCost += (usage.outputTokens / 1000000) * pricing.output;
|
|
241
|
-
}
|
|
242
|
-
// Image costs
|
|
243
|
-
if (usage.imagesInput && pricing.imageInput) {
|
|
244
|
-
totalCost += usage.imagesInput * pricing.imageInput;
|
|
245
|
-
}
|
|
246
|
-
if (usage.imagesOutput && pricing.imageOutput) {
|
|
247
|
-
totalCost += usage.imagesOutput * pricing.imageOutput;
|
|
248
|
-
}
|
|
249
|
-
// Audio costs
|
|
250
|
-
if (usage.audioInputMinutes && pricing.audioInput) {
|
|
251
|
-
totalCost += usage.audioInputMinutes * pricing.audioInput;
|
|
252
|
-
}
|
|
253
|
-
if (usage.audioOutputMinutes && pricing.audioOutput) {
|
|
254
|
-
totalCost += usage.audioOutputMinutes * pricing.audioOutput;
|
|
255
|
-
}
|
|
256
|
-
// Video costs
|
|
257
|
-
if (usage.videoInputMinutes && pricing.videoInput) {
|
|
258
|
-
totalCost += usage.videoInputMinutes * pricing.videoInput;
|
|
259
|
-
}
|
|
260
|
-
if (usage.videoOutputMinutes && pricing.videoOutput) {
|
|
261
|
-
totalCost += usage.videoOutputMinutes * pricing.videoOutput;
|
|
262
|
-
}
|
|
263
|
-
return Math.round(totalCost * 100) / 100; // Round to 2 decimal places
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Format cost in cents to a readable string (e.g., "$0.0015" or "$1.50")
|
|
267
|
-
*/
|
|
268
|
-
function formatCost(costCents) {
|
|
269
|
-
const dollars = costCents / 100;
|
|
270
|
-
if (dollars < 0.01) {
|
|
271
|
-
return `$${dollars.toFixed(4)}`;
|
|
272
|
-
}
|
|
273
|
-
else if (dollars < 1) {
|
|
274
|
-
return `$${dollars.toFixed(3)}`;
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
return `$${dollars.toFixed(2)}`;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Format cost per million tokens for display
|
|
282
|
-
*/
|
|
283
|
-
function formatCostPerMillion(pricing) {
|
|
284
|
-
const inputDollars = pricing.input / 100;
|
|
285
|
-
const outputDollars = pricing.output / 100;
|
|
286
|
-
return `$${inputDollars.toFixed(2)} / $${outputDollars.toFixed(2)} per 1M tokens`;
|
|
287
|
-
}
|
|
288
|
-
// =============================================================================
|
|
289
|
-
// Response Helper Functions
|
|
290
|
-
// =============================================================================
|
|
291
|
-
/**
|
|
292
|
-
* Create a typed success response wrapping the given data.
|
|
293
|
-
*
|
|
294
|
-
* @example
|
|
295
|
-
* ```typescript
|
|
296
|
-
* import { successResponse, type Project } from '@sudobility/shapeshyft_types';
|
|
297
|
-
*
|
|
298
|
-
* const project: Project = { uuid: '...', entity_id: '...', project_name: 'my-project', display_name: 'My Project', description: null, is_active: true, api_key_prefix: null, api_key_created_at: null, created_at: new Date(), updated_at: new Date() };
|
|
299
|
-
* const response = successResponse<Project>(project);
|
|
300
|
-
* // { success: true, data: { uuid: '...', project_name: 'my-project', ... }, timestamp: '2026-01-15T...' }
|
|
301
|
-
* ```
|
|
302
|
-
*/
|
|
303
|
-
function successResponse(data) {
|
|
304
|
-
return {
|
|
305
|
-
success: true,
|
|
306
|
-
data,
|
|
307
|
-
timestamp: new Date().toISOString(),
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
/**
|
|
311
|
-
* Create a typed error response with the given error message.
|
|
312
|
-
*
|
|
313
|
-
* @example
|
|
314
|
-
* ```typescript
|
|
315
|
-
* import { errorResponse } from '@sudobility/shapeshyft_types';
|
|
316
|
-
*
|
|
317
|
-
* const response = errorResponse('Project not found');
|
|
318
|
-
* // { success: false, error: 'Project not found', timestamp: '2026-01-15T...' }
|
|
319
|
-
*
|
|
320
|
-
* // In an API handler:
|
|
321
|
-
* if (!project) {
|
|
322
|
-
* return c.json(errorResponse('Project not found'), 404);
|
|
323
|
-
* }
|
|
324
|
-
* ```
|
|
325
|
-
*/
|
|
326
|
-
function errorResponse(error) {
|
|
327
|
-
return {
|
|
328
|
-
success: false,
|
|
329
|
-
error,
|
|
330
|
-
timestamp: new Date().toISOString(),
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
//# sourceMappingURL=index.js.map
|