sapiens-mcp 1.51.0 → 1.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/registry.js CHANGED
@@ -53,7 +53,7 @@ export const TOOLS = {
53
53
  handler: pipeline,
54
54
  },
55
55
  sapiens_image: {
56
- description: "Operações de imagem via Sapiens (Gemini, Azure gpt-image-2, Grok, Seedream/ByteDance, Veo). Sub-actions: 'generate' (gera imagem completa imediato — prompt+model+aspectRatio+size; suporta mode=edit/variation e MULTI-REFERÊNCIA: combine até 4 imagens como referência numa geração só, igual ao modal 'Selecionar Referência' do web — via referenceImageUrls (sua galeria + Acervo + personagens públicos de sapiens_character) e/ou sourceImageIds (ids da sua galeria); refs valem pros modelos robustos nano-banana-2/gpt-image-2-*/grok-2-image*/seedream-*), 'request_generation' (cria APENAS row pendente em generatedImages + debita créditos — pra modelos sapiens-video-* ANTES de sapiens_shorts/sapiens_video; whitelist, rate limit 3/min), 'compose' (combina persona+screen via Gemini pra app-demo Shorts; 25 sinapses, rate limit 10/min). generate=image one-shot, request_generation=criar row video, compose=montar start frame app-demo. TEMPLATE: passe templateSlug numa generate pra usar um super-prompt travado da casa — o `prompt` vira só a CENA (quem + pose + objeto-conceito) e o template embrulha estilo+fundo+enquadramento+ref de traço. 'retrato-sapiens-v1' = retrato editorial cartoon de um personagem no grid verde Sapiens (mesma 'mão' dos artigos); sem ref própria, injeta a Helen como âncora de traço (passar referenceImageUrls troca quem aparece). Mutuamente exclusivo com brandSlug. Sub-action 'models' (sem custo, sem login): lista o catálogo vivo (modelos ativos + preço atual com override admin + maxResolution + se aceita referência) pra descobrir modelo/preço em vez de chutar. NOTA: generate é SÍNCRONA e cobra ao concluir; modelo pesado (Pro, gpt-image-2-high, Grok quality, 2K/4K) cai na REGRA DO TIMEOUT (cheque sapiens_gallery action=list antes de repetir, evita cobrança dupla).",
56
+ description: "Operações de imagem via Sapiens (Gemini, Azure gpt-image-2, Grok, Seedream/ByteDance, Veo). Sub-actions: 'generate' (gera imagem completa imediato — prompt+model+aspectRatio+size; suporta mode=edit/variation e MULTI-REFERÊNCIA: combine até 4 imagens como referência numa geração só, igual ao modal 'Selecionar Referência' do web — via referenceImageUrls (sua galeria + Acervo + personagens públicos de sapiens_character) e/ou sourceImageIds (ids da sua galeria); refs valem pros modelos robustos nano-banana-2/gpt-image-2-*/grok-2-image*/seedream-*), 'request_generation' (cria APENAS row pendente em generatedImages + debita créditos — pra modelos sapiens-video-* ANTES de sapiens_shorts/sapiens_video; whitelist, rate limit 3/min), 'compose' (combina persona+screen via Gemini pra app-demo Shorts; 25 sinapses, rate limit 10/min). generate=image one-shot, request_generation=criar row video, compose=montar start frame app-demo. TEMPLATE: passe templateSlug numa generate pra usar um super-prompt travado da casa — o `prompt` vira só a CENA (quem + pose + objeto-conceito) e o template embrulha estilo+fundo+enquadramento+ref de traço. 'retrato-sapiens-v1' = retrato editorial cartoon de um personagem no grid verde Sapiens (mesma 'mão' dos artigos); sem ref própria, injeta a Helen como âncora de traço (passar referenceImageUrls troca quem aparece). Mutuamente exclusivo com brandSlug. Sub-action 'models' (sem custo, sem login): lista o catálogo vivo (modelos ativos + preço cobrado em 1K com override admin + resolutionAdders, o adder por resolução já clampado ao teto de cada motor + maxResolution + se aceita referência) pra descobrir modelo/preço em vez de chutar. O preço de uma geração é priceSinapses + resolutionAdders[size], então 2K/4K custam MAIS que o número base: nunca cite o base como se fosse o total quando o size não for 1K. NOTA: generate é SÍNCRONA e cobra ao concluir; modelo pesado (Pro, gpt-image-2-high, Grok quality, 2K/4K) cai na REGRA DO TIMEOUT (cheque sapiens_gallery action=list antes de repetir, evita cobrança dupla).",
57
57
  schema: imageSchema,
58
58
  handler: image,
59
59
  },
@@ -83,7 +83,7 @@ export const TOOLS = {
83
83
  handler: community,
84
84
  },
85
85
  sapiens_article: {
86
- description: "NÃO CRIA ARTIGO: este tool só mexe em artigo que JÁ existe. Pra criar draft novo do blog use sapiens_pipeline action=create_draft_article_and_source (devolve articleId + sourceId), ou sapiens_quote_pop pra quote e pop-article. Não confunda com sapiens_write, que é o espaço pessoal do membro em /u/<username> (tabela user_articles), e nunca salve o texto num .md solto no repo: draft de blog mora na tabela articles. CRUD do resto: get (by slug, retorna doc completo pra edit local), update (patch em title/excerpt/tldr/content/tags/etc + VISUAIS: thumbnailUrl capa webp, ogImageUrl JPEG do preview social, bodyImages array das ilustrações inline, conceptMap mapa visual, pra recapear um artigo num novo estilo; NÃO toca status/column/format), publish (status='published', set publishedAt), unpublish (volta pra draft), delete (irreversível), ensure_visuals (gera banner/ilustrações inline/conceptMap que faltam no artigo; idempotente, pula o que existe; ~1700 Sinapses num artigo pelado, forceBanner/forceInline/forceConceptMap regeram). ensure_visuals é ASSÍNCRONA: volta NA HORA com {status:'running', plan} e a leva corre no servidor, como o vídeo. NÃO repita a chamada pra ver se andou (cada leva gera e COBRA de novo, e as ilustrações somam) — acompanhe com visuals_status (custo 0) até jobStatus='done' ou 'error'. Quando não há nada faltando, ela responde na hora com status:'idle' e o retrato dos visuais, de graça: é a sonda pra saber o que o artigo já tem. Leva já em andamento devolve alreadyRunning:true em vez de abrir outra. visuals_status (custo 0) traz jobStatus (none/running/done/error/stale), o plano da leva, custo, erro e o estado real (hasBanner, inlineCount, hasConceptMap); 'stale' é leva que passou do teto de 10min do servidor sem fechar, ou seja, ninguém está mais gerando.",
86
+ description: "NÃO CRIA ARTIGO: este tool só mexe em artigo que JÁ existe. Pra criar draft novo do blog use sapiens_pipeline action=create_draft_article_and_source (devolve articleId + sourceId), ou sapiens_quote_pop pra quote e pop-article. Não confunda com sapiens_write, que é o espaço pessoal do membro em /u/<username> (tabela user_articles), e nunca salve o texto num .md solto no repo: draft de blog mora na tabela articles. CRUD do resto: get (by slug, retorna doc completo pra edit local), update (patch em title/excerpt/tldr/content/tags/etc + VISUAIS: thumbnailUrl capa webp, ogImageUrl JPEG do preview social, bodyImages array das ilustrações inline, conceptMap mapa visual, pra recapear um artigo num novo estilo; NÃO toca status/column/format), publish (status='published', set publishedAt), unpublish (volta pra draft), delete (irreversível), ensure_visuals (gera banner/ilustrações inline/conceptMap que faltam no artigo; idempotente, pula o que existe; ~2550 Sinapses num artigo pelado (capa 450 + 2 ilustracoes de 450 + mapa 1200; inlineCount=1 baixa pra ~2100), forceBanner/forceInline/forceConceptMap regeram). ensure_visuals é ASSÍNCRONA: volta NA HORA com {status:'running', plan} e a leva corre no servidor, como o vídeo. NÃO repita a chamada pra ver se andou (cada leva gera e COBRA de novo, e as ilustrações somam) — acompanhe com visuals_status (custo 0) até jobStatus='done' ou 'error'. Quando não há nada faltando, ela responde na hora com status:'idle' e o retrato dos visuais, de graça: é a sonda pra saber o que o artigo já tem. Leva já em andamento devolve alreadyRunning:true em vez de abrir outra. visuals_status (custo 0) traz jobStatus (none/running/done/error/stale), o plano da leva, custo, erro e o estado real (hasBanner, inlineCount, hasConceptMap); 'stale' é leva que passou do teto de 10min do servidor sem fechar, ou seja, ninguém está mais gerando.",
87
87
  schema: articleSchema,
88
88
  handler: article,
89
89
  },
@@ -103,7 +103,7 @@ export const TOOLS = {
103
103
  handler: search,
104
104
  },
