Skip to main content

Calling in Mini Programs

WeChat Mini Programs can call the TCB Agent via wx.cloud.extend.AI, which supports streaming output.

Check which protocol your Agent uses

An Agent's communication protocol is determined by the template it was created from. If its endpoint on the console's "Integration & Debugging" page ends with /acp (the cloudbase-agent template), it uses the ACP protocol; self-hosted HTTP Agents use the AG-UI protocol. The examples below are grouped by protocol.

Prerequisites

  • Mini Program Basic Library 3.15.1+
  • TCB environment has been activated
  • Agent has been created

Initialization

// app.js
App({
onLaunch() {
wx.cloud.init({
env: 'your-env-id',
});
}
});

Calling an ACP Protocol Agent (cloudbase-agent template)

Write the request body in the JSON-RPC format of the ACP protocol, and parse session/update events from eventStream:

async function sendMessage(message) {
const res = await wx.cloud.extend.AI.bot.sendMessage({
data: {
// botId required, identifying the invoked Agent
botId: 'your-agent-id',
jsonrpc: '2.0',
id: 1,
method: 'session/prompt',
params: {
prompt: [{ type: 'text', text: message }],
// Multi-turn: pass back the sessionId returned in previous events to keep context
// sessionId: 'your-session-id',
},
}
});

let response = '';
for await (const event of res.eventStream) {
if (event.data === '[DONE]') break;
const frame = JSON.parse(event.data);
const update = frame?.params?.update;
if (update?.sessionUpdate === 'agent_message_chunk') {
response += update.content.text; // reply text increment
}
}
return response;
}

sendMessage('Hello');

Calling an AG-UI Protocol Agent (self-hosted HTTP Agent)

Basic Invocation

function generateId() {
const timestamp = Date.now().toString().slice(-4);
const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
return timestamp + random;
}

async function sendMessage(message) {
const res = await wx.cloud.extend.AI.bot.sendMessage({
data: {
// botId required, identifying the invoked Agent
botId: 'your-agent-id',
// Input parameter structure refers to the frontend-backend communication protocol:
// https://docs.cloudbase.net/ai/agent/http-agent-protocol
threadId: 'thread_id_' + generateId(),
runId: 'run_id_' + generateId(),
messages: [
{ id: String(Date.now()), role: 'user', content: message }
],
tools: [],
context: [],
state: {},
forwardedProps: {},
}
});

// Receive streaming responses
let response = '';
for await (const event of res.eventStream) {
// Need to manually parse event.data
const data = JSON.parse(event.data);
// Output based on event type; refer to the documentation for response events:
// https://docs.cloudbase.net/ai/agent/http-agent-protocol#%E5%93%8D%E5%BA%94%E4%BA%8B%E4%BB%B6
switch (data.type) {
case 'TEXT_MESSAGE_CONTENT':
response += data.delta;
console.log(data.delta); // Real-time output
break;

case 'RUN_ERROR':
console.error('Runtime error:', data.message);
break;

case 'RUN_FINISHED':
// Execution ended
break;
}
}

return response;
}

sendMessage('Hello');

Complete Example

// pages/chat/chat.js

function generateId() {
const timestamp = Date.now().toString().slice(-4);
const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
return timestamp + random;
}

Page({
data: {
messages: [],
inputValue: '',
loading: false,
},

onInput(e) {
this.setData({ inputValue: e.detail.value });
},

async sendMessage() {
const { inputValue, messages } = this.data;
if (!inputValue.trim() || this.data.loading) return;

this.setData({
messages: [...messages, { role: 'user', content: inputValue }],
inputValue: '',
loading: true,
});

try {
const res = await wx.cloud.extend.AI.bot.sendMessage({
data: {
botId: 'your-agent-id',
threadId: 'thread_id_' + generateId(),
runId: 'run_id_' + generateId(),
messages: [
{ id: String(Date.now()), role: 'user', content: inputValue }
],
tools: [],
context: [],
state: {},
forwardedProps: {},
}
});

// Add an empty assistant message
this.setData({
messages: [...this.data.messages, { role: 'assistant', content: '' }],
});

// Receive streaming responses
let fullText = '';
for await (const event of res.eventStream) {
const data = JSON.parse(event.data);
if (data.type === 'TEXT_MESSAGE_CONTENT') {
fullText += data.delta;
const updatedMessages = [...this.data.messages];
updatedMessages[updatedMessages.length - 1].content = fullText;
this.setData({ messages: updatedMessages });
}
}
} catch (error) {
console.error('Failed to send message:', error);
wx.showToast({ title: 'Send failed', icon: 'none' });
} finally {
this.setData({ loading: false });
}
},
});