asmpkg / guiche
Core PHP para assistentes conversacionais orientados a Tools, Plugins, estado, segurança, persistência e runtime de conversação.
Requires
- php: ^8.4
- vlucas/phpdotenv: ^5.6
Requires (Dev)
- phpstan/phpstan: ^2.2
- phpunit/phpunit: ^13.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v1.6.0
- v1.5.0
- v1.4.0
- v1.3.0
- v1.2.2
- v1.2.1
- v1.2.0
- v1.1.1
- v1.1.0
- v1.0.2
- v1.0.1
- v1.0.0
- v0.9.0
- v0.8.0
- v0.7.0
- v0.6.0
- v0.5.1
- v0.5.0
- v0.4.0
- v0.3.0
- v0.2.0
- dev-feature/v1.5.0-loaders-multitenant
- dev-feature/v1.1.0-contexto-dinamico-multitenant
- dev-feature/v1.0.1-clinical-chat-ci
- dev-hotfix/v1.0.1-clinical-chat
- dev-feature/v1.0-stable
- dev-feature/v0.9-release-candidate
- dev-feature/v0.8-clinical-example
- dev-feature/v0.7-developer-experience
- dev-feature/v0.6-test-suite-static-analysis
- dev-feature/v0.5.1-conversation-runtime
- dev-feature/v0.5-persistence-observability
- dev-feature/v0.4-safety-layer
This package is auto-updated.
Last update: 2026-10-17 20:17:04 UTC
README
Guichê é um Core PHP para construir assistentes conversacionais orientados a Tools, Plugins, estado, segurança, persistência e runtime de conversação sem acoplar o Core a um domínio específico.
O projeto evoluiu de um piloto clínico para uma biblioteca reutilizável. O domínio clínico deixa de definir a arquitetura do Core e passa a ser apenas uma integração construída sobre os mesmos contratos públicos disponíveis para qualquer outro domínio.
Versão documentada: v1.6.0 — Stable
Requisitos
- PHP
^8.4; - Composer;
- uma chave de API para o provider usado na conversa real. O exemplo oficial utiliza OpenAI.
O quality gate do projeto e os testes automatizados não dependem de OpenAI real, banco real, Clinsoft, Internet ou side effects reais.
Instalação
Instale a linha estável v1:
composer require asmpkg/guiche:^1.0
Para trabalhar diretamente com o clone deste repositório:
git clone git@github.com:alexsmonte/guiche.git guiche
cd guiche
composer install
Quick Start — primeira conversa
Na v1.6.0 você não precisa copiar nem criar chat.php para começar.
1. Crie um projeto vazio
mkdir meu-guiche
cd meu-guiche
composer require asmpkg/guiche:^1.6
2. Inicialize o projeto
vendor/bin/guiche init
O comando cria, sem sobrescrever arquivos existentes:
.env
guiche.prompt.md # compatibilidade
guiche.php
prompts/
└── comportamento.md # prompt global v1.5
src/
├── Tool/
└── Plugin/
storage/
└── conversations/
Quando o projeto consumidor possui composer.json, o init também garante
o mapeamento PSR-4:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Se o init tiver adicionado esse prefixo, regenere o autoload uma vez:
composer dump-autoload
Um App\\ já existente com outro caminho é preservado e será reportado pelo
doctor, em vez de ser sobrescrito silenciosamente.
3. Configure o provider
Edite .env:
AI_API_KEY=sua-chave AI_MODEL=gpt-5.6-luna
AI_MODEL possui valor padrão. Por compatibilidade, OPENAI_API_KEY e
OPENAI_MODEL ainda são aceitos como aliases legados.
4. Personalize o prompt
O padrão da v1.5 usa TenantPromptResolver com:
prompts/comportamento.md
Para um tenant confiável acme, você pode adicionar:
prompts/acme.md
A composição será:
prompts/comportamento.md
+
prompts/acme.md
A resolução completa segue esta prioridade:
$app['prompt_resolver']
↓
GUICHE_PROMPT_FILE
↓
GUICHE_PROMPT
↓
prompts/comportamento.md + prompts/{tenant_id}.md
↓
guiche.prompt.md legado
O tenant_id precisa vir do contexto confiável da sessão. Mensagem do usuário,
state livre e argumentos de Tool não podem selecionar o arquivo de tenant.
5. Verifique o ambiente
vendor/bin/guiche doctor
O doctor valida PHP, extensões, .env, configuração de IA, prompt global,
App\\ => src/, diretórios de loaders e storage/conversations sem
fazer uma chamada de rede ao provider.
6. Converse
Modo interativo:
vendor/bin/guiche chat
Mensagem única:
vendor/bin/guiche chat "Olá, tudo bem?"
Sessão explícita:
vendor/bin/guiche chat --session=cliente-123 "Olá"
No modo interativo:
/contextmostra o contexto salvo;/usagemostra o uso registrado na sessão;/toolsmostra as Tools disponíveis;/resetreinicia a sessão;/sairencerra a CLI.
Esses comandos são tratados localmente e não são enviados à IA.
Também é possível consultar usage fora do chat:
vendor/bin/guiche usage --session=cliente-123
Novidades da v1.6
A v1.6 consolida Operational State & Runtime DX sem quebrar os contratos estáveis da linha v1.
- Trusted Parameter Binding para parâmetros confiáveis de Tools;
- cache/reuso de READ com dependências explícitas do contexto;
GuicheBuilder::withSessionTtl()e lifecyclenew/active/expired;FollowUpRuntimeexperimental sobre o scheduler durável;CompositePromptResolverewithPromptResolvers(...);GuicheBuilder::loadCapabilities()paraservices,toolseplugins;- Operational State e interoperabilidade no exemplo clínico.
Exemplo básico com Tool
A CLI da v1.2.0 oferece a menor experiência genérica sem exigir arquivo PHP manual. Quando você quiser estudar a integração de uma Tool e um Plugin, o exemplo oficial continua disponível em:
examples/basic/
Ele contém:
BasicPlugin;- Tool local
CatalogSearch; - catálogo determinístico em memória;
- operação somente
READ; - nenhum MySQL;
- nenhuma API privada;
- nenhum side effect.
O BasicPlugin registra sua Tool pela mesma API pública do
GuicheBuilder usada por aplicações externas.
Conceitos principais
Tool
Uma Tool implementa ToolInterface e declara:
- nome;
- descrição;
- schema de argumentos;
- execução.
Tools podem ser classificadas como operações de leitura ou escrita. Operações de escrita possuem requisitos de segurança adicionais.
Plugin
Um Plugin implementa PluginInterface e registra capacidades pelo GuicheBuilder, como:
- Tools;
- Presenters;
- State Manager;
- Policies;
- instruction fragments;
- completion guards;
- result projections.
State
O contexto estruturado da conversa pode ser persistido por uma implementação de ContextStoreInterface. O Core não precisa conhecer detalhes do domínio para manter esse estado.
Contexto dinâmico multi-tenant
A partir da v1.1, uma Tool pode implementar ContextAwareToolInterface
quando sua execução depende de identidade e tenant vinculados à sessão.
O fluxo confiável é:
SESSION
↓
execution_context.identity
↓
TenantResolver
↓
execution_context.tenant_id
↓
ToolExecutionContext
↓
ContextAwareToolInterface::executeWithContext()
tenant_id não deve ser aceito da IA como fonte de autoridade.
O ToolInterface original permanece compatível. Tools legadas continuam
executando por execute(array $arguments) sem exigir contexto multi-tenant.
Veja:
docs/multitenancy.md;docs/migration-v1.0-to-v1.1.md.
Contexto externo confiável — v1.3
A v1.3 torna público o caminho recomendado para aplicações externas vincularem uma identidade autenticada à sessão:
$guiche->bindIdentity( $sessionId, [ 'provider' => 'custom-crm', 'account_id' => $accountId, 'conversation_id' => $conversationId, ] ); $response = $guiche->handle( $sessionId, $message );
O fluxo é:
host externo confiável
↓
bindIdentity()
↓
execution_context.identity
↓
TenantResolver
↓
execution_context.tenant_id
↓
ToolExecutionContext
↓
ContextAwareTool
bindIdentity() é write-once por sessão, idempotente para o mesmo binding e
falha fechado quando há tentativa de troca. Binding e turno da mesma sessão
também compartilham o mesmo lock de concorrência.
O Core não depende de Chatwoot ou de qualquer provider externo. Chatwoot é
um adapter de referência em examples/chatwoot/; um exemplo genérico fica
em examples/external-host/.
A autenticação do webhook/request externo pertence ao host. Somente depois
de estabelecer a confiança o host deve chamar bindIdentity().
Veja:
docs/trusted-external-identity.md;docs/migration-v1.2-to-v1.3.md;examples/chatwoot/;examples/external-host/.
Prompt dinâmico e Composition Root — v1.4
A v1.4 adiciona PromptResolverInterface, PromptContext e resolução de
prompt em runtime por sessão/tenant, preservando withInstructions().
vendor/bin/guiche init passa a criar também guiche.php, o Composition Root
do projeto consumidor:
$factory = require __DIR__ . '/guiche.php'; $guiche = $factory();
Fontes públicas: StaticPromptResolver, FilePromptResolver,
CallbackPromptResolver e FallbackPromptResolver.
Fluxo confiável:
SESSION → bindIdentity() → TenantResolver → tenant_id
→ PromptContext → PromptResolver → prompt
Mensagem do usuário, state e argumentos livres de Tool não são fonte de autoridade para selecionar tenant/prompt.
Veja docs/dynamic-prompts.md, docs/migration-v1.3-to-v1.4.md,
examples/prompt-sources/ e examples/framework-integration/.
Loaders, DI e prompts por tenant — v1.5
A v1.5 adiciona uma camada de conveniência sobre a API explícita existente.
Baixo nível, preservado:
$builder->registerTool(new MinhaTool()); $builder->registerPlugin(new MeuPlugin());
Alto nível, por convenção:
$builder ->loadTools('InformacoesEmpresa', 'ConsultarPedido') ->loadPlugins('Clinica');
Convenções:
InformacoesEmpresa
→ App\Tool\InformacoesEmpresaTool
Clinica
→ App\Plugin\ClinicaPlugin
FQCN também é aceito. Não existe scanning de diretório, glob, require
dinâmico ou autowiring recursivo.
Dependências de construtor precisam ser registradas explicitamente:
$builder ->setService(MinhaConexao::class, $conexao) ->loadTool('InformacoesEmpresa');
No Composition Root:
$guiche = $factory([ 'services' => [ MinhaConexao::class => $conexao, ], 'tools' => [ 'InformacoesEmpresa', $toolLegada, ], 'plugins' => [ 'Clinica', $pluginLegado, ], ]);
Os nomes enviados a loadTool() e loadPlugin() são configuração de bootstrap
confiável. Nunca use mensagem, saída da IA ou argumentos livres do usuário
para escolher classe a carregar.
Migração: docs/migration-v1.4-to-v1.5.md.
Safety Layer
A execução de Tools passa por regras estruturadas de segurança. O runtime suporta, entre outros mecanismos:
- classificação READ/WRITE;
- validação de argumentos;
- preconditions de estado;
- estágios permitidos;
- confirmação;
- proteção de idempotência para escrita;
- bloqueio de duplicate writes;
- Result Projection.
Conversation Runtime
O runtime de conversação cobre responsabilidades como:
- incoming events;
- buffer/debounce;
- turn;
- sequence;
- scheduler;
- claim/lease;
- stale-event protection;
- follow-up e recovery.
A divisão conceitual é:
ConversationRuntime = quando processar
Guiche = como processar/raciocinar o turno
Exemplo básico
O código de referência fica em:
examples/basic/
Ele foi criado especificamente para Developer Experience e deve permanecer:
- pequeno;
- legível;
- neutro de domínio;
- sem banco;
- sem dependências privadas;
- seguro para leitura;
- executável como primeira experiência com o framework.
Veja Quick Start detalhado.
Desenvolvimento
Instale as dependências:
composer install
Execute o quality gate:
composer check
O quality gate inclui PHPUnit, PHPStan e cobertura mínima definida pelo projeto.
Arquitetura e documentação
A documentação pública da linha v1 é organizada em:
- Quick Start:
docs/quick-start.md; - arquitetura:
docs/architecture.md; - Tools:
docs/tools.md; - Plugins:
docs/plugins.md; - State:
docs/state.md; - contexto multi-tenant:
docs/multitenancy.md; - prompts dinâmicos:
docs/dynamic-prompts.md; - migração v1.4 → v1.5:
docs/migration-v1.4-to-v1.5.md; - migração v1.0 → v1.1:
docs/migration-v1.0-to-v1.1.md; - migração v1.1 → v1.2:
docs/migration-v1.1-to-v1.2.md; - segurança:
docs/security.md.
A política de estabilidade da API e suporte PHP complementa essa documentação.
Status
A v1.0 estabeleceu a linha estável; a v1.1 adicionou contexto multi-tenant; a v1.2 adicionou CLI/bootstrap; a v1.3 tornou bindIdentity() o caminho recomendado para identidade externa; e a v1.4 adicionou Composition Root e prompts dinâmicos por sessão/tenant; e a v1.5 adiciona loaders por convenção, DI explícita e prompt multi-tenant baseado em arquivos.
O compromisso da linha v1 inclui:
- API
publicprotegida por SemVer/BC; - suporte oficial a PHP 8.4 e PHP 8.5;
- hard execution gate antes de side effects;
- idempotência explícita para WRITE;
- extensibilidade por Tools, Plugins, ContextStore e AiProvider;
- instalação e uso comprovados em consumidor Composer externo;
- Conversation Runtime disponível como API
experimental, fora do compromisso BC estável até promoção explícita.
O principal critério de aceite permanece:
em um projeto vazio, um desenvolvedor deve conseguir seguir somente este README e obter uma conversa funcional.
Licença
Consulte o arquivo de licença do repositório.
Exemplo clínico avançado
A biblioteca mantém o Core genérico em src/ e disponibiliza um exemplo
completo de agendamento em
examples/clinica-piloto/.
Para executar o exemplo pela primeira vez, use o Fake Mode, que não depende de banco, IA ou API externos:
cp examples/clinica-piloto/.env.example examples/clinica-piloto/.env php examples/clinica-piloto/fake-smoke.php
Veja o guia de instalação e isolamento em
examples/clinica-piloto/INSTALL.md.
O namespace do exemplo não pertence ao autoload público do pacote.
Linha estável v1
A v1.0.0 congela a primeira superfície pública estável do Guichê e mantém o Conversation Runtime explicitamente experimental.
Instalação:
composer require asmpkg/guiche:^1.0
Fluxo básico de integração:
$builder = new Asmpkg\Guiche\GuicheBuilder(); $builder->withContextStore($contextStore); $builder->withAiProvider($provider); $builder->registerPlugin($plugin); $guiche = $builder->build(); $result = $guiche->handle('session-123', 'Olá');
Pontos de extensão estáveis:
ToolInterface;PluginInterface;ContextStoreInterface;AiProviderInterface;ToolRegistration;GuicheBuilder.
O hard execution gate valida policy, estado, argumentos e regras de WRITE imediatamente antes da execução real da Tool. Uma Tool call da IA nunca equivale, por si só, a autorização de side effect.
Documentação da linha v1:
- Quick Start
- External Consumer Guide
- API Stability & SemVer
- PHP Support
- Security Architecture
- Security Policy
- Migração v0.9 → v1.0
- Release v1.0.0
- Release v1.2.0
- Release v1.4.0
- Release v1.5.0
Os exemplos permanecem separados do Core: examples/basic/ para início rápido e examples/clinica-piloto/ como exemplo avançado de domínio.