democut 0.6.17 → 0.6.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 (2) hide show
  1. package/dist/cli.js +1525 -102
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -6916,7 +6916,7 @@ import { realpathSync } from "fs";
6916
6916
  import { fileURLToPath } from "url";
6917
6917
 
6918
6918
  // src/version.ts
6919
- var VERSION = "0.6.17";
6919
+ var VERSION = "0.6.23";
6920
6920
 
6921
6921
  // src/device-flow.ts
6922
6922
  var DeviceFlowError = class extends Error {
@@ -16164,7 +16164,7 @@ var GENERATED_TOOLS = [
16164
16164
  },
16165
16165
  {
16166
16166
  "name": "democut_estimate_cuts",
16167
- "description": "\uCEF7 N \uAC1C\uC758 \uACAC\uC801(0\uC6D0, \uBD80\uC791\uC6A9 \uC5C6\uC74C). \uC751\uB2F5\uC758 total_krw\xB7rate_version\xB7can_afford \uB97C \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBCF4\uC5EC \uC8FC\uACE0 \uADF8\uB300\uB85C democut_make_cuts \uC5D0 \uB123\uC5B4\uB77C. BYO \uD544\uB4DC(image_asset_id\xB7narration_asset_id\xB7tsx\xB7source.asset_id)\uB97C \uC8FC\uBA74 \uADF8 \uD589\uC740 0\uC6D0\uC774\uB2E4. \uB2E4\uC74C \uD638\uCD9C: democut_make_cuts.",
16167
+ "description": "\uCEF7 N \uAC1C\uC758 \uACAC\uC801(0\uC6D0, \uBD80\uC791\uC6A9 \uC5C6\uC74C). \uC751\uB2F5\uC758 total_krw\xB7rate_version\xB7can_afford \uB97C \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBCF4\uC5EC \uC8FC\uACE0 \uADF8\uB300\uB85C democut_make_cuts \uC5D0 \uB123\uC5B4\uB77C. BYO \uD544\uB4DC(image_asset_id\xB7narration_asset_id\xB7tsx\xB7source.asset_id)\uB97C \uC8FC\uBA74 \uADF8 \uD589\uC740 0\uC6D0\uC774\uB2E4. \u2605 \uC751\uB2F5 notes \uB97C **\uBC18\uB4DC\uC2DC \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC804\uD558\uB77C** \u2014 \uB9C9\uC9C0\uB294 \uC54A\uC9C0\uB9CC \uADF8\uB300\uB85C \uB9CC\uB4E4\uBA74 \uACB0\uACFC\uAC00 \uC758\uB3C4\uC640 \uB2E4\uB97C \uC218 \uC788\uB294 \uAC83\uB4E4\uC774\uB2E4. \uD2B9\uD788 ai_video \uC5D0 \uCC38\uC870 \uC774\uBBF8\uC9C0\uB97C \uC548 \uC8FC\uBA74 \uD14D\uC2A4\uD2B8\uB9CC\uC73C\uB85C \uB9CC\uB4E0\uB2E4(t2v): \uCCAB \uD504\uB808\uC784\uC744 \uC8FC\uBA74 \uD6E8\uC52C \uC548\uC815\uC801\uC774\uBBC0\uB85C \uC774\uBBF8\uC9C0\uB97C \uB9CC\uB4E4\uC5B4 \uC0AC\uC6A9\uC790 \uD655\uC778\uC744 \uBC1B\uC740 \uB4A4 democut_upload_asset \u2192 spec.image_asset_id \uB85C \uC8FC\uB294 \uD3B8\uC774 \uB0AB\uB2E4. \uB2E4\uC74C \uD638\uCD9C: democut_make_cuts.",
16168
16168
  "inputSchema": {
16169
16169
  "type": "object",
16170
16170
  "properties": {
@@ -16351,7 +16351,7 @@ var GENERATED_TOOLS = [
16351
16351
  }
16352
16352
  ],
16353
16353
  "default": null,
16354
- "description": "\uCCAB \uD504\uB808\uC784. \uC5C6\uC73C\uBA74 image_asset_id \u2192 \uCEF7 \uC774\uBBF8\uC9C0 \u2192 t2v \uC21C",
16354
+ "description": "\uCCAB \uD504\uB808\uC784. \uC5C6\uC73C\uBA74 image_asset_id \u2192 \uADF8\uAC83\uB3C4 \uC5C6\uC73C\uBA74 t2v(\uD14D\uC2A4\uD2B8\uB9CC) \u2014 \uACAC\uC801\uC774 notes \uB85C \uC54C\uB824\uC900\uB2E4",
16355
16355
  "title": "Image"
16356
16356
  },
16357
16357
  "end_image": {
@@ -16502,6 +16502,20 @@ var GENERATED_TOOLS = [
16502
16502
  }
16503
16503
  ],
16504
16504
  "title": "Spec"
16505
+ },
16506
+ "note": {
16507
+ "anyOf": [
16508
+ {
16509
+ "maxLength": 500,
16510
+ "type": "string"
16511
+ },
16512
+ {
16513
+ "type": "null"
16514
+ }
16515
+ ],
16516
+ "default": null,
16517
+ "description": "\uC774 \uCEF7\uC744 \uC65C \uB9CC\uB4DC\uB294\uC9C0 \u2014 \uB9CC\uB4E4 \uB54C \uADF8 \uBC84\uC804 \uD589\uC5D0 \uB0A8\uB294\uB2E4. \uACAC\uC801 \uB2E8\uACC4\uC5D0\uC11C\uB294 \uAE08\uC561\uC5D0 \uC601\uD5A5\uC774 \uC5C6\uACE0 \uC800\uC7A5\uB418\uC9C0\uB3C4 \uC54A\uB294\uB2E4(\uAC19\uC740 items \uB97C make_cuts \uC5D0 \uADF8\uB300\uB85C \uBCF4\uB0BC \uC218 \uC788\uAC8C \uBC1B\uB294\uB2E4)",
16518
+ "title": "Note"
16505
16519
  }
16506
16520
  },
16507
16521
  "required": [
@@ -17005,7 +17019,7 @@ var GENERATED_TOOLS = [
17005
17019
  },
17006
17020
  {
17007
17021
  "name": "democut_make_cuts",
17008
- "description": "\uCEF7 N \uAC1C\uB97C \uB9CC\uB4E0\uB2E4(\uCCAD\uAD6C \u2014 \uC81C\uCD9C \uC2DC \uC794\uC561\uC5D0\uC11C \uCC28\uAC10, \uC2E4\uD328 \uC2DC \uD658\uBD88). \uAE30\uBCF8 \uBC29\uC2DD\uC740 ai_video. items \uB294 all-or-nothing \uC774\uB2E4. \uB3C8\uC774 \uB098\uAC00\uB294 \uB3C4\uAD6C\uB2E4: estimate_cuts(\uB610\uB294 \uC9DD\uC774 \uB418\uB294 estimate \uB3C4\uAD6C)\uB85C \uAE08\uC561\uC744 \uBCF4\uACE0 \uC0AC\uC6A9\uC790 \uB3D9\uC758\uB97C \uBC1B\uC740 \uB4A4 confirmed_*_krw \uC640 rate_version \uC744 \uADF8\uB300\uB85C \uB123\uC5B4\uB77C. \uC5B4\uAE0B\uB098\uBA74 409 QUOTE_MISMATCH \uB85C \uC0C8 \uACAC\uC801\uC744 \uC900\uB2E4(\uACFC\uAE08 \uC5C6\uC74C). \uC2E4\uD328\uD574\uB3C4 \uC7AC\uC81C\uCD9C\uD558\uC9C0 \uB9C8\uB77C \u2014 \uAC19\uC740 spec \uC774 \uD65C\uC131\uC774\uBA74 \uC11C\uBC84\uAC00 \uAE30\uC874 \uC7A1\uC744 \uB3CC\uB824\uC900\uB2E4(deduplicated=true). \uC751\uB2F5\uC740 202 \u2014 \uACB0\uACFC\uB294 democut_wait_jobs \uB85C \uBC1B\uB294\uB2E4. \uB2E4\uC74C \uD638\uCD9C: democut_wait_jobs.",
17022
+ "description": "\uCEF7 N \uAC1C\uB97C \uB9CC\uB4E0\uB2E4(\uCCAD\uAD6C \u2014 \uC81C\uCD9C \uC2DC \uC794\uC561\uC5D0\uC11C \uCC28\uAC10, \uC2E4\uD328 \uC2DC \uD658\uBD88). \uAE30\uBCF8 \uBC29\uC2DD\uC740 ai_video. items \uB294 all-or-nothing \uC774\uB2E4. \u2605 democut_estimate_cuts \uC758 notes \uB97C \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC804\uD558\uACE0 \uB2F5\uC744 \uBC1B\uC740 \uB4A4\uC5D0 \uBD80\uB974\uB77C \u2014 \uD2B9\uD788 \uCC38\uC870 \uC774\uBBF8\uC9C0 \uC5C6\uB294 ai_video(t2v)\uB294 \uB9CC\uB4E0 \uB4A4 \uB9C8\uC74C\uC5D0 \uC548 \uB4E4\uC5B4\uB3C4 \uB2E4\uC2DC \uB9CC\uB4E4\uBA74 **\uC7AC\uACFC\uAE08**\uC774\uB2E4. \uB3C8\uC774 \uB098\uAC00\uB294 \uB3C4\uAD6C\uB2E4: estimate_cuts(\uB610\uB294 \uC9DD\uC774 \uB418\uB294 estimate \uB3C4\uAD6C)\uB85C \uAE08\uC561\uC744 \uBCF4\uACE0 \uC0AC\uC6A9\uC790 \uB3D9\uC758\uB97C \uBC1B\uC740 \uB4A4 confirmed_*_krw \uC640 rate_version \uC744 \uADF8\uB300\uB85C \uB123\uC5B4\uB77C. \uC5B4\uAE0B\uB098\uBA74 409 QUOTE_MISMATCH \uB85C \uC0C8 \uACAC\uC801\uC744 \uC900\uB2E4(\uACFC\uAE08 \uC5C6\uC74C). \uC2E4\uD328\uD574\uB3C4 \uC7AC\uC81C\uCD9C\uD558\uC9C0 \uB9C8\uB77C \u2014 \uAC19\uC740 spec \uC774 \uD65C\uC131\uC774\uBA74 \uC11C\uBC84\uAC00 \uAE30\uC874 \uC7A1\uC744 \uB3CC\uB824\uC900\uB2E4(deduplicated=true). \uC751\uB2F5\uC740 202 \u2014 \uACB0\uACFC\uB294 democut_wait_jobs \uB85C \uBC1B\uB294\uB2E4. \uB2E4\uC74C \uD638\uCD9C: democut_wait_jobs.",
17009
17023
  "inputSchema": {
17010
17024
  "type": "object",
17011
17025
  "properties": {
@@ -17200,7 +17214,7 @@ var GENERATED_TOOLS = [
17200
17214
  }
17201
17215
  ],
17202
17216
  "default": null,
17203
- "description": "\uCCAB \uD504\uB808\uC784. \uC5C6\uC73C\uBA74 image_asset_id \u2192 \uCEF7 \uC774\uBBF8\uC9C0 \u2192 t2v \uC21C",
17217
+ "description": "\uCCAB \uD504\uB808\uC784. \uC5C6\uC73C\uBA74 image_asset_id \u2192 \uADF8\uAC83\uB3C4 \uC5C6\uC73C\uBA74 t2v(\uD14D\uC2A4\uD2B8\uB9CC) \u2014 \uACAC\uC801\uC774 notes \uB85C \uC54C\uB824\uC900\uB2E4",
17204
17218
  "title": "Image"
17205
17219
  },
17206
17220
  "end_image": {
@@ -17424,6 +17438,7 @@ var GENERATED_TOOLS = [
17424
17438
  }
17425
17439
  ],
17426
17440
  "default": null,
17441
+ "description": "\uC774 \uCEF7\uC744 \uC65C \uB9CC\uB4DC\uB294\uC9C0 \u2014 \uB9CC\uB4E4\uC5B4\uC9C4 \uBC84\uC804 \uD589\uC5D0 \uB0A8\uB294\uB2E4(\uC0B0\uCD9C\uBB3C\xB7\uAE08\uC561\uC5D0\uB294 \uC601\uD5A5\uC774 \uC5C6\uB2E4)",
17427
17442
  "title": "Note"
17428
17443
  }
17429
17444
  },
@@ -17908,7 +17923,7 @@ var GENERATED_TOOLS = [
17908
17923
  },
