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

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 (178) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/CLAUDE.md +7 -0
  3. package/README.md +45 -25
  4. package/dist/Chat/ChatTools.js +30 -16
  5. package/dist/Chat/ChatTools.js.map +1 -1
  6. package/dist/Chat/hostedToolValidation.generated.d.ts +46 -0
  7. package/dist/Chat/hostedToolValidation.generated.js +306 -0
  8. package/dist/Chat/hostedToolValidation.generated.js.map +1 -0
  9. package/dist/Chat/index.d.ts +41 -1
  10. package/dist/Chat/index.js +285 -26
  11. package/dist/Chat/index.js.map +1 -1
  12. package/dist/Chat/modelRouting.d.ts +8 -26
  13. package/dist/Chat/modelRouting.js +11 -106
  14. package/dist/Chat/modelRouting.js.map +1 -1
  15. package/dist/Chat/sogniHostedTools.generated.json +1596 -304
  16. package/dist/Chat/tools.d.ts +52 -3
  17. package/dist/Chat/tools.js +80 -27
  18. package/dist/Chat/tools.js.map +1 -1
  19. package/dist/Chat/types.d.ts +119 -3
  20. package/dist/CreativeWorkflows/index.d.ts +1 -7
  21. package/dist/CreativeWorkflows/index.js +60 -21
  22. package/dist/CreativeWorkflows/index.js.map +1 -1
  23. package/dist/CreativeWorkflows/types.d.ts +28 -33
  24. package/dist/Projects/index.d.ts +49 -8
  25. package/dist/Projects/index.js +49 -8
  26. package/dist/Projects/index.js.map +1 -1
  27. package/dist/index.d.ts +19 -4
  28. package/dist/index.js +1 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/lib/Cache.js +6 -1
  31. package/dist/lib/Cache.js.map +1 -1
  32. package/dist/lib/mediaValidation.d.ts +3 -0
  33. package/dist/lib/mediaValidation.js +154 -0
  34. package/dist/lib/mediaValidation.js.map +1 -1
  35. package/dist-esm/Account/CurrentAccount.js +59 -0
  36. package/dist-esm/Account/CurrentAccount.js.map +1 -0
  37. package/dist-esm/Account/index.js +543 -0
  38. package/dist-esm/Account/index.js.map +1 -0
  39. package/dist-esm/Account/types.js +2 -0
  40. package/dist-esm/Account/types.js.map +1 -0
  41. package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/ChannelCoordinator.js +327 -0
  42. package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/ChannelCoordinator.js.map +1 -0
  43. package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +222 -0
  44. package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -0
  45. package/dist-esm/ApiClient/WebSocketClient/ErrorCode.js +15 -0
  46. package/dist-esm/ApiClient/WebSocketClient/ErrorCode.js.map +1 -0
  47. package/dist-esm/ApiClient/WebSocketClient/eventSubscriptions.js +35 -0
  48. package/dist-esm/ApiClient/WebSocketClient/eventSubscriptions.js.map +1 -0
  49. package/dist-esm/ApiClient/WebSocketClient/events.js +2 -0
  50. package/dist-esm/ApiClient/WebSocketClient/events.js.map +1 -0
  51. package/dist-esm/ApiClient/WebSocketClient/index.js +221 -0
  52. package/dist-esm/ApiClient/WebSocketClient/index.js.map +1 -0
  53. package/dist-esm/ApiClient/WebSocketClient/messages.js +2 -0
  54. package/dist-esm/ApiClient/WebSocketClient/messages.js.map +1 -0
  55. package/dist-esm/ApiClient/WebSocketClient/types.js +2 -0
  56. package/dist-esm/ApiClient/WebSocketClient/types.js.map +1 -0
  57. package/dist-esm/ApiClient/events.js +2 -0
  58. package/dist-esm/ApiClient/events.js.map +1 -0
  59. package/dist-esm/ApiClient/index.js +120 -0
  60. package/dist-esm/ApiClient/index.js.map +1 -0
  61. package/dist-esm/ApiGroup.js +10 -0
  62. package/dist-esm/ApiGroup.js.map +1 -0
  63. package/dist-esm/Chat/ChatStream.js +181 -0
  64. package/dist-esm/Chat/ChatStream.js.map +1 -0
  65. package/dist-esm/Chat/ChatTools.js +562 -0
  66. package/dist-esm/Chat/ChatTools.js.map +1 -0
  67. package/dist-esm/Chat/hostedToolValidation.generated.js +301 -0
  68. package/dist-esm/Chat/hostedToolValidation.generated.js.map +1 -0
  69. package/dist-esm/Chat/index.js +693 -0
  70. package/dist-esm/Chat/index.js.map +1 -0
  71. package/dist-esm/Chat/modelRouting.js +326 -0
  72. package/dist-esm/Chat/modelRouting.js.map +1 -0
  73. package/dist-esm/Chat/sogniHostedTools.generated.json +1821 -0
  74. package/dist-esm/Chat/tools.js +149 -0
  75. package/dist-esm/Chat/tools.js.map +1 -0
  76. package/dist-esm/Chat/types.js +2 -0
  77. package/dist-esm/Chat/types.js.map +1 -0
  78. package/dist-esm/CreativeWorkflows/index.js +293 -0
  79. package/dist-esm/CreativeWorkflows/index.js.map +1 -0
  80. package/dist-esm/CreativeWorkflows/types.js +2 -0
  81. package/dist-esm/CreativeWorkflows/types.js.map +1 -0
  82. package/dist-esm/Projects/Job.js +391 -0
  83. package/dist-esm/Projects/Job.js.map +1 -0
  84. package/dist-esm/Projects/Project.js +295 -0
  85. package/dist-esm/Projects/Project.js.map +1 -0
  86. package/dist-esm/Projects/createJobRequestMessage.js +528 -0
  87. package/dist-esm/Projects/createJobRequestMessage.js.map +1 -0
  88. package/dist-esm/Projects/index.js +1350 -0
  89. package/dist-esm/Projects/index.js.map +1 -0
  90. package/dist-esm/Projects/types/ComfySamplerParams.js +2 -0
  91. package/dist-esm/Projects/types/ComfySamplerParams.js.map +1 -0
  92. package/dist-esm/Projects/types/ControlNetParams.js +2 -0
  93. package/dist-esm/Projects/types/ControlNetParams.js.map +1 -0
  94. package/dist-esm/Projects/types/EstimationResponse.js +2 -0
  95. package/dist-esm/Projects/types/EstimationResponse.js.map +1 -0
  96. package/dist-esm/Projects/types/ModelOptions.js +89 -0
  97. package/dist-esm/Projects/types/ModelOptions.js.map +1 -0
  98. package/dist-esm/Projects/types/ModelTiersRaw.js +13 -0
  99. package/dist-esm/Projects/types/ModelTiersRaw.js.map +1 -0
  100. package/dist-esm/Projects/types/RawProject.js +2 -0
  101. package/dist-esm/Projects/types/RawProject.js.map +1 -0
  102. package/dist-esm/Projects/types/events.js +2 -0
  103. package/dist-esm/Projects/types/events.js.map +1 -0
  104. package/dist-esm/Projects/types/index.js +10 -0
  105. package/dist-esm/Projects/types/index.js.map +1 -0
  106. package/dist-esm/Projects/utils/index.js +229 -0
  107. package/dist-esm/Projects/utils/index.js.map +1 -0
  108. package/dist-esm/Projects/utils/samplers.js +36 -0
  109. package/dist-esm/Projects/utils/samplers.js.map +1 -0
  110. package/dist-esm/Projects/utils/scheduler.js +27 -0
  111. package/dist-esm/Projects/utils/scheduler.js.map +1 -0
  112. package/dist-esm/Stats/index.js +20 -0
  113. package/dist-esm/Stats/index.js.map +1 -0
  114. package/dist-esm/Stats/types.js +2 -0
  115. package/dist-esm/Stats/types.js.map +1 -0
  116. package/dist-esm/events.js +2 -0
  117. package/dist-esm/events.js.map +1 -0
  118. package/dist-esm/index.js +144 -0
  119. package/dist-esm/index.js.map +1 -0
  120. package/dist-esm/lib/AuthManager/ApiKeyAuthManager.js +58 -0
  121. package/dist-esm/lib/AuthManager/ApiKeyAuthManager.js.map +1 -0
  122. package/dist-esm/lib/AuthManager/AuthManagerBase.js +9 -0
  123. package/dist-esm/lib/AuthManager/AuthManagerBase.js.map +1 -0
  124. package/dist-esm/lib/AuthManager/CookieAuthManager.js +48 -0
  125. package/dist-esm/lib/AuthManager/CookieAuthManager.js.map +1 -0
  126. package/dist-esm/lib/AuthManager/TokenAuthManager.js +186 -0
  127. package/dist-esm/lib/AuthManager/TokenAuthManager.js.map +1 -0
  128. package/dist-esm/lib/AuthManager/index.js +5 -0
  129. package/dist-esm/lib/AuthManager/index.js.map +1 -0
  130. package/dist-esm/lib/Cache.js +32 -0
  131. package/dist-esm/lib/Cache.js.map +1 -0
  132. package/dist-esm/lib/DataEntity.js +30 -0
  133. package/dist-esm/lib/DataEntity.js.map +1 -0
  134. package/dist-esm/lib/DefaultLogger.js +32 -0
  135. package/dist-esm/lib/DefaultLogger.js.map +1 -0
  136. package/dist-esm/lib/EIP712Helper.js +37 -0
  137. package/dist-esm/lib/EIP712Helper.js.map +1 -0
  138. package/dist-esm/lib/RestClient.js +90 -0
  139. package/dist-esm/lib/RestClient.js.map +1 -0
  140. package/dist-esm/lib/TypedEventEmitter.js +68 -0
  141. package/dist-esm/lib/TypedEventEmitter.js.map +1 -0
  142. package/dist-esm/lib/base64.js +18 -0
  143. package/dist-esm/lib/base64.js.map +1 -0
  144. package/dist-esm/lib/getUUID.js +7 -0
  145. package/dist-esm/lib/getUUID.js.map +1 -0
  146. package/dist-esm/lib/isNodejs.js +3 -0
  147. package/dist-esm/lib/isNodejs.js.map +1 -0
  148. package/dist-esm/lib/mediaValidation.js +430 -0
  149. package/dist-esm/lib/mediaValidation.js.map +1 -0
  150. package/dist-esm/lib/utils/index.js +30 -0
  151. package/dist-esm/lib/utils/index.js.map +1 -0
  152. package/dist-esm/lib/validation.js +138 -0
  153. package/dist-esm/lib/validation.js.map +1 -0
  154. package/dist-esm/package.json +3 -0
  155. package/dist-esm/types/ErrorData.js +2 -0
  156. package/dist-esm/types/ErrorData.js.map +1 -0
  157. package/dist-esm/types/json.js +2 -0
  158. package/dist-esm/types/json.js.map +1 -0
  159. package/dist-esm/types/token.js +2 -0
  160. package/dist-esm/types/token.js.map +1 -0
  161. package/dist-esm/version.js +3 -0
  162. package/dist-esm/version.js.map +1 -0
  163. package/llms-full.txt +11 -20
  164. package/llms.txt +9 -18
  165. package/package.json +21 -5
  166. package/src/Chat/ChatTools.ts +36 -16
  167. package/src/Chat/hostedToolValidation.generated.ts +453 -0
  168. package/src/Chat/index.ts +322 -37
  169. package/src/Chat/modelRouting.ts +26 -150
  170. package/src/Chat/sogniHostedTools.generated.json +1596 -304
  171. package/src/Chat/tools.ts +106 -41
  172. package/src/Chat/types.ts +131 -3
  173. package/src/CreativeWorkflows/index.ts +55 -41
  174. package/src/CreativeWorkflows/types.ts +70 -42
  175. package/src/Projects/index.ts +49 -8
  176. package/src/index.ts +33 -12
  177. package/src/lib/Cache.ts +8 -1
  178. package/src/lib/mediaValidation.ts +155 -0
