autoInstall() — one-line install
Zero-config on-ramp. Returns a fully-constructed DotDotDuck with sensible defaults so you can see the SDK working before deciding what to configure.
Minimum
import { autoInstall } from '@perhapxin/dddk';
import '@perhapxin/dddk/styles.css';
const dddk = autoInstall();
That's it. You get:
- Command palette wired to
Ctrl+K/⌘K. - Subtitle bar mounted center-bottom.
- Dwell long-press detector on desktop mouse input.
- Mobile FAB (bottom-right).
- All six default duck sprites loaded from the SDK's bundled
dist/duck/. - Locale auto-detected:
zh/zh-*→'zh-TW', everything else →'en'. - SDK-shipped prompt defaults registered on
dddk.prompts. - A demo LLM that responds to any completion with a "wire your real provider" nudge — so agent / InlineAgent / voice-cleanup don't silently no-op; the user sees why nothing is happening.
Passing overrides
Every field of DotDotDuckConfig is accepted verbatim, plus one factory-specific flag (demoLLM).
const dddk = autoInstall({
llm: myOpenAIProvider, // real LLM replaces the demo stub
siteName: 'Acme',
agentName: 'Rex',
paletteCommands: myCommands,
brand: { voice: 'friendly' },
webAgent: {
contextProvider: () => ({ tenant: currentTenant() }),
},
});
autoInstall(overrides) and new DotDotDuck({ ...factoryDefaults, ...overrides }) are functionally equivalent — the factory just picks the defaults. Anything you don't override keeps the demo default.
Disabling the demo LLM
By default, if you don't pass llm, autoInstall wires a demo stub. To keep the old "silent no-op if no LLM" behaviour (matches raw new DotDotDuck({})), set demoLLM: false:
const dddk = autoInstall({ demoLLM: false });
// Palette + Dwell + FAB still mount; agent-side features silently
// no-op until an `llm` gets wired at runtime.
Useful when your LLM provider is async-loaded (e.g. behind auth) and you want the SDK up before it's ready.
Full option type
interface AutoInstallOptions extends Partial<DotDotDuckConfig> {
/**
* When true and no `llm` is provided, wire a demo LLM that returns
* a canned "wire an LLM" response. Default: true. Set to false to
* keep the agent silently no-op — matches raw `new DotDotDuck({})`
* behaviour, useful when the host will wire an LLM later.
*/
demoLLM?: boolean;
}
Return type: DotDotDuck. Same instance you'd get from new DotDotDuck(...). All methods (startAgent, runSkill, submitSurface, etc.) are available.
When NOT to use autoInstall
- You already wire every config field explicitly. Migrating to
autoInstall({...})would just move code around — no benefit. - You need SSR-safe initialisation.
autoInstallreadsnavigator.languageat construction time, so it can't run on the server. Call it insideonMount(Svelte) /useEffect(React) /mounted(Vue). - You want the demo LLM to be permanent. The demo LLM is intentionally hostile-to-real-use — its response tells the user to wire a real provider. If your product legitimately doesn't need an LLM, pass
demoLLM: falseand skip the pill.
Common integration patterns
Vanilla HTML + <script>
<script type="module">
import { autoInstall } from 'https://esm.sh/@perhapxin/dddk@0.2.2';
import 'https://esm.sh/@perhapxin/dddk@0.2.2/styles.css';
const dddk = autoInstall();
window.dddk = dddk; // for DevTools poking
</script>
SvelteKit
<script lang="ts">
import { onMount } from 'svelte';
import { autoInstall } from '@perhapxin/dddk';
import '@perhapxin/dddk/styles.css';
onMount(() => {
const dddk = autoInstall({
llm: myProvider,
paletteCommands: buildCommands(),
});
return () => dddk.destroy?.();
});
</script>
React / Next.js
'use client';
import { useEffect } from 'react';
import { autoInstall } from '@perhapxin/dddk';
import '@perhapxin/dddk/styles.css';
export function DddkBoot() {
useEffect(() => {
const dddk = autoInstall({ llm: getLLM() });
return () => dddk.destroy?.();
}, []);
return null;
}
Related
- overview.md — what the SDK does at a glance.
- quickstart-frameworks.md — framework-specific setup.
- prompts.md — customise the prompts your demo LLM (or real LLM) will use.
- migrating.md — moving from
new DotDotDuck({...})toautoInstall(...).