@impalasys/talon-chat
v0.2.11
Published
React chat panels for Talon agent sessions and channels
Readme
@impalasys/talon-chat
@impalasys/talon-chat provides React panels for Talon agent sessions and channels.
Install
pnpm add @impalasys/talon-chat @impalasys/talon-clientreact and react-dom are required peer dependencies.
Usage
import { createTalonClient } from "@impalasys/talon-client";
import { TalonSession } from "@impalasys/talon-chat";
const gatewayClient = createTalonClient({
baseUrl: "http://localhost:50051",
authToken: "secret-token",
});
export function App() {
return (
<TalonSession
namespace="support"
agent="docs"
gatewayClient={gatewayClient}
/>
);
}Keep session state in your app when you want to control which transcript is shown:
<TalonSession
namespace="support"
agent="docs"
gatewayClient={gatewayClient}
sessionId={sessionId}
onSessionChange={(nextSessionId) => setSessionId(nextSessionId)}
/>TalonCopilot is still exported as an alias for existing integrations.
Styling
The chat text defaults to a 16px reading size. Hosts can tune the main message and composer sizes with CSS variables:
:root {
--talon-chat-message-font-size: 1rem;
--talon-chat-composer-font-size: 1rem;
}Image uploads
TalonSession can accept image attachments when you provide an onImageUpload
callback. The callback is responsible for uploading bytes to your object store
or backend upload route and returning the Talon ObjectRef. The chat request
then sends only text plus object references.
<TalonSession
namespace="support"
agent="docs"
gatewayClient={gatewayClient}
onImageUpload={async ({ file, namespace, agent, sessionId, signal }) => {
const form = new FormData();
form.set("file", file);
form.set("namespace", namespace);
form.set("agent", agent);
form.set("sessionId", sessionId);
const response = await fetch("/api/talon/objects", {
method: "POST",
body: form,
signal,
});
if (!response.ok) {
throw new Error(`Upload failed: ${response.status}`);
}
return response.json();
}}
/>The uploader may return either an ObjectRef directly or { object:
ObjectRef }. Supported image types default to PNG, JPEG, GIF, and WebP. Use
acceptedImageTypes, maxImageAttachments, and maxImageBytes to tune the
composer validation.
Commands
Both TalonSession and TalonChannel can intercept slash commands before they are sent as chat messages. Enable the built-in session /clear command with enabledBuiltInCommands:
<TalonSession
namespace="support"
agent="docs"
gatewayClient={gatewayClient}
enabledBuiltInCommands={["clear"]}
/>For sessions, /clear calls the gateway session clear API when a session is active and then clears the visible transcript. Channels do not include a built-in clear command because channel messages are shared history, not per-session transcript state.
You can also provide custom commands:
<TalonChannel
namespace="support"
channel="incident-room"
gatewayClient={gatewayClient}
commands={[
{
name: "ack",
description: "Acknowledge the active incident room.",
run: ({ target }) => console.log(`Acknowledged ${target.channel}`),
},
]}
/>Channels can be rendered with the same package:
import { createTalonClient } from "@impalasys/talon-client";
import { TalonChannel } from "@impalasys/talon-chat";
const gatewayClient = createTalonClient({
baseUrl: "http://localhost:50051",
authToken: `Bearer ${channelJwt}`,
});
<TalonChannel
namespace="support"
channel="incident-room"
gatewayClient={gatewayClient}
disableUserInput
renderMessageActions={(message) => {
const agent = message.sourceAgent || message.source_agent;
const sessionId = message.sourceSessionId || message.source_session_id;
return agent && sessionId ? <button>Open session</button> : null;
}}
/>For local development with untrusted frontends, mint a short-lived channel token from the platform private PEM and pass it as a Bearer token:
TALON_JWT_ISSUER=https://talon.localhost \
talon-cli auth local-token \
--private-key-pem-file ./talon-jwt-private-key.pem \
--namespace support \
--channel incident-room \
--ttl-seconds 900In production, mint frontend tokens through your trusted backend after OIDC-authenticated authorization.
Resource URIs
Assistant and user messages can include Talon resource URIs:
| Scheme | Format | Example |
| --- | --- | --- |
| Artifact | artifact://<namespace>/<agent>/<session>/<artifact_id> | artifact://Tenant:acme:Ops/writer/sess-1/draft |
| File | file://<namespace>/<file_name> | file://Tenant:acme:Ops/memory-brand-guidelines |
Bare URIs (and markdown links with those schemes) render as clickable links.
In TalonSession, clicking a resource opens a split pane next to the chat
when the gateway client exposes the matching service:
const gatewayClient = createTalonClient({ baseUrl, authToken });
// gatewayClient.artifacts and gatewayClient.files are used automatically.
<TalonSession
namespace="support"
agent="docs"
gatewayClient={gatewayClient}
sessionId={sessionId}
/>- Artifacts load via
artifacts.readArtifact(caller agent/session headers are attached from the session props for owner reads). - Files load via
files.readFilewith{ file: { uri } }. - Hosts can take over with
onResourceClick(no built-in pane) or override loading withfetchResource. TalonChannellinkifies and callsonResourceClickonly; it does not open a built-in pane yet.
Helpers parseResourceUri, isResourceUri, and linkifyResourceUris are
exported for host apps.
OS-style paths like file:///tmp/foo are not treated as Talon file URIs.
Session Artifacts
Enable the optional session Artifact card when users should be able to browse outputs that are not linked directly in the transcript:
<TalonSession
namespace="support"
agent="docs"
sessionId={sessionId}
gatewayClient={gatewayClient}
showSessionArtifacts
/>The card appears only when the session has Artifacts, lists them via
artifacts.listArtifacts, and selecting
one opens the same read-only split-pane viewer used by artifact:// links.
Storybook and Chromatic
Run the component preview locally:
pnpm --filter @impalasys/talon-chat storybookBuild the static Storybook:
pnpm --filter @impalasys/talon-chat build-storybookPublish visual snapshots to Chromatic:
CHROMATIC_PROJECT_TOKEN=chpt_... pnpm --filter @impalasys/talon-chat chromaticGitHub Actions also publishes Chromatic builds for packages/talon-chat changes. Configure the repository secret CHROMATIC_PROJECT_TOKEN before enabling that check.
