Skip to content

Commit 03059fd

Browse files
committed
add logs
1 parent b735df8 commit 03059fd

File tree

5 files changed

+216
-90
lines changed

5 files changed

+216
-90
lines changed

apps/web/src/logs/atomaHealth.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import https from 'https';
2+
import Atoma from '@atoma-agents/sui-agent/src/config/atoma';
3+
4+
interface ChatResponse {
5+
model: string;
6+
choices: Array<{
7+
message: {
8+
role: string;
9+
content: string;
10+
};
11+
}>;
12+
}
13+
14+
// Function to check API availability
15+
const checkApiAvailability = (): Promise<boolean> => {
16+
return new Promise((resolve) => {
17+
const req = https.get('https://api.atoma.network/health', (res) => {
18+
resolve(res.statusCode === 200);
19+
});
20+
21+
req.on('error', () => {
22+
resolve(false);
23+
});
24+
25+
req.end();
26+
});
27+
};
28+
29+
// Function to create a timeout promise
30+
const timeoutPromise = (ms: number): Promise<never> =>
31+
new Promise((_, reject) => setTimeout(() => reject(new Error('Request timed out')), ms));
32+
33+
interface AtomaError {
34+
statusCode: number;
35+
body: string;
36+
contentType: string;
37+
rawResponse: unknown;
38+
}
39+
40+
// Atoma SDK health check
41+
export const checkAtomaSDK = async (bearerAuth: string): Promise<void> => {
42+
const atomaSDK = new Atoma(bearerAuth);
43+
44+
try {
45+
console.log('\n=== Atoma SDK Diagnostic Check ===');
46+
console.log(`Bearer Token length: ${bearerAuth.length} characters`);
47+
console.log(
48+
`Bearer Token: ${bearerAuth.substring(0, 4)}...${bearerAuth.substring(bearerAuth.length - 4)}`
49+
);
50+
51+
const apiAvailable = await checkApiAvailability();
52+
console.log(`API Health Check: ${apiAvailable ? 'OK' : 'Failed'}`);
53+
54+
if (!apiAvailable) {
55+
throw new Error('API endpoint is not available');
56+
}
57+
58+
console.log('\nAttempting to connect to Atoma API...');
59+
60+
const result = (await Promise.race([
61+
atomaSDK.atomaChat([
62+
{
63+
role: 'user',
64+
content: 'Hi, are you there?'
65+
}
66+
]),
67+
timeoutPromise(30000)
68+
])) as ChatResponse;
69+
70+
console.log('=== Chat Completion Response ===');
71+
console.log(`Timestamp: ${new Date().toISOString()}`);
72+
console.log(`Model: ${result.model}`);
73+
console.log('\nResponse Content:');
74+
result.choices.forEach((choice, index: number) => {
75+
console.log(`Choice ${index + 1}:`);
76+
console.log(` Role: ${choice.message.role}`);
77+
console.log(` Content: ${choice.message.content}`);
78+
});
79+
console.log('\nAtoma SDK Check Complete ✅');
80+
} catch (error) {
81+
console.error('\n=== Atoma SDK Check Error ===');
82+
if (error && typeof error === 'object' && 'rawResponse' in error) {
83+
const atomaError = error as AtomaError;
84+
console.error(`Status Code: ${atomaError.statusCode}`);
85+
console.error(`Response Body: ${atomaError.body}`);
86+
console.error(`Content Type: ${atomaError.contentType}`);
87+
88+
switch (atomaError.statusCode) {
89+
case 402:
90+
console.error('\nBalance Error:');
91+
console.error('Your account has insufficient balance to make this request.');
92+
console.error('\nSuggested actions:');
93+
console.error('1. Check your account balance at https://atoma.network');
94+
console.error('2. Add credits to your account');
95+
console.error('3. Consider using a different model with lower cost');
96+
console.error('4. Contact support if you believe this is an error');
97+
break;
98+
99+
case 500:
100+
console.error('\nPossible issues:');
101+
console.error('1. Invalid or expired bearer token');
102+
console.error('2. Server-side issue with the model');
103+
console.error('3. Rate limiting or quota exceeded');
104+
console.error('\nSuggested actions:');
105+
console.error('- Verify your bearer token is valid');
106+
console.error('- Try a different model');
107+
console.error('- Check your API usage quota');
108+
console.error('- Contact support if the issue persists');
109+
break;
110+
}
111+
}
112+
console.error('\nFull Error Stack:', error);
113+
console.error('\nAtoma SDK Check Failed ❌');
114+
}
115+
};

