@nomyx/assistant
Version:
A powerful assistant library and cli for your AI projects. works with Vertex AI (Claude and Gemini)
121 lines (104 loc) • 3.54 kB
text/typescript
import { Action, ActionSchema } from '../types/tool';
import { PromptDefinition } from '../types/common';
import { ExtendedActionContext, PromptActionConfig, Route } from './types';
import { ChatMessage, ChatOptions } from '../types/chat';
import { evaluateCondition } from '../utils/conditionEvaluator';
export async function executePromptAction<I, O>(
promptAction: PromptAction<I, O>,
params: I,
context: ExtendedActionContext
): Promise<O> {
if (promptAction.routing && promptAction.routing.length > 0) {
for (const route of promptAction.routing) {
if (evaluateCondition(route.condition, { ...context.state, ...params })) {
if (typeof route.prompt === 'string') {
return context.executeAction!(route.prompt) as Promise<O>;
} else {
return executePromptAction(route.prompt, params, context);
}
}
}
// If no conditions are met, end execution
return null as unknown as O;
}
// Execute the current prompt if no routing or no conditions met
const messages: ChatMessage[] = [
{ role: 'system', content: promptAction.content },
{ role: 'user', content: JSON.stringify(params) }
];
const options: ChatOptions = {
...promptAction.options,
...promptAction.config
};
try {
const result = await context.aiProvider.chat(messages, options);
return result as O;
} catch (error) {
context.logger.error('Error executing prompt action:', error);
throw error;
}
}
// Export a test function to verify routing
export function testPromptRouting(promptAction: PromptAction<any, any>, params: any, context: ExtendedActionContext): string {
let result = 'Routing Test:\n';
if (promptAction.routing && promptAction.routing.length > 0) {
for (const route of promptAction.routing) {
const conditionMet = evaluateCondition(route.condition, { ...context.state, ...params });
result += `Condition "${route.condition}": ${conditionMet ? 'Met' : 'Not Met'}\n`;
if (conditionMet) {
result += `Routing to: ${typeof route.prompt === 'string' ? route.prompt : route.prompt.name}\n`;
break;
}
}
} else {
result += 'No routing defined. Executing current prompt.\n';
}
return result;
}
export class PromptAction<I, O> implements Action<I, O> {
name: string;
content: string;
options?: ChatOptions;
routing?: Route[];
description: string;
schema: ActionSchema<I, O>;
priority?: number;
config?: PromptDefinition['config'];
constructor({
name,
schema,
systemContent,
userContent,
options,
routing,
description,
priority,
config
}: PromptActionConfig) {
this.name = name;
this.schema = schema as ActionSchema<I, O>;
this.content = `${systemContent}\n\n${userContent}. Format your response as a RAW JSON object with NO codeblocks. Use format:${JSON.stringify(
schema.output
)}`;
this.options = options;
this.routing = routing;
this.description = description || '';
this.priority = priority;
this.config = config;
}
async execute(params: I, context: ExtendedActionContext): Promise<O> {
return executePromptAction(this, params, context);
}
getPriority(): number | undefined {
return this.priority;
}
setPriority(priority: number): void {
this.priority = priority;
}
getConfig(): PromptDefinition['config'] | undefined {
return this.config;
}
setConfig(config: PromptDefinition['config']): void {
this.config = config;
}
}