webagent — Public API

安裝

npm install @perhapxin/webagent

最小範例

import { WebAgent, OpenAIProvider } from '@perhapxin/webagent';

const agent = new WebAgent({
  llm: new OpenAIProvider({ apiKey: 'sk-...' }),
  locale: 'zh-TW',
});

agent.on('subtitle', (text) => console.log('Agent:', text));
agent.on('done', () => console.log('Done'));

await agent.run('幫我把標題改成「年度報告」');

主要 class

WebAgent

class WebAgent {
  constructor(config: WebAgentConfig);

  // 控制
  run(task: string): Promise<void>;
  stop(): void;
  pause(): void;
  resume(): void;
  isRunning(): boolean;

  // Session
  getSession(): AgentSession | null;
  clearSession(): void;

  // 互動回應(用戶填完 ask_user / a2ui form 後呼叫)
  respond(answer: string | object): void;

  // Events (EventEmitter API)
  on(event: AgentEvent, handler: Function): void;
  off(event: AgentEvent, handler: Function): void;
}

Config

interface WebAgentConfig {
  llm: LLMProvider;          // 見 03-llm-providers
  locale?: 'en' | 'zh-TW';   // 預設根據 navigator.language
  maxSteps?: number;         // 預設 20
  maxErrors?: number;        // 預設 3
  systemPrompt?: string;     // 額外加在 system prompt 後面
  sitemap?: SitemapEntry[];  // 告訴 agent 站內有哪些路由
  agentName?: string;        // 顯示用名字
  siteName?: string;
  customActions?: ActionDefinition[];  // 註冊自訂 action
  sessionStorageKey?: string;  // 預設 'webagent.session'
}

interface SitemapEntry {
  path: string;
  description: string;
}

Events

Event Payload 何時觸發
status 'idle' | 'thinking' | 'executing' | 'waiting' | 'done' | 'failed' status 改變
step AgentStep 每執行完一個 action
subtitle string agent 呼叫 show_subtitle action
a2ui_surface A2UISurface agent 呼叫 render_a2ui_surface action
ask_user { question: string; resolve: (answer: string) => void } agent 呼叫 ask_user action
overlay_update OverlayItem[] overlay 增 / 改 / 刪
navigate { path: string } agent 想換頁
error Error 任何錯誤
done AgentSession 任務完成

互動模式範例

1. ask_user(純文字問答)

agent.on('ask_user', ({ question, resolve }) => {
  const answer = window.prompt(question);
  resolve(answer ?? '');
});

2. A2UI surface(結構化 form)

import { A2UIRenderer } from '@perhapxin/webagent/ui';

const renderer = new A2UIRenderer({
  catalog: 'basic',         // 用內建 catalog
  placement: 'center',      // modal 在中央
});

agent.on('a2ui_surface', (surface) => {
  renderer.render(surface, {
    onSubmit: (data) => agent.respond(data),
    onCancel: () => agent.stop(),
  });
});

3. Subtitle / overlay

agent.on('subtitle', (text) => {
  myUI.showBottomBar(text);
});

agent.on('overlay_update', (items) => {
  myUI.renderHighlights(items);
});

Navigation Hook

Agent 想換頁時不會自己呼 location.href — 它發 navigate event,host 決定怎麼換(保留 SPA router 友善):

agent.on('navigate', ({ path }) => {
  router.push(path);  // Next.js / SvelteKit / React Router
});

自訂 action

agent.config.customActions = [
  {
    name: 'add_to_cart',
    description: 'Add a product to shopping cart',
    parameters: z.object({ productId: z.string() }),
    handler: async ({ productId }) => {
      await fetch(`/api/cart/add`, {
        method: 'POST',
        body: JSON.stringify({ productId }),
      });
      return { ok: true };
    },
  },
];

註冊後 LLM 會自動知道有這個 tool 可用。

Type 完整匯出

import type {
  WebAgentConfig,
  AgentSession,
  AgentStep,
  AgentAction,
  AgentEvent,
  AgentStatus,
  ActionDefinition,
  ActionResult,
  SitemapEntry,
  OverlayItem,
  A2UISurface,
  LLMProvider,
  LLMMessage,
} from '@perhapxin/webagent';