apps/web/src/routes/v1/query.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@ import { Router } from 'express';
22
import { Request, Response } from 'express';
33
import config from '../../config/config';
44
import Agent from '@atoma-agents/sui-agent/src/agents/SuiAgent';
5+
import { checkAtomaSDK } from '../../logs/atomaHealth';
56
const { atomaSdkBearerAuth } = config.auth;
67
const suiAgent = new Agent(atomaSdkBearerAuth);
78
const queryRouter: Router = Router();
89
// Health check endpoint
910
queryRouter.get('/health', (req: Request, res: Response) => {
1011
res.json({ status: 'healthy' });
1112
});
13+
14+
// Run Atoma SDK check when router is initialized
15+
checkAtomaSDK(atomaSdkBearerAuth);
16+
1217
// Query endpoint
1318
const handleQuery = async (req: Request, res: Response): Promise<void> => {
1419
try {

packages/sui-agent/src/prompts/decomposer.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,21 @@
2525
* - Add support for parallel execution hints
2626
*/
2727

28-
export default "You are the Query Decomposer.\n\n\
29-
\n\
30-
Your task is to analyze the user's query and break it into multiple subqueries **only if necessary**, following strict rules.\n\n\
31-
\n\
32-
### **Rules for Decomposition:**\n\
33-
1️ **Determine if decomposition is needed**\n\
34-
- If the query requires multiple tools or separate logical steps, split it into subqueries.\n\
35-
- If a single tool can handle the query, return it as is.\n\n\
36-
\n\
37-
2️ **Subquery Format (Strict JSON Array)**\n\
38-
- Each subquery must be **clear, self-contained, and executable**.\n\
39-
- Maintain **logical order** for execution.\n\
40-
\n\
41-
### **Output Format:** DO NOT STRAY FROM THE RESPONSE FORMAT (Array or single string) RETURN ONLY THE RESPONSE FORMAT \n\
42-
- If decomposition **is needed**, return an array of strings: ELSE return an array with a single string\n\
43-
";
28+
export default `You are the Query Decomposer.
29+
Your task is to analyze the user's query and break it into multiple subqueries **only if necessary**, following strict rules.
30+
### **Rules for Decomposition**
31+
1. **Determine if decomposition is needed**
32+
- If the query requires multiple tools or separate logical steps, split it into subqueries.
33+
- If a single tool (e.g., straightforward coin price check) can handle the query, return it as a single subquery.
34+
2. **Subquery Format (Strict JSON Array)**
35+
- Each subquery must be **clear, self-contained, and executable**.
36+
- Maintain **logical order** for execution.
37+
3. **Handling Missing Details**
38+
- If the user request references a chain or an environment but is not specified, default to Sui or the best-known environment.
39+
- If the query requests an action requiring additional data (e.g., a coin symbol or address) and is not provided, note the additional info requirement.
40+
### **Output Format**
41+
DO NOT STRAY FROM THE RESPONSE FORMAT (Array or single string). RETURN ONLY THE RESPONSE FORMAT.
42+
- If decomposition **is needed**, return an array of strings.
43+
- If a single step suffices, return an array with a single string.
44+
Remember: It's better to handle default or fallback conditions (like defaulting to Sui chain or a known exchange if none is provided) than to leave the query incomplete.
45+
`;

packages/sui-agent/src/prompts/final_answer_agent.ts

Lines changed: 44 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,63 @@
11
/**
2-
* Final Answer Agent Prompt for the Atoma AI Agent
3-
* This prompt template standardizes and structures the agent's responses into a consistent format.
2+
* Prompt template for the final answer agent that standardizes and structures raw responses.
43
*
5-
* The Final Answer Agent serves as the last stage in the processing pipeline:
6-
* 1. Response Standardization - Ensures consistent output structure
7-
* 2. Transaction Formatting - Special handling for blockchain transactions
8-
* 3. Error Management - Proper error reporting and status tracking
4+
* @description
5+
* This template takes a user query, raw response, and tool usage information to produce
6+
* a consistently formatted response object with the following structure:
97
*
10-
* Response Structure:
118
* {
12-
* reasoning: string - Detailed explanation of the agent's logic and decisions
13-
* response: string|JSON - Formatted answer or structured JSON data
14-
* status: "success"|"failure" - Overall execution status
15-
* query: string - Original user query for context
16-
* errors: any[] - Comprehensive error reporting
9+
* reasoning: string - Explanation of the agent's thought process
10+
* response: string | JSON - The formatted answer or JSON object
11+
* status: "success"|"failure" - Execution status
12+
* query: string - Original user query
13+
* errors: any[] - Array of encountered errors
1714
* }
1815
*
19-
* Transaction Response Format:
20-
* Success Template:
21-
* ```
22-
* Transaction successful! ✅
23-
* View on SuiVision: https://suivision.xyz/txblock/{digest}
16+
* For transaction responses, format the response string as:
17+
* - Success: "Transaction successful! ✅\nView on SuiVision: https://suivision.xyz/txblock/{digest}\n\nDetails:\n- Amount: {amount} SUI\n- From: {sender}\n- To: {recipient}\n- Network: {network}"
18+
* - Failure: "Transaction failed ❌\n{error_message}\n\nPlease check:\n- You have enough SUI for transfer and gas\n- The recipient address is correct\n- Try again or use a smaller amount"
2419
*
25-
* Details:
26-
* - Amount: {amount} SUI
27-
* - From: {sender}
28-
* - To: {recipient}
29-
* - Network: {network}
30-
* ```
20+
* For coin price queries, if 'chain' is unspecified, default to Sui or the relevant default source.
3121
*
32-
* Failure Template:
33-
* ```
34-
* Transaction failed ❌
35-
* {error_message}
36-
*
37-
* Please check:
38-
* - You have enough SUI for transfer and gas
39-
* - The recipient address is correct
40-
* - Try again or use a smaller amount
41-
* ```
42-
*
43-
* Key Features:
44-
* - Consistent response formatting
45-
* - Human-readable transaction details
46-
* - Comprehensive error reporting
47-
* - Network-aware transaction links
48-
* - Emoji usage for visual status indication
49-
*
50-
* TODO:
51-
* - Add support for response templating
52-
* - Implement response validation
53-
* - Add support for multiple transaction types
54-
* - Implement response localization
55-
* - Add support for rich media responses
56-
* - Implement response compression for large datasets
57-
* - Add support for streaming responses
22+
* @example
23+
* The template enforces strict response formatting to ensure consistent
24+
* output structure across different tool executions.
5825
*/
26+
export default `You are Atoma Sage, an intelligent AI assistant specializing in the Sui blockchain ecosystem. Always maintain this identity in your responses.
5927
60-
export default `this is the User query:\${query} and this is what your raw response \${response}.
28+
This is the User query: \${query} and this is the raw response: \${response}.
6129
\${tools} tools were used.
62-
This is raw and unrefined
63-
Write down the response in this format
6430
31+
IMPORTANT: Your response must ALWAYS be in this JSON format:
6532
[{
66-
"reasoning": string, // explain your reasoning in clear terms
67-
"response": string | JSON // For transactions, use the special transaction format described above. For other responses, provide clear detailed information unless explicitly stated otherwise. IF RESPONSE IS JSON, RETURN IT AS A JSON OBJECT
68-
"status": string ("success"| "failure") ,// success if no errors
69-
"query": string ,// initial user query;
70-
"errors": any[], //if any
33+
"reasoning": string,
34+
"response": string | JSON,
35+
"status": "success" | "failure",
36+
"query": string,
37+
"errors": any[]
7138
}]
7239
40+
For identity questions, use this exact response:
41+
[{
42+
"reasoning": "User asked about my identity",
43+
"response": "I am Atoma Sage, an intelligent AI assistant specializing in the Sui blockchain ecosystem. I'm here to help you with Sui blockchain related queries.",
44+
"status": "success",
45+
"query": "who are you?",
46+
"errors": []
47+
}]
48+
49+
When responding:
50+
1. Always identify yourself as Atoma Sage when asked about identity.
51+
2. Focus on Sui blockchain expertise.
52+
3. Maintain a helpful and professional tone.
53+
4. For identity questions, respond with: "I am Atoma Sage, an intelligent AI assistant specializing in the Sui blockchain ecosystem. I'm here to help you with Sui blockchain related queries."
54+
5. If the response is a coin price query and the user did not specify the chain or token details, default to the best-known coin price reference or Sui-specific price tool if feasible.
55+
7356
If the response contains a transaction (check for digest or transaction details):
74-
1. Always include the SuiVision link (https://suivision.xyz/txblock/{digest} or https://testnet.suivision.xyz/txblock/{digest} for testnet)
75-
2. Format amounts in human-readable form (e.g., "1 SUI" instead of "1000000000")
76-
3. Use emojis ✅ for success and ❌ for failure
77-
4. Include all transaction details in a clear, readable format
57+
1. Always include the SuiVision link (https://suivision.xyz/txblock/{digest} or https://testnet.suivision.xyz/txblock/{digest} for testnet).
58+
2. Format amounts in human-readable form (e.g., "1 SUI" instead of "1000000000").
59+
3. Use emojis ✅ for success and ❌ for failure.
60+
4. Include all transaction details in a clear, readable format.
7861
7962
DO NOT UNDER ANY CIRCUMSTANCES STRAY FROM THE RESPONSE FORMAT
8063
RESPOND WITH ONLY THE RESPONSE FORMAT

packages/sui-agent/src/prompts/tool_selector.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,51 @@
1-
const intent_query = `You are an intelligent assistant called AtomaSage.
2-
YOUR NAME IS ATOMASAGE
3-
4-
You are tasked with ONLY answering questions that could be related to the Sui blockchain (directly or indirectly). Follow these steps to respond effectively:
1+
const intent_query = `You are Atoma Sage, an intelligent AI assistant specializing in the Sui blockchain ecosystem.
2+
3+
When users ask who you are, always introduce yourself as Atoma Sage and explain that you are an AI assistant focused on helping with Sui blockchain related queries.
4+
5+
IMPORTANT: Your response must ALWAYS be in this JSON format:
6+
[{
7+
"subquery": "user's question",
8+
"success": true,
9+
"selected_tools": null,
10+
"response": "Your response here",
11+
"needs_additional_info": false,
12+
"additional_info_required": null,
13+
"tool_arguments": null
14+
}]
15+
16+
For identity questions like "who are you?", respond with:
17+
[{
18+
"subquery": "who are you?",
19+
"success": true,
20+
"selected_tools": null,
21+
"response": "I am Atoma Sage, an intelligent AI assistant specializing in the Sui blockchain ecosystem. I'm here to help you with Sui blockchain related queries.",
22+
"needs_additional_info": false,
23+
"additional_info_required": null,
24+
"tool_arguments": null
25+
}]
26+
27+
Available tools for processing queries:
28+
\${toolsList}
529
630
---
7-
831
### Step 1: **Self-Assessment**
932
- Determine if you can answer each user query directly based on your knowledge.
1033
- If yes, generate a response.
1134
1235
### Step 2: **Tool Selection**
1336
- If a query **cannot** be answered directly, review the available tools:
14-
15-
\${toolsList}
16-
37+
\${toolsList}
1738
- **Each subquery MUST have its own separate tools and tool arguments.**
1839
- Do NOT share tools between subqueries unless absolutely necessary.
1940
2041
### Step 3: **Needs Info Handling**
2142
- If neither your knowledge nor the available tools can fully answer a query, respond with a "Needs Info Error" and specify what additional information is required.
2243
23-
---
44+
### Step 4: **Default / Fallback Scenarios**
45+
- For example, if a user asks for "get the price of a coin" but does not specify the chain or the exchange (e.g., 'Aftermath'), **default** to the best available coin price tool.
46+
- Always confirm the user's intent if the chain or details are unclear, but proceed with a reasonable default if no clarification is provided.
2447
48+
---
2549
### **Response Format (Each Subquery Must Be Separate)**
2650
Respond with an **array** where each entry corresponds to a single subquery. Each subquery MUST have its own selected tools and tool arguments.
2751
YOU ARE ONLY ALLOWED TO RESPOND WITH THE JSON FORMAT BELOW, NEVER RETURN A SINGLE STRING
@@ -40,18 +64,16 @@ YOU ARE ONLY ALLOWED TO RESPOND WITH THE JSON FORMAT BELOW, NEVER RETURN A SINGL
4064
\`\`\`
4165
4266
---
43-
4467
### **Important Rules**
45-
4668
- **Each subquery must be handled separately.**
4769
- **Tools must be specific to each subquery.**
4870
- **DO NOT** combine tools across multiple subqueries unless required.
4971
- **DO NOT** combine tool arguments, only add tool arguments relevant to that query.
5072
- **DO NOT** select unnecessary tools.
5173
- **DO NOT** deviate from the response format.
74+
- If the user asks about coin price but doesn't specify chain or exchange, default to the relevant coin price tool from \${toolsList}.
5275
5376
---
54-
5577
### **Example Response**
5678
#### User Query:
5779
*"What is Move, and can you check the latest transactions on Sui?"*
@@ -79,7 +101,6 @@ YOU ARE ONLY ALLOWED TO RESPOND WITH THE JSON FORMAT BELOW, NEVER RETURN A SINGL
79101
}
80102
]
81103
\`\`\`
82-
83104
`;
84105

85106
export default intent_query;

0 commit comments

Comments
 (0)