Variables and Tool Functions
Overview
When working with AI agents in trading platforms like ViRi, they often need to access dynamic market data such as:
- Current symbol price and trading data
- Technical indicators (RSI, MACD, Moving Averages, etc.)
- Market news and analysis
- Chart patterns and signals
ViRi AI makes this easy through two main concepts:
-
Variables: These are like containers that hold dynamic trading data. They can be used in prompts or user requests and will automatically update with real market data when needed. For example:
#currentPrice: Shows the current price of the selected symbol#technicalIndicators: Displays values of technical indicators#marketNews: Provides latest news related to the symbol
-
Tool Functions: These allow AI agents to actively perform actions, like:
- Fetching real-time market data
- Calculating technical indicators
- Analyzing chart patterns
- Generating trading signals
Variables
ViRi AI supports two types of variables:
-
Global Variables: These are available to all agents and can be used anywhere. For example:
#currentText: Shows the text you've currently selected- Tool developers can add their own global variables to provide additional data
-
Agent-specific Variables: These are only available to specific agents and their prompt templates, not to other agents or in the default chat.
Agent-specific Variables
Let's look at a practical example. Say we want to create a chat agent that helps users run commands on trading charts. Here's how we can do it:
// First, get all available commands
const knownCommands: string[] = [];
for (const command of this.commandRegistry.getAllCommands()) {
knownCommands.push(`${command.id}: ${command.label}`);
}
// Then, use this data in the system prompt
const systemPrompt = await this.promptService.getPrompt('command-chat-agent-system-prompt-template', {
'command-ids': knownCommands.join('\n')
});
We can then use this variable in our prompt template like this:
You are a service that helps users run commands on trading charts.
These are the available chart commands:
Begin List:
{{command-ids}}
End List
You can help users:
- Draw technical indicators
- Add chart patterns
- Modify chart settings
- Execute trading signals
To declare an agent-specific variable, add this to your agent's constructor:
this.agentSpecificVariables = [{
name: 'command-ids',
description: 'The list of available commands in the IDE.',
usedInPrompt: true
}];
Global Variables
Global variables are available to all agents. Here's how to create a simple one that shows the current date:
- First, define the variable and its options:
export const TODAY_VARIABLE: AIVariable = {
id: 'today-provider',
description: 'Shows the current date',
name: 'today',
args: [
{ name: TodayVariableArgs.IN_ISO_8601, description: 'Shows date in ISO 8601 format (e.g., 2024-03-20T10:30:00Z)' },
{ name: TodayVariableArgs.IN_UNIX_SECONDS, description: 'Shows date in Unix timestamp format' }
]
};
- Then, create the variable handler:
export class TodayVariableContribution implements AIVariableContribution, AIVariableResolver {
// Register the variable
registerVariables(service: AIVariableService): void {
service.registerResolver(TODAY_VARIABLE, this);
}
// Handle variable requests
async resolve(request: AIVariableResolutionRequest, context: AIVariableContext): Promise<ResolvedAIVariable | undefined> {
if (request.variable.name === TODAY_VARIABLE.name) {
return this.resolveTodayVariable(request);
}
return undefined;
}
private resolveTodayVariable(request: AIVariableResolutionRequest): ResolvedTodayVariable {
const date = new Date();
if (request.arg === TodayVariableArgs.IN_ISO_8601) {
return { variable: request.variable, value: date.toISOString(), date };
}
if (request.arg === TodayVariableArgs.IN_UNIX_SECONDS) {
return { variable: request.variable, value: Math.round(date.getTime() / 1000).toString(), date };
}
return { variable: request.variable, value: date.toDateString(), date };
}
}
// Register the variable
bind(AIVariableContribution).to(TodayVariableContribution).inSingletonScope();
Once created, you can use this variable in any prompt template or user request. For example, typing #today will show the current date or {{today}} in prompt template.
Chat Context Variables
ViRi AI allows you to add important context information to your chat requests using context variables. These are different from regular variables because they provide two pieces of information:
- A value that gets inserted where you use the variable
- A contextValue that contains additional data for the AI to use
Context variables help you make your requests more specific by including things like:
- Trading charts and technical analysis patterns
- Market indicators and their current values
- Trading signals and entry/exit points
- Portfolio positions and performance metrics
- Market news and economic events
The AI agent can handle this context information in different ways:
- Summarization: The agent can create a summary of the context (like listing news) before using it
- Smart Context Management: The agent can:
- Use all context if it's small enough
- Create summaries if there's too much information
- Break down large contexts into smaller parts
- On-Demand Access: Instead of sending all context at once, the agent can fetch specific parts when needed
The context feature is turned on by default, but you can turn it off by changing this setting:
rebind(AIChatInputConfiguration).toConstantValue({
showContext: false,
showPinnedAgent: true
});
Example: News Context Variable
Here's how to set up a news context variable:
export default new ContainerModule(bind => {
...
// Register the basic variable
bind(AIVariableContribution).to(NewsVariableContribution).inSingletonScope();
// Register additional features like auto-completion
bind(AIVariableContribution).to(NewsChatVariableContribution).inSingletonScope();
// Set up how the context element appears in the chat
bind(ContextNewsVariableLabelProvider).toSelf().inSingletonScope();
bind(LabelProviderContribution).toService(ContextNewsVariableLabelProvider);
...
});
News Variable Provider
This code fetches news data and provides both the headline and full content. When you use #news:latest, it:
- Inserts the news headline where you used the variable
- Makes the full news content available to the AI for better responses
export const NEWS_VARIABLE: AIVariable = {
id: 'news-provider',
description: 'Gets the headline and content of news articles',
name: 'news',
label: 'News',
// The icon shown in the user interface
iconClasses: codiconArray('megaphone'),
// Marks this as a context variable
isContextVariable: true,
// The news source and type
args: [{ name: 'source', description: 'The source of the news (e.g., latest, market, company).' }]
};
@injectable()
export class NewsVariableContribution implements AIVariableContribution, AIVariableResolver {
@inject(NewsService)
protected readonly newsService: NewsService;
registerVariables(service: AIVariableService): void {
service.registerResolver(NEWS_VARIABLE, this);
}
async canResolve(request: AIVariableResolutionRequest, _: AIVariableContext): Promise<number> {
return request.variable.name === NEWS_VARIABLE.name ? 1 : 0;
}
async resolve(request: AIVariableResolutionRequest, _: AIVariableContext): Promise<ResolvedAIContextVariable | undefined> {
try {
const newsData = await this.newsService.fetchNews(request.arg);
return {
variable: request.variable,
value: newsData.headline,
contextValue: newsData.content,
};
} catch (error) {
return undefined;
}
}
//...
}
Using Context Variables in Your Agent
Your agent can use context variables in several ways. The context information is available in the ChatRequestModel's context property, and you can decide how to use it.
You can use these special variables in your agent's prompt:
#contextSummary: Shows a list of the context#contextDetails: Shows the full context
Or you can use these tool functions to let the AI get context when needed:
~{context_ListChatContext}~{context_ResolveChatContext}
Important: If you show the context interface in the chat but don't use the context in your agent, users might get unexpected results.
Tool Functions
Tool Functions are ways for AI agents to perform specific actions in ViRi. Unlike Variables which only retrieve information, Tool Functions allow AI to:
- Fetch additional information from the system
- Perform actions like drawing charts and calculating technical indicators
- Interact with other ViRi platform features
For example, you can inform the AI about available Tool Functions in the prompt like this:
You can use the following functions to interact with ViRi:
- ~{searchSymbols}: Search for trading symbols
- ~{getMarketData}: Get market data for symbols
To create a new Tool Function, you need to:
- Create a new class implementing the
ToolProviderinterface - Define the ID, description, and parameters of the function
- Write the handling code in the handler function
Here's an example of a Tool Function to search for trading symbols:
@injectable()
export class SymbolSearchFunction implements ToolProvider {
static ID = 'search-symbols';
getTool(): ToolRequest {
return {
id: SymbolSearchFunction.ID,
name: 'Search Symbols',
description: 'Search for trading symbols based on criteria',
parameters: {
type: 'object',
properties: {
query: {
type: 'string',
description: 'Search query (e.g., "tech stocks", "forex pairs")',
},
market: {
type: 'string',
description: 'Market to search in (e.g., "stocks", "forex", "crypto")',
},
limit: {
type: 'number',
description: 'Maximum number of results to return'
}
}
},
handler: (args: string) => {
const { query, market, limit } = this.parseArgs(args);
return this.searchSymbols(query, market, limit);
}
};
}
}
In the handler function, you can:
- Search through ViRi's symbol database
- Filter results based on market type
- Return relevant trading symbols with their details
Finally, register your new Tool Function by:
bind(ToolProvider).to(SymbolSearchFunction);
After registration, the AI agent can use this function to help users find trading symbols that match their criteria.