@sogni-ai/sogni-client 5.1.0 → 5.3.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.
Files changed (118) hide show
  1. package/AGENTS.md +2 -1
  2. package/CHANGELOG.md +26 -0
  3. package/README.md +63 -1
  4. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.d.ts +3 -1
  5. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +14 -2
  6. package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -1
  7. package/dist/ApiClient/WebSocketClient/events.d.ts +11 -0
  8. package/dist/ApiClient/WebSocketClient/index.d.ts +3 -1
  9. package/dist/ApiClient/WebSocketClient/index.js +4 -1
  10. package/dist/ApiClient/WebSocketClient/index.js.map +1 -1
  11. package/dist/ApiClient/index.d.ts +10 -1
  12. package/dist/ApiClient/index.js +16 -3
  13. package/dist/ApiClient/index.js.map +1 -1
  14. package/dist/ApiGroup.d.ts +3 -0
  15. package/dist/ApiGroup.js +13 -0
  16. package/dist/ApiGroup.js.map +1 -1
  17. package/dist/Chat/ChatTools.js +2 -1
  18. package/dist/Chat/ChatTools.js.map +1 -1
  19. package/dist/Chat/index.d.ts +9 -1
  20. package/dist/Chat/index.js +46 -6
  21. package/dist/Chat/index.js.map +1 -1
  22. package/dist/Chat/modelRouting.d.ts +2 -0
  23. package/dist/Chat/modelRouting.js +6 -2
  24. package/dist/Chat/modelRouting.js.map +1 -1
  25. package/dist/Chat/types.d.ts +50 -1
  26. package/dist/CreativeWorkflows/index.js +4 -5
  27. package/dist/CreativeWorkflows/index.js.map +1 -1
  28. package/dist/CreativeWorkflows/types.d.ts +7 -0
  29. package/dist/Projects/createJobRequestMessage.js +4 -1
  30. package/dist/Projects/createJobRequestMessage.js.map +1 -1
  31. package/dist/Projects/index.js +4 -3
  32. package/dist/Projects/index.js.map +1 -1
  33. package/dist/Projects/types/ModelOptions.d.ts +1 -0
  34. package/dist/Projects/types/ModelOptions.js +2 -1
  35. package/dist/Projects/types/ModelOptions.js.map +1 -1
  36. package/dist/Projects/types/ModelTiersRaw.d.ts +1 -0
  37. package/dist/Projects/types/ModelTiersRaw.js.map +1 -1
  38. package/dist/Projects/types/events.d.ts +3 -0
  39. package/dist/Projects/types/index.d.ts +35 -9
  40. package/dist/Projects/types/index.js.map +1 -1
  41. package/dist/index.d.ts +11 -3
  42. package/dist/index.js +1 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/lib/RestClient.d.ts +3 -2
  45. package/dist/lib/RestClient.js +2 -3
  46. package/dist/lib/RestClient.js.map +1 -1
  47. package/dist/lib/attribution.d.ts +24 -0
  48. package/dist/lib/attribution.js +264 -0
  49. package/dist/lib/attribution.js.map +1 -0
  50. package/dist/lib/validation.d.ts +6 -0
  51. package/dist/lib/validation.js +40 -7
  52. package/dist/lib/validation.js.map +1 -1
  53. package/dist/types/attribution.d.ts +67 -0
  54. package/dist/types/attribution.js +3 -0
  55. package/dist/types/attribution.js.map +1 -0
  56. package/dist/version.d.ts +1 -1
  57. package/dist/version.js +1 -1
  58. package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +14 -2
  59. package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -1
  60. package/dist-esm/ApiClient/WebSocketClient/index.js +4 -1
  61. package/dist-esm/ApiClient/WebSocketClient/index.js.map +1 -1
  62. package/dist-esm/ApiClient/index.js +16 -3
  63. package/dist-esm/ApiClient/index.js.map +1 -1
  64. package/dist-esm/ApiGroup.js +13 -0
  65. package/dist-esm/ApiGroup.js.map +1 -1
  66. package/dist-esm/Chat/ChatTools.js +2 -1
  67. package/dist-esm/Chat/ChatTools.js.map +1 -1
  68. package/dist-esm/Chat/index.js +46 -6
  69. package/dist-esm/Chat/index.js.map +1 -1
  70. package/dist-esm/Chat/modelRouting.js +6 -2
  71. package/dist-esm/Chat/modelRouting.js.map +1 -1
  72. package/dist-esm/CreativeWorkflows/index.js +4 -5
  73. package/dist-esm/CreativeWorkflows/index.js.map +1 -1
  74. package/dist-esm/Projects/createJobRequestMessage.js +5 -2
  75. package/dist-esm/Projects/createJobRequestMessage.js.map +1 -1
  76. package/dist-esm/Projects/index.js +4 -3
  77. package/dist-esm/Projects/index.js.map +1 -1
  78. package/dist-esm/Projects/types/ModelOptions.js +2 -1
  79. package/dist-esm/Projects/types/ModelOptions.js.map +1 -1
  80. package/dist-esm/Projects/types/ModelTiersRaw.js.map +1 -1
  81. package/dist-esm/Projects/types/index.js.map +1 -1
  82. package/dist-esm/index.js +1 -0
  83. package/dist-esm/index.js.map +1 -1
  84. package/dist-esm/lib/RestClient.js +2 -3
  85. package/dist-esm/lib/RestClient.js.map +1 -1
  86. package/dist-esm/lib/attribution.js +257 -0
  87. package/dist-esm/lib/attribution.js.map +1 -0
  88. package/dist-esm/lib/validation.js +39 -7
  89. package/dist-esm/lib/validation.js.map +1 -1
  90. package/dist-esm/types/attribution.js +2 -0
  91. package/dist-esm/types/attribution.js.map +1 -0
  92. package/dist-esm/version.js +1 -1
  93. package/llms-full.txt +45 -4
  94. package/llms.txt +14 -2
  95. package/package.json +2 -1
  96. package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/index.ts +16 -2
  97. package/src/ApiClient/WebSocketClient/events.ts +12 -0
  98. package/src/ApiClient/WebSocketClient/index.ts +10 -1
  99. package/src/ApiClient/index.ts +42 -2
  100. package/src/ApiGroup.ts +25 -0
  101. package/src/Chat/ChatTools.ts +5 -1
  102. package/src/Chat/index.ts +73 -6
  103. package/src/Chat/modelRouting.ts +15 -2
  104. package/src/Chat/types.ts +59 -1
  105. package/src/CreativeWorkflows/index.ts +11 -3
  106. package/src/CreativeWorkflows/types.ts +7 -0
  107. package/src/Projects/createJobRequestMessage.ts +7 -2
  108. package/src/Projects/index.ts +5 -3
  109. package/src/Projects/types/ModelOptions.ts +3 -1
  110. package/src/Projects/types/ModelTiersRaw.ts +1 -0
  111. package/src/Projects/types/events.ts +4 -0
  112. package/src/Projects/types/index.ts +35 -9
  113. package/src/index.ts +43 -2
  114. package/src/lib/RestClient.ts +10 -3
  115. package/src/lib/attribution.ts +304 -0
  116. package/src/lib/validation.ts +44 -7
  117. package/src/types/attribution.ts +89 -0
  118. package/src/version.ts +1 -1
