Alokai Compass
Alokai Compass is a powerful framework designed for building AI workflows in e-commerce applications. It allows you to enhance your customers' journey. For example, you can build workflows that will help users:
- Search for products faster
- Compare different products and find the best pick
- Rate products by specific use cases
- Automate bulk-orders
Architecture
Alokai Compass module consists of two main elements:
- @alokai/compass: core library exporting AI integration, utils and type definitions to be used in your Storefront,
- @alokai/compass-module: an out-of-the-box set of configuration files, workflows, tools, assets, components and hooks copied over to your Storefront during the module installation process

To adjust out-of-the-box functionalities provided by @alokai/compass-module and create your own, you have to get familiar with the building blocks provided by @alokai/compass: Workflows, Actions, Tools and Transitions.
Workflows
Workflow is the core building block of Alokai Compass. It represents a single, focused type of AI interaction. Think of it as a conversation path that helps users accomplish specific tasks. Each workflow consists of the following key components:
- Actions: specific tasks performed by LLM
- Tools: functions available in actions, callable by LLM
- Transitions: map of how workflow actions are linked to each other
import { defineWorkflow } from '@alokai/compass';
const assistantWorkflow = defineWorkflow({
actions: {},
toolkits: [],
transitions: {},
startingPrompt: ''
});
Actions
Action is a specific task the LLM performs within a workflow. When defining an action, you need to:
- choose AI model the action should use,
- define prompts the action's AI model should follow,
- choose tools the action's AI model should have access to.
Example
import { defineAction } from '@alokai/compass';
const assistantAction = defineAction({
model: 'heavy',
prompt: 'You are an assistant in a clothing store',
type: 'llm',
toolkit: ['searchProducts'],
});
Tools
Tool is a special Javascript function that can be called by an LLM within an Action. It comes with name, description and - optionally - a Zod schema informing the LLM about the expected tool arguments.
Tools are defined globally at the Workflow level, while Actions only reference tool names. This allows you to define tools once and selectively make them available to specific actions based on their needs.
import { defineWorkflow, defineTool } from '@alokai/compass';
const exampleTool = defineTool({
name: 'exampleTool',
// ...other tool properties
});
const exampleWorkflow = defineWorkflow({
actions: {
exampleAction: {
//...
toolkit: ['exampleTool'], // Reference tool by name
}
},
toolkits: [exampleTool], // Include actual tool definition
//...
});
Only include tools that are essential for each action. Tool schemas are sent to the LLM with every request, increasing token usage and costs.
Example 1
A simple tool calculating a sum of two numbers:
import { z } from 'zod';
import { defineTool } from '@alokai/compass';
const addNumbersTool = defineTool({
schema: z.object({
a: z.number(),
b: z.number(),
}),
callback: async (context, args) => {
return args.a + args.b;
},
description: 'Adds two numbers',
name: 'addNumbers',
})
Example 2
A dynamic tool that demonstrates several key concepts: schema callback with access to context, optional caching, and real-time data streaming to the frontend. This tool calls the SAPCC searchProducts API method and uses sendToBrowser() to immediately send results to the user interface:
import { defineDynamicTool, sendToBrowser } from '@alokai/compass';
import type { Endpoints } from '@vsf-enterprise/unified-api-sapcc';
import { z } from 'zod';
const searchProducts = defineDynamicTool({
name: 'searchProducts',
description: 'Searches for products in a catalog',
callback: async (context, args) => {
const commerceApi = await context.getApiClient<{ unified: UnifiedEndpoints }>('commerce');
const response = await commerceApi.api.unified.searchProducts(args);
sendToBrowser(response);
return 'Product search results sent to the user. Ask if he needs further assistance.';
},
schema: async (context) => z.object({
category: z.string().optional(),
currentPage: z.number().optional(),
pageSize: z.number().optional(),
search: z.string().optional(),
sortBy: z.string().optional(),
}),
cache: {
key: async () => 'catalogOverview',
},
});
The sendToBrowser(response) function sends the search results directly to the frontend through a custom event stream, allowing users to see products immediately while the AI continues processing. This creates a responsive user experience where data appears instantly rather than waiting for the complete AI response.
Transitions
Transitions are relationships between actions, describing how the control should be passed between them as the workflow progresses.
Example 1
A linear transition between two actions:
import { defineWorkflow, START, END } from '@alokai/compass';
const assistantWorkflow = defineWorkflow({
actions: {
actionA: {/* action configuration */},
actionB: {/* action configuration */ }
},
transitions: {
[START]: 'actionA',
['actionA']: 'actionB',
['actionB']: END,
},
});
Example 2
A choice transition featuring prompts for LLM to help it decide which action to call:
import { defineWorkflow, START, END } from '@alokai/compass';
const assistantWorkflow = defineWorkflow({
actions: {
actionA: {/* action configuration */},
actionB: {/* action configuration */ }
},
transitions: {
[START]: {
to: [
{
id: 'actionA',
when: 'when user message says "cat"',
},
{
id: 'actionB',
when: 'when user message says "dog"',
},
],
type: 'choice',
},
['actionA']: END,
['actionB']: END,
},
});
Data Flow
The data flow in Alokai Compass is driven by AI workflow orchestration, creating a sophisticated, non-linear process. The complexity varies depending on your workflow design. Here's how the example Quotes workflow operates:

1
2
3
4
Tool Call Generation
The AI API analyzes the user's request and determines which tools are needed to fulfill it. It responds with a tool_calls array that specifies exactly which tools to execute:
{
"tool_calls": [
{
"name": "getQuote",
"args": {},
"id": "call_14fTKJBG6aVNmE1xJ4dVvxyO",
"type": "tool_call"
}
]
}
5
Tool Execution
The quote action executes the getQuote tool, which:
- Sends a request to the DummyJSON Quotes API
- Receives quotes data from the Quotes API
- Sends the quote data directly to the browser
- Returns a formatted prompt for the next AI interaction
6
This architecture enables Compass to provide intelligent, context-aware responses while maintaining real-time user feedback through streaming events.
Prompts
Writing effective prompts is essential for achieving satisfactory results from your workflows. Just like humans, LLMs require clear and precise instructions to perform tasks well.
While detailed guidance on writing good prompts is beyond the scope of this documentation, we highly recommend reading Anthropic's comprehensive guide on prompt engineering.
When building a workflow, you can define prompts in two places:
- Workflow: The
startingPromptproperty, - Action: The
promptproperty.
The key difference between these prompt types lies in when and how often they are sent to the AI API:
- Workflow's
startingPrompt: Included in every API call throughout the entire workflow execution, providing persistent context - Action's
prompt: Only included when that specific action is being executed, providing action-specific instructions
Let's examine how prompts are handled when invoking the following workflow with a "Hello" message:
import { defineWorkflow, END, START } from '@alokai/compass';
defineWorkflow({
actions: {
actionA: {
model: 'light',
prompt: 'This is action A prompt',
type: 'llm',
},
actionB: {
model: 'light',
prompt: 'This is action B prompt',
type: 'llm',
},
},
startingPrompt: 'This is the starting prompt',
transitions: {
[START]: 'actionA',
actionA: 'actionB',
actionB: END,
},
});
When this workflow executes, Alokai Compass sends different messages arrays to the AI API for each action:
When executing Action A:
[
{
"role": "user",
"content": [
{
"text": "Hello",
"type": "text"
}
]
},
{
"role": "system",
"content": "This is the starting prompt"
},
{
"role": "system",
"content": "This is action A prompt"
}
]
When executing Action B:
[
{
"role": "user",
"content": [
{
"text": "Hello",
"type": "text"
}
]
},
{
"role": "assistant",
"content": "Response from Action A..."
},
{
"role": "system",
"content": "This is the starting prompt"
},
{
"role": "system",
"content": "This is action B prompt"
}
]
Notice how the starting prompt appears in both actions, while each action only receives its own specific action prompt. This design allows you to maintain consistent context throughout the workflow while providing action-specific instructions where needed.
What next?
Since you are now familiar with the Alokai Compass module architecture, let's install it in your Storefront and build the first workflow!