105
105
  sapiens_studios: {
106
- description: "O SEU studio (o perfil de EMPRESA da casa do user) + o catálogo dos estúdios/experimentos Sapiens. Sub-actions: mine (o studio do user: nome/endereço público/marca/operador/tamanho do time), create (FUNDA um studio novo, exige name; nasce NO AR com endereço público, sem rascunho, de graça, teto de 4 por pessoa), list (catálogo com URL+status+tags+mcpReady), get (detalhe de 1 slug), publishable_url (formata URL /articles/<slug>). Use quando user pergunta 'que estúdios existem', 'qual o meu studio', ou diz 'quero abrir/fundar meu studio', 'criar a página da minha empresa'. Estúdios cobertos: helen-voice, musicator, persona-sapiens, personagem-atlas, sapiens-shorts, sapiens-video, text-post-builder, comic-builder, carrosel-editorial, comunidade, repertorio.",
106
+ description: "O SEU studio (o perfil de EMPRESA da casa do user) + o catálogo dos estúdios/experimentos Sapiens. Sub-actions: mine (o studio do user: nome/endereço público/marca/operador/tamanho do time), create (FUNDA um studio novo, exige name; nasce NO AR com endereço público, sem rascunho, de graça, teto de 4 por pessoa), list (catálogo com URL+status+tags+mcpReady), get (detalhe de 1 slug), publishable_url (formata URL /articles/<slug>). Use quando user pergunta 'que estúdios existem', 'qual o meu studio', ou diz 'quero abrir/fundar meu studio', 'criar a página da minha empresa'. Estúdios cobertos: helen-voice, musicator, persona-sapiens, personagem-atlas, sapiens-shorts, sapiens-video, text-post-builder, carrosel-editorial, comunidade, repertorio.",
107
107
  schema: studiosSchema,
108
108
  handler: studios,
109
109
  },
@@ -123,7 +123,7 @@ export const TOOLS = {
123
123
  handler: musicator,
124
124
  },
