Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions packages/baseai/src/dev/llms/call-llm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '@/dev/data/models';

import { addContextFromMemory } from '@/utils/memory/lib';
import type { Message } from 'types/pipe';
import type { Message, VariablesI } from 'types/pipe';
import { ApiError } from '../hono/errors';
import type { Pipe } from '../routes/beta/pipes/run';
import { dlog } from '../utils/dlog';
Expand All @@ -30,12 +30,14 @@ export async function callLLM({
pipe,
stream,
messages,
llmApiKey
llmApiKey,
variables
}: {
pipe: Pipe;
stream: boolean;
llmApiKey: string;
messages: Message[];
variables?: VariablesI;
}) {
try {
// Get the model provider from the pipe config.
Expand All @@ -51,7 +53,8 @@ export async function callLLM({
const messagesThread = getRunThread({
pipe,
messages,
similarChunks
similarChunks,
variables
});
messages = messagesThread;

Expand Down
8 changes: 5 additions & 3 deletions packages/baseai/src/dev/routes/beta/pipes/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { dlog } from '@/dev/utils/dlog';
import { handleStreamingResponse } from '@/dev/utils/provider-handlers/streaming-response-handler';
import { logger } from '@/utils/logger-utils';
import { Hono } from 'hono';
import { schemaMessage } from 'types/pipe';
import { schemaMessage, VariablesSchema } from 'types/pipe';
import { z } from 'zod';

// Schema definitions
Expand Down Expand Up @@ -33,7 +33,8 @@ const PipeSchema = z.object({
model: ModelSchema,
messages: z.array(schemaMessage),
functions: z.array(z.unknown()).default([]),
memorysets: z.array(z.string().trim().min(1)).default([])
memorysets: z.array(z.string().trim().min(1)).default([]),
variables: VariablesSchema
});

export type Pipe = z.infer<typeof PipeSchema>;
Expand All @@ -42,7 +43,8 @@ const RequestBodySchema = z.object({
pipe: PipeSchema,
stream: z.boolean(),
messages: z.array(schemaMessage),
llmApiKey: z.string()
llmApiKey: z.string(),
variables: VariablesSchema.optional()
});

type RequestBody = z.infer<typeof RequestBodySchema>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Pipe } from '@/dev/routes/pipes/run';
import type { Pipe } from '@/dev/routes/beta/pipes/run';
import type { Message } from 'types/pipe';

export function getPipeFewShotsMessages(pipe: Pipe): Message[] {
Expand Down
15 changes: 12 additions & 3 deletions packages/baseai/src/dev/utils/thread/get-run-thread.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { ApiError } from '@/dev/hono/errors';
import type { Pipe } from '@/dev/routes/beta/pipes/run';
import type { SimilarChunk } from '@/utils/memory/db/lib';
import type { Message } from 'types/pipe';
import type { Message, VariablesI } from 'types/pipe';
import { dlog } from '../dlog';
import { getPipeFewShotsMessages } from './get-few-shot-messages';
import { getSystemPromptMessage } from './get-system-prompt';
import { processMessages } from './process-messages';

export function getRunThread({
pipe,
messages,
similarChunks
similarChunks,
variables
}: {
pipe: Pipe;
messages: Message[];
similarChunks: SimilarChunk[] | undefined;
variables?: VariablesI;
}) {
try {
const systemPromptMessage = getSystemPromptMessage({
Expand All @@ -30,7 +33,13 @@ export function getRunThread({
...messages
];

return messagesThread;
const { messages: messagesThreadWithVars } = processMessages({
pipe,
messages: messagesThread,
variables
});

return messagesThreadWithVars;
} catch (error: any) {
dlog('Error get-run-thread.ts:', error);

Expand Down
105 changes: 105 additions & 0 deletions packages/baseai/src/dev/utils/thread/process-messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import type { Pipe } from '@/dev/routes/beta/pipes/run';
import type { Message, VariableI, VariablesI } from 'types/pipe';
import { dlog } from '../dlog';

/**
* Process the messages to replace variables with their values
* Replaces variables in messages content with their values
*/
export function processMessages({
pipe,
messages,
variables
}: {
pipe: Pipe;
messages: Message[];
variables?: VariablesI;
}) {
const variablesMap = getVarsMap({ pipe, variables });

const messagesWithVarsValues = replaceVarsInMessagesWithVals({
messages,
variablesMap
});
return { messages: messagesWithVarsValues, variablesMap };
}

function getVarsMap({
pipe,
variables
}: {
pipe: Pipe;
variables?: VariablesI;
}) {
const hasPipeVars = pipe.variables ? pipe.variables.length > 0 : false;
const hasCurrentPromptVars = variables ? variables.length > 0 : false;

const pipeVars = hasPipeVars ? pipe.variables : [];
const currentPromptVars = hasCurrentPromptVars ? variables : [];

let finalVariablesMap: Map<string, string> = new Map();

if (hasPipeVars) {
pipeVars.forEach((v: { name: string; value: string }) =>
finalVariablesMap.set(v.name, v.value)
);
}

if (hasCurrentPromptVars) {
currentPromptVars?.forEach((v: VariableI) =>
finalVariablesMap.set(v.name, v.value)
);
}

// Convert the map back to an array for debugging
let finalVariables: VariableI[] = Array.from(
finalVariablesMap,
([name, value]) => ({
name,
value
})
);
dlog(`finalVariables`, finalVariables);

return finalVariablesMap;
}

// Function to replace variables in the messages
function replaceVarsInMessagesWithVals({
messages,
variablesMap
}: {
messages: Message[];
variablesMap: Map<string, string>;
}): Message[] {
const variableRegex = /{{(.*?)}}/g; // Regex to match double curly braces

return messages.map(message => {
// When Assistant requests a tool call,
// 1- message.content is empty
// 2- message.role is 'assistant'
// 3- message.tool_calls is an array of tool calls requested by LLM.
const isAssistantToolCall =
!message.content &&
message.role === 'assistant' &&
message.tool_calls?.length;

// Since no content to replace variables in, return the message as is.
if (isAssistantToolCall) return message;
if (!message.content) return message;

// Replace variables in the message content
const updatedContent = message.content.replace(
variableRegex,
(match, varName) => {
const trimmedVarName = varName.trim(); // Trim any extra spaces
// If the variable exists in the map, replace with its value; otherwise, leave the placeholder intact
return variablesMap.get(trimmedVarName) || match;
}
);
return {
...message,
content: updatedContent
};
});
}
14 changes: 12 additions & 2 deletions packages/baseai/types/pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ export const schemaMessage = z

export type Message = z.infer<typeof schemaMessage>;

export const VariableSchema = z.object({
name: z.string(),
value: z.string()
});

export const VariablesSchema = z.array(VariableSchema).default([]);

export type VariablesI = z.infer<typeof VariablesSchema>;
export type VariableI = z.infer<typeof VariableSchema>;

interface ToolFunction {
name: string;
}
Expand Down Expand Up @@ -89,7 +99,7 @@ export interface Pipe {
tool_choice: ToolChoice;
parallel_tool_calls: boolean;
messages: Message[];
variables: any[];
variables: VariablesI;
tools: PipeTool[];
memory: {
name: string;
Expand Down Expand Up @@ -126,7 +136,7 @@ export interface PipeOld {
opening: string;
safety: string;
messages: { role: string; content: string }[];
variables: any[];
variables: VariablesI;
json: string;
rag: string;
};
Expand Down