143 lines
3.7 KiB
TypeScript
143 lines
3.7 KiB
TypeScript
import type { ToolCallUpdate } from '@agentclientprotocol/sdk';
|
|
import type { NotificationEvent } from '../../types/message';
|
|
import type { AcpChatStateChange } from './shared';
|
|
import { isRecord } from './shared';
|
|
|
|
type ToolNotification =
|
|
| {
|
|
type: 'message';
|
|
params: LoggingMessageNotificationParams;
|
|
}
|
|
| {
|
|
type: 'progress';
|
|
params: ProgressNotificationParams;
|
|
}
|
|
| {
|
|
type: 'platform_event';
|
|
params: PlatformEventParams;
|
|
};
|
|
|
|
type LoggingMessageNotificationParams = {
|
|
level: string;
|
|
logger?: string;
|
|
data: unknown;
|
|
};
|
|
|
|
type ProgressNotificationParams = {
|
|
progressToken: string | number;
|
|
progress: number;
|
|
total?: number;
|
|
message?: string;
|
|
};
|
|
|
|
type PlatformEventParams = Record<string, unknown>;
|
|
|
|
export function toolNotificationChange(
|
|
update: ToolCallUpdate
|
|
): Extract<AcpChatStateChange, { type: 'notification' }> | undefined {
|
|
const notification = toolNotificationEvent(update);
|
|
if (!notification) {
|
|
return undefined;
|
|
}
|
|
|
|
return {
|
|
type: 'notification',
|
|
notification,
|
|
};
|
|
}
|
|
|
|
export function toolNotificationEvent(update: ToolCallUpdate): NotificationEvent | undefined {
|
|
const toolNotification = parseToolNotification(update._meta);
|
|
if (!toolNotification) {
|
|
return undefined;
|
|
}
|
|
|
|
return toNotificationEvent(update.toolCallId, toolNotification);
|
|
}
|
|
|
|
function parseToolNotification(meta: unknown): ToolNotification | undefined {
|
|
if (!isRecord(meta)) {
|
|
return undefined;
|
|
}
|
|
|
|
const toolNotification = meta.toolNotification;
|
|
if (!isRecord(toolNotification)) {
|
|
return undefined;
|
|
}
|
|
|
|
if (toolNotification.type === 'message') {
|
|
const params = parseLoggingMessageParams(toolNotification.params);
|
|
return params ? { type: 'message', params } : undefined;
|
|
}
|
|
|
|
if (toolNotification.type === 'progress') {
|
|
const params = parseProgressParams(toolNotification.params);
|
|
return params ? { type: 'progress', params } : undefined;
|
|
}
|
|
|
|
if (toolNotification.type === 'platform_event') {
|
|
const params = parsePlatformEventParams(toolNotification.params);
|
|
return params ? { type: 'platform_event', params } : undefined;
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
function parseLoggingMessageParams(value: unknown): LoggingMessageNotificationParams | undefined {
|
|
if (!isRecord(value) || typeof value.level !== 'string' || !('data' in value)) {
|
|
return undefined;
|
|
}
|
|
|
|
return {
|
|
level: value.level,
|
|
...(typeof value.logger === 'string' ? { logger: value.logger } : {}),
|
|
data: value.data,
|
|
};
|
|
}
|
|
|
|
function parseProgressParams(value: unknown): ProgressNotificationParams | undefined {
|
|
if (
|
|
!isRecord(value) ||
|
|
(typeof value.progressToken !== 'string' && typeof value.progressToken !== 'number') ||
|
|
typeof value.progress !== 'number'
|
|
) {
|
|
return undefined;
|
|
}
|
|
|
|
return {
|
|
progressToken: value.progressToken,
|
|
progress: value.progress,
|
|
...(typeof value.total === 'number' ? { total: value.total } : {}),
|
|
...(typeof value.message === 'string' ? { message: value.message } : {}),
|
|
};
|
|
}
|
|
|
|
function parsePlatformEventParams(value: unknown): PlatformEventParams | undefined {
|
|
return isRecord(value) ? value : undefined;
|
|
}
|
|
|
|
function toNotificationEvent(
|
|
toolCallId: string,
|
|
toolNotification: ToolNotification
|
|
): NotificationEvent {
|
|
return {
|
|
type: 'Notification',
|
|
request_id: toolCallId,
|
|
message: {
|
|
method: notificationMethod(toolNotification),
|
|
params: toolNotification.params,
|
|
},
|
|
};
|
|
}
|
|
|
|
function notificationMethod(toolNotification: ToolNotification): string {
|
|
switch (toolNotification.type) {
|
|
case 'message':
|
|
return 'notifications/message';
|
|
case 'progress':
|
|
return 'notifications/progress';
|
|
case 'platform_event':
|
|
return 'platform_event';
|
|
}
|
|
}
|