• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Mastra agent and Telex equals super integration

Sascha Оффлайн

Sascha

Заместитель Администратора
Команда форума
Администратор
Регистрация
9 Май 2015
Сообщения
1,605
Баллы
155


Building agent workflow has never been easy. However Mastra and Telex and are changing that narrative.

In this guide, I’ll walk you through how I integrated a Mastra AI Agent with Telex, using A2A (App-to-App) requests to enable smooth communication between the two platforms.

Telex is an educational platform similar to Slack, it supports apps and agents that interact using messages.
Mastra, on the other hand, is a modern framework for building, deploying, and scaling AI agents in production.

By combining the two, we can create a setup where Telex sends structured messages to Mastra, Mastra processes them intelligently using our agent, and then sends a meaningful response back, all through JSON-RPC.

Installing and Setting Up Mastra
Before writing any code, we’ll need to set up Mastra locally.
You can always check the official docs

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Step 1: Create and initialize your project


mkdir weather-agent
cd weather-agent
npm init -y




Step 2: Install Mastra


npm install @mastra/core @mastra/agents




Step 3: Define your Agent

Create a file src/mastra/agents/weather-agent.ts:


import { Agent } from '@mastra/core/agent';
import { Memory } from '@mastra/memory';
import { LibSQLStore } from '@mastra/libsql';
import { weatherTool } from '../tools/weather-tool.js';

export const weatherAgent = new Agent({
name: 'Weather Agent',
instructions: `
You are a helpful weather assistant that provides accurate weather information and can help planning activities based on the weather

Use the weatherTool to fetch current weather data.
`,
model: 'google/gemini-2.5-pro',
tools: { weatherTool },

memory: new Memory({
storage: new LibSQLStore({
url: 'file:../mastra.db', // path is relative to the .mastra/output directory
}),
}),
});





Understanding the A2A Request Format

When Telex sends data to an AI agent, it follows a strict JSON-RPC 2.0 format.
Here’s what a sample Telex request looks like:


{
"jsonrpc": "2.0",
"id": "request-001",
"method": "message/send",
"params": {
"message": {
"kind": "message",
"role": "user",
"parts": [
{
"kind": "text",
"text": "What's the weather condition"
}
],
"messageId": "msg-001"
},
"configuration": {
"blocking": true
}
}
}





It is importatnt to make sure Mastra understands this format, extract the relevant message, and then send it to the agent for processing.

Setting Up the Custom A2A Endpoint

Mastra allows you to extend its API by registering custom routes.
We created one called /a2a/agent/:agentId to handle requests from Telex.

Here’s the full code for a2aRouter.ts:


import { registerApiRoute } from '@mastra/core/server';
import { randomUUID } from 'crypto';

interface A2AMessagePart {
kind: 'text' | 'data';
text?: string;
data?: any;
}

interface A2AMessage {
role: string;
parts: A2AMessagePart[];
messageId?: string;
taskId?: string;
}

export const a2aAgentRoute = registerApiRoute('/a2a/agent/:agentId', {
method: 'POST',
handler: async (c: any) => {
try {
const mastra = c.get('mastra');
const agentId = c.req.param('agentId');

// Parse JSON-RPC 2.0 request
const body = await c.req.json();
const { jsonrpc, id: requestId, method, params } = body;

// Validate JSON-RPC 2.0 format
if (jsonrpc !== '2.0' || !requestId) {
return c.json(
{
jsonrpc: '2.0',
id: requestId || null,
error: {
code: -32600,
message: 'Invalid Request: jsonrpc must be "2.0" and id is required'
}
},
400
);
}

const agent = mastra.getAgent(agentId);
if (!agent) {
return c.json(
{
jsonrpc: '2.0',
id: requestId,
error: {
code: -32602,
message: `Agent '${agentId}' not found`
}
},
404
);
}

// Extract messages
const { message, messages, contextId, taskId, metadata } = params || {};

const messagesList: A2AMessage[] = message
? [message]
: Array.isArray(messages)
? messages
: [];

// Convert A2A messages to Mastra format
const mastraMessages = messagesList.map((msg) => ({
role: msg.role,
content:
msg.parts
?.map((part) => {
if (part.kind === 'text') return part.text || '';
if (part.kind === 'data') return JSON.stringify(part.data || {});
return '';
})
.join('\n') || ''
}));

// Execute agent
const response = await agent.generate(mastraMessages);
const agentText = response.text || '';

// Build artifacts
const artifacts = [
{
artifactId: randomUUID(),
name: `${agentId}Response`,
parts: [{ kind: 'text', text: agentText }]
}
];

if (response.toolResults?.length) {
artifacts.push({
artifactId: randomUUID(),
name: 'ToolResults',
parts: response.toolResults.map((result: any) => ({
kind: 'data',
data: result
}))
});
}

// Build conversation history
const history = [
...messagesList.map((msg) => ({
kind: 'message',
role: msg.role,
parts: msg.parts,
messageId: msg.messageId || randomUUID(),
taskId: msg.taskId || taskId || randomUUID()
})),
{
kind: 'message',
role: 'agent',
parts: [{ kind: 'text', text: agentText }],
messageId: randomUUID(),
taskId: taskId || randomUUID()
}
];

// Return A2A-compliant response
return c.json({
jsonrpc: '2.0',
id: requestId,
result: {
id: taskId || randomUUID(),
contextId: contextId || randomUUID(),
status: {
state: 'completed',
timestamp: new Date().toISOString(),
message: {
messageId: randomUUID(),
role: 'agent',
parts: [{ kind: 'text', text: agentText }],
kind: 'message'
}
},
artifacts,
history,
kind: 'task'
}
});
} catch (error: any) {
return c.json(
{
jsonrpc: '2.0',
id: null,
error: {
code: -32603,
message: 'Internal error',
data: { details: error?.message || String(error) }
}
},
500
);
}
}
});




Linking the Route to Mastra

In the mastra/index.ts, register the new route like this:



import { Mastra } from '@mastra/core/mastra';
import { PinoLogger } from '@mastra/loggers';
import { LibSQLStore } from '@mastra/libsql';
import { weatherWorkflow } from './workflows/weather-workflow.js';
import { weatherAgent } from './agents/weather-agent.js';
import { a2aAgentRoute } from '../mastra/routes/a2a-agent-route.js';


export const mastra = new Mastra({
workflows: { weatherWorkflow },
agents: { weatherAgent },
storage: new LibSQLStore({
// stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
url: ":memory:",
}),
logger: new PinoLogger({
name: 'Mastra',
level: 'info',
}),
telemetry: {
// Telemetry is deprecated and will be removed in the Nov 4th release
enabled: false,
},
observability: {
// Enables DefaultExporter and CloudExporter for AI tracing
default: { enabled: true },
},

server: {
build: {
openAPIDocs: true,
swaggerUI: true,
},
apiRoutes: [
a2aAgentRoute
]
}
});




Deployment to Mastra Cloud
Once you’ve created your project and agent locally, simply push:

npx mastra deploy
After deployment, you’ll get a public URL like:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.


This is the endpoint you’ll register on Telex under your A2A app configuration.

Now, Telex will send messages directly to your agent and receive responses in real time.



Источник:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу