astra-insight-mcp 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -0
- package/bin/cli.js +43 -0
- package/package.json +19 -0
- package/platform/darwin-arm64/astra +0 -0
- package/platform/darwin-x64/astra +0 -0
- package/platform/linux-arm64/astra +0 -0
- package/platform/linux-x64/astra +0 -0
- package/skills/agent-creation.md +55 -0
- package/skills/astra-create-agent.md +70 -0
- package/skills/astra-diagnose.md +56 -0
- package/skills/astra-optimize-instruction.md +62 -0
- package/skills/astra-quick-start.md +31 -0
- package/skills/astra-setup-knowledge.md +58 -0
- package/skills/astra-test-agent.md +47 -0
- package/skills/debugging-tips.md +62 -0
- package/skills/instruction-optimization.md +49 -0
- package/skills/integration-auth-flow.md +98 -0
- package/skills/knowledge-management.md +55 -0
- package/skills/voice-agent.md +250 -0
- package/skills/wati-api.md +240 -0
package/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# @wati/astra-mcp
|
|
2
|
+
|
|
3
|
+
AI agent management for the WATI/Astra platform via [Model Context Protocol](https://modelcontextprotocol.io).
|
|
4
|
+
|
|
5
|
+
Create, test, optimize, and diagnose WhatsApp AI agents — directly from your IDE.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx -y @wati/astra-mcp@latest
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or install globally:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g @wati/astra-mcp
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## IDE Configuration
|
|
20
|
+
|
|
21
|
+
### Cursor
|
|
22
|
+
|
|
23
|
+
Settings → Tools and MCP → New MCP server:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"mcpServers": {
|
|
28
|
+
"astra": {
|
|
29
|
+
"command": "npx",
|
|
30
|
+
"args": ["-y", "@wati/astra-mcp@latest"]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Claude Desktop
|
|
37
|
+
|
|
38
|
+
Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"mcpServers": {
|
|
43
|
+
"astra": {
|
|
44
|
+
"command": "npx",
|
|
45
|
+
"args": ["-y", "@wati/astra-mcp@latest"]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Environment Variables
|
|
52
|
+
|
|
53
|
+
| Variable | Description |
|
|
54
|
+
|----------|-------------|
|
|
55
|
+
| `ASTRA_API_KEY` | Your Astra platform API key |
|
|
56
|
+
| `ASTRA_GATEWAY_URL` | Custom gateway URL (optional) |
|
|
57
|
+
|
|
58
|
+
## Supported Platforms
|
|
59
|
+
|
|
60
|
+
| OS | Architecture |
|
|
61
|
+
|----|-------------|
|
|
62
|
+
| macOS | Apple Silicon (arm64) |
|
|
63
|
+
| macOS | Intel (x64) |
|
|
64
|
+
| Linux | arm64 |
|
|
65
|
+
| Linux | x64 |
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
|
|
69
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Thin wrapper that locates the bundled platform binary and runs it.
|
|
4
|
+
* Defaults to "stdio" mode when no subcommand is given.
|
|
5
|
+
*/
|
|
6
|
+
const { execFileSync } = require("child_process");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
const fs = require("fs");
|
|
9
|
+
|
|
10
|
+
const PLATFORM_MAP = { darwin: "darwin", linux: "linux" };
|
|
11
|
+
const ARCH_MAP = { arm64: "arm64", x64: "x64" };
|
|
12
|
+
|
|
13
|
+
const plat = PLATFORM_MAP[process.platform];
|
|
14
|
+
const arch = ARCH_MAP[process.arch];
|
|
15
|
+
|
|
16
|
+
if (!plat || !arch) {
|
|
17
|
+
process.stderr.write(
|
|
18
|
+
`[astra-mcp] Unsupported platform: ${process.platform}/${process.arch}\n` +
|
|
19
|
+
" Supported: darwin-arm64, darwin-x64, linux-arm64, linux-x64\n"
|
|
20
|
+
);
|
|
21
|
+
process.exit(126);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const BIN_PATH = path.join(__dirname, "..", "platform", `${plat}-${arch}`, "astra");
|
|
25
|
+
|
|
26
|
+
if (!fs.existsSync(BIN_PATH)) {
|
|
27
|
+
process.stderr.write(
|
|
28
|
+
`[astra-mcp] Binary not found at ${BIN_PATH}\n` +
|
|
29
|
+
" Try reinstalling: npm install -g @wati/astra-mcp\n"
|
|
30
|
+
);
|
|
31
|
+
process.exit(127);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const args = process.argv.slice(2);
|
|
35
|
+
if (args.length === 0) {
|
|
36
|
+
args.push("stdio");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
execFileSync(BIN_PATH, args, { stdio: "inherit" });
|
|
41
|
+
} catch (err) {
|
|
42
|
+
process.exit(err.status || 1);
|
|
43
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "astra-insight-mcp",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Astra Insight MCP — AI agent management for the WATI/Astra platform",
|
|
5
|
+
"bin": {
|
|
6
|
+
"astra-mcp": "./bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"keywords": ["mcp", "astra", "wati", "ai-agent", "whatsapp"],
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=18"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"bin/",
|
|
15
|
+
"platform/",
|
|
16
|
+
"skills/",
|
|
17
|
+
"README.md"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Agent Creation Workflow
|
|
2
|
+
|
|
3
|
+
## Critical Workflow Order
|
|
4
|
+
|
|
5
|
+
**IMPORTANT**: `knowledge_base_id` can ONLY be set at agent creation time. The `update_agent` endpoint does NOT support changing it — the backend silently ignores the field. Therefore, always create the KB BEFORE creating the agent.
|
|
6
|
+
|
|
7
|
+
The correct sequence for creating a fully functional agent:
|
|
8
|
+
|
|
9
|
+
1. **`fetch_brandkit(identifier=<domain>)`** — Pre-fetch brand data (no agent_id needed yet).
|
|
10
|
+
2. **`create_knowledge_base(name=<name>)`** — Create an empty KB, get the `dataset_id` UUID.
|
|
11
|
+
3. **`import_knowledge_from_website(dataset_id=<uuid>, url=<site>)`** — Start async content crawl into the KB.
|
|
12
|
+
4. **`create_agent(name=..., knowledge_base_id=<uuid>, ...)`** — Create agent WITH the KB attached. This is the ONLY time you can set `knowledge_base_id`.
|
|
13
|
+
5. **`fetch_brandkit(identifier=<domain>, agent_id=<new_id>)`** — Re-fetch with agent_id to attach brandkit.
|
|
14
|
+
6. **`update_brandkit(...)`** — Customize persona, appearance_config, conversation starters, welcome message.
|
|
15
|
+
7. **`update_agent_instruction(agent_id, instructions=...)`** — This creates the **draft runtime config** (required before publishing).
|
|
16
|
+
8. **`publish_agent(agent_id)`** — Publishes the draft config to make it live.
|
|
17
|
+
9. **Test and verify** — Test only after publishing.
|
|
18
|
+
|
|
19
|
+
## Critical Gotchas
|
|
20
|
+
|
|
21
|
+
### Draft Config is Required Before Publishing
|
|
22
|
+
`publish_agent` will fail with "No draft configuration found" unless you call `update_agent_instruction` first. Simply calling `create_agent` with instructions does NOT create a draft config — it sets the agent-level instructions but the runtime config system is separate.
|
|
23
|
+
|
|
24
|
+
### system_rules via update_agent Don't Propagate to Runtime Config
|
|
25
|
+
Calling `update_agent(system_rules=...)` sets rules on the agent object, but the published runtime config may show empty `system_rules`. **Workaround**: Embed guardrails directly in the instructions passed to `update_agent_instruction`.
|
|
26
|
+
|
|
27
|
+
### Brandkit Attachment — Use fetch_brandkit, Not create_brandkit
|
|
28
|
+
`fetch_brandkit(identifier=<domain>, agent_id=<id>)` is the reliable one-step method. `create_brandkit` requires precise struct formats (`minimized_button_label` as object, `agent_id` in body) and is error-prone.
|
|
29
|
+
|
|
30
|
+
### Annotations as Immediate Safety Net
|
|
31
|
+
Create annotations for critical guardrail responses BEFORE the knowledge base is ready. Annotations work without a KB and guarantee exact answers for:
|
|
32
|
+
- Fee-blocking responses (high priority)
|
|
33
|
+
- Competitor comparison deflections
|
|
34
|
+
- Unavailable product/service responses
|
|
35
|
+
- Campus/location redirect links
|
|
36
|
+
- Accreditation/ranking verified data
|
|
37
|
+
|
|
38
|
+
### appearance_config Structure
|
|
39
|
+
The appearance_config has two parallel sections: `widget` (for web widget) and `ai_bar` (for AI bar). Both need the same structure:
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"widget": {
|
|
43
|
+
"name": "Agent Name",
|
|
44
|
+
"welcome_message": {"message": "...", "popup_mode": true},
|
|
45
|
+
"conversation_starter": {"messages": ["Q1", "Q2", "Q3"], "popup_mode": true},
|
|
46
|
+
"brand_logo": {"url": "..."},
|
|
47
|
+
"color_theme": {"primary_color": "#hex"},
|
|
48
|
+
"display_form_immediately": false
|
|
49
|
+
},
|
|
50
|
+
"ai_bar": { ... same structure ... }
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Typical Cost for Full Agent Creation
|
|
55
|
+
A complete agent creation workflow (brandkit + create + KB + annotations + publish + test attempts) costs approximately $2.50-3.50 with Claude Sonnet, spanning ~25 iterations.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Create a New Astra Agent
|
|
2
|
+
|
|
3
|
+
You are guiding the user through creating a fully functional Astra AI agent. Follow this workflow step by step, confirming with the user at each stage.
|
|
4
|
+
|
|
5
|
+
## Step 1 — Gather Requirements
|
|
6
|
+
|
|
7
|
+
Ask the user for:
|
|
8
|
+
- **Agent name** (required)
|
|
9
|
+
- **Purpose** — what does the agent do? (e.g., customer support, sales, FAQ)
|
|
10
|
+
- **Channel** — whatsapp, web_widget, or voice? (default: whatsapp)
|
|
11
|
+
- **Website/domain** — for auto-fetching brand kit and knowledge base content
|
|
12
|
+
- **Any specific instructions or rules** the agent should follow
|
|
13
|
+
|
|
14
|
+
If the user already provided some of these, skip those questions.
|
|
15
|
+
|
|
16
|
+
## Step 2 — Set Up Knowledge Base (if website provided)
|
|
17
|
+
|
|
18
|
+
If the user provided a website/domain:
|
|
19
|
+
1. Call `create_knowledge_base(name="<agent_name> KB")`
|
|
20
|
+
2. Call `import_knowledge_from_website(dataset_id=<kb_id>, url=<website>)`
|
|
21
|
+
3. Tell the user: "Knowledge base is importing in the background. This takes 1-3 minutes."
|
|
22
|
+
|
|
23
|
+
Save the `dataset_id` — you MUST pass it when creating the agent (it cannot be added later).
|
|
24
|
+
|
|
25
|
+
## Step 3 — Create the Agent
|
|
26
|
+
|
|
27
|
+
Call `create_agent` with:
|
|
28
|
+
- `name` — from step 1
|
|
29
|
+
- `type` — "conversational" (general purpose) or "faq" (Q&A focused)
|
|
30
|
+
- `channel_type` — from step 1
|
|
31
|
+
- `communication_mode` — "text" (default), "voice", or "both"
|
|
32
|
+
- `knowledge_base_id` — from step 2 (if created)
|
|
33
|
+
- `instructions` — write a good initial instruction based on the user's purpose description. Include:
|
|
34
|
+
- Role definition ("You are a customer support agent for ...")
|
|
35
|
+
- Tone and style guidelines
|
|
36
|
+
- Key behaviors (be helpful, stay on topic, escalate when unsure)
|
|
37
|
+
- Any specific rules the user mentioned
|
|
38
|
+
|
|
39
|
+
**CRITICAL**: `knowledge_base_id` can ONLY be set at creation time. It cannot be changed later.
|
|
40
|
+
|
|
41
|
+
## Step 4 — Set Up Brand Kit (if website provided)
|
|
42
|
+
|
|
43
|
+
1. Call `fetch_brandkit(identifier=<domain>, agent_id=<agent_id>)` to auto-detect branding
|
|
44
|
+
2. Show the user what was detected (colors, logo, name)
|
|
45
|
+
3. Ask if they want to customize anything
|
|
46
|
+
|
|
47
|
+
## Step 5 — Create Draft & Publish
|
|
48
|
+
|
|
49
|
+
1. Call `update_agent_instruction(agent_id=<id>, instructions=<instructions>)` — this creates the required draft config
|
|
50
|
+
2. Call `publish_agent(agent_id=<id>)` — makes the agent live
|
|
51
|
+
|
|
52
|
+
**IMPORTANT**: You MUST call `update_agent_instruction` before `publish_agent`, otherwise publishing will fail with "No draft configuration found".
|
|
53
|
+
|
|
54
|
+
## Step 6 — Test
|
|
55
|
+
|
|
56
|
+
Call `send_test_message(agent_id=<id>, message="Hi, what can you help me with?")` to verify the agent responds correctly.
|
|
57
|
+
|
|
58
|
+
Show the response to the user and ask if they want to adjust anything.
|
|
59
|
+
|
|
60
|
+
## Summary
|
|
61
|
+
|
|
62
|
+
After completion, show a summary:
|
|
63
|
+
```
|
|
64
|
+
✅ Agent Created
|
|
65
|
+
Name: <name>
|
|
66
|
+
ID: <agent_id>
|
|
67
|
+
Channel: <channel>
|
|
68
|
+
KB: <attached/none>
|
|
69
|
+
Status: Published & Live
|
|
70
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Diagnose Agent Issues
|
|
2
|
+
|
|
3
|
+
You are helping the user diagnose why an Astra agent isn't working correctly. Follow a systematic approach to identify the root cause.
|
|
4
|
+
|
|
5
|
+
## Step 1 — Identify Agent & Symptom
|
|
6
|
+
|
|
7
|
+
Ask:
|
|
8
|
+
- "Which agent has the issue?" (name or ID)
|
|
9
|
+
- "What's going wrong?" — e.g., wrong answers, not responding, ignoring KB, hallucinating
|
|
10
|
+
|
|
11
|
+
Call `get_agent(agent_id)` to get current config.
|
|
12
|
+
|
|
13
|
+
## Step 2 — Quick Health Check
|
|
14
|
+
|
|
15
|
+
Run these checks in parallel:
|
|
16
|
+
|
|
17
|
+
1. **Agent status**: Is it published? Call `get_runtime_config(agent_id)` — if no draft/published config exists, the agent can't function.
|
|
18
|
+
2. **Knowledge base**: Does it have a KB? Call `list_documents(dataset_id)` if KB exists — are documents there?
|
|
19
|
+
3. **Recent conversations**: Call `list_conversations(agent_id, limit=5)` to see if the agent is actually receiving messages.
|
|
20
|
+
4. **Test message**: Call `send_test_message(agent_id, message=<reproduce the problem>)` to see the actual response.
|
|
21
|
+
|
|
22
|
+
## Step 3 — Diagnose by Symptom
|
|
23
|
+
|
|
24
|
+
### "Agent gives wrong answers"
|
|
25
|
+
1. Call `retrieve_knowledge(agent_id, query=<the question>)` — is the correct info in the KB?
|
|
26
|
+
2. Check instruction for conflicting or missing guidance
|
|
27
|
+
3. Check annotations — is there an annotation overriding the correct answer?
|
|
28
|
+
|
|
29
|
+
### "Agent doesn't use knowledge base"
|
|
30
|
+
1. Verify KB is attached: check `knowledge_base_id` in agent config
|
|
31
|
+
2. Verify KB has content: `list_documents(dataset_id)`
|
|
32
|
+
3. Test retrieval: `retrieve_knowledge(agent_id, query=<question>)` — if empty results, the content isn't indexed properly
|
|
33
|
+
|
|
34
|
+
### "Agent hallucinates / makes things up"
|
|
35
|
+
1. Check instruction — does it say "only answer from knowledge base" or similar grounding rules?
|
|
36
|
+
2. Add annotations for critical facts that must be exact
|
|
37
|
+
3. Consider adding to instruction: "If you don't know the answer, say so. Never make up information."
|
|
38
|
+
|
|
39
|
+
### "Agent not responding at all"
|
|
40
|
+
1. Check if agent is published
|
|
41
|
+
2. Check if agent is enabled: `get_agent` → `enabled` field
|
|
42
|
+
3. Check channel configuration — is the trigger type correct?
|
|
43
|
+
|
|
44
|
+
## Step 4 — Fix
|
|
45
|
+
|
|
46
|
+
Based on diagnosis, suggest specific fixes:
|
|
47
|
+
- Instruction changes → use `/astra-optimize-instruction`
|
|
48
|
+
- KB content gaps → use `/astra-setup-knowledge`
|
|
49
|
+
- Missing annotations → offer to create them
|
|
50
|
+
- Config issues → fix directly via `update_agent` or `publish_agent`
|
|
51
|
+
|
|
52
|
+
## Step 5 — Verify Fix
|
|
53
|
+
|
|
54
|
+
After applying changes:
|
|
55
|
+
1. Call `send_test_message(agent_id, message=<original problem message>)` to verify
|
|
56
|
+
2. Show before/after comparison
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Optimize Agent Instruction
|
|
2
|
+
|
|
3
|
+
You are guiding the user through an instruction optimization cycle: analyze current performance → identify weaknesses → generate improved instruction → test → compare.
|
|
4
|
+
|
|
5
|
+
## Step 1 — Identify the Agent
|
|
6
|
+
|
|
7
|
+
Ask: "Which agent's instruction do you want to optimize?"
|
|
8
|
+
|
|
9
|
+
Call `list_agents` if needed, then `get_agent(agent_id=<id>)` to fetch current instruction and configuration.
|
|
10
|
+
|
|
11
|
+
Show the user:
|
|
12
|
+
- Agent name and ID
|
|
13
|
+
- Current instruction (first 200 chars + "...")
|
|
14
|
+
- Whether it has a knowledge base attached
|
|
15
|
+
|
|
16
|
+
## Step 2 — Assess Current Performance
|
|
17
|
+
|
|
18
|
+
Check if there are existing test results:
|
|
19
|
+
1. Call `get_agent_test_overview(agent_id=<id>)`
|
|
20
|
+
2. If there are recent runs, show the latest pass rate
|
|
21
|
+
|
|
22
|
+
If no test data exists, suggest: "No test data yet. Want me to run a test first? Use `/astra-test-agent`"
|
|
23
|
+
|
|
24
|
+
## Step 3 — Analyze Failures
|
|
25
|
+
|
|
26
|
+
If a recent test run exists:
|
|
27
|
+
1. Call `analyze_failures(run_id=<latest_run_id>)` to get failure analysis
|
|
28
|
+
2. Show the improvement suggestions grouped by priority (high → medium → low)
|
|
29
|
+
3. Ask the user if they want to address all suggestions or focus on specific ones
|
|
30
|
+
|
|
31
|
+
## Step 4 — Generate Improved Instruction
|
|
32
|
+
|
|
33
|
+
Call `generate_instruction` with:
|
|
34
|
+
- `instruction` — the current agent instruction
|
|
35
|
+
- `analysis_json` — from step 3 (if available)
|
|
36
|
+
- `improvement_suggestions` — the selected suggestions
|
|
37
|
+
- `agent_description` — brief description of what the agent does
|
|
38
|
+
|
|
39
|
+
Show the proposed new instruction to the user. Highlight what changed and why.
|
|
40
|
+
|
|
41
|
+
Ask: "Want to apply this instruction, edit it first, or try a different approach?"
|
|
42
|
+
|
|
43
|
+
## Step 5 — Apply & Test
|
|
44
|
+
|
|
45
|
+
Once approved:
|
|
46
|
+
1. Call `update_agent_instruction(agent_id, instructions=<new_instruction>)` to update draft
|
|
47
|
+
2. Call `publish_agent(agent_id)` to make it live
|
|
48
|
+
3. Call `create_test_run(generator_id=<suite_id>, user_id="test-user")` to re-run the same test suite
|
|
49
|
+
4. Compare old vs new pass rates
|
|
50
|
+
|
|
51
|
+
Show comparison:
|
|
52
|
+
```
|
|
53
|
+
📊 Instruction Optimization Results
|
|
54
|
+
Before: 72% pass rate (18/25)
|
|
55
|
+
After: 88% pass rate (22/25)
|
|
56
|
+
Delta: +16% improvement
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Step 6 — Iterate or Done
|
|
60
|
+
|
|
61
|
+
If improvement is satisfactory, congratulate and summarize.
|
|
62
|
+
If not, ask: "Want to run another optimization cycle focusing on the remaining failures?"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Astra Quick Start
|
|
2
|
+
|
|
3
|
+
Welcome to Astra Insight MCP! Here's what you can do. Type any of these commands to get started:
|
|
4
|
+
|
|
5
|
+
## Common Tasks
|
|
6
|
+
|
|
7
|
+
| Command | What it does |
|
|
8
|
+
|---------|-------------|
|
|
9
|
+
| `/astra-create-agent` | Create a new AI agent from scratch (guided workflow) |
|
|
10
|
+
| `/astra-test-agent` | Run tests on an agent and see pass/fail results |
|
|
11
|
+
| `/astra-optimize-instruction` | Improve an agent's instruction based on test failures |
|
|
12
|
+
| `/astra-setup-knowledge` | Create and populate a knowledge base |
|
|
13
|
+
| `/astra-diagnose` | Debug why an agent isn't working correctly |
|
|
14
|
+
|
|
15
|
+
## Quick Actions (just ask in natural language)
|
|
16
|
+
|
|
17
|
+
- "List all my agents" → calls `list_agents`
|
|
18
|
+
- "Send a test message to agent X" → calls `send_test_message`
|
|
19
|
+
- "Show conversations for agent X" → calls `list_conversations`
|
|
20
|
+
- "What's the analytics for agent X?" → calls `get_analytics`
|
|
21
|
+
|
|
22
|
+
## Reference Guides
|
|
23
|
+
|
|
24
|
+
| Command | Content |
|
|
25
|
+
|---------|---------|
|
|
26
|
+
| `/agent-creation` | Detailed agent creation reference (API gotchas, field requirements) |
|
|
27
|
+
| `/knowledge-management` | KB import workflows, annotation patterns |
|
|
28
|
+
| `/instruction-optimization` | How the test → analyze → improve cycle works |
|
|
29
|
+
| `/voice-agent` | Voice agent configuration reference |
|
|
30
|
+
| `/integration-auth-flow` | How to set up Composio integrations (Slack, HubSpot, etc.) |
|
|
31
|
+
| `/debugging-tips` | Common API errors and workarounds |
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Set Up Knowledge Base
|
|
2
|
+
|
|
3
|
+
You are guiding the user through creating and populating a knowledge base for an Astra agent.
|
|
4
|
+
|
|
5
|
+
## Step 1 — Identify Target
|
|
6
|
+
|
|
7
|
+
Ask:
|
|
8
|
+
- "Which agent needs a knowledge base?" (or "Are you creating a KB for a new agent?")
|
|
9
|
+
- "What content source do you have?" — Website URL, document files, or manual FAQ entries?
|
|
10
|
+
|
|
11
|
+
If the agent already exists, call `get_agent(agent_id)` to check if it already has a KB attached.
|
|
12
|
+
|
|
13
|
+
**WARNING**: If the agent already exists WITHOUT a KB, you CANNOT attach one later via API. The user would need to create a new agent with the KB. Inform them of this limitation upfront.
|
|
14
|
+
|
|
15
|
+
## Step 2 — Create Knowledge Base
|
|
16
|
+
|
|
17
|
+
Call `create_knowledge_base(name="<descriptive name>")`.
|
|
18
|
+
|
|
19
|
+
Save the `dataset_id` — this is needed for all subsequent operations.
|
|
20
|
+
|
|
21
|
+
## Step 3 — Import Content
|
|
22
|
+
|
|
23
|
+
Based on the user's content source:
|
|
24
|
+
|
|
25
|
+
### Website
|
|
26
|
+
1. Call `import_knowledge_from_website(dataset_id=<id>, url=<website_url>)`
|
|
27
|
+
2. This crawls the site asynchronously. Tell the user it takes 1-5 minutes depending on site size.
|
|
28
|
+
3. Poll `get_import_status(import_id=<id>)` to check progress.
|
|
29
|
+
|
|
30
|
+
### URL (single page)
|
|
31
|
+
1. Call `import_knowledge_from_url(dataset_id=<id>, url=<page_url>)`
|
|
32
|
+
2. Faster than website crawl — usually completes in under a minute.
|
|
33
|
+
|
|
34
|
+
### Manual FAQ / Annotations
|
|
35
|
+
For critical Q&A pairs that need exact answers:
|
|
36
|
+
1. Call `create_annotation(agent_id=<id>, question=<q>, answer=<a>)` for each pair
|
|
37
|
+
2. Annotations take priority over KB content — use for pricing, policies, compliance answers
|
|
38
|
+
|
|
39
|
+
## Step 4 — Verify
|
|
40
|
+
|
|
41
|
+
1. Call `list_documents(dataset_id=<id>)` to see what was imported
|
|
42
|
+
2. Call `retrieve_knowledge(agent_id=<id>, query="<test question>")` to test retrieval
|
|
43
|
+
3. Show results to the user
|
|
44
|
+
|
|
45
|
+
## Step 5 — Connect to Agent
|
|
46
|
+
|
|
47
|
+
If creating a new agent, remind: "Use `/astra-create-agent` and I'll include this KB automatically."
|
|
48
|
+
|
|
49
|
+
If KB is already attached, the agent will start using it after publishing.
|
|
50
|
+
|
|
51
|
+
Show summary:
|
|
52
|
+
```
|
|
53
|
+
✅ Knowledge Base Ready
|
|
54
|
+
Name: <name>
|
|
55
|
+
ID: <dataset_id>
|
|
56
|
+
Documents: <count>
|
|
57
|
+
Status: Ready for use
|
|
58
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Test an Astra Agent
|
|
2
|
+
|
|
3
|
+
You are guiding the user through a full test cycle for an Astra agent. This includes generating test cases, running them, and analyzing results.
|
|
4
|
+
|
|
5
|
+
## Step 1 — Identify the Agent
|
|
6
|
+
|
|
7
|
+
Ask: "Which agent do you want to test?"
|
|
8
|
+
|
|
9
|
+
If the user gives a name, call `list_agents` and find the matching agent. Show the agent's name, ID, and current status.
|
|
10
|
+
|
|
11
|
+
If the user gives an ID, call `get_agent(agent_id=<id>)` directly.
|
|
12
|
+
|
|
13
|
+
## Step 2 — Choose Test Strategy
|
|
14
|
+
|
|
15
|
+
Ask the user:
|
|
16
|
+
> How would you like to test?
|
|
17
|
+
> 1. **Quick test** — Send a few messages manually
|
|
18
|
+
> 2. **Full test pipeline** — Auto-generate test cases, run them all, and get a score
|
|
19
|
+
> 3. **Re-run existing tests** — Run tests from a previous test suite
|
|
20
|
+
|
|
21
|
+
### Option 1: Quick Test
|
|
22
|
+
Ask what messages to send, then call `send_test_message(agent_id, message)` for each. Show responses inline.
|
|
23
|
+
|
|
24
|
+
### Option 2: Full Pipeline
|
|
25
|
+
1. Call `start_test_pipeline(agent_id=<id>, user_id="test-user")`
|
|
26
|
+
2. Poll `get_pipeline_job(job_id=<id>)` every 10 seconds until status is "completed"
|
|
27
|
+
3. Show results: pass rate, failures, and improvement suggestions
|
|
28
|
+
|
|
29
|
+
### Option 3: Re-run Existing
|
|
30
|
+
1. Call `get_agent_latest_test_suite(agent_id=<id>)` to find the latest suite
|
|
31
|
+
2. Call `create_test_run(generator_id=<suite_id>, user_id="test-user")` to re-run
|
|
32
|
+
3. Poll `get_test_run(run_id=<id>)` until complete
|
|
33
|
+
4. Show results
|
|
34
|
+
|
|
35
|
+
## Step 3 — Review Results
|
|
36
|
+
|
|
37
|
+
For any test run, show:
|
|
38
|
+
- **Pass rate**: X/Y tests passed (Z%)
|
|
39
|
+
- **Failures**: List each failed test with the expected vs actual response
|
|
40
|
+
- **Suggestions**: If analysis is available, show improvement recommendations
|
|
41
|
+
|
|
42
|
+
## Step 4 — Next Steps
|
|
43
|
+
|
|
44
|
+
Based on results, suggest:
|
|
45
|
+
- If pass rate > 90%: "Agent is performing well! Consider publishing if not already live."
|
|
46
|
+
- If pass rate 70-90%: "Some improvements needed. Want me to optimize the instruction? Use `/astra-optimize-instruction`"
|
|
47
|
+
- If pass rate < 70%: "Significant issues found. Let's review the failures and rewrite the instruction."
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Debugging & Troubleshooting
|
|
2
|
+
|
|
3
|
+
## Common API Errors
|
|
4
|
+
|
|
5
|
+
### 400 "Invalid request body"
|
|
6
|
+
- `minimized_button_label` must be `{"enabled": true, "label": "..."}`, not a string
|
|
7
|
+
- `create_brandkit` requires `agent_id` in the JSON body (auto-handled by client)
|
|
8
|
+
- **Chat endpoints** (`/chat`, `/chat-test`, `/chat-preview`) return this when:
|
|
9
|
+
- Agent has no published runtime config → publish first via `update_agent_instruction` + `publish_agent`
|
|
10
|
+
- Backend service rejects the request format → this is a known backend issue, not a client bug
|
|
11
|
+
|
|
12
|
+
### 400 "No draft configuration found"
|
|
13
|
+
- `publish_agent` fails because no draft exists
|
|
14
|
+
- **Fix**: Call `update_agent_instruction(agent_id, instructions=...)` first — this creates the draft config
|
|
15
|
+
- `create_agent` with instructions does NOT create a draft runtime config
|
|
16
|
+
|
|
17
|
+
### 422 Validation Error
|
|
18
|
+
- `get_import_status` requires `url` query parameter matching the original import URL
|
|
19
|
+
- `create_knowledge_document` requires a real dataset UUID, NOT `new`
|
|
20
|
+
|
|
21
|
+
### 500 Internal Server Error
|
|
22
|
+
- **`import_knowledge_from_url`** — "Failed to import document: Expecting value: line 1 column 1 (char 0)":
|
|
23
|
+
- **Root cause**: RAG service's `upload_webpage_to_knowledge_base()` in `dify_console_op.py` calls Dify's `/datasets/{id}/documents` API but does NOT check `response.status_code` before calling `response.json()`. When Dify returns a non-200 response (HTML error), JSON parsing fails.
|
|
24
|
+
- **Underlying Dify failure**: Usually because the tenant has no `jinareader` API credentials configured. Dify needs valid provider credentials (jinareader/firecrawl/watercrawl) in its `api_key_auth` system.
|
|
25
|
+
- **`get_import_status`** — "Error fetching crawl status: HTTP 500":
|
|
26
|
+
- **Root cause**: RAG's `check_crawl_status()` (line 778) hardcodes `provider=jinareader` in the Dify status URL. Dify's `WebsiteService` then calls `_get_credentials_and_config(tenant_id, "jinareader")` which raises "Invalid provider" if no credentials exist for that tenant+provider combo.
|
|
27
|
+
- The actual Dify error is `{"code": "crawl_failed", "message": "Invalid provider", "status": 500}`.
|
|
28
|
+
- Google Sheets, Docs, and authenticated URLs always fail on import.
|
|
29
|
+
|
|
30
|
+
### 409 Conflict
|
|
31
|
+
- `create_brandkit` fails if a brandkit already exists — use `update_brandkit` instead
|
|
32
|
+
- Or use `fetch_brandkit(identifier=..., agent_id=...)` which handles create-or-update automatically
|
|
33
|
+
|
|
34
|
+
## Known Backend Issues (Not Client Bugs)
|
|
35
|
+
|
|
36
|
+
1. **`send_test_message` (chat-preview) returns 400** — was caused by using `message` field instead of `user_query`. The API service's `ExecuteRequest` requires `user_query` (binding:"required"). Fixed in client.
|
|
37
|
+
2. **`import_knowledge_from_url` returns 500** — RAG service doesn't check Dify response status before JSON parse; Dify fails because tenant lacks jinareader API credentials
|
|
38
|
+
3. **`get_import_status` returns 500** — RAG hardcodes `provider=jinareader` in Dify status URL; Dify rejects if tenant has no jinareader credentials configured
|
|
39
|
+
4. **`system_rules` via `update_agent` may not propagate** to published runtime config — embed guardrails in instructions instead
|
|
40
|
+
5. **`process_crawl_results_realtime` batch uploads fail** with "Expecting value" — same root cause as #2, Dify document upload returns non-JSON when credentials are missing
|
|
41
|
+
|
|
42
|
+
## Debugging Strategy
|
|
43
|
+
|
|
44
|
+
1. **Enable debug mode** (`--debug`) to see curl commands and API responses
|
|
45
|
+
2. **Check HTTP status codes**: 2xx = success, 4xx = client error (fix payload), 5xx = server/backend error
|
|
46
|
+
3. **For 400 errors**: Compare payload against OpenAPI spec in `astra-gateway/docs/openapi.yaml`
|
|
47
|
+
4. **For 500 errors**: Usually backend issues — try alternative approaches rather than retrying
|
|
48
|
+
5. **For chat errors**: Don't waste iterations retrying — verify agent is published (`get_runtime_config(status=active)`) first
|
|
49
|
+
|
|
50
|
+
## Efficiency Tips
|
|
51
|
+
|
|
52
|
+
- **Don't retry failing endpoints** — If `import_knowledge_from_url` fails once with 500, it will fail again. Switch to `import_knowledge_from_website` or manual documents.
|
|
53
|
+
- **Don't poll import status aggressively** — Status endpoint is unreliable. Start the crawl, do other work, check back later.
|
|
54
|
+
- **Use annotations early** — Don't wait for KB to be ready. Create annotations for guardrail responses immediately while import runs in background.
|
|
55
|
+
- **Batch annotation creation** — Create multiple annotations in sequence for different guardrail categories (fees, competitors, availability, redirects, facts).
|
|
56
|
+
|
|
57
|
+
## Performance Tips
|
|
58
|
+
|
|
59
|
+
- `list_agents` returns lightweight summaries (no instructions) — use `get_agent` for full details
|
|
60
|
+
- Truncate long content before sending to LLM (auto-handled at 8000 chars)
|
|
61
|
+
- Prompt caching is enabled automatically for Claude models — static content (system prompt + tools) cached for 5 minutes, ~90% savings on repeat calls
|
|
62
|
+
- Full agent creation workflow costs ~$2.50-3.50 with Claude Sonnet over ~25 iterations
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Instruction Optimization Workflow
|
|
2
|
+
|
|
3
|
+
## Analysis Phase
|
|
4
|
+
|
|
5
|
+
1. **Get current config** — `get_agent` + `get_runtime_config(status=active)` to see what's live.
|
|
6
|
+
2. **Review conversations** — `get_analytics` first for overview, then `list_conversations` to find problematic ones. Read actual messages with `get_conversation_messages`.
|
|
7
|
+
3. **Check knowledge gaps** — `retrieve_knowledge` with common user queries to see what the agent retrieves. If results are poor, the KB needs enrichment.
|
|
8
|
+
|
|
9
|
+
## Improvement Phase
|
|
10
|
+
|
|
11
|
+
1. **Instructions should be structured** — Use markdown headers: Role & Identity, Core Flow, Guardrails, Communication Style.
|
|
12
|
+
2. **Embed guardrails directly in instructions** — `system_rules` set via `update_agent` may NOT propagate to the published runtime config. Always include critical guardrails (NEVER/ALWAYS rules) directly in the instruction text passed to `update_agent_instruction`.
|
|
13
|
+
3. **Use annotations for FAQ overrides** — `create_annotation` with exact Q&A pairs takes priority over KB retrieval. Use for critical questions that must have exact answers. Annotations work even without a KB attached.
|
|
14
|
+
4. **Keep instructions under 4000 tokens** — Very long instructions degrade LLM performance. Be concise and use bullet points.
|
|
15
|
+
|
|
16
|
+
## Publishing Flow
|
|
17
|
+
|
|
18
|
+
The correct publishing flow is:
|
|
19
|
+
1. `update_agent_instruction(agent_id, instructions=...)` — creates/updates the **draft runtime config**
|
|
20
|
+
2. `publish_agent(agent_id)` — publishes the draft to make it live
|
|
21
|
+
3. Verify: `get_runtime_config(agent_id, status=active)` — confirm instructions are correct
|
|
22
|
+
|
|
23
|
+
**Critical**: `publish_agent` requires a draft config. If you only used `create_agent` or `update_agent`, there is no draft config — you MUST call `update_agent_instruction` first.
|
|
24
|
+
|
|
25
|
+
## Testing Phase
|
|
26
|
+
|
|
27
|
+
1. **Publish before testing** — `send_test_message` (chat-preview) requires a published runtime config. An unpublished agent returns 400 errors.
|
|
28
|
+
2. **chat-preview endpoint may return 400** — This is a known backend issue. If test messages fail, verify the agent is published and has an active runtime config (`get_runtime_config(status=active)`).
|
|
29
|
+
3. **For systematic testing** — Use the testing pipeline: `create_test_suite` → `add_test_case` (multiple) → `create_test_run` → `get_test_run` → `create_run_analysis`.
|
|
30
|
+
4. **Use `generate_instruction`** — After analyzing test failures with `analyze_failures`, use `generate_instruction` to get AI-suggested improvements.
|
|
31
|
+
|
|
32
|
+
## Annotation Patterns for Guardrails
|
|
33
|
+
|
|
34
|
+
Annotations are the most reliable way to enforce guardrail responses. Create them for:
|
|
35
|
+
|
|
36
|
+
| Guardrail | Example Questions | Fixed Response |
|
|
37
|
+
|-----------|------------------|----------------|
|
|
38
|
+
| Fee blocking | "What's the fee?", "How much does it cost?" | "For fee information, please contact..." |
|
|
39
|
+
| Competitor deflection | "Is X better than Y?", "X vs Y" | "I can help with information about [brand]..." |
|
|
40
|
+
| Unavailable items | "Do you offer [thing]?" | "Sorry, [thing] is not available." |
|
|
41
|
+
| Location redirects | "Tell me about [other branch]" | "For [branch], please visit: [URL]" |
|
|
42
|
+
| Verified facts | "What's [brand]'s ranking?" | Exact verified answer with source links |
|
|
43
|
+
|
|
44
|
+
## Common Instruction Patterns
|
|
45
|
+
|
|
46
|
+
- **Lead capture agent**: Step-by-step flow (greet → collect name → phone → email → interest → answer → qualify). Collect one field at a time. If user asks a question first, answer it, then return to collection.
|
|
47
|
+
- **Support agent**: Prioritize KB retrieval, with clear escalation rules and human handoff triggers.
|
|
48
|
+
- **Sales agent**: Include objection handling, CTA patterns, and qualification criteria.
|
|
49
|
+
- **Multi-location agent**: Define primary location, redirect rules for other locations with specific URLs.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Integration Auth Flow
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Connect a third-party platform (e.g. HubSpot, Slack, Salesforce, Google Sheets) to an Astra agent via OAuth. This is a 3-step sequential flow — each step depends on the previous one.
|
|
6
|
+
|
|
7
|
+
## Flow
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
create_integration_auth(platform)
|
|
11
|
+
│
|
|
12
|
+
▼
|
|
13
|
+
{connection_id, redirect_url} ← user must visit redirect_url to authorize
|
|
14
|
+
│
|
|
15
|
+
▼
|
|
16
|
+
wait_integration_auth(connection_id)
|
|
17
|
+
│
|
|
18
|
+
▼
|
|
19
|
+
{success, account_name} ← if success=false → abort, auth failed
|
|
20
|
+
│
|
|
21
|
+
▼
|
|
22
|
+
create_connection(platform, connection_id, connection_name=account_name)
|
|
23
|
+
│
|
|
24
|
+
▼
|
|
25
|
+
Connection mapping created ← done, connection_id is ready for use
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Step-by-Step
|
|
29
|
+
|
|
30
|
+
### Step 1: Initiate OAuth — `create_integration_auth`
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
create_integration_auth(platform="hubspot")
|
|
34
|
+
→ { connection_id: "conn_xxx", redirect_url: "https://..." }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- Present the `redirect_url` to the user and ask them to complete authorization.
|
|
38
|
+
- For **WATI** platform: provide `bearer_token` and `api_endpoint` instead of OAuth (no redirect needed).
|
|
39
|
+
- Hold on to `connection_id` — it's needed in all subsequent steps.
|
|
40
|
+
|
|
41
|
+
### Step 2: Wait for Auth — `wait_integration_auth`
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
wait_integration_auth(connection_id="conn_xxx", timeout=120, platform="hubspot")
|
|
45
|
+
→ { success: true, account_name: "My HubSpot Account" }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- Blocks until the user completes OAuth or the timeout expires.
|
|
49
|
+
- Default timeout is 120 seconds.
|
|
50
|
+
- **If `success=false`**: Auth failed or timed out. Stop here — do not proceed to Step 3.
|
|
51
|
+
- **If `success=true`**: Save `account_name` for Step 3.
|
|
52
|
+
|
|
53
|
+
**Important field mapping**: The response field is `account_name`. In Step 3, pass this value as `connection_name`.
|
|
54
|
+
|
|
55
|
+
### Step 3: Create Connection Mapping — `create_connection`
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
create_connection(platform="hubspot", connection_id="conn_xxx", connection_name="My HubSpot Account")
|
|
59
|
+
→ { id: 1, platform: "hubspot", connection_id: "conn_xxx", ... }
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- **`connection_name`** = the `account_name` from Step 2's response. This is a required field.
|
|
63
|
+
- `tenant_id` is resolved automatically from the API key.
|
|
64
|
+
- Calls `POST /connections` (gateway forwards to `POST /mapping/v2/connections`).
|
|
65
|
+
- After this, the `connection_id` can be used with `create_integration` to set up actions.
|
|
66
|
+
|
|
67
|
+
## After Auth: Creating Integration Actions
|
|
68
|
+
|
|
69
|
+
Once the connection is established, create and register actions:
|
|
70
|
+
|
|
71
|
+
1. **`list_integration_templates`** — Find the `at_id` for the desired action (e.g. `HUBSPOT_CREATE_CONTACT`).
|
|
72
|
+
2. **`create_integration`** — Create an action with `at_id`, `action_name`, `status="active"`, and the `connection_id` from above.
|
|
73
|
+
3. **`register_agent_integrations`** — Register the action to a specific agent so it can use it at runtime.
|
|
74
|
+
|
|
75
|
+
## Error Handling
|
|
76
|
+
|
|
77
|
+
| Step | Failure | Action |
|
|
78
|
+
|------|---------|--------|
|
|
79
|
+
| 1 | API error | Check platform name is valid; retry |
|
|
80
|
+
| 2 | `success=false` | User didn't complete auth in time; restart from Step 1 |
|
|
81
|
+
| 2 | Timeout | Increase timeout or ask user to retry auth faster |
|
|
82
|
+
| 3 | 422 | Missing required fields; check connection_id and account_name |
|
|
83
|
+
| 3 | 500 | Server-side issue; retry once, then escalate |
|
|
84
|
+
|
|
85
|
+
## WATI Special Case
|
|
86
|
+
|
|
87
|
+
WATI uses API key auth instead of OAuth. The flow is shorter:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
create_integration_auth(platform="wati", bearer_token="tok_xxx", api_endpoint="https://api.wati.io")
|
|
91
|
+
→ { connection_id: "conn_xxx" }
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Then skip Step 2 (no OAuth needed) and go directly to Step 3:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
create_connection(platform="wati", connection_id="conn_xxx", connection_name="WATI Account")
|
|
98
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Knowledge Base Management
|
|
2
|
+
|
|
3
|
+
## Correct Workflow
|
|
4
|
+
|
|
5
|
+
**CRITICAL**: `knowledge_base_id` can ONLY be set at agent creation time. `update_agent` silently ignores this field. Always create the KB BEFORE the agent.
|
|
6
|
+
|
|
7
|
+
1. **`create_knowledge_base(name=...)`** — Creates an empty KB, returns a `dataset_id` UUID.
|
|
8
|
+
2. **Import content** using the real `dataset_id`:
|
|
9
|
+
- `import_knowledge_from_website(dataset_id=<uuid>, url=...)` — BFS crawl (recommended)
|
|
10
|
+
- `import_knowledge_from_url(dataset_id=<uuid>, title=..., urls=[...])` — specific pages
|
|
11
|
+
3. **`create_agent(name=..., knowledge_base_id=<uuid>)`** — Create the agent WITH the KB. This is the only time KB can be linked.
|
|
12
|
+
|
|
13
|
+
**CRITICAL**: Do NOT use `dataset_id=new` — it's not a valid UUID and will cause 500 errors.
|
|
14
|
+
|
|
15
|
+
**NOTE**: The backend expects the create request wrapped as `{"kb_data": {...}}`. The gateway client handles this automatically.
|
|
16
|
+
|
|
17
|
+
## Import Strategies
|
|
18
|
+
|
|
19
|
+
### Website Crawl — RECOMMENDED (Most Reliable)
|
|
20
|
+
```
|
|
21
|
+
create_knowledge_base(name="Company KB") → dataset_id
|
|
22
|
+
import_knowledge_from_website(dataset_id=<uuid>, url="https://docs.example.com", max_pages=50)
|
|
23
|
+
```
|
|
24
|
+
- BFS crawl from the root URL
|
|
25
|
+
- Returns immediately with a `job_id`; crawling happens async in background
|
|
26
|
+
- Best for structured sites with internal links
|
|
27
|
+
|
|
28
|
+
### URL Import — MAY FAIL (Root Cause Known)
|
|
29
|
+
```
|
|
30
|
+
import_knowledge_from_url(dataset_id=<uuid>, title="FAQ Pages", urls=["https://example.com/faq"])
|
|
31
|
+
```
|
|
32
|
+
- May return 500 with "Failed to import document: Expecting value: line 1 column 1 (char 0)"
|
|
33
|
+
- **Root cause**: The RAG service calls Dify's `/datasets/{id}/documents` API but does NOT check `response.status_code` before calling `.json()`. When Dify returns a non-JSON error, parsing fails.
|
|
34
|
+
- **Underlying Dify failure**: Usually because the tenant lacks `jinareader` API credentials.
|
|
35
|
+
- Does NOT work with: Google Sheets, Google Docs, pages behind auth, SPAs
|
|
36
|
+
|
|
37
|
+
### There Is NO Text Document Creation Endpoint
|
|
38
|
+
The `POST /knowledge-bases/{id}/documents` endpoint is Dify's internal document upload API requiring `{tenant_id, urls, job_id, size}`. It is NOT for creating text documents from raw content. If you need to add curated text content, use annotations (`create_annotation`) instead.
|
|
39
|
+
|
|
40
|
+
## Import Status Checking
|
|
41
|
+
|
|
42
|
+
`get_import_status` may return 500 for BFS crawl jobs:
|
|
43
|
+
- **Root cause**: RAG's `check_crawl_status()` hardcodes `provider=jinareader` in the Dify status URL. Dify rejects it if the tenant has no jinareader credentials.
|
|
44
|
+
- **Workaround**: Don't poll status. Start the crawl, do other work, verify later by listing documents.
|
|
45
|
+
|
|
46
|
+
## Fallback: Use Annotations
|
|
47
|
+
|
|
48
|
+
When imports fail or for critical Q&A pairs:
|
|
49
|
+
- `create_annotation(agent_id, title, questions=[...], answer="...")` — works immediately, no KB needed
|
|
50
|
+
- Annotations take priority over KB retrieval for matching questions
|
|
51
|
+
- Best for: fee guardrails, competitor deflections, exact verified facts, location redirects
|
|
52
|
+
|
|
53
|
+
## Google Sheets / Docs Data
|
|
54
|
+
|
|
55
|
+
Google Sheets and Docs URLs **cannot be imported** via any endpoint (auth required, dynamic content). Ask the user to export as text, then use annotations to add the content.
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# Voice Agent Management
|
|
2
|
+
|
|
3
|
+
## Creating a Voice Agent
|
|
4
|
+
|
|
5
|
+
Voice agents MUST be linked to a text agent. There is only one creation method:
|
|
6
|
+
|
|
7
|
+
1. Check existence first: **`get_voice_agent_by_text_agent(text_agent_id)`** — avoid duplicates.
|
|
8
|
+
2. **`quick_create_voice_agent(text_agent_id, template_id)`** — Creates a voice agent pre-configured from a template, linked to the text agent. Automatically resolves `tenant_id` from the text agent.
|
|
9
|
+
3. **`update_voice_agent(voice_agent_id, instruction=...)`** — Customize the instruction to match your use case.
|
|
10
|
+
4. **`publish_voice_agent(voice_agent_id)`** — Push draft config live.
|
|
11
|
+
|
|
12
|
+
There is NO other creation method. Do NOT use `create_agent` or any text-agent tool to create voice agents.
|
|
13
|
+
|
|
14
|
+
## Configuring and Optimizing Instructions
|
|
15
|
+
|
|
16
|
+
Voice agent instructions follow the same principles as text agent instructions. Use `update_voice_agent(voice_agent_id, instruction=...)` to set them.
|
|
17
|
+
|
|
18
|
+
**Structure instructions with markdown headers**: Role & Identity, Core Flow, Guardrails, Communication Style — just like text agents.
|
|
19
|
+
|
|
20
|
+
**Key differences from text agents**:
|
|
21
|
+
- Voice agents need concise responses — users are listening, not reading.
|
|
22
|
+
- Include explicit turn-taking guidance (e.g., "Ask one question at a time, wait for the answer").
|
|
23
|
+
- Add pronunciation hints for brand names or technical terms if the TTS mispronounces them.
|
|
24
|
+
- Specify escalation triggers (e.g., "If the user says 'speak to a human', transfer immediately").
|
|
25
|
+
|
|
26
|
+
**Publishing flow** (same as text agents):
|
|
27
|
+
1. `update_voice_agent(voice_agent_id, instruction=...)` — creates/updates draft config
|
|
28
|
+
2. `publish_voice_agent(voice_agent_id)` — makes it live
|
|
29
|
+
3. Verify by calling `get_voice_agent(voice_agent_id)` — confirm `published_agent_config` has the new instruction
|
|
30
|
+
|
|
31
|
+
## Customizing the Voice (Voice Clone)
|
|
32
|
+
|
|
33
|
+
To use a custom voice instead of the default:
|
|
34
|
+
1. **`upload_user_voice(audio_url=<url>)`** — Uploads the user's audio. Tell user: "Audio uploaded successfully." Do NOT mention storage details.
|
|
35
|
+
2. **`submit_voice_clone(tenant_id, voice_name, gcs_url)`** — Starts the cloning process. Tell user: "Voice cloning started, please wait."
|
|
36
|
+
3. **`get_minimax_voice(id)`** — Poll until status=`completed`. The tool auto-confirms when ready. Do NOT tell user about internal statuses.
|
|
37
|
+
4. When completed, share the `demo_audio` URL so the user can listen.
|
|
38
|
+
5. **CRITICAL — MUST NOT SKIP**: Take `agent_config_voice_id` from the `get_minimax_voice` response and call:
|
|
39
|
+
**`update_voice_agent(voice_agent_id, agent_config={"voice_id": "<agent_config_voice_id>"})`**
|
|
40
|
+
Without this step the cloned voice will NOT take effect on the agent.
|
|
41
|
+
6. **`publish_voice_agent(voice_agent_id)`** — Push the new voice live.
|
|
42
|
+
|
|
43
|
+
### User-facing communication
|
|
44
|
+
|
|
45
|
+
| Internal step | What to tell user |
|
|
46
|
+
|---------------|-------------------|
|
|
47
|
+
| upload_user_voice | "Audio uploaded successfully" |
|
|
48
|
+
| submit_voice_clone | "Voice cloning started, this may take a moment" |
|
|
49
|
+
| get_minimax_voice (polling) | "Still processing..." or "Almost ready..." |
|
|
50
|
+
| status=completed | "Your voice clone is ready! Here's a preview: {demo_audio}" |
|
|
51
|
+
| update_voice_agent + publish | "Your custom voice has been applied to the agent" |
|
|
52
|
+
|
|
53
|
+
**NEVER expose to user**: GCS URLs, internal status names (pending/processing/tentative), voice_id, clone_model, minimax IDs.
|
|
54
|
+
|
|
55
|
+
### Internal notes (for tool logic, not user-facing)
|
|
56
|
+
|
|
57
|
+
- Clone lifecycle: `pending` → `processing` → `tentative` → `completed` (or `failed`)
|
|
58
|
+
- `tentative` means clone finished but awaiting confirmation — `get_minimax_voice` auto-confirms it to `completed`
|
|
59
|
+
- `failed` — retry with `submit_voice_clone(id=<existing_id>, ...)`
|
|
60
|
+
- Always use `upload_user_voice` first — external URLs (e.g. from Wati) require auth and cannot be passed to `submit_voice_clone` directly
|
|
61
|
+
|
|
62
|
+
To browse existing voices: `search_voice_library(keyword=...)` or `search_collected_voices(tenant_id=...)`.
|
|
63
|
+
|
|
64
|
+
**NOTE**: If `submit_voice_clone` returns 503, Minimax clone is not configured for this deployment.
|
|
65
|
+
|
|
66
|
+
## ASR (Speech-to-Text) for Voice Messages
|
|
67
|
+
|
|
68
|
+
When a user sends a voice message (audio) instead of text, the webhook automatically:
|
|
69
|
+
1. Downloads the audio file (with Wati token authentication)
|
|
70
|
+
2. Uploads to ASR for transcription
|
|
71
|
+
3. Passes the transcribed text + original audio URL to the agent
|
|
72
|
+
|
|
73
|
+
The agent receives voice messages in this format:
|
|
74
|
+
```
|
|
75
|
+
[Voice message | audio_url: <url> | format: audio.opus]
|
|
76
|
+
<transcribed text>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If the user's intent involves using their audio for voice cloning, use the `audio_url` with `upload_user_voice`. Otherwise, just process the transcribed text normally.
|
|
80
|
+
|
|
81
|
+
## Starting Calls
|
|
82
|
+
|
|
83
|
+
### Inbound Calls (WhatsApp)
|
|
84
|
+
- **`new_voice_call(call_id, sdp)`** — Accept an incoming WhatsApp call. Requires tenant validation and usage gating. Call is processed asynchronously.
|
|
85
|
+
- Uses the **published** agent config.
|
|
86
|
+
|
|
87
|
+
### Web Calls (Browser)
|
|
88
|
+
- **`web_new_voice_call(agent_id, call_id, sdp)`** — Start a browser-based call via WebRTC.
|
|
89
|
+
- Use **`get_webrtc_config()`** first to get ICE servers (STUN/TURN) for frontend setup.
|
|
90
|
+
- Uses the **published** agent config.
|
|
91
|
+
|
|
92
|
+
### Test Calls (Development)
|
|
93
|
+
- **`test_new_voice_call(agent_id, call_id, sdp)`** — Same as web call but skips tenant validation.
|
|
94
|
+
- Uses the **draft** agent config — best for iterating on config before publishing.
|
|
95
|
+
|
|
96
|
+
### Outbound Calls (WhatsApp)
|
|
97
|
+
- **`initiate_outbound_call(waid)`** — Call a WhatsApp user by their WAID.
|
|
98
|
+
- Uses the **draft** agent config (test mode). Requires a valid WhatsApp user ID.
|
|
99
|
+
- Optional: set `voice_language`, `accent`, `agent_id`, `channel_phone_number`.
|
|
100
|
+
|
|
101
|
+
### Ending Calls
|
|
102
|
+
- **`terminate_voice_call(call_id)`** — End a production call.
|
|
103
|
+
- **`test_terminate_voice_call(call_id)`** — End a test call (skips Wati API).
|
|
104
|
+
|
|
105
|
+
## Critical Gotchas
|
|
106
|
+
|
|
107
|
+
### Only Use quick_create_voice_agent
|
|
108
|
+
`quick_create_voice_agent(text_agent_id, template_id)` is the only creation method. It handles tenant setup internally. Always call `get_voice_agent_by_text_agent(text_agent_id)` before creation to avoid duplicates.
|
|
109
|
+
|
|
110
|
+
### voice_id Must Reference a Completed Clone
|
|
111
|
+
`agent_config.voice_id` must reference a voice with `status=completed`. The `get_minimax_voice` tool auto-confirms tentative clones, so just poll until completed. Setting an incomplete or invalid voice_id will cause failures.
|
|
112
|
+
|
|
113
|
+
### Never Expose Internal Details to Users
|
|
114
|
+
Do NOT show users: voice_id, GCS URLs, clone_model, minimax config, internal status names. Only share: upload success, cloning progress, preview audio link, and final confirmation.
|
|
115
|
+
|
|
116
|
+
### Draft Config Required Before Publishing
|
|
117
|
+
`publish_voice_agent` will fail if `agent_config` is empty. Always call `update_voice_agent` to set the draft config before publishing.
|
|
118
|
+
|
|
119
|
+
### Test Calls Use Draft Config, Production Calls Use Published Config
|
|
120
|
+
`test_new_voice_call` and `initiate_outbound_call` use draft config — changes are reflected immediately. `new_voice_call` and `web_new_voice_call` use published config — must call `publish_voice_agent` first.
|
|
121
|
+
|
|
122
|
+
### Text Agent Linkage
|
|
123
|
+
Use `get_voice_agent_by_text_agent(text_agent_id)` to find the voice counterpart of a text agent. This is the primary lookup when working across text and voice systems.
|
|
124
|
+
|
|
125
|
+
## agent_config Fields Reference
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"tone": "professional, helpful, and concise",
|
|
130
|
+
"speed": 1,
|
|
131
|
+
"voice": "VoiceDisplayName",
|
|
132
|
+
"persona": "Professional Voice Assistant",
|
|
133
|
+
"language": "en",
|
|
134
|
+
"services": ["lead_qualification", "meeting_booking", "q_and_a"],
|
|
135
|
+
"voice_id": "minimax-voice-uuid",
|
|
136
|
+
"expertise": ["customer_service", "sales", "scheduling"],
|
|
137
|
+
"default_accent": "us",
|
|
138
|
+
"model_provider": "minimax",
|
|
139
|
+
"max_call_duration": 600,
|
|
140
|
+
"prompt_config": {
|
|
141
|
+
"greeting_template": "Hello! How can I help you today?",
|
|
142
|
+
"realtime_template": "## Role & Objective\n...",
|
|
143
|
+
"system_instructions": "You are a helpful assistant...",
|
|
144
|
+
"auto_language_switching": true
|
|
145
|
+
},
|
|
146
|
+
"outbound_prompt_config": {
|
|
147
|
+
"greeting_template": "Hello! This is {{.CompanyName}}...",
|
|
148
|
+
"realtime_template": "## Role & Objective\n...",
|
|
149
|
+
"system_instructions": "..."
|
|
150
|
+
},
|
|
151
|
+
"minimax_config": {
|
|
152
|
+
"model": "speech-02-turbo",
|
|
153
|
+
"speed": 1,
|
|
154
|
+
"format": "pcm",
|
|
155
|
+
"volume": 1,
|
|
156
|
+
"bitrate": 128000,
|
|
157
|
+
"channels": 1,
|
|
158
|
+
"voice_id": "astra-voice-xxx",
|
|
159
|
+
"sample_rate": 32000
|
|
160
|
+
},
|
|
161
|
+
"rag_config": {
|
|
162
|
+
"enabled": true,
|
|
163
|
+
"token": "...",
|
|
164
|
+
"base_url": "...",
|
|
165
|
+
"timeout": 30,
|
|
166
|
+
"max_retries": 3
|
|
167
|
+
},
|
|
168
|
+
"silence_config": {},
|
|
169
|
+
"integrated_actions": [],
|
|
170
|
+
"outbound_integrated_actions": []
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Top-level fields
|
|
175
|
+
|
|
176
|
+
| Field | Type | Description |
|
|
177
|
+
|-------|------|-------------|
|
|
178
|
+
| `voice` | string | Display name of the selected voice |
|
|
179
|
+
| `voice_id` | string | Minimax voice record's `id` (NOT its `voice_id` field). Must reference a clone with `status=completed` |
|
|
180
|
+
| `speed` | number | Speech speed multiplier (default 1) |
|
|
181
|
+
| `tone` | string | Tone descriptor (e.g. "professional, helpful") |
|
|
182
|
+
| `persona` | string | Agent persona label |
|
|
183
|
+
| `language` | string | Primary language code. Default: `en`. See supported values below. Do NOT use "multilingual" — for multi-language support, set `auto_language_switching: true` in `prompt_config` instead |
|
|
184
|
+
| `default_accent` | string | Accent variant (e.g. `us`, `uk`, `in`) |
|
|
185
|
+
| `model_provider` | string | LLM backend: `openai`, `gemini`, or `minimax` |
|
|
186
|
+
| `services` | []string | Enabled service types |
|
|
187
|
+
| `expertise` | []string | Domain expertise tags |
|
|
188
|
+
| `max_call_duration` | int | Hard limit in seconds; call auto-terminates after this |
|
|
189
|
+
|
|
190
|
+
### prompt_config / outbound_prompt_config
|
|
191
|
+
|
|
192
|
+
Separate configurations for inbound vs outbound calls. Both share the same structure:
|
|
193
|
+
|
|
194
|
+
| Field | Description |
|
|
195
|
+
|-------|-------------|
|
|
196
|
+
| `realtime_template` | System prompt / instruction for voice calls (equivalent to text agent's instruction) |
|
|
197
|
+
| `greeting_template` | Opening message when the call starts. Supports `{{.CompanyName}}` etc. |
|
|
198
|
+
| `system_instructions` | Additional system-level instructions appended to the prompt |
|
|
199
|
+
| `auto_language_switching` | If true, agent auto-detects and switches to the caller's language. Set this when user wants "multilingual" support |
|
|
200
|
+
|
|
201
|
+
### Language Configuration
|
|
202
|
+
|
|
203
|
+
**`language` field** must be one of the supported language codes (default: `en`):
|
|
204
|
+
|
|
205
|
+
`en`, `zh`, `yue`, `es`, `fr`, `de`, `ja`, `ko`, `pt`, `it`, `ru`, `ar`, `hi`, `th`, `vi`, `id`, `ms`, `nl`, `pl`, `tr`, `sv`, `no`, `da`, `fi`, `el`, `he`, `uk`, `cs`, `ro`, `hu`, `bg`, `fa`, `sk`, `hr`, `tl`, `sl`, `ca`, `nn`, `ta`, `af`
|
|
206
|
+
|
|
207
|
+
**Rules:**
|
|
208
|
+
- Default to `en` unless the user specifies a different primary language
|
|
209
|
+
- **Never** set `language` to `"multilingual"` — it is not a valid value
|
|
210
|
+
- When the user says "multilingual" or "multi-language", set `language` to their primary language (or `en` by default) AND set `prompt_config.auto_language_switching: true`
|
|
211
|
+
- Example: user says "I want multilingual support, mainly Chinese" → `language: "zh"`, `auto_language_switching: true`
|
|
212
|
+
- Example: user says "support multiple languages" → `language: "en"`, `auto_language_switching: true`
|
|
213
|
+
|
|
214
|
+
### minimax_config
|
|
215
|
+
|
|
216
|
+
Low-level TTS engine parameters (only relevant when `model_provider=minimax`):
|
|
217
|
+
|
|
218
|
+
| Field | Description |
|
|
219
|
+
|-------|-------------|
|
|
220
|
+
| `model` | TTS model (e.g. `speech-02-turbo`) |
|
|
221
|
+
| `voice_id` | Internal Minimax voice ID (auto-derived from top-level `voice_id`) |
|
|
222
|
+
| `speed`, `volume` | Playback tuning |
|
|
223
|
+
| `format`, `bitrate`, `channels`, `sample_rate` | Audio encoding parameters |
|
|
224
|
+
|
|
225
|
+
### rag_config
|
|
226
|
+
|
|
227
|
+
Controls knowledge-base retrieval for the voice agent:
|
|
228
|
+
|
|
229
|
+
| Field | Description |
|
|
230
|
+
|-------|-------------|
|
|
231
|
+
| `enabled` | Whether RAG is active |
|
|
232
|
+
| `token`, `base_url` | Credentials and endpoint for the knowledge service |
|
|
233
|
+
| `timeout`, `max_retries` | Request tuning |
|
|
234
|
+
|
|
235
|
+
### Other fields
|
|
236
|
+
|
|
237
|
+
- `silence_config` — Silence detection thresholds (affects when the agent speaks during pauses)
|
|
238
|
+
- `integrated_actions` / `outbound_integrated_actions` — Action definitions triggered during inbound/outbound calls
|
|
239
|
+
|
|
240
|
+
### Updating agent_config
|
|
241
|
+
|
|
242
|
+
`update_voice_agent` performs a safe GET → merge → PUT for all `agent_config` changes. Examples:
|
|
243
|
+
|
|
244
|
+
- **Bind a cloned voice**: `update_voice_agent(voice_agent_id, agent_config={voice_id: "uuid", voice: "MyVoice"})`
|
|
245
|
+
- **Change language**: `update_voice_agent(voice_agent_id, agent_config={language: "zh", default_accent: "cn"})`
|
|
246
|
+
- **Update instruction**: `update_voice_agent(voice_agent_id, instruction="new prompt text")`
|
|
247
|
+
- **Update greeting**: `update_voice_agent(voice_agent_id, greeting="Hello! ...")`
|
|
248
|
+
- **Combo**: `update_voice_agent(voice_agent_id, instruction="...", agent_config={language: "en", tone: "friendly"})`
|
|
249
|
+
|
|
250
|
+
The `instruction` and `greeting` shortcut params map to `prompt_config.realtime_template` and `prompt_config.greeting_template` respectively. The `agent_config` param merges at the top level. All three can be combined in a single call.
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# WATI API Reference
|
|
2
|
+
|
|
3
|
+
WATI API for WhatsApp business messaging. Base URL depends on the tenant's `api_endpoint` (e.g. `https://live-mt-server.wati.io`).
|
|
4
|
+
|
|
5
|
+
Full docs: https://docs.wati.io/reference/introduction
|
|
6
|
+
|
|
7
|
+
## Authentication
|
|
8
|
+
|
|
9
|
+
All requests require `Authorization: Bearer <token>` header. The bearer token is obtained when creating a WATI connection via `create_integration_auth(platform="wati", bearer_token=..., api_endpoint=...)`.
|
|
10
|
+
|
|
11
|
+
## Contacts
|
|
12
|
+
|
|
13
|
+
### List Contacts
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
GET /api/ext/v3/contacts?page_number=1&page_size=20
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Response:
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"contact_list": [
|
|
23
|
+
{
|
|
24
|
+
"id": "507f1f77bcf86cd799439011",
|
|
25
|
+
"wa_id": "1234567890",
|
|
26
|
+
"name": "John Doe",
|
|
27
|
+
"phone": "+1234567890",
|
|
28
|
+
"contact_status": "active",
|
|
29
|
+
"source": "manual",
|
|
30
|
+
"opted_in": true,
|
|
31
|
+
"allow_broadcast": true,
|
|
32
|
+
"teams": ["Team A"],
|
|
33
|
+
"custom_params": [{"name": "city", "value": "New York"}],
|
|
34
|
+
"channel_type": "whatsapp"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"page_number": 1,
|
|
38
|
+
"page_size": 20
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Add Contact
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
POST /api/ext/v3/contacts
|
|
46
|
+
Content-Type: application/json
|
|
47
|
+
|
|
48
|
+
{
|
|
49
|
+
"whatsapp_number": "1234567890",
|
|
50
|
+
"name": "John Doe",
|
|
51
|
+
"custom_params": [
|
|
52
|
+
{"name": "age", "value": "30"},
|
|
53
|
+
{"name": "city", "value": "New York"}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Required fields: `whatsapp_number`, `name`.
|
|
59
|
+
|
|
60
|
+
### Update Contacts (Batch)
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
PUT /api/ext/v3/contacts
|
|
64
|
+
Content-Type: application/json
|
|
65
|
+
|
|
66
|
+
{
|
|
67
|
+
"contacts": [
|
|
68
|
+
{
|
|
69
|
+
"target": "507f1f77bcf86cd799439011",
|
|
70
|
+
"customParams": [{"name": "city", "value": "London"}]
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`target` can be: ContactId, PhoneNumber, or `Channel:PhoneNumber` format.
|
|
77
|
+
|
|
78
|
+
### Get Contact Detail
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
GET /api/ext/v3/contacts/{contact_id}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Conversations
|
|
85
|
+
|
|
86
|
+
### Get Messages
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
GET /api/ext/v3/conversations/{target}/messages?page_number=1&page_size=20
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`target` can be:
|
|
93
|
+
- **ConversationId** — unique conversation ID
|
|
94
|
+
- **PhoneNumber** — e.g. `14155552671`
|
|
95
|
+
- **Channel:PhoneNumber** — e.g. `MyChannel:14155552671`
|
|
96
|
+
|
|
97
|
+
Response:
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"message_list": [
|
|
101
|
+
{
|
|
102
|
+
"id": "507f1f77bcf86cd799439011",
|
|
103
|
+
"text": "Hello!",
|
|
104
|
+
"type": "text",
|
|
105
|
+
"timestamp": "2026-01-06T02:50:13Z",
|
|
106
|
+
"owner": true,
|
|
107
|
+
"status": "delivered",
|
|
108
|
+
"operator_name": "John Doe",
|
|
109
|
+
"conversation_id": "685bd235e6119686e693a093",
|
|
110
|
+
"event_type": "message"
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
"page_number": 1,
|
|
114
|
+
"page_size": 20
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Send Text Message
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
POST /api/ext/v3/conversations/{target}/messages/text
|
|
122
|
+
Content-Type: application/json
|
|
123
|
+
|
|
124
|
+
{
|
|
125
|
+
"text": "Hello, how can I help you?"
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Send File Message (via URL)
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
POST /api/ext/v3/conversations/{target}/messages/file/url
|
|
133
|
+
Content-Type: application/json
|
|
134
|
+
|
|
135
|
+
{
|
|
136
|
+
"url": "https://example.com/document.pdf",
|
|
137
|
+
"caption": "Here is your document"
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Send Interactive Message
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
POST /api/ext/v3/conversations/{target}/messages/interactive
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Assign Operator
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
PUT /api/ext/v3/conversations/{target}/assign
|
|
151
|
+
Content-Type: application/json
|
|
152
|
+
|
|
153
|
+
{
|
|
154
|
+
"assigned_id": "<operator_id>"
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Update Conversation Status
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
PUT /api/ext/v3/conversations/{target}/status
|
|
162
|
+
Content-Type: application/json
|
|
163
|
+
|
|
164
|
+
{
|
|
165
|
+
"status": "resolved"
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Template Messages (V1)
|
|
170
|
+
|
|
171
|
+
### Send Template Message
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
POST /api/v1/sendTemplateMessage?whatsappNumber=85264318721
|
|
175
|
+
Content-Type: application/json
|
|
176
|
+
|
|
177
|
+
{
|
|
178
|
+
"template_name": "new_chat_v1",
|
|
179
|
+
"broadcast_name": "my_broadcast",
|
|
180
|
+
"channel_number": "85264318721",
|
|
181
|
+
"parameters": [
|
|
182
|
+
{"name": "name", "value": "Matthew"}
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Required fields: `template_name`, `broadcast_name`, `channel_number`, `parameters`.
|
|
188
|
+
|
|
189
|
+
### Get Templates
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
GET /api/v1/getMessageTemplates
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Campaigns (V3)
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
GET /api/ext/v3/campaigns?page_number=1&page_size=20
|
|
199
|
+
GET /api/ext/v3/campaigns/{campaign_id}
|
|
200
|
+
GET /api/ext/v3/campaigns/{campaign_id}/recipients
|
|
201
|
+
GET /api/ext/v3/campaigns/{campaign_id}/overview
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Chatbots (V3, Pro Plan)
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
GET /api/ext/v3/chatbots
|
|
208
|
+
POST /api/ext/v3/chatbots/start
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Error Handling
|
|
212
|
+
|
|
213
|
+
| Code | Meaning |
|
|
214
|
+
|------|---------|
|
|
215
|
+
| 400 | Invalid request — check required fields |
|
|
216
|
+
| 401 | Unauthorized — invalid or expired bearer token |
|
|
217
|
+
| 403 | Forbidden — insufficient permissions |
|
|
218
|
+
| 429 | Rate limit exceeded |
|
|
219
|
+
| 500 | Server error — retry |
|
|
220
|
+
|
|
221
|
+
Error response format:
|
|
222
|
+
```json
|
|
223
|
+
{"code": 400, "message": "Description", "timestamp": "2026-01-01T00:00:00Z"}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Astra ↔ WATI Mapping
|
|
227
|
+
|
|
228
|
+
| Astra Tool | WATI Equivalent |
|
|
229
|
+
|------------|-----------------|
|
|
230
|
+
| `get_contacts_and_leads` | `GET /api/ext/v3/contacts` |
|
|
231
|
+
| `get_contact` | `GET /api/ext/v3/contacts/{id}` |
|
|
232
|
+
| `list_conversations` | N/A (Astra gateway conversations) |
|
|
233
|
+
| `get_conversation_messages` | `GET /api/ext/v3/conversations/{target}/messages` |
|
|
234
|
+
|
|
235
|
+
WATI-specific operations not available through Astra gateway:
|
|
236
|
+
- `POST /api/ext/v3/contacts` — add contact directly
|
|
237
|
+
- `PUT /api/ext/v3/contacts` — batch update contacts
|
|
238
|
+
- `POST /api/ext/v3/conversations/{target}/messages/text` — send message
|
|
239
|
+
- `POST /api/v1/sendTemplateMessage` — send template message
|
|
240
|
+
- `GET /api/ext/v3/campaigns` — campaign management
|