17909
17924
  "timeout_s": {
17910
17925
  "default": 600,
17911
- "description": "0 = \uAE30\uB2E4\uB9AC\uC9C0 \uC54A\uACE0 \uC9C0\uAE08 \uC0C1\uD0DC\uB9CC. all_done=false \uBA74 \uB0A8\uC740 id \uB9CC \uB2E4\uC2DC \uBD80\uB978\uB2E4",
17926
+ "description": "\uAE30\uB2E4\uB9AC\uACE0 \uC2F6\uC740 \uCD08(0 = \uC9C0\uAE08 \uC0C1\uD0DC\uB9CC). \u2605 \uD55C \uBC88\uC758 \uD638\uCD9C\uC774 \uC2E4\uC81C\uB85C \uAE30\uB2E4\uB9AC\uB294 \uC2DC\uAC04\uC740 \uCD5C\uB300 60\uCD08\uB2E4(\uADF8\uBCF4\uB2E4 \uAE38\uBA74 MCP \uC804\uC1A1\uC774 \uBA3C\uC800 \uB04A\uAE34\uB2E4) \u2014 all_done=false \uBA74 \uB0A8\uC740 id \uB85C \uB2E4\uC2DC \uBD80\uB974\uBA74 \uC774\uC5B4\uC11C \uAE30\uB2E4\uB9B0\uB2E4.",
17912
17927
  "maximum": 600,
17913
17928
  "minimum": 0,
17914
17929
  "title": "Timeout S",
@@ -18115,6 +18130,157 @@ var GENERATED_TOOLS = [
18115
18130
  "openWorldHint": false
18116
18131
  }
18117
18132
  },
