
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
@automattic/agenttic-client
Advanced tools
A TypeScript client library for A2A (Agent2Agent) protocol communication
A TypeScript client library for Agent2Agent (A2A) protocol communication with React hooks and component integration. Built for seamless AI agent integration in both browser and Node.js environments.
npm install @automattic/agenttic-client
useAgentChat
, useClientContext
, useClientTools
)import { useAgentChat } from '@automattic/agenttic-client';
function ChatComponent() {
const {
messages,
isProcessing,
error,
onSubmit,
registerSuggestions,
registerMarkdownComponents
} = useAgentChat({
agentId: 'big-sky',
sessionId: 'my-session-123',
authProvider: async () => ({ Authorization: 'Bearer your-token' })
});
return (
<div>
{messages.map(msg => (
<div key={msg.id} className={msg.role}>
{msg.content.map(content => content.text).join('')}
</div>
))}
<input
onKeyDown={(e) => e.key === 'Enter' && onSubmit(e.target.value)}
disabled={isProcessing}
/>
{error && <div>Error: {error}</div>}
</div>
);
}
import { useAgentChat, useClientTools, useClientContext } from '@automattic/agenttic-client';
function AdvancedChatComponent() {
const contextProvider = useClientContext(() => ({
page: window.location.href,
timestamp: Date.now(),
userRole: getCurrentUserRole()
}));
const toolProvider = useClientTools(
async () => [
{
id: 'calculator',
name: 'Calculator',
description: 'Perform mathematical calculations',
input_schema: {
type: 'object',
properties: {
expression: { type: 'string' }
},
required: ['expression']
}
}
],
async (toolId, args) => {
if (toolId === 'calculator') {
return { result: calc(args.expression)};
}
}
);
const chat = useAgentChat({
agentId: 'big-sky',
contextProvider,
toolProvider,
authProvider: async () => ({ Authorization: 'Bearer token' })
});
return <ChatInterface {...chat} />;
}
The primary hook for chat functionality, providing everything needed for a complete chat interface.
const {
// Chat state
messages, // UIMessage[] - formatted for display
isProcessing, // boolean - request in progress
error, // string | null - last error
// Core methods
onSubmit, // (message: string) => Promise<void>
abortCurrentRequest, // () => void - cancel in-flight request
// Configuration
registerSuggestions, // (suggestions: Suggestion[]) => void
registerMarkdownComponents, // (components: MarkdownComponents) => void
registerMessageActions, // (registration: MessageActionsRegistration) => void
// Utilities
messageRenderer, // React component for markdown rendering
addMessage, // (message: UIMessage) => void
} = useAgentChat( config );
Config Options:
agentId: string
- Required. Agent identifieragentUrl?: string
- Agent endpoint URL (defaults to WordPress.com)sessionId?: string
- Session ID for conversation persistencecontextProvider?: ContextProvider
- Dynamic context injectiontoolProvider?: ToolProvider
- Tool execution capabilitiesauthProvider?: AuthProvider
- Authentication headersProvides dynamic context that refreshes with each message.
const contextProvider = useClientContext( () => ( {
currentPage: {
url: window.location.href,
title: document.title,
selectedText: getSelection(),
},
user: {
role: getUserRole(),
permissions: getPermissions(),
},
timestamp: Date.now(),
} ) );
Enables agents to execute tools in your application.
const toolProvider = useClientTools(
// Define available tools
async () => [
{
id: 'file-reader',
name: 'File Reader',
description: 'Read file contents',
input_schema: {
type: 'object',
properties: {
path: { type: 'string' },
},
required: [ 'path' ],
},
},
],
// Execute tool calls
async ( toolId, args ) => {
if ( toolId === 'file-reader' ) {
return { content: await readFile( args.path ) };
}
throw new Error( `Unknown tool: ${ toolId }` );
}
);
Low-level client for direct A2A communication without React.
import { createClient } from '@automattic/agenttic-client';
const client = createClient({
agentId: 'big-sky',
authProvider: async () => ({ Authorization: 'Bearer token' }),
toolProvider: {
getAvailableTools: async () => [...],
executeTool: async (toolId, args) => ({ result: '...' })
}
});
// Non-streaming
const task = await client.sendMessage({
message: createTextMessage('Hello'),
sessionId: 'session-123'
});
// Streaming
for await (const update of client.sendMessageStream({
message: createTextMessage('Hello'),
sessionId: 'session-123'
})) {
console.log(update.text);
if (update.final) break;
}
// With abort control
const abortController = new AbortController();
const task = await client.sendMessage({
message: createTextMessage('Hello'),
sessionId: 'session-123',
abortSignal: abortController.signal
});
// Cancel the request
abortController.abort();
Functional singleton for managing multiple agent instances.
import { getAgentManager } from '@automattic/agenttic-client';
const manager = getAgentManager();
// Create agent
await manager.createAgent( 'my-agent', {
agentId: 'big-sky',
sessionId: 'session-123',
contextProvider,
toolProvider,
} );
// Send messages
const task = await manager.sendMessage( 'my-agent', 'Hello' );
// Streaming
for await ( const update of manager.sendMessageStream( 'my-agent', 'Hello' ) ) {
console.log( update );
}
// Manage conversation
const history = manager.getConversationHistory( 'my-agent' );
await manager.resetConversation( 'my-agent' );
Cancel in-flight requests using the built-in abort functionality:
const { abortCurrentRequest, isProcessing } = useAgentChat(config);
// Cancel current request
if (isProcessing) {
abortCurrentRequest();
}
For low-level client usage, use AbortController
:
import { createClient, createAbortController } from '@automattic/agenttic-client';
const client = createClient(config);
const abortController = createAbortController();
// Start a request with abort signal
const requestPromise = client.sendMessage({
message: createTextMessage('Hello'),
abortSignal: abortController.signal
});
// Cancel the request
abortController.abort();
// Handle cancellation
try {
await requestPromise;
} catch (error) {
if (error.name === 'AbortError') {
console.log('Request was cancelled');
}
}
Add interactive buttons to agent messages:
const { registerMessageActions, createFeedbackActions } =
useAgentChat( config );
// Built-in feedback actions
registerMessageActions(
createFeedbackActions( {
onFeedback: async ( messageId, feedback ) => {
console.log( `${ feedback } feedback for ${ messageId }` );
},
icons: { up: '👍', down: '👎' },
} )
);
// Custom actions
registerMessageActions( {
id: 'copy-actions',
actions: [
{
id: 'copy',
label: 'Copy',
icon: '📋',
onClick: ( message ) =>
navigator.clipboard.writeText( message.content[ 0 ].text ),
},
],
} );
Extend markdown rendering with custom components:
import { BarChart, LineChart } from '@automattic/agenttic-client';
const { registerMarkdownComponents, registerMarkdownExtensions } = useAgentChat(config);
// Register chart components
registerMarkdownComponents( {
// Custom heading styles
h1: ({ children }) => (
<h1 className="text-2xl font-bold text-brand">{children}</h1>
),
// Custom code blocks with syntax highlighting
code: ({ children, className }) => (
<SyntaxHighlighter language={className}>
{children}
</SyntaxHighlighter>
),
// Custom link handling
a: ({ href, children }) => (
<a href={href} target="_blank" rel="noopener">
{children} ↗
</a>
),
blockquote: ( { children, ...props } ) => (
<blockquote
{ ...props }
style={ {
borderLeft: '4px solid #007cba',
backgroundColor: '#f0f8ff',
margin: '16px 0',
padding: '12px 16px',
fontStyle: 'italic',
borderRadius: '0 4px 4px 0',
} }
>
{ children }
</blockquote>
),
});
// Register custom extensions
registerMarkdownExtensions({
charts: {
BarChart,
LineChart
}
});
Provide suggested prompts to users:
const { registerSuggestions, clearSuggestions } = useAgentChat( config );
registerSuggestions( [
{
id: '1',
label: 'Help me write code',
prompt: 'Can you help me write a function?',
},
{
id: '2',
label: 'Explain this error',
prompt: 'What does this error mean?',
},
] );
interface UIMessage {
id: string;
role: 'user' | 'agent';
content: Array< {
type: 'text' | 'image_url' | 'component';
text?: string;
image_url?: string;
component?: React.ComponentType;
} >;
timestamp: number;
actions?: UIMessageAction[];
}
interface Tool {
id: string;
name: string;
description: string;
input_schema: {
type: 'object';
properties: Record< string, any >;
required?: string[];
};
}
type AuthProvider = () => Promise< Record< string, string > >;
type ContextProvider = { getClientContext: () => any };
type ToolProvider = {
getAvailableTools: () => Promise< Tool[] >;
executeTool: ( toolId: string, args: any ) => Promise< any >;
};
# Build the package
pnpm build
# Run tests
pnpm test
# Type checking
pnpm type-check
# Lint
pnpm lint
FAQs
A TypeScript client library for A2A (Agent2Agent) protocol communication
The npm package @automattic/agenttic-client receives a total of 6,691 weekly downloads. As such, @automattic/agenttic-client popularity was classified as popular.
We found that @automattic/agenttic-client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 52 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.