@sogni-ai/sogni-client 4.2.0-alpha.2 → 4.2.0-alpha.21

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.
Files changed (109) hide show
  1. package/CHANGELOG.md +148 -0
  2. package/CLAUDE.md +25 -3
  3. package/README.md +411 -136
  4. package/dist/Account/index.d.ts +4 -2
  5. package/dist/Account/index.js +27 -23
  6. package/dist/Account/index.js.map +1 -1
  7. package/dist/Account/types.d.ts +7 -0
  8. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.d.ts +3 -1
  9. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +26 -2
  10. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -1
  11. package/dist/ApiClient/WebSocketClient/eventSubscriptions.d.ts +33 -0
  12. package/dist/ApiClient/WebSocketClient/eventSubscriptions.js +39 -0
  13. package/dist/ApiClient/WebSocketClient/eventSubscriptions.js.map +1 -0
  14. package/dist/ApiClient/WebSocketClient/events.d.ts +24 -7
  15. package/dist/ApiClient/WebSocketClient/index.d.ts +5 -1
  16. package/dist/ApiClient/WebSocketClient/index.js +24 -1
  17. package/dist/ApiClient/WebSocketClient/index.js.map +1 -1
  18. package/dist/ApiClient/WebSocketClient/messages.d.ts +2 -0
  19. package/dist/ApiClient/WebSocketClient/types.d.ts +2 -0
  20. package/dist/ApiClient/index.d.ts +6 -1
  21. package/dist/ApiClient/index.js +7 -3
  22. package/dist/ApiClient/index.js.map +1 -1
  23. package/dist/Chat/ChatTools.d.ts +5 -49
  24. package/dist/Chat/ChatTools.js +311 -88
  25. package/dist/Chat/ChatTools.js.map +1 -1
  26. package/dist/Chat/index.d.ts +11 -2
  27. package/dist/Chat/index.js +78 -4
  28. package/dist/Chat/index.js.map +1 -1
  29. package/dist/Chat/modelRouting.d.ts +100 -0
  30. package/dist/Chat/modelRouting.js +441 -0
  31. package/dist/Chat/modelRouting.js.map +1 -0
  32. package/dist/Chat/sogniHostedTools.generated.json +529 -0
  33. package/dist/Chat/tools.d.ts +9 -55
  34. package/dist/Chat/tools.js +72 -228
  35. package/dist/Chat/tools.js.map +1 -1
  36. package/dist/Chat/types.d.ts +91 -2
  37. package/dist/CreativeWorkflows/index.d.ts +23 -0
  38. package/dist/CreativeWorkflows/index.js +274 -0
  39. package/dist/CreativeWorkflows/index.js.map +1 -0
  40. package/dist/CreativeWorkflows/types.d.ts +106 -0
  41. package/dist/CreativeWorkflows/types.js +3 -0
  42. package/dist/CreativeWorkflows/types.js.map +1 -0
  43. package/dist/Projects/Job.d.ts +6 -0
  44. package/dist/Projects/Job.js +60 -5
  45. package/dist/Projects/Job.js.map +1 -1
  46. package/dist/Projects/Project.js +15 -3
  47. package/dist/Projects/Project.js.map +1 -1
  48. package/dist/Projects/createJobRequestMessage.js +140 -6
  49. package/dist/Projects/createJobRequestMessage.js.map +1 -1
  50. package/dist/Projects/index.d.ts +10 -1
  51. package/dist/Projects/index.js +197 -58
  52. package/dist/Projects/index.js.map +1 -1
  53. package/dist/Projects/types/ModelOptions.d.ts +3 -3
  54. package/dist/Projects/types/ModelOptions.js +12 -5
  55. package/dist/Projects/types/ModelOptions.js.map +1 -1
  56. package/dist/Projects/types/ModelTiersRaw.d.ts +7 -7
  57. package/dist/Projects/types/RawProject.d.ts +2 -0
  58. package/dist/Projects/types/events.d.ts +5 -4
  59. package/dist/Projects/types/index.d.ts +77 -7
  60. package/dist/Projects/types/index.js.map +1 -1
  61. package/dist/Projects/utils/index.d.ts +8 -1
  62. package/dist/Projects/utils/index.js +22 -8
  63. package/dist/Projects/utils/index.js.map +1 -1
  64. package/dist/index.d.ts +28 -3
  65. package/dist/index.js +19 -1
  66. package/dist/index.js.map +1 -1
  67. package/dist/lib/RestClient.d.ts +4 -1
  68. package/dist/lib/RestClient.js +17 -9
  69. package/dist/lib/RestClient.js.map +1 -1
  70. package/dist/lib/mediaValidation.d.ts +16 -0
  71. package/dist/lib/mediaValidation.js +280 -0
  72. package/dist/lib/mediaValidation.js.map +1 -0
  73. package/dist/lib/validation.d.ts +6 -1
  74. package/dist/lib/validation.js +28 -2
  75. package/dist/lib/validation.js.map +1 -1
  76. package/llms-full.txt +372 -133
  77. package/llms.txt +197 -86
  78. package/package.json +13 -4
  79. package/src/Account/index.ts +22 -2
  80. package/src/Account/types.ts +7 -0
  81. package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/index.ts +47 -3
  82. package/src/ApiClient/WebSocketClient/eventSubscriptions.ts +92 -0
  83. package/src/ApiClient/WebSocketClient/events.ts +25 -7
  84. package/src/ApiClient/WebSocketClient/index.ts +33 -1
  85. package/src/ApiClient/WebSocketClient/messages.ts +2 -0
  86. package/src/ApiClient/WebSocketClient/types.ts +2 -0
  87. package/src/ApiClient/index.ts +32 -2
  88. package/src/Chat/ChatTools.ts +395 -95
  89. package/src/Chat/index.ts +149 -5
  90. package/src/Chat/modelRouting.ts +602 -0
  91. package/src/Chat/sogniHostedTools.generated.json +529 -0
  92. package/src/Chat/tools.ts +98 -245
  93. package/src/Chat/types.ts +100 -2
  94. package/src/CreativeWorkflows/index.ts +290 -0
  95. package/src/CreativeWorkflows/types.ts +134 -0
  96. package/src/Projects/Job.ts +76 -5
  97. package/src/Projects/Project.ts +13 -3
  98. package/src/Projects/createJobRequestMessage.ts +152 -13
  99. package/src/Projects/index.ts +230 -52
  100. package/src/Projects/types/ModelOptions.ts +15 -8
  101. package/src/Projects/types/ModelTiersRaw.ts +7 -7
  102. package/src/Projects/types/RawProject.ts +2 -0
  103. package/src/Projects/types/events.ts +5 -4
  104. package/src/Projects/types/index.ts +86 -6
  105. package/src/Projects/utils/index.ts +24 -8
  106. package/src/index.ts +93 -0
  107. package/src/lib/RestClient.ts +15 -5
  108. package/src/lib/mediaValidation.ts +367 -0
  109. package/src/lib/validation.ts +38 -2
