Skip to main content

Provider Context 和依赖注入

Vue 3 SDK 使用 Vue 3 的 provide/inject 机制来管理 AaaS Pilot Kit 实例的生命周期和状态共享。

依赖注入系统

推荐使用
  • 常规场景:使用 provideAaaSPilotKit - 这是推荐的标准方式,适用于大多数应用
  • 多实例场景:使用 useAaaSPilotKitProvider + provide - 用于需要在同一应用中管理多个独立的 AaaS Pilot Kit 实例

provideAaaSPilotKit

推荐使用 - Vue 3 依赖注入提供者,负责创建/销毁底层 createAaaSPilotKit 控制器,并将状态注入到子组件。

function provideAaaSPilotKit<AS extends BaseAgentService = BaseAgentService>(
options: IOptions<AS>
): IAaaSPilotKitProvider<AS>

核心职责

  • 在首次调用及 options 变更时自动创建控制器
  • 组件卸载时自动执行 controller.dispose()
  • 同步监听 readymuteis_rendering_change 等事件,生成响应式状态
  • 为子组件提供统一的状态和控制器访问接口

基本使用

<template>
<div class="app">
<ChatComponent />
<VoiceControls />
<ConversationHistory />
</div>
</template>

<script setup lang="ts">
import {provideAaaSPilotKit} from '@bdky/aaas-pilot-kit-vue3';
import type {IOptions} from '@bdky/aaas-pilot-kit';

const options: IOptions = {
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
// agentConfig: 若未提供自定义 agentService,此配置必填
agentConfig: {
token: 'your-token',
robotId: 'your-robot-id'
}
};

// 提供 AaaSPilotKit 实例给所有子组件
const provider = provideAaaSPilotKit(options);
</script>

语言配置

通过 lang 参数可以配置 ASR 识别和 TTS 合成的语言:

<script setup lang="ts">
import {provideAaaSPilotKit, Language} from '@bdky/aaas-pilot-kit-vue3';
import type {IOptions} from '@bdky/aaas-pilot-kit';

const options: IOptions = {
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
lang: Language.ENGLISH, // 使用 Language 常量
// 或 lang: 'en' // 直接使用字符串
agentConfig: {
token: 'your-token',
robotId: 'your-robot-id'
}
};

const provider = provideAaaSPilotKit(options);
</script>

支持的语言包括: 中文(zh)、英语(en)、日语(ja)、西班牙语(es)、俄语(ru)、韩语(ko)、越南语(vi)、德语(de)、印尼语(id)、泰语(th)。

详细的语言配置说明请参考 配置选项文档

动态配置更新

Provider 支持响应式地更新配置:

<script setup lang="ts">
import {ref, computed} from 'vue';
import {provideAaaSPilotKit} from '@bdky/aaas-pilot-kit-vue3';

const userId = ref('user123');
const selectedRobot = ref('robot456');

// 响应式配置
const options = computed(() => ({
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
// agentConfig: 若未提供自定义 agentService,此配置必填
agentConfig: {
token: `token-${userId.value}`,
robotId: selectedRobot.value
}
}));

// 配置变更时自动重新创建控制器
provideAaaSPilotKit(options.value);
</script>

useAaaSPilotKitProvider

高级用法 - 底层提供者实现,返回响应式的控制器和状态。