18133
+ {
18134
+ "name": "democut_get_asset",
18135
+ "description": "\uC790\uC0B0 \uD558\uB098(\uC11C\uBA85 URL \uB3D9\uBD09). fetch \uC790\uC0B0\uC740 state \uAC00 ready \uAC00 \uB420 \uB54C\uAE4C\uC9C0 \uAE30\uB2E4\uB9B0\uB2E4.",
18136
+ "inputSchema": {
18137
+ "type": "object",
18138
+ "properties": {
18139
+ "asset_id": {
18140
+ "type": "string",
18141
+ "description": "\uC790\uC0B0 id(ast_\u2026)"
18142
+ }
18143
+ },
18144
+ "required": [
18145
+ "asset_id"
18146
+ ],
18147
+ "additionalProperties": false
18148
+ },
18149
+ "annotations": {
18150
+ "readOnlyHint": true,
18151
+ "destructiveHint": false,
18152
+ "idempotentHint": true,
18153
+ "openWorldHint": false
18154
+ }
18155
+ },
18156
+ {
18157
+ "name": "democut_set_cut_image",
18158
+ "description": "\uCEF7 \uC774\uBBF8\uC9C0\uB97C \uC62C\uB9B0 \uC790\uC0B0 \uB610\uB294 \uAE30\uC874 \uBC84\uC804\uC758 \uD504\uB808\uC784\uC5D0\uC11C \uCD94\uAC00\uD55C\uB2E4(0\uC6D0).",
18159
+ "inputSchema": {
18160
+ "type": "object",
18161
+ "properties": {
18162
+ "slug": {
18163
+ "type": "string",
18164
+ "description": "\uD504\uB85C\uC81D\uD2B8 \uC2AC\uB7EC\uADF8(list_projects)"
18165
+ },
18166
+ "cut_id": {
18167
+ "type": "string",
18168
+ "description": "\uCEF7 id(cut_\u2026)"
18169
+ },
18170
+ "asset_id": {
18171
+ "anyOf": [
18172
+ {
18173
+ "type": "string"
18174
+ },
18175
+ {
18176
+ "type": "null"
18177
+ }
18178
+ ],
18179
+ "default": null,
18180
+ "title": "Asset Id"
18181
+ },
18182
+ "from_version": {
18183
+ "anyOf": [
18184
+ {
18185
+ "minimum": 1,
18186
+ "type": "integer"
18187
+ },
18188
+ {
18189
+ "type": "null"
18190
+ }
18191
+ ],
18192
+ "default": null,
18193
+ "title": "From Version"
18194
+ },
18195
+ "frame": {
18196
+ "default": "first",
18197
+ "enum": [
18198
+ "first",
18199
+ "last"
18200
+ ],
18201
+ "title": "Frame",
18202
+ "type": "string"
18203
+ }
18204
+ },
18205
+ "required": [
18206
+ "slug",
18207
+ "cut_id"
18208
+ ],
18209
+ "additionalProperties": false
18210
+ },
18211
+ "annotations": {
18212
+ "readOnlyHint": false,
18213
+ "destructiveHint": false,
18214
+ "idempotentHint": false,
18215
+ "openWorldHint": false
18216
+ }
18217
+ },
18218
+ {
18219
+ "name": "democut_select_cut_image",
18220
+ "description": "\uB300\uD45C \uCEF7 \uC774\uBBF8\uC9C0\uB97C \uACE0\uB978\uB2E4.",
18221
+ "inputSchema": {
18222
+ "type": "object",
18223
+ "properties": {
18224
+ "slug": {
18225
+ "type": "string",
18226
+ "description": "\uD504\uB85C\uC81D\uD2B8 \uC2AC\uB7EC\uADF8(list_projects)"
18227
+ },
18228
+ "cut_id": {
18229
+ "type": "string",
18230
+ "description": "\uCEF7 id(cut_\u2026)"
18231
+ },
18232
+ "image_id": {
18233
+ "title": "Image Id",
18234
+ "type": "string"
18235
+ }
18236
+ },
18237
+ "required": [
18238
+ "slug",
18239
+ "cut_id",
18240
+ "image_id"
18241
+ ],
18242
+ "additionalProperties": false
18243
+ },
18244
+ "annotations": {
18245
+ "readOnlyHint": false,
18246
+ "destructiveHint": false,
18247
+ "idempotentHint": true,
18248
+ "openWorldHint": false
18249
+ }
18250
+ },
18251
+ {
18252
+ "name": "democut_delete_cut_image",
18253
+ "description": "\uCEF7 \uC774\uBBF8\uC9C0 \uD558\uB098\uB97C \uC9C0\uC6B4\uB2E4.",
18254
+ "inputSchema": {
18255
+ "type": "object",
18256
+ "properties": {
18257
+ "slug": {
18258
+ "type": "string",
18259
+ "description": "\uD504\uB85C\uC81D\uD2B8 \uC2AC\uB7EC\uADF8(list_projects)"
18260
+ },
18261
+ "cut_id": {
18262
+ "type": "string",
18263
+ "description": "\uCEF7 id(cut_\u2026)"
18264
+ },
18265
+ "image_id": {
18266
+ "type": "string",
18267
+ "description": "\uCEF7 \uC774\uBBF8\uC9C0 id(img_\u2026)"
18268
+ }
18269
+ },
18270
+ "required": [
18271
+ "slug",
18272
+ "cut_id",
18273
+ "image_id"
18274
+ ],
18275
+ "additionalProperties": false
18276
+ },
18277
+ "annotations": {
18278
+ "readOnlyHint": false,
18279
+ "destructiveHint": true,
18280
+ "idempotentHint": true,
18281
+ "openWorldHint": false
18282
+ }
18283
+ },
18118
18284
  {
18119
18285
  "name": "democut_credit_balance",
18120
18286
  "description": "\uB0B4 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uC758 \uD06C\uB808\uB527 \uC794\uC561. \uBD80\uC791\uC6A9\uB3C4 \uACFC\uAE08\uB3C4 \uC5C6\uB2E4. \uB3C8\uC774 \uB098\uAC00\uB294 \uC791\uC5C5(democut_make_cuts \uB4F1)\uC744 \uC81C\uCD9C\uD558\uAE30 **\uC804\uC5D0** \uD655\uC778\uD558\uB77C \u2014 \uBD80\uC871\uD558\uBA74 \uC81C\uCD9C\uC774 402 \uB85C \uAC70\uBD80\uB418\uACE0, \uADF8\uAC83\uC744 \uBBF8\uB9AC \uC544\uB294 \uD3B8\uC774 \uB0AB\uB2E4(democut_estimate_cuts \uC758 can_afford \uAC00 \uC788\uC73C\uBA74 \uB9E4\uBC88 \uBD80\uB97C \uD544\uC694\uB294 \uC5C6\uB2E4). \uBAA8\uC790\uB77C\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC54C\uB9AC\uACE0 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uAD00\uB9AC\uC790\uC5D0\uAC8C \uCDA9\uC804\uC744 \uC694\uCCAD\uD558\uB3C4\uB85D \uC548\uB0B4\uD558\uB77C \u2014 \uB124\uAC00 \uC9C1\uC811 \uCDA9\uC804\uD560 \uC218\uB294 \uC5C6\uB2E4.",
@@ -18343,73 +18509,1045 @@ var GENERATED_TOOLS = [
18343
18509
  "idempotentHint": true,
18344
18510
  "openWorldHint": false
18345
18511
  }
18346
- }
18347
- ];
18348
-
18349
- // src/api-errors.ts
18350
- var TOOL_BASE_NAMES = GENERATED_TOOLS.map((t) => t.name.replace(/^democut_/, "")).sort((a, b) => b.length - a.length);
18351
- var escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
18352
- var NAME_PATTERNS = TOOL_BASE_NAMES.map((name) => [
18353
- new RegExp(`(?<!democut_)(?<![\\w.])${escapeRe(name)}(?![\\w{(])`, "g"),
18354
- `democut_${name}`
18355
- ]);
18356
- function callableToolNames(text) {
18357
- let out2 = text;
18358
- for (const [re, replacement] of NAME_PATTERNS) out2 = out2.replace(re, replacement);
18359
- return out2;
18360
- }
18361
- function usd(v) {
18362
- return v < 0.01 ? `$${v.toFixed(4)}` : `$${v.toFixed(2)}`;
18363
- }
18364
- function classifyApiError(e, ctx) {
18365
- const hint = ctx.statusHint ?? "\uC0C1\uD0DC \uC870\uD68C";
18366
- const contractHint = typeof e.extra.hint === "string" ? callableToolNames(e.extra.hint) : null;
18367
- if (contractHint) {
18368
- const lines = [contractHint];
18369
- if (ctx.submitted) {
18370
- lines.push(
18371
- e.status < 500 ? "\uC544\uC9C1 \uC544\uBB34\uAC83\uB3C4 \uC81C\uCD9C\uB418\uC9C0 \uC54A\uC558\uACE0 \uACFC\uAE08\uB3C4 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uC694\uCCAD\uC744 \uACE0\uCCD0 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694." : `\u26A0\uFE0F \uC81C\uCD9C\uC774 \uC811\uC218\uB410\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4 \u2014 \uB2E4\uC2DC \uBCF4\uB0B4\uC9C0 \uB9D0\uACE0 ${hint} \uB85C \uC0C1\uD0DC\uB97C \uBA3C\uC800 \uD655\uC778\uD558\uC138\uC694.`
18372
- );
18512
+ },
18513
+ {
18514
+ "name": "democut_add_character_photo",
18515
+ "description": "\uC62C\uB9B0 \uC774\uBBF8\uC9C0\uB97C \uC0AC\uC9C4 \uD310\uC73C\uB85C \uCD94\uAC00\uD55C\uB2E4(0\uC6D0). \uC18C\uAE09 \uC5C6\uC74C.",
18516
+ "inputSchema": {
18517
+ "type": "object",
18518
+ "properties": {
18519
+ "character_id": {
18520
+ "type": "string",
18521
+ "description": "\uC544\uBC14\uD0C0 id(chr_\u2026)"
18522
+ },
18523
+ "asset_id": {
18524
+ "title": "Asset Id",
18525
+ "type": "string"
18526
+ },
18527
+ "note": {
18528
+ "anyOf": [
18529
+ {
18530
+ "type": "string"
18531
+ },
18532
+ {
18533
+ "type": "null"
18534
+ }
18535
+ ],
18536
+ "default": null,
18537
+ "title": "Note"
18538
+ }
18539
+ },
18540
+ "required": [
18541
+ "character_id",
18542
+ "asset_id"
18543
+ ],
18544
+ "additionalProperties": false
18545
+ },
18546
+ "annotations": {
18547
+ "readOnlyHint": false,
18548
+ "destructiveHint": false,
18549
+ "idempotentHint": false,
18550
+ "openWorldHint": false
18373
18551
  }
18374
- return {
18375
- safety: e.status >= 500 && ctx.submitted ? "unsafe" : e.retriable === false ? "fixable" : "safe",
18376
- notCharged: e.status < 500,
18377
- lines
18378
- };
18379
- }
18380
- if (e.status === 422 && e.code === "VIDEOGEN_UPSTREAM_REJECTED") {
18381
- return {
18382
- safety: "unsafe",
18383
- // 돈이 나갔다가 돌아왔다 — "애초에 과금이 없었다" 와는 다르다. 그 구분을 흐리면
18384
- // 원장을 보는 사람이 이 거래를 설명하지 못한다.
18385
- notCharged: false,
18386
- lines: [
18387
- "\uC5C5\uC2A4\uD2B8\uB9BC\uC774 \uC774 \uC791\uC5C5\uC744 \uC601\uAD6C \uAC70\uBD80\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC870\uD68C\uD574\uB3C4 \uBCF5\uAD6C\uB418\uC9C0 \uC54A\uC73C\uBA70, \uACFC\uAE08\uC740 \uD658\uBD88\uB410\uC2B5\uB2C8\uB2E4.",
18388
- "\uACE0\uCE60 \uD30C\uB77C\uBBF8\uD130\uAC00 \uC788\uB294 \uC624\uB958\uAC00 \uC544\uB2D9\uB2C8\uB2E4 \u2014 \uC0C8\uB85C \uB9CC\uB4E4\uB824\uBA74 \uD504\uB86C\uD504\uD2B8\xB7\uC124\uC815\uC744 \uBC14\uAFD4 **\uC0C8\uB85C \uC81C\uCD9C**\uD574\uC57C \uD558\uACE0, \uADF8\uAC74 \uB2E4\uC2DC \uACFC\uAE08\uB429\uB2C8\uB2E4(\uC0AC\uC6A9\uC790 \uB3D9\uC758\uB97C \uBC1B\uC73C\uC138\uC694)."
18389
- ]
18390
- };
18391
- }
18392
- if (e.status === 404 && e.code === "VIDEOGEN_JOB_NOT_FOUND") {
18393
- return {
18394
- safety: "unsafe",
18395
- notCharged: false,
18396
- lines: [
18397
- "\uADF8 \uC791\uC5C5\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. job_id \uAC00 \uB9DE\uB294\uC9C0 \uBA3C\uC800 \uD655\uC778\uD558\uC138\uC694.",
18398
- "\u26A0\uFE0F \uC791\uC5C5\uC774 \uC0B4\uC544 \uC788\uB294\uB370 \uC870\uD68C\uB9CC \uC5B4\uAE0B\uB0AC\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4 \u2014 \uC0C8\uB85C \uC81C\uCD9C\uD558\uBA74 **\uBCC4\uB3C4 \uC791\uC5C5\uC73C\uB85C \uB2E4\uC2DC \uACFC\uAE08**\uB429\uB2C8\uB2E4."
18399
- ]
18400
- };
18401
- }
18402
- if (e.status === 402) {
18403
- const lines = [];
18404
- const limit = e.extra.limit_usd;
18405
- const would = e.extra.would_cost_usd;
18406
- if (typeof limit === "number" && typeof would === "number") {
18407
- lines.push(`\uC0C1\uD55C ${usd(limit)} \xB7 \uC774 \uC694\uCCAD ${usd(would)}`);
18552
+ },
18553
+ {
18554
+ "name": "democut_select_character_photo",
18555
+ "description": "\uB300\uD45C \uC0AC\uC9C4\uC744 \uACE0\uB978\uB2E4(\uC774\uBBF8 \uB9CC\uB4E0 \uCEF7\uC5D0\uB294 \uC18C\uAE09\uD558\uC9C0 \uC54A\uB294\uB2E4).",
18556
+ "inputSchema": {
18557
+ "type": "object",
18558
+ "properties": {
18559
+ "character_id": {
18560
+ "type": "string",
18561
+ "description": "\uC544\uBC14\uD0C0 id(chr_\u2026)"
18562
+ },
18563
+ "photo_id": {
18564
+ "title": "Photo Id",
18565
+ "type": "string"
18566
+ }
18567
+ },
18568
+ "required": [
18569
+ "character_id",
18570
+ "photo_id"
18571
+ ],
18572
+ "additionalProperties": false
18573
+ },
18574
+ "annotations": {
18575
+ "readOnlyHint": false,
18576
+ "destructiveHint": false,
18577
+ "idempotentHint": true,
18578
+ "openWorldHint": false
18408
18579
  }
18409
- lines.push("\uD574\uC0C1\uB3C4\uB098 \uAE38\uC774\uB97C \uB0AE\uCDB0 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694. \uC544\uC9C1 \uACFC\uAE08\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");
18410
- return { safety: "fixable", notCharged: true, lines };
18411
- }
18580
+ },
18581
+ {
18582
+ "name": "democut_get_storyboard",
18583
+ "description": "\uC2A4\uD1A0\uB9AC\uBCF4\uB4DC \u2014 rev\xB7\uC21C\uC11C\xB7\uCEF7(\uD30C\uC0DD \uD544\uB4DC)\xB7\uB300\uAE30 \uC81C\uC548\xB7\uC0AC\uC6A9\uB7C9. If-Match \uC5D0 \uC4F8 rev \uAC00 \uC5EC\uAE30 \uC788\uB2E4. \uB2E4\uC74C \uD638\uCD9C: democut_add_cut.",
18584
+ "inputSchema": {
18585
+ "type": "object",
18586
+ "properties": {
18587
+ "slug": {
18588
+ "type": "string",
18589
+ "description": "\uD504\uB85C\uC81D\uD2B8 \uC2AC\uB7EC\uADF8(list_projects)"
18590
+ }
18591
+ },
18592
+ "required": [
18593
+ "slug"
18594
+ ],
18595
+ "additionalProperties": false
18596
+ },
18597
+ "annotations": {
18598
+ "readOnlyHint": true,
18599
+ "destructiveHint": false,
18600
+ "idempotentHint": true,
18601
+ "openWorldHint": false
18602
+ }
18603
+ },
18604
+ {
18605
+ "name": "democut_add_cut",
18606
+ "description": "\uCEF7\uC744 \uD558\uB098 \uCD94\uAC00\uD55C\uB2E4(0\uC6D0, \uB80C\uB354\uD558\uC9C0 \uC54A\uB294\uB2E4). after \uAC00 \uC5C6\uC73C\uBA74 \uB05D\uC5D0 \uC5F0\uACB0. draft_spec \uC744 \uC8FC\uBA74 \uBC14\uB85C \uACAC\uC801\uC744 \uB0BC \uC218 \uC788\uACE0, \uC8FC\uC9C0 \uC54A\uC73C\uBA74 \uC790\uB9AC \uD45C\uC2DC \uCD08\uC548\uC774 \uB4E4\uC5B4\uAC00 \uB0B4\uC6A9\uC744 \uC815\uD558\uAE30 \uC804\uAE4C\uC9C0 \uACAC\uC801\xB7\uC81C\uCD9C\uC774 \uB9C9\uD78C\uB2E4 \u2014 \uB2E4\uC74C \uD589\uB3D9\uC740 \uC751\uB2F5\uC758 next_calls \uB97C \uB530\uB974\uB77C.",
18607
+ "inputSchema": {
18608
+ "type": "object",
18609
+ "properties": {
18610
+ "slug": {
18611
+ "type": "string",
18612
+ "description": "\uD504\uB85C\uC81D\uD2B8 \uC2AC\uB7EC\uADF8(list_projects)"
18613
+ },
18614
+ "mode": {
18615
+ "default": "ai_video",
18616
+ "enum": [
18617
+ "motion_graphic",
18618
+ "ai_video",
18619
+ "youtube_clip"
18620
+ ],
18621
+ "title": "Mode",
18622
+ "type": "string"
18623
+ },
18624
+ "after": {
18625
+ "anyOf": [
18626
+ {
18627
+ "type": "string"
18628
+ },
18629
+ {
18630
+ "type": "null"
18631
+ }
18632
+ ],
18633
+ "default": null,
18634
+ "description": "\uC774 \uCEF7 \uB2E4\uC74C\uC5D0 \uC5F0\uACB0. \uC5C6\uC73C\uBA74 \uB05D",
18635
+ "title": "After"
18636
+ },
18637
+ "title": {
18638
+ "default": "",
18639
+ "title": "Title",
18640
+ "type": "string"
18641
+ },
18642
+ "draft_spec": {
18643
+ "anyOf": [
18644
+ {
18645
+ "discriminator": {
18646
+ "mapping": {
18647
+ "ai_video": "#/$defs/AiVideoSpec",
18648
+ "motion_graphic": "#/$defs/MotionGraphicSpec",
18649
+ "youtube_clip": "#/$defs/YoutubeClipSpec"
18650
+ },
18651
+ "propertyName": "mode"
18652
+ },
18653
+ "oneOf": [
18654
+ {
18655
+ "$ref": "#/$defs/MotionGraphicSpec"
18656
+ },
18657
+ {
18658
+ "$ref": "#/$defs/AiVideoSpec"
18659
+ },
18660
+ {
18661
+ "$ref": "#/$defs/YoutubeClipSpec"
18662
+ }
18663
+ ]
18664
+ },
18665
+ {
18666
+ "type": "null"
18667
+ }
18668
+ ],
18669
+ "default": null,
18670
+ "title": "Draft Spec"
18671
+ }
18672
+ },
18673
+ "required": [
18674
+ "slug"
18675
+ ],
18676
+ "additionalProperties": false,
18677
+ "$defs": {
18678
+ "AiVideoSpec": {
18679
+ "additionalProperties": false,
18680
+ "properties": {
18681
+ "dialogue": {
18682
+ "items": {
18683
+ "$ref": "#/$defs/DialogueLine"
18684
+ },
18685
+ "title": "Dialogue",
18686
+ "type": "array"
18687
+ },
18688
+ "narration_asset_id": {
18689
+ "anyOf": [
18690
+ {
18691
+ "minLength": 1,
18692
+ "type": "string"
18693
+ },
18694
+ {
18695
+ "type": "null"
18696
+ }
18697
+ ],
18698
+ "default": null,
18699
+ "description": "BYO: \uCEF7 \uC804\uCCB4 \uB098\uB808\uC774\uC158 wav \uD55C \uAC1C(\uB300\uC0AC\uAC00 \uC788\uC5B4\uC57C \uD55C\uB2E4 \u2014 \uC790\uB9C9\xB7\uD0C0\uC774\uBC0D\uC758 \uADFC\uAC70). \uC904\uBCC4 audio_asset_id \uC640 \uB3D9\uC2DC \uC9C0\uC815 422",
18700
+ "title": "Narration Asset Id"
18701
+ },
18702
+ "subtitles": {
18703
+ "default": false,
18704
+ "title": "Subtitles",
18705
+ "type": "boolean"
18706
+ },
18707
+ "host": {
18708
+ "anyOf": [
18709
+ {
18710
+ "type": "string"
18711
+ },
18712
+ {
18713
+ "type": "null"
18714
+ }
18715
+ ],
18716
+ "default": null,
18717
+ "description": "\uC9C4\uD589 \u2014 \uD5C8\uC6A9 \uC9D1\uD569\uC740 \uCE74\uD0C8\uB85C\uADF8(\uBC29\uC2DD\uBCC4). \uBAA8\uC158\uADF8\uB798\uD53D\uC740 \uD544\uC218",
18718
+ "title": "Host"
18719
+ },
18720
+ "voice_id": {
18721
+ "anyOf": [
18722
+ {
18723
+ "minLength": 1,
18724
+ "type": "string"
18725
+ },
18726
+ {
18727
+ "type": "null"
18728
+ }
18729
+ ],
18730
+ "default": null,
18731
+ "description": "host\u2208{voice,avatar} \uC774\uACE0 BYO \uC624\uB514\uC624\uAC00 \uC5C6\uC744 \uB54C \uD544\uC218",
18732
+ "title": "Voice Id"
18733
+ },
18734
+ "pip": {
18735
+ "anyOf": [
18736
+ {
18737
+ "$ref": "#/$defs/PipSpec"
18738
+ },
18739
+ {
18740
+ "type": "null"
18741
+ }
18742
+ ],
18743
+ "default": null,
18744
+ "description": "host=avatar \uC77C \uB54C \uD544\uC218"
18745
+ },
18746
+ "image_asset_id": {
18747
+ "anyOf": [
18748
+ {
18749
+ "minLength": 1,
18750
+ "type": "string"
18751
+ },
18752
+ {
18753
+ "type": "null"
18754
+ }
18755
+ ],
18756
+ "default": null,
18757
+ "description": "\uCEF7 \uC774\uBBF8\uC9C0\uB97C spec \uC5D0\uC11C \uC9C1\uC811 \uC9C0\uC815(\uC5D0\uC774\uC804\uD2B8 \uC6D0\uC0F7\uC6A9)",
18758
+ "title": "Image Asset Id"
18759
+ },
18760
+ "duration_s": {
18761
+ "default": 5,
18762
+ "maximum": 15,
18763
+ "minimum": 4,
18764
+ "title": "Duration S",
18765
+ "type": "number"
18766
+ },
18767
+ "mode": {
18768
+ "const": "ai_video",
18769
+ "default": "ai_video",
18770
+ "title": "Mode",
18771
+ "type": "string"
18772
+ },
18773
+ "image_prompt": {
18774
+ "maxLength": 4e3,
18775
+ "minLength": 1,
18776
+ "title": "Image Prompt",
18777
+ "type": "string"
18778
+ },
18779
+ "provider": {
18780
+ "anyOf": [
18781
+ {
18782
+ "maxLength": 32,
18783
+ "minLength": 1,
18784
+ "type": "string"
18785
+ },
18786
+ {
18787
+ "type": "null"
18788
+ }
18789
+ ],
18790
+ "default": null,
18791
+ "description": "\uC601\uC0C1 \uC0DD\uC131 \uACF5\uAE09\uC790(\uC608: minimax). \uBE44\uC6B0\uBA74 \uC11C\uBC84 \uAE30\uBCF8\uAC12 \u2014 \uC4F8 \uC218 \uC788\uB294 \uBAA9\uB85D\uC740 GET \u2026/options \uC758 videogen_providers",
18792
+ "title": "Provider"
18793
+ },
18794
+ "seed": {
18795
+ "anyOf": [
18796
+ {
18797
+ "minimum": 0,
18798
+ "type": "integer"
18799
+ },
18800
+ {
18801
+ "type": "null"
18802
+ }
18803
+ ],
18804
+ "default": null,
18805
+ "title": "Seed"
18806
+ },
18807
+ "image": {
18808
+ "anyOf": [
18809
+ {
18810
+ "discriminator": {
18811
+ "mapping": {
18812
+ "asset": "#/$defs/AssetImageRef",
18813
+ "from_cut": "#/$defs/FromCutImageRef",
18814
+ "from_version": "#/$defs/FromVersionImageRef"
18815
+ },
18816
+ "propertyName": "kind"
18817
+ },
18818
+ "oneOf": [
18819
+ {
18820
+ "$ref": "#/$defs/AssetImageRef"
18821
+ },
18822
+ {
18823
+ "$ref": "#/$defs/FromCutImageRef"
18824
+ },
18825
+ {
18826
+ "$ref": "#/$defs/FromVersionImageRef"
18827
+ }
18828
+ ]
18829
+ },
18830
+ {
18831
+ "type": "null"
18832
+ }
18833
+ ],
18834
+ "default": null,
18835
+ "description": "\uCCAB \uD504\uB808\uC784. \uC5C6\uC73C\uBA74 image_asset_id \u2192 \uADF8\uAC83\uB3C4 \uC5C6\uC73C\uBA74 t2v(\uD14D\uC2A4\uD2B8\uB9CC) \u2014 \uACAC\uC801\uC774 notes \uB85C \uC54C\uB824\uC900\uB2E4",
18836
+ "title": "Image"
18837
+ },
18838
+ "end_image": {
18839
+ "anyOf": [
18840
+ {
18841
+ "discriminator": {
18842
+ "mapping": {
18843
+ "asset": "#/$defs/AssetImageRef",
18844
+ "from_cut": "#/$defs/FromCutImageRef",
18845
+ "from_version": "#/$defs/FromVersionImageRef"
18846
+ },
18847
+ "propertyName": "kind"
18848
+ },
18849
+ "oneOf": [
18850
+ {
18851
+ "$ref": "#/$defs/AssetImageRef"
18852
+ },
18853
+ {
18854
+ "$ref": "#/$defs/FromCutImageRef"
18855
+ },
18856
+ {
18857
+ "$ref": "#/$defs/FromVersionImageRef"
18858
+ }
18859
+ ]
18860
+ },
18861
+ {
18862
+ "type": "null"
18863
+ }
18864
+ ],
18865
+ "default": null,
18866
+ "title": "End Image"
18867
+ }
18868
+ },
18869
+ "required": [
18870
+ "image_prompt"
18871
+ ],
18872
+ "title": "AiVideoSpec",
18873
+ "type": "object"
18874
+ },
18875
+ "AssetImageRef": {
18876
+ "additionalProperties": false,
18877
+ "properties": {
18878
+ "kind": {
18879
+ "const": "asset",
18880
+ "default": "asset",
18881
+ "title": "Kind",
18882
+ "type": "string"
18883
+ },
18884
+ "asset_id": {
18885
+ "minLength": 1,
18886
+ "title": "Asset Id",
18887
+ "type": "string"
18888
+ }
18889
+ },
18890
+ "required": [
18891
+ "asset_id"
18892
+ ],
18893
+ "title": "AssetImageRef",
18894
+ "type": "object"
18895
+ },
18896
+ "DialogueLine": {
18897
+ "additionalProperties": false,
18898
+ "properties": {
18899
+ "id": {
18900
+ "description": "\uC904 id ln_<6> \u2014 \uC81C\uC548 diff \uC758 \uB300\uC870 \uD0A4",
18901
+ "pattern": "^ln_[a-z0-9]{6}$",
18902
+ "title": "Id",
18903
+ "type": "string",
18904
+ "x-diff": "ignore"
18905
+ },
18906
+ "text": {
18907
+ "description": "\uBC1C\uD654 \uD14D\uC2A4\uD2B8(\uC22B\uC790\uB294 \uC11C\uBC84\uAC00 \uC77D\uB294 \uBC95\uC744 \uC815\uD55C\uB2E4 \u2014 \uD480\uC5B4\uC4F0\uC9C0 \uC54A\uB294\uB2E4)",
18908
+ "maxLength": 2e3,
18909
+ "minLength": 1,
18910
+ "title": "Text",
18911
+ "type": "string"
18912
+ },
18913
+ "subtitle_text": {
18914
+ "anyOf": [
18915
+ {
18916
+ "maxLength": 2e3,
18917
+ "type": "string"
18918
+ },
18919
+ {
18920
+ "type": "null"
18921
+ }
18922
+ ],
18923
+ "default": null,
18924
+ "description": "\uC790\uB9C9 \uD45C\uAE30(\uC6D0\uBB38 \uD45C\uAE30). \uC5C6\uC73C\uBA74 text",
18925
+ "title": "Subtitle Text"
18926
+ },
18927
+ "audio_asset_id": {
18928
+ "anyOf": [
18929
+ {
18930
+ "minLength": 1,
18931
+ "type": "string"
18932
+ },
18933
+ {
18934
+ "type": "null"
18935
+ }
18936
+ ],
18937
+ "default": null,
18938
+ "description": "BYO: \uC774 \uC904\uC758 \uB098\uB808\uC774\uC158 \uC624\uB514\uC624 \uC790\uC0B0 \u2014 TTS \uD589 0\uC6D0, \uC815\uB82C \uD589\uB9CC",
18939
+ "title": "Audio Asset Id"
18940
+ }
18941
+ },
18942
+ "required": [
18943
+ "id",
18944
+ "text"
18945
+ ],
18946
+ "title": "DialogueLine",
18947
+ "type": "object"
18948
+ },
18949
+ "FromCutImageRef": {
18950
+ "additionalProperties": false,
18951
+ "properties": {
18952
+ "kind": {
18953
+ "const": "from_cut",
18954
+ "default": "from_cut",
18955
+ "title": "Kind",
18956
+ "type": "string"
18957
+ },
18958
+ "from_cut": {
18959
+ "description": "\uB2E4\uB978 \uCEF7\uC758 \uB300\uD45C \uBC84\uC804 \uD504\uB808\uC784(\uC5F0\uC18D\uC131 \uB3C4\uC6B0\uBBF8)",
18960
+ "minLength": 1,
18961
+ "title": "From Cut",
18962
+ "type": "string"
18963
+ },
18964
+ "frame": {
18965
+ "default": "last",
18966
+ "enum": [
18967
+ "first",
18968
+ "last"
18969
+ ],
18970
+ "title": "Frame",
18971
+ "type": "string"
18972
+ }
18973
+ },
18974
+ "required": [
18975
+ "from_cut"
18976
+ ],
18977
+ "title": "FromCutImageRef",
18978
+ "type": "object"
18979
+ },
18980
+ "FromVersionImageRef": {
18981
+ "additionalProperties": false,
18982
+ "properties": {
18983
+ "kind": {
18984
+ "const": "from_version",
18985
+ "default": "from_version",
18986
+ "title": "Kind",
18987
+ "type": "string"
18988
+ },
18989
+ "from_version": {
18990
+ "description": "\uC774 \uCEF7\uC758 \uD2B9\uC815 \uBC84\uC804 \uD504\uB808\uC784",
18991
+ "minimum": 1,
18992
+ "title": "From Version",
18993
+ "type": "integer"
18994
+ },
18995
+ "frame": {
18996
+ "default": "last",
18997
+ "enum": [
18998
+ "first",
18999
+ "last"
19000
+ ],
19001
+ "title": "Frame",
19002
+ "type": "string"
19003
+ }
19004
+ },
19005
+ "required": [
19006
+ "from_version"
19007
+ ],
19008
+ "title": "FromVersionImageRef",
19009
+ "type": "object"
19010
+ },
19011
+ "MotionGraphicSpec": {
19012
+ "additionalProperties": false,
19013
+ "properties": {
19014
+ "dialogue": {
19015
+ "items": {
19016
+ "$ref": "#/$defs/DialogueLine"
19017
+ },
19018
+ "title": "Dialogue",
19019
+ "type": "array"
19020
+ },
19021
+ "narration_asset_id": {
19022
+ "anyOf": [
19023
+ {
19024
+ "minLength": 1,
19025
+ "type": "string"
19026
+ },
19027
+ {
19028
+ "type": "null"
19029
+ }
19030
+ ],
19031
+ "default": null,
19032
+ "description": "BYO: \uCEF7 \uC804\uCCB4 \uB098\uB808\uC774\uC158 wav \uD55C \uAC1C(\uB300\uC0AC\uAC00 \uC788\uC5B4\uC57C \uD55C\uB2E4 \u2014 \uC790\uB9C9\xB7\uD0C0\uC774\uBC0D\uC758 \uADFC\uAC70). \uC904\uBCC4 audio_asset_id \uC640 \uB3D9\uC2DC \uC9C0\uC815 422",
19033
+ "title": "Narration Asset Id"
19034
+ },
19035
+ "subtitles": {
19036
+ "default": false,
19037
+ "title": "Subtitles",
19038
+ "type": "boolean"
19039
+ },
19040
+ "host": {
19041
+ "anyOf": [
19042
+ {
19043
+ "type": "string"
19044
+ },
19045
+ {
19046
+ "type": "null"
19047
+ }
19048
+ ],
19049
+ "default": null,
19050
+ "description": "\uC9C4\uD589 \u2014 \uD5C8\uC6A9 \uC9D1\uD569\uC740 \uCE74\uD0C8\uB85C\uADF8(\uBC29\uC2DD\uBCC4). \uBAA8\uC158\uADF8\uB798\uD53D\uC740 \uD544\uC218",
19051
+ "title": "Host"
19052
+ },
19053
+ "voice_id": {
19054
+ "anyOf": [
19055
+ {
19056
+ "minLength": 1,
19057
+ "type": "string"
19058
+ },
19059
+ {
19060
+ "type": "null"
19061
+ }
19062
+ ],
19063
+ "default": null,
19064
+ "description": "host\u2208{voice,avatar} \uC774\uACE0 BYO \uC624\uB514\uC624\uAC00 \uC5C6\uC744 \uB54C \uD544\uC218",
19065
+ "title": "Voice Id"
19066
+ },
19067
+ "pip": {
19068
+ "anyOf": [
19069
+ {
19070
+ "$ref": "#/$defs/PipSpec"
19071
+ },
19072
+ {
19073
+ "type": "null"
19074
+ }
19075
+ ],
19076
+ "default": null,
19077
+ "description": "host=avatar \uC77C \uB54C \uD544\uC218"
19078
+ },
19079
+ "image_asset_id": {
19080
+ "anyOf": [
19081
+ {
19082
+ "minLength": 1,
19083
+ "type": "string"
19084
+ },
19085
+ {
19086
+ "type": "null"
19087
+ }
19088
+ ],
19089
+ "default": null,
19090
+ "description": "\uCEF7 \uC774\uBBF8\uC9C0\uB97C spec \uC5D0\uC11C \uC9C1\uC811 \uC9C0\uC815(\uC5D0\uC774\uC804\uD2B8 \uC6D0\uC0F7\uC6A9)",
19091
+ "title": "Image Asset Id"
19092
+ },
19093
+ "duration_s": {
19094
+ "anyOf": [
19095
+ {
19096
+ "exclusiveMinimum": 0,
19097
+ "maximum": 600,
19098
+ "type": "number"
19099
+ },
19100
+ {
19101
+ "type": "null"
19102
+ }
19103
+ ],
19104
+ "default": null,
19105
+ "title": "Duration S"
19106
+ },
19107
+ "mode": {
19108
+ "const": "motion_graphic",
19109
+ "default": "motion_graphic",
19110
+ "title": "Mode",
19111
+ "type": "string"
19112
+ },
19113
+ "motion_prompt": {
19114
+ "anyOf": [
19115
+ {
19116
+ "maxLength": 4e3,
19117
+ "type": "string"
19118
+ },
19119
+ {
19120
+ "type": "null"
19121
+ }
19122
+ ],
19123
+ "default": null,
19124
+ "title": "Motion Prompt"
19125
+ },
19126
+ "tsx": {
19127
+ "anyOf": [
19128
+ {
19129
+ "maxLength": 2e5,
19130
+ "type": "string"
19131
+ },
19132
+ {
19133
+ "type": "null"
19134
+ }
19135
+ ],
19136
+ "default": null,
19137
+ "description": "BYO Remotion \uCF54\uB4DC(UTF-8 \u2264 200KB) \u2014 codegen \uD589 0\uC6D0, \uAC8C\uC774\uD2B8\uB294 codegen \uACFC \uB3D9\uAE09",
19138
+ "title": "Tsx"
19139
+ },
19140
+ "brand_override": {
19141
+ "anyOf": [
19142
+ {
19143
+ "additionalProperties": true,
19144
+ "type": "object"
19145
+ },
19146
+ {
19147
+ "type": "null"
19148
+ }
19149
+ ],
19150
+ "default": null,
19151
+ "title": "Brand Override"
19152
+ }
19153
+ },
19154
+ "title": "MotionGraphicSpec",
19155
+ "type": "object"
19156
+ },
19157
+ "PipSpec": {
19158
+ "additionalProperties": false,
19159
+ "properties": {
19160
+ "avatar_id": {
19161
+ "minLength": 1,
19162
+ "title": "Avatar Id",
19163
+ "type": "string"
19164
+ },
19165
+ "background_asset_id": {
19166
+ "description": "\uBC30\uACBD\uC740 \uC5B8\uC81C\uB098 \uC790\uC0B0(origin=background \uCE74\uD0C8\uB85C\uADF8 \uB610\uB294 \uC62C\uB9B0 \uC774\uBBF8\uC9C0)",
19167
+ "minLength": 1,
19168
+ "title": "Background Asset Id",
19169
+ "type": "string"
19170
+ },
19171
+ "position": {
19172
+ "default": "br",
19173
+ "enum": [
19174
+ "tl",
19175
+ "tr",
19176
+ "bl",
19177
+ "br"
19178
+ ],
19179
+ "title": "Position",
19180
+ "type": "string"
19181
+ },
19182
+ "size": {
19183
+ "default": "m",
19184
+ "enum": [
19185
+ "s",
19186
+ "m",
19187
+ "l"
19188
+ ],
19189
+ "title": "Size",
19190
+ "type": "string"
19191
+ }
19192
+ },
19193
+ "required": [
19194
+ "avatar_id",
19195
+ "background_asset_id"
19196
+ ],
19197
+ "title": "PipSpec",
19198
+ "type": "object"
19199
+ },
19200
+ "YoutubeAssetSource": {
19201
+ "additionalProperties": false,
19202
+ "properties": {
19203
+ "kind": {
19204
+ "const": "asset",
19205
+ "default": "asset",
19206
+ "title": "Kind",
19207
+ "type": "string"
19208
+ },
19209
+ "asset_id": {
19210
+ "description": "BYO: \uC62C\uB9B0 \uC6D0\uBCF8 \uC601\uC0C1 \u2014 \uB0B4\uB824\uBC1B\uAE30 \uD589 0\uC6D0",
19211
+ "minLength": 1,
19212
+ "title": "Asset Id",
19213
+ "type": "string"
19214
+ },
19215
+ "start_s": {
19216
+ "anyOf": [
19217
+ {
19218
+ "minimum": 0,
19219
+ "type": "number"
19220
+ },
19221
+ {
19222
+ "type": "null"
19223
+ }
19224
+ ],
19225
+ "default": null,
19226
+ "title": "Start S"
19227
+ },
19228
+ "end_s": {
19229
+ "anyOf": [
19230
+ {
19231
+ "exclusiveMinimum": 0,
19232
+ "type": "number"
19233
+ },
19234
+ {
19235
+ "type": "null"
19236
+ }
19237
+ ],
19238
+ "default": null,
19239
+ "title": "End S"
19240
+ }
19241
+ },
19242
+ "required": [
19243
+ "asset_id"
19244
+ ],
19245
+ "title": "YoutubeAssetSource",
19246
+ "type": "object"
19247
+ },
19248
+ "YoutubeClipSpec": {
19249
+ "additionalProperties": false,
19250
+ "properties": {
19251
+ "dialogue": {
19252
+ "items": {
19253
+ "$ref": "#/$defs/DialogueLine"
19254
+ },
19255
+ "title": "Dialogue",
19256
+ "type": "array"
19257
+ },
19258
+ "narration_asset_id": {
19259
+ "anyOf": [
19260
+ {
19261
+ "minLength": 1,
19262
+ "type": "string"
19263
+ },
19264
+ {
19265
+ "type": "null"
19266
+ }
19267
+ ],
19268
+ "default": null,
19269
+ "description": "BYO: \uCEF7 \uC804\uCCB4 \uB098\uB808\uC774\uC158 wav \uD55C \uAC1C(\uB300\uC0AC\uAC00 \uC788\uC5B4\uC57C \uD55C\uB2E4 \u2014 \uC790\uB9C9\xB7\uD0C0\uC774\uBC0D\uC758 \uADFC\uAC70). \uC904\uBCC4 audio_asset_id \uC640 \uB3D9\uC2DC \uC9C0\uC815 422",
19270
+ "title": "Narration Asset Id"
19271
+ },
19272
+ "subtitles": {
19273
+ "default": false,
19274
+ "title": "Subtitles",
19275
+ "type": "boolean"
19276
+ },
19277
+ "host": {
19278
+ "anyOf": [
19279
+ {
19280
+ "type": "string"
19281
+ },
19282
+ {
19283
+ "type": "null"
19284
+ }
19285
+ ],
19286
+ "default": null,
19287
+ "description": "\uC9C4\uD589 \u2014 \uD5C8\uC6A9 \uC9D1\uD569\uC740 \uCE74\uD0C8\uB85C\uADF8(\uBC29\uC2DD\uBCC4). \uBAA8\uC158\uADF8\uB798\uD53D\uC740 \uD544\uC218",
19288
+ "title": "Host"
19289
+ },
19290
+ "voice_id": {
19291
+ "anyOf": [
19292
+ {
19293
+ "minLength": 1,
19294
+ "type": "string"
19295
+ },
19296
+ {
19297
+ "type": "null"
19298
+ }
19299
+ ],
19300
+ "default": null,
19301
+ "description": "host\u2208{voice,avatar} \uC774\uACE0 BYO \uC624\uB514\uC624\uAC00 \uC5C6\uC744 \uB54C \uD544\uC218",
19302
+ "title": "Voice Id"
19303
+ },
19304
+ "pip": {
19305
+ "anyOf": [
19306
+ {
19307
+ "$ref": "#/$defs/PipSpec"
19308
+ },
19309
+ {
19310
+ "type": "null"
19311
+ }
19312
+ ],
19313
+ "default": null,
19314
+ "description": "host=avatar \uC77C \uB54C \uD544\uC218"
19315
+ },
19316
+ "image_asset_id": {
19317
+ "anyOf": [
19318
+ {
19319
+ "minLength": 1,
19320
+ "type": "string"
19321
+ },
19322
+ {
19323
+ "type": "null"
19324
+ }
19325
+ ],
19326
+ "default": null,
19327
+ "description": "\uCEF7 \uC774\uBBF8\uC9C0\uB97C spec \uC5D0\uC11C \uC9C1\uC811 \uC9C0\uC815(\uC5D0\uC774\uC804\uD2B8 \uC6D0\uC0F7\uC6A9)",
19328
+ "title": "Image Asset Id"
19329
+ },
19330
+ "duration_s": {
19331
+ "anyOf": [
19332
+ {
19333
+ "exclusiveMinimum": 0,
19334
+ "maximum": 600,
19335
+ "type": "number"
19336
+ },
19337
+ {
19338
+ "type": "null"
19339
+ }
19340
+ ],
19341
+ "default": null,
19342
+ "title": "Duration S"
19343
+ },
19344
+ "mode": {
19345
+ "const": "youtube_clip",
19346
+ "default": "youtube_clip",
19347
+ "title": "Mode",
19348
+ "type": "string"
19349
+ },
19350
+ "source": {
19351
+ "discriminator": {
19352
+ "mapping": {
19353
+ "asset": "#/$defs/YoutubeAssetSource",
19354
+ "url": "#/$defs/YoutubeUrlSource"
19355
+ },
19356
+ "propertyName": "kind"
19357
+ },
19358
+ "oneOf": [
19359
+ {
19360
+ "$ref": "#/$defs/YoutubeUrlSource"
19361
+ },
19362
+ {
19363
+ "$ref": "#/$defs/YoutubeAssetSource"
19364
+ }
19365
+ ],
19366
+ "title": "Source"
19367
+ }
19368
+ },
19369
+ "required": [
19370
+ "source"
19371
+ ],
19372
+ "title": "YoutubeClipSpec",
19373
+ "type": "object"
19374
+ },
19375
+ "YoutubeUrlSource": {
19376
+ "additionalProperties": false,
19377
+ "properties": {
19378
+ "kind": {
19379
+ "const": "url",
19380
+ "default": "url",
19381
+ "title": "Kind",
19382
+ "type": "string"
19383
+ },
19384
+ "url": {
19385
+ "description": "https://youtube.com|youtu.be \uACF5\uAC1C \uC8FC\uC18C\uB9CC",
19386
+ "minLength": 1,
19387
+ "title": "Url",
19388
+ "type": "string"
19389
+ },
19390
+ "start_s": {
19391
+ "minimum": 0,
19392
+ "title": "Start S",
19393
+ "type": "number"
19394
+ },
19395
+ "end_s": {
19396
+ "exclusiveMinimum": 0,
19397
+ "title": "End S",
19398
+ "type": "number"
19399
+ }
19400
+ },
19401
+ "required": [
19402
+ "url",
19403
+ "start_s",
19404
+ "end_s"
19405
+ ],
19406
+ "title": "YoutubeUrlSource",
19407
+ "type": "object"
19408
+ }
19409
+ }
19410
+ },
19411
+ "annotations": {
19412
+ "readOnlyHint": false,
19413
+ "destructiveHint": false,
19414
+ "idempotentHint": false,
19415
+ "openWorldHint": false
19416
+ }
19417
+ },
19418
+ {
19419
+ "name": "democut_duplicate_cut",
19420
+ "description": "\uCEF7\uC744 \uBCF5\uC81C\uD55C\uB2E4(\uACC4\uD68D\uB9CC, \uBC84\uC804\uC740 \uBCF5\uC81C\uD558\uC9C0 \uC54A\uB294\uB2E4).",
19421
+ "inputSchema": {
19422
+ "type": "object",
19423
+ "properties": {
19424
+ "slug": {
19425
+ "type": "string",
19426
+ "description": "\uD504\uB85C\uC81D\uD2B8 \uC2AC\uB7EC\uADF8(list_projects)"
19427
+ },
19428
+ "cut_id": {
19429
+ "type": "string",
19430
+ "description": "\uCEF7 id(cut_\u2026)"
19431
+ }
19432
+ },
19433
+ "required": [
19434
+ "slug",
19435
+ "cut_id"
19436
+ ],
19437
+ "additionalProperties": false
19438
+ },
19439
+ "annotations": {
19440
+ "readOnlyHint": false,
19441
+ "destructiveHint": false,
19442
+ "idempotentHint": false,
19443
+ "openWorldHint": false
19444
+ }
19445
+ },
19446
+ {
19447
+ "name": "democut_delete_cut",
19448
+ "description": "\uCEF7\uC744 \uC9C0\uC6B4\uB2E4(\uD65C\uC131 \uC7A1\uC774 \uC788\uC73C\uBA74 409 CUT_BUSY).",
19449
+ "inputSchema": {
19450
+ "type": "object",
19451
+ "properties": {
19452
+ "slug": {
19453
+ "type": "string",
19454
+ "description": "\uD504\uB85C\uC81D\uD2B8 \uC2AC\uB7EC\uADF8(list_projects)"
19455
+ },
19456
+ "cut_id": {
19457
+ "type": "string",
19458
+ "description": "\uCEF7 id(cut_\u2026)"
19459
+ }
19460
+ },
19461
+ "required": [
19462
+ "slug",
19463
+ "cut_id"
19464
+ ],
19465
+ "additionalProperties": false
19466
+ },
19467
+ "annotations": {
19468
+ "readOnlyHint": false,
19469
+ "destructiveHint": true,
19470
+ "idempotentHint": true,
19471
+ "openWorldHint": false
19472
+ }
19473
+ }
19474
+ ];
19475
+
19476
+ // src/api-errors.ts
19477
+ var TOOL_BASE_NAMES = GENERATED_TOOLS.map((t) => t.name.replace(/^democut_/, "")).sort((a, b) => b.length - a.length);
19478
+ var escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
19479
+ var NAME_PATTERNS = TOOL_BASE_NAMES.map((name) => [
19480
+ new RegExp(`(?<!democut_)(?<![\\w.])${escapeRe(name)}(?![\\w{(])`, "g"),
19481
+ `democut_${name}`
19482
+ ]);
19483
+ function callableToolNames(text) {
19484
+ let out2 = text;
19485
+ for (const [re, replacement] of NAME_PATTERNS) out2 = out2.replace(re, replacement);
19486
+ return out2;
19487
+ }
19488
+ function usd(v) {
19489
+ return v < 0.01 ? `$${v.toFixed(4)}` : `$${v.toFixed(2)}`;
19490
+ }
19491
+ function classifyApiError(e, ctx) {
19492
+ const hint = ctx.statusHint ?? "\uC0C1\uD0DC \uC870\uD68C";
19493
+ const contractHint = typeof e.extra.hint === "string" ? callableToolNames(e.extra.hint) : null;
19494
+ if (contractHint) {
19495
+ const lines = [contractHint];
19496
+ if (ctx.submitted) {
19497
+ lines.push(
19498
+ e.status < 500 ? "\uC544\uC9C1 \uC544\uBB34\uAC83\uB3C4 \uC81C\uCD9C\uB418\uC9C0 \uC54A\uC558\uACE0 \uACFC\uAE08\uB3C4 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uC694\uCCAD\uC744 \uACE0\uCCD0 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694." : `\u26A0\uFE0F \uC81C\uCD9C\uC774 \uC811\uC218\uB410\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4 \u2014 \uB2E4\uC2DC \uBCF4\uB0B4\uC9C0 \uB9D0\uACE0 ${hint} \uB85C \uC0C1\uD0DC\uB97C \uBA3C\uC800 \uD655\uC778\uD558\uC138\uC694.`
19499
+ );
19500
+ }
19501
+ return {
19502
+ safety: e.status >= 500 && ctx.submitted ? "unsafe" : e.retriable === false ? "fixable" : "safe",
19503
+ notCharged: e.status < 500,
19504
+ lines
19505
+ };
19506
+ }
19507
+ if (e.status === 422 && e.code === "VIDEOGEN_UPSTREAM_REJECTED") {
19508
+ return {
19509
+ safety: "unsafe",
19510
+ // 돈이 나갔다가 돌아왔다 — "애초에 과금이 없었다" 와는 다르다. 그 구분을 흐리면
19511
+ // 원장을 보는 사람이 이 거래를 설명하지 못한다.
19512
+ notCharged: false,
19513
+ lines: [
19514
+ "\uC5C5\uC2A4\uD2B8\uB9BC\uC774 \uC774 \uC791\uC5C5\uC744 \uC601\uAD6C \uAC70\uBD80\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC870\uD68C\uD574\uB3C4 \uBCF5\uAD6C\uB418\uC9C0 \uC54A\uC73C\uBA70, \uACFC\uAE08\uC740 \uD658\uBD88\uB410\uC2B5\uB2C8\uB2E4.",
19515
+ "\uACE0\uCE60 \uD30C\uB77C\uBBF8\uD130\uAC00 \uC788\uB294 \uC624\uB958\uAC00 \uC544\uB2D9\uB2C8\uB2E4 \u2014 \uC0C8\uB85C \uB9CC\uB4E4\uB824\uBA74 \uD504\uB86C\uD504\uD2B8\xB7\uC124\uC815\uC744 \uBC14\uAFD4 **\uC0C8\uB85C \uC81C\uCD9C**\uD574\uC57C \uD558\uACE0, \uADF8\uAC74 \uB2E4\uC2DC \uACFC\uAE08\uB429\uB2C8\uB2E4(\uC0AC\uC6A9\uC790 \uB3D9\uC758\uB97C \uBC1B\uC73C\uC138\uC694)."
19516
+ ]
19517
+ };
19518
+ }
19519
+ if (e.status === 404 && e.code === "VIDEOGEN_JOB_NOT_FOUND") {
19520
+ return {
19521
+ safety: "unsafe",
19522
+ notCharged: false,
19523
+ lines: [
19524
+ "\uADF8 \uC791\uC5C5\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. job_id \uAC00 \uB9DE\uB294\uC9C0 \uBA3C\uC800 \uD655\uC778\uD558\uC138\uC694.",
19525
+ "\u26A0\uFE0F \uC791\uC5C5\uC774 \uC0B4\uC544 \uC788\uB294\uB370 \uC870\uD68C\uB9CC \uC5B4\uAE0B\uB0AC\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4 \u2014 \uC0C8\uB85C \uC81C\uCD9C\uD558\uBA74 **\uBCC4\uB3C4 \uC791\uC5C5\uC73C\uB85C \uB2E4\uC2DC \uACFC\uAE08**\uB429\uB2C8\uB2E4."
19526
+ ]
19527
+ };
19528
+ }
19529
+ if (e.status === 402) {
19530
+ const lines = [];
19531
+ const limit = e.extra.limit_usd;
19532
+ const would = e.extra.would_cost_usd;
19533
+ if (typeof limit === "number" && typeof would === "number") {
19534
+ lines.push(`\uC0C1\uD55C ${usd(limit)} \xB7 \uC774 \uC694\uCCAD ${usd(would)}`);
19535
+ }
19536
+ lines.push("\uD574\uC0C1\uB3C4\uB098 \uAE38\uC774\uB97C \uB0AE\uCDB0 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694. \uC544\uC9C1 \uACFC\uAE08\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");
19537
+ return { safety: "fixable", notCharged: true, lines };
19538
+ }
18412
19539
  if (e.status === 422) {
19540
+ const unknown2 = e.extra.unknownFields;
19541
+ if (Array.isArray(unknown2) && unknown2.length) {
19542
+ return {
19543
+ safety: "fixable",
19544
+ notCharged: true,
19545
+ lines: [
19546
+ `\uC11C\uBC84\uAC00 \uC544\uC9C1 \uBAA8\uB974\uB294 \uC778\uC790\uC785\uB2C8\uB2E4: ${unknown2.join(", ")} \u2014 \uBC30\uD3EC\uAC00 \uACB9\uCE58\uB294 \uC911\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4.`,
19547
+ "\uADF8 \uC778\uC790\uB9CC \uBE7C\uACE0 \uB098\uBA38\uC9C0\uB294 \uADF8\uB300\uB85C \uB2E4\uC2DC \uBCF4\uB0B4\uC138\uC694. \uC544\uC9C1 \uACFC\uAE08\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."
19548
+ ]
19549
+ };
19550
+ }
18413
19551
  return {
18414
19552
  safety: "fixable",
18415
19553
  notCharged: true,
@@ -18520,7 +19658,17 @@ function parseDetail(status, body) {
18520
19658
  const msg = typeof item.msg === "string" ? item.msg : JSON.stringify(e);
18521
19659
  return where ? `${where}: ${msg}` : msg;
18522
19660
  });
18523
- return new ApiError(status, "VALIDATION_ERROR", lines.join("\n"), true);
19661
+ const unknownFields = detail.filter((e) => e.type === "extra_forbidden").map((e) => {
19662
+ const loc = e.loc;
19663
+ return Array.isArray(loc) ? String(loc[loc.length - 1]) : "";
19664
+ }).filter(Boolean);
19665
+ return new ApiError(
19666
+ status,
19667
+ "VALIDATION_ERROR",
19668
+ lines.join("\n"),
19669
+ true,
19670
+ unknownFields.length ? { unknownFields } : {}
19671
+ );
18524
19672
  }
18525
19673
  return new ApiError(status, `HTTP_${status}`, `\uC694\uCCAD\uC774 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4 (HTTP ${status}).`, null);
18526
19674
  }
@@ -18825,19 +19973,6 @@ function listProjects(a = {}, deps = {}) {
18825
19973
  return { text: lines.join("\n") };
18826
19974
  });
