diff --git a/README.md b/README.md index f0fadf6..829e630 100644 --- a/README.md +++ b/README.md @@ -62,13 +62,15 @@ shows only the old tools, restart the app before starting a new conversation. - Place sound effects at specified times - Duck music under voice audio - Review translated subtitles before dubbing into the requested languages +- Use a video, audio, or subtitle file from your computer by uploading it to Sonilo - Use an eligible account's 15-second dubbing preview, then request a full video - Inspect current USD cash balance, account services, trial allowance, and historical usage - Retrieve an existing generation after waiting or a timeout without resubmission Features depend on the connected hosted tool schemas and account access. The [Sonilo MCP repository](https://github.com/sonilo-ai/sonilo-mcp) is a useful -feature reference, but its local-file and playback tools are not bundled here. +feature reference, but its file-path parameters and playback tools are not +bundled here; local files go through the hosted upload tool instead. ### Example prompts @@ -79,10 +81,14 @@ feature reference, but its local-file and playback tools are not bundled here. - "Generate 30 seconds of jazz with separate drums and bass tracks." - "Translate this video into English subtitles first. I will correct the product names before dubbing: ``" - "Let me try English dubbing for free: ``" +- "Add music to `~/Videos/launch.mp4` and give me the finished video." - "What is my cash balance, and how many free text-to-music runs remain?" Use real public HTTPS media URLs in place of the labels above. A local file -or attachment is not a hosted media URL. The plugin returns actual result +or attachment is not a hosted media URL: when the hosted `create_upload_url` +tool is available and Codex can run the upload, the plugin uploads a file you +name to temporary storage on your Sonilo Platform account and uses the link it +gets back; otherwise it asks for a public HTTPS URL. The plugin returns actual result links for previews, subtitles, videos, variants, and stems. ### Account status and continuation @@ -114,7 +120,7 @@ existing account credits. Available free runs depend on the service and account; dubbing previews require one target language and no supplied script. Multiple music variants and multi-language dubbing can cost more. Account and usage tools (`get_account_services`, `get_usage`, `get_generation_task`) are -read-only and never incur a charge. Paid tools run only after you explicitly +read-only and never incur a charge. Uploading a file is also free. Paid tools run only after you explicitly ask for them. ## What this plugin connects to @@ -125,10 +131,13 @@ hosted endpoint: - **Endpoint:** `https://api.sonilo.com/mcp` (HTTPS, Streamable HTTP MCP) - **Authorization server:** Sonilo's Clerk instance (OAuth 2.1 + PKCE; the plugin registers dynamically — no pre-shared client secret) -- **Data sent:** your prompts and any media URLs you provide to a tool +- **Data sent:** your prompts, any media URLs you provide to a tool, and any + local file you ask the plugin to process, which is uploaded to Sonilo as a + temporary working file - **Data stored:** the OAuth token, kept locally per user by Codex -No local command or binary is executed by this plugin. +The plugin bundles no local command or binary. Uploading a local file uses +an HTTP PUT that Codex runs in your environment when you ask for it. ## Support diff --git a/docs/REVISION_1.2.0_NOTES.md b/docs/REVISION_1.2.0_NOTES.md new file mode 100644 index 0000000..0ff2131 --- /dev/null +++ b/docs/REVISION_1.2.0_NOTES.md @@ -0,0 +1,84 @@ +# Revision 1.2.0 draft notes + +> Status — October 9, 2026: prepared locally on `codex/plugin-v1.2.0`. Not +> committed, packaged, uploaded, or submitted. Version 1.1.0 is still in +> review and has not been cancelled. + +## Why + +Two hosted tool changes landed after 1.1.0 was submitted: + +- The subtitle tool is now listed as `generate_video_subtitles`. The name + `proofread` is no longer in the hosted tool list, and OpenAI's scan no + longer shows it. The 1.1.0 skill still routes to `proofread`. +- `create_upload_url` lets the hosted server take a file from the user's + machine. The skill guidance for it was added to the `codex/plugin-v1.1.0` + branch in PR #3 on October 9, after the 1.1.0 package had been submitted, + so the package in review does not contain it. This draft builds on that + guidance and does not replace it. + +## Release notes + +Subtitle review before dubbing now uses the hosted `generate_video_subtitles` +tool. Its availability and trial allowance are still reported under the +`proofread` service key, and the skill says so. + +Videos, audio, and subtitle files on your computer can now be used directly: +the skill uploads the file to Sonilo with the hosted upload tool and then +runs the requested workflow. Uploads go only to the one-time URL Sonilo +returns, only for a file the user named, and are temporary working files. +Where the upload cannot run, the skill asks for a public HTTPS link instead. +An edited subtitle file can be uploaded the same way before dubbing. + +Rules for user-supplied URLs are unchanged: public HTTPS only, and no tool +call for an unsafe URL. + +## Changed files + +- `plugins/sonilo/.codex-plugin/plugin.json`: version 1.2.0; the long + description no longer says media must be public HTTPS links. +- `plugins/sonilo/skills/sonilo-workflows/SKILL.md`: subtitle routing and the + service-key note. The "Use a local file" section comes from PR #3 unchanged. +- `references/dubbing.md`, `references/examples.md`: tool name, upload of an + edited script, one local-file example. +- `scripts/check_release.py`: paid-tool list, a guard against routing to the + retired name, and guards for the upload rules. +- `README.md`: feature list, example, data-sent and local-command statements. + +## Validation recorded for this draft + +- `python3 scripts/check_release.py` and `--live` pass. +- Codex CLI 0.162.0-alpha.2, fresh non-interactive sessions, hosted MCP only + (the legacy local `sonilo` server removed from the test configuration): + - Baseline with the installed 1.1.0 skill: 8 of 9 subtitle requests chose + `generate_video_subtitles`; 1 stopped, reporting that `proofread` was not + available. + - With this draft, after merging PR #3: 4 of 4 subtitle requests chose + `generate_video_subtitles`. + - Local file, network blocked: 1 of 1 called `create_upload_url`, could not + upload, started no generation, and asked for a public HTTPS link. + - Local file, network allowed: 1 of 1 uploaded and then called a generation + tool with the returned link. It chose `video_to_music` although the + request asked for a finished video, where `video_to_video_music` is the + documented route; one run, not investigated. + - Private-network `http://` URL: 1 of 1 refused with no tool call. +- Every generation call in these runs was stopped by the session's approval + policy before executing, so no task was created and nothing was charged. + The runs establish tool selection, not finished results. + +Not validated: a complete run through to a delivered result, the Codex +desktop app, ChatGPT web, the packaged ZIP, and the portal Skill scan. + +## Before submitting + +- The long description changed. The nine portal translations and + `docs/LISTING_COPY_1.1.0.json` still carry the old sentence. +- The portal's tool justifications were written for the 15 tools of 1.1.0. + They need entries for `generate_video_subtitles` and `create_upload_url`, + and the `proofread` entry removed. +- The privacy and data-use answers should mention that a local file the user + asks to process is uploaded to Sonilo. +- Check whether any of the three negative test cases expects a local file to + be refused; that behaviour changed. +- Record one end-to-end local-file run before claiming the feature in review + notes. diff --git a/plugins/sonilo/.codex-plugin/plugin.json b/plugins/sonilo/.codex-plugin/plugin.json index 0abab39..03b6f52 100644 --- a/plugins/sonilo/.codex-plugin/plugin.json +++ b/plugins/sonilo/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "sonilo", - "version": "1.1.0", + "version": "1.2.0", "description": "Generate licensed music, sound effects, mixed videos, translated subtitles, and dubbing with Sonilo Platform.", "author": { "name": "Sonilo", @@ -24,7 +24,7 @@ "interface": { "displayName": "Sonilo", "shortDescription": "Music, sound effects & dubbing", - "longDescription": "Connect your Sonilo Platform account to create licensed music, sound effects, and newly mixed videos from text or public HTTPS media. Combine music and effects, keep narration clear, request multiple music variants or instrument stems, review translated subtitles before dubbing, and retrieve generation results. Eligible accounts can preview dubbing before requesting a full video. Check your current USD cash balance, available services, free-trial allowance, and usage in Codex. Generation can consume existing account credits; read-only checks do not. Features and previews depend on account access and the connected service. Sonilo.com creator accounts are separate and cannot be used with this plugin.", + "longDescription": "Create licensed music, sound effects, and multilingual voiceovers for your videos with Sonilo.\n\n• Explore multiple music options and get separate instrument tracks for editing.\n• Get newly mixed videos with music and sound effects together, while keeping speech clear.\n• Review translated subtitles before creating a dubbed video.\n\nYou can also place sound effects at specific times, check your USD balance and free trials, and retrieve existing results after an interruption. Eligible accounts can preview dubbing before requesting the full video.\n\nConnect a Sonilo Platform account. Media inputs can be public HTTPS links or files on your computer, which are uploaded to Sonilo for processing. Generation may use existing account funds; account and task lookups are free. Features and previews depend on account access and service availability. Sonilo.com creator accounts are separate.", "developerName": "Sonilo", "category": "Creativity", "capabilities": [ @@ -43,7 +43,7 @@ "privacyPolicyURL": "https://sonilo.com/privacy-policy", "termsOfServiceURL": "https://sonilo.com/terms-of-service", "defaultPrompt": [ - "Create 30 seconds of jazz and provide separate drums and bass tracks.", + "Create three 10-second jazz music options with separate drums and bass tracks.", "Add music and sound effects to my video, keeping the voices clear.", "Translate my video into English subtitles for me to review before dubbing." ], diff --git a/plugins/sonilo/skills/sonilo-workflows/SKILL.md b/plugins/sonilo/skills/sonilo-workflows/SKILL.md index f02213e..cb467ad 100644 --- a/plugins/sonilo/skills/sonilo-workflows/SKILL.md +++ b/plugins/sonilo/skills/sonilo-workflows/SKILL.md @@ -1,6 +1,6 @@ --- name: sonilo-workflows -description: Create licensed music, sound effects, mixed videos, translated subtitles, and dubbed videos with a Sonilo Platform account. Check cash balance, usage, and trial allowance, preserve speech, request variants or stems, and retrieve existing tasks. Validate public HTTPS media inputs before any tool call; never direct users to pricing, checkout, subscriptions, or credit recharge. +description: Create licensed music, sound effects, mixed videos, translated subtitles, and dubbed videos with a Sonilo Platform account. Check cash balance, usage, and trial allowance, preserve speech, request variants or stems, and retrieve existing tasks. Validate public HTTPS media inputs before any tool call, and send a local file only through Sonilo's own upload tool; never direct users to pricing, checkout, subscriptions, or credit recharge. --- # Sonilo Workflows @@ -27,8 +27,9 @@ use a different namespace; identify them by their hosted schemas, including generation to check service availability and trial allowance. Check both the connected tools and `available_services`; describe an unavailable feature honestly instead of silently substituting a different paid operation. - `analyze_video` uses the service key `video_analysis`; other generation tools - in the routing table use their tool name as the service key. + `analyze_video` uses the service key `video_analysis`, and + `generate_video_subtitles` uses the service key `proofread`; other + generation tools in the routing table use their tool name as the service key. - For account, balance, trial, or insufficient-credit questions, read [account and links](references/account-and-links.md). `get_usage` reports historical spending, not the remaining balance. @@ -46,13 +47,40 @@ user-supplied video, audio, and subtitle URL. - Do not claim that a URL is public merely because it uses HTTPS. The hosted service remains responsible for DNS resolution, redirect validation, and SSRF protections. A filename or local attachment is not a public URL; do not - upload a user's file to an external host without authorization. + upload a user's file to a third-party host to obtain one. The only supported + upload path is the one below. + +## Use a local file + +When the user asks to process a file on their own machine, use the hosted +`create_upload_url` tool if it is among the connected tools and this +environment can send the file's bytes in an HTTP PUT. + +1. Proceed only when the request clearly covers that file, and say that the + file will be uploaded to temporary storage on the user's Sonilo Platform + account. Do not upload files the user did not name. +2. Call `create_upload_url` with the file's name and its exact size in bytes. + It is free and creates no task. It accepts video, audio, `.srt`, and `.vtt` + files up to `max_upload_size_mb` from `get_account_services`. +3. Send the raw bytes to the returned `upload_url` with one HTTP PUT, for + example `curl -T ""`, adding no authorization header. + A 403 means the size did not match or the URL expired: request a new URL + instead of retrying the old one. +4. Once the PUT succeeds, pass the returned `file_url` wherever the chosen + tool takes a media or subtitle URL. A `file_url` from this tool is a valid + input; do not ask for a public URL in its place. + +Treat `upload_url` as a credential for that one upload: never show it to the +user, log it, or reuse it. Do not present `file_url` as a result or download +link; uploads are temporary working files. If the tool is not connected or +the PUT cannot be made here, do not try another upload route: explain that a +public `https://` URL is needed instead. ## Choose the operation Generation and processing tools run only when the user clearly asks to create or process media. They may consume existing account credits. Read-only account -and task lookups do not. Explain options without generating anything when the +and task lookups do not, and neither does `create_upload_url`. Explain options without generating anything when the user asks what Sonilo can do. Do not require redundant confirmation for an explicit, sufficiently specified generation request. @@ -67,12 +95,13 @@ explicit, sufficiently specified generation request. | Music and sound effects together, delivered as audio | `video_to_sound` | | A new video with music and sound effects together | `video_to_video_sound` | | Lower existing music under a separate voice track | `audio_ducking` | -| Editable translated subtitles before dubbing | `proofread` | +| Editable translated subtitles before dubbing | `generate_video_subtitles` | | A dubbed video per requested language | `dubbing` | | A creative brief for a video | `analyze_video` (also potentially charged) | | Cash balance, available services, and trial counts | `get_account_services` | | Historical usage and spend | `get_usage` | | Progress or results of an existing task | `get_generation_task` | +| Make a local video, audio, or subtitle file usable as an input | `create_upload_url` (free; see Use a local file) | Use video-producing tools for a new video with the generated audio mixed in; do not substitute them for an audio-only request. Prefer a single combined diff --git a/plugins/sonilo/skills/sonilo-workflows/references/dubbing.md b/plugins/sonilo/skills/sonilo-workflows/references/dubbing.md index acee829..aafd19e 100644 --- a/plugins/sonilo/skills/sonilo-workflows/references/dubbing.md +++ b/plugins/sonilo/skills/sonilo-workflows/references/dubbing.md @@ -2,8 +2,10 @@ ## Review the script before dubbing -1. For “translate the subtitles first; I will correct them,” use `proofread` - only. It may consume credits; it produces SRT files, not a dubbed video. +1. For “translate the subtitles first; I will correct them,” use + `generate_video_subtitles` only. Its availability and trial allowance are + listed under the service key `proofread`. It may consume credits; it + produces SRT files, not a dubbed video. Check that the service is available before submitting. 2. Return the source transcript and target-language SRT URLs actually present in the result. Report warnings without claiming the files are invalid @@ -12,7 +14,9 @@ HTTPS SRT/VTT URL per target language, with keys matching the requested languages exactly. Validate every subtitle URL as well as the video URL. If the user edits text in chat, do not silently reuse the unedited SRT: - obtain a reachable URL for the approved script before submission. + obtain a reachable URL for the approved script before submission. An + edited `.srt` or `.vtt` saved on the user's machine can be uploaded with + `create_upload_url`; use its `file_url` as the script URL. 4. Set `export_srt=true` only if the user wants aligned subtitles with the dubbed result and scripts were supplied. Deliver each language's video and any successful subtitle export; report a blocked export separately. @@ -23,8 +27,10 @@ and accidentally accept the server's multiple-language default. Ask for the target language if missing. Dubbing is billed per language. - Follow the hosted schema: `dubbing.languages` currently takes a JSON array - encoded as a string (for example, `["en"]`), while `proofread.languages` - takes a list. Do not copy local MCP parameter types or local-file options. + encoded as a string (for example, `["en"]`), while + `generate_video_subtitles.languages` takes a list. Do not copy local MCP + parameter types or path parameters; a local file goes through + `create_upload_url`. - A free dubbing preview is conditional on current account eligibility, a single target language, and no supplied subtitles. Check `trial.dubbing.remaining`; never promise every user a free preview. diff --git a/plugins/sonilo/skills/sonilo-workflows/references/examples.md b/plugins/sonilo/skills/sonilo-workflows/references/examples.md index 13e8212..f2a621f 100644 --- a/plugins/sonilo/skills/sonilo-workflows/references/examples.md +++ b/plugins/sonilo/skills/sonilo-workflows/references/examples.md @@ -6,14 +6,15 @@ result; substitute actual account data for illustrative numbers. | User request | Behavior and response shape | | --- | --- | -| “Translate this one-minute product demo into English subtitles first; I will correct the product name.” + video URL | Run `proofread`, return the English SRT link, and wait: “Review this English subtitle file. Send the approved script URL when you are ready to dub.” | +| “Translate this one-minute product demo into English subtitles first; I will correct the product name.” + video URL | Run `generate_video_subtitles`, return the English SRT link, and wait: “Review this English subtitle file. Send the approved script URL when you are ready to dub.” | +| “Add music to the clip at ~/Videos/launch.mp4 and give me the finished video.” | Call `create_upload_url` with the file's name and exact size, PUT the file to the returned `upload_url`, then run `video_to_video_music` once with the returned `file_url`. Say first that the file will be uploaded to temporary storage on the user's Sonilo Platform account. “Here is your new video with music: [video].” Never show `upload_url`, and do not present `file_url` as a result. If the upload cannot run here, ask for a public HTTPS link instead. | | “Add relaxed music and waves to this 20-second beach video and give me the finished video.” + video URL | Run `video_to_video_sound` once. “Here is your new video with music and wave effects: [video].” | | “Let me try English dubbing for free on this one-minute Chinese video.” + video URL | Check single-language, no-script trial eligibility. If confirmed and the task succeeds with a trimmed preview: “Here is the first 15 seconds in English: [preview]. The remaining 45 seconds have not been processed.” Otherwise explain that a free preview is unavailable without submitting a paid job. | | “That preview sounds good. Dub the whole one-minute video.” | Refresh services, check for an existing full-video task, then submit once using the original source and English settings. “I will check your account and use the same video and language for the full version.” Do not claim it is already complete. | | “How much balance do I have, and how many free music runs remain?” | Call `get_account_services`. If it returns `cash_balance="2.5001"`, `currency="USD"`, and `trial.text_to_music.remaining=1`: “Your current cash balance is USD 2.5001. You have 1 free text-to-music run remaining.” Use actual returned values. If balance is missing: “The service did not return your cash balance.” Missing trial data is unknown, not zero. | | “Generate another 30-second upbeat track.” when rejected for insufficient balance | “The service reports insufficient balance.” If a fresh account lookup returns `cash_balance="0.0000"` and `currency="USD"`, add “Your current cash balance is USD 0.” Add “Generation did not start” only for a confirmed pre-generation rejection. Add “[Balance and free trials](https://platform.sonilo.com/usage-and-entitlements) explains how balance and trial limits work.” No automatic retry or instructions to purchase. | | “My account credits have updated. Continue the English video from before.” | Refresh account data and retrieve any prior task. Submit once only after a confirmed rejection or when the only completed task is a preview and the user wants the full video. If the refreshed response returns `cash_balance="5.0000"` and `currency="USD"`: “Your current cash balance is USD 5. I will use the same video and English settings; the service checks available funds when processing the request.” A positive balance alone does not prove sufficient funds. | -| “I am new to Sonilo. How do I ask for music for a café ad?” | No generation. “Send a public HTTPS video link and say: ‘Add warm, relaxed jazz to this 30-second café ad.’” For more examples, link to `https://platform.sonilo.com/mcp`. | +| “I am new to Sonilo. How do I ask for music for a café ad?” | No generation. “Send a public HTTPS video link, or name a video file on your computer, and say: ‘Add warm, relaxed jazz to this 30-second café ad.’” For more examples, link to `https://platform.sonilo.com/mcp`. | | “Is the English video ready?” | Retrieve the same task ID. While processing: “It is still processing. I am checking the original task, not submitting another generation.” If waiting stops, provide the task ID without promising unattended monitoring. | | “Give me three music choices for this 30-second café ad.” + video URL | Use `video_to_music` with `variants_num=3`, or the video-output tool if requested. Multiple variants use paid credits; a free-only constraint prevents this submission. Return three separately labeled actual URLs after success. | | “Add light music to my travel narration, but keep my voice clear.” + video URL | Use the requested output type with `preserve_speech=true` and `ducking=true` where supported. Link to the actual processed output, not an unducked alternative. | diff --git a/scripts/check_release.py b/scripts/check_release.py index 65d65de..1db6377 100644 --- a/scripts/check_release.py +++ b/scripts/check_release.py @@ -40,7 +40,7 @@ "audio_ducking", "video_to_sound", "video_to_video_sound", - "proofread", + "generate_video_subtitles", "dubbing", "analyze_video", } @@ -282,6 +282,30 @@ def check_local() -> None: "Do not call even a read-only Sonilo tool" in skill, "skill must reject unsafe media URLs without account lookups", ) + # `proofread` survives only as the service key that get_account_services + # reports; the hosted server no longer lists a tool by that name. + require( + "| `proofread` |" not in guidance and "use `proofread`" not in guidance + and "Run `proofread`" not in guidance, + "guidance must not route to the retired proofread tool name", + ) + require( + "uses the service key `proofread`" in skill, + "skill must map generate_video_subtitles to its proofread service key", + ) + require("`create_upload_url`" in skill, "skill is missing local-file upload guidance") + require( + "upload a user's file to a third-party host" in skill, + "skill must confine local-file uploads to Sonilo's upload URL", + ) + require( + "never show it to the\nuser" in skill, + "skill must keep the one-time upload URL out of replies", + ) + require( + "do not try another upload route" in skill, + "skill must fall back to a public link when an upload cannot run", + ) require( "Do not provide or direct users to pricing, checkout, subscription, credit" in guidance, "skill must not direct users to purchase or recharge",