使用场景
  • 常规场景:不需要直接调用,使用 provideAaaSPilotKit 即可
  • 多实例场景:需要在同一应用中管理多个独立实例时使用(见 多实例支持
  • 自定义注入:需要使用自定义 injection key 时使用
function useAaaSPilotKitProvider<AS extends BaseAgentService = BaseAgentService>(
options: IOptions<AS>
): IAaaSPilotKitProvider<AS>

返回值接口

interface IAaaSPilotKitProvider<AS extends BaseAgentService = BaseAgentService> {
controller: ShallowRef<ReturnType<typeof createAaaSPilotKit<AS>> | null>;
isReady: Ref<boolean>;
isMuted: Ref<boolean>;
isRendering: Ref<boolean>;
create: () => void;
dispose: () => void;
}

injectAaaSPilotKit

底层依赖注入函数,用于在 子组件 中访问 Provider 实例。

function injectAaaSPilotKit<AS extends BaseAgentService = BaseAgentService>(): 
IAaaSPilotKitProvider<AS> | undefined

使用示例

<script setup lang="ts">
import {injectAaaSPilotKit} from '@bdky/aaas-pilot-kit-vue3';

const provider = injectAaaSPilotKit();

if (!provider) {
throw new Error('AaaSPilotKit 未注入提供者,请确保在 provideAaaSPilotKit 作用范围内使用');
}

// 直接访问 provider 属性
console.log('控制器实例:', provider.controller.value);
console.log('就绪状态:', provider.isReady.value);
</script>

生命周期管理

自动生命周期

Provider 自动管理控制器的生命周期:

<script setup lang="ts">
import {onMounted, onUnmounted} from 'vue';
import {provideAaaSPilotKit} from '@bdky/aaas-pilot-kit-vue3';

const provider = provideAaaSPilotKit(options);

// Provider 自动处理:
// - onMounted: 调用 provider.controller.mount(element)
// - onUnmounted: 调用 provider.controller.dispose()
// - 配置变更: 重新创建控制器
</script>

手动生命周期控制

在某些场景下,你可能需要手动控制生命周期:

<script setup lang="ts">
import {nextTick} from 'vue';
import {useAaaSPilotKit} from '@bdky/aaas-pilot-kit-vue3';

const {controller, create, dispose} = useAaaSPilotKit();

// 手动创建(例如延迟初始化)
const initializeAvatar = async () => {
if (!controller.value) {
create();
}
};

// 手动销毁(例如用户退出登录)
const cleanup = () => {
dispose();
};

// 重置会话
const restartSession = async () => {
dispose();
// 等待一个 tick 确保销毁完成
await nextTick();
create();
};
</script>

状态管理

响应式状态

Provider 维护的所有状态都是响应式的:

<template>
<div class="status-indicator">
<div :class="['status', {ready: isReady}]">
{{isReady ? '已就绪' : '初始化中'}}
</div>
<div v-if="isMuted" class="muted">🔇 已静音</div>
<div v-if="isRendering" class="rendering">⏳ 处理中</div>
</div>
</template>

<script setup lang="ts">
import {useAasSPilotKit} from '@bdky/aaas-pilot-kit-vue3';

const {isReady, isMuted, isRendering} = useAaaSPilotKit();
</script>

<style scoped>
.status.ready {
color: #4caf50;
}

.muted, .rendering {
color: #ff9800;
}
</style>

跨组件状态共享

所有子组件都可以访问相同的状态实例:

<!-- ParentComponent.vue -->
<template>
<div class="chat-app">
<StatusBar />
<MessageInput />
<ConversationList />
</div>
</template>

<script setup lang="ts">
import {provideAaaSPilotKit} from '@bdky/aaas-pilot-kit-vue3';

provideAaaSPilotKit(options);
</script>
<!-- StatusBar.vue -->
<script setup lang="ts">
import {useAaaSPilotKit} from '@bdky/aaas-pilot-kit-vue3';

// 访问共享状态
const {isReady, isRendering} = useAaaSPilotKit();
</script>
<!-- MessageInput.vue -->
<script setup lang="ts">
import {useAaaSPilotKit} from '@bdky/aaas-pilot-kit-vue3';

// 访问共享控制器
const {controller} = useAaaSPilotKit();

const sendMessage = (text: string) => {
controller.value?.input(text);
};
</script>

错误处理

Provider 注入检查

<script setup lang="ts">
import {useAaaSPilotKit} from '@bdky/aaas-pilot-kit-vue3';

try {
const {controller} = useAaaSPilotKit();
}
catch (error) {
console.error('AaaSPilotKit Provider 未找到,请检查:');
console.error('1. 是否在父组件中调用了 provideAaaSPilotKit');
console.error('2. 当前组件是否在 Provider 的作用范围内');
throw error;
}
</script>

控制器可用性检查

<script setup lang="ts">
import {computed} from 'vue';
import { useAaaSPilotKit } from '@bdky/aaas-pilot-kit-vue3';

const {controller, isReady} = useAaaSPilotKit();

const isControllerAvailable = computed(() => {
return controller.value !== null && isReady.value;
});

const safelyCallController = (callback: (ctrl: any) => void) => {
if (isControllerAvailable.value) {
callback(controller.value);
}
else {
console.warn('控制器未就绪或不可用');
}
};
</script>

高级用法

多实例支持

在复杂应用中,你可能需要管理多个 AaaS Pilot Kit 实例:

<template>
<div class="multi-avatar-app">
<div class="avatar-section">
<h3>客服助手</h3>
<AvatarContainer :provide-key="customerServiceKey" />
</div>
<div class="avatar-section">
<h3>销售助手</h3>
<AvatarContainer :provide-key="salesAssistantKey" />
</div>
</div>
</template>

<script setup lang="ts">
import {provide} from 'vue';
import {useAaaSPilotKitProvider} from '@bdky/aaas-pilot-kit-vue3';

// 为不同用途创建不同的实例
const customerServiceKey = Symbol('customer-service');
const salesAssistantKey = Symbol('sales-assistant');

const customerServiceProvider = useAaaSPilotKitProvider({
token: 'your-auth-token-here',
figureId: '209337',
// agentConfig: 若未提供自定义 agentService,此配置必填
agentConfig: {
robotId: 'customer-service-bot'
}
});

const salesAssistantProvider = useAaaSPilotKitProvider({
token: 'your-auth-token-here',
figureId: '209338',
// agentConfig: 若未提供自定义 agentService,此配置必填
agentConfig: {
robotId: 'sales-assistant-bot'
}
});

provide(customerServiceKey, customerServiceProvider);
provide(salesAssistantKey, salesAssistantProvider);
</script>

与全局状态管理集成

<script setup lang="ts">
import {watch} from 'vue';
import {useStore} from 'vuex'; // 或其他状态管理库
import {provideAaaSPilotKit, useAaaSPilotKitEvents} from '@bdky/aaas-pilot-kit-vue3';

const store = useStore();

// 从全局状态获取配置
const options = computed(() => ({
token: store.state.auth.token,
figureId: store.state.avatar.figureId,
// agentConfig: 若未提供自定义 agentService,此配置必填
agentConfig: {
token: store.state.user.token,
robotId: store.state.avatar.selectedRobot
}
}));

const provider = provideAaaSPilotKit(options.value);

// 同步状态到全局 store
useAaaSPilotKitEvents({
onReady: () => store.dispatch('avatar/setReady', true),
onConversationAdd: (conversation) =>
store.dispatch('chat/addConversation', conversation)
});
</script>

类型安全

Provider 系统提供完整的 TypeScript 支持:

import type { 
IAaaSPilotKitProvider,
AaaSPilotKitProviderKey
} from '@bdky/aaas-pilot-kit-vue3';

// 自定义 Agent Service 类型
class CustomAgentService extends BaseAgentService {
customMethod() {
return 'custom';
}
}

// 类型化的 Provider
const provider = provideAaaSPilotKit<CustomAgentService>(options);

// 类型安全的控制器访问
const { controller } = useAaaSPilotKit<CustomAgentService>();
if (controller.value) {
// 类型安全
controller.value.agentService.customMethod();
}