Skip to content
On this page

Agent 接入案例:小程序

小程序使用 AgentBehavior 接入多轮 Agent 对话、工具调用和状态管理。状态通过 this.data.agent 读取,方法通过 this.agent.* 调用。

index.js

js
import { AgentBehavior } from '@tencent/ssv-ai-sdk-miniprogram';
import { AGUIPlugin } from '@tencent/ssv-ai-sdk-plugin-agui';

const UI_ONLY_TOOLS = ['launchRocket'];

Component({
  behaviors: [
    AgentBehavior({
      api: {
        chatEndpoint: {
          url: 'https://your-api.com/agent',
        },
      },
      plugins: [new AGUIPlugin()],
    }),
  ],

  data: {
    inputValue: '',
    themeColor: '#1890ff',
    scrollId: '',
  },

  lifetimes: {
    attached() {
      this.agent?.setTools(this.createTools());
      this._handleToolExecuted = this.handleToolExecuted.bind(this);
      this.agent?.on('toolExecuted', this._handleToolExecuted);
    },

    detached() {
      if (this._handleToolExecuted) {
        this.agent?.off('toolExecuted', this._handleToolExecuted);
      }
      this.agent?.stop();
    },
  },

  observers: {
    'agent.messages'(messages) {
      if (messages && messages.length > 0) {
        this.setData({ scrollId: 'bottom' });
      }
    },
  },

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

    async handleSend() {
      const input = this.data.inputValue.trim();
      if (!input || this.data.agent?.status === 'loading') return;

      this.setData({ inputValue: '' });
      await this.agent.send({ input });
    },

    async handleToolExecuted({ toolCallId, toolCallName, result }) {
      if (UI_ONLY_TOOLS.includes(toolCallName)) return;

      const toolMessage = {
        id: `tool-${Date.now()}`,
        role: 'tool',
        content: typeof result === 'string' ? result : JSON.stringify(result),
        toolCallId,
        extraInfo: {},
      };

      const messages = this.data.agent?.messages || [];
      this.agent.setMessages([...messages, toolMessage]);
      await this.agent.send({}, { type: 'tools' });
    },

    createTools() {
      return [
        {
          name: 'setThemeColor',
          description: 'Set the page theme color. Use hex format like #1890ff.',
          type: 'frontend',
          parameters: {
            type: 'object',
            properties: {
              color: { type: 'string', description: 'Hex color' },
            },
            required: ['color'],
          },
          handler: async ({ color }) => {
            this.setData({ themeColor: color });
            return { success: true, color };
          },
        },
      ];
    },
  },
});

index.wxml

xml
<scroll-view scroll-y scroll-into-view="{{scrollId}}" class="messages">
  <block wx:for="{{agent.messages}}" wx:key="id">
    <view class="message {{item.role}}">
      <view wx:if="{{item.role === 'user'}}">
        <text>{{item.content}}</text>
      </view>

      <view wx:elif="{{item.role === 'assistant'}}">
        <block wx:for="{{item.parts}}" wx:key="index" wx:for-item="part">
          <view wx:if="{{part.type === 'reasoning'}}" class="reasoning">
            <text>{{part.reason}}</text>
          </view>
          <view wx:elif="{{part.type === 'text'}}">
            <text>{{part.text}}</text>
          </view>
          <view wx:elif="{{part.type === 'tool_call'}}" class="tool-call">
            <text>工具:{{part.name}},状态:{{part.status}}</text>
          </view>
        </block>
      </view>
    </view>
  </block>
  <view id="bottom" />
</scroll-view>

<input value="{{inputValue}}" bindinput="onInput" bindconfirm="handleSend" />
<button bindtap="handleSend" disabled="{{agent.status === 'loading'}}">发送</button>
<button wx:if="{{agent.status === 'loading'}}" bindtap="agent.stop">停止</button>

状态 / 方法速查

js
// 状态:this.data.agent.*
this.data.agent.messages
this.data.agent.status
this.data.agent.assistantStatus
this.data.agent.agentState

// 方法:this.agent.*
this.agent.send(params, options)
this.agent.stop()
this.agent.setMessages(messages)
this.agent.setTools(tools)
this.agent.on(event, handler)
this.agent.off(event, handler)

Released under the MIT License.