package/src/Chat/tools.ts CHANGED
@@ -2,19 +2,41 @@ import hostedToolManifest from './sogniHostedTools.generated.json';
2
2
  import { ToolDefinition, ToolCall } from './types';
3
3
  import { filterVideoModelsByWorkflow, isEditImageModel, VideoWorkflow } from './modelRouting';
4
4
 
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';
5
+ /**
6
+ * Canonical hosted creative-tool names mirrored from
7
+ * `@sogni/creative-agent/src/backbone/openai-tools/{generation,composition}-tools.json`.
8
+ * The legacy `sogni_*` prefixed names were retired; tool names are now flat.
9
+ */
10
+ export type SogniHostedToolName =
11
+ | 'generate_image'
12
+ | 'generate_video'
13
+ | 'generate_music'
14
+ | 'edit_image'
15
+ | 'apply_style'
16
+ | 'restore_photo'
17
+ | 'refine_result'
18
+ | 'animate_photo'
19
+ | 'change_angle'
20
+ | 'video_to_video'
21
+ | 'stitch_video'
22
+ | 'orbit_video'
23
+ | 'dance_montage'
24
+ | 'sound_to_video'
25
+ | 'extend_video'
26
+ | 'replace_video_segment'
27
+ | 'overlay_video'
28
+ | 'add_subtitles'
29
+ | 'enhance_prompt'
30
+ | 'compose_lyrics'
31
+ | 'compose_instrumental'
32
+ | 'compose_script';
12
33
 