125
125
  sapiens_video: {
126
- description: "Sapiens Video — gera vídeo (qualquer membro logado; vídeo é caro, cobra as Sinapses da sua conta). Sub-action 'create' (recomendada): escolhe modelo + config e gera num call (cria a row + renderiza). Modelos: 'sapiens-video-seedance' (Seedance 2.0, cena+áudio nativo, 4-15s, 480/720/1080p, t2v/i2v; aceita até 4 imagens de REFERÊNCIA via referenceImageIds/referenceImageUrls/referenceImagePaths (os Veo fast/quality também aceitam, até 3; Lite/Kling/WAN/Omni não), que guiam estilo/personagem/composição SEM virar o 1º frame — é o fluxo STORYBOARD: gere a folha de key poses com sapiens_image templateSlug='storyboard-sapiens-v1', passe folha + personagem como refs num t2v e descreva o take contínuo no prompt, citando as refs por descrição e mandando ignorar o traço do sketch; aceita também 1 VÍDEO DE MOVIMENTO via referenceVideoUrls (role 'refvideo' -> reference_videos, <=15s, host da casa): a coreografia/câmera do clipe guia o take, combinável com a folha), 'sapiens-video-seedance-2-fast' e 'sapiens-video-seedance-2-mini' (os irmãos do 2.0: MESMO repertório completo, incluindo referência, frame final e vídeo de movimento; o Fast custa 20% menos e o Mini METADE, ambos com teto 720p — pedir 1080p neles entrega e cobra 720p. Use o Mini pra iterar enquadramento/prompt barato e feche no 'sapiens-video-seedance' quando o take estiver certo), 'sapiens-video-seedance-25' (Seedance 2.5, a geração SEGUINTE e não um quarto tier da 2.0: take de 4 a 30s num fôlego, edita e estende vídeo, mesmo repertório de referência mais ÁUDIO como referência; teto 720p e ~1,5x o preço por segundo do 2.0. Duração é o que pesa aqui: 30s em 720p passa de 40 mil Sinapses, então confirme a duração com a pessoa antes de disparar. Quem precisa de 1080p fica no 'sapiens-video-seedance'), 'sapiens-video-seedance-15' (Seedance 1.5 Pro: o degrau entre o 1.0 e a linha 2.x; t2v/i2v, 4-12s, 480/720/1080p, som sempre incluso sem toggle; imagem de referência e frame final ficam de fora por ora), 'sapiens-video-kling' (Kling 3.0 Pro, anima imagem, 3-15s, sound opcional, i2v/t2v), 'sapiens-video-hailuo' (Hailuo 2.3 da MiniMax, física e movimento em 768p, 6 ou 10s, t2v/i2v) e 'sapiens-video-hailuo-pro' (o mesmo em 1080p, 5s fixo — duração não é param aqui): motores PUROS, sem áudio nativo, sem imagens de referência e sem frame final, então quem precisa disso fica no Seedance 2.0; o Pro é o 1080p mais barato da casa depois do Seedance 1.0 Fast, 'sapiens-video-h3' (MiniMax H3: 2K com áudio nativo incluso sem toggle, 5 a 10s, t2v/i2v e frame final; não aceita imagem de referência), 'sapiens-video-wan' (WAN 2.5, imagem que fala/canta com áudio+lip-sync, 5/10s, i2v), 'sapiens-video-kling-motion' (Motion transfer: passa o movimento de um vídeo pra uma imagem, PRECISA de pessoa com tronco visível na imagem E no vídeo), 'sapiens-video-shot-mimic' (Shot Mimic: recria o plano/câmera/cortes de um vídeo de referência como cena nova), 'sapiens-video-omni' (Gemini Omni: texto vira vídeo 10s 720p com áudio nativo; NÃO aceita mídia do user, ignora references/durationSec/resolution; editOfImageId aponta um vídeo Omni seu e o prompt edita a MESMA cena, preservando câmera e ambiente), 'sapiens-video-lite/fast/quality' (Veo 3.1). Args create: model, prompt, durationSec, resolution ('480p'/'720p'/'1080p'), audio, aspectRatio. RECEITA DE TAKE (templateSlug + brief), o irmão do templateSlug da imagem: em vez de escrever o prompt inteiro, passe templateSlug e a receita travada da casa embrulha a cena com estilo, cenário, arco, áudio e look, e ainda escolhe o motor (por isso model fica opcional). O `prompt` vira só a CENA e o `brief` preenche os campos do formato (subject, persona, hook, shots com voiceLine e propVisible, uvps, language, energy); campo vazio some do prompt em vez de virar buraco. Receitas de hoje: 'ugc-vertical-v1' (selfie que fala, o formato nativo de Reels/TikTok/Shorts), 'unboxing-vertical-v1' (mãos e reveal, som real do papel e do lacre), 'app-demo-vertical-v1' (a tela do app legível na mão da pessoa) e 'reflexao-vertical-v1' (talking-head lento pra ideia ou ensaio). Override de model/aspectRatio/durationSec/resolution vale dentro do que a receita aceita, e o erro lista as opções. Sub-action 'templates' (sem custo, sem login) traz o catálogo vivo com spec default, whitelist e os briefFields de cada uma. Isto substitui a tool sapiens_shorts, que era admin-only e só falava Veo 3.1 Fast; o mesmo UGC de 8s sai a 720p no Seedance 2.0 Mini por bem menos. FRAME INICIAL/FINAL POR REFERÊNCIA (recomendado): startImageId/endImageId (id da sua galeria) ou startImageUrl/endImageUrl (url de galeria/Acervo/personagem) — resolvidos server-side igual à imagem, descubra via sapiens_reference. FRAME POR ARQUIVO LOCAL (só no MCP instalado/stdio, não no remoto): startImagePath/endImagePath = caminho absoluto de uma imagem no seu PC (PNG/JPEG/WebP até 8MB); o processo lê o arquivo e sobe como frame inicial/final, igual a subir no gerador do site — 1 imagem inicial + 1 final por vídeo, então pra vários vídeos rode create uma vez por imagem. No remoto use id/url. Alternativa base64: references (role 'start'=imagem i2v, 'end'=frame final, 'driving'=vídeo de movimento do Motion). Suporte a frame final varia por modelo. Custo server-side por config. Sub-action 'generate' (legado): renderiza um imageId de vídeo já criado no site. Retorna {success, url, imageId, cost}. VITRINE (sem custo): sub-action 'demos' lista os SEUS demo films (kind=demo do Estúdio de Vídeo) com slug + estado de vitrine; sub-action 'showcase' põe/tira um demo (por slug) do mini-cinema da /conectar-claude, com showcaseTag (chip de capacidade) e showcaseOrder (ordem asc). Fluxo: 'demos' pra achar o slug, depois 'showcase' com showcase=true. Só entra na vitrine pública se for a conta da casa. VÍDEOS PROGRAMÁTICOS (ADMIN, sem custo): o Lab do Estúdio de Vídeo (/experimentos/films, tabela videoSpecs, 5 kinds: demo | aula-tour | essay | tipografia-musical | dataviz) opera por aqui sem browser — 'film-list' (todos os kinds; filtros filmKind/filmStatus), 'film-get' (spec inteiro por slug), 'film-upsert' (cria/atualiza por slug, idempotente; spec = objeto JSON no shape do 'Copiar spec' da tela, validação no servidor), 'film-status' (produção por slug: filmStatus + videoUrl + durationSecMeasured; o fecho do render é os três num call), 'film-publish' (Acervo aba Fitas + portfólio; exige pronto+URL), 'film-delete' (limpar rascunho). O RENDER do filme segue no agente local (skill /film, repo da casa): o MCP registra e fecha o ciclo, não renderiza. create é ASSÍNCRONA: cria o row, debita e volta NA HORA com {imageId, status:'rendering', cost} (não espera o render, que leva de segundos a minutos). Acompanhe com a sub-action 'status' (imageId) até status='completed' (traz a url) ou 'error'/'blocked'. NÃO chame create de novo enquanto renderiza (cria outro vídeo e cobra de novo); falha de provider refunda sozinha. SOM: 'sonorize' (imageId de vídeo SEU completed + prompt do som da cena) gera uma VARIANTE nova com trilha sincronizada (20 Sinapses/s, o original fica intacto; sonorize sempre o original, nunca uma variante). ADMIN: 'shadows' (videoUrl + title) extrai o deepshadow (depth-map) de um vídeo: entra na sua timeline de vídeos e no Acervo como driving reutilizável; 'shadows-list' lista os deepshadows prontos. Sub-action 'models' (sem custo, sem login): lista os modelos de vídeo ativos + preço-piso + config (durações/resoluções) + disponibilidade (Omni depende de env). LEGENDA (fita, por slug): 'caption-list' (sem custo, mostra os idiomas que a peça já tem), 'caption-generate' (captionLang = idioma FALADO; captionTrio=true já traduz pro trio da casa pt+en+ja na mesma chamada) e 'caption-translate' (captionLang = destino, parte sempre da faixa original). Cobra por minuto começado de vídeo: 50 Sinapses o minuto transcrito, 20 o traduzido, com a duração vindo do doc da peça. A legenda é desenhada pela casa em dois estilos (discreta e social), trocáveis no play sem regerar e sem custo.",
126
+ description: "Sapiens Video — gera vídeo (qualquer membro logado; vídeo é caro, cobra as Sinapses da sua conta). Sub-action 'create' (recomendada): escolhe modelo + config e gera num call (cria a row + renderiza). Modelos: 'sapiens-video-seedance' (Seedance 2.0, cena+áudio nativo, 4-15s, 480/720/1080p, t2v/i2v; aceita até 4 imagens de REFERÊNCIA via referenceImageIds/referenceImageUrls/referenceImagePaths (os Veo fast/quality também aceitam, até 3; Lite/Kling/WAN/Omni não), que guiam estilo/personagem/composição SEM virar o 1º frame — é o fluxo STORYBOARD: gere a folha de key poses com sapiens_image templateSlug='storyboard-sapiens-v1', passe folha + personagem como refs num t2v e descreva o take contínuo no prompt, citando as refs por descrição e mandando ignorar o traço do sketch; aceita também 1 VÍDEO DE MOVIMENTO via referenceVideoUrls (role 'refvideo' -> reference_videos, <=15s, host da casa): a coreografia/câmera do clipe guia o take, combinável com a folha), 'sapiens-video-seedance-2-fast' e 'sapiens-video-seedance-2-mini' (os irmãos do 2.0: MESMO repertório completo, incluindo referência, frame final e vídeo de movimento; o Fast custa 20% menos e o Mini METADE, ambos com teto 720p — pedir 1080p neles entrega e cobra 720p. Use o Mini pra iterar enquadramento/prompt barato e feche no 'sapiens-video-seedance' quando o take estiver certo), 'sapiens-video-seedance-25' (Seedance 2.5, a geração SEGUINTE e não um quarto tier da 2.0: take de 4 a 30s num fôlego, edita e estende vídeo, mesmo repertório de referência mais ÁUDIO como referência; teto 720p e ~1,5x o preço por segundo do 2.0. Duração é o que pesa aqui: 30s em 720p passa de 40 mil Sinapses, então confirme a duração com a pessoa antes de disparar. Quem precisa de 1080p fica no 'sapiens-video-seedance'), 'sapiens-video-seedance-15' (Seedance 1.5 Pro: o degrau entre o 1.0 e a linha 2.x; t2v/i2v, 4-12s, 480/720/1080p, som sempre incluso sem toggle; imagem de referência e frame final ficam de fora por ora), 'sapiens-video-kling' (Kling 3.0 Pro, anima imagem, 3-15s, sound opcional, i2v/t2v), 'sapiens-video-hailuo' (Hailuo 2.3 da MiniMax, física e movimento em 768p, 6 ou 10s, t2v/i2v) e 'sapiens-video-hailuo-pro' (o mesmo em 1080p, 5s fixo — duração não é param aqui): motores PUROS, sem áudio nativo, sem imagens de referência e sem frame final, então quem precisa disso fica no Seedance 2.0; o Pro é o 1080p mais barato da casa depois do Seedance 1.0 Fast, 'sapiens-video-h3' (MiniMax H3: 2K com áudio nativo incluso sem toggle, 5 a 10s, t2v/i2v e frame final; não aceita imagem de referência), 'sapiens-video-wan' (WAN 2.5, imagem que fala/canta com áudio+lip-sync, 5/10s, i2v), 'sapiens-video-kling-motion' (Motion transfer: passa o movimento de um vídeo pra uma imagem, PRECISA de pessoa com tronco visível na imagem E no vídeo), 'sapiens-video-shot-mimic' (Shot Mimic: recria o plano/câmera/cortes de um vídeo de referência como cena nova), 'sapiens-video-omni' (Gemini Omni: texto vira vídeo 10s 720p com áudio nativo; NÃO aceita mídia do user, ignora references/durationSec/resolution; editOfImageId aponta um vídeo Omni seu e o prompt edita a MESMA cena, preservando câmera e ambiente), 'sapiens-video-lite/fast/quality' (Veo 3.1). Args create: model, prompt, durationSec, resolution ('480p'/'720p'/'1080p'), audio, aspectRatio. RECEITA DE TAKE (templateSlug + brief), o irmão do templateSlug da imagem: em vez de escrever o prompt inteiro, passe templateSlug e a receita travada da casa embrulha a cena com estilo, cenário, arco, áudio e look, e ainda escolhe o motor (por isso model fica opcional). O `prompt` vira só a CENA e o `brief` preenche os campos do formato (subject, persona, hook, shots com voiceLine e propVisible, uvps, language, energy); campo vazio some do prompt em vez de virar buraco. Receitas de hoje: 'ugc-vertical-v1' (selfie que fala, o formato nativo de Reels/TikTok/Shorts), 'unboxing-vertical-v1' (mãos e reveal, som real do papel e do lacre), 'app-demo-vertical-v1' (a tela do app legível na mão da pessoa) e 'reflexao-vertical-v1' (talking-head lento pra ideia ou ensaio). Override de model/aspectRatio/durationSec/resolution vale dentro do que a receita aceita, e o erro lista as opções. Sub-action 'templates' (sem custo, sem login) traz o catálogo vivo com spec default, whitelist e os briefFields de cada uma. Isto substitui a tool sapiens_shorts, que era admin-only e só falava Veo 3.1 Fast; o mesmo UGC de 8s sai a 720p no Seedance 2.0 Mini por bem menos. FRAME INICIAL/FINAL POR REFERÊNCIA (recomendado): startImageId/endImageId (id da sua galeria) ou startImageUrl/endImageUrl (url de galeria/Acervo/personagem) — resolvidos server-side igual à imagem, descubra via sapiens_reference. FRAME POR ARQUIVO LOCAL (só no MCP instalado/stdio, não no remoto): startImagePath/endImagePath = caminho absoluto de uma imagem no seu PC (PNG/JPEG/WebP até 8MB); o processo lê o arquivo e sobe como frame inicial/final, igual a subir no gerador do site — 1 imagem inicial + 1 final por vídeo, então pra vários vídeos rode create uma vez por imagem. No remoto use id/url. Alternativa base64: references (role 'start'=imagem i2v, 'end'=frame final, 'driving'=vídeo de movimento do Motion). Suporte a frame final varia por modelo. Custo server-side por config. Sub-action 'generate' (legado): renderiza um imageId de vídeo já criado no site. Retorna {success, url, imageId, cost}. VITRINE (sem custo): sub-action 'demos' lista os SEUS demo films (kind=demo do Estúdio de Vídeo) com slug + estado de vitrine; sub-action 'showcase' põe/tira um demo (por slug) do mini-cinema da /conectar-claude, com showcaseTag (chip de capacidade) e showcaseOrder (ordem asc). Fluxo: 'demos' pra achar o slug, depois 'showcase' com showcase=true. Só entra na vitrine pública se for a conta da casa. VÍDEOS PROGRAMÁTICOS (ADMIN, sem custo): o Lab do Estúdio de Vídeo (/experimentos/films, tabela videoSpecs, 5 kinds: demo | aula-tour | essay | tipografia-musical | dataviz) opera por aqui sem browser — 'film-list' (todos os kinds; filtros filmKind/filmStatus), 'film-get' (spec inteiro por slug), 'film-upsert' (cria/atualiza por slug, idempotente; spec = objeto JSON no shape do 'Copiar spec' da tela, validação no servidor), 'film-status' (produção por slug: filmStatus + videoUrl + durationSecMeasured; o fecho do render é os três num call), 'film-publish' (Acervo aba Fitas + portfólio; exige pronto+URL), 'film-delete' (limpar rascunho). O RENDER do filme segue no agente local (skill /film, repo da casa): o MCP registra e fecha o ciclo, não renderiza. create é ASSÍNCRONA: cria o row, debita e volta NA HORA com {imageId, status:'rendering', cost} (não espera o render, que leva de segundos a minutos). Acompanhe com a sub-action 'status' (imageId) até status='completed' (traz a url) ou 'error'/'blocked'. NÃO chame create de novo enquanto renderiza (cria outro vídeo e cobra de novo); falha de provider refunda sozinha. SOM: 'sonorize' (imageId de vídeo SEU completed + prompt do som da cena) gera uma VARIANTE nova com trilha sincronizada (20 Sinapses/s, o original fica intacto; sonorize sempre o original, nunca uma variante). ADMIN: 'shadows' (videoUrl + title) extrai o deepshadow (depth-map) de um vídeo: entra na sua timeline de vídeos e no Acervo como driving reutilizável; 'shadows-list' lista os deepshadows prontos. PREÇO DE VÍDEO É FAIXA, NÃO NÚMERO: nos motores por segundo (todo Seedance, Kling, WAN, Hailuo, H3, Shot Mimic) a conta é duração x resolução [x áudio], e OMITIR não pega o barato: sem 'resolution' o servidor cobra o tier MAIS CARO do motor, sem 'durationSec' cobra o piso de duração. Um create de Seedance 2.0 sem resolution debita 1080p. Nunca prometa um valor sem cotar: sub-action 'price' (sem custo, sem login) devolve o número EXATO que o create vai debitar pra model + durationSec + resolution + audio, e avisa (clamped=true) quando o que você pediu não é o que vai ser cobrado. Sub-action 'models' (sem custo, sem login): lista os modelos ativos + a faixa de preço calculada pela mesma função que debita (priceDefault = o que uma chamada sem config custa, priceMin e priceMax = os dois cantos do motor, cada um com a config que o produz) + config (durações/resoluções) + disponibilidade (Omni depende de env). LEGENDA (fita, por slug): 'caption-list' (sem custo, mostra os idiomas que a peça já tem), 'caption-generate' (captionLang = idioma FALADO; captionTrio=true já traduz pro trio da casa pt+en+ja na mesma chamada) e 'caption-translate' (captionLang = destino, parte sempre da faixa original). Cobra por minuto começado de vídeo: 50 Sinapses o minuto transcrito, 20 o traduzido, com a duração vindo do doc da peça. A legenda é desenhada pela casa em dois estilos (discreta e social), trocáveis no play sem regerar e sem custo.",
127
127
  schema: videoSchema,
128
128
  handler: video,
129
129
  },