@@ -9,19 +9,27 @@ const EXTENDED_IMAGE_SIZE_MODEL_IDS = new Set([
9
9
  'qwen_image_2512_fp8_lightning',
10
10
  'flux2_dev_fp8'
11
11
  ]);
12
- function getMaxCustomImageSize(modelId) {
12
+ const KREA_IDENTITY_EDIT_MODEL_IDS = new Set([
13
+ 'krea2_identity_edit_v1_2',
14
+ 'dark_beast_krea2_identity_edit_v1_2'
15
+ ]);
16
+ function getCustomImageSizeBounds(modelId) {
17
+ if (modelId && KREA_IDENTITY_EDIT_MODEL_IDS.has(modelId)) {
18
+ return { min: 512, max: 2048 };
19
+ }
13
20
  if (modelId === 'gpt-image-2') {
14
- return 3840;
21
+ return { min: 256, max: 3840 };
15
22
  }
16
23
  if (modelId && EXTENDED_IMAGE_SIZE_MODEL_IDS.has(modelId)) {
17
- return 2560;
24
+ return { min: 256, max: 2560 };
18
25
  }
19
- return 2048;
26
+ return { min: 256, max: 2048 };
20
27
  }
21
28
  export function validateCustomImageSize(value, { modelId, propertyName = 'Width and height' } = {}) {
29
+ const bounds = getCustomImageSizeBounds(modelId);
22
30
  return validateNumber(value, {
23
- min: 256,
24
- max: getMaxCustomImageSize(modelId),
31
+ min: bounds.min,
32
+ max: bounds.max,
25
33
  propertyName
26
34
  });
27
35
  }
@@ -79,7 +87,16 @@ export function validateTeacacheThreshold(value) {
79
87
  return num;
80
88
  }
81
89
  export function isComfyModel(modelId) {
82
- const COMFY_PREFIXES = ['z_image_', 'krea2_', 'qwen_image_', 'flux2_', 'wan_', 'ace_step'];
90
+ const COMFY_PREFIXES = [
91
+ 'z_image_',
92
+ 'dark_beast_z_image_',
93
+ 'krea2_',
94
+ 'dark_beast_krea2_',
95
+ 'qwen_image_',
96
+ 'flux2_',
97
+ 'wan_',
98
+ 'ace_step'
99
+ ];
83
100
  return COMFY_PREFIXES.some((prefix) => modelId.startsWith(prefix));
84
101
  }
85
102
  /**
@@ -87,6 +104,7 @@ export function isComfyModel(modelId) {
87
104
  * - GPT Image 2: 16 images
88
105
  * - Flux.2 Dev: 6 images
89
106
  * - Qwen Image Edit: 3 images
107
+ * - Krea 2 Identity Edit: 2 images
90
108
  * - Flux Kontext: 2 images
91
109
  * - Default: 3 images
92
110
  */
@@ -100,6 +118,9 @@ export function getMaxContextImages(modelId) {
100
118
  if (modelId.startsWith('qwen_image_')) {
101
119
  return 3;
102
120
  }
121
+ if (KREA_IDENTITY_EDIT_MODEL_IDS.has(modelId)) {
122
+ return 2;
123
+ }
103
124
  if (modelId.includes('kontext')) {
104
125
  return 2;
105
126
  }
@@ -136,4 +157,15 @@ export function validateScheduler(value, options) {
136
157
  }
137
158
  return validateOption(value, options.scheduler.allowed, `Invalid scheduler ${value}. Must be one of "${options.scheduler.allowed.join('", "')}".`);
138
159
  }
160
+ /**
161
+ * Validate a model-specific VAE value against allowed options.
162
+ * Returns the validated value unchanged; sogni-socket passes the filename to ComfyUI.
163
+ */
164
+ export function validateVae(value, options) {
165
+ var _a;
166
+ if (!('vae' in options) || !((_a = options.vae) === null || _a === void 0 ? void 0 : _a.allowed.length) || !value) {
167
+ return null;
168
+ }
169
+ return validateOption(value, options.vae.allowed, `Invalid VAE ${value}. Must be one of "${options.vae.allowed.join('", "')}".`);
170
+ }
139
171
  //# sourceMappingURL=validation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=attribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attribution.js","sourceRoot":"","sources":["../../src/types/attribution.ts"],"names":[],"mappings":""}
@@ -1,4 +1,4 @@
1
1
  // AUTO-GENERATED by scripts/generate-version.mjs — do not edit.
2
2
  // Source of truth: package.json version.
3
- export const LIB_VERSION = '5.1.0';
3
+ export const LIB_VERSION = '5.3.0';
4
4
  //# sourceMappingURL=version.js.map
package/llms-full.txt CHANGED
@@ -254,6 +254,33 @@ const portal = await sogni.account.createSubscriptionPortalSession();
254
254
 
255
255
  `checkAuth()` is only for cookie-auth browser flows on permitted Sogni domains. API-key auth auto-authenticates during `createInstance()`. Username/password auth uses `sogni.account.login()`. Token auth can be resumed with `sogni.setTokens()`.
256
256
 
257
+ AGENT ATTRIBUTION:
258
+
259
+ Keep `appSource` as the stable product/integration identifier. Agent wrappers may add immutable `attribution.connection` and `attribution.workload` defaults:
260
+
261
+ ```typescript
262
+ const sogni = await SogniClient.createInstance({
263
+ appId: 'my-agent',
264
+ appSource: 'my-agent-integration',
265
+ apiKey: process.env.SOGNI_API_KEY,
266
+ attribution: {
267
+ connection: {
268
+ interactionKind: 'external_agent',
269
+ agentFramework: 'codex',
270
+ agentSurface: 'plugin'
271
+ },
272
+ workload: {
273
+ workloadKind: 'agent_mediated',
274
+ agentFramework: 'codex',
275
+ agentSurface: 'plugin',
276
+ executionMode: 'server'
277
+ }
278
+ }
279
+ });
280
+ ```
281
+
282
+ Project, socket chat, hosted chat/tool, durable chat run, and creative workflow calls accept an optional per-operation `attribution` override. Standalone attributed requests default to `operationScope: 'top_level'` and use the underlying project/job request ID. For child work, pass `operationScope: 'child'`, a stable `rootOperationId`, and the immediate `parentOperationId`; omit `operationId` to use the request's generated ID. The exported attribution types include `native_desktop`. Invalid metadata is dropped, the server remains authoritative, and all new wire fields are omitted when attribution is not configured.
283
+
257
284
  NETWORK TYPES:
258
285
 
259
286
  - 'fast': High-end GPU workers. Faster, higher cost. REQUIRED for video.
@@ -407,6 +434,7 @@ RECOMMENDED MODELS:
407
434
  | z_image_turbo_bf16 | Ultra-fast | 8 | 1 | Fastest generation |
408
435
  | z_image_bf16 | Quality | 20 | 3 | High quality Z-Image generation |
409
436
  | krea2_turbo_fp8_scaled | Fast | 8 | 1 | Distilled few-step, strong in-image text, up to 2K |
437
+ | krea2_identity_edit_v1_2 | Edit | 10 | 1 | Identity-preserving Krea 2 edit LoRA with 1-2 context images |
410
438
  | chroma1-hd_fp8_scaled | Quality | 26 | 3.8 | Final high-res Chroma (uncensored, LoRA-capable) |
411
439
  | flux2_dev_fp8 | Quality | 20 | 4 | Pro quality + up to 6 context images (also image edit) |
412
440
  | qwen_image_edit_2511_fp8_lightning | Edit | 4 | 1 | Multi-image context |
@@ -417,6 +445,7 @@ COMMUNITY FINE-TUNES (uncensored; discover with sogni.projects.getAvailableModel
417
445
  |----------|------|-------|----------|-------|
418
446
  | dark_beast_z_image_turbo_v9_bf16 | Ultra-fast | 8 | 1 | Community Z-Image Turbo fine-tune (2K needs 24GB VRAM) |
419
447
  | dark_beast_krea2_fp8 | Fast | 16 | 1 | Community Krea 2 fine-tune (2K needs 24GB VRAM) |
448
+ | dark_beast_krea2_identity_edit_v1_2 | Edit | 10 | 1 | Community Krea 2 identity edit LoRA with 1-2 context images |
420
449
  | one_obsession_v22_fp16 | Quality | 28 | 6 | Community Illustrious/anime checkpoint, LoRA-capable |
421
450
 
422
451
  ================================================================================ 5. VIDEO GENERATION - WAN 2.2 MODELS
@@ -880,9 +909,10 @@ sv (Swedish), ro (Romanian), el (Greek), and more. Use 'unknown' for auto-detect
880
909
  ================================================================================
881
910
 
882
911
  The Sogni SDK supports LLM text generation through the Supernet with
883
- socket-native chat completions, hosted REST chat completions, durable hosted
884
- chat runs, streaming, multi-turn conversations, thinking/reasoning controls,
885
- structured outputs, and tool calling.
912
+ socket-native chat completions, hosted REST chat completions, direct hosted
913
+ synchronous tool execution, durable hosted chat runs, streaming, multi-turn
914
+ conversations, thinking/reasoning controls, structured outputs, and tool
915
+ calling.
886
916
 
887
917
  DEFAULT LLM MODEL: qwen3.6-35b-a3b-gguf-iq4xs
888
918
 
@@ -892,6 +922,9 @@ PRIMARY CHAT SURFACES:
892
922
  `ChatCompletionResult` for `stream: false` and `ChatStream` for `stream: true`.
893
923
  - `sogni.chat.hosted.create(params)` - hosted REST chat completion at
894
924
  `/v1/chat/completions`; can execute hosted Sogni tools server-side.
925
+ - `sogni.chat.hosted.executeTool(params)` - direct synchronous hosted
926
+ composition/planning tool execution at `/v1/creative-agent/tools/execute`;
927
+ use when the caller already has the exact tool and JSON arguments.
895
928
  - `sogni.chat.runs.{create,get,cancel,streamEvents}` - durable hosted runs at
896
929
  `/v1/chat/runs`; the server owns the LLM/tool loop and clients can reconnect
897
930
  through SSE event replay.
@@ -1190,7 +1223,7 @@ Sogni's generation APIs automatically:
1190
1223
  - Music Generation: "Compose a jazz song about the rain"
1191
1224
 
1192
1225
  CANONICAL HOSTED CREATIVE-TOOL SURFACE (`SogniTools.all`, 24 tools):
1193
- The full hosted surface executes server-side via `sogni.chat.hosted.create()` / `sogni.chat.runs.create()`. The default `creative-tools` value of `sogni_tools` injects this surface server-side; `sogni_tools: "creative-agent"` adds workflow control and asset-manifest tools on top. The client-side `sogni.chat.tools.execute()` path directly dispatches only the core generation tools (`generate_image`, `edit_image`, `generate_video`, `sound_to_video`, `video_to_video`, `generate_music`); composition and post-production tools should be routed through hosted chat or durable runs.
1226
+ The full hosted surface executes server-side via `sogni.chat.hosted.create()` / `sogni.chat.runs.create()`. The default `creative-tools` value of `sogni_tools` injects this surface server-side; `sogni_tools: "creative-agent"` adds workflow control and asset-manifest tools on top. The client-side `sogni.chat.tools.execute()` path directly dispatches only the core generation tools (`generate_image`, `edit_image`, `generate_video`, `sound_to_video`, `video_to_video`, `generate_music`). Known synchronous composition/planning calls can use `sogni.chat.hosted.executeTool()`; post-production tools should be routed through hosted chat, durable runs, or explicit workflows.
1194
1227
 
1195
1228
  - `generate_image`, `edit_image`, `generate_video`, `generate_music`, `sound_to_video`, `video_to_video` — core media-generation tools with creative-agent naming.
1196
1229
  - `restore_photo`, `apply_style`, `refine_result`, `change_angle` — image-edit adapters backed by the shared image-edit workflow.
@@ -1207,6 +1240,9 @@ The full hosted surface executes server-side via `sogni.chat.hosted.create()` /
1207
1240
  - `compose_lyrics`, `compose_instrumental` — vocal lyrics or instrumental music structures.
1208
1241
  - `compose_workflow`, `compose_workflow_template` — durable workflow and workflow-template planners.
1209
1242
 
1243
+ DIRECT SYNCHRONOUS HOSTED TOOL EXECUTION:
1244
+ When the caller already knows the exact synchronous composition/planning tool and JSON arguments, use `sogni.chat.hosted.executeTool()` instead of forcing a `/v1/chat/completions` tool-choice round. Direct execution supports `enhance_prompt`, `compose_script`, `compose_lyrics`, `compose_instrumental`, `compose_workflow`, and `compose_workflow_template`; long-running media tools still use hosted chat/runs or `sogni.workflows`.
1245
+
1210
1246
  PER-REQUEST MEDIA CONTEXT:
1211
1247
  Generated images, videos, and audio are addressable by stable indices across tool rounds. Every hosted Sogni tool result returns `startIndex` and `indices` in its envelope so a later tool can target the result with `sourceImageIndex`, `videoIndices`, `audioIndex`, etc., without the model having to copy URLs back into prompt text.
1212
1248
 
@@ -1243,6 +1279,8 @@ PLATFORM TOOL WORKFLOW:
1243
1279
  See `workflow_text_chat_sogni_tools.mjs` for a composition-pipeline example
1244
1280
  covering the core image/video/music flows. See `workflow_creative_agent_tools.mjs`
1245
1281
  for server-side hosted Sogni tool injection with `sogni_tools`.
1282
+ See `workflow_direct_creative_tool.mjs` for known synchronous tool calls through
1283
+ `sogni.chat.hosted.executeTool()`.
1246
1284
  Pass `SogniTools.all` (or individual tool defs) to the LLM via `tools` and
1247
1285
  execute calls through `sogni.chat.hosted.create()` / `sogni.chat.runs.create()`.
1248
1286
 
@@ -1275,6 +1313,9 @@ node workflow_text_chat_sogni_tools.mjs -n 4 "Create images of fantasy landscape
1275
1313
  # Server-side hosted creative tools
1276
1314
  node workflow_creative_agent_tools.mjs "Create an orbit video plan for a crystal perfume bottle"
1277
1315
 
1316
+ # Direct synchronous hosted tool execution
1317
+ node workflow_direct_creative_tool.mjs --tool compose_workflow "Plan a 3-shot neon bakery teaser"
1318
+
1278
1319
  # Durable creative-agent workflow
1279
1320
  node workflow_creative_agent_workflows.mjs "A chrome monorail over neon gardens" --watch
1280
1321
 
package/llms.txt CHANGED
@@ -140,6 +140,10 @@ const portal = await sogni.account.createSubscriptionPortalSession();
140
140
 
141
141
  Checkout and portal sessions require user authentication; API-key auth is rejected for those redirect operations.
142
142
 
143
+ AGENT ATTRIBUTION:
144
+
145
+ Keep `appSource` as the stable product/integration ID. Agent wrappers may additionally set immutable `attribution.connection` and `attribution.workload` defaults on `createInstance()`, then override `attribution` per project, socket/hosted/durable chat request, hosted tool, or creative workflow. Exported unions cover `interactionKind`, `workloadKind`, `agentSurface` (including `native_desktop`), `executionMode`, and operation lineage. Standalone attributed calls receive a top-level operation ID from the underlying job/request; child calls should provide `operationScope: 'child'`, `rootOperationId`, and `parentOperationId`. All fields are optional and omitted for legacy callers.
146
+
143
147
  ### Network Types
144
148
 
145
149
  - `fast` - High-end GPUs, faster, more expensive. **Required for video.**
@@ -205,22 +209,28 @@ The full catalog is dynamic — enumerate it at runtime with
205
209
  | `z_image_turbo_bf16` | Z-Image Turbo — ultra-fast 8-step (free-tier eligible) |
206
210
  | `z_image_bf16` | Z-Image — high quality 20-50 step |
207
211
  | `krea2_turbo_fp8_scaled` | Krea 2 Turbo — few-step, strong in-image text, up to 2K |
212
+ | `krea2_identity_edit_v1_2` | Krea 2 Identity Edit LoRA v1.2 — identity-preserving edits with 1-2 reference images |
208
213
  | `chroma-v.46-flash_fp8` | Chroma v.46 Flash — fast, high quality |
209
214
  | `chroma-v48-detail-svd_fp8` | Chroma v.48 Detail — high detail |
210
215
  | `chroma1-hd_fp8_scaled` | Chroma1-HD — final high-res Chroma (uncensored, LoRA-capable) |
211
216
  | `flux1-schnell-fp8` | Flux.1 [schnell] — 1-5 step |
212
217
  | `flux1-krea-dev_fp8_scaled` | Flux.1 Krea [dev] — creative detail |
213
218
  | `flux2_dev_fp8` | Flux.2 [dev] — pro quality + context images (also image edit) |
219
+ | `dark_beast_krea2_identity_edit_v1_2` | Dark Beast Krea 2 Identity Edit — community identity edit LoRA with 1-2 reference images |
214
220
  | `qwen_image_2512_fp8` / `_lightning` | Qwen Image 2512 — text rendering |
215
221
  | `gpt-image-2` | GPT Image 2 — OpenAI partner (premium, Spark-only) |
216
222
 
217
223
  Community fine-tunes (uncensored; pass the id directly):
218
224
  `dark_beast_z_image_turbo_v9_bf16` (fast Z-Image fine-tune, 2K needs 24GB VRAM),
219
225
  `dark_beast_krea2_fp8` (Krea 2 fine-tune, 2K needs 24GB VRAM),
226
+ `dark_beast_krea2_identity_edit_v1_2` (Krea 2 identity edit LoRA),
220
227
  `one_obsession_v22_fp16` (Illustrious/anime, LoRA-capable).
221
228
 
222
229
  Krea 2 Turbo supports the `krea2-filter-bypass-3` style LoRA via
223
230
  `loras: ['krea2-filter-bypass-3']` + `loraStrengths: [1.0]`.
231
+ For identity-preserving edits, use `krea2_identity_edit_v1_2` or
232
+ `dark_beast_krea2_identity_edit_v1_2` with 1-2 `contextImages`, `steps: 10`,
233
+ and `guidance: 1`.
224
234
 
225
235
  ---
226
236
 
@@ -448,7 +458,7 @@ const project = await sogni.projects.create({
448
458
 
449
459
  ## 7. LLM Text Generation
450
460
 
451
- The Sogni SDK supports LLM text generation via the Supernet. Socket-native chat uses `sogni.chat.completions.create()`. Hosted REST chat uses `sogni.chat.hosted.create()`. Durable server-side chat runs use `sogni.chat.runs`.
461
+ The Sogni SDK supports LLM text generation via the Supernet. Socket-native chat uses `sogni.chat.completions.create()`. Hosted REST chat uses `sogni.chat.hosted.create()`. Direct synchronous hosted tool execution uses `sogni.chat.hosted.executeTool()`. Durable server-side chat runs use `sogni.chat.runs`.
452
462
 
453
463
  ### Chat Completion (Non-Streaming)
454
464
 
@@ -570,9 +580,11 @@ Canonical hosted creative-tool surface (`SogniTools.all`, 24 tools, executed ser
570
580
 
571
581
  The default `creative-tools` surface includes the tools above. `sogni_tools: "creative-agent"` adds workflow control and asset-manifest tools. Per-request media context lets generated images / videos / audio be addressed by stable indices across tool rounds (each tool result envelope returns `startIndex` and `indices`).
572
582
 
583
+ When the caller already knows the exact synchronous composition/planning tool and JSON arguments, use `sogni.chat.hosted.executeTool()` instead of forcing a `/v1/chat/completions` tool-choice round. Direct execution supports `enhance_prompt`, `compose_script`, `compose_lyrics`, `compose_instrumental`, `compose_workflow`, and `compose_workflow_template`; long-running media tools still use hosted chat/runs or `sogni.workflows`.
584
+
573
585
  Media-conditioned tools accept explicit inline base64 `data:` URIs such as `source_image_url`, `reference_image_url`, `reference_audio_url`, and `reference_video_url`. Tool image inputs accept PNG/JPEG, tool audio inputs accept MP3/M4A/WAV, and tool video inputs accept MP4 or MOV/QuickTime. For uploaded or Sogni-hosted HTTP(S) assets, pass media through request-level `mediaReferences` / `mediaContext` or through `sogni.workflows` dependencies.
574
586
 
575
- The `workflow_text_chat_sogni_tools.mjs` example demonstrates the core image/video/music composition flows. `workflow_creative_agent_tools.mjs` demonstrates server-side hosted Sogni tool injection through `/v1/chat/completions`. Pass `SogniTools.all` (or individual tool defs) to the LLM and execute calls through `sogni.chat.hosted.create()` / `sogni.chat.runs.create()`.
587
+ The `workflow_text_chat_sogni_tools.mjs` example demonstrates the core image/video/music composition flows. `workflow_creative_agent_tools.mjs` demonstrates server-side hosted Sogni tool injection through `/v1/chat/completions`. `workflow_direct_creative_tool.mjs` demonstrates `sogni.chat.hosted.executeTool()` for known synchronous tool calls. Pass `SogniTools.all` (or individual tool defs) to the LLM and execute calls through `sogni.chat.hosted.create()` / `sogni.chat.runs.create()`.
576
588
 
577
589
  Durable creative workflows: the SDK exposes persistent multi-step workflows through `sogni.workflows` (`start`, `list`, `get`, `events`, `streamEvents`, `resume`, `reseed`, `cancel`) backed by `/v1/creative-agent/workflows`. `start()` accepts either an inline `input` plan or a saved `workflowId` + `inputs`. Saved workflow templates are managed via `sogni.workflows.templates` (`list`, `get`, `create`, `update`, `delete`, `fork`). All endpoints use the SDK's active auth. See `workflow_creative_agent_workflows.mjs` for start/list/get/events/stream/cancel coverage.
578
590
 
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "5.1.0",
6
+ "version": "5.3.0",
7
7
  "engines": {
8
8
  "node": ">=22"
9
9
  },
@@ -61,6 +61,7 @@
61
61
  "prepublishOnly": "npm run build",
62
62
  "build": "npm run clean && npm run codegen && tsc --project tsconfig.json && tsc --project tsconfig.esm.json && node scripts/write-dist-esm-package-json.mjs",
63
63
  "test:chat-routing": "npm run build && node scripts/check-chat-model-routing.cjs",
64
+ "test:attribution": "npm run build && node scripts/check-attribution-transport.cjs",
64
65
  "test:subscription-api": "npm run build && node scripts/check-subscription-api.cjs",
65
66
  "test:workflow-template-envelope": "npm run build && node scripts/check-workflow-template-envelope.cjs",
66
67
  "watch": "npm run clean && npm run codegen && tsc --watch --project tsconfig.json",
@@ -14,6 +14,7 @@ import type {
14
14
  SocketEventSubscriptionInput,
15
15
  SocketEventSubscriptions
16
16
  } from '../eventSubscriptions.js';
17
+ import type { NormalizedConnectionAttribution } from '../../../lib/attribution.js';
17
18
 
18
19
  interface SocketSend<T extends MessageType = MessageType> {
19
20
  type: 'socket-send';
@@ -98,6 +99,9 @@ class BrowserWebSocketClient extends RestClient<SocketEventMap> implements IWebS
98
99
  // a long wait, since the server skips swarmModels for artists that have
99
100
  // active jobs. Cached and replayed like the balance snapshot.
100
101
  private _lastSwarmModels: SocketEventMap['swarmModels'] | null = null;
102
+ // Last swarmLLMModels the primary observed. ChatApi builds `models` from
103
+ // this live event, so replay it to late-joining tabs just like swarmModels.
104
+ private _lastSwarmLLMModels: SocketEventMap['swarmLLMModels'] | null = null;
101
105
  // Last subscription entitlement snapshot observed on the primary tab. Replayed
102
106
  // to late-joining secondaries so CurrentAccount reflects purchases made after
103
107
  // the shared socket originally connected.
@@ -111,7 +115,8 @@ class BrowserWebSocketClient extends RestClient<SocketEventMap> implements IWebS
111
115
  supernetType: SupernetType,
112
116
  logger: Logger,
113
117
  appSource?: string,
114
- socketEventSubscriptions?: SocketEventSubscriptions
118
+ socketEventSubscriptions?: SocketEventSubscriptions,
119
+ connectionAttribution?: NormalizedConnectionAttribution
115
120
  ) {
116
121
  const socketClient = new WrappedClient(
117
122
  baseUrl,
@@ -120,7 +125,8 @@ class BrowserWebSocketClient extends RestClient<SocketEventMap> implements IWebS
120
125
  supernetType,
121
126
  logger,
122
127
  appSource,
123
- socketEventSubscriptions
128
+ socketEventSubscriptions,
129
+ connectionAttribution
124
130
  );
125
131
  super(socketClient.baseUrl, auth, logger);
126
132
  this.socketClient = socketClient;
@@ -262,6 +268,12 @@ class BrowserWebSocketClient extends RestClient<SocketEventMap> implements IWebS
262
268
  payload: { type: 'swarmModels', data: this._lastSwarmModels }
263
269
  });
264
270
  }
271
+ if (this._lastSwarmLLMModels) {
272
+ this.coordinator.notify({
273
+ type: 'socket-event',
274
+ payload: { type: 'swarmLLMModels', data: this._lastSwarmLLMModels }
275
+ });
276
+ }
265
277
  if (this._lastSubscriptionEntitlement) {
266
278
  this.coordinator.notify({
267
279
  type: 'socket-event',
@@ -330,6 +342,8 @@ class BrowserWebSocketClient extends RestClient<SocketEventMap> implements IWebS
330
342
  this._lastBalanceUpdate = payload;
331
343
  } else if (eventType === 'swarmModels') {
332
344
  this._lastSwarmModels = payload;
345
+ } else if (eventType === 'swarmLLMModels') {
346
+ this._lastSwarmLLMModels = payload;
333
347
  } else if (eventType === 'subscriptionEntitlementUpdated') {
334
348
  this._lastSubscriptionEntitlement = payload;
335
349
  } else if (eventType === 'authenticated' && payload?.subscriptionEntitlement) {
@@ -117,6 +117,17 @@ export type JobETAData = {
117
117
  etaSeconds: number;
118
118
  };
119
119
 
120
+ export type JobPreparation = {
121
+ phase: 'downloadingAssets';
122
+ assetType: 'lora';
123
+ requested: number;
124
+ cached: number;
125
+ total: number;
126
+ completed: number;
127
+ current: number;
128
+ currentProgress?: number;
129
+ };
130
+
120
131
  export type JobResultData = {
121
132
  jobID: string;
122
133
  imgID: string;
@@ -145,6 +156,7 @@ export type JobStateData =
145
156
  positivePrompt?: string;
146
157
  negativePrompt?: string;
147
158
  jobIndex?: number;
159
+ preparation?: JobPreparation;
148
160
  }
149
161
  | {
150
162
  type: 'assigned';
@@ -16,6 +16,11 @@ import type {
16
16
  SocketEventSubscriptionInput,
17
17
  SocketEventSubscriptions
18
18
  } from './eventSubscriptions.js';
19
+ import {
20
+ appendConnectionAttributionQuery,
21
+ normalizeConnectionAttribution,
22
+ type NormalizedConnectionAttribution
23
+ } from '../../lib/attribution.js';
19
24
 
20
25
  const PROTOCOL_VERSION = '3.0.0';
21
26
 
@@ -24,6 +29,7 @@ const PING_INTERVAL = 15000;
24
29
  class WebSocketClient extends RestClient<SocketEventMap> implements IWebSocketClient {
25
30
  appId: string;
26
31
  appSource?: string;
32
+ connectionAttribution?: NormalizedConnectionAttribution;
27
33
  baseUrl: string;
28
34
  socketEventSubscriptions?: SocketEventSubscriptions;
29
35
  private socket: WebSocket | null = null;
@@ -37,7 +43,8 @@ class WebSocketClient extends RestClient<SocketEventMap> implements IWebSocketCl
37
43
  supernetType: SupernetType,
38
44
  logger: Logger,
39
45
  appSource?: string,
40
- socketEventSubscriptions?: SocketEventSubscriptions
46
+ socketEventSubscriptions?: SocketEventSubscriptions,
47
+ connectionAttribution?: NormalizedConnectionAttribution
41
48
  ) {
42
49
  const _baseUrl = new URL(baseUrl);
43
50
  switch (_baseUrl.protocol) {
@@ -55,6 +62,7 @@ class WebSocketClient extends RestClient<SocketEventMap> implements IWebSocketCl
55
62
  super(_baseUrl.toString(), auth, logger);
56
63
  this.appId = appId;
57
64
  this.appSource = appSource?.trim() || undefined;
65
+ this.connectionAttribution = normalizeConnectionAttribution(connectionAttribution);
58
66
  this.socketEventSubscriptions = socketEventSubscriptions;
59
67
  this.baseUrl = _baseUrl.toString();
60
68
  this._supernetType = supernetType;
@@ -87,6 +95,7 @@ class WebSocketClient extends RestClient<SocketEventMap> implements IWebSocketCl
87
95
  if (this.appSource) {
88
96
  url.searchParams.set('appSource', this.appSource);
89
97
  }
98
+ appendConnectionAttributionQuery(url, this.connectionAttribution);
90
99
  const socketEventSubscriptions = serializeSocketEventSubscriptions(
91
100
  this.socketEventSubscriptions
92
101
  );
@@ -16,6 +16,17 @@ import CookieAuthManager from '../lib/AuthManager/CookieAuthManager.js';
16
16
  import { AuthManager, TokenAuthManager } from '../lib/AuthManager/index.js';
17
17
  import isNodejs from '../lib/isNodejs.js';
18
18
  import BrowserWebSocketClient from './WebSocketClient/BrowserWebSocketClient/index.js';
19
+ import {
20
+ buildSogniAttributionHeaders,
21
+ normalizeConnectionAttribution,
22
+ resolveWorkloadAttribution,
23
+ type NormalizedConnectionAttribution
24
+ } from '../lib/attribution.js';
25
+ import type {
26
+ SogniAttributionConfig,
27
+ WorkloadAttributionDefaults,
28
+ WorkloadAttributionInput
29
+ } from '../types/attribution.js';
19
30
 
20
31
  const WS_RECONNECT_ATTEMPTS = 5;
21
32
 
@@ -46,6 +57,7 @@ export interface ApiClientOptions {
46
57
  socketUrl: string;
47
58
  appId: string;
48
59
  appSource?: string;
60
+ attribution?: SogniAttributionConfig;
49
61
  socketEventSubscriptions?: SocketEventSubscriptions;
50
62
  networkType: SupernetType;
51
63
  logger: Logger;
@@ -57,6 +69,10 @@ export interface ApiClientOptions {
57
69
  class ApiClient extends TypedEventEmitter<ApiClientEvents> {
58
70
  readonly appId: string;
59
71
  readonly appSource?: string;
72
+ readonly attribution: Readonly<{
73
+ connection?: Readonly<NormalizedConnectionAttribution>;
74
+ workload?: Readonly<WorkloadAttributionDefaults>;
75
+ }>;
60
76
  readonly logger: Logger;
61
77
  private _rest: RestClient;
62
78
  private _socket: IWebSocketClient;
@@ -69,6 +85,7 @@ class ApiClient extends TypedEventEmitter<ApiClientEvents> {
69
85
  socketUrl,
70
86
  appId,
71
87
  appSource,
88
+ attribution,
72
89
  socketEventSubscriptions,
73
90
  networkType,
74
91
  authType,
@@ -79,6 +96,11 @@ class ApiClient extends TypedEventEmitter<ApiClientEvents> {
79
96
  super();
80
97
  this.appId = appId;
81
98
  this.appSource = appSource?.trim() || undefined;
99
+ const connectionAttribution = normalizeConnectionAttribution(attribution?.connection);
100
+ this.attribution = Object.freeze({
101
+ ...(connectionAttribution ? { connection: Object.freeze(connectionAttribution) } : {}),
102
+ ...(attribution?.workload ? { workload: Object.freeze({ ...attribution.workload }) } : {})
103
+ });
82
104
  this.logger = logger;
83
105
  if (authType === 'apiKey') {
84
106
  this._auth = new ApiKeyAuthManager(logger);
@@ -98,7 +120,8 @@ class ApiClient extends TypedEventEmitter<ApiClientEvents> {
98
120
  networkType,
99
121
  logger,
100
122
  this.appSource,
101
- socketEventSubscriptions
123
+ socketEventSubscriptions,
124
+ this.attribution.connection
102
125
  );
103
126
  } else {
104
127
  this._socket = new WebSocketClient(
@@ -108,7 +131,8 @@ class ApiClient extends TypedEventEmitter<ApiClientEvents> {
108
131
  networkType,
109
132
  logger,
110
133
  this.appSource,
111
- socketEventSubscriptions
134
+ socketEventSubscriptions,
135
+ this.attribution.connection
112
136
  );
113
137
  }
114
138
  this._disableSocket = disableSocket;
@@ -137,6 +161,22 @@ class ApiClient extends TypedEventEmitter<ApiClientEvents> {
137
161
  return !this._disableSocket;
138
162
  }
139
163
 
164
+ resolveWorkloadAttribution(override?: WorkloadAttributionInput, fallbackOperationId?: string) {
165
+ return resolveWorkloadAttribution(this.attribution.workload, override, fallbackOperationId);
166
+ }
167
+
168
+ attributionHeaders(
169
+ appSource: string | undefined,
170
+ override?: WorkloadAttributionInput,
171
+ fallbackOperationId?: string
172
+ ): Record<string, string> {
173
+ return buildSogniAttributionHeaders({
174
+ appSource,
175
+ connection: this.attribution.connection,
176
+ workload: this.resolveWorkloadAttribution(override, fallbackOperationId)
177
+ });
178
+ }
179
+
140
180
  setSocketEventSubscriptions(update: SocketEventSubscriptionInput): Promise<void> {
141
181
  return this.socket.setSocketEventSubscriptions(update);
142
182
  }
package/src/ApiGroup.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import ApiClient from './ApiClient/index.js';
2
2
  import EIP712Helper from './lib/EIP712Helper.js';
3
3
  import TypedEventEmitter, { EventMap } from './lib/TypedEventEmitter.js';
4
+ import { buildSogniAttributionHeaders, resolveWorkloadAttribution } from './lib/attribution.js';
5
+ import type { WorkloadAttributionInput } from './types/attribution.js';
4
6
 
5
7
  export interface ApiConfig {
6
8
  client: ApiClient;
@@ -16,6 +18,29 @@ abstract class ApiGroup<E extends EventMap = {}> extends TypedEventEmitter<E> {
16
18
  this.client = config.client;
17
19
  this.eip712 = config.eip712;
18
20
  }
21
+
22
+ protected resolveWorkloadAttribution(
23
+ override?: WorkloadAttributionInput,
24
+ fallbackOperationId?: string
25
+ ) {
26
+ return resolveWorkloadAttribution(
27
+ this.client.attribution?.workload,
28
+ override,
29
+ fallbackOperationId
30
+ );
31
+ }
32
+
33
+ protected attributionHeaders(
34
+ appSource: string | undefined,
35
+ override?: WorkloadAttributionInput,
36
+ fallbackOperationId?: string
37
+ ): Record<string, string> {
38
+ return buildSogniAttributionHeaders({
39
+ appSource,
40
+ connection: this.client.attribution?.connection,
41
+ workload: this.resolveWorkloadAttribution(override, fallbackOperationId)
42
+ });
43
+ }
19
44
  }
20
45
 
21
46
  export default ApiGroup;
@@ -155,6 +155,7 @@ class ChatToolsApi {
155
155
  tokenType: options?.tokenType,
156
156
  network: options?.network,
157
157
  numberOfMedia: options?.numberOfMedia,
158
+ attribution: options?.attribution,
158
159
  timeout: options?.timeout,
159
160
  onProgress: options?.onToolProgress
160
161
  ? (progress: ToolExecutionProgress) => options.onToolProgress!(toolCall, progress)
@@ -213,7 +214,10 @@ class ChatToolsApi {
213
214
  ): Promise<ToolExecutionResult> {
214
215
  options?.onProgress?.({ status: 'creating', percent: 0 });
215
216
 
216
- const project = await this.projects.create(projectParams as any);
217
+ const project = await this.projects.create({
218
+ ...projectParams,
219
+ ...(options?.attribution ? { attribution: options.attribution } : {})
220
+ } as any);
217
221
  const timeout = options?.timeout ?? DEFAULT_TIMEOUT;
218
222
  let timeoutId: ReturnType<typeof setTimeout> | null = null;
219
223
  let jobsCompleted = 0;