> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-web-sdk/actions.md).

# 动作

### 1. 配置 `actionConfig` 在连接时

```typescript
const client = useConvaiClient({
  apiKey: '...',
  characterId: '...',
  actionConfig: {
    // 角色可以发出的动作名称
    actions: ['Move To', 'Pick Up', 'Drop', 'Follow', 'Wave', 'Attack'],

    // 角色可以操作的场景对象
    objects: [
      { name: 'sword',  description: '地上的一把锋利钢剑' },
      { name: 'chest',  description: '角落里的一个木制宝箱' },
      { name: 'torch',  description: '墙上的一支燃烧火把' },
    ],

    // 机器人可以引用或操作的其他角色
    characters: [
      { name: 'Player', bio: '当前用户' },
      { name: 'Guard',  bio: '附近的守卫 NPC' },
    ],

    // 可选：角色初始关注的对象
    current_attention_object: 'sword',
  },
});
```

规则：

* `动作`, `对象`，以及 `角色` 定义本次会话中唯一有效的可执行项。
* `当前关注对象` 必须与以下项中的一个条目匹配： `objects[].name`.
* 如果可用动作或对象集合发生变化，请使用更新后的 `actionConfig`.

***

### 2. 接收 `actionResponse`

订阅 `actionResponse` 以在每回合后获取角色的动作决策。该负载有类型——请从 `ConvaiAction` 和 `ActionResponseEvent` 导入 SDK。

```typescript
import type { ActionResponseEvent } from '@convai/web-sdk/core';

client.on('actionResponse', ({ actions }: ActionResponseEvent) => {
  // actions: ConvaiAction[] — 数组<{ name: string; target?: string }>
  // 空数组是有效的无动作响应
  for (const action of actions) {
    dispatch(action.name, action.target);
  }
});
```

* 动作按顺序排列——请按顺序执行。
* `目标` 是可选的；某些动作（例如 `"Wave"`）没有目标。
* 空的 `动作` 数组不是错误——角色只是选择不行动。

***

### 3. 参数化动作

带有 `目标` 为 *参数化*：角色会执行 **为开启** 某个特定对象或角色，而不是只做一个简单手势。基础动作名称来自 `actionConfig.actions[]`，而目标会解析为来自 `actionConfig.objects[]` 或 `actionConfig.characters[]`.

```typescript
import type { ConvaiAction } from '@convai/web-sdk/core';

function handleAction(action: ConvaiAction) {
  if (action.target) {
    // 参数化：“Move To” → “chest”，“Follow” → “Player”
    moveCharacterTo(action.name, action.target);
  } else {
    // 简单动作：“Wave”，“Dance”
    playAnimation(action.name);
  }
}

client.on('actionResponse', ({ actions }) => actions.forEach(handleAction));
```

如果用户说 *"捡起剑并把它交给守卫"*，一次回合可发出：

```typescript
{ "actions": [
  { "name": "Move To", "target": "sword" },
  { "name": "Pick Up", "target": "sword" },
  { "name": "Move To", "target": "Guard" },
  { "name": "Drop",    "target": "Guard" }
] }
```

#### 要点

* `目标` 始终与以下项中声明的名称匹配： `actionConfig.objects[]` 或 `actionConfig.characters[]` ——角色不能凭空编造目标，因此可安全地用作场景图中的查找键。
* 根据角色的决定，同一个基础动作既可以作为参数化形式出现，也可以作为简单形式出现（`"Wave"` 对比 `"Wave" → "Player"`）；请根据是否存在 `目标`来分支处理，而不是根据动作名称。
* 来自 `updateSceneMetadata` 仅用于描述，绝不会作为 `目标` ——将任何可执行对象提升到 `actionConfig.objects`.

***

### 4. 在运行时更新关注对象

使用 `updateContext`告诉角色玩家当前正在查看哪个对象。角色会用它来解析“它”“那儿”“这里”。

```typescript
// 玩家把焦点移到了宝箱——静默更新
client.updateContext({
  current_attention_object: 'chest',
  run_llm: 'false',
});

// 更新关注对象并让角色回应
client.updateContext({
  text: '玩家现在正在看杠杆。',
  current_attention_object: 'lever',
  run_llm: 'auto',
});

// 清除关注对象
client.updateContext({
  current_attention_object: '',
  run_llm: 'false',
});
```