@@ -218,26 +218,26 @@ export const TOOLS = {
218
218
  // É a "skill que anda junto com o pacote": escrevo uma vez, vale pra todos os clients,
219
219
  // sem instalar nada. Cobre os tropeços reais (fluxo do musicator, model no vídeo, o
220
220
  // disjuntor anti-loop). Mantém curto de propósito: viaja em todo handshake.
221
- export const SAPIENS_INSTRUCTIONS = `Você opera o Sapiens Sintéticos (sapiensinteticos.com) NA CONTA de um usuário logado. Cada tool age de verdade na conta dele e muitas COBRAM Sinapses (o crédito da casa). Aja como operador, não no chute.
222
-
223
- AS SKILLS DA CASA (leia ANTES de operar, não improvise o fluxo):
224
- O passo a passo travado de cada fluxo mora na tool sapiens_skill, servida por este mesmo servidor: sem login, sem custo, sem rede. Ler a skill é mais barato que errar uma geração que cobra.
225
- - sapiens_skill action=list -> o índice (slug + quando usar cada uma).
226
- - sapiens_skill action=get name=<slug> -> a skill inteira.
227
- Slugs: ${skillMenuLine()}
228
- Puxe a skill ANTES de: gerar música ou efeito sonoro (musica), escolher modelo de vídeo (video), gerar imagem (imagem), criar personagem ou prompt de Midjourney (personagem), criar na identidade do usuário (studio), montar tirinha (tirinha), postar no Fórum ou no chat (forum-comunidade), redigir qualquer texto publicável (voz-da-casa), incorporar o Sintético (companhia), missão de Desafio (trilhas), montar currículo (curriculo), guardar obra ou ferramenta no acervo (repertorio). Perdido no começo: primeiros-passos.
229
- Cliente que lê resources MCP acha o MESMO conteúdo em skill://sapiens/<slug>/SKILL.md.
230
-
231
- REGRA DE OURO:
232
- - PRIMEIRO CONTATO ou "o que você faz?"/"como começo?"/"o que dá pra fazer?": chame sapiens_meta action=start e MOSTRE o resultado na sua voz. Sem login, ele ensina a conectar; logado, traz saldo + primeiros poderes com exemplos. É a porta de entrada: não despeje a lista inteira de tools, deixe o start guiar.
233
- - LOGO APÓS UM LOGIN BEM-SUCEDIDO (action=login retornou ok): chame action=start na sequência e mostre a porta de entrada. O recém-chegado não sabe o que pedir; não o deixe na tela em branco, guie a primeira jogada sem ele precisar perguntar.
234
- - Antes de gerar algo caro (imagem/música/vídeo), cheque saldo: sapiens_meta action=credits (ou subscription). Saldo baixo, avise o usuário antes. Vídeo é o mais caro da casa: confirme com ele antes de disparar.
235
- - REGRA DO TIMEOUT: geração SÍNCRONA pode estourar o teto de ~120s do cliente e voltar 'Timeout' MESMO tendo gerado e COBRADO. Nunca repita às cegas: confira antes onde o resultado cairia (a tabela de onde conferir está na skill 'primeiros-passos').
236
- - "sessionToken expirado" = refaça login: sapiens_meta action=login com o código de sapiensinteticos.com/conectar-claude.
237
- - sapiens_meta action=formats devolve os schemas por formato; action=whoami diz tier (user/admin) + saldo. sapiens_image e sapiens_video action=models trazem o catálogo com o preço ATUAL: consulte em vez de chutar custo.
238
-
239
- MODO COMPANHIA: sapiens_meta action=start e action=whoami podem trazer um bloco 'companion'. Quando vier companion.active=true, você INCORPORA aquele Sintético (a voz dele, o avatar, o oi dele) continuando a operar na conta e nas Sinapses do USUÁRIO. Puxe a skill 'companhia' antes de fazer isso. Se vier 'characterOffer', siga o que ele manda: são personagens que o usuário escreveu e que podem entrar em cena, e quem OFERECE é você, na hora em que a conversa encostar num deles. Só personagem de autoria dele; a alma de personagem alheio não sai por aqui.
240
-
221
+ export const SAPIENS_INSTRUCTIONS = `Você opera o Sapiens Sintéticos (sapiensinteticos.com) NA CONTA de um usuário logado. Cada tool age de verdade na conta dele e muitas COBRAM Sinapses (o crédito da casa). Aja como operador, não no chute.
222
+
223
+ AS SKILLS DA CASA (leia ANTES de operar, não improvise o fluxo):
224
+ O passo a passo travado de cada fluxo mora na tool sapiens_skill, servida por este mesmo servidor: sem login, sem custo, sem rede. Ler a skill é mais barato que errar uma geração que cobra.
225
+ - sapiens_skill action=list -> o índice (slug + quando usar cada uma).
226
+ - sapiens_skill action=get name=<slug> -> a skill inteira.
227
+ Slugs: ${skillMenuLine()}
228
+ Puxe a skill ANTES de: gerar música ou efeito sonoro (musica), escolher modelo de vídeo (video), gerar imagem (imagem), criar personagem ou prompt de Midjourney (personagem), criar na identidade do usuário (studio), postar no Fórum ou no chat (forum-comunidade), redigir qualquer texto publicável (voz-da-casa), incorporar o Sintético (companhia), missão de Desafio (trilhas), montar currículo (curriculo), guardar obra ou ferramenta no acervo (repertorio). Perdido no começo: primeiros-passos.
229
+ Cliente que lê resources MCP acha o MESMO conteúdo em skill://sapiens/<slug>/SKILL.md.
230
+
231
+ REGRA DE OURO:
232
+ - PRIMEIRO CONTATO ou "o que você faz?"/"como começo?"/"o que dá pra fazer?": chame sapiens_meta action=start e MOSTRE o resultado na sua voz. Sem login, ele ensina a conectar; logado, traz saldo + primeiros poderes com exemplos. É a porta de entrada: não despeje a lista inteira de tools, deixe o start guiar.
233
+ - LOGO APÓS UM LOGIN BEM-SUCEDIDO (action=login retornou ok): chame action=start na sequência e mostre a porta de entrada. O recém-chegado não sabe o que pedir; não o deixe na tela em branco, guie a primeira jogada sem ele precisar perguntar.
234
+ - Antes de gerar algo caro (imagem/música/vídeo), cheque saldo: sapiens_meta action=credits (ou subscription). Saldo baixo, avise o usuário antes. Vídeo é o mais caro da casa: confirme com ele antes de disparar.
235
+ - REGRA DO TIMEOUT: geração SÍNCRONA pode estourar o teto de ~120s do cliente e voltar 'Timeout' MESMO tendo gerado e COBRADO. Nunca repita às cegas: confira antes onde o resultado cairia (a tabela de onde conferir está na skill 'primeiros-passos').
236
+ - "sessionToken expirado" = refaça login: sapiens_meta action=login com o código de sapiensinteticos.com/conectar-claude.
237
+ - sapiens_meta action=formats devolve os schemas por formato; action=whoami diz tier (user/admin) + saldo. sapiens_image e sapiens_video action=models trazem o catálogo com o preço ATUAL: consulte em vez de chutar custo.
238
+
239
+ MODO COMPANHIA: sapiens_meta action=start e action=whoami podem trazer um bloco 'companion'. Quando vier companion.active=true, você INCORPORA aquele Sintético (a voz dele, o avatar, o oi dele) continuando a operar na conta e nas Sinapses do USUÁRIO. Puxe a skill 'companhia' antes de fazer isso. Se vier 'characterOffer', siga o que ele manda: são personagens que o usuário escreveu e que podem entrar em cena, e quem OFERECE é você, na hora em que a conversa encostar num deles. Só personagem de autoria dele; a alma de personagem alheio não sai por aqui.
240
+
241
241
  Voz da casa: 1ª pessoa, direto, anti-corporate, sem travessão. Pra bom entendedor, meia palavra basta. Texto que vai ser publicado pede a skill 'voz-da-casa' antes.`;
242
242
  // Annotations MCP: título humano + dica read-only. São HINTS (não-confiáveis por
243
243
  // spec): quem gateia de verdade continua o servidor (saldo, gate de admin,
package/dist/skills.js CHANGED
@@ -204,7 +204,11 @@ Dar som a um vídeo SEU já pronto é \`sapiens_video action=sonorize\`, não é
204
204
 
205
205
  \`action=create\` EXIGE \`model\`. Sem model, falha de cara. Vídeo é o mais caro: confirme com a pessoa antes de disparar.
206
206
 
207
- \`action=models\` (sem custo, sem login) lista os modelos ativos com preço-piso, durações, resoluções e disponibilidade. Consulte em vez de chutar.
207
+ \`action=models\` (sem custo, sem login) lista os modelos ativos com durações, resoluções, disponibilidade e a FAIXA de preço: o padrão, o piso e o teto, cada um dizendo em qual configuração acontece. Motor de preço-por-segundo não tem "um preço": o mesmo modelo custa 3x mais em 1080p e 30s do que em 720p e 5s.
208
+
209
+ \`action=price\` (sem custo, sem login) cota a configuração EXATA antes de rodar: passe \`model\`, \`durationSec\`, \`resolution\` e \`audio\` e receba o número que vai ser debitado, calculado pela mesma função que cobra. Ela também avisa quando o motor não aceita o que você pediu e vai cobrar outra coisa (\`clamped\`), o que acontece quando a duração não existe no enum ou a resolução cai num tier diferente.
210
+
211
+ Use \`price\` sempre que a pessoa perguntar quanto custa, e ANTES de qualquer \`create\` que não seja o default. Dizer o piso como se fosse o preço final é o jeito mais rápido de queimar a confiança dela: a cobrança vem maior e a culpa é sua.
208
212
 
209
213
  ## Iterar barato, fechar caro
210
214
 
@@ -421,34 +425,6 @@ Pergunte qual, não adivinhe.
421
425
  Gente entra por convite, e o convite exige **follow mútuo**: os dois precisam já se seguir. Personagem do próprio elenco entra sem convite, é posse. Teto de 4 pessoas por casa.
422
426
 
423
427
  A obra da página é automática por default: a soma dos Destaques de quem está no time. Se alguém empurrar uma peça à mão, ela passa a ser curada. Tudo isso se faz na página, não por aqui.`,
424
- },
425
- {
426
- name: "tirinha",
427
- title: "Tirinha e quadrinho",
428
- description: "O fluxo de 2 fases da tirinha e a regra de ouro (a imagem sai SEM texto, a fala vai separada). Puxe ANTES de gerar qualquer quadrinho, assar a fala no prompt é o erro clássico.",
429
- body: `## Duas fases. Decida o modo antes de gerar pixel.
430
-
431
- ### Fase 1: roteiro
432
-
433
- Monte 3 a 6 painéis, cada um com a CENA visual e a FALA/legenda SEPARADAS. Salve em \`sapiens_pipeline action=create_production format=tirinha\`.
434
-
435
- O texto dos balões mora no payload (campos \`dialogue\` e \`caption\`), NUNCA dentro da imagem.
436
-
437
- ### Fase 2: imagem, escolha um dos modos
438
-
439
- **Modo A, tira inteira numa imagem só.** UMA chamada \`sapiens_image\` com prompt em grade: descreva "Painel 1 (cima-esquerda): ...; Painel 2 (cima-direita): ...", peça grade NxM com calhas brancas finas, e o MESMO personagem, estilo e luz em todos os quadros. Mais barato, estilo mais travado, menos controle quadro a quadro.
440
-
441
- **Modo B, painel a painel.** UMA \`sapiens_image\` por painel, com character-lock: passe o painel anterior e a ref da Helen em \`referenceImageUrls\`. Mais controle e consistência de enquadramento, custa N gerações.
442
-
443
- Pergunte à pessoa, ou decida pelo caso: tira curta de humor pede A, narrativa com continuidade pede B.
444
-
445
- ## A regra de ouro
446
-
447
- **A imagem sai SEM texto.** O estilo da casa é no-text e modelo de imagem erra letra.
448
-
449
- A fala vai SEPARADA, como legenda junto da imagem (por exemplo no Telegram: "Painel 1 · Helen: '...'"). Os balões editáveis e a diagramação final ficam no comic-builder do dashboard (/experimentos/comic-builder).
450
-
451
- Não tente assar a fala dentro do prompt. Nunca funciona.`,
452
428
  },
