
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
@redhat-cloud-services/ai-client-common
Advanced tools
Common interfaces and utilities for AI client packages in the Red Hat Cloud Services ecosystem.
Common interfaces and utilities for AI client packages in the Red Hat Cloud Services ecosystem.
IAIClient
interface for all AI servicesnpm install @redhat-cloud-services/ai-client-common
All AI clients in this workspace implement the IAIClient
interface:
import { IAIClient, ClientInitLimitation, IInitErrorResponse } from '@redhat-cloud-services/ai-client-common';
declare class IAIClient<AP extends Record<string, unknown> = Record<string, unknown>> {
constructor(config: IBaseClientConfig);
init(): Promise<{
conversations: IConversation[];
limitation?: ClientInitLimitation;
error?: IInitErrorResponse;
}>;
// Basic message sending
sendMessage<T extends Record<string, unknown> = Record<string, unknown>>(
conversationId: string,
message: string,
options?: ISendMessageOptions<T>
): Promise<IMessageResponse<AP>>;
// Message sending with custom request payload
sendMessage<
T extends Record<string, unknown> = Record<string, unknown>,
R extends Record<string, unknown> = Record<string, unknown>
>(
conversationId: string,
message: string,
options?: ISendMessageOptions<T, R>
): Promise<IMessageResponse<AP>>;
getConversationHistory(conversationId: string, options?: IRequestOptions): Promise<IConversationHistoryResponse<AP>>;
healthCheck(options?: IRequestOptions): Promise<unknown>;
getServiceStatus?(options?: IRequestOptions): Promise<unknown>;
createNewConversation(): Promise<IConversation>;
}
Important: Do NOT set 'Content-Type'
headers in your fetchFunction - AI clients manage these internally based on endpoint requirements.
import { IFetchFunction } from '@redhat-cloud-services/ai-client-common';
const customFetch: IFetchFunction = async (input, init) => {
// Add authentication headers
const token = await getAuthToken();
return fetch(input, {
...init,
headers: {
...init?.headers,
'Authorization': `Bearer ${token}`,
// DO NOT set 'Content-Type' - AI clients handle this internally
},
});
};
import { IBaseClientConfig } from '@redhat-cloud-services/ai-client-common';
const config: IBaseClientConfig = {
baseUrl: 'https://your-ai-service.com',
fetchFunction: customFetch // Optional - defaults to native fetch
};
AI clients now use lazy initialization by default. The init()
method no longer auto-creates conversations - instead, conversations are created automatically when needed (e.g., on first message send).
Default Behavior:
init()
only loads existing conversationssendMessage()
callKey Changes:
ClientInitOptions
interface (no longer needed)getInitOptions()
method from IAIClient
interfaceinitialConversationId
from init()
return typeThe init()
method returns additional information about client limitations and errors:
import { ClientInitLimitation, IInitErrorResponse } from '@redhat-cloud-services/ai-client-common';
// Client limitations (e.g., quota exceeded)
type ClientInitLimitation = {
reason: string;
detail?: string;
};
// Initialization errors
interface IInitErrorResponse {
message: string;
status: number;
}
// Utility function to check if an object is an IInitErrorResponse
function isInitErrorResponse(obj: unknown): obj is IInitErrorResponse;
The streaming interface has been updated to standardize chunk handling across all AI clients. The handleChunk
callback now receives an IStreamChunk
object with standardized structure.
import { IStreamChunk } from '@redhat-cloud-services/ai-client-common';
interface IStreamChunk<T extends Record<string, unknown> = Record<string, unknown>> {
answer: string;
messageId: string;
conversationId: string;
additionalAttributes: T;
}
import { IStreamingHandler, HandleChunkCallback, IStreamChunk } from '@redhat-cloud-services/ai-client-common';
class CustomStreamingHandler<TChunk = unknown> implements IStreamingHandler<TChunk> {
onChunk(chunk: TChunk, handleChunk?: HandleChunkCallback): void {
console.log('Received chunk:', chunk);
// Process the chunk and call handleChunk with standardized format
if (handleChunk) {
handleChunk({
answer: extractAnswer(chunk), // Extract answer from chunk
additionalAttributes: extractAttributes(chunk) // Extract additional data
});
}
}
onStart?(conversationId?: string, messageId?: string): void {
console.log('Stream started', { conversationId, messageId });
}
onComplete?(finalChunk: TChunk): void {
console.log('Stream completed:', finalChunk);
}
onError?(error: Error): void {
console.error('Stream error:', error);
}
onAbort?(): void {
console.log('Stream aborted');
}
}
import { ISendMessageOptions, IStreamChunk } from '@redhat-cloud-services/ai-client-common';
// Basic streaming options
const streamingOptions: ISendMessageOptions = {
stream: true,
headers: { 'Custom-Header': 'value' },
signal: abortController.signal,
handleChunk: (chunk: IStreamChunk) => {
// Process each standardized chunk as it arrives
console.log('Answer:', chunk.answer);
console.log('Message ID:', chunk.messageId);
console.log('Conversation ID:', chunk.conversationId);
console.log('Additional data:', chunk.additionalAttributes);
updateUI(chunk.answer);
}
};
// Options with custom request payload (client-specific)
const optionsWithPayload: ISendMessageOptions<AdditionalProps, CustomPayload> = {
stream: false,
headers: { 'X-Custom': 'value' },
requestPayload: {
// Client-specific payload data
customData: 'value',
options: { setting: true }
}
};
The ISendMessageOptions
interface supports method overloading to enable client-specific request payloads:
// Interface definition
export interface ISendMessageOptions<
T extends Record<string, unknown> = Record<string, unknown>,
R extends Record<string, unknown> = never
> extends IRequestOptions {
stream?: boolean;
handleChunk?: HandleChunkCallback<T>;
requestPayload?: R extends never ? never : R;
}
// Usage with client-specific payload
interface MyClientPayload {
context?: { systemInfo: string };
skipCache?: boolean;
}
const response = await client.sendMessage(
'conversation-id',
'message',
{
requestPayload: {
context: { systemInfo: 'linux' },
skipCache: true
}
}
);
import {
AIClientError,
AIClientValidationError
} from '@redhat-cloud-services/ai-client-common';
try {
const response = await client.sendMessage(conversationId, message);
} catch (error) {
if (error instanceof AIClientValidationError) {
console.error('Validation errors:', error.validationErrors);
error.validationErrors.forEach(validationError => {
console.log(`Field: ${validationError.loc.join('.')}`);
console.log(`Message: ${validationError.msg}`);
console.log(`Type: ${validationError.type}`);
});
} else if (error instanceof AIClientError) {
console.error(`API Error ${error.status}: ${error.message}`);
console.error('Response data:', error.data);
} else {
console.error('Unexpected error:', error);
}
}
import {
IRequestOptions,
IMessageResponse,
IConversationHistoryResponse,
IConversation
} from '@redhat-cloud-services/ai-client-common';
// Standard request options
const options: IRequestOptions = {
headers: { 'Custom-Header': 'value' },
signal: new AbortController().signal
};
// Message response structure
interface IMessageResponse<AP = Record<string, unknown>> {
messageId: string;
answer: string;
conversationId: string;
date?: Date;
additionalAttributes?: AP;
}
// Conversation structure
interface IConversation {
id: string;
title: string;
locked: boolean; // Prevents new messages when true
createdAt: Date;
}
This package provides the foundation for:
Run nx build ai-client-common
to build the library.
Run nx test ai-client-common
to execute the unit tests via Jest.
This package follows the workspace standards:
any
typesFAQs
Common interfaces and utilities for AI client packages in the Red Hat Cloud Services ecosystem.
The npm package @redhat-cloud-services/ai-client-common receives a total of 161 weekly downloads. As such, @redhat-cloud-services/ai-client-common popularity was classified as not popular.
We found that @redhat-cloud-services/ai-client-common demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 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
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.