package/src/Chat/tools.ts CHANGED
@@ -1,223 +1,83 @@
1
+ import hostedToolManifest from './sogniHostedTools.generated.json';
1
2
  import { ToolDefinition, ToolCall } from './types';
3
+ import { filterVideoModelsByWorkflow, isEditImageModel, VideoWorkflow } from './modelRouting';
2
4
 
3
- /**
4
- * Built-in Sogni platform tool definitions for use with LLM tool calling.
5
- *
6
- * These tools allow the LLM to generate images, videos, and music
7
- * through the Sogni Supernet. Include them in your `tools` array when
8
- * calling `sogni.chat.completions.create()`.
9
- *
10
- * @example
11
- * ```typescript
12
- * import { SogniTools } from '@sogni-ai/sogni-client';
13
- *
14
- * const stream = await sogni.chat.completions.create({
15
- * model: 'qwen3.6-35b-a3b-gguf-iq4xs',
16
- * messages: [{ role: 'user', content: 'Generate an image of a sunset' }],
17
- * tools: SogniTools.all,
18
- * tool_choice: 'auto',
19
- * stream: true,
20
- * });
21
- * ```
22
- */
5
+ type SogniHostedToolName =
6
+ | 'sogni_generate_image'
7
+ | 'sogni_edit_image'
8
+ | 'sogni_generate_video'
9
+ | 'sogni_sound_to_video'
10
+ | 'sogni_video_to_video'
11
+ | 'sogni_generate_music';
23
12
 
