sapiens-mcp 1.67.1 → 1.68.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 +1 -1
- package/dist/skills.js +2 -1
- package/dist/tools/character.js +22 -0
- package/dist/tools/image.js +36 -18
- package/package.json +1 -1
package/dist/registry.js
CHANGED
|
@@ -146,7 +146,7 @@ export const TOOLS = {
|
|
|
146
146
|
handler: brand,
|
|
147
147
|
},
|
|
148
148
|
sapiens_character: {
|
|
149
|
-
description: "Personagens (character sheets) do Sapiens — a tabela `influencers`: personagem reutilizável com imagens (pra character-lock em geração) + alma (systemPrompt), tudo amarrado à conta do dono do token (sem admin). Sub-actions: list_public (catálogo global de personagens públicos do Explorar; cada um traz mainImageUrl/imageUrls usáveis direto como referenceImageUrls em sapiens_image; sem custo, sem login), get (detalhe de 1 por characterId — público+ativo qualquer um vê, draft/privado só o dono; systemPrompt só volta pro dono), list_mine (os personagens do próprio user, inclui drafts/privados), create (cria rascunho na conta: name + gender + opcional form/title/systemPrompt), add_image (adiciona imagem ao próprio personagem via imageUrl público OU sourceImageId da galeria; 1ª vira principal), set_card (edita alma/título/lema em inglês/nome/nome por extenso/forma do próprio), set_presence (escreve onde o personagem existe FORA da casa: redes sociais por handle, Fanvue, site e o email dele, este último privado), set_passport (escreve o PASSAPORTE dele: como ACERTAR este ser, que é outra coisa de quem ele é. Guarda o `descriptor` de geração em inglês pra colar verbatim, o `negative` travado que fica sempre ligado, os `locks` (o que TRAVA nele, um por entrada, que é a lista que vira as perguntas da conferência), as `refs` por PAPEL (proporção, rosto, tatuagem: ref sem papel ninguém sabe usar), as `recipes` medidas por tipo de peça (com o prompt VERBATIM, porque o valor está na palavra exata que funcionou) e o `discarded`, o que já foi recusado. Esse último não é enfeite: o motor traz de volta o que ninguém proibiu, então ideia descartada sem negativo escrito volta sozinha na leva seguinte. É MERGE por campo, então mandar só o negative não apaga o descritor, e campo vazio apaga. Só o DONO lê: receita de produção não sai em personagem público. Em action=get ele volta em duas formas, `passport` (campo a campo, o que se reedita) e `passportPrompt` (o bloco já montado pra colar). Preencha sempre que uma rodada medir algo que a próxima não deve redescobrir: é o que faz a receita viajar pra fora do repo), activate (tira do rascunho e libera o personagem pra USAR nas gerações do dono; exige ≥1 imagem. NÃO torna público: quem publica é set_visibility, e ativar é gesto reversível e privado), set_visibility (isPublic true=Explorar+slug / false=privado). GESTÃO de imagem (por url, pegue as urls atuais em action=get campo imageUrls): remove_image (tira uma), set_main_image (define a principal), reorder_images (nova ordem via orderedUrls, posição 0=principal), e delete (apaga o personagem, permanente). FORMA (`form`, o que tipo de CORPO ele tem: human default, humanoid, animal (bicho real), creature (ser inventado), object, abstract): não é enfeite de cadastro, é o que a ficha, as figurinhas e o vídeo leem pra decidir se descrevem rosto e mãos ou silhueta e postura, e é ele que impede uma criatura de voltar desenhada como pessoa. Mande no create sempre que o personagem não for gente; personagem que já existe sem ele conserta com set_card form=creature. Ausente = human, que é o que a casa desenhava antes do campo existir. NOME E NOME POR EXTENSO (`name` e `fullName`): `name` é como o personagem é CHAMADO e é o que toda tela desenha; `fullName` é o nome inteiro, pra quem tem apelido ('Crow Girl' na tela, 'Kaia Crowe' por extenso). Um não substitui o outro, e o extenso não mexe no slug da página nem no cartão de nome do vídeo: batizar personagem que já existe não muda endereço publicado nem assinatura de peça que já saiu. Vem em action=get e list_mine no campo `fullName` (null = ainda sem nome por extenso). TRAÇO (`style`, em que TÉCNICA ele é feito: auto default, realista, anime, manhwa, 3d, custom): irmão da forma, e a divisão é limpa, a forma diz que CORPO é esse e o traço diz como ele é DESENHADO. As mesmas três peças leem daqui. No 'auto' a peça não afirma técnica nenhuma e as imagens de referência mandam; 'realista' é fotografia, 'anime' é cel shading com contorno de tinta, 'manhwa' é pintura de webtoon, '3d' é render com material e oclusão, 'custom' usa a linha escrita em `styleNote` (até 140 caracteres, ex: aquarela sobre papel texturizado). Mande sempre que o personagem tiver técnica definida: até ago/2026 a ficha cravava vocabulário de desenho e devolvia personagem fotográfico virado em ilustração. Conserto sem custo em quem já existe: set_card style=realista. PRESENÇA (set_presence, de graça): o ENDEREÇO do personagem, o que faltava pra ele existir fora da ficha. `socials` é {rede: handle} nas redes instagram, tiktok, youtube, x, threads, bluesky, twitch, spotify, fanvue, patreon, onlyfans, telegram; `websiteUrl` é o site dele e `email` é o email do personagem, o que cadastra e recupera as contas dele nas redes. As redes e o site são PÚBLICOS; o email é PRIVADO e fica só com o dono, mesmo com o personagem publicado, porque email é chave de conta e isca de spam, não canal de contato. Em action=get e list_public de personagem de OUTRA pessoa, o campo simplesmente não vem. É MERGE: mandar {fanvue:'helen'} não apaga o instagram, e pra apagar uma rede se manda ela vazia. O que volta em action=get são as duas formas, `presence` (o handle cru, que é o que se reedita) e `presenceLinks` (o link já montado, pra mostrar sem remontar URL na mão). Vale a pena preencher quando o personagem TEM conta de verdade: é o que separa uma ficha de um ser com endereço, e a página pública dele desenha as redes e o site (nunca o email). FICHA (generate_sheet, COBRA 450 Sinapses): desenha a página-pôster do personagem no traço das imagens que ele já tem (exige pelo menos uma), em duas orientações (arg `orientation`): 'portrait' (default) é a página de processo, pose, expressões, trocas de roupa e adereços soltos na folha; 'landscape' é a prancha larga, com a volta completa à esquerda, a figura grande no meio, poses à direita, estudos de silhueta, expressão e detalhe embaixo e um painel CHARACTER ID na ponta. A personalidade sai da alma (systemPrompt) e é ela que escolhe roupa e objeto, então personagem com alma escrita rende ficha melhor. Cada geração é um estilo NOVO e elas acumulam no personagem (campo sheetUrls em action=get), nenhuma apaga a anterior, e a ficha já entra na galeria dele como referência das próximas gerações. É geração síncrona: se voltar Timeout, cheque action=get antes de repetir, senão cobra duas vezes. STICKERS (generate_stickers, COBRA 550 Sinapses): desenha 5 stickers do personagem DE UMA VEZ. Uma folha só, em 2K, com as cinco figuras separadas sobre um fundo verde chroma, recortada por código em peças 512x512 transparentes abaixo de 100KB (o teto do WhatsApp). É por isso que sai o preço de UMA imagem em 2K e não de cinco: quem paga é a folha. As peças entram no pack do personagem (um por personagem, os lotes acumulam) e já ficam no picker de expressão do dono, no chat e no Fórum. Arg `moods`: até 5 humores do vocabulário comum por slug (kkkkk, amei, isso, hmm, chega, que, aff, bora, socorro, seinao, valeu, ainao, seila, ideia, calma, contatudo, perfeito, euavisei, naovourir, zzz, somaisum, sextou, merecido, quedia, tudobem); faltando, a casa completa com os mais usados. Arg `hint`: direcionamento curto do autor (roupa, adereço, clima), até 140 caracteres. Arg `stickerTier`: 'folha' (default) é esse lote de cinco, desenhado no Gemini 3.1 Flash; 'unica' (COBRA 900 Sinapses) desenha UM sticker por vez no Gemini 3 Pro, o motor mais fiel da casa, com a figura sozinha no quadro e o dobro de pixel por peça, e leva só o PRIMEIRO mood da lista. Pra encher o pack, folha; pra traço difícil ou a reação que vira a cara do personagem, a unica. Ao oferecer a escolha, diga o NOME DO MOTOR e o que ele troca: adjetivo vago de acabamento não informa nada a quem vai pagar. Os dois caem no MESMO pack e acumulam. Sem legenda queimada na imagem, de propósito: modelo erra acento em português, então o rótulo fica na row e serve de busca no picker. Exige pelo menos uma imagem no personagem (é dela que sai a cara) e é geração síncrona: se voltar Timeout, cheque sapiens_gallery antes de repetir. Quando a resposta vem com ok=false, a folha foi gerada e paga mas o corte falhou; ela está na galeria e o recorte de novo é de graça, pela web. Publicar o pack na vitrine e o carimbo da casa (que é o que põe no picker de todo mundo) são gestos da web, não desta tool. CHARACTER VIDEO (a ficha que anda): o personagem atravessa 6 mundos em 12s, trocando de roupa em cada um, com som gerado junto, e o último plano fecha a peça com ele parando e encarando a câmera. A peça volta FECHADA pelas duas portas (tela e agente), sem ninguém pedir: o personagem se apresenta no cartão de nome por cima do fim do último plano, com o LEMA em inglês embaixo (o campo `titleEn`, escrito uma vez em set_card), e só depois a casa assina. Quem não tem lema recebe o subtítulo que o roteiro inventou naquele take, e ele muda no take seguinte. O fecho é asset, não geração: zero Sinapse a mais, e é fail-open, então a resposta traz `closed` e `nameCard` dizendo o que entrou de verdade em vez de prometer um cartão que não está no arquivo. Pra colocar esse cartão num vídeo que JÁ existe, o caminho é a ficha do take na web (gaveta do fecho, 'Apresentação do personagem'), também sem custo. Exige FICHA gerada (é dela que saem a cara e o guarda-roupa), não só imagem. Duas actions, nesta ordem: plan_video (COBRA 50 Sinapses) devolve os 6 planos que a alma do personagem escolheu, com ambiente, ato, enquadramento e roupa. Cada plano vem nas duas línguas: em inglês (setting/act/wardrobe, que é o que vai pro motor) e em português (settingPt/actPt/wardrobePt). MOSTRE a versão em português pro autor, o público da casa é brasileiro e roteiro que ele lê de través não é roteiro aprovado; peça de novo quantas vezes ele quiser, porque trocar sai por 50 e o take errado sai por milhares. replan_shot (COBRA 15 Sinapses) reescreve UM plano e não toca nos outros cinco: os seis são cenas independentes, então quando o autor gosta de quatro e implica com um, troque só aquele em vez de sortear tudo de novo (mande os 6 planos em `shots`, o número em `shotIndex`, e o que ele quer diferente em `shotHint`; volta só o plano trocado, e é você que remonta o roteiro). Depois generate_video (COBRA) renderiza, com os planos aprovados no arg `shots` e o MOTOR no arg `videoTier`: 'draft' (5.400 Sinapses) é o Seedance 2.0 Mini, metade do preço, que tropeça em mão, pouca luz e câmera rápida, e 'final' (8.640 Sinapses) é o Seedance 2.0 Fast, que segura o que o Mini erra. A peça é a MESMA nos dois (mesmos 6 planos, 12s, 720p, com som), então ofereça pelo nome do motor e pelo que ele troca, nunca por adjetivo vago de acabamento. Vertical ou horizontal pelo arg `orientation`. Chamar generate_video SEM `shots` funciona, mas escreve um roteiro novo às cegas e cobra igual: não faça isso sem o autor ter visto o que vai receber. É geração demorada: se voltar Timeout, cheque sapiens_gallery antes de repetir. Resposta com `pending: true` (sem `url`) quer dizer ACEITO E COBRADO: o servidor continua renderizando sozinho (até 25 min) e a peça chega na ficha já fechada; NÃO repita a chamada, isso cobraria de novo, confira depois em sapiens_gallery. Fluxo de criação: create → add_image (1+) → set_card (opcional) → activate. PARE AÍ. O personagem nasce e continua PRIVADO, e é assim que ele serve pro dono: dá pra gerar, referenciar e iterar sem ninguém ver. set_visibility isPublic=true é o gesto de PUBLICAR no Explorar, com slug público, e nÃO é passo de fluxo: só chame quando o dono pedir pra publicar aquele personagem, com essas palavras. Na dúvida, não publique e pergunte. Pra usar um personagem público como referência numa geração, pegue mainImageUrl em list_public/get e passe em sapiens_image referenceImageUrls.",
|
|
149
|
+
description: "Personagens (character sheets) do Sapiens — a tabela `influencers`: personagem reutilizável com imagens (pra character-lock em geração) + alma (systemPrompt), tudo amarrado à conta do dono do token (sem admin). Sub-actions: list_public (catálogo global de personagens públicos do Explorar; cada um traz mainImageUrl/imageUrls usáveis direto como referenceImageUrls em sapiens_image; sem custo, sem login), get (detalhe de 1 por characterId — público+ativo qualquer um vê, draft/privado só o dono; systemPrompt só volta pro dono), list_mine (os personagens do próprio user, inclui drafts/privados), create (cria rascunho na conta: name + gender + opcional form/title/systemPrompt), add_image (adiciona imagem ao próprio personagem via imageUrl público OU sourceImageId da galeria; 1ª vira principal), set_card (edita alma/título/lema em inglês/nome/nome por extenso/forma do próprio), set_presence (escreve onde o personagem existe FORA da casa: redes sociais por handle, Fanvue, site e o email dele, este último privado), set_passport (escreve o PASSAPORTE dele: como ACERTAR este ser, que é outra coisa de quem ele é. Guarda o `descriptor` de geração em inglês pra colar verbatim, o `negative` travado que fica sempre ligado, os `locks` (o que TRAVA nele, um por entrada, que é a lista que vira as perguntas da conferência), as `refs` por PAPEL (proporção, rosto, tatuagem: ref sem papel ninguém sabe usar), as `recipes` medidas por tipo de peça (com o prompt VERBATIM, porque o valor está na palavra exata que funcionou) e o `discarded`, o que já foi recusado. Esse último não é enfeite: o motor traz de volta o que ninguém proibiu, então ideia descartada sem negativo escrito volta sozinha na leva seguinte. É MERGE por campo, então mandar só o negative não apaga o descritor, e campo vazio apaga. Só o DONO lê: receita de produção não sai em personagem público. Em action=get ele volta em duas formas, `passport` (campo a campo, o que se reedita) e `passportPrompt` (o bloco já montado pra colar). Preencha sempre que uma rodada medir algo que a próxima não deve redescobrir: é o que faz a receita viajar pra fora do repo), activate (tira do rascunho e libera o personagem pra USAR nas gerações do dono; exige ≥1 imagem. NÃO torna público: quem publica é set_visibility, e ativar é gesto reversível e privado), set_visibility (isPublic true=Explorar+slug / false=privado), set_hidden (hidden true tira o personagem da TELA do dono: some da lista de personagens e as peças geradas com ele saem da galeria de fotos, vídeos e rascunhos do dono, voltando pelo filtro Ocultos; hidden false devolve. É o gesto de quem vai compartilhar tela. Não despublica, não apaga, não sai dos seletores de geração, e personagem oculto não publica até ser mostrado. Grátis. O list_mine traz `hidden` em cada personagem). GESTÃO de imagem (por url, pegue as urls atuais em action=get campo imageUrls): remove_image (tira uma), set_main_image (define a principal), reorder_images (nova ordem via orderedUrls, posição 0=principal), e delete (apaga o personagem, permanente). FORMA (`form`, o que tipo de CORPO ele tem: human default, humanoid, animal (bicho real), creature (ser inventado), object, abstract): não é enfeite de cadastro, é o que a ficha, as figurinhas e o vídeo leem pra decidir se descrevem rosto e mãos ou silhueta e postura, e é ele que impede uma criatura de voltar desenhada como pessoa. Mande no create sempre que o personagem não for gente; personagem que já existe sem ele conserta com set_card form=creature. Ausente = human, que é o que a casa desenhava antes do campo existir. NOME E NOME POR EXTENSO (`name` e `fullName`): `name` é como o personagem é CHAMADO e é o que toda tela desenha; `fullName` é o nome inteiro, pra quem tem apelido ('Crow Girl' na tela, 'Kaia Crowe' por extenso). Um não substitui o outro, e o extenso não mexe no slug da página nem no cartão de nome do vídeo: batizar personagem que já existe não muda endereço publicado nem assinatura de peça que já saiu. Vem em action=get e list_mine no campo `fullName` (null = ainda sem nome por extenso). TRAÇO (`style`, em que TÉCNICA ele é feito: auto default, realista, anime, manhwa, 3d, custom): irmão da forma, e a divisão é limpa, a forma diz que CORPO é esse e o traço diz como ele é DESENHADO. As mesmas três peças leem daqui. No 'auto' a peça não afirma técnica nenhuma e as imagens de referência mandam; 'realista' é fotografia, 'anime' é cel shading com contorno de tinta, 'manhwa' é pintura de webtoon, '3d' é render com material e oclusão, 'custom' usa a linha escrita em `styleNote` (até 140 caracteres, ex: aquarela sobre papel texturizado). Mande sempre que o personagem tiver técnica definida: até ago/2026 a ficha cravava vocabulário de desenho e devolvia personagem fotográfico virado em ilustração. Conserto sem custo em quem já existe: set_card style=realista. PRESENÇA (set_presence, de graça): o ENDEREÇO do personagem, o que faltava pra ele existir fora da ficha. `socials` é {rede: handle} nas redes instagram, tiktok, youtube, x, threads, bluesky, twitch, spotify, fanvue, patreon, onlyfans, telegram; `websiteUrl` é o site dele e `email` é o email do personagem, o que cadastra e recupera as contas dele nas redes. As redes e o site são PÚBLICOS; o email é PRIVADO e fica só com o dono, mesmo com o personagem publicado, porque email é chave de conta e isca de spam, não canal de contato. Em action=get e list_public de personagem de OUTRA pessoa, o campo simplesmente não vem. É MERGE: mandar {fanvue:'helen'} não apaga o instagram, e pra apagar uma rede se manda ela vazia. O que volta em action=get são as duas formas, `presence` (o handle cru, que é o que se reedita) e `presenceLinks` (o link já montado, pra mostrar sem remontar URL na mão). Vale a pena preencher quando o personagem TEM conta de verdade: é o que separa uma ficha de um ser com endereço, e a página pública dele desenha as redes e o site (nunca o email). FICHA (generate_sheet, COBRA 450 Sinapses): desenha a página-pôster do personagem no traço das imagens que ele já tem (exige pelo menos uma), em duas orientações (arg `orientation`): 'portrait' (default) é a página de processo, pose, expressões, trocas de roupa e adereços soltos na folha; 'landscape' é a prancha larga, com a volta completa à esquerda, a figura grande no meio, poses à direita, estudos de silhueta, expressão e detalhe embaixo e um painel CHARACTER ID na ponta. A personalidade sai da alma (systemPrompt) e é ela que escolhe roupa e objeto, então personagem com alma escrita rende ficha melhor. Cada geração é um estilo NOVO e elas acumulam no personagem (campo sheetUrls em action=get), nenhuma apaga a anterior, e a ficha já entra na galeria dele como referência das próximas gerações. É geração síncrona: se voltar Timeout, cheque action=get antes de repetir, senão cobra duas vezes. STICKERS (generate_stickers, COBRA 550 Sinapses): desenha 5 stickers do personagem DE UMA VEZ. Uma folha só, em 2K, com as cinco figuras separadas sobre um fundo verde chroma, recortada por código em peças 512x512 transparentes abaixo de 100KB (o teto do WhatsApp). É por isso que sai o preço de UMA imagem em 2K e não de cinco: quem paga é a folha. As peças entram no pack do personagem (um por personagem, os lotes acumulam) e já ficam no picker de expressão do dono, no chat e no Fórum. Arg `moods`: até 5 humores do vocabulário comum por slug (kkkkk, amei, isso, hmm, chega, que, aff, bora, socorro, seinao, valeu, ainao, seila, ideia, calma, contatudo, perfeito, euavisei, naovourir, zzz, somaisum, sextou, merecido, quedia, tudobem); faltando, a casa completa com os mais usados. Arg `hint`: direcionamento curto do autor (roupa, adereço, clima), até 140 caracteres. Arg `stickerTier`: 'folha' (default) é esse lote de cinco, desenhado no Gemini 3.1 Flash; 'unica' (COBRA 900 Sinapses) desenha UM sticker por vez no Gemini 3 Pro, o motor mais fiel da casa, com a figura sozinha no quadro e o dobro de pixel por peça, e leva só o PRIMEIRO mood da lista. Pra encher o pack, folha; pra traço difícil ou a reação que vira a cara do personagem, a unica. Ao oferecer a escolha, diga o NOME DO MOTOR e o que ele troca: adjetivo vago de acabamento não informa nada a quem vai pagar. Os dois caem no MESMO pack e acumulam. Sem legenda queimada na imagem, de propósito: modelo erra acento em português, então o rótulo fica na row e serve de busca no picker. Exige pelo menos uma imagem no personagem (é dela que sai a cara) e é geração síncrona: se voltar Timeout, cheque sapiens_gallery antes de repetir. Quando a resposta vem com ok=false, a folha foi gerada e paga mas o corte falhou; ela está na galeria e o recorte de novo é de graça, pela web. Publicar o pack na vitrine e o carimbo da casa (que é o que põe no picker de todo mundo) são gestos da web, não desta tool. CHARACTER VIDEO (a ficha que anda): o personagem atravessa 6 mundos em 12s, trocando de roupa em cada um, com som gerado junto, e o último plano fecha a peça com ele parando e encarando a câmera. A peça volta FECHADA pelas duas portas (tela e agente), sem ninguém pedir: o personagem se apresenta no cartão de nome por cima do fim do último plano, com o LEMA em inglês embaixo (o campo `titleEn`, escrito uma vez em set_card), e só depois a casa assina. Quem não tem lema recebe o subtítulo que o roteiro inventou naquele take, e ele muda no take seguinte. O fecho é asset, não geração: zero Sinapse a mais, e é fail-open, então a resposta traz `closed` e `nameCard` dizendo o que entrou de verdade em vez de prometer um cartão que não está no arquivo. Pra colocar esse cartão num vídeo que JÁ existe, o caminho é a ficha do take na web (gaveta do fecho, 'Apresentação do personagem'), também sem custo. Exige FICHA gerada (é dela que saem a cara e o guarda-roupa), não só imagem. Duas actions, nesta ordem: plan_video (COBRA 50 Sinapses) devolve os 6 planos que a alma do personagem escolheu, com ambiente, ato, enquadramento e roupa. Cada plano vem nas duas línguas: em inglês (setting/act/wardrobe, que é o que vai pro motor) e em português (settingPt/actPt/wardrobePt). MOSTRE a versão em português pro autor, o público da casa é brasileiro e roteiro que ele lê de través não é roteiro aprovado; peça de novo quantas vezes ele quiser, porque trocar sai por 50 e o take errado sai por milhares. replan_shot (COBRA 15 Sinapses) reescreve UM plano e não toca nos outros cinco: os seis são cenas independentes, então quando o autor gosta de quatro e implica com um, troque só aquele em vez de sortear tudo de novo (mande os 6 planos em `shots`, o número em `shotIndex`, e o que ele quer diferente em `shotHint`; volta só o plano trocado, e é você que remonta o roteiro). Depois generate_video (COBRA) renderiza, com os planos aprovados no arg `shots` e o MOTOR no arg `videoTier`: 'draft' (5.400 Sinapses) é o Seedance 2.0 Mini, metade do preço, que tropeça em mão, pouca luz e câmera rápida, e 'final' (8.640 Sinapses) é o Seedance 2.0 Fast, que segura o que o Mini erra. A peça é a MESMA nos dois (mesmos 6 planos, 12s, 720p, com som), então ofereça pelo nome do motor e pelo que ele troca, nunca por adjetivo vago de acabamento. Vertical ou horizontal pelo arg `orientation`. Chamar generate_video SEM `shots` funciona, mas escreve um roteiro novo às cegas e cobra igual: não faça isso sem o autor ter visto o que vai receber. É geração demorada: se voltar Timeout, cheque sapiens_gallery antes de repetir. Resposta com `pending: true` (sem `url`) quer dizer ACEITO E COBRADO: o servidor continua renderizando sozinho (até 25 min) e a peça chega na ficha já fechada; NÃO repita a chamada, isso cobraria de novo, confira depois em sapiens_gallery. Fluxo de criação: create → add_image (1+) → set_card (opcional) → activate. PARE AÍ. O personagem nasce e continua PRIVADO, e é assim que ele serve pro dono: dá pra gerar, referenciar e iterar sem ninguém ver. set_visibility isPublic=true é o gesto de PUBLICAR no Explorar, com slug público, e nÃO é passo de fluxo: só chame quando o dono pedir pra publicar aquele personagem, com essas palavras. Na dúvida, não publique e pergunte. Pra usar um personagem público como referência numa geração, pegue mainImageUrl em list_public/get e passe em sapiens_image referenceImageUrls.",
|
|
150
150
|
schema: characterSchema,
|
|
151
151
|
handler: character,
|
|
152
152
|
},
|
package/dist/skills.js
CHANGED
|
@@ -315,7 +315,8 @@ Proibidos no prompt: "tarot card illustration", "intimate scale", "card-style po
|
|
|
315
315
|
A lista de action=models é longa e ordenada por PREÇO, que não é a pergunta de quem vai gerar. Três campos do payload resolvem isso:
|
|
316
316
|
|
|
317
317
|
- bestFor: pra que o motor serve, num vocabulário fechado (foto, anime, texto pra palavra legível na arte, personagem pra segurar a mesma pessoa, adulto). FILTRE por aqui antes de comparar preço.
|
|
318
|
-
- family + variant: motores com a MESMA family são o mesmo motor em versão diferente (Krea 2 tem Realism
|
|
318
|
+
- family + variant: motores com a MESMA family são o mesmo motor em versão diferente (Flux.2 Klein tem Base, Anime, Celular e Transparência; Krea 2 tem Realism e Transparência; Gemini tem 3 Pro e 3.1 Flash; GPT Image tem 2 Low, 2 High, 2.5 Flare e 2.5 Sunburst). O retorno traz um índice families já montado.
|
|
319
|
+
- ousadia: nudez é NÍVEL, não motor. Quando o campo vem preenchido, a mesma escolha tem uma versão com nudez: gere com \`ousadia.model\` + \`loraIntensity\` (suave, medio, forte) pra ter nudez, e com o id da linha pra não ter. Não procure um motor "+18" ou "Nu" separado na lista: ele virou este campo.
|
|
319
320
|
|
|
320
321
|
Texto legível na arte (placa, rótulo, pôster com acento): a família GPT Image é a de referência. Dentro dela, o 2.5 acerta letra pequena e acento cobrando menos que o 2 High; o Flare é o rápido, o Sunburst segura composição densa e edição em várias voltas. O preço vivo de cada um sai em action=models.
|
|
321
322
|
|
package/dist/tools/character.js
CHANGED
|
@@ -26,6 +26,9 @@ import { convexQuery, convexMutation, convexAction, getSessionToken } from "../c
|
|
|
26
26
|
* email). Merge: mandar uma rede não apaga as outras.
|
|
27
27
|
* - activate: publica (sai de draft). Exige ≥1 imagem.
|
|
28
28
|
* - set_visibility: público (entra no Explorar, ganha slug) ou privado.
|
|
29
|
+
* - set_hidden: oculta (ou mostra) o personagem na tela do DONO: some da
|
|
30
|
+
* lista e as peças dele saem da galeria de fotos e vídeos
|
|
31
|
+
* dele. Não despublica, não apaga; oculto não publica.
|
|
29
32
|
* - remove_image: tira UMA imagem do próprio personagem (por url).
|
|
30
33
|
* - set_main_image: define a principal (por url, entre as que já existem).
|
|
31
34
|
* - reorder_images: reordena as imagens (posição 0 = principal).
|
|
@@ -72,6 +75,7 @@ export const characterSchema = z.object({
|
|
|
72
75
|
"set_passport",
|
|
73
76
|
"activate",
|
|
74
77
|
"set_visibility",
|
|
78
|
+
"set_hidden",
|
|
75
79
|
"remove_image",
|
|
76
80
|
"set_main_image",
|
|
77
81
|
"reorder_images",
|
|
@@ -234,6 +238,10 @@ export const characterSchema = z.object({
|
|
|
234
238
|
.boolean()
|
|
235
239
|
.optional()
|
|
236
240
|
.describe("Pra set_visibility: true = público no Explorar (gera slug), false = privado."),
|
|
241
|
+
hidden: z
|
|
242
|
+
.boolean()
|
|
243
|
+
.optional()
|
|
244
|
+
.describe("Pra set_hidden: true = oculta o personagem da tela do dono (some da lista de personagens e as peças dele saem da galeria de fotos e vídeos do dono, voltando pelo filtro Ocultos), false = mostra de novo. Não mexe em isPublic."),
|
|
237
245
|
orientation: z
|
|
238
246
|
.enum(["portrait", "landscape"])
|
|
239
247
|
.optional()
|
|
@@ -450,6 +458,20 @@ export async function character(args) {
|
|
|
450
458
|
isPublic: args.isPublic,
|
|
451
459
|
});
|
|
452
460
|
}
|
|
461
|
+
// -------- set_hidden: oculta ou mostra na tela do dono --------
|
|
462
|
+
if (args.action === "set_hidden") {
|
|
463
|
+
if (!args.characterId)
|
|
464
|
+
throw new Error("action=set_hidden exige characterId.");
|
|
465
|
+
if (args.hidden === undefined) {
|
|
466
|
+
throw new Error("action=set_hidden exige hidden (true=oculta da sua tela, false=mostra de novo).");
|
|
467
|
+
}
|
|
468
|
+
const sessionToken = getSessionToken();
|
|
469
|
+
return await convexMutation("influencers:mcpSetCharacterHidden", {
|
|
470
|
+
sessionToken,
|
|
471
|
+
characterId: args.characterId,
|
|
472
|
+
hidden: args.hidden,
|
|
473
|
+
});
|
|
474
|
+
}
|
|
453
475
|
// -------- remove_image: tira UMA imagem (por url) --------
|
|
454
476
|
if (args.action === "remove_image") {
|
|
455
477
|
if (!args.characterId)
|
package/dist/tools/image.js
CHANGED
|
@@ -30,27 +30,30 @@ const MODELS = [
|
|
|
30
30
|
"grok-2-image-quality", // grok-imagine-image-quality, mais fiel pra character lock · COM refs · adder até 2K
|
|
31
31
|
"grok-imagine-2", // grok-imagine-image-2.0, a geração nova (ago/2026) · COM refs · adder até 2K
|
|
32
32
|
// Degen (uncensored, gate +18 na galeria). WaveSpeed = rápido (6-25s):
|
|
33
|
+
// NUDEZ É NÍVEL, NÃO MOTOR (set/2026): três pares abaixo são a MESMA escolha com
|
|
34
|
+
// e sem nudez. Sem nudez = o primeiro id; com nudez = o id "com Ousadia" +
|
|
35
|
+
// loraIntensity. A tela do site mostra só o primeiro e troca pelo segundo quando
|
|
36
|
+
// a Ousadia liga. action=models devolve o par no campo `ousadia`.
|
|
33
37
|
"wavespeed-chroma", // Chroma uncensored fotorrealista
|
|
34
|
-
"wavespeed-flux2", // Flux.2 Klein
|
|
35
|
-
"wavespeed-klein-plus", //
|
|
36
|
-
"wavespeed-flux-nsfw", // Flux dev + LoRA NSFW (AIDMA) · Ousadia regulável
|
|
37
|
-
"wavespeed-klein-anime", // Flux.2 Klein + LoRA anime (inteligente + controlável)
|
|
38
|
-
"wavespeed-klein-anime-plus", // Klein Anime + SNOFS uncensored
|
|
38
|
+
"wavespeed-flux2", // Flux.2 Klein Base · com Ousadia = wavespeed-klein-nu
|
|
39
|
+
"wavespeed-klein-plus", // FORA da prateleira: era Klein + LoRA de ANATOMIA, a escolha virou Klein Base com Ousadia. O id segue gerando.
|
|
40
|
+
"wavespeed-flux-nsfw", // Flux dev + LoRA NSFW (AIDMA) · Ousadia regulável (sem par: a nudez é dele mesmo)
|
|
41
|
+
"wavespeed-klein-anime", // Flux.2 Klein + LoRA anime (inteligente + controlável) · com Ousadia = wavespeed-klein-anime-plus
|
|
42
|
+
"wavespeed-klein-anime-plus", // Klein Anime COM Ousadia (+ SNOFS uncensored) · loraIntensity regula
|
|
39
43
|
"wavespeed-klein-celular", // O MESMO Klein 9B + LoRA de foto de celular (candid), segura o rosto da ref
|
|
40
|
-
"wavespeed-klein-nu", //
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
// Ousadia regulável.
|
|
44
|
+
"wavespeed-klein-nu", // Klein Base COM Ousadia: + SNOFS no registro de FOTO. O Klein em edit VESTE a
|
|
45
|
+
// modelo sozinho mesmo sem safety checker: é esta LoRA que destrava o nível, e a referência é que
|
|
46
|
+
// segura a identidade. loraIntensity regula.
|
|
44
47
|
"wavespeed-klein-transparencia", // O MESMO Klein 9B + Transparent Clothes: tecido que a luz
|
|
45
48
|
// atravessa de verdade. Aqui o efeito é a LoRA e não a descrição (prompt caprichado sobre renda e
|
|
46
49
|
// trama, sem ela, devolve tecido opaco). Trigger no começo do prompt: "sheer clothes, revealing her
|
|
47
50
|
// breasts underneath". Segura o rosto da ref.
|
|
48
51
|
"wavespeed-krea2-transparencia", // A MESMA LoRA de transparência na base Krea 2: fotografia mais
|
|
49
52
|
// rica (luz com caráter, grão, profundidade) e identidade mais frouxa que a irmã Klein.
|
|
50
|
-
"wavespeed-krea2", // Krea
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
"wavespeed-krea2-base", //
|
|
53
|
+
"wavespeed-krea2-realism", // Krea 2 Realism pela WaveSpeed, sem nudez: sem o classificador de entrada
|
|
54
|
+
// da fal, img2img de verdade, 2K nativo · com Ousadia = wavespeed-krea2
|
|
55
|
+
"wavespeed-krea2", // Krea 2 Realism COM Ousadia (a antiga "Livre"): mesmo realismo + LoRA NSFW. loraIntensity regula.
|
|
56
|
+
"wavespeed-krea2-base", // FORA da prateleira: Krea 2 sem LoRA nenhuma, a escolha virou o Krea 2 Realism. O id segue gerando.
|
|
54
57
|
// Civitai (sdcpp, rápido). Família FLUX no Civitai saiu: lenta demais (>5min,
|
|
55
58
|
// estoura o poll). Pra flux uncensored use wavespeed-flux-nsfw.
|
|
56
59
|
"civitai-wai-illustrious", // anime Illustrious
|
|
@@ -61,7 +64,7 @@ const MODELS = [
|
|
|
61
64
|
// off). Aceitam até 3 referências de ESTILO (endpoint krea-2/turbo/style): trava
|
|
62
65
|
// paleta/luz/textura de uma série, não trava a mesma pessoa. Com referência a
|
|
63
66
|
// LoRA do catálogo não vai junto (o endpoint de style não a aceita).
|
|
64
|
-
"fal-krea2-realism-v2", // Krea 2 Realism (LoRA RudySen, venceu o A/B de 30/ago) · txt2img
|
|
67
|
+
"fal-krea2-realism-v2", // FORA da prateleira: Krea 2 Realism pela fal (LoRA RudySen, venceu o A/B de 30/ago) · txt2img. A escolha virou o wavespeed-krea2-realism; o id segue gerando.
|
|
65
68
|
];
|
|
66
69
|
// Motor ATIVO no catálogo que fica fora do enum DE PROPÓSITO, com o motivo. O
|
|
67
70
|
// gate audit:catalog-parity (apps/sapiens) lê este mapa: id ativo que não está
|
|
@@ -123,7 +126,7 @@ export const imageSchema = z.object({
|
|
|
123
126
|
loraIntensity: z
|
|
124
127
|
.enum(["suave", "medio", "forte"])
|
|
125
128
|
.optional()
|
|
126
|
-
.describe("Ousadia
|
|
129
|
+
.describe("Ousadia: o nível de nudez. Só vale nos modelos COM Ousadia ('wavespeed-klein-nu' = Klein Base, 'wavespeed-klein-anime-plus' = Klein Anime, 'wavespeed-krea2' = Krea 2 Realism, 'wavespeed-flux-nsfw', e o legado 'wavespeed-klein-plus'): suave=insinua sem despir, medio=maduro no limite (default), forte=sem freio. Sem nudez, use o par sem Ousadia ('wavespeed-flux2', 'wavespeed-klein-anime', 'wavespeed-krea2-realism'): o par vem no campo `ousadia` de action=models. Ideal pra remixar personagem (ex: a Helen) preservando a identidade e regulando a liberdade. Ignorado nos demais modelos."),
|
|
127
130
|
mode: z
|
|
128
131
|
.enum(["create", "edit", "variation"])
|
|
129
132
|
.optional()
|
|
@@ -158,8 +161,19 @@ export async function image(args) {
|
|
|
158
161
|
// de confiar no enum congelado. Antes de exigir sessão de propósito.
|
|
159
162
|
if (args.action === "models") {
|
|
160
163
|
const all = await convexQuery("imageModels:listWithOverrides", {});
|
|
161
|
-
const
|
|
162
|
-
|
|
164
|
+
const active = (all ?? []).filter((m) => m?.isActive);
|
|
165
|
+
// Nudez é nível, não motor (set/2026): a entrada com `ousadiaOf` é a mesma
|
|
166
|
+
// escolha com nudez, e a com `mergedInto` saiu da prateleira. As duas seguem
|
|
167
|
+
// gerando pelo id, mas não viram linha: a irmã com Ousadia vira o campo
|
|
168
|
+
// `ousadia` da escolha que ela completa, igual à tela do site. Backend sem os
|
|
169
|
+
// campos (deploy anterior) só devolve a lista como sempre.
|
|
170
|
+
const ousadiaByShelf = {};
|
|
171
|
+
for (const m of active) {
|
|
172
|
+
if (m.ousadiaOf)
|
|
173
|
+
ousadiaByShelf[m.ousadiaOf] = { model: m.id, priceSinapses: m.effectivePriceSinapses };
|
|
174
|
+
}
|
|
175
|
+
const models = active
|
|
176
|
+
.filter((m) => !m.ousadiaOf && !m.mergedInto)
|
|
163
177
|
.sort((a, b) => (a.order ?? 99) - (b.order ?? 99))
|
|
164
178
|
.map((m) => ({
|
|
165
179
|
id: m.id,
|
|
@@ -180,6 +194,9 @@ export async function image(args) {
|
|
|
180
194
|
resolutionAdders: m.resolutionAdders,
|
|
181
195
|
supportsReferences: !!m.supportsReferences,
|
|
182
196
|
degen: /^(civitai-|wavespeed-|fal-)/.test(String(m.id)),
|
|
197
|
+
// O id que gera esta mesma escolha COM nudez (manda junto loraIntensity).
|
|
198
|
+
// null = sem par; se o próprio motor tem LoRA tunável, a Ousadia é dele.
|
|
199
|
+
ousadia: ousadiaByShelf[m.id] ?? null,
|
|
183
200
|
note: m.description ?? null,
|
|
184
201
|
}));
|
|
185
202
|
// Índice por família, pro cliente escolher em dois passos como a tela faz:
|
|
@@ -201,7 +218,8 @@ export async function image(args) {
|
|
|
201
218
|
families,
|
|
202
219
|
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. " +
|
|
203
220
|
"Preço final = priceSinapses + resolutionAdders[size]. degen=+18 (gate na galeria). " +
|
|
204
|
-
"Modelos com a MESMA family são o mesmo motor em versão diferente (o variant diz qual): compare preço e nota entre eles antes de trocar de família."
|
|
221
|
+
"Modelos com a MESMA family são o mesmo motor em versão diferente (o variant diz qual): compare preço e nota entre eles antes de trocar de família. " +
|
|
222
|
+
"Nudez é nível, não motor: quando `ousadia` vem preenchido, gere com ousadia.model + loraIntensity pra ter nudez e com o id da linha pra não ter (o preço com nudez vem em ousadia.priceSinapses).",
|
|
205
223
|
};
|
|
206
224
|
}
|
|
207
225
|
const sessionToken = getSessionToken();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sapiens-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.68.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",
|