Skip to content

Recipes

Common Vue patterns for autopilot-client. Each example assumes you have wired up a client in main.ts as shown in Vue overview.

Register a function from inside a component

Scope the function to the component's lifetime:

vue
<script setup lang="ts">
import { onScopeDispose } from 'vue';
import { useAutopilotClient } from '@llmor/autopilot-core';

const client = useAutopilotClient();

client.registerFunction({
  name: 'open_settings',
  description: 'Opens the settings dialog.',
  handler: () => {
    settingsOpen.value = true;
  },
});

onScopeDispose(() => client.unregisterFunction('open_settings'));

const settingsOpen = ref(false);
</script>

Sync the current route into context

ts
// router-context.ts
import { watchEffect } from 'vue';
import { useRoute } from 'vue-router';
import { useAutopilotStore } from '@llmor/autopilot-vue';

export function useRouteContext() {
  const route = useRoute();
  const store = useAutopilotStore();

  watchEffect(() => {
    store.context.route = {
      path: route.path,
      params: route.params,
      query: route.query,
    };
  });
}

Call useRouteContext() once in your root component.

React to streaming

vue
<script setup lang="ts">
import { watch } from 'vue';
import { useAutopilotStore } from '@llmor/autopilot-vue';

const store = useAutopilotStore();

watch(
  () => store.isStreaming,
  (streaming) => {
    document.body.dataset.assistantBusy = String(streaming);
  },
);
</script>

Scroll a chat container to the bottom

vue
<script setup lang="ts">
import { ref, watch, nextTick } from 'vue';
import { useAutopilotConversation } from '@llmor/autopilot-vue';

const { visibleMessages, streamingMessage } = useAutopilotConversation();
const scroller = ref<HTMLElement>();

watch(
  [visibleMessages, () => streamingMessage.value?.message],
  async () => {
    await nextTick();
    scroller.value?.scrollTo({ top: scroller.value.scrollHeight });
  },
);
</script>

<template>
  <div ref="scroller" class="chat">
    <article v-for="(msg, i) in visibleMessages" :key="i">{{ msg.message }}</article>
  </div>
</template>

Wait for connection before rendering a feature

vue
<script setup lang="ts">
import { useAutopilotStore } from '@llmor/autopilot-vue';
const store = useAutopilotStore();
</script>

<template>
  <Suspense>
    <template #default>
      <AutopilotFeature v-if="store.isConnected" />
      <p v-else>Connecting to the assistant…</p>
    </template>
  </Suspense>
</template>

Show toasts for function errors

ts
import { useAutopilotClient } from '@llmor/autopilot-core';
import { useToast } from '@/composables/useToast';

const client = useAutopilotClient();
const toast = useToast();

client.on('functionError', ({ request, error }) => {
  toast.error(`${request.name}: ${error.message}`);
});