`当前关注对象` 必须与以下项中的一个条目匹配： `actionConfig.objects[].name`.

***

### 5. 更新描述性场景上下文

使用 `updateSceneMetadata` 来描述角色应该知道的环境变化。这是 **仅用于描述** ——不会添加新的动作目标。

```typescript
client.updateSceneMetadata([
  { name: 'fog',  description: '浓雾已弥漫开来，能见度很低' },
  { name: 'rain', description: '外面正下着大雨' },
]);
```

如果角色需要对某物采取行动，它必须在 `actionConfig.objects`.

***

### 6. 以编程方式触发动作

使用 `sendTriggerMessage` 以在没有用户输入的情况下让角色说话并行动——用于脚本事件或过场动画。

```typescript
// 在 Convai 仪表板中定义的命名触发器
client.sendTriggerMessage('greet_player');

// 带有自定义指令的触发器
client.sendTriggerMessage('pickup_item', '捡起剑并把它交给玩家。');
```

***

### 完整示例

```typescript
const client = useConvaiClient({
  apiKey: '...',
  characterId: '...',
  actionConfig: {
    actions: ['Move To', 'Pick Up', 'Drop', 'Follow'],
    objects: [
      { name: 'apple',  description: '木箱上的一个青苹果' },
      { name: 'basket', description: '玩家附近的一个柳条篮' },
    ],
    characters: [{ name: 'Player', bio: '当前用户' }],
    current_attention_object: 'apple',
  },
});

client.on('actionResponse', ({ actions }) => {
  for (const { name, target } of actions) {
    console.log(`[ACTION] ${name}${target ? ` → ${target}` : ''}`);
    // 例如：“Move To → apple”，“Pick Up → apple”，“Drop → basket”
  }
});

// 玩家在界面中选择了篮子
client.updateContext({
  current_attention_object: 'basket',
  run_llm: 'false',
});

// 玩家说“把那个放进篮子里”
// 角色将“那个”解析为 apple，并执行：Move To apple → Pick Up apple → Move To basket → Drop apple
```

***

### API 参考

#### `actionConfig` （连接选项）

| 字段       | 类型                        | 描述          |
| -------- | ------------------------- | ----------- |
| `动作`     | `string[]`                | 角色可以发出的动作名称 |
| `对象`     | `{ name, description }[]` | 场景中的对象      |
| `角色`     | `{ name, bio }[]`         | 其他角色        |
| `当前关注对象` | `string?`                 | 初始关注对象      |

#### `actionResponse` 事件

```
import type { ConvaiAction, ActionResponseEvent } from '@convai/web-sdk/core';

client.on('actionResponse', ({ actions }: ActionResponseEvent) => { ... });
```

| 类型                    | 字段                        | 描述                                                           |
| --------------------- | ------------------------- | ------------------------------------------------------------ |
| `ActionResponseEvent` | `actions: ConvaiAction[]` | 本回合的有序动作；空 = 无动作                                             |
| `ConvaiAction`        | `name: string`            | 基础动作名称来自 `actionConfig.actions[]`                            |
| `ConvaiAction`        | `target?: string`         | 参数化目标——来自 `actionConfig.objects[]` / `characters[]`；简单动作时不存在 |

#### `updateContext` （关注）

| 字段        | 类型                                 | 描述                 |
| --------- | ---------------------------------- | ------------------ |
| `文本`      | `string?`                          | 可选上下文文本            |
| `模式`      | `"append" \| "replace" \| "reset"` | 如何应用文本             |
| `run_llm` | `"true" \| "false" \| "auto"`      | 是否触发回应             |
| `当前关注对象`  | `string?`                          | 新的关注对象，或 `""` 用于清除 |

#### `updateSceneMetadata(items)`

| 字段   | 类型                        | 描述      |
| ---- | ------------------------- | ------- |
| `条目` | `{ name, description }[]` | 描述性场景元素 |

#### `sendTriggerMessage(triggerName?, triggerMessage?)`

以编程方式触发角色回应。两个参数均为可选。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-web-sdk/actions.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
