@pouchy_ai/react
v0.1.9
Published
React hooks for the Pouchy companion — <CompanionProvider> + useCompanion / useMessages / useTyping / useCall over the @pouchy_ai/companion-sdk.
Maintainers
Readme
@pouchy_ai/react
React hooks for the Pouchy companion — a thin, typed layer
over @pouchy_ai/companion-sdk.
Wrap your app in a <CompanionProvider> and read live state with hooks; the
provider owns the handshake, the auto-reconnecting stream, and teardown.
npm install @pouchy_ai/react @pouchy_ai/companion-sdk reactQuick start
import { useState } from 'react';
import {
CompanionProvider,
useCompanion,
useMessages,
useTyping,
useCall
} from '@pouchy_ai/react';
function Chat() {
const { status, grantedScopes } = useCompanion();
const { messages, send } = useMessages();
const typing = useTyping();
const [text, setText] = useState('');
if (status === 'connecting') return <p>connecting…</p>;
if (status === 'error') return <p>connection failed</p>;
return (
<>
{messages.map((m, i) => (
<p key={i}><b>{m.role}</b> {m.text}</p>
))}
{typing && <p><i>companion is typing…</i></p>}
<form onSubmit={(e) => { e.preventDefault(); send(text); setText(''); }}>
<input value={text} onChange={(e) => setText(e.target.value)} />
</form>
</>
);
}
export default function App() {
return (
<CompanionProvider baseUrl="https://pouchy.ai" token="pchy_…" surface="my-web-app">
<Chat />
</CompanionProvider>
);
}API
<CompanionProvider>
Takes every CompanionClientOptions field
(token, baseUrl, surface, modalities, tools, debug, …) plus:
| prop | meaning |
| --- | --- |
| manualStart? | skip the automatic start() (SSE stream); connect() still runs so scopes/session are ready |
It creates one client, runs connect(), opens the stream, and calls
client.stop() on unmount. The client is recreated only when the
token/baseUrl identity changes.
Hooks
| hook | returns |
| --- | --- |
| useCompanion() | { client, status, session, grantedScopes, error } — client is the full SDK client for anything below |
| useMessages({ restore? }) | { messages, send, ready } — accumulates replies, optimistic user turns, restores recent history on connect (default 20) |
| useTyping() | boolean — a "typing…" indicator spanning the whole turn (incl. the thinking/tool phase) |
| useCall({ locale? }) | { inCall, connecting, speaking, provider, transcript, error, start, hangup, interrupt } — live WebRTC voice; interrupt() silently cuts the current speech (needs companion-sdk ≥ 0.36.0 — a no-op on older peers; best-effort on elevenlabs-convai) |
Anything the hooks don't cover — sendWorldState, recall, ping,
setModalities, onToolCall, sendToolResult — is on the client from
useCompanion(). See the SDK reference.
Notes
reactand@pouchy_ai/companion-sdkare peer dependencies — you install them.- Voice (
useCall) needs thecall+voicescopes on the token and a browser (WebRTC + microphone). The audio path is provider-direct; Pouchy is out of it. - Sensitive actions (pay / message / run a skill) are never executed because a
page said so — the runtime emits
companion.confirm_request, and how it resolves depends on the token: companion tokens (pchy_…) approve on a trusted Pouchy surface, while platform session tokens (fromPOST /v1/sessions) resolve in YOUR app viaclient.confirmAction(confirmId, approved)— build the confirm card yourself. Subscribe viaclient.on('companion.confirm_request', …).
