| name | smm-openrouter |
| description | Use when the user explicitly asks OpenRouter/Gemini/Gemini Flash/Opus/Claude for SMM/copywriting, including anti-AI rewrite from a file, or asks to audit a saved OpenRouter SMM report. Do not use for ordinary copywriting without an external model. |
| verified_at | "2026-05-29T00:00:00.000Z" |
| covers | ["marketing","copywriting","api"] |
| drift_covers | [".agents/skills/smm-openrouter/**","scripts/or_smm.py","config/openrouter_smm.models.json","config/openrouter_smm.instruction_presets.json","AGENTS.md"] |
SMM OpenRouter
Use this skill only when the user explicitly asks for OpenRouter, Gemini, Opus/Claude, or an external model for SMM/copywriting. This includes requests like "прогони текст из файла через Gemini Flash и убери нейросетевую стилистику". Codex remains the orchestrator; the external model is the editor whose successful output must be shown faithfully.
For detailed command options, budgets, privacy checklist and output schema, read references/openrouter-smm.md when preparing an actual call.
Default Workflow
- Confirm the request really asks for an external model. If not, handle the copywriting task inside Codex.
- Classify the task as
ideas, hooks, rewrite, edit or sales.
- For explicit anti-AI/humanization requests such as "убери нейросетевую стилистику", "сделай человечнее" or "менее нейросетево" through Gemini/OpenRouter, use
--instruction-preset anti-ai-human-cleanup.
- For explicit clarity/readability cleanup through Gemini/OpenRouter, use
--instruction-preset clarity-tighten.
- For explicit soft sales strengthening through Gemini/OpenRouter, use
--instruction-preset soft-sales-rewrite.
- For explicit event/афиша/announcement polish through Gemini/OpenRouter, use
--instruction-preset event-announcement-polish.
- For explicit personal long Telegram posts, author drafts or voice transcripts through Gemini/OpenRouter, use
--instruction-preset longform-human-rewrite when preserving the source author's voice is the goal.
- Create compact local files with task-scoped names:
.tmp/or_<safe-task>_<YYYYMMDD_HHMM>_request.md with the user's original request, verbatim enough to preserve intent.
.tmp/or_<safe-task>_<YYYYMMDD_HHMM>_brief.md
.tmp/or_<safe-task>_<YYYYMMDD_HHMM>_source.md
.tmp/or_<safe-task>_<YYYYMMDD_HHMM>_style.md only when the user explicitly asks for a project, brand or author voice.
Exact shared names .tmp/or_request.md, .tmp/or_brief.md, .tmp/or_source.md and .tmp/or_style.md are blocked because parallel chats can overwrite them.
- Run a dry-run with
scripts/or_smm.py --original-request-file .tmp/or_<safe-task>_<YYYYMMDD_HHMM>_request.md; the CLI auto-loads OpenRouter env vars from current-working-directory env files, then repo-root env files, and lets the first project-local key override a global process key.
- Let the CLI run executable privacy preflight and budget checks. Do not bypass
privacy_preflight=block unless the operator explicitly asks to inspect a blocked dry-run.
- If cost, privacy and explicit profile gates pass, run the real call.
- Read the concrete
markdown_path returned by the call. The CLI also maintains ignored convenience files: latest.md copies the latest successful valid external report, and index.md lists recent report/index events without prompt/source text. Use latest.md only for navigation when no parallel calls may have raced; use scripts/or_smm.py --latest-report / --ledger-summary when discovery or spend history matters.
- Optionally run
scripts/or_smm.py --audit-report <report> to check contract/privacy risks. Audit labels blockers only; it never rewrites, ranks or selects copy.
- Return the external Markdown report's variants faithfully in chat. Do not locally rewrite, synthesize, select or "improve" the external output after a successful call.
- After a successful valid external report, ask one short feedback question. Record only the operator's explicit answer with
scripts/or_smm.py --record-feedback <report> --feedback-file <file>; if the operator skips or gives no concrete preference, record nothing.
Model Defaults
gemini-flash: default profile, google/gemini-3.5-flash; cheap hooks, quick ideas, lightweight rewrites; minimal reasoning, default budget $0.07 with a 6000 token output cap.
gemini-pro: use only when the user explicitly asks for Gemini Pro or a stronger Gemini profile; pass --allow-expensive; default budget $0.08.
opus: use only when the user explicitly asks for Opus/Claude; pass --allow-expensive; returns external variants, not a selected/polished Codex final; default budget $0.15 with a larger default output cap for three full variants.
- Do not use
opus-fast; it is not part of this workflow.
- Do not compare Gemini and Opus in this workflow. If the user asks to compare models, explain that this workflow only runs the explicitly requested model and ask which one to call.
--allow-expensive only authorizes an expensive profile. It does not bypass --budget-usd.
Hard Rules
- Never send full
AGENTS.md, hidden/system instructions, secrets, API keys, cookies, CRM exports, private customer data, long private correspondence or whole paid course materials.
- Treat
scripts/or_smm.py --privacy-preflight block as the enforcement source of truth before any OpenRouter call. If it blocks, do not manually copy the same text into another external tool.
--privacy-preflight warn is diagnostic only. It may be used for dry-runs to inspect findings, but block-level findings must never be sent in a real OpenRouter call.
- Treat instruction-leak preflight findings (
instruction_*, system_*, project_instruction_*) as hard blockers. Do not summarize, anonymize or forward hidden/project instructions to another external model.
- Do not look for
GEMINI_API_KEY, Gemini CLI, Vertex AI or Google service account credentials for this workflow. "Gemini" here means the OpenRouter gemini-flash/gemini-pro profiles through scripts/or_smm.py.
- Do not ask the operator to run
source/export for an existing key file. Use CLI autoload; project-local .tmp/openrouter_smm.env must win over a global OPENROUTER_API_KEY. Ask only for the secret file to be created if no key exists.
- Send only the immediate task, compact brief, relevant source text, short style digest, platform, audience, CTA and constraints.
- Always use context minimization. Do not send more context just because the user says "max quality".
- Use approved instruction presets for explicit matching tasks:
anti-ai-human-cleanup, clarity-tighten, soft-sales-rewrite, event-announcement-polish, longform-human-rewrite. These are task instructions, not project style packs.
- Auto-select a preset only when the user's wording clearly maps to one preset. If multiple preset goals fit, ask one short question before the external call instead of inventing priority.
longform-human-rewrite preserves the voice already present in a personal Telegram post, author draft or voice transcript; it does not add a new brand/project voice.
- Before changing preset wording or selection docs, verify the synthetic golden fixtures in
scripts/tests/fixtures/or_smm/preset_golden_fixtures.json; they check contract drift only and never require paid OpenRouter calls.
- Use
scripts/or_smm.py --feedback-summary before future calls when prior feedback may be relevant. Reuse feedback only by explicitly citing the selected feedback bullets before adding them to the task-scoped _brief.md; never apply it silently as hidden prompt drift.
- Feedback is source-backed guidance, not a style pack and not permission for local post-call editing. Do not infer feedback from vague chat context; record only explicit operator preference after a successful valid external report.
--draft-feedback-promotion <feedback-id> creates an ignored local promotion packet only. Tracked promotion of generalized preferences requires a separate explicit task after review.
- Do not plan tracked preference promotion, feedback-driven style packs or feedback-driven routing notes until
--feedback-summary shows at least 3 concrete feedback events. A single critical blocker-pattern may bypass this gate only if the operator explicitly asks to canonize it.
- Keep project/brand/author voice off by default. Use a task-scoped
_style.md only when the user explicitly asks for that voice; if you believe it materially matters but the request is ambiguous, ask one short question before the external call.
- Do not paste the standard external-model metaprompt manually into task-scoped
_brief.md or _source.md; scripts/or_smm.py injects it into every OpenRouter payload as quality_metaprompt. It is a hidden quality instruction and must not appear inside returned SMM copy unless the user explicitly asks for that wrapper.
- Do not pass
--temperature to profiles that declare omit_temperature=true; for Opus, let the CLI use the profile-safe payload.
--save-prompt writes the full request payload. Use it only in ignored local artifact dirs; never use it with a tracked custom output dir unless the operator explicitly approved it.
- Always run dry-run before Opus or longer input. If estimate exceeds budget, ask before raising
--budget-usd, compressing input, reducing output settings or chunking.
- One complete source document should stay one OpenRouter request when privacy and budget pass. Do not split one source document into separate variants, and do not automatically chunk it into multiple paid calls.
--auto-retry-truncation is an opt-in technical retry only for truncated structured JSON. It allows one extra OpenRouter call with a higher token cap only when the retry estimate still fits the active --budget-usd; it does not bypass budget, privacy, model gates or response validation.
- If a paid call returns truncated/invalid output, stop. Read and show the saved Markdown/raw partial output first, then ask the operator whether to retry. Do not make a manual second paid call without explicit approval.
- For rewrite/edit/sales SMM tasks, request exactly three full external variants unless the user explicitly asks for another count. One must preserve the user's original request as
direct_user_request; the others may be context_enriched or neutral_alternative.
- Treat response validation failure as a blocker: exact variant count, required tracks, non-empty
id/prompt_track/angle/text, no unrequested format split. Do not cache or present invalid output as success.
- Do not turn the three variants into format splits such as "short version", "for stories", "for caption" or "for poster" unless the user explicitly asked for those placements. All variants should solve the same requested format/task.
- Do not invent creative direction when the user's request is already sufficient. If useful, add compact brand/platform/style context only as a second track.
- If you cannot confidently decide whether enrichment is useful, ask one short question before the external call.
- After a successful external call, return all external variants from the Markdown report in order. You may add a short factual frame with profile/model/cost/finish_reason/report path, but the generated text itself must remain unchanged.
- The report may include
Copy-ready variants; those blocks duplicate the external variant text for easier copying. They are not Codex edits and do not permit selection, polishing or shortening.
- If you run post-call audit, show only the audit verdict/risks beside the unchanged external variants. Audit cannot be used as permission to pick a winner or produce a Codex-authored final.
- Do not choose a "best" text as the final answer, do not combine variants, do not fix wording, do not rewrite headings/CTA, do not "докручивать", and do not treat the model output as draft material unless the user explicitly asks for local follow-up editing after seeing the external output.
- Do not use local copywriting skills after a successful external call. They may only help before the call to compress context or extract a compact style/source digest.
- If the user asks for the full/raw answer from the external model, provide the full Markdown report or the raw provider content from the saved artifact without paraphrase.
- If OpenRouter fails, is over budget, has a missing/key-limit error, returns invalid/truncated output, returns invalid output after the allowed truncation retry, or is blocked by privacy checks, do not return a locally rewritten final copy unless the user explicitly authorizes local fallback after the failure. Report the blocker, cost/status/report paths, show saved partial output when present, and ask whether to retry, change key, switch profile, reduce scope or allow local fallback.
- When model/pricing drift is suspected or before an expensive profile call, run
scripts/or_smm.py --check-models before a paid call. This uses OpenRouter Models API and does not require an API key; unsupported payload parameters are blockers, not warnings.
Mirror Policy
.agents/skills/smm-openrouter/ is canonical. Do not hand-edit .claude/skills/smm-openrouter/ or .gemini/commands/skills/smm-openrouter.toml; run python3 scripts/harness_sync_runtimes.py --write --repo-only and then --check --repo-only.
Final Output
External output is the deliverable, not raw material for Codex synthesis. Preserve the report's variant text exactly. Codex may only remove secrets if a provider unexpectedly echoes them, add factual run metadata, run deterministic audit without rewrite, or ask the user whether they want a separate local editing pass.