18827
19975
  }
18828
- var PROJECT_FIELD_DEFAULTS = {
18829
- ratio: "16:9",
18830
- resolution: "1080p",
18831
- folder_id: null,
18832
- defaults: null
18833
- };
18834
- function unsupportedProjectFields(a) {
18835
- const given = a;
18836
- return Object.keys(PROJECT_FIELD_DEFAULTS).filter((key) => {
18837
- const v = given[key];
18838
- return v !== void 0 && v !== null && v !== PROJECT_FIELD_DEFAULTS[key];
18839
- });
18840
- }
18841
19976
  function createProject(a = {}, deps = {}) {
18842
19977
  return guarded(READ_ONLY, async () => {
18843
19978
  const title = (a.title ?? "").trim();
@@ -18847,24 +19982,38 @@ function createProject(a = {}, deps = {}) {
18847
19982
  text: "title \uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 \uC54C\uC544\uBCFC \uC218 \uC788\uB294 \uD504\uB85C\uC81D\uD2B8 \uC774\uB984\uC744 \uB123\uC5B4 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694."
18848
19983
  };
18849
19984
  }
18850
- const unsupported = unsupportedProjectFields(a);
18851
- if (unsupported.length > 0) {
18852
- return {
18853
- isError: true,
18854
- text: `${unsupported.join(", ")} \uC740 \uC544\uC9C1 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uAE30\uBCF8\uAC12\uB9CC \uAC00\uB2A5). \uADF8 \uC778\uC790\uB97C \uBE7C\uACE0 \uB2E4\uC2DC \uD638\uCD9C\uD558\uBA74 ${PROJECT_FIELD_DEFAULTS.ratio}\xB7${PROJECT_FIELD_DEFAULTS.resolution} \uB85C \uB9CC\uB4E4\uC5B4\uC9D1\uB2C8\uB2E4.`
18855
- };
18856
- }
18857
19985
  const base = resolveBaseUrl(deps.baseUrl);
18858
19986
  const voiceId = await defaultVoiceId(base, deps);
18859
19987
  const p = await create(
18860
19988
  base,
18861
- { title, voice_id: voiceId, external_ref: `mcp:project:${title}` },
19989
+ {
19990
+ title,
19991
+ voice_id: voiceId,
19992
+ external_ref: `mcp:project:${title}`,
19993
+ ...a.ratio !== void 0 ? { ratio: a.ratio } : {},
19994
+ ...a.resolution !== void 0 ? { resolution: a.resolution } : {},
19995
+ ...a.folder_id !== void 0 ? { folder_id: a.folder_id } : {},
19996
+ ...a.defaults !== void 0 ? { defaults: a.defaults } : {}
19997
+ },
18862
19998
  deps
18863
19999
  );
20000
+ const asked = a.ratio;
20001
+ const mismatch = asked && p.ratio && p.ratio !== asked;
18864
20002
  return {
18865
20003
  text: [
18866
20004
  `\uD504\uB85C\uC81D\uD2B8 \uC900\uBE44\uB428 \u2014 slug: ${p.slug}`,
18867
20005
  `\uC81C\uBAA9: ${p.title}`,
20006
+ // ⚠️ 롤링 중 옛 api 는 이 둘을 내지 않는다 — 없으면 **말하지 않는다**(undefined 를 찍으면
20007
+ // 모델이 그것을 사실로 읽는다).
20008
+ ...p.ratio && p.resolution ? [
20009
+ `\uBE44\uC728\xB7\uD574\uC0C1\uB3C4: ${p.ratio} \xB7 ${p.resolution}` + (p.ratio !== "16:9" ? " (\uBE44\uC728\uC740 \uC774\uD6C4 \uBC14\uAFC0 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4)" : "")
20010
+ ] : [],
20011
+ ...mismatch ? [
20012
+ `\u26A0\uFE0F ${asked} \uB85C \uC694\uCCAD\uD588\uC9C0\uB9CC ${p.ratio} \uB85C \uB9CC\uB4E4\uC5B4\uC84C\uC2B5\uB2C8\uB2E4 \u2014 \uC11C\uBC84\uAC00 \uC544\uC9C1 \uC774 \uC635\uC158\uC744 \uBC1B\uC9C0 \uC54A\uB294 \uBC84\uC804\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uBE44\uC728\uC740 \uBC14\uAFC0 \uC218 \uC5C6\uC73C\uB2C8, ${asked} \uAC00 \uD544\uC694\uD558\uBA74 \uC774 \uD504\uB85C\uC81D\uD2B8\uB97C \uC4F0\uC9C0 \uB9D0\uACE0 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC54C\uB9B0 \uB4A4 \uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uB9CC\uB4DC\uC138\uC694.`
20013
+ ] : [],
20014
+ ...asked && !p.ratio ? [
20015
+ `\u26A0\uFE0F \uC11C\uBC84\uAC00 \uBE44\uC728\uC744 \uC54C\uB824\uC8FC\uC9C0 \uC54A\uC544 ${asked} \uB85C \uB9CC\uB4E4\uC5B4\uC84C\uB294\uC9C0 \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (\uC61B \uBC84\uC804\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4). democut_get_options \uB85C \uD655\uC778\uD558\uC138\uC694.`
20016
+ ] : [],
18868
20017
  "",
18869
20018
  "\uD504\uB85C\uC81D\uD2B8\uB97C \uC694\uAD6C\uD558\uB294 \uB3C4\uAD6C\uC758 project_slug \uC5D0 \uC704 slug \uB97C \uADF8\uB300\uB85C \uB123\uC73C\uC138\uC694.",
18870
20019
  "\uAC19\uC740 \uC81C\uBAA9\uC73C\uB85C \uC774 \uB3C4\uAD6C\uB97C \uB2E4\uC2DC \uBD88\uB7EC\uB3C4 \uC0C8\uB85C \uB9CC\uB4E4\uC9C0 \uC54A\uACE0 \uC774 \uD504\uB85C\uC81D\uD2B8\uAC00 \uB098\uC635\uB2C8\uB2E4."
@@ -18931,12 +20080,32 @@ function uploadAsset(a = {}, deps = {}) {
18931
20080
  return {
18932
20081
  text: [
18933
20082
  `\uC790\uC0B0 ${view.id} (${view.kind}) \uB97C \uAC00\uC838\uC624\uB294 \uC911\uC785\uB2C8\uB2E4 \u2014 state=${view.state}`,
18934
- "democut_get_cut \uC774 \uC544\uB2C8\uB77C \uC790\uC0B0 \uC870\uD68C\uB85C state \uAC00 ready \uAC00 \uB420 \uB54C\uAE4C\uC9C0 \uAE30\uB2E4\uB9B0 \uB4A4 \uC4F0\uC138\uC694.",
20083
+ "democut_get_asset \uC73C\uB85C state \uAC00 ready \uAC00 \uB420 \uB54C\uAE4C\uC9C0 \uAE30\uB2E4\uB9B0 \uB4A4 \uADF8 id \uB97C spec \uC5D0 \uC4F0\uC138\uC694.",
18935
20084
  "\uC2E4\uD328\uD558\uBA74 state=deleted \uAC00 \uB418\uACE0 \uC0AC\uC720\uB294 meta.error \uC5D0 \uB0A8\uC2B5\uB2C8\uB2E4."
18936
20085
  ].join("\n")
18937
20086
  };
18938
20087
  });
18939
20088
  }
20089
+ function getAsset(a = {}, deps = {}) {
20090
+ return guarded(READ_ONLY, async () => {
20091
+ if (!a.asset_id) return { isError: true, text: "asset_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
20092
+ const base = resolveBaseUrl(deps.baseUrl);
20093
+ const view = await apiRequest(base, `/api/assets/${encodeURIComponent(a.asset_id)}`, {}, deps);
20094
+ const lines = [`\uC790\uC0B0 ${view.id} (${view.kind}) \u2014 state=${view.state}`];
20095
+ if (view.state === "ready") {
20096
+ lines.push("\uC774 id \uB97C \uCEF7 spec \uC5D0 \uC4F0\uBA74 \uB429\uB2C8\uB2E4.");
20097
+ if (view.download_url) {
20098
+ lines.push(`\uB2E4\uC6B4\uB85C\uB4DC: ${view.download_url} (\uC11C\uBA85 URL \u2014 \uB9CC\uB8CC\uB418\uBA74 \uC774 \uB3C4\uAD6C\uB97C \uB2E4\uC2DC \uBD80\uB974\uC138\uC694)`);
20099
+ }
20100
+ } else if (view.state === "pending") {
20101
+ lines.push("\uC544\uC9C1 \uAC00\uC838\uC624\uB294 \uC911\uC785\uB2C8\uB2E4 \u2014 \uC7A0\uC2DC \uB4A4 \uB2E4\uC2DC \uBD80\uB974\uC138\uC694.");
20102
+ } else {
20103
+ const error2 = view.meta?.error;
20104
+ lines.push(`\uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4${typeof error2 === "string" ? ` \u2014 ${error2}` : ""}. \uB2E4\uB978 \uC790\uC0B0\uC744 \uC62C\uB9AC\uC138\uC694.`);
20105
+ }
20106
+ return { text: lines.join("\n") };
20107
+ });
20108
+ }
18940
20109
  function estimateCuts(a = {}, deps = {}) {
18941
20110
  return guarded(READ_ONLY, async () => {
18942
20111
  const slug = needSlug(a);
@@ -18964,9 +20133,92 @@ function estimateCuts(a = {}, deps = {}) {
18964
20133
  "\uC774 total_krw\xB7rate_version \uC744 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBCF4\uC5EC \uC8FC\uACE0 **\uADF8\uB300\uB85C** democut_make_cuts \uC5D0 \uB123\uC73C\uC138\uC694."
18965
20134
  );
18966
20135
  if (out2.mock) lines.push("(mock \uB2E8\uAC00\uC785\uB2C8\uB2E4 \u2014 \uC2E4\uC81C \uCCAD\uAD6C\uC640 \uB2E4\uB97C \uC218 \uC788\uC2B5\uB2C8\uB2E4.)");
20136
+ for (const note of out2.notes ?? []) {
20137
+ lines.push(`\u258E ${note.cut_id ? `${note.cut_id}: ` : ""}${callableToolNames(note.message)}`);
20138
+ }
18967
20139
  return { text: lines.join("\n") };
18968
20140
  });
18969
20141
  }
20142
+ function cutImageLine(cut) {
20143
+ const n = cut.images?.length ?? 0;
20144
+ if (!n) return `${cut.id}: \uC774\uBBF8\uC9C0 \uC5C6\uC74C \u2014 \uB2E4\uC74C \uC601\uC0C1\uC740 \uD14D\uC2A4\uD2B8\uB9CC\uC73C\uB85C \uB9CC\uB4ED\uB2C8\uB2E4(t2v).`;
20145
+ const cover = cut.current_image_id ? `\uB300\uD45C ${cut.current_image_id}` : "\uB300\uD45C \uC5C6\uC74C";
20146
+ const tail = cut.current_image_id ? " \u2014 \uB2E4\uC74C \uC601\uC0C1\uC758 \uCCAB \uD504\uB808\uC784\uC774 \uB429\uB2C8\uB2E4." : "";
20147
+ return `${cut.id}: \uC774\uBBF8\uC9C0 ${n}\uC7A5 \xB7 ${cover}${tail}`;
20148
+ }
20149
+ function setCutImage(a = {}, deps = {}) {
20150
+ return guarded(READ_ONLY, async () => {
20151
+ const slug = needSlug(a);
20152
+ if (typeof slug !== "string") return slug;
20153
+ const cutId = (a.cut_id ?? "").trim();
20154
+ if (!cutId) return { isError: true, text: "cut_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
20155
+ const assetId = (a.asset_id ?? "").trim();
20156
+ if (!assetId && a.from_version == null) {
20157
+ return {
20158
+ isError: true,
20159
+ text: "asset_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 \u2014 democut_upload_asset \uC73C\uB85C \uC774\uBBF8\uC9C0\uB97C \uBA3C\uC800 \uC62C\uB9AC\uC138\uC694."
20160
+ };
20161
+ }
20162
+ const base = resolveBaseUrl(deps.baseUrl);
20163
+ const out2 = await apiRequest(
20164
+ base,
20165
+ projectPath(slug, `/cuts/${encodeURIComponent(cutId)}/images`),
20166
+ {
20167
+ method: "POST",
20168
+ // ★ 광고한 인자는 **전부 넘긴다** — 안 넘기면 모델이 값을 넣었는데 아무 일도 일어나지 않고
20169
+ // 오류도 안 난다(이 레포가 반복해 밟은 결함 클래스, `mcp-server.test.ts` 가드).
20170
+ body: {
20171
+ ...assetId ? { asset_id: assetId } : {},
20172
+ // ★ `!= null` 이다 — `0` 은 계약이 422 로 거부할 값이고, 그 판정은 **서버가** 한다.
20173
+ // 여기서 falsy 로 걸러 버리면 잘못된 값이 조용히 사라져 오류조차 안 난다.
20174
+ ...a.from_version != null ? { from_version: a.from_version } : {},
20175
+ ...a.frame ? { frame: a.frame } : {}
20176
+ }
20177
+ },
20178
+ deps
20179
+ );
20180
+ const added = out2.images?.[out2.images.length - 1];
20181
+ const first = added && out2.current_image_id === added.id && (out2.images?.length ?? 0) === 1;
20182
+ return { text: `\uCEF7 \uC774\uBBF8\uC9C0\uB97C \uCD94\uAC00\uD588\uC2B5\uB2C8\uB2E4. ${cutImageLine(out2)}${first ? " \uCCAB \uC774\uBBF8\uC9C0\uB77C \uB300\uD45C\uB85C \uC815\uD588\uC2B5\uB2C8\uB2E4." : ""}` };
20183
+ });
20184
+ }
20185
+ function selectCutImage(a = {}, deps = {}) {
20186
+ return guarded(READ_ONLY, async () => {
20187
+ const slug = needSlug(a);
20188
+ if (typeof slug !== "string") return slug;
20189
+ const cutId = (a.cut_id ?? "").trim();
20190
+ if (!cutId) return { isError: true, text: "cut_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
20191
+ const imageId = (a.image_id ?? "").trim();
20192
+ if (!imageId) {
20193
+ return { isError: true, text: "image_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 \u2014 democut_get_cut \uC758 images[].id \uB97C \uC4F0\uC138\uC694." };
20194
+ }
20195
+ const base = resolveBaseUrl(deps.baseUrl);
20196
+ const out2 = await apiRequest(
20197
+ base,
20198
+ projectPath(slug, `/cuts/${encodeURIComponent(cutId)}/images/current`),
20199
+ { method: "PUT", body: { image_id: imageId } },
20200
+ deps
20201
+ );
20202
+ return { text: `\uB300\uD45C \uCEF7 \uC774\uBBF8\uC9C0\uB97C \uBC14\uAFE8\uC2B5\uB2C8\uB2E4. ${cutImageLine(out2)} \uC774\uBBF8 \uB9CC\uB4E0 \uBC84\uC804\uC740 \uADF8\uB300\uB85C\uC785\uB2C8\uB2E4.` };
20203
+ });
20204
+ }
20205
+ function deleteCutImage(a = {}, deps = {}) {
20206
+ return guarded(READ_ONLY, async () => {
20207
+ const slug = needSlug(a);
20208
+ if (typeof slug !== "string") return slug;
20209
+ const cutId = (a.cut_id ?? "").trim();
20210
+ const imageId = (a.image_id ?? "").trim();
20211
+ if (!cutId || !imageId) return { isError: true, text: "cut_id \uC640 image_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
20212
+ const base = resolveBaseUrl(deps.baseUrl);
20213
+ await apiRequest(
20214
+ base,
20215
+ projectPath(slug, `/cuts/${encodeURIComponent(cutId)}/images/${encodeURIComponent(imageId)}`),
20216
+ { method: "DELETE" },
20217
+ deps
20218
+ );
20219
+ return { text: `\uCEF7 \uC774\uBBF8\uC9C0 ${imageId} \uB97C \uC9C0\uC6E0\uC2B5\uB2C8\uB2E4. \uC790\uC0B0\uC740 \uB0A8\uC2B5\uB2C8\uB2E4(\uC790\uC0B0 \uCE35\uC774 \uAD00\uB9AC\uD569\uB2C8\uB2E4).` };
20220
+ });
20221
+ }
18970
20222
  function makeCuts(a = {}, deps = {}) {
18971
20223
  return guarded(SUBMITTING, async () => {
18972
20224
  const slug = needSlug(a);
@@ -18995,6 +20247,13 @@ function makeCuts(a = {}, deps = {}) {
18995
20247
  });
18996
20248
  }
18997
20249
  var WAIT_CHUNK_S = 30;
20250
+ var WAIT_CALL_CAP_S = 60;
20251
+ function waitBudgetLimits() {
20252
+ const schema = GENERATED_TOOLS.find((t) => t.name === "democut_wait_jobs")?.inputSchema;
20253
+ const field = schema?.properties?.timeout_s;
20254
+ const num = (v, fb) => typeof v === "number" && Number.isFinite(v) ? v : fb;
20255
+ return { fallback: num(field?.default, 600), max: WAIT_CALL_CAP_S };
20256
+ }
18998
20257
  var LIST_LINES = 20;
18999
20258
  function listing(lines) {
19000
20259
  if (lines.length <= LIST_LINES) return lines;
@@ -19011,7 +20270,8 @@ function jobLine(j) {
19011
20270
  function waitJobs(a = {}, deps = {}) {
19012
20271
  return guarded(READ_ONLY, async () => {
19013
20272
  const base = resolveBaseUrl(deps.baseUrl);
19014
- const budget = Math.max(0, Math.min(Math.trunc(a.timeout_s ?? 600), 600));
20273
+ const { fallback, max } = waitBudgetLimits();
20274
+ const budget = Math.max(0, Math.min(Math.trunc(a.timeout_s ?? fallback), max));
19015
20275
  const deadline = Date.now() + budget * 1e3;
19016
20276
  let ids = [...a.job_ids ?? []];
19017
20277
  let narrowed = false;
@@ -19060,14 +20320,8 @@ function getCut(a = {}, deps = {}) {
19060
20320
  if (!cutId) return { isError: true, text: "cut_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
19061
20321
  const base = resolveBaseUrl(deps.baseUrl);
19062
20322
  const cut = await apiRequest(base, projectPath(slug, `/cuts/${encodeURIComponent(cutId)}`), {}, deps);
19063
- const head = [`${cut.id} [${cut.state}] ${cut.mode}`];
19064
- if (cut.title) head.push(`\u300C${cut.title}\u300D`);
19065
- if (cut.current_version != null) head.push(`\uB300\uD45C v${cut.current_version}`);
19066
- if (cut.dirty_fields?.length) head.push(`\uB2EC\uB77C\uC9C4 \uD544\uB4DC: ${cut.dirty_fields.join(", ")}`);
19067
- if (cut.estimated_cost_krw != null) head.push(`\uC608\uC0C1 ${krw(cut.estimated_cost_krw)}`);
19068
- if (cut.blocked_reason) head.push(`\uB9C9\uD798: ${cut.blocked_reason}`);
19069
20323
  const versions = [...cut.versions ?? []].sort((x, y) => y.version - x.version);
19070
- const lines = [head.join(" \xB7 ")];
20324
+ const lines = [cutLine(cut)];
19071
20325
  lines.push(
19072
20326
  ...listing(
19073
20327
  versions.map((v) => {
@@ -19076,10 +20330,113 @@ function getCut(a = {}, deps = {}) {
19076
20330
  })
19077
20331
  )
19078
20332
  );
19079
- if (cut.next_calls?.length) lines.push(`\uB2E4\uC74C \uD638\uCD9C: ${cut.next_calls.join(", ")}`);
20333
+ if (cut.next_calls?.length)
20334
+ lines.push(callableToolNames(`\uB2E4\uC74C \uD638\uCD9C: ${cut.next_calls.join(", ")}`));
20335
+ return { text: lines.join("\n") };
20336
+ });
20337
+ }
20338
+ function mb(v) {
20339
+ if (v < 1024) return `${v}B`;
20340
+ if (v < 1024 * 1024) return `${Math.round(v / 1024)}KB`;
20341
+ if (v < 1024 * 1024 * 1024) return `${(v / (1024 * 1024)).toFixed(1)}MB`;
20342
+ return `${(v / (1024 * 1024 * 1024)).toFixed(2)}GB`;
20343
+ }
20344
+ function getStoryboard(a = {}, deps = {}) {
20345
+ return guarded(READ_ONLY, async () => {
20346
+ const slug = needSlug(a);
20347
+ if (typeof slug !== "string") return slug;
20348
+ const base = resolveBaseUrl(deps.baseUrl);
20349
+ const board = await apiRequest(base, projectPath(slug, "/storyboard"), {}, deps);
20350
+ const cuts = board.cuts ?? [];
20351
+ const lines = [
20352
+ `\uC2A4\uD1A0\uB9AC\uBCF4\uB4DC rev ${board.rev} \xB7 \uCEF7 ${cuts.length}\uAC1C \xB7 \uC0AC\uC6A9\uB7C9 ${mb(board.usage_bytes ?? 0)}`
20353
+ ];
20354
+ if (board.order?.length) lines.push(`\uC21C\uC11C: ${board.order.join(" \u2192 ")}`);
20355
+ const loose = cuts.filter((c) => c.position == null).map((c) => c.id);
20356
+ if (loose.length) lines.push(`\uC21C\uC11C\uC5D0 \uC5C6\uC74C(\uC644\uC131\uBCF8 \uC81C\uC678): ${loose.join(", ")}`);
20357
+ lines.push(
20358
+ ...listing(
20359
+ cuts.map((c) => ` ${cutLine(c)}`)
20360
+ )
20361
+ );
20362
+ if (board.next_calls?.length)
20363
+ lines.push(callableToolNames(`\uB2E4\uC74C \uD638\uCD9C: ${board.next_calls.join(", ")}`));
20364
+ return { text: lines.join("\n") };
20365
+ });
20366
+ }
20367
+ function cutLine(cut) {
20368
+ const bits = [`${cut.id} [${cut.state}] ${cut.mode}`];
20369
+ if (cut.title) bits.push(`\u300C${cut.title}\u300D`);
20370
+ if (cut.current_version != null) bits.push(`\uB300\uD45C v${cut.current_version}`);
20371
+ if (cut.dirty_fields?.length) bits.push(`\uB2EC\uB77C\uC9C4 \uD544\uB4DC: ${cut.dirty_fields.join(", ")}`);
20372
+ if (cut.estimated_cost_krw != null) bits.push(`\uC608\uC0C1 ${krw(cut.estimated_cost_krw)}`);
20373
+ if (cut.blocked_reason) bits.push(`\uB9C9\uD798: ${callableToolNames(cut.blocked_reason)}`);
20374
+ return bits.join(" \xB7 ");
20375
+ }
20376
+ function addCut(a = {}, deps = {}) {
20377
+ return guarded(READ_ONLY, async () => {
20378
+ const slug = needSlug(a);
20379
+ if (typeof slug !== "string") return slug;
20380
+ const base = resolveBaseUrl(deps.baseUrl);
20381
+ const body = {};
20382
+ for (const k of ["mode", "after", "title", "draft_spec"]) {
20383
+ if (a[k] !== void 0) body[k] = a[k];
20384
+ }
20385
+ const cut = await apiRequest(
20386
+ base,
20387
+ projectPath(slug, "/cuts"),
20388
+ { method: "POST", body },
20389
+ deps
20390
+ );
20391
+ const lines = [cutLine(cut)];
20392
+ if (cut.blocked_reason) lines.push(`\u2192 ${callableToolNames(cut.blocked_reason)}`);
20393
+ if (cut.next_calls?.length)
20394
+ lines.push(callableToolNames(`\uB2E4\uC74C \uD638\uCD9C: ${cut.next_calls.join(", ")}`));
19080
20395
  return { text: lines.join("\n") };
19081
20396
  });
19082
20397
  }
20398
+ function duplicateCut(a = {}, deps = {}) {
20399
+ return guarded(READ_ONLY, async () => {
20400
+ const slug = needSlug(a);
20401
+ if (typeof slug !== "string") return slug;
20402
+ const cutId = (a.cut_id ?? "").trim();
20403
+ if (!cutId) return { isError: true, text: "cut_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
20404
+ const base = resolveBaseUrl(deps.baseUrl);
20405
+ const cut = await apiRequest(
20406
+ base,
20407
+ projectPath(slug, `/cuts/${encodeURIComponent(cutId)}/duplicate`),
20408
+ { method: "POST", body: {} },
20409
+ deps
20410
+ );
20411
+ return {
20412
+ text: [
20413
+ `\uBCF5\uC81C\uB428 \u2014 ${cutLine(cut)}`,
20414
+ callableToolNames("\uC0B0\uCD9C\uBB3C(\uBC84\uC804)\uC740 \uBCF5\uC81C\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 \uACC4\uD68D\uB9CC \uBCF5\uC0AC\uB410\uC73C\uB2C8 estimate_cuts \uB85C \uACAC\uC801\uC744 \uB0B4\uACE0 \uB9CC\uB4DC\uC138\uC694.")
20415
+ ].join("\n")
20416
+ };
20417
+ });
20418
+ }
20419
+ function deleteCut(a = {}, deps = {}) {
20420
+ return guarded(READ_ONLY, async () => {
20421
+ const slug = needSlug(a);
20422
+ if (typeof slug !== "string") return slug;
20423
+ const cutId = (a.cut_id ?? "").trim();
20424
+ if (!cutId) return { isError: true, text: "cut_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
20425
+ const base = resolveBaseUrl(deps.baseUrl);
20426
+ await apiRequest(
20427
+ base,
20428
+ projectPath(slug, `/cuts/${encodeURIComponent(cutId)}`),
20429
+ { method: "DELETE" },
20430
+ deps
20431
+ );
20432
+ return {
20433
+ text: [
20434
+ `\uCEF7\uC744 \uC9C0\uC6E0\uC2B5\uB2C8\uB2E4 \u2014 ${cutId}`,
20435
+ "\uB9CC\uB4E4\uC5B4 \uB454 \uC601\uC0C1 \uD30C\uC77C\uC740 \uC790\uC0B0 \uBAA9\uB85D\uC5D0 \uADF8\uB300\uB85C \uC788\uC2B5\uB2C8\uB2E4(\uC0AC\uC6A9\uB7C9\uC740 \uC904\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4)."
20436
+ ].join("\n")
20437
+ };
20438
+ });
20439
+ }
19083
20440
  function download(a = {}, deps = {}) {
19084
20441
  return guarded(READ_ONLY, async () => {
19085
20442
  const slug = needSlug(a);
@@ -19244,6 +20601,52 @@ function putCharacter(a = {}, deps = {}) {
19244
20601
  return { text: `\uC544\uBC14\uD0C0\uB97C \uBC14\uAFE8\uC2B5\uB2C8\uB2E4: ${characterLine(out2)}` };
19245
20602
  });
19246
20603
  }
20604
+ function addCharacterPhoto(a = {}, deps = {}) {
20605
+ return guarded(READ_ONLY, async () => {
20606
+ const id = (a.character_id ?? "").trim();
20607
+ if (!id) return { isError: true, text: "character_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
20608
+ const assetId = (a.asset_id ?? "").trim();
20609
+ if (!assetId) {
20610
+ return {
20611
+ isError: true,
20612
+ text: "asset_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 \u2014 democut_upload_asset \uC73C\uB85C \uC774\uBBF8\uC9C0\uB97C \uBA3C\uC800 \uC62C\uB9AC\uC138\uC694."
20613
+ };
20614
+ }
20615
+ const base = resolveBaseUrl(deps.baseUrl);
20616
+ const out2 = await apiRequest(
20617
+ base,
20618
+ `/api/characters/${encodeURIComponent(id)}/photos`,
20619
+ { method: "POST", body: { asset_id: assetId, ...a.note ? { note: a.note } : {} } },
20620
+ deps
20621
+ );
20622
+ const added = out2.photos?.[out2.photos.length - 1];
20623
+ const tail = added && out2.current_photo_id === added.id ? " \uCCAB \uC0AC\uC9C4\uC774\uB77C \uB300\uD45C\uB85C \uC815\uD588\uC2B5\uB2C8\uB2E4." : "";
20624
+ return { text: `\uC0AC\uC9C4\uC744 \uCD94\uAC00\uD588\uC2B5\uB2C8\uB2E4: ${characterLine(out2)}${tail}` };
20625
+ });
20626
+ }
20627
+ function selectCharacterPhoto(a = {}, deps = {}) {
20628
+ return guarded(READ_ONLY, async () => {
20629
+ const id = (a.character_id ?? "").trim();
20630
+ if (!id) return { isError: true, text: "character_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
20631
+ const photoId = (a.photo_id ?? "").trim();
20632
+ if (!photoId) {
20633
+ return {
20634
+ isError: true,
20635
+ text: "photo_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 \u2014 democut_get_character \uC758 photos[].id \uB97C \uC4F0\uC138\uC694."
20636
+ };
20637
+ }
20638
+ const base = resolveBaseUrl(deps.baseUrl);
20639
+ const out2 = await apiRequest(
20640
+ base,
20641
+ `/api/characters/${encodeURIComponent(id)}/photos/current`,
20642
+ { method: "PUT", body: { photo_id: photoId } },
20643
+ deps
20644
+ );
20645
+ return {
20646
+ text: `\uB300\uD45C \uC0AC\uC9C4\uC744 \uBC14\uAFE8\uC2B5\uB2C8\uB2E4: ${characterLine(out2)} \u2014 \uC774\uBBF8 \uB9CC\uB4E0 \uCEF7\uC740 \uADF8\uB300\uB85C\uC785\uB2C8\uB2E4.`
20647
+ };
20648
+ });
20649
+ }
19247
20650
  function deleteCharacter(a = {}, deps = {}) {
19248
20651
  return guarded(READ_ONLY, async () => {
19249
20652
  const id = (a.character_id ?? "").trim();
@@ -19279,14 +20682,30 @@ function dispatch(name, args, deps = {}) {
19279
20682
  return getOptions(args, deps);
19280
20683
  case "democut_upload_asset":
19281
20684
  return uploadAsset(args, deps);
20685
+ case "democut_get_asset":
20686
+ return getAsset(args, deps);
19282
20687
  case "democut_estimate_cuts":
19283
20688
  return estimateCuts(args, deps);
19284
20689
  case "democut_make_cuts":
19285
20690
  return makeCuts(args, deps);
19286
20691
  case "democut_wait_jobs":
19287
20692
  return waitJobs(args, deps);
20693
+ case "democut_set_cut_image":
20694
+ return setCutImage(args, deps);
20695
+ case "democut_select_cut_image":
20696
+ return selectCutImage(args, deps);
20697
+ case "democut_delete_cut_image":
20698
+ return deleteCutImage(args, deps);
19288
20699
  case "democut_get_cut":
19289
20700
  return getCut(args, deps);
20701
+ case "democut_get_storyboard":
20702
+ return getStoryboard(args, deps);
20703
+ case "democut_add_cut":
20704
+ return addCut(args, deps);
20705
+ case "democut_duplicate_cut":
20706
+ return duplicateCut(args, deps);
20707
+ case "democut_delete_cut":
20708
+ return deleteCut(args, deps);
19290
20709
  case "democut_download":
19291
20710
  return download(args, deps);
19292
20711
  case "democut_import_cut":
@@ -19302,6 +20721,10 @@ function dispatch(name, args, deps = {}) {
19302
20721
  return getCharacter(args, deps);
19303
20722
  case "democut_put_character":
19304
20723
  return putCharacter(args, deps);
20724
+ case "democut_add_character_photo":
20725
+ return addCharacterPhoto(args, deps);
20726
+ case "democut_select_character_photo":
20727
+ return selectCharacterPhoto(args, deps);
19305
20728
  case "democut_delete_character":
19306
20729
  return deleteCharacter(args, deps);
19307
20730
  default: