Advertisement

← vibesdk

worker/agents/inferutils/common.ts

3.2 KB Download file
// Provider-agnostic tool call shape used across providers.
export type ToolCall = {
	id: string;
	type: 'function';
	function: {
		name: string;
		arguments: string;
	};
};

// Define allowed message roles for type safety
export type MessageRole = 'system' | 'user' | 'assistant' | 'function' | 'tool';

// Define content types for multi-modal support
export type TextContent = {
	type: 'text';
	text: string;
};

export type ImageContent = {
	type: 'image_url';
	image_url: {
		url: string; // Can be a URL or base64 data URL
		detail?: 'auto' | 'low' | 'high'; // Optional detail level for vision models
	};
};

export type MessageContent = string | (TextContent | ImageContent)[] | null;

// Define a proper message type that matches OpenAI's requirements and supports multi-modal content
export type Message = {
	role: MessageRole;
	content: MessageContent;
	name?: string; // Optional name field required for function messages
	tool_calls?: ToolCall[];
    tool_call_id?: string;  // For role = tool
    reasoning?: string; // Optional assistant reasoning ("thinking") text, preserved for UI reload
};

export interface ConversationMessage extends Message {
	conversationId: string;
}

export interface ConversationState {
    // Conversation Session ID
    id: string;
    // Running history of messages
    runningHistory: ConversationMessage[];
    // Full history of messages
    fullHistory: ConversationMessage[];
}

/**
 * Create a standard user message with content
 */
export function createUserMessage(content: MessageContent) {
	return {
		role: 'user' as MessageRole,
		content,
	};
}

/**
 * Create a standard system message with content
 */
export function createSystemMessage(content: string) {
	return {
		role: 'system' as MessageRole,
		content,
	};
}

/**
 * Create a standard assistant message with content
 */
export function createAssistantMessage(content: string) {
	return {
		role: 'assistant' as MessageRole,
		content,
	};
}

/**
 * Create a multi-modal user message with text and image content
 */
export function createMultiModalUserMessage(
	text: string,
	imageUrls: string | string[],
	detail?: 'auto' | 'low' | 'high',
): {
	role: MessageRole;
	content: (TextContent | ImageContent)[];
} {
	const urls = Array.isArray(imageUrls) ? imageUrls : [imageUrls];
	
	return {
		role: 'user' as MessageRole,
		content: [
			{
				type: 'text',
				text,
			},
			...urls.map(url => ({
				type: 'image_url' as const,
				image_url: {
					url,
					detail: detail || 'auto',
				},
			})),
		],
	};
}

export async function mapImagesInMultiModalMessage(message: ConversationMessage, fn: (content: ImageContent) => Promise<ImageContent>) {
    // Check if message is of type multi-modal
    if (message.content && Array.isArray(message.content)) {
        message.content = await Promise.all(message.content.map(c => {
                if (c.type === 'image_url') {
                    return fn(c);
                }
                return c;
            })
        )
    }

    return message;
}

/**
 * Represents a completion signal detected from tool execution
 */
export interface CompletionSignal {
	signaled: boolean;
	toolName: string;
	summary?: string;
	timestamp: number;
}