453
429
  {
454
430
  name: "forum-comunidade",
@@ -100,7 +100,7 @@ export const articleSchema = z.object({
100
100
  .min(1)
101
101
  .max(3)
102
102
  .optional()
103
- .describe("ensure_visuals: quantas ilustrações inline gerar (1-3). Default 1."),
103
+ .describe("ensure_visuals: quantas ilustrações inline gerar (1-3). Default 2 (cada uma custa ~450 Sinapses, então 1 economiza)."),
104
104
  // Classifica retroativamente como Educativo (Trilhas → Blog).
105
105
  educativeReference: z
106
106
  .object({
@@ -177,8 +177,10 @@ export async function article(args) {
177
177
  }
178
178
  case "ensure_visuals": {
179
179
  // Gera banner / inline / conceptMap que estiverem faltando.
180
- // Idempotente: pula o que já existe. Custo: ~1700 sinapses pra
181
- // artigo novo (450+450+800), só do que regerar pros que existem.
180
+ // Idempotente: pula o que já existe. Custo MEDIDO num artigo pelado
181
+ // (11/ago/2026): ~2550 Sinapses = capa 450 + 2 inlines de 450 + mapa
182
+ // 1200. Com inlineCount=1 cai pra ~2100. Artigo que já tem parte dos
183
+ // visuais paga só o que faltar.
182
184
  //
183
185
  // ASSÍNCRONO (ago/2026): volta na hora com o plano da leva, porque as
184
186
  // quatro gerações em sequência estouravam o teto de 120s do cliente em
@@ -4,35 +4,41 @@ import { convexAction, convexQuery, getSessionToken } from "../convexClient.js";
4
4
  // IDs canônicos do catálogo (apps/sapiens/convex/shared/imageModels.ts).
5
5
  // IDs fora dessa lista caem no fallback e o pricing vira 999. Sempre usar os
6
6
  // IDs canônicos.
7
+ //
8
+ // SEM PREÇO AQUI de propósito: esta lista já carregou o valor de cada motor em
9
+ // comentário, e os números ficaram anos-luz da fonte (o gpt-image-2-high dizia
10
+ // 800 quando o catálogo cobrava 1200, o nano-banana-max dizia 450 contra 900).
11
+ // Preço de imagem tem UMA fonte viva, `action=models`, que já traz o override
12
+ // admin e o adder de resolução clampado ao teto do motor.
7
13
  const MODELS = [
8
- "nano-banana-max", // gemini-3-pro-image-preview · 450 + adder
9
- "nano-banana-2", // gemini-3.1-flash-image-preview (V2, Flash 3.1) · 450 + adder · COM refs · DEFAULT
10
- "gpt-image-2-low", // Azure gpt-image-2 quality=low · 250
11
- "gpt-image-2-high", // Azure gpt-image-2 quality=high · 800
14
+ "nano-banana-max", // gemini-3-pro-image-preview · COM refs · adder até 4K
15
+ "nano-banana-2", // gemini-3.1-flash-image-preview (V2, Flash 3.1) · COM refs · adder até 4K · DEFAULT
16
+ "gpt-image-2-low", // Azure gpt-image-2 quality=low
17
+ "gpt-image-2-high", // Azure gpt-image-2 quality=high · o motor de texto legível
12
18
  // ByteDance via ModelArk direto. Corp/censurado, 2K nativo, COM refs (até 4).
13
19
  // (O "nova-canvas" ficava aqui e saiu: a AWS matou o modelo. Pedido antigo
14
20
  // ainda funciona, o backend faz o alias pro gpt-image-2-low.)
15
- "seedream-4-5", // Seedream 4.5 · 400 · cinematográfico
16
- "seedream-5-0", // Seedream 5.0, a geração nova · 400 · lê prompt complexo melhor
17
- "seedream-5-0-pro", // Seedream 5.0 Pro, topo da linha · 450 (roda no pacote pago)
21
+ "seedream-4-5", // Seedream 4.5 · cinematográfico
22
+ "seedream-5-0", // Seedream 5.0, a geração nova · lê prompt complexo melhor
23
+ "seedream-5-0-pro", // Seedream 5.0 Pro, topo da linha (roda no pacote pago)
18
24
  // xAI Grok Imagine. Moderação frouxa (+18), aceita refs (img2img) + aspect.
19
- "grok-2-image", // grok-imagine-image · 450 + adder 2K · COM refs
20
- "grok-2-image-quality", // grok-imagine-image-quality, mais fiel pra character lock · 900 + adder 2K · COM refs
25
+ "grok-2-image", // grok-imagine-image · COM refs · adder até 2K
26
+ "grok-2-image-quality", // grok-imagine-image-quality, mais fiel pra character lock · COM refs · adder até 2K
21
27
  // Degen (uncensored, gate +18 na galeria). WaveSpeed = rápido (6-25s):
22
- "wavespeed-chroma", // Chroma uncensored fotorrealista · 600
23
- "wavespeed-flux2", // Flux.2 Klein 9B · 600
24
- "wavespeed-flux-nsfw", // Flux dev + LoRA NSFW (AIDMA) · 600 · Ousadia regulável
25
- "wavespeed-klein-anime", // Flux.2 Klein + LoRA anime (inteligente + controlável) · 600
26
- "wavespeed-klein-anime-plus", // Klein Anime + SNOFS uncensored (+18) · 600 · Ousadia regulável
28
+ "wavespeed-chroma", // Chroma uncensored fotorrealista
29
+ "wavespeed-flux2", // Flux.2 Klein 9B
30
+ "wavespeed-flux-nsfw", // Flux dev + LoRA NSFW (AIDMA) · Ousadia regulável
31
+ "wavespeed-klein-anime", // Flux.2 Klein + LoRA anime (inteligente + controlável)
32
+ "wavespeed-klein-anime-plus", // Klein Anime + SNOFS uncensored (+18) · Ousadia regulável
27
33
  // Civitai (sdcpp, rápido). Família FLUX no Civitai saiu: lenta demais (>5min,
28
34
  // estoura o poll). Pra flux uncensored use wavespeed-flux-nsfw.
29
- "civitai-wai-illustrious", // anime Illustrious · 400
30
- "civitai-nova-anime-xl", // anime Illustrious · 400
31
- "civitai-pony-v6", // Pony Diffusion V6 XL, a base nº1 do Civitai · 400
35
+ "civitai-wai-illustrious", // anime Illustrious
36
+ "civitai-nova-anime-xl", // anime Illustrious
37
+ "civitai-pony-v6", // Pony Diffusion V6 XL, a base nº1 do Civitai
32
38
  // fal.ai (Krea-2 Turbo 12B + LoRA de realismo, ~4s). Grupo Degen (+18, checker
33
39
  // off). SEM referência: o endpoint krea-2/turbo/lora é text-to-image puro.
34
- "fal-krea2-realism", // Krea-2 + LoRA realismo (gokaygokay) · 600 · txt2img
35
- "fal-krea2-realism-v2", // Krea-2 + LoRA realismo alt (RudySen), pro A/B · 600 · txt2img
40
+ "fal-krea2-realism", // Krea-2 + LoRA realismo (gokaygokay) · txt2img
41
+ "fal-krea2-realism-v2", // Krea-2 + LoRA realismo alt (RudySen), pro A/B · txt2img
36
42
  ];
37
43
  export const imageSchema = z.object({
38
44
  action: z.enum(["generate", "request_generation", "compose", "models"]),
@@ -51,7 +57,7 @@ export const imageSchema = z.object({
51
57
  size: z
52
58
  .enum(["1K", "2K", "4K"])
53
59
  .optional()
54
- .describe("Default '1K'. Adder de resolução só nos modelos com hasResolutionAdder: nano-banana-max e nano-banana-2 aceitam 2K (+100) e 4K (+300); grok-2-image e grok-2-image-quality aceitam só 2K (+100), sem 4K. Nos demais modelos o size é ignorado (fica em 1K)."),
60
+ .describe("Default '1K'. Resolução acima de 1K SOMA um adder ao preço do modelo, e só nos modelos com hasResolutionAdder (nano-banana-max e nano-banana-2 vão até 4K; grok-2-image e grok-2-image-quality param em 2K, e pedir 4K neles entrega 2K e cobra o adder de 2K). Nos demais modelos o size é ignorado (fica em 1K). O valor VIVO do adder por modelo sai em action=models (campo resolutionAdders, já clampado ao teto do motor): não escreva o número de cabeça, ele muda quando o provider reajusta."),
55
61
  styleId: z
56
62
  .string()
57
63
  .optional()
@@ -136,7 +142,8 @@ export async function image(args) {
136
142
  count: models.length,
137
143
  default: "nano-banana-2",
138
144
  models,
139
- note: "priceSinapses é o base (1K); 2K/4K somam resolutionAdders quando o modelo tem teto pra isso. degen=+18 (gate na galeria). O preço já inclui override admin.",
145
+ note: "priceSinapses é o preço COBRADO em 1K (já com override admin). Acima de 1K some o adder de resolutionAdders[size], que vem clampado ao teto do motor: em modelo que para em 2K, a chave '4K' repete o valor de 2K porque é isso que a cobrança aplica quando você pede 4K nele. " +
146
+ "Preço final = priceSinapses + resolutionAdders[size]. degen=+18 (gate na galeria).",
140
147
  };
141
148
  }
142
149
  const sessionToken = getSessionToken();
@@ -86,23 +86,8 @@ const FORMAT_GUIDE = {
86
86
  ],
87
87
  },
88
88
  },
89
- tirinha: {
90
- description: "Tirinha/quadrinho em painéis (3-6). DOIS modos de imagem: 'strip' (tira inteira numa imagem só, 1 sapiens_image em grade) ou 'panels' (painel a painel, N sapiens_image com character-lock). A imagem SEMPRE sai sem texto; a fala/legenda vive no payload (dialogue/caption) e os balões finalizam no comic-builder do dashboard.",
91
- payloadHint: {
92
- title: "string",
93
- mode: "'strip' (tudo numa imagem) | 'panels' (uma imagem por painel)",
94
- layout: "string opcional pro modo strip: '2x2' | 'tira' (horizontal) | 'vertical'",
95
- panels: [
96
- {
97
- description: "string narrativo: a CENA visual do painel (vai pro prompt da imagem, SEM texto)",
98
- dialogue: "string opcional: a fala do balão (NÃO entra na imagem, é legenda)",
99
- caption: "string opcional: legenda de narração",
100
- imagePrompt: "string: prompt final do painel (full-bleed, no-text)",
101
- imageUrl: "string opcional (preenchido depois de gerar)",
102
- },
103
- ],
104
- },
105
- },
89
+ // tirinha saiu do guia em ago/2026: peça aposentada (format vive só como
90
+ // tolerância de validação pra productions antigas, ver pipeline.ts).
106
91
  musica: {
107
92
  description: "Faixa curta com letra + estilo + mood.",
108
93
  payloadHint: {
@@ -6,10 +6,8 @@ import { need } from "../schema.js";
6
6
  // lint: `npm run audit:mcp-format-parity` falha o CI se divergir. Ao adicionar
7
7
  // ou remover formato, mexa nos dois lados.
8
8
  const FORMATS = [
9
- "tirinha",
10
9
  "carrossel_ig",
11
10
  "post_social",
12
- "mega_grafico",
13
11
  "shorts_yt",
14
12
  "video_yt",
15
13
  "musica",
@@ -17,8 +15,19 @@ const FORMATS = [
17
15
  ];
18
16
  // Formatos legados: fora do FORMAT_GUIDE (não advertidos), mas ainda aceitos na
19
17
  // validação pra editar productions antigas sem quebrar. cena_visual ("Vídeo
20
- // Programático") saiu de linha em jul/2026: Films + gerador de vídeo cobrem o caso.
21
- const LEGACY_FORMATS = ["post_linkedin", "post_twitter", "post_threads", "cena_visual"];
18
+ // Programático") saiu de linha em jul/2026: Films + gerador de vídeo cobrem o
19
+ // caso. tirinha saiu de linha em ago/2026 (peça aposentada; as publicadas
20
+ // seguem de pé). mega_grafico saiu do picker web em ago/2026 mas o fluxo MCP
21
+ // segue vivo e ADVERTIDO (propose_mega_grafico_plan / run_mega_grafico_full
22
+ // criam a production no servidor; o formato aqui é só tolerância de validação).
23
+ const LEGACY_FORMATS = [
24
+ "post_linkedin",
25
+ "post_twitter",
26
+ "post_threads",
27
+ "cena_visual",
28
+ "tirinha",
29
+ "mega_grafico",
30
+ ];
22
31
  const ACCEPTED_FORMATS = [...FORMATS, ...LEGACY_FORMATS];
23
32
  const STATUSES = ["draft", "ready", "finalized"];
24
33
  export const pipelineSchema = z.object({
@@ -117,16 +117,8 @@ const STUDIOS = {
117
117
  mcpReady: true,
118
118
  mcpNote: "Parcialmente coberto via sapiens_pipeline format=post_social (texto Claude-side) + sapiens_image.",
119
119
  },
120
- "comic-builder": {
121
- name: "Comic Builder (Tirinhas)",
122
- description: "Estúdio oficial de tirinhas/quadrinhos. A IA roteiriza e gera os painéis de dois jeitos: painel a painel (controle fino) ou a tira inteira numa imagem só (estilo e lógica mais travados). Traço dos artigos como estilo base, Helen opcional, diagramação (2×2, tira, vertical) e histórico das tirinhas.",
123
- url: `${APP}/experimentos/comic-builder`,
124
- status: "stable",
125
- tags: ["tirinha", "tirinhas", "comic", "quadrinhos", "hq", "painel", "roteiro", "narrativa"],
126
- convex: "comicStrips",
127
- mcpReady: true,
128
- mcpNote: "Coberto via sapiens_pipeline format=tirinha (roteiro: cena + fala dos balões) + sapiens_image pra render. DOIS modos: MODO A tira inteira numa imagem só (1 sapiens_image em grade) ou MODO B painel a painel (N sapiens_image com character-lock por referência). Decida o modo antes de gerar. A imagem sai SEM texto (no-text da casa, modelo erra letra); a fala vai como legenda separada e os balões editáveis + diagramação + histórico finalizam no dashboard. Estúdio canônico de tirinha: não precisa freestyle de prompt.",
129
- },
120
+ // comic-builder (Tirinhas) saiu do roster em ago/2026: peça aposentada. As
121
+ // tirinhas publicadas seguem de pé (/tirinha/<id>, cards na Comunidade).
130
122
  "carrosel-editorial": {
131
123
  name: "Carrossel Editorial",
132
124
  description: "Gerador de carrossel Instagram com templates fixos (role × variant A/B/C), 9 slides Sapiens. Render via Playwright.",
@@ -11,6 +11,12 @@ import { httpUrl } from "../schema.js";
11
11
  * Com `templateSlug`, a RECEITA da casa embrulha a cena (estilo, arco,
12
12
  * áudio, look) e escolhe o motor: `prompt` vira só a cena e `brief`
13
13
  * preenche os campos do formato.
14
+ * - models: catálogo vivo dos motores ativos com a FAIXA de preço (o que uma
15
+ * chamada sem config debita + o canto mais barato e o mais caro).
16
+ * Sem custo, sem login.
17
+ * - price: cotação exata de uma config (model + durationSec/resolution/audio),
18
+ * calculada pela mesma função que debita. Sem custo, sem login. Use
19
+ * antes de create pra dizer o número certo pra pessoa.
14
20
  * - templates: catálogo das receitas de take (slug, spec default, whitelist de
15
21
  * override e os campos de brief que cada uma usa). Sem custo, sem login.
16
22
  * Comeu o antigo sapiens_shorts, que era admin-only e só falava Veo.
@@ -85,22 +91,27 @@ import { httpUrl } from "../schema.js";
85
91
  * - sapiens-video-shot-mimic Shot Mimic — recria o plano do vídeo de referência (câmera,
86
92
  * cortes, blocking) como cena nova; personagem via role 'start'
87
93
  * (vídeo de referência MÁX 15s — acima o provider corta em 15s)
88
- * - sapiens-video-lite/fast/quality Veo 3.1 (2000/5000/25000 sinapses)
94
+ * - sapiens-video-lite/fast/quality Veo 3.1 (preço fixo por clipe; o número vivo
95
+ * sai em action=models, campo priceDefault)
89
96
  * - sapiens-video-omni Gemini Omni — texto -> vídeo 10s 720p com áudio nativo embutido.
90
97
  * t2v + EDIÇÃO conversacional: `editOfImageId` aponta um vídeo Omni
91
98
  * seu e o prompt edita a MESMA cena (troca item/personagem preservando
92
99
  * o resto). Não aceita mídia do user (ignora references/durationSec/resolution).
93
100
  *
94
- * FORA DE PROPÓSITO: o `sapiens-video-seedance-fast` (Seedance 1.0 Fast, piso 600)
95
- * está ativo no catálogo do backend mas NÃO entra neste enum. Ele é geração velha:
96
- * sem áudio, sem referência e sem frame final. Economiza 200 sinapses no piso contra
97
- * o 1.5 Pro e perde três capacidades. Quem quer queimar tentativa barata usa o
101
+ * FORA DE PROPÓSITO: o `sapiens-video-seedance-fast` (Seedance 1.0 Fast) está ativo
102
+ * no catálogo do backend mas NÃO entra neste enum. Ele é geração velha: sem áudio,
103
+ * sem referência e sem frame final. Economiza pouco contra o 1.5 Pro e perde três
104
+ * capacidades. Quem quer queimar tentativa barata usa o
98
105
  * `sapiens-video-seedance-2-mini`, que custa metade do 2.0 com o repertório inteiro.
99
106
  * Não "conserte" essa ausência: ela é decisão (29/jul/2026).
100
107
  *
101
- * Custo: server-side por config (duração x resolução [x áudio]). i2v/motion usam
102
- * `references` em base64 (role 'start' = imagem inicial, 'end' = frame final,
103
- * 'driving' = vídeo de movimento do Motion).
108
+ * CUSTO: server-side por config (duração x resolução [x áudio]). NÃO existe "o preço"
109
+ * de um motor por segundo: existe faixa. Omitir `resolution` não pega o meio nem o
110
+ * mais barato, pega o tier MAIS CARO do motor (é o clamp de `resolveBilledVideoConfig`,
111
+ * que não subcobra), e omitir `durationSec` pega o piso de duração. Antes de prometer
112
+ * um número pra pessoa, tire a cotação em action=price (sem custo, sem login).
113
+ * i2v/motion usam `references` em base64 (role 'start' = imagem inicial,
114
+ * 'end' = frame final, 'driving' = vídeo de movimento do Motion).
104
115
  *
105
116
  * Retorna `{ success, url, imageId, cost }` ou `{ success: false, error }`.
106
117
  */
@@ -131,6 +142,7 @@ export const videoSchema = z.object({
131
142
  "generate",
132
143
  "status",
133
144
  "models",
145
+ "price",
134
146
  "templates",
135
147
  "demos",
136
148
  "showcase",
@@ -259,23 +271,25 @@ export const videoSchema = z.object({
259
271
  model: z
260
272
  .enum(VIDEO_MODELS)
261
273
  .optional()
262
- .describe("action=create: modelo de vídeo (opcional quando você passa templateSlug: a receita traz o motor). O catálogo POR MODELO (capacidades, referências, tetos, preço) mora na description desta tool e VIVO em action=models; a skill 'video' (sapiens_skill) guia a escolha. " +
274
+ .describe("action=create (opcional quando você passa templateSlug: a receita traz o motor) e action=price (obrigatório). O catálogo POR MODELO (capacidades, referências, tetos, FAIXA de preço) mora na description desta tool e VIVO em action=models; a skill 'video' (sapiens_skill) guia a escolha. " +
263
275
  "Atalho de famílias: seedance/seedance-2-*/seedance-25 = cena+áudio+referências (o 25 estica até 30s e o preço acompanha), seedance-15 = degrau 1.5, kling = anima imagem, wan = imagem que fala, " +
264
276
  "hailuo/hailuo-pro = movimento puro sem áudio, h3 = 2K com áudio, kling-motion/shot-mimic = transferência de movimento/plano, lite/fast/quality = Veo 3.1, omni = Gemini com áudio nativo."),
265
277
  durationSec: z
266
278
  .number()
267
279
  .optional()
268
- .describe("action=create: duração em segundos (Omni ignora). Seedance 2.0/Shot Mimic 4-15, Seedance 2.5 4-30 (o preço acompanha: confirme a duração com a pessoa antes de passar de 15), Seedance 1.5 4-12, Kling 3-15, WAN 5/10, H3 5/6/8/10. " +
269
- "Sem isso usa a config mais barata. O preço escala com a duração. " +
280
+ .describe("action=create e action=price: duração em segundos (Omni ignora). Seedance 2.0/Shot Mimic 4-15, Seedance 2.5 4-30 (o preço acompanha: confirme a duração com a pessoa antes de passar de 15), Seedance 1.5 4-12, Kling 3-15, WAN 5/10, H3 5/6/8/10. " +
281
+ "O PREÇO ESCALA COM A DURAÇÃO. Omitir não é 'a config padrão da casa': duração ausente, ou fora do leque do motor, cai no PISO de duração do motor. " +
270
282
  "action=shadows: duração do vídeo-fonte, se souber (cobra 200/s; sem ela, flat ~2000)."),
271
283
  resolution: z
272
284
  .enum(["480p", "720p", "1080p"])
273
285
  .optional()
274
- .describe("action=create: resolução (Seedance/WAN/Shot Mimic). Default 720p. Kling não usa (1080p nativo)."),
286
+ .describe("action=create e action=price: resolução (Seedance/WAN/Shot Mimic). NÃO existe default 720p aqui: resolução ausente, ou fora do que o motor aceita, cai no tier MAIS CARO do motor. " +
287
+ "É isso que faz um create sem este campo custar muito mais que o piso do catálogo (em sapiens-video-seedance vira 1080p, não 480p). Passe sempre a resolução que você quer pagar, e confira com action=price antes. " +
288
+ "Kling e a linha Hailuo/H3 não usam este campo (resolução fixa pelo motor)."),
275
289
  audio: z
276
290
  .boolean()
277
291
  .optional()
278
- .describe("action=create: liga áudio. Seedance = on por default; Kling 'sound' = +50%. WAN é áudio nativo sempre."),
292
+ .describe("action=create e action=price: liga áudio. Seedance = on por default; Kling 'sound' = +50% no preço. WAN é áudio nativo sempre."),
279
293
  editOfImageId: z
280
294
  .string()
281
295
  .optional()
@@ -447,9 +461,17 @@ export async function localFrameReferences(args) {
447
461
  return refs;
448
462
  }
449
463
  export async function video(args) {
450
- // models: catálogo VIVO dos modelos de vídeo (ativos + preço-piso/config +
451
- // override admin + disponibilidade). Público, sem custo e sem login — antes de
452
- // exigir sessão. Espelha sapiens_image action=models.
464
+ // models: catálogo VIVO dos modelos de vídeo (ativos + faixa de preço real +
465
+ // config + disponibilidade). Público, sem custo e sem login, antes de exigir
466
+ // sessão. Espelha sapiens_image action=models.
467
+ //
468
+ // A faixa vem calculada do servidor pela MESMA função que debita
469
+ // (resolveVideoCostSinapses). Até ago/2026 esta action entregava só o
470
+ // `basePriceSinapses`, que é o PISO do motor, e o agente do outro lado
471
+ // repassava esse número como se fosse o preço: em `sapiens-video-seedance` o
472
+ // piso é 1600 e um create sem resolução debita 9000, porque resolução ausente
473
+ // cai no tier mais caro. Piso sozinho vira promessa quebrada, então ele saiu
474
+ // do retorno e no lugar entrou o trio "sem config / mais barato / mais caro".
453
475
  if (args.action === "models") {
454
476
  const all = await convexQuery("videoModels:listWithOverrides", {});
455
477
  const models = (all ?? [])
@@ -458,7 +480,17 @@ export async function video(args) {
458
480
  id: m.id,
459
481
  engine: m.engine,
460
482
  label: m.label,
461
- basePriceSinapses: m.basePriceSinapses,
483
+ // "por-segundo" = o preço MUDA com duração, resolução e (no Kling) áudio.
484
+ // "por-clipe" = preço fixo, config não mexe na conta.
485
+ priceMode: m.priceMode ?? null,
486
+ // O que um create SEM durationSec/resolution debita hoje neste motor,
487
+ // com a config que esse preço paga de fato.
488
+ priceDefault: m.priceDefault ?? null,
489
+ // Os dois cantos do motor: a config mais barata e a mais cara possíveis.
490
+ priceMin: m.priceMin ?? null,
491
+ priceMax: m.priceMax ?? null,
492
+ // +50% no Kling quando o som liga; null = som já embutido no preço.
493
+ audioMultiplier: m.audioMultiplier ?? null,
462
494
  modes: m.modes,
463
495
  durationsSec: m.durationsSec,
464
496
  resolutions: m.resolutions,
@@ -471,7 +503,42 @@ export async function video(args) {
471
503
  count: models.length,
472
504
  default: "sapiens-video-seedance",
473
505
  models,
474
- note: "basePriceSinapses é o PISO (config mais barata, já com override admin); o preço real escala por duração x resolução [x áudio]. available=false = 'em breve' (depende de env, ex: Omni).",
506
+ note: "NÃO EXISTE 'o preço' de um motor de vídeo com priceMode='por-segundo': o custo é duração x resolução [x áudio], então o que existe é uma FAIXA. " +
507
+ "priceDefault.sinapses é o que um create SEM durationSec e SEM resolution debita hoje (o clamp da casa manda duração ausente pro piso e resolução ausente pro tier MAIS CARO, por isso ele costuma ser bem maior que priceMin). " +
508
+ "priceMin e priceMax são os dois cantos do motor, cada um com a config que o produz. " +
509
+ "Ao falar de preço com a pessoa, diga a faixa e a config, nunca um número solto. " +
510
+ "Pro número exato de uma config antes de gerar, use action=price (sem custo, sem login): ele devolve o valor que o create vai debitar. " +
511
+ "Motor com priceMode='por-clipe' (linha Veo, Omni) tem preço fixo e as três pontas são iguais. " +
512
+ "available=false = 'em breve' (depende de env, ex: Omni).",
513
+ };
514
+ }
515
+ // price: cotação EXATA de uma config, pela mesma função que debita. Sem custo
516
+ // e sem login, igual ao models: confirmar o preço é de graça, errar o take é
517
+ // que custa. É a porta pra dizer o número certo pra pessoa antes do create.
518
+ if (args.action === "price") {
519
+ if (!args.model) {
520
+ throw new Error("action=price exige model (o id do motor; a lista viva sai em action=models).");
521
+ }
522
+ const quote = await convexQuery("videoModels:priceQuote", {
523
+ model: args.model,
524
+ durationSec: args.durationSec,
525
+ resolution: args.resolution,
526
+ audio: args.audio,
527
+ });
528
+ // Três avisos possíveis, e a ordem importa: o clamp é o que mais surpreende
529
+ // (a conta vem diferente do pedido), depois o campo omitido (que o servidor
530
+ // preenche pelo lado CARO da régua) e por último o caso limpo.
531
+ const perSecond = quote?.priceMode === "por-segundo";
532
+ const omitiu = perSecond &&
533
+ (args.resolution === undefined || args.durationSec === undefined) &&
534
+ !quote?.clamped;
535
+ return {
536
+ ...quote,
537
+ note: quote?.clamped
538
+ ? "ATENÇÃO: a config cobrada (billed) não é a que você pediu (asked). Duração fora do leque do motor cai no piso e resolução inválida cai no tier MAIS CARO, e é esse valor clampado que o create vai debitar e mandar pro provider. Ajuste o pedido pra um valor que o motor aceita (veja durationsSec/resolutions em action=models)."
539
+ : omitiu
540
+ ? "Você não passou durationSec e/ou resolution, então o servidor preencheu (billed mostra o quê): duração ausente vira o piso, resolução ausente vira o tier MAIS CARO do motor. O valor em sinapses já é o desse preenchimento, e é o que o create vai debitar se você chamar do mesmo jeito. Passe os dois campos pra pagar o que você escolheu."
541
+ : "sinapses é o valor que o create vai debitar com exatamente essa config. Confirme com a pessoa antes de gerar.",
475
542
  };
476
543
  }
477
544
  // templates: catálogo VIVO das receitas de take (estilo + spec + os campos de
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapiens-mcp",
3
- "version": "1.51.0",
3
+ "version": "1.52.0",
4
4
  "mcpName": "com.sapiensinteticos/sapiens",
5
5
  "description": "MCP server pra operar o Sapiens Sintéticos (sapiensinteticos.com) pelo Claude Code: gerar imagem, escrever artigo, voz, música e mais, na sua conta. Login pelo código de sapiensinteticos.com/conectar-claude.",
6
6
  "type": "module",