24
- /** Tool definition: Generate an image using the Sogni Supernet */
25
- export const generateImageTool: ToolDefinition = {
26
- type: 'function',
27
- function: {
28
- name: 'sogni_generate_image',
29
- description:
30
- 'Generate an image using AI image generation on the Sogni Supernet. Returns a URL to the generated image. Use this tool EVERY TIME the user asks to create, generate, draw, or make an image or picture. Do NOT generate URLs yourself — you MUST call this tool.',
31
- parameters: {
32
- type: 'object',
33
- properties: {
34
- prompt: {
35
- type: 'string',
36
- description:
37
- 'Detailed text description of the image to generate. Be specific about style, composition, lighting, colors, and subject matter.'
38
- },
39
- negative_prompt: {
40
- type: 'string',
41
- description:
42
- 'Things to avoid in the generated image (e.g., "blurry, low quality, distorted").'
43
- },
44
- width: {
45
- type: 'number',
46
- description: 'Image width in pixels. Must be a multiple of 16. Default: 1024. Max: 2048.'
47
- },
48
- height: {
49
- type: 'number',
50
- description: 'Image height in pixels. Must be a multiple of 16. Default: 1024. Max: 2048.'
51
- },
52
- model: {
53
- type: 'string',
54
- description: 'Image generation model to use.',
55
- enum: [
56
- 'flux1-schnell-fp8',
57
- 'flux2-dev_fp8',
58
- 'chroma-v.46-flash_fp8',
59
- 'z_image_turbo_bf16'
60
- ]
61
- },
62
- steps: {
63
- type: 'number',
64
- description:
65
- 'Number of inference steps. Higher = better quality but slower. Default depends on model (4-50).'
66
- },
67
- seed: {
68
- type: 'number',
69
- description: 'Random seed for reproducible generation. Use -1 for random.'
70
- }
71
- },
72
- required: ['prompt']
73
- }
74
- }
75
- };
13
+ interface SogniHostedToolManifest {
14
+ tools: ToolDefinition[];
15
+ }
16
+
17
+ const hostedTools = (hostedToolManifest as SogniHostedToolManifest).tools;
76
18
 
77
- /** Tool definition: Generate a video using the Sogni Supernet */
78
- export const generateVideoTool: ToolDefinition = {
79
- type: 'function',
80
- function: {
81
- name: 'sogni_generate_video',
82
- description:
83
- 'Generate a short video using AI video generation on the Sogni Supernet. Returns a URL to the generated video. Use this tool EVERY TIME the user asks to create, generate, or make a video, clip, or animation. Do NOT generate URLs yourself — you MUST call this tool. Write the prompt as a cohesive mini-scene in present tense, describing motion, camera movement, lighting, and atmosphere in flowing prose.',
84
- parameters: {
85
- type: 'object',
86
- properties: {
87
- prompt: {
88
- type: 'string',
89
- description:
90
- 'Detailed text description of the video to generate. Write it as a flowing present-tense scene: describe the subject, action, camera movement, lighting, and atmosphere. Clear camera-to-subject relationship improves motion consistency. Be specific and vivid.'
91
- },
92
- negative_prompt: {
93
- type: 'string',
94
- description:
95
- 'Things to avoid in the generated video (e.g., "blurry, low quality, distorted, watermark").'
96
- },
97
- width: {
98
- type: 'number',
99
- description:
100
- 'Video width in pixels. Default: 1920. Standard resolutions: 1920x1088 (landscape), 1088x1920 (portrait), 1280x720.'
101
- },
102
- height: {
103
- type: 'number',
104
- description: 'Video height in pixels. Default: 1088. Must be a multiple of 16.'
105
- },
106
- duration: {
107
- type: 'number',
108
- description: 'Video duration in seconds. Range: 1-20. Default: 5.'
109
- },
110
- fps: {
111
- type: 'number',
112
- description: 'Frames per second. Default: 24. Range: 1-60.'
113
- },
114
- model: {
115
- type: 'string',
116
- description:
117
- 'Video generation model to use. Prefer LTX-2.3 text-to-video (t2v) models for best quality.'
118
- },
119
- seed: {
120
- type: 'number',
121
- description: 'Random seed for reproducible generation. Use -1 for random.'
122
- }
123
- },
124
- required: ['prompt']
125
- }
19
+ function getHostedTool(name: SogniHostedToolName): ToolDefinition {
20
+ const tool = hostedTools.find((candidate) => candidate.function.name === name);
21
+ if (!tool) {
22
+ throw new Error(`Missing hosted Sogni tool definition: ${name}`);
126
23
  }
127
- };
24
+ return tool;
25
+ }
128
26
 
129
- /** Tool definition: Generate music using the Sogni Supernet */
130
- export const generateMusicTool: ToolDefinition = {
131
- type: 'function',
132
- function: {
133
- name: 'sogni_generate_music',
134
- description:
135
- 'Generate a music track using AI music generation on the Sogni Supernet. Returns a URL to the generated audio file. Use this tool EVERY TIME the user asks to create, generate, compose, or make music, a song, a beat, or audio. Do NOT generate URLs yourself — you MUST call this tool.',
136
- parameters: {
137
- type: 'object',
138
- properties: {
139
- prompt: {
140
- type: 'string',
141
- description:
142
- 'Description of the music to generate. Include genre, mood, tempo, instruments, and style. Can also include lyrics wrapped in [verse], [chorus], etc. tags.'
143
- },
144
- duration: {
145
- type: 'number',
146
- description: 'Duration of the generated music in seconds. Range: 10-600. Default: 30.'
147
- },
148
- bpm: {
149
- type: 'number',
150
- description: 'Beats per minute. Range: 30-300. Default: 120.'
151
- },
152
- keyscale: {
153
- type: 'string',
154
- description:
155
- 'Musical key and scale (e.g., "C major", "A minor", "F# minor", "Bb major"). Default: "C major".'
156
- },
157
- timesignature: {
158
- type: 'string',
159
- description: 'Time signature. "4" for 4/4, "3" for 3/4, "2" for 2/4. Default: "4".',
160
- enum: ['4', '3', '2']
161
- },
162
- model: {
163
- type: 'string',
164
- description:
165
- 'Music generation model. "ace_step_1.5_turbo" for fast/catchy, "ace_step_1.5_sft" for more control over lyrics.',
166
- enum: ['ace_step_1.5_turbo', 'ace_step_1.5_sft']
167
- },
168
- output_format: {
169
- type: 'string',
170
- description: 'Audio output format. Default: "mp3".',
171
- enum: ['mp3', 'flac', 'wav']
172
- },
173
- seed: {
174
- type: 'number',
175
- description: 'Random seed for reproducible generation. Use -1 for random.'
176
- }
177
- },
178
- required: ['prompt']
179
- }
27
+ function cloneTool(tool: ToolDefinition): ToolDefinition {
28
+ return structuredClone(tool);
29
+ }
30
+
31
+ function setModelEnum(
32
+ tool: ToolDefinition,
33
+ modelIds: string[],
34
+ description: string
35
+ ): ToolDefinition {
36
+ if (modelIds.length === 0) {
37
+ return tool;
180
38
  }
181
- };
39
+ (tool.function.parameters as any).properties.model = {
40
+ type: 'string',
41
+ description,
42
+ enum: modelIds
43
+ };
44
+ return tool;
45
+ }
182
46
 
183
47
  /**
184
- * Collection of all Sogni platform tool definitions.
48
+ * Built-in Sogni platform tool definitions for use with LLM tool calling.
49
+ *
50
+ * These definitions are generated from the shared
51
+ * `@sogni/creative-agent` hosted tool backbone. The public SDK keeps a local
52
+ * generated copy so consumers do not need access to the private package.
185
53
  */
54
+
55
+ export const generateImageTool: ToolDefinition = getHostedTool('sogni_generate_image');
56
+ export const editImageTool: ToolDefinition = getHostedTool('sogni_edit_image');
57
+ export const generateVideoTool: ToolDefinition = getHostedTool('sogni_generate_video');
58
+ export const soundToVideoTool: ToolDefinition = getHostedTool('sogni_sound_to_video');
59
+ export const videoToVideoTool: ToolDefinition = getHostedTool('sogni_video_to_video');
60
+ export const generateMusicTool: ToolDefinition = getHostedTool('sogni_generate_music');
61
+
186
62
  export const SogniTools = {
187
- /** Generate an image */
188
63
  generateImage: generateImageTool,
189
- /** Generate a video */
64
+ editImage: editImageTool,
190
65
  generateVideo: generateVideoTool,
191
- /** Generate music */
66
+ soundToVideo: soundToVideoTool,
67
+ videoToVideo: videoToVideoTool,
192
68
  generateMusic: generateMusicTool,
193
- /** All Sogni tools combined — convenience array for `tools` param */
194
69
  get all(): ToolDefinition[] {
195
- return [generateImageTool, generateVideoTool, generateMusicTool];
70
+ return [
71
+ generateImageTool,
72
+ editImageTool,
73
+ generateVideoTool,
74
+ soundToVideoTool,
75
+ videoToVideoTool,
76
+ generateMusicTool
77
+ ];
196
78
  }
197
79
  };
198
80
 
199
- /**
200
- * Build Sogni tool definitions with dynamically populated model enums
201
- * based on currently available models on the network.
202
- *
203
- * @param availableModels - Result of `sogni.projects.waitForModels()`. If omitted, returns
204
- * the default tool definitions with static model lists.
205
- *
206
- * @example
207
- * ```typescript
208
- * import { buildSogniTools } from '@sogni-ai/sogni-client';
209
- *
210
- * const models = await sogni.projects.waitForModels();
211
- * const tools = buildSogniTools(models);
212
- *
213
- * const stream = await sogni.chat.completions.create({
214
- * model: 'qwen3.6-35b-a3b-gguf-iq4xs',
215
- * messages,
216
- * tools,
217
- * stream: true,
218
- * });
219
- * ```
220
- */
221
81
  export function buildSogniTools(
222
82
  availableModels?: Array<{ id: string; media?: string }>
223
83
  ): ToolDefinition[] {
@@ -225,56 +85,49 @@ export function buildSogniTools(
225
85
  return SogniTools.all;
226
86
  }
227
87
 
228
- const imageModels = availableModels.filter((m) => m.media === 'image').map((m) => m.id);
229
- const videoModels = availableModels.filter((m) => m.media === 'video').map((m) => m.id);
230
- const audioModels = availableModels.filter((m) => m.media === 'audio').map((m) => m.id);
231
-
232
- const tools: ToolDefinition[] = [];
233
-
234
- // Image tool override model enum if image models are available
235
- const imageTool = structuredClone(generateImageTool);
236
- if (imageModels.length > 0) {
237
- (imageTool.function.parameters as any).properties.model.enum = imageModels;
238
- }
239
- tools.push(imageTool);
240
-
241
- // Video tool — override model enum if video models are available
242
- const videoTool = structuredClone(generateVideoTool);
243
- if (videoModels.length > 0) {
244
- (videoTool.function.parameters as any).properties.model = {
245
- type: 'string',
246
- description: 'Video generation model to use. Choose a text-to-video (t2v) model.',
247
- enum: videoModels
248
- };
249
- }
250
- tools.push(videoTool);
251
-
252
- // Music tool — override model enum if audio models are available
253
- const musicTool = structuredClone(generateMusicTool);
254
- if (audioModels.length > 0) {
255
- (musicTool.function.parameters as any).properties.model = {
256
- type: 'string',
257
- description:
258
- 'Music generation model. "ace_step_1.5_turbo" for fast/catchy, "ace_step_1.5_sft" for more control over lyrics.',
259
- enum: audioModels
260
- };
261
- }
262
- tools.push(musicTool);
88
+ const imageModels = availableModels
89
+ .filter((model) => model.media === 'image')
90
+ .map((model) => model.id);
91
+ const editImageModels = availableModels
92
+ .filter((model) => model.media === 'image' && isEditImageModel(model.id))
93
+ .map((model) => model.id);
94
+ const videoModels = filterVideoModelsByWorkflow(availableModels, ['t2v', 'i2v']);
95
+ const soundToVideoModels = filterVideoModelsByWorkflow(availableModels, ['s2v', 'ia2v', 'a2v']);
96
+ const videoToVideoModels = filterVideoModelsByWorkflow(availableModels, [
97
+ 'animate-move',
98
+ 'animate-replace',
99
+ 'v2v'
100
+ ] as VideoWorkflow[]);
101
+ const audioModels = availableModels
102
+ .filter((model) => model.media === 'audio')
103
+ .map((model) => model.id);
263
104
 
264
- return tools;
105
+ return [
106
+ setModelEnum(cloneTool(generateImageTool), imageModels, 'Image generation model to use.'),
107
+ setModelEnum(
108
+ cloneTool(editImageTool),
109
+ editImageModels,
110
+ 'Image editing model to use. These models support reference-guided editing.'
111
+ ),
112
+ setModelEnum(
113
+ cloneTool(generateVideoTool),
114
+ videoModels,
115
+ 'Video generation model to use. Prefer t2v models for text-only generation and i2v models when reference images are supplied.'
116
+ ),
117
+ setModelEnum(
118
+ cloneTool(soundToVideoTool),
119
+ soundToVideoModels,
120
+ 'Audio-driven video model to use.'
121
+ ),
122
+ setModelEnum(cloneTool(videoToVideoTool), videoToVideoModels, 'Video-to-video model to use.'),
123
+ setModelEnum(cloneTool(generateMusicTool), audioModels, 'Music generation model to use.')
124
+ ];
265
125
  }
266
126
 
267
- /**
268
- * Check if a tool call is a Sogni platform tool.
269
- */
270
127
  export function isSogniToolCall(toolCall: ToolCall): boolean {
271
128
  return toolCall.function.name.startsWith('sogni_');
272
129
  }
273
130
 
274
- /**
275
- * Parse arguments from a tool call's JSON string.
276
- * Returns the parsed object or an empty object if parsing fails.
277
- */
278
131
  export function parseToolCallArguments(toolCall: ToolCall): Record<string, unknown> {
279
132
  try {
280
133
  return JSON.parse(toolCall.function.arguments);
package/src/Chat/types.ts CHANGED
@@ -36,6 +36,31 @@ export type ToolChoice =
36
36
  | 'required'
37
37
  | { type: 'function'; function: { name: string } };
38
38
 
39
+ export type SogniToolsMode = boolean | 'creative-agent' | 'creative-tools' | 'rich';
40
+
41
+ /**
42
+ * OpenAI-compatible structured-output controls. Forwarded to the worker
43
+ * unchanged; honored natively by llama-server (compiles JSON Schema → GBNF
44
+ * internally) and vLLM (`xgrammar` / `outlines`). Per-request opt-in — when
45
+ * omitted, the model generates without constraint.
46
+ */
47
+ export type ChatResponseFormat =
48
+ | { type: 'text' }
49
+ | { type: 'json_object' }
50
+ | {
51
+ type: 'json_schema';
52
+ json_schema: {
53
+ /** Identifier for cached grammar reuse. */
54
+ name: string;
55
+ /** JSON Schema describing the required output shape. */
56
+ schema: Record<string, unknown>;
57
+ /** When true, only fields named in `schema` may appear. Default: false. */
58
+ strict?: boolean;
59
+ /** Optional description shown to the model. */
60
+ description?: string;
61
+ };
62
+ };
63
+
39
64
  /** Text content part for multimodal messages. */
40
65
  export interface TextContentPart {
41
66
  type: 'text';
@@ -46,7 +71,7 @@ export interface TextContentPart {
46
71
  export interface ImageUrlContentPart {
47
72
  type: 'image_url';
48
73
  image_url: {
49
- /** Supports http(s) URLs and data URIs (e.g., `data:image/jpeg;base64,...`). */
74
+ /** Supports inline base64-encoded JPEG or PNG data URIs only (e.g., `data:image/jpeg;base64,...`) for vision-model inputs. Max 20 images per request, 10MB each, longest side 1024px. */
50
75
  url: string;
51
76
  /** Controls how the model processes the image: 'auto' (default), 'low' (faster), 'high' (more detail). */
52
77
  detail?: 'auto' | 'low' | 'high';
@@ -67,6 +92,8 @@ export interface ChatMessage {
67
92
  export interface ChatCompletionParams {
68
93
  model: string;
69
94
  messages: ChatMessage[];
95
+ /** Optional source label for this request. Defaults to the client appSource when configured. */
96
+ appSource?: string;
70
97
  max_tokens?: number;
71
98
  temperature?: number;
72
99
  top_p?: number;
@@ -83,6 +110,19 @@ export interface ChatCompletionParams {
83
110
  tools?: ToolDefinition[];
84
111
  /** Controls which (if any) tool is called by the model. */
85
112
  tool_choice?: ToolChoice;
113
+ /**
114
+ * Ask the Sogni API to inject server-side media-generation tool families.
115
+ * `true` or `'creative-tools'` injects the hosted creative media/planning tool family.
116
+ * `'rich'` is accepted as a legacy alias for `'creative-tools'`.
117
+ * `'creative-agent'` adds hosted workflow-control and asset-manifest tools.
118
+ */
119
+ sogni_tools?: SogniToolsMode;
120
+ /**
121
+ * When `sogni_tools` is enabled, ask the Sogni API to execute requested Sogni
122
+ * tools server-side before returning the chat response. This is separate from
123
+ * the SDK-local `autoExecuteTools` loop.
124
+ */
125
+ sogni_tool_execution?: boolean;
86
126
  /**
87
127
  * Control thinking/reasoning mode for supported models (e.g. Qwen3/3.5).
88
128
  * When `false`, sends `chat_template_kwargs: { enable_thinking: false }` so
@@ -92,6 +132,12 @@ export interface ChatCompletionParams {
92
132
  think?: boolean;
93
133
  /** Hint for server-side preset selection. */
94
134
  taskProfile?: 'general' | 'coding' | 'reasoning';
135
+ /**
136
+ * Constrain output structure (OpenAI-compatible). Most useful on tool-call
137
+ * rounds where the model must emit a specific argument shape — eliminates
138
+ * JSON drift on quantized models. Forwarded to the worker unchanged.
139
+ */
140
+ response_format?: ChatResponseFormat;
95
141
  /**
96
142
  * Automatically execute Sogni tool calls (image/video/music generation) when the
97
143
  * model requests them. The SDK handles the full multi-round tool calling loop:
@@ -124,6 +170,7 @@ export interface ChatRequestMessage {
124
170
  type: 'llm';
125
171
  model: string;
126
172
  messages: ChatMessage[];
173
+ appSource?: string;
127
174
  max_tokens?: number;
128
175
  temperature?: number;
129
176
  top_p?: number;
@@ -137,9 +184,13 @@ export interface ChatRequestMessage {
137
184
  tokenType?: 'sogni' | 'spark';
138
185
  tools?: ToolDefinition[];
139
186
  tool_choice?: ToolChoice;
187
+ sogni_tools?: SogniToolsMode;
188
+ sogni_tool_execution?: boolean;
140
189
  taskProfile?: 'general' | 'coding' | 'reasoning';
141
190
  /** Per-request chat template arguments (e.g. `{ enable_thinking: false }` for llama.cpp). */
142
191
  chat_template_kwargs?: Record<string, unknown>;
192
+ /** Per-request structured-output constraint (OpenAI-compatible). */
193
+ response_format?: ChatResponseFormat;
143
194
  }
144
195
 
145
196
  export interface ChatCompletionChunk {
@@ -175,6 +226,52 @@ export interface ChatCompletionResult {
175
226
  toolHistory?: ToolHistoryEntry[];
176
227
  }
177
228
 
229
+ export interface HostedChatCompletionMessage {
230
+ role: 'system' | 'user' | 'assistant' | 'tool';
231
+ content: string | null;
232
+ tool_calls?: ToolCall[];
233
+ tool_call_id?: string;
234
+ }
235
+
236
+ export interface HostedChatCompletionChoice {
237
+ index: number;
238
+ message: HostedChatCompletionMessage;
239
+ finish_reason: string | null;
240
+ }
241
+
242
+ export interface HostedCreativeWorkflowReference {
243
+ workflowId: string;
244
+ status: string;
245
+ url: string;
246
+ eventsUrl: string;
247
+ streamUrl: string;
248
+ }
249
+
250
+ export interface HostedChatCompletionResult {
251
+ id: string;
252
+ object: 'chat.completion';
253
+ created: number;
254
+ model: string;
255
+ choices: HostedChatCompletionChoice[];
256
+ usage?: TokenUsage;
257
+ creative_workflows?: HostedCreativeWorkflowReference[];
258
+ sogni_tool_results?: Record<string, unknown>[];
259
+ }
260
+
261
+ export type HostedChatCompletionParams = Omit<
262
+ ChatCompletionParams,
263
+ 'stream' | 'autoExecuteTools' | 'onToolCall' | 'onToolProgress' | 'maxToolRounds'
264
+ > & {
265
+ stream?: false;
266
+ token_type?: 'sogni' | 'spark' | 'auto';
267
+ app_source?: string;
268
+ chat_template_kwargs?: Record<string, unknown>;
269
+ media_references?: unknown[];
270
+ mediaReferences?: unknown[];
271
+ api_media_references?: unknown[];
272
+ apiMediaReferences?: unknown[];
273
+ };
274
+
178
275
  export interface ChatJobStateEvent {
179
276
  jobID: string;
180
277
  type: string;
@@ -191,6 +288,7 @@ export interface LLMParamConstraint {
191
288
  max: number;
192
289
  decimals?: number;
193
290
  default: number;
291
+ thinkingComplexDefault?: number;
194
292
  }
195
293
 
196
294
  /** Recommended sampling defaults for a specific thinking mode. */
@@ -329,7 +427,7 @@ export interface ToolExecutionOptions {
329
427
  * complete within this time, the tool call will fail with a timeout error
330
428
  * and the project will be canceled.
331
429
  *
332
- * Default: 600000 (10 minutes).
430
+ * Default: 1800000 (30 minutes).
333
431
  */
334
432
  timeout?: number;
335
433
  }