{"_id":"@autonomoss/chat-core","_rev":"2-5c0ef72b448d2eb296f30c81193e559f","name":"@autonomoss/chat-core","dist-tags":{"latest":"2.0.0"},"versions":{"1.0.1":{"name":"@autonomoss/chat-core","version":"1.0.1","license":"MIT","_id":"@autonomoss/chat-core@1.0.1","maintainers":[{"name":"walbersondev","email":"walberson.mv@gmail.com"}],"dist":{"shasum":"0769ad6bd81fdb7b2d431d1a03293566147b6996","tarball":"https://registry.npmjs.org/@autonomoss/chat-core/-/chat-core-1.0.1.tgz","fileCount":9,"integrity":"sha512-fl6ctRSzQha4lpTfCFUr7H8AmD4x55g4HMsYSXmEgEZKAucVPS2KZc98vecFl+Ki2BtK7ibnqSDP0k4eAVmJKg==","signatures":[{"sig":"MEYCIQCLPq99som+wTJf7RPpdagIA3o/gYiT6YkKEIOTZw0lnwIhAMwYIFVKI5WfhRKW6oCtTGM/MuSecVb+KNStifLPzevM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":160050},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"size":"size-limit","test":"vitest run --passWithNoTests","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"walbersondev","email":"walberson.mv@gmail.com"},"repository":{"url":"https://github.com/autonomoss/autonomoss-web-sdk.git","type":"git"},"size-limit":[{"path":"dist/index.js","limit":"12 kB"}],"description":"Headless TypeScript client for embedding Autonomoss AI chat: sessions, secure attributes, SSE streaming, threads.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.0","tsup":"^8.5.0","vitest":"^3.2.0","size-limit":"^11.2.0","@size-limit/preset-small-lib":"^11.2.0"},"_npmOperationalInternal":{"tmp":"tmp/chat-core_1.0.1_1785453860252_0.9417766043892264","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@autonomoss/chat-core","version":"2.0.0","description":"Headless TypeScript client for embedding Autonomoss AI chat: sessions, secure attributes, SSE streaming, threads.","license":"MIT","repository":{"type":"git","url":"https://github.com/autonomoss/autonomoss-web-sdk.git"},"type":"module","sideEffects":false,"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"size-limit":[{"path":"dist/index.js","limit":"12 kB"}],"devDependencies":{"@size-limit/preset-small-lib":"^11.2.0","msw":"^2.12.0","size-limit":"^11.2.0","tsup":"^8.5.0","vitest":"^3.2.0"},"publishConfig":{"access":"public"},"scripts":{"build":"tsup","typecheck":"tsc --noEmit","test":"vitest run --passWithNoTests","test:watch":"vitest","size":"size-limit"},"_nodeVersion":"22.23.1","_id":"@autonomoss/chat-core@2.0.0","dist":{"integrity":"sha512-hMV4V0WaECQHHmao6VWJMSW476oWBcOsTnRC1QgVBb+oZWIBfOp+e7DxJBcMpDhD606bRDQpsjwMkpTjFifdrA==","shasum":"b6c970725a7dd1d96ed70b950748a87ec3161c5d","tarball":"https://registry.npmjs.org/@autonomoss/chat-core/-/chat-core-2.0.0.tgz","fileCount":9,"unpackedSize":160416,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDRdZLZXTYykefuLndr0VHuIxX7y0HobObsA/H4pf8IcwIhALO7zH31ivTfS96HbxvovB63IY77eYF3dVRFW7HZO97L"}]},"_npmUser":{"name":"walbersondev","email":"walberson.mv@gmail.com"},"directories":{},"maintainers":[{"name":"walbersondev","email":"walberson.mv@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/chat-core_2.0.0_1785903093851_0.8496819206232182"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-30T23:24:20.113Z","modified":"2026-08-05T04:11:34.172Z","1.0.1":"2026-07-30T23:24:20.476Z","2.0.0":"2026-08-05T04:11:33.992Z"},"license":"MIT","repository":{"type":"git","url":"https://github.com/autonomoss/autonomoss-web-sdk.git"},"description":"Headless TypeScript client for embedding Autonomoss AI chat: sessions, secure attributes, SSE streaming, threads.","maintainers":[{"name":"walbersondev","email":"walberson.mv@gmail.com"}],"readme":"# @autonomoss/chat-core\n\nCliente headless do Autonomoss Web SDK — sem UI, sem framework. Sessão,\natributos seguros/públicos, streaming SSE e histórico de conversas. Use\ndiretamente se você vai construir sua própria interface; se quiser um chat\npronto, veja [`@autonomoss/chat`](https://github.com/autonomoss/autonomoss-web-sdk/tree/main/packages/ui) ou\n[`@autonomoss/chat-react`](https://github.com/autonomoss/autonomoss-web-sdk/tree/main/packages/react).\n\n## Instalação\n\nPacote público — instala normalmente, sem autenticação:\n\n```bash\nnpm install @autonomoss/chat-core\n# ou\npnpm add @autonomoss/chat-core\n# ou\nyarn add @autonomoss/chat-core\n```\n\nTambém publicado em espelho no\n[GitHub Packages](https://github.com/autonomoss/autonomoss-web-sdk/pkgs/npm/chat-core)\n— útil se sua organização já centraliza dependências ali; requer um\n`.npmrc` com token `read:packages` (ver\n[documentação do GitHub Packages](https://docs.github.com/pt/packages/working-with-a-github-packages-registry/working-with-the-npm-registry)).\n\n## Quickstart\n\n```ts\nimport { Autonomoss } from '@autonomoss/chat-core'\n\nconst client = Autonomoss({\n  publishableKey: 'pk_...',\n  baseUrl: 'https://sua-api.exemplo.com/v1/embed',\n  attributes: {\n    secure: {\n      access_token: { format: 'bearer_token', value: () => keycloak.token! },\n    },\n  },\n})\n\nfor await (const event of client.sendMessage({ message: 'Olá!' })) {\n  if (event.type === 'text') process.stdout.write(event.text)\n}\n```\n\n`baseUrl` é obrigatório — aponte para a API de embed do seu próprio backend\nAutonomoss. O SDK não embute nenhum endereço padrão.\n\n## Referência de API\n\n### `Autonomoss(config)` / `new EmbedClient(config)`\n\nFábrica (ou construtor direto) que recebe um `AutonomossConfig`:\n\n| Campo            | Tipo               | Obrigatório | Descrição                                                                                    |\n| ---------------- | ------------------ | ----------- | -------------------------------------------------------------------------------------------- |\n| `publishableKey` | `string`           | sim         | Chave pública do widget (`pk_...`). Nunca a `sk_` — essa é só server-side.                   |\n| `baseUrl`        | `string`           | sim         | Base da API de embed do seu backend Autonomoss (ex: `https://sua-api.exemplo.com/v1/embed`). |\n| `attributes`     | `AttributesConfig` | sim         | Atributos seguros/públicos da sessão — ver [Atributos](#atributos).                          |\n| `telemetry`      | `TelemetryConfig`  | não         | Opt-in, ver [Telemetria](#telemetria).                                                       |\n\n### `EmbedClient`\n\n| Membro                                       | Assinatura                                                                                        | Descrição                                                                                                                                                                                                      |\n| -------------------------------------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `connect()`                                  | `(): Promise<void>`                                                                               | Faz o bootstrap da sessão adiantado. Opcional — `sendMessage`/`threads.*` fazem sob demanda.                                                                                                                   |\n| `sendMessage(input, options?)`               | `(input: SendMessageInput, options?: { signal?: AbortSignal }): AsyncGenerator<EmbedStreamEvent>` | Envia uma mensagem; itere o generator para receber o stream incremental (também emitido via `on('message', ...)`).                                                                                             |\n| `setAttributes(patch)`                       | `(patch: { public?: Record<string, unknown> }): void`                                             | Atualiza atributos **públicos** (contexto de orquestração) sem recriar a sessão. Atributos seguros são sempre resolvidos on-demand a cada bootstrap/refresh — não há como \"setá-los\" fora do `config` inicial. |\n| `on(event, handler)` / `off(event, handler)` | ver [Eventos](#eventos)                                                                           | Assina/cancela eventos do client. `on` retorna uma função de unsubscribe.                                                                                                                                      |\n| `threads`                                    | `ThreadsApi`                                                                                      | Histórico de conversas — ver [Threads](#threads-histórico).                                                                                                                                                    |\n| `destroy()`                                  | `(): void`                                                                                        | Remove todos os listeners registrados via `on`.                                                                                                                                                                |\n\n### `SendMessageInput`\n\n```ts\ninterface SendMessageInput {\n  message: string\n  chatId?: string // continua uma conversa existente; omitido cria uma nova\n  attachments?: ChatAttachment[] // até 3, 2 MB cada, efêmeros — o SDK não os persiste\n}\n```\n\n### `EmbedStreamEvent`\n\nUnião discriminada por `type`, o que `sendMessage` produz a cada iteração:\n\n```ts\ntype EmbedStreamEvent =\n  | { type: 'meta'; chatId: string; senderName: string; modelBadge: string }\n  | { type: 'text'; text: string } // token incremental da resposta\n  | {\n      type: 'status'\n      stepId: string\n      title: string\n      description: string\n      status: 'loading' | 'complete' | 'error'\n    }\n  | { type: 'error'; reason: string; message?: string }\n```\n\n### Threads (histórico)\n\n`client.threads` expõe:\n\n| Método                 | Retorno                  | Descrição                           |\n| ---------------------- | ------------------------ | ----------------------------------- |\n| `list()`               | `Promise<ChatSummary[]>` | Lista as conversas da sessão atual. |\n| `create()`             | `Promise<ChatSummary>`   | Cria uma conversa nova.             |\n| `listMessages(chatId)` | `Promise<ChatMessage[]>` | Histórico de uma conversa.          |\n| `reopen(chatId)`       | `Promise<ChatSummary>`   | Reabre uma conversa arquivada.      |\n\n### Eventos\n\n```ts\nclient.on('message', (event: EmbedStreamEvent) => {})\nclient.on('session', (event: { type: 'bootstrapped' | 'refreshed' | 'expired' }) => {})\nclient.on('error', (event: { reason: string; message: string }) => {})\n```\n\n## Atributos\n\nDois tipos, declarados em `config.attributes`:\n\n- **`secure`** — nunca persistidos entre chamadas. Cada valor pode ser\n  estático ou um callback (síncrono ou assíncrono); o callback é\n  **reavaliado a cada bootstrap/refresh de sessão**, o que cobre renovação\n  de token (ex. Keycloak) de forma transparente, sem você precisar\n  gerenciar isso manualmente.\n\n  ```ts\n  attributes: {\n    secure: {\n      access_token: { format: 'bearer_token', value: () => keycloak.token! },\n    },\n  }\n  ```\n\n  `format` é `'bearer_token' | 'api_key' | 'string' | 'json'` — descreve o\n  _tipo_ do valor que você está enviando; quem decide como esse valor é\n  usado no destino (ex. prefixo `Bearer`, nome do header) é configurado do\n  lado do Autonomoss Studio, na tela de Integrações — não aqui.\n\n- **`public`** — contexto não sensível (ex. `{ cidade: 'Recife' }`), enviado\n  junto de cada bootstrap/refresh. Atualizável a qualquer momento via\n  `client.setAttributes({ public: {...} })`, sem recriar a sessão.\n\n## Cookbook de erros\n\nToda falha de rede/API vira uma das classes abaixo (nunca uma exceção crua\ndo `fetch`):\n\n| Classe                   | Quando                                                                                                                                               |\n| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `AutonomossConfigError`  | Erro de configuração/uso do SDK detectado no client antes de qualquer chamada de rede (ex. `publishableKey` vazio, callback de atributo que lançou). |\n| `AutonomossNetworkError` | Falha de transporte — rede indisponível, CORS, DNS. Nunca chegou a uma resposta HTTP.                                                                |\n| `AutonomossApiError`     | Erro nomeado do contrato de embed. Tem `.reason` (string estável, ver tabela abaixo) e `.status` (HTTP).                                             |\n| `AutonomossStreamError`  | O stream SSE caiu no meio de uma resposta.                                                                                                           |\n\n```ts\nimport { AutonomossApiError, isSessionExpiredError } from '@autonomoss/chat-core'\n\ntry {\n  await client.connect()\n} catch (error) {\n  if (isSessionExpiredError(error)) {\n    // error.reason === 'token_expired' — o SDK já tenta um retry automático\n    // internamente antes de propagar; se chegou aqui, os dois tentaram e falharam.\n  } else if (error instanceof AutonomossApiError) {\n    console.error(error.reason, error.status)\n  }\n}\n```\n\nSe você não quer lidar com as classes diretamente, use `normalizeFriendlyError`\n(o que `@autonomoss/chat` e `@autonomoss/chat-react` já fazem internamente)\npara obter uma mensagem pronta para exibir ao usuário final, em pt-BR, sem\nnunca vazar detalhes internos:\n\n```ts\nimport { normalizeFriendlyError } from '@autonomoss/chat-core'\n\nconst { reason, message } = normalizeFriendlyError(error)\n// reason: FriendlyErrorReason — inclui todos os ApiErrorReason do contrato\n// + 'config_error' | 'insufficient_scope' | 'network_error' | 'server_error' | 'stream_interrupted'\n// message: string já traduzida, segura para mostrar ao usuário\n```\n\n## Telemetria (opt-in)\n\nDesligada por padrão. Se habilitada, recebe **somente** estados e razões\nfechadas — nunca mensagem, anexo, atributo ou token:\n\n```ts\ntelemetry: {\n  enabled: true,\n  onEvent: (event) => {\n    // { type: 'session', state: 'bootstrapped' | 'refreshed' | 'expired' }\n    // { type: 'message', state: 'started' | 'completed' }\n    // { type: 'error', reason: string }\n  },\n}\n```\n\n## Segurança\n\n- A `pk_` é pública e pode ficar no frontend. O SDK nunca pede `sk_`.\n- Nada é persistido em `localStorage`, `sessionStorage` ou cookies — sessão\n  e atributos seguros vivem só em memória, pelo tempo de vida da página.\n- Atributos seguros são resolvidos sob demanda a cada bootstrap/refresh e\n  nunca cacheados entre chamadas.\n- O contrato de tipos (`generated/api.d.ts`) é gerado a partir de\n  [`contract/openapi.yaml`](https://github.com/autonomoss/autonomoss-web-sdk/blob/main/contract/openapi.yaml)\n  — nunca escrito à mão, para não haver deriva entre SDK e backend.\n\n## Browser / runtime\n\n- Requer `fetch`, `AsyncGenerator`/`for await`, `ReadableStream` (para SSE)\n  e `URL` — presentes em todos os browsers modernos (últimas 2 versões de\n  Chrome/Firefox/Safari/Edge) e em runtimes Node ≥ 20.\n- Sem dependência de DOM: `@autonomoss/chat-core` roda igualmente em Node\n  (ex. testes, scripts) e no browser.\n\n## Troubleshooting\n\n- **CORS**: o backend valida o `Origin` da requisição contra os domínios\n  permitidos configurados no widget (tela de admin do Autonomoss Studio).\n  Um erro `origin_not_allowed` normalmente significa que o domínio atual\n  não está na allowlist do widget.\n- **Sessão expirando em loop**: o SDK já tenta renovar a sessão uma vez\n  automaticamente em `token_expired` (ver `withSessionRefreshRetry`); se\n  isso persistir, o atributo seguro (ex. token Keycloak) provavelmente está\n  expirado/inválido no callback — confira o que ele está retornando.\n- **Streaming não chega**: confirme que nada no caminho (proxy reverso,\n  CDN) está bufferizando a resposta SSE — `Content-Type: text/event-stream`\n  precisa passar sem buffer.\n\n## Versionamento\n\nEste pacote segue [Changesets](https://github.com/changesets/changesets).\nMudanças entram via `pnpm changeset` na raiz do monorepo; o\n[`CHANGELOG.md`](https://github.com/autonomoss/autonomoss-web-sdk/blob/main/packages/core/CHANGELOG.md)\né gerado a partir disso.\n","readmeFilename":""}