13
34
  interface SogniHostedToolManifest {
14
35
  tools: ToolDefinition[];
15
36
  }
16
37
 
17
38
  const hostedTools = (hostedToolManifest as SogniHostedToolManifest).tools;
39
+ const HOSTED_TOOL_NAMES = new Set<string>(hostedTools.map((tool) => tool.function.name));
18
40
 
19
41
  function getHostedTool(name: SogniHostedToolName): ToolDefinition {
20
42
  const tool = hostedTools.find((candidate) => candidate.function.name === name);
@@ -47,17 +69,40 @@ function setModelEnum(
47
69
  /**
48
70
  * Built-in Sogni platform tool definitions for use with LLM tool calling.
49
71
  *
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.
72
+ * Generated from the shared `@sogni/creative-agent` hosted tool backbone via
73
+ * `npm run sync:hosted-tools-manifest`. The public SDK keeps a local copy so
74
+ * consumers do not need the private creative-agent package at runtime.
53
75
  */
54
76
 
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');
77
+ // Generation tools (image / video / audio).
78
+ export const generateImageTool: ToolDefinition = getHostedTool('generate_image');
79
+ export const editImageTool: ToolDefinition = getHostedTool('edit_image');
80
+ export const generateVideoTool: ToolDefinition = getHostedTool('generate_video');
81
+ export const soundToVideoTool: ToolDefinition = getHostedTool('sound_to_video');
82
+ export const videoToVideoTool: ToolDefinition = getHostedTool('video_to_video');
83
+ export const generateMusicTool: ToolDefinition = getHostedTool('generate_music');
84
+
85
+ // Image adapters (style / restore / refine / re-angle / animate).
86
+ export const applyStyleTool: ToolDefinition = getHostedTool('apply_style');
87
+ export const restorePhotoTool: ToolDefinition = getHostedTool('restore_photo');
88
+ export const refineResultTool: ToolDefinition = getHostedTool('refine_result');
89
+ export const changeAngleTool: ToolDefinition = getHostedTool('change_angle');
90
+ export const animatePhotoTool: ToolDefinition = getHostedTool('animate_photo');
91
+
92
+ // Video composition / post-production tools.
93
+ export const stitchVideoTool: ToolDefinition = getHostedTool('stitch_video');
94
+ export const orbitVideoTool: ToolDefinition = getHostedTool('orbit_video');
95
+ export const danceMontageTool: ToolDefinition = getHostedTool('dance_montage');
96
+ export const extendVideoTool: ToolDefinition = getHostedTool('extend_video');
97
+ export const replaceVideoSegmentTool: ToolDefinition = getHostedTool('replace_video_segment');
98
+ export const overlayVideoTool: ToolDefinition = getHostedTool('overlay_video');
99
+ export const addSubtitlesTool: ToolDefinition = getHostedTool('add_subtitles');
100
+
101
+ // Synchronous composition tools (text-only outputs).
102
+ export const enhancePromptTool: ToolDefinition = getHostedTool('enhance_prompt');
103
+ export const composeLyricsTool: ToolDefinition = getHostedTool('compose_lyrics');
104
+ export const composeInstrumentalTool: ToolDefinition = getHostedTool('compose_instrumental');
105
+ export const composeScriptTool: ToolDefinition = getHostedTool('compose_script');
61
106
 
62
107
  export const SogniTools = {
63
108
  generateImage: generateImageTool,
@@ -66,15 +111,30 @@ export const SogniTools = {
66
111
  soundToVideo: soundToVideoTool,
67
112
  videoToVideo: videoToVideoTool,
68
113
  generateMusic: generateMusicTool,
114
+ applyStyle: applyStyleTool,
115
+ restorePhoto: restorePhotoTool,
116
+ refineResult: refineResultTool,
117
+ changeAngle: changeAngleTool,
118
+ animatePhoto: animatePhotoTool,
119
+ stitchVideo: stitchVideoTool,
120
+ orbitVideo: orbitVideoTool,
121
+ danceMontage: danceMontageTool,
122
+ extendVideo: extendVideoTool,
123
+ replaceVideoSegment: replaceVideoSegmentTool,
124
+ overlayVideo: overlayVideoTool,
125
+ addSubtitles: addSubtitlesTool,
126
+ enhancePrompt: enhancePromptTool,
127
+ composeLyrics: composeLyricsTool,
128
+ composeInstrumental: composeInstrumentalTool,
129
+ composeScript: composeScriptTool,
130
+ /**
131
+ * Full canonical hosted creative-tools surface — generation tools, image
132
+ * adapters, video composition / post-production, and synchronous composition
133
+ * tools. Mirrored from `@sogni/creative-agent`. Route tool calls through
134
+ * `chat.hosted.create()` or `chat.runs.create()` for server-side execution.
135
+ */
69
136
  get all(): ToolDefinition[] {
70
- return [
71
- generateImageTool,
72
- editImageTool,
73
- generateVideoTool,
74
- soundToVideoTool,
75
- videoToVideoTool,
76
- generateMusicTool
77
- ];
137
+ return [...hostedTools];
78
138
  }
79
139
  };
80
140
 
@@ -102,30 +162,35 @@ export function buildSogniTools(
102
162
  .filter((model) => model.media === 'audio')
103
163
  .map((model) => model.id);
104
164
 
105
- return [
106
- setModelEnum(cloneTool(generateImageTool), imageModels, 'Image generation model to use.'),
107
- setModelEnum(
108
- cloneTool(editImageTool),
165
+ const modelEnumOverrides: Partial<Record<SogniHostedToolName, [string[], string]>> = {
166
+ generate_image: [imageModels, 'Image generation model to use.'],
167
+ edit_image: [
109
168
  editImageModels,
110
169
  'Image editing model to use. These models support reference-guided editing.'
111
- ),
112
- setModelEnum(
113
- cloneTool(generateVideoTool),
170
+ ],
171
+ generate_video: [
114
172
  videoModels,
115
173
  '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
- ];
174
+ ],
175
+ sound_to_video: [soundToVideoModels, 'Audio-driven video model to use.'],
176
+ video_to_video: [videoToVideoModels, 'Video-to-video model to use.'],
177
+ generate_music: [audioModels, 'Music generation model to use.']
178
+ };
179
+
180
+ return hostedTools.map((tool) => {
181
+ const override = modelEnumOverrides[tool.function.name as SogniHostedToolName];
182
+ if (!override) return tool;
183
+ return setModelEnum(cloneTool(tool), override[0], override[1]);
184
+ });
125
185
  }
126
186
 
187
+ /**
188
+ * True if the tool call targets a canonical Sogni hosted creative tool.
189
+ * Replaces the legacy `sogni_` prefix check; tool names are now flat and
190
+ * verified against the manifest mirrored from `@sogni/creative-agent`.
191
+ */
127
192
  export function isSogniToolCall(toolCall: ToolCall): boolean {
128
- return toolCall.function.name.startsWith('sogni_');
193
+ return HOSTED_TOOL_NAMES.has(toolCall.function.name);
129
194
  }
130
195
 
131
196
  export function parseToolCallArguments(toolCall: ToolCall): Record<string, unknown> {
package/src/Chat/types.ts CHANGED
@@ -119,8 +119,8 @@ export interface ChatCompletionParams {
119
119
  sogni_tools?: SogniToolsMode;
120
120
  /**
121
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.
122
+ * tools server-side before returning the chat response. Independent of the
123
+ * SDK's client-side `autoExecuteTools` loop.
124
124
  */
125
125
  sogni_tool_execution?: boolean;
126
126
  /**
@@ -263,8 +263,18 @@ export type HostedChatCompletionParams = Omit<
263
263
  'stream' | 'autoExecuteTools' | 'onToolCall' | 'onToolProgress' | 'maxToolRounds'
264
264
  > & {
265
265
  stream?: false;
266
- token_type?: 'sogni' | 'spark' | 'auto';
266
+ /** Optional source label for this hosted REST request. Defaults to the client appSource when configured. */
267
267
  app_source?: string;
268
+ /** camelCase alias for {@link HostedChatCompletionParams.app_source}. */
269
+ appSource?: string;
270
+ /** Token type to use for hosted REST billing. */
271
+ token_type?: 'sogni' | 'spark';
272
+ /** camelCase alias for {@link HostedChatCompletionParams.token_type}. */
273
+ tokenType?: 'sogni' | 'spark';
274
+ /** Hosted REST task profile hint. */
275
+ task_profile?: 'general' | 'coding' | 'reasoning';
276
+ /** camelCase alias for {@link HostedChatCompletionParams.task_profile}. */
277
+ taskProfile?: 'general' | 'coding' | 'reasoning';
268
278
  chat_template_kwargs?: Record<string, unknown>;
269
279
  media_references?: unknown[];
270
280
  mediaReferences?: unknown[];
@@ -272,6 +282,124 @@ export type HostedChatCompletionParams = Omit<
272
282
  apiMediaReferences?: unknown[];
273
283
  };
274
284
 
285
+ /**
286
+ * Durable hosted chat run status.
287
+ *
288
+ * Mirrors the canonical state machine from
289
+ * `@sogni/creative-agent/backbone` `ChatRunStatus`. The duplicate
290
+ * declaration here keeps the SDK self-contained — the shared package is
291
+ * not a runtime SDK dependency.
292
+ */
293
+ export type ChatRunStatus =
294
+ | 'queued'
295
+ | 'running'
296
+ | 'waiting_for_user'
297
+ | 'completed'
298
+ | 'partial_failure'
299
+ | 'failed'
300
+ | 'cancelled';
301
+
302
+ export interface ChatRunEvent {
303
+ sequence: number;
304
+ type: string;
305
+ at: string;
306
+ payload?: Record<string, unknown>;
307
+ }
308
+
309
+ export interface ChatRunRecord {
310
+ runId: string;
311
+ status: ChatRunStatus;
312
+ schemaVersion: string;
313
+ scope: {
314
+ ownerWalletAddress: string;
315
+ tokenType?: string;
316
+ appSource?: string;
317
+ };
318
+ request: {
319
+ sessionId?: string;
320
+ clientMessageId?: string;
321
+ model?: string;
322
+ messages: unknown[];
323
+ [key: string]: unknown;
324
+ };
325
+ messages: unknown[];
326
+ toolCalls: unknown[];
327
+ toolResults: unknown[];
328
+ mediaContext: {
329
+ images: string[];
330
+ videos: string[];
331
+ audio: string[];
332
+ uploadedImages?: string[];
333
+ uploadedVideos?: string[];
334
+ uploadedAudio?: string[];
335
+ };
336
+ artifacts: unknown[];
337
+ events: ChatRunEvent[];
338
+ finalResponse?: {
339
+ content?: string;
340
+ finishReason?: string;
341
+ };
342
+ waiting?: {
343
+ reason: string;
344
+ message?: string;
345
+ details?: Record<string, unknown>;
346
+ };
347
+ billingPreview?: unknown;
348
+ billingPreviews?: unknown[];
349
+ failureReason?: string;
350
+ cancellationReason?: string;
351
+ timestamps: {
352
+ createdAt: string;
353
+ updatedAt: string;
354
+ completedAt?: string;
355
+ };
356
+ }
357
+
358
+ export interface StartChatRunParams {
359
+ /** OpenAI-style messages array. Required. */
360
+ messages: unknown[];
361
+ /** OpenAI-style tools array. */
362
+ tools?: unknown[];
363
+ /** OpenAI-style tool choice (`auto`, `none`, or specific tool). */
364
+ toolChoice?: unknown;
365
+ /** Model id requested for the run. */
366
+ model?: string;
367
+ /** Sampling defaults captured with the run for reproducibility. */
368
+ sampling?: Record<string, unknown>;
369
+ /** Inbound media references attached to the run. Durable runs require uploaded HTTP(S) URLs, not inline data URIs. */
370
+ mediaReferences?: unknown[];
371
+ /** Full chat media context snapshot for generated + uploaded source indexing. Durable runs require uploaded HTTP(S) URLs, not inline data URIs. */
372
+ mediaContext?: {
373
+ images: string[];
374
+ videos: string[];
375
+ audio: string[];
376
+ uploadedImages?: string[];
377
+ uploadedVideos?: string[];
378
+ uploadedAudio?: string[];
379
+ };
380
+ /** Cost ceiling for this run (capacity units). */
381
+ maxEstimatedCapacityUnits?: number;
382
+ /** Set true to confirm higher-cost work. */
383
+ confirmCost?: boolean;
384
+ /** Stable session id for browser-side rehydration queries. */
385
+ sessionId?: string;
386
+ /** Stable client message id for pairing with the assistant response. */
387
+ clientMessageId?: string;
388
+ /** Token type for billing. */
389
+ tokenType?: 'sogni' | 'spark';
390
+ /** App source label for attribution. */
391
+ appSource?: string;
392
+ /** Idempotency key (also accepted via `Idempotency-Key` header). */
393
+ idempotencyKey?: string;
394
+ }
395
+
396
+ export interface StreamChatRunEventsOptions {
397
+ /** Last event sequence id observed by the caller. */
398
+ lastEventId?: number;
399
+ /** Optional AbortSignal to terminate the stream. */
400
+ signal?: AbortSignal;
401
+ }
402
+
275
403
  export interface ChatJobStateEvent {
276
404
  jobID: string;
277
405
  type: string;
@@ -7,8 +7,6 @@ import {
7
7
  ListCreativeWorkflowOptions,
8
8
  StartCreativeWorkflowOptions,
9
9
  StartCreativeWorkflowParams,
10
- StartHostedToolSequenceWorkflowInput,
11
- StartImageToVideoWorkflowInput,
12
10
  StreamCreativeWorkflowEventsOptions
13
11
  } from './types';
14
12
 
@@ -21,6 +19,8 @@ interface CreativeWorkflowEnvelope {
21
19
  }
22
20
 
23
21
  const TERMINAL_STATUSES = new Set(['completed', 'failed', 'cancelled']);
22
+ const EXTERNAL_DURABLE_MEDIA_URL = /^https?:\/\//i;
23
+ const INLINE_DURABLE_MEDIA_URL = /^data:/i;
24
24
 
25
25
  function toQuery(params: Record<string, string | number | undefined>): string {
26
26
  const query = new URLSearchParams();
@@ -37,6 +37,36 @@ function isTerminalWorkflowStatus(value: unknown): boolean {
37
37
  return typeof value === 'string' && TERMINAL_STATUSES.has(value);
38
38
  }
39
39
 
40
+ function mediaReferenceViolation(path: string, value: unknown): string | null {
41
+ if (typeof value !== 'string') return null;
42
+ const trimmed = value.trim();
43
+ if (!trimmed) return null;
44
+ if (INLINE_DURABLE_MEDIA_URL.test(trimmed)) return path;
45
+ if (!EXTERNAL_DURABLE_MEDIA_URL.test(trimmed)) return path;
46
+ return null;
47
+ }
48
+
49
+ function assertWorkflowUsesExternalMedia(mediaReferences: unknown): void {
50
+ if (!Array.isArray(mediaReferences)) return;
51
+ const violations: string[] = [];
52
+ mediaReferences.forEach((reference, index) => {
53
+ if (!reference || typeof reference !== 'object' || Array.isArray(reference)) return;
54
+ const record = reference as { url?: unknown; dataUri?: unknown; data_uri?: unknown };
55
+ const urlViolation = mediaReferenceViolation(`mediaReferences[${index}].url`, record.url);
56
+ if (urlViolation) violations.push(urlViolation);
57
+ if (typeof record.dataUri === 'string' && record.dataUri.trim()) {
58
+ violations.push(`mediaReferences[${index}].dataUri`);
59
+ }
60
+ if (typeof record.data_uri === 'string' && record.data_uri.trim()) {
61
+ violations.push(`mediaReferences[${index}].data_uri`);
62
+ }
63
+ });
64
+ if (violations.length === 0) return;
65
+ throw new Error(
66
+ `Durable creative workflows do not support inline base64/data URI media. Upload media first and pass HTTP(S) URLs instead. Offending field(s): ${violations.join(', ')}`
67
+ );
68
+ }
69
+
40
70
  function parseJsonResponse(text: string): unknown {
41
71
  if (!text) return {};
42
72
  try {
@@ -107,58 +137,42 @@ class CreativeWorkflowsApi extends ApiGroup {
107
137
  params: StartCreativeWorkflowParams,
108
138
  options: StartCreativeWorkflowOptions = {}
109
139
  ): Promise<CreativeWorkflowRecord> {
140
+ const tokenType = params.tokenType ?? params.token_type;
141
+ const appSource = params.appSource ?? params.app_source;
142
+ const idempotencyKey = params.idempotencyKey ?? params.idempotency_key;
143
+ const mediaReferences = params.mediaReferences ?? params.media_references;
144
+ assertWorkflowUsesExternalMedia(mediaReferences);
145
+ const maxEstimatedCapacityUnits =
146
+ params.maxEstimatedCapacityUnits ?? params.max_estimated_capacity_units;
147
+ const confirmCost = params.confirmCost ?? params.confirm_cost;
148
+
110
149
  const body: Record<string, unknown> = {
111
- kind: params.kind,
112
150
  input: params.input
113
151
  };
114
- const tokenType = params.token_type ?? params.tokenType;
115
- if (tokenType) {
116
- body.token_type = tokenType;
152
+ if (tokenType) body.token_type = tokenType;
153
+ if (appSource) body.app_source = appSource;
154
+ if (maxEstimatedCapacityUnits !== undefined) {
155
+ body.max_estimated_capacity_units = maxEstimatedCapacityUnits;
156
+ }
157
+ if (confirmCost !== undefined) body.confirm_cost = confirmCost;
158
+ if (mediaReferences !== undefined) body.media_references = mediaReferences;
159
+
160
+ const headers: Record<string, string> = {
161
+ 'Content-Type': 'application/json'
162
+ };
163
+ if (idempotencyKey) {
164
+ headers['Idempotency-Key'] = idempotencyKey;
117
165
  }
118
166
 
119
167
  const response = await this.request<CreativeWorkflowEnvelope>('/v1/creative-agent/workflows', {
120
168
  method: 'POST',
121
- headers: {
122
- 'Content-Type': 'application/json'
123
- },
169
+ headers,
124
170
  body: JSON.stringify(body),
125
171
  signal: options.signal
126
172
  });
127
173
  return parseEnvelope<CreativeWorkflowRecord>(response, 'workflow');
128
174
  }
129
175
 
130
- startImageToVideo(
131
- input: StartImageToVideoWorkflowInput,
132
- options: StartCreativeWorkflowOptions & {
133
- tokenType?: StartCreativeWorkflowParams['tokenType'];
134
- } = {}
135
- ): Promise<CreativeWorkflowRecord> {
136
- return this.start(
137
- {
138
- kind: 'image_to_video',
139
- input,
140
- tokenType: options.tokenType
141
- },
142
- options
143
- );
144
- }
145
-
146
- startHostedToolSequence(
147
- input: StartHostedToolSequenceWorkflowInput,
148
- options: StartCreativeWorkflowOptions & {
149
- tokenType?: StartCreativeWorkflowParams['tokenType'];
150
- } = {}
151
- ): Promise<CreativeWorkflowRecord> {
152
- return this.start(
153
- {
154
- kind: 'hosted_tool_sequence',
155
- input,
156
- tokenType: options.tokenType
157
- },
158
- options
159
- );
160
- }
161
-
162
176
  async list(options: ListCreativeWorkflowOptions = {}): Promise<CreativeWorkflowRecord[]> {
163
177
  const response = await this.request<CreativeWorkflowEnvelope>(
164
178
  `/v1/creative-agent/workflows${toQuery({
@@ -4,18 +4,41 @@ export type CreativeWorkflowStatus =
4
4
  | 'queued'
5
5
  | 'running'
6
6
  | 'completed'
7
+ | 'partial_failure'
8
+ | 'waiting_for_user'
7
9
  | 'failed'
8
10
  | 'cancelled'
9
11
  | string;
10
12
 
11
- export type CreativeWorkflowKind = 'image_to_video' | 'hosted_tool_sequence' | string;
12
13
  export type CreativeWorkflowHostedToolName =
13
- | 'sogni_generate_image'
14
- | 'sogni_edit_image'
15
- | 'sogni_generate_video'
16
- | 'sogni_sound_to_video'
17
- | 'sogni_video_to_video'
18
- | 'sogni_generate_music';
14
+ | 'generate_image'
15
+ | 'generate_video'
16
+ | 'generate_music'
17
+ | 'edit_image'
18
+ | 'apply_style'
19
+ | 'restore_photo'
20
+ | 'refine_result'
21
+ | 'animate_photo'
22
+ | 'change_angle'
23
+ | 'video_to_video'
24
+ | 'stitch_video'
25
+ | 'orbit_video'
26
+ | 'dance_montage'
27
+ | 'sound_to_video'
28
+ | 'extend_video'
29
+ | 'replace_video_segment'
30
+ | 'overlay_video'
31
+ | 'add_subtitles'
32
+ | 'analyze_image'
33
+ | 'analyze_video'
34
+ | 'extract_metadata'
35
+ | 'ask_clarifying_question'
36
+ | 'finalize_response'
37
+ | 'create_asset_manifest'
38
+ | 'inspect_asset'
39
+ | 'label_asset'
40
+ | 'map_assets_for_model'
41
+ | 'validate_asset_references';
19
42
 
20
43
  export interface CreativeWorkflowArtifact {
21
44
  id?: string;
@@ -42,7 +65,6 @@ export interface CreativeWorkflowEvent {
42
65
 
43
66
  export interface CreativeWorkflowRecord {
44
67
  workflowId: string;
45
- kind?: CreativeWorkflowKind;
46
68
  title?: string;
47
69
  status?: CreativeWorkflowStatus;
48
70
  input?: Record<string, unknown>;
@@ -60,56 +82,62 @@ export interface CreativeWorkflowRecord {
60
82
  [key: string]: unknown;
61
83
  }
62
84
 
63
- export interface StartImageToVideoWorkflowInput {
64
- prompt: string;
65
- videoPrompt?: string;
66
- negativePrompt?: string;
67
- width?: number;
68
- height?: number;
69
- duration?: number;
70
- imageModel?: string;
71
- videoModel?: string;
72
- numberOfMedia?: number;
73
- seed?: number;
74
- [key: string]: unknown;
75
- }
76
-
77
- export interface StartHostedToolSequenceWorkflowDependency {
85
+ export interface StartCreativeWorkflowDependency {
78
86
  sourceStepId: string;
79
87
  targetArgument: string;
80
- transform: 'artifact_url' | 'artifact_data_uri';
88
+ transform:
89
+ | 'artifact_url'
90
+ | 'artifact_data_uri'
91
+ | 'image_url'
92
+ | 'video_url'
93
+ | 'audio_url'
94
+ | 'image_index'
95
+ | 'video_index'
96
+ | 'audio_index'
97
+ | 'subtitle_cues'
98
+ | 'subtitle_srt'
99
+ | 'overlay_items'
100
+ | 'asset_ref';
81
101
  sourceArtifactId?: string;
82
102
  sourceArtifactIndex?: number;
83
103
  mediaType?: 'image' | 'video' | 'audio';
84
104
  required?: boolean;
85
105
  }
86
106
 
87
- export interface StartHostedToolSequenceWorkflowStep {
107
+ export interface StartCreativeWorkflowStep {
88
108
  id?: string;
89
109
  toolName: CreativeWorkflowHostedToolName;
90
110
  arguments: Record<string, unknown>;
91
- dependsOn?: StartHostedToolSequenceWorkflowDependency[];
111
+ dependsOn?: StartCreativeWorkflowDependency[];
92
112
  }
93
113
 
94
- export interface StartHostedToolSequenceWorkflowInput {
114
+ export interface StartCreativeWorkflowInput {
95
115
  title?: string;
96
- steps: StartHostedToolSequenceWorkflowStep[];
97
- [key: string]: unknown;
116
+ steps: StartCreativeWorkflowStep[];
98
117
  }
99
118
 
100
- export type StartCreativeWorkflowParams =
101
- | {
102
- kind: 'image_to_video';
103
- input: StartImageToVideoWorkflowInput;
104
- tokenType?: TokenType;
105
- token_type?: TokenType;
106
- }
107
- | {
108
- kind: 'hosted_tool_sequence';
109
- input: StartHostedToolSequenceWorkflowInput;
110
- tokenType?: TokenType;
111
- token_type?: TokenType;
112
- };
119
+ export interface StartCreativeWorkflowParams {
120
+ input: StartCreativeWorkflowInput;
121
+ tokenType?: TokenType;
122
+ appSource?: string;
123
+ idempotencyKey?: string;
124
+ /** Durable workflows require uploaded HTTP(S) URLs, not inline data URIs. */
125
+ mediaReferences?: unknown[];
126
+ maxEstimatedCapacityUnits?: number;
127
+ confirmCost?: boolean;
128
+ /** @internal Undocumented compatibility alias. Use tokenType. */
129
+ token_type?: TokenType;
130
+ /** @internal Undocumented compatibility alias. Use appSource. */
131
+ app_source?: string;
132
+ /** @internal Undocumented compatibility alias. Use idempotencyKey. */
133
+ idempotency_key?: string;
134
+ /** @internal Undocumented compatibility alias. Use mediaReferences. */
135
+ media_references?: unknown[];
136
+ /** @internal Undocumented compatibility alias. Use maxEstimatedCapacityUnits. */
137
+ max_estimated_capacity_units?: number;
138
+ /** @internal Undocumented compatibility alias. Use confirmCost. */
139
+ confirm_cost?: boolean;
140
+ }
113
141
 
114
142
  export interface StartCreativeWorkflowOptions {
115
143
  signal?: AbortSignal;