@agent-native/core 0.7.52 → 0.7.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +1 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.js +54 -13
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
- package/docs/content/a2a-protocol.md +19 -9
- package/docs/content/agent-mentions.md +2 -2
- package/docs/content/agent-teams.md +2 -2
- package/docs/content/client.md +1 -1
- package/docs/content/cloneable-saas.md +13 -13
- package/docs/content/creating-templates.md +251 -219
- package/docs/content/faq.md +2 -2
- package/docs/content/frames.md +1 -1
- package/docs/content/getting-started.md +1 -1
- package/docs/content/key-concepts.md +1 -1
- package/docs/content/messaging.md +11 -6
- package/docs/content/multi-app-workspace.md +2 -2
- package/docs/content/server.md +117 -133
- package/docs/content/skills-guide.md +3 -3
- package/docs/content/template-analytics.md +8 -6
- package/docs/content/template-design.md +25 -27
- package/docs/content/template-forms.md +26 -21
- package/docs/content/template-mail.md +4 -0
- package/docs/content/template-video.md +4 -4
- package/docs/content/what-is-agent-native.md +1 -1
- package/docs/content/workspace.md +37 -30
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates-meta.d.ts","sourceRoot":"","sources":["../../src/cli/templates-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC7B,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,eAAO,MAAM,SAAS,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"templates-meta.d.ts","sourceRoot":"","sources":["../../src/cli/templates-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC7B,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,eAAO,MAAM,SAAS,EAAE,YAAY,EA2NnC,CAAC;AAEF,yEAAyE;AACzE,wBAAgB,gBAAgB,IAAI,YAAY,EAAE,CAEjD;AAED,gFAAgF;AAChF,wBAAgB,aAAa,IAAI,YAAY,EAAE,CAE9C;AAED,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAIlE;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates-meta.js","sourceRoot":"","sources":["../../src/cli/templates-meta.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-party template metadata used by the `agent-native` CLI.\n *\n * This file is intentionally inlined here (rather than imported from a\n * separate workspace package) so that the published `@agent-native/core`\n * has no `workspace:*` runtime dependencies. Without this inlining, `npx\n * @agent-native/core create ...` fails on a fresh machine with:\n *\n * npm error code EUNSUPPORTEDPROTOCOL\n * npm error Unsupported URL Type \"workspace:\": workspace:*\n *\n * Keep this list in sync with `packages/shared-app-config/templates.ts`,\n * which serves the same metadata to the desktop / mobile / frame packages\n * that always run inside the workspace. Duplication is intentional: the\n * CLI must remain installable outside the monorepo.\n */\n\nexport interface TemplateMeta {\n /** Directory name under templates/ and package name */\n name: string;\n /** Display name in pickers */\n label: string;\n /** One-line description shown in the picker */\n hint: string;\n /** Longer description (optional) */\n description?: string;\n /** Tabler icon name used in the desktop sidebar */\n icon: string;\n /** Hex accent color */\n color: string;\n /** CSS-safe RGB triplet (e.g. \"59 130 246\") */\n colorRgb: string;\n /** Dev server port for desktop `pnpm dev` */\n devPort: number;\n /** Production URL when running as a first-party app on agent-native.com */\n prodUrl?: string;\n /** Default URL path when deployed in a workspace (defaults to \"/<name>\") */\n prodPath?: string;\n /** Default mode when added to desktop app */\n defaultMode?: \"dev\" | \"prod\";\n /** Hide from pickers but still scaffoldable via explicit --template */\n hidden?: boolean;\n /** Always scaffold without prompting (e.g. starter as fallback) */\n alwaysAvailable?: boolean;\n /** Internal workspace packages this template depends on (e.g. \"scheduling\") */\n requiredPackages?: string[];\n /** Core app — featured in the CLI picker, homepage, and docs gallery */\n core?: boolean;\n}\n\nexport const TEMPLATES: TemplateMeta[] = [\n {\n name: \"mail\",\n label: \"Mail\",\n hint: \"Agent-native Superhuman — email client with keyboard shortcuts and AI triage\",\n icon: \"Mail\",\n color: \"#3B82F6\",\n colorRgb: \"59 130 246\",\n devPort: 8085,\n prodUrl: \"https://mail.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"calendar\",\n label: \"Calendar\",\n hint: \"Agent-native Google Calendar — manage events, sync, and public booking\",\n icon: \"CalendarDays\",\n color: \"#8B5CF6\",\n colorRgb: \"139 92 246\",\n devPort: 8082,\n prodUrl: \"https://calendar.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"scheduling\"],\n core: true,\n },\n {\n name: \"content\",\n label: \"Content\",\n hint: \"Agent-native Notion/Google Docs — write and organize with agent assistance\",\n icon: \"FileText\",\n color: \"#10B981\",\n colorRgb: \"16 185 129\",\n devPort: 8083,\n prodUrl: \"https://content.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"slides\",\n label: \"Slides\",\n hint: \"Agent-native Google Slides — generate and edit React presentations\",\n icon: \"GalleryHorizontal\",\n color: \"#EC4899\",\n colorRgb: \"236 72 153\",\n devPort: 8086,\n prodUrl: \"https://slides.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"videos\",\n label: \"Video\",\n hint: \"Agent-native video editing with Remotion\",\n icon: \"Video\",\n color: \"#EF4444\",\n colorRgb: \"239 68 68\",\n devPort: 8087,\n prodUrl: \"https://videos.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"analytics\",\n label: \"Analytics\",\n hint: \"Agent-native Amplitude/Mixpanel — connect data sources, prompt for charts\",\n icon: \"BarChart2\",\n color: \"#F59E0B\",\n colorRgb: \"245 158 11\",\n devPort: 8088,\n prodUrl: \"https://analytics.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"dispatch\",\n label: \"Dispatch\",\n hint: \"Central Slack/Telegram router with jobs, memory, approvals, and A2A delegation\",\n icon: \"MessageCircle\",\n color: \"#14B8A6\",\n colorRgb: \"20 184 166\",\n devPort: 8092,\n prodUrl: \"https://dispatch.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"forms\",\n label: \"Forms\",\n hint: \"Agent-native form builder — create, edit, and manage forms\",\n icon: \"ClipboardList\",\n color: \"#06B6D4\",\n colorRgb: \"6 182 212\",\n devPort: 8084,\n prodUrl: \"https://forms.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"issues\",\n label: \"Issues\",\n hint: \"Agent-native Jira — project management and issue tracking\",\n icon: \"BrandJira\",\n color: \"#6366F1\",\n colorRgb: \"99 102 241\",\n devPort: 8091,\n prodUrl: \"https://issues.agent-native.com\",\n defaultMode: \"dev\",\n hidden: true,\n },\n {\n name: \"recruiting\",\n label: \"Recruiting\",\n hint: \"Agent-native Greenhouse — manage candidates and recruiting pipelines\",\n icon: \"Users\",\n color: \"#16A34A\",\n colorRgb: \"22 163 74\",\n devPort: 8090,\n prodUrl: \"https://recruiting.agent-native.com\",\n defaultMode: \"dev\",\n hidden: true,\n },\n {\n name: \"starter\",\n label: \"Starter\",\n hint: \"Minimal scaffold with the agent chat and core architecture wired up\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8089,\n defaultMode: \"prod\",\n alwaysAvailable: true,\n core: true,\n },\n {\n name: \"clips\",\n label: \"Clips\",\n hint: \"Async screen recording — record, transcribe, share\",\n icon: \"ScreenShare\",\n color: \"#625DF5\",\n colorRgb: \"98 93 245\",\n devPort: 8094,\n prodUrl: \"https://clips.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"design\",\n label: \"Design\",\n hint: \"Agent-native design tool — create and edit visual designs with agent assistance\",\n icon: \"Brush\",\n color: \"#F472B6\",\n colorRgb: \"244 114 182\",\n devPort: 8099,\n prodUrl: \"https://design.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"calls\",\n label: \"Calls\",\n hint: \"Agent-native Gong — record, transcribe, and analyze sales calls\",\n icon: \"Phone\",\n color: \"#111111\",\n colorRgb: \"17 17 17\",\n devPort: 8095,\n prodUrl: \"https://calls.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"meeting-notes\",\n label: \"Meeting Notes\",\n hint: \"AI meeting notes — transcribe, enhance, and share meeting notes\",\n icon: \"Note\",\n color: \"#16A34A\",\n colorRgb: \"22 163 74\",\n devPort: 8096,\n prodUrl: \"https://meeting-notes.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"scheduling\",\n label: \"Scheduling\",\n hint: \"Full scheduling app — event types, team round-robin, routing forms, workflows\",\n icon: \"CalendarTime\",\n color: \"#7C3AED\",\n colorRgb: \"124 58 237\",\n devPort: 8098,\n prodUrl: \"https://scheduling.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"scheduling\"],\n hidden: true,\n },\n {\n name: \"voice\",\n label: \"Voice\",\n hint: \"Voice dictation — speak to type anywhere with context-aware formatting\",\n icon: \"Microphone\",\n color: \"#8B5CF6\",\n colorRgb: \"139 92 246\",\n devPort: 8097,\n prodUrl: \"https://voice.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"macros\",\n label: \"Macros\",\n hint: \"Internal template — not shown in pickers\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8093,\n hidden: true,\n defaultMode: \"dev\",\n },\n];\n\n/** Return templates visible in user-facing pickers (excludes hidden). */\nexport function visibleTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => !t.hidden);\n}\n\n/** Return core templates — the featured set shown in CLI pickers by default. */\nexport function coreTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => t.core);\n}\n\n/** Lookup by name. Returns undefined for unknown names. */\nexport function getTemplate(name: string): TemplateMeta | undefined {\n // Tolerate the legacy \"video\" alias.\n if (name === \"video\") name = \"videos\";\n return TEMPLATES.find((t) => t.name === name);\n}\n\n/** Names of all templates (including hidden) for validation. */\nexport function allTemplateNames(): string[] {\n return TEMPLATES.map((t) => t.name);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"templates-meta.js","sourceRoot":"","sources":["../../src/cli/templates-meta.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-party template metadata used by the `agent-native` CLI.\n *\n * This file is intentionally inlined here (rather than imported from a\n * separate workspace package) so that the published `@agent-native/core`\n * has no `workspace:*` runtime dependencies. Without this inlining, `npx\n * @agent-native/core create ...` fails on a fresh machine with:\n *\n * npm error code EUNSUPPORTEDPROTOCOL\n * npm error Unsupported URL Type \"workspace:\": workspace:*\n *\n * Keep this list in sync with `packages/shared-app-config/templates.ts`,\n * which serves the same metadata to the desktop / mobile / frame packages\n * that always run inside the workspace. Duplication is intentional: the\n * CLI must remain installable outside the monorepo.\n */\n\nexport interface TemplateMeta {\n /** Directory name under templates/ and package name */\n name: string;\n /** Display name in pickers */\n label: string;\n /** One-line description shown in the picker */\n hint: string;\n /** Longer description (optional) */\n description?: string;\n /** Tabler icon name used in the desktop sidebar */\n icon: string;\n /** Hex accent color */\n color: string;\n /** CSS-safe RGB triplet (e.g. \"59 130 246\") */\n colorRgb: string;\n /** Dev server port for desktop `pnpm dev` */\n devPort: number;\n /** Production URL when running as a first-party app on agent-native.com */\n prodUrl?: string;\n /** Default URL path when deployed in a workspace (defaults to \"/<name>\") */\n prodPath?: string;\n /** Default mode when added to desktop app */\n defaultMode?: \"dev\" | \"prod\";\n /** Hide from pickers but still scaffoldable via explicit --template */\n hidden?: boolean;\n /** Always scaffold without prompting (e.g. starter as fallback) */\n alwaysAvailable?: boolean;\n /** Internal workspace packages this template depends on (e.g. \"scheduling\") */\n requiredPackages?: string[];\n /** Core app — featured in the CLI picker, homepage, and docs gallery */\n core?: boolean;\n}\n\nexport const TEMPLATES: TemplateMeta[] = [\n {\n name: \"mail\",\n label: \"Mail\",\n hint: \"Agent-native Superhuman — email client with keyboard shortcuts and AI triage\",\n icon: \"Mail\",\n color: \"#3B82F6\",\n colorRgb: \"59 130 246\",\n devPort: 8085,\n prodUrl: \"https://mail.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"calendar\",\n label: \"Calendar\",\n hint: \"Agent-native Google Calendar — manage events, sync, and public booking\",\n icon: \"CalendarDays\",\n color: \"#8B5CF6\",\n colorRgb: \"139 92 246\",\n devPort: 8082,\n prodUrl: \"https://calendar.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"scheduling\"],\n core: true,\n },\n {\n name: \"content\",\n label: \"Content\",\n hint: \"Agent-native Notion/Google Docs — write and organize with agent assistance\",\n icon: \"FileText\",\n color: \"#10B981\",\n colorRgb: \"16 185 129\",\n devPort: 8083,\n prodUrl: \"https://content.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"slides\",\n label: \"Slides\",\n hint: \"Agent-native Google Slides — generate and edit React presentations\",\n icon: \"GalleryHorizontal\",\n color: \"#EC4899\",\n colorRgb: \"236 72 153\",\n devPort: 8086,\n prodUrl: \"https://slides.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"videos\",\n label: \"Video\",\n hint: \"Agent-native video editing with Remotion\",\n icon: \"Video\",\n color: \"#EF4444\",\n colorRgb: \"239 68 68\",\n devPort: 8087,\n prodUrl: \"https://videos.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"analytics\",\n label: \"Analytics\",\n hint: \"Agent-native Amplitude/Mixpanel — connect data sources, prompt for charts\",\n icon: \"BarChart2\",\n color: \"#F59E0B\",\n colorRgb: \"245 158 11\",\n devPort: 8088,\n prodUrl: \"https://analytics.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"dispatch\",\n label: \"Dispatch\",\n hint: \"Central Slack/Telegram router with jobs, memory, approvals, and A2A delegation\",\n icon: \"MessageCircle\",\n color: \"#14B8A6\",\n colorRgb: \"20 184 166\",\n devPort: 8092,\n prodUrl: \"https://dispatch.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"forms\",\n label: \"Forms\",\n hint: \"Agent-native form builder — create, edit, and manage forms\",\n icon: \"ClipboardList\",\n color: \"#06B6D4\",\n colorRgb: \"6 182 212\",\n devPort: 8084,\n prodUrl: \"https://forms.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"issues\",\n label: \"Issues\",\n hint: \"Agent-native Jira — project management and issue tracking\",\n icon: \"BrandJira\",\n color: \"#6366F1\",\n colorRgb: \"99 102 241\",\n devPort: 8091,\n prodUrl: \"https://issues.agent-native.com\",\n defaultMode: \"dev\",\n hidden: true,\n },\n {\n name: \"recruiting\",\n label: \"Recruiting\",\n hint: \"Agent-native Greenhouse — manage candidates and recruiting pipelines\",\n icon: \"Users\",\n color: \"#16A34A\",\n colorRgb: \"22 163 74\",\n devPort: 8090,\n prodUrl: \"https://recruiting.agent-native.com\",\n defaultMode: \"dev\",\n hidden: true,\n },\n {\n name: \"starter\",\n label: \"Starter\",\n hint: \"Minimal scaffold with the agent chat and core architecture wired up\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8089,\n defaultMode: \"prod\",\n alwaysAvailable: true,\n core: true,\n hidden: true,\n },\n {\n name: \"clips\",\n label: \"Clips\",\n hint: \"Async screen recording — record, transcribe, share\",\n icon: \"ScreenShare\",\n color: \"#625DF5\",\n colorRgb: \"98 93 245\",\n devPort: 8094,\n prodUrl: \"https://clips.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"design\",\n label: \"Design\",\n hint: \"Agent-native design tool — create and edit visual designs with agent assistance\",\n icon: \"Brush\",\n color: \"#F472B6\",\n colorRgb: \"244 114 182\",\n devPort: 8099,\n prodUrl: \"https://design.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"calls\",\n label: \"Calls\",\n hint: \"Agent-native Gong — record, transcribe, and analyze sales calls\",\n icon: \"Phone\",\n color: \"#111111\",\n colorRgb: \"17 17 17\",\n devPort: 8095,\n prodUrl: \"https://calls.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"meeting-notes\",\n label: \"Meeting Notes\",\n hint: \"AI meeting notes — transcribe, enhance, and share meeting notes\",\n icon: \"Note\",\n color: \"#16A34A\",\n colorRgb: \"22 163 74\",\n devPort: 8096,\n prodUrl: \"https://meeting-notes.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"scheduling\",\n label: \"Scheduling\",\n hint: \"Full scheduling app — event types, team round-robin, routing forms, workflows\",\n icon: \"CalendarTime\",\n color: \"#7C3AED\",\n colorRgb: \"124 58 237\",\n devPort: 8098,\n prodUrl: \"https://scheduling.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"scheduling\"],\n hidden: true,\n },\n {\n name: \"voice\",\n label: \"Voice\",\n hint: \"Voice dictation — speak to type anywhere with context-aware formatting\",\n icon: \"Microphone\",\n color: \"#8B5CF6\",\n colorRgb: \"139 92 246\",\n devPort: 8097,\n prodUrl: \"https://voice.agent-native.com\",\n defaultMode: \"prod\",\n hidden: true,\n },\n {\n name: \"macros\",\n label: \"Macros\",\n hint: \"Internal template — not shown in pickers\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8093,\n hidden: true,\n defaultMode: \"dev\",\n },\n];\n\n/** Return templates visible in user-facing pickers (excludes hidden). */\nexport function visibleTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => !t.hidden);\n}\n\n/** Return core templates — the featured set shown in CLI pickers by default. */\nexport function coreTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => t.core);\n}\n\n/** Lookup by name. Returns undefined for unknown names. */\nexport function getTemplate(name: string): TemplateMeta | undefined {\n // Tolerate the legacy \"video\" alias.\n if (name === \"video\") name = \"videos\";\n return TEMPLATES.find((t) => t.name === name);\n}\n\n/** Names of all templates (including hidden) for validation. */\nexport function allTemplateNames(): string[] {\n return TEMPLATES.map((t) => t.name);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoiceTranscriptionSection.d.ts","sourceRoot":"","sources":["../../../src/client/settings/VoiceTranscriptionSection.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"VoiceTranscriptionSection.d.ts","sourceRoot":"","sources":["../../../src/client/settings/VoiceTranscriptionSection.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA+DH,wBAAgB,yBAAyB,4CA2ZxC;AAuED,wBAAgB,sBAAsB,4CAErC"}
|
|
@@ -10,9 +10,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
10
10
|
*/
|
|
11
11
|
import { useCallback, useEffect, useState } from "react";
|
|
12
12
|
import { agentNativePath } from "../api-path.js";
|
|
13
|
-
import { IconCheck, IconExternalLink, IconLoader2, IconMicrophone, } from "@tabler/icons-react";
|
|
13
|
+
import { IconCheck, IconChevronDown, IconChevronRight, IconExternalLink, IconLoader2, IconMicrophone, } from "@tabler/icons-react";
|
|
14
14
|
import { useBuilderStatus } from "./useBuilderStatus.js";
|
|
15
15
|
const PREFS_URL = agentNativePath("/_agent-native/application-state/voice-transcription-prefs");
|
|
16
|
+
const CLEANUP_PREFS_URL = agentNativePath("/_agent-native/application-state/voice-cleanup-prefs");
|
|
16
17
|
const SECRETS_URL = agentNativePath("/_agent-native/secrets");
|
|
17
18
|
const PROVIDER_STATUS_URL = agentNativePath("/_agent-native/voice-providers/status");
|
|
18
19
|
const DEFAULT_PROVIDER = "browser";
|
|
@@ -33,7 +34,45 @@ export function VoiceTranscriptionSection() {
|
|
|
33
34
|
const [groqConfigured, setGroqConfigured] = useState(null);
|
|
34
35
|
const [saving, setSaving] = useState(false);
|
|
35
36
|
const [saveError, setSaveError] = useState(null);
|
|
37
|
+
const [showAdvanced, setShowAdvanced] = useState(false);
|
|
38
|
+
const [cleanupEnabled, setCleanupEnabled] = useState(null);
|
|
36
39
|
const { status: builderStatus } = useBuilderStatus();
|
|
40
|
+
// Read cleanup pref (default: true if Builder is connected).
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
let cancelled = false;
|
|
43
|
+
fetch(CLEANUP_PREFS_URL)
|
|
44
|
+
.then((r) => (r.ok ? r.json() : null))
|
|
45
|
+
.then((body) => {
|
|
46
|
+
if (cancelled)
|
|
47
|
+
return;
|
|
48
|
+
const stored = body?.enabled ??
|
|
49
|
+
body?.value?.enabled;
|
|
50
|
+
if (typeof stored === "boolean")
|
|
51
|
+
setCleanupEnabled(stored);
|
|
52
|
+
else
|
|
53
|
+
setCleanupEnabled(null); // resolve once builderStatus arrives
|
|
54
|
+
})
|
|
55
|
+
.catch(() => !cancelled && setCleanupEnabled(null));
|
|
56
|
+
return () => {
|
|
57
|
+
cancelled = true;
|
|
58
|
+
};
|
|
59
|
+
}, []);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (cleanupEnabled !== null)
|
|
62
|
+
return;
|
|
63
|
+
if (builderStatus?.configured !== undefined) {
|
|
64
|
+
setCleanupEnabled(!!builderStatus.configured);
|
|
65
|
+
}
|
|
66
|
+
}, [builderStatus?.configured, cleanupEnabled]);
|
|
67
|
+
const toggleCleanup = (next) => {
|
|
68
|
+
const previous = cleanupEnabled;
|
|
69
|
+
setCleanupEnabled(next);
|
|
70
|
+
fetch(CLEANUP_PREFS_URL, {
|
|
71
|
+
method: "PUT",
|
|
72
|
+
headers: { "Content-Type": "application/json" },
|
|
73
|
+
body: JSON.stringify({ enabled: next }),
|
|
74
|
+
}).catch(() => setCleanupEnabled(previous));
|
|
75
|
+
};
|
|
37
76
|
useEffect(() => {
|
|
38
77
|
let cancelled = false;
|
|
39
78
|
fetch(PREFS_URL)
|
|
@@ -149,22 +188,24 @@ export function VoiceTranscriptionSection() {
|
|
|
149
188
|
return;
|
|
150
189
|
window.location.hash = `#secrets:${key}`;
|
|
151
190
|
};
|
|
152
|
-
return (_jsxs("div", { className: "space-y-2", children: [_jsx(ProviderOption, { id: "
|
|
153
|
-
e.stopPropagation();
|
|
154
|
-
focusKey("OPENAI_API_KEY");
|
|
155
|
-
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Add key", _jsx(IconExternalLink, { size: 10 })] })) }), _jsx(ProviderOption, { id: "builder-gemini", selected: provider === "builder-gemini", onSelect: () => choose("builder-gemini"), disabled: !builderStatus?.configured, title: "Builder.io", subtitle: builderStatus?.configured
|
|
191
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsx(ProviderOption, { id: "builder-gemini", selected: provider === "builder-gemini", onSelect: () => choose("builder-gemini"), disabled: !builderStatus?.configured, title: "Builder.io Connect (recommended)", subtitle: builderStatus?.configured
|
|
156
192
|
? "Fast Gemini Flash-Lite transcription and cleanup through Builder.io. No Google key needed."
|
|
157
|
-
: "
|
|
193
|
+
: "One-click connect — uses Gemini Flash-Lite without a Google key.", rightSlot: builderStatus?.configured ? (_jsxs("span", { className: "flex items-center gap-1 text-[10px] text-green-500", children: [_jsx(IconCheck, { size: 10 }), "Connected"] })) : (_jsxs("button", { type: "button", onClick: (e) => {
|
|
158
194
|
e.stopPropagation();
|
|
159
195
|
const url = new URL(agentNativePath("/_agent-native/builder/connect"), window.location.origin).href;
|
|
160
196
|
window.open(url, "_blank", "noopener,noreferrer,width=600,height=700");
|
|
161
|
-
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Connect Builder.io", _jsx(IconExternalLink, { size: 10 })] })) }),
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
197
|
+
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Connect Builder.io", _jsx(IconExternalLink, { size: 10 })] })) }), _jsxs("div", { className: "flex items-start justify-between gap-3 rounded-md border border-border bg-accent/30 px-2.5 py-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-[11px] font-medium text-foreground", children: "Cleanup transcripts with AI" }), _jsx("p", { className: "text-[10px] text-muted-foreground mt-0.5", children: "Polish punctuation, casing, and remove filler words after each recording." })] }), _jsx("button", { type: "button", role: "switch", "aria-checked": !!cleanupEnabled, onClick: () => toggleCleanup(!cleanupEnabled), className: `relative inline-flex h-4 w-7 shrink-0 cursor-pointer items-center rounded-full transition-colors ${cleanupEnabled
|
|
198
|
+
? "bg-[#625DF5]"
|
|
199
|
+
: "bg-muted-foreground/30 hover:bg-muted-foreground/50"}`, children: _jsx("span", { className: `inline-block h-3 w-3 transform rounded-full bg-background transition-transform ${cleanupEnabled ? "translate-x-3.5" : "translate-x-0.5"}` }) })] }), _jsxs("div", { className: "rounded-md border border-border bg-background", children: [_jsxs("button", { type: "button", onClick: () => setShowAdvanced((v) => !v), className: "w-full flex items-center justify-between gap-2 px-2.5 py-2 cursor-pointer", children: [_jsxs("span", { className: "text-[11px] font-medium text-foreground inline-flex items-center gap-1", children: [showAdvanced ? (_jsx(IconChevronDown, { size: 12 })) : (_jsx(IconChevronRight, { size: 12 })), "Add API keys"] }), _jsx("span", { className: "text-[10px] text-muted-foreground", children: "OpenAI \u00B7 Gemini \u00B7 Groq \u00B7 browser" })] }), showAdvanced && (_jsxs("div", { className: "px-2 pb-2 space-y-2", children: [_jsx(ProviderOption, { id: "openai", selected: provider === "openai", onSelect: () => choose("openai"), title: "OpenAI Whisper", subtitle: "Best quality. Requires an OpenAI API key.", rightSlot: openAiConfigured === null ? null : openAiConfigured ? (_jsxs("span", { className: "flex items-center gap-1 text-[10px] text-green-500", children: [_jsx(IconCheck, { size: 10 }), "Key set"] })) : (_jsxs("button", { type: "button", onClick: (e) => {
|
|
200
|
+
e.stopPropagation();
|
|
201
|
+
focusKey("OPENAI_API_KEY");
|
|
202
|
+
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Add key", _jsx(IconExternalLink, { size: 10 })] })) }), _jsx(ProviderOption, { id: "gemini", selected: provider === "gemini", onSelect: () => choose("gemini"), title: "Google Gemini", subtitle: "Fast transcription via Gemini Flash Lite. Requires a Gemini API key.", rightSlot: geminiConfigured === null ? null : geminiConfigured ? (_jsxs("span", { className: "flex items-center gap-1 text-[10px] text-green-500", children: [_jsx(IconCheck, { size: 10 }), "Key set"] })) : (_jsxs("button", { type: "button", onClick: (e) => {
|
|
203
|
+
e.stopPropagation();
|
|
204
|
+
focusKey("GEMINI_API_KEY");
|
|
205
|
+
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Add key", _jsx(IconExternalLink, { size: 10 })] })) }), _jsx(ProviderOption, { id: "groq", selected: provider === "groq", onSelect: () => choose("groq"), title: "Groq Whisper", subtitle: "Fastest Whisper inference. Requires a Groq API key.", rightSlot: groqConfigured === null ? null : groqConfigured ? (_jsxs("span", { className: "flex items-center gap-1 text-[10px] text-green-500", children: [_jsx(IconCheck, { size: 10 }), "Key set"] })) : (_jsxs("button", { type: "button", onClick: (e) => {
|
|
206
|
+
e.stopPropagation();
|
|
207
|
+
focusKey("GROQ_API_KEY");
|
|
208
|
+
}, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40", children: ["Add key", _jsx(IconExternalLink, { size: 10 })] })) }), _jsx(ProviderOption, { id: "browser", selected: provider === "browser", onSelect: () => choose("browser"), title: "Native browser", subtitle: "Free built-in speech recognition. No key required." })] }))] }), provider !== "browser" && (_jsxs("div", { className: "rounded-md border border-border bg-accent/20 px-2.5 py-2", children: [_jsx("label", { htmlFor: "voice-transcription-instructions", className: "block text-[10px] font-medium text-foreground", children: "Custom instructions" }), _jsx("textarea", { id: "voice-transcription-instructions", value: instructions, onChange: (event) => updateInstructions(event.target.value), placeholder: "Names, casing, punctuation, style, or terms to preserve.", className: "mt-1 min-h-16 w-full resize-y rounded border border-border bg-background px-2 py-1.5 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent" }), _jsx("p", { className: "mt-1 text-[10px] text-muted-foreground", children: "Included with LLM-based transcription and cleanup." })] })), saving && _jsx("p", { className: "text-[10px] text-muted-foreground", children: "Saving\u2026" }), saveError && !saving && (_jsx("p", { className: "text-[10px] text-red-500", role: "alert", children: saveError }))] }));
|
|
168
209
|
}
|
|
169
210
|
function ProviderOption({ id, selected, disabled, onSelect, title, subtitle, rightSlot, }) {
|
|
170
211
|
const select = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoiceTranscriptionSection.js","sourceRoot":"","sources":["../../../src/client/settings/VoiceTranscriptionSection.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * <VoiceTranscriptionSection /> — provider picker for composer voice input.\n *\n * Writes the selection to application_state under `voice-transcription-prefs`\n * so the composer's `useVoiceDictation` hook picks it up on next record.\n *\n * Provider status comes from `/_agent-native/voice-providers/status`, which\n * mirrors the server transcription route's key/env resolution.\n */\n\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { agentNativePath } from \"../api-path.js\";\nimport {\n IconCheck,\n IconExternalLink,\n IconLoader2,\n IconMicrophone,\n} from \"@tabler/icons-react\";\nimport { useBuilderStatus } from \"./useBuilderStatus.js\";\n\ntype Provider =\n | \"openai\"\n | \"builder-gemini\"\n | \"builder\"\n | \"browser\"\n | \"gemini\"\n | \"groq\";\n\ninterface Prefs {\n provider: Provider;\n instructions?: string;\n}\n\ninterface SecretStatus {\n key: string;\n status: \"set\" | \"unset\" | \"invalid\";\n}\n\ninterface ProviderStatus {\n builder: boolean;\n gemini: boolean;\n openai: boolean;\n groq: boolean;\n browser: true;\n}\n\nconst PREFS_URL = agentNativePath(\n \"/_agent-native/application-state/voice-transcription-prefs\",\n);\nconst SECRETS_URL = agentNativePath(\"/_agent-native/secrets\");\nconst PROVIDER_STATUS_URL = agentNativePath(\n \"/_agent-native/voice-providers/status\",\n);\nconst DEFAULT_PROVIDER: Provider = \"browser\";\n\nfunction isProvider(value: unknown): value is Provider {\n return (\n value === \"openai\" ||\n value === \"builder-gemini\" ||\n value === \"builder\" ||\n value === \"browser\" ||\n value === \"gemini\" ||\n value === \"groq\"\n );\n}\n\nexport function VoiceTranscriptionSection() {\n const [provider, setProvider] = useState<Provider | null>(null);\n const [instructions, setInstructions] = useState(\"\");\n const [hasStoredProvider, setHasStoredProvider] = useState(false);\n const [openAiConfigured, setOpenAiConfigured] = useState<boolean | null>(\n null,\n );\n const [geminiConfigured, setGeminiConfigured] = useState<boolean | null>(\n null,\n );\n const [groqConfigured, setGroqConfigured] = useState<boolean | null>(null);\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n const { status: builderStatus } = useBuilderStatus();\n\n useEffect(() => {\n let cancelled = false;\n fetch(PREFS_URL)\n .then((r) => (r.ok ? r.json() : null))\n .then((body: Prefs | { value?: Prefs } | null) => {\n if (cancelled) return;\n const p =\n (body as Prefs | null)?.provider ??\n (body as { value?: Prefs } | null)?.value?.provider;\n const savedInstructions =\n (body as Prefs | null)?.instructions ??\n (body as { value?: Prefs } | null)?.value?.instructions;\n setHasStoredProvider(isProvider(p));\n setProvider(\n isProvider(p)\n ? p === \"builder\"\n ? \"builder-gemini\"\n : p\n : DEFAULT_PROVIDER,\n );\n if (typeof savedInstructions === \"string\") {\n setInstructions(savedInstructions);\n }\n })\n .catch(() => !cancelled && setProvider(DEFAULT_PROVIDER));\n return () => {\n cancelled = true;\n };\n }, []);\n\n useEffect(() => {\n if (hasStoredProvider || provider === null) return;\n if (builderStatus?.configured) setProvider(\"builder-gemini\");\n }, [builderStatus?.configured, hasStoredProvider, provider]);\n\n useEffect(() => {\n let cancelled = false;\n fetch(PROVIDER_STATUS_URL)\n .then((r) => (r.ok ? r.json() : null))\n .then((status: ProviderStatus | null) => {\n if (cancelled) return;\n if (status) {\n setOpenAiConfigured(status.openai);\n setGeminiConfigured(status.gemini);\n setGroqConfigured(status.groq);\n return;\n }\n return fetch(SECRETS_URL)\n .then((r) => (r.ok ? r.json() : []))\n .then((list: SecretStatus[]) => {\n if (cancelled) return;\n const find = (key: string) =>\n Array.isArray(list) ? list.find((s) => s.key === key) : null;\n setOpenAiConfigured(find(\"OPENAI_API_KEY\")?.status === \"set\");\n setGeminiConfigured(find(\"GEMINI_API_KEY\")?.status === \"set\");\n setGroqConfigured(find(\"GROQ_API_KEY\")?.status === \"set\");\n });\n })\n .catch(() => {\n if (!cancelled) {\n setOpenAiConfigured(false);\n setGeminiConfigured(false);\n setGroqConfigured(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, []);\n\n const persist = useCallback(\n async (\n nextProvider: Provider,\n nextInstructions: string,\n previous: { provider: Provider | null; instructions: string },\n ) => {\n setSaving(true);\n setSaveError(null);\n try {\n const res = await fetch(PREFS_URL, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n provider: nextProvider,\n instructions: nextInstructions.trim(),\n }),\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n } catch (err) {\n // Revert the optimistic update so the UI matches server state.\n setProvider(previous.provider);\n setInstructions(previous.instructions);\n setSaveError(\n `Couldn't save: ${(err as Error)?.message ?? \"network error\"}. Try again.`,\n );\n } finally {\n setSaving(false);\n }\n },\n [],\n );\n\n const choose = (next: Provider) => {\n if (next === provider) return;\n const previous = { provider, instructions };\n setHasStoredProvider(true);\n setProvider(next);\n void persist(next, instructions, previous);\n };\n\n const updateInstructions = (next: string) => {\n const previous = { provider, instructions };\n setInstructions(next);\n if (provider) void persist(provider, next, previous);\n };\n\n if (provider === null) {\n return (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading…\n </div>\n );\n }\n\n const focusKey = (key: string) => {\n if (typeof window === \"undefined\") return;\n window.location.hash = `#secrets:${key}`;\n };\n\n return (\n <div className=\"space-y-2\">\n <ProviderOption\n id=\"openai\"\n selected={provider === \"openai\"}\n onSelect={() => choose(\"openai\")}\n title=\"OpenAI Whisper\"\n subtitle=\"Best quality. Requires an OpenAI API key.\"\n rightSlot={\n openAiConfigured === null ? null : openAiConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"OPENAI_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"builder-gemini\"\n selected={provider === \"builder-gemini\"}\n onSelect={() => choose(\"builder-gemini\")}\n disabled={!builderStatus?.configured}\n title=\"Builder.io\"\n subtitle={\n builderStatus?.configured\n ? \"Fast Gemini Flash-Lite transcription and cleanup through Builder.io. No Google key needed.\"\n : \"Connect Builder.io to use Gemini Flash-Lite without a Google key.\"\n }\n rightSlot={\n builderStatus?.configured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Connected\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n const url = new URL(\n agentNativePath(\"/_agent-native/builder/connect\"),\n window.location.origin,\n ).href;\n window.open(\n url,\n \"_blank\",\n \"noopener,noreferrer,width=600,height=700\",\n );\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Connect Builder.io\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"gemini\"\n selected={provider === \"gemini\"}\n onSelect={() => choose(\"gemini\")}\n title=\"Google Gemini\"\n subtitle=\"Fast transcription via Gemini Flash Lite. Requires a Gemini API key.\"\n rightSlot={\n geminiConfigured === null ? null : geminiConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"GEMINI_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"groq\"\n selected={provider === \"groq\"}\n onSelect={() => choose(\"groq\")}\n title=\"Groq Whisper\"\n subtitle=\"Fastest Whisper inference. Requires a Groq API key.\"\n rightSlot={\n groqConfigured === null ? null : groqConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"GROQ_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"browser\"\n selected={provider === \"browser\"}\n onSelect={() => choose(\"browser\")}\n title=\"Native browser\"\n subtitle=\"Free built-in speech recognition. No key required.\"\n />\n\n {provider !== \"browser\" && (\n <div className=\"rounded-md border border-border bg-accent/20 px-2.5 py-2\">\n <label\n htmlFor=\"voice-transcription-instructions\"\n className=\"block text-[10px] font-medium text-foreground\"\n >\n Custom instructions\n </label>\n <textarea\n id=\"voice-transcription-instructions\"\n value={instructions}\n onChange={(event) => updateInstructions(event.target.value)}\n placeholder=\"Names, casing, punctuation, style, or terms to preserve.\"\n className=\"mt-1 min-h-16 w-full resize-y rounded border border-border bg-background px-2 py-1.5 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n />\n <p className=\"mt-1 text-[10px] text-muted-foreground\">\n Included with LLM-based transcription and cleanup.\n </p>\n </div>\n )}\n\n {saving && <p className=\"text-[10px] text-muted-foreground\">Saving…</p>}\n {saveError && !saving && (\n <p className=\"text-[10px] text-red-500\" role=\"alert\">\n {saveError}\n </p>\n )}\n </div>\n );\n}\n\ninterface ProviderOptionProps {\n id: string;\n selected: boolean;\n disabled?: boolean;\n onSelect: () => void;\n title: string;\n subtitle?: React.ReactNode;\n rightSlot?: React.ReactNode;\n}\n\nfunction ProviderOption({\n id,\n selected,\n disabled,\n onSelect,\n title,\n subtitle,\n rightSlot,\n}: ProviderOptionProps) {\n const select = () => {\n if (!disabled) onSelect();\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onSelect();\n }\n };\n\n return (\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onClick={select}\n onKeyDown={onKeyDown}\n aria-pressed={selected}\n aria-disabled={disabled || undefined}\n className={`w-full text-left rounded-md border px-2.5 py-2 flex items-start gap-2 ${\n selected\n ? \"border-[#625DF5] bg-[#625DF5]/10\"\n : \"border-border bg-accent/30 hover:bg-accent/50\"\n } ${disabled ? \"opacity-60 cursor-not-allowed\" : \"\"}`}\n >\n <span\n className={`mt-[2px] shrink-0 flex h-3.5 w-3.5 items-center justify-center rounded-full border ${\n selected\n ? \"border-[#625DF5] bg-[#625DF5]\"\n : \"border-muted-foreground/40 bg-background\"\n }`}\n >\n {selected && (\n <span className=\"h-1.5 w-1.5 rounded-full bg-background\" />\n )}\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"text-[11px] font-medium text-foreground\">{title}</div>\n {rightSlot && <div className=\"shrink-0\">{rightSlot}</div>}\n </div>\n {subtitle && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">{subtitle}</p>\n )}\n </div>\n </div>\n );\n}\n\nexport function VoiceTranscriptionIcon() {\n return <IconMicrophone size={14} />;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"VoiceTranscriptionSection.js","sourceRoot":"","sources":["../../../src/client/settings/VoiceTranscriptionSection.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * <VoiceTranscriptionSection /> — provider picker for composer voice input.\n *\n * Writes the selection to application_state under `voice-transcription-prefs`\n * so the composer's `useVoiceDictation` hook picks it up on next record.\n *\n * Provider status comes from `/_agent-native/voice-providers/status`, which\n * mirrors the server transcription route's key/env resolution.\n */\n\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { agentNativePath } from \"../api-path.js\";\nimport {\n IconCheck,\n IconChevronDown,\n IconChevronRight,\n IconExternalLink,\n IconLoader2,\n IconMicrophone,\n} from \"@tabler/icons-react\";\nimport { useBuilderStatus } from \"./useBuilderStatus.js\";\n\ntype Provider =\n | \"openai\"\n | \"builder-gemini\"\n | \"builder\"\n | \"browser\"\n | \"gemini\"\n | \"groq\";\n\ninterface Prefs {\n provider: Provider;\n instructions?: string;\n}\n\ninterface SecretStatus {\n key: string;\n status: \"set\" | \"unset\" | \"invalid\";\n}\n\ninterface ProviderStatus {\n builder: boolean;\n gemini: boolean;\n openai: boolean;\n groq: boolean;\n browser: true;\n}\n\nconst PREFS_URL = agentNativePath(\n \"/_agent-native/application-state/voice-transcription-prefs\",\n);\nconst CLEANUP_PREFS_URL = agentNativePath(\n \"/_agent-native/application-state/voice-cleanup-prefs\",\n);\nconst SECRETS_URL = agentNativePath(\"/_agent-native/secrets\");\nconst PROVIDER_STATUS_URL = agentNativePath(\n \"/_agent-native/voice-providers/status\",\n);\nconst DEFAULT_PROVIDER: Provider = \"browser\";\n\nfunction isProvider(value: unknown): value is Provider {\n return (\n value === \"openai\" ||\n value === \"builder-gemini\" ||\n value === \"builder\" ||\n value === \"browser\" ||\n value === \"gemini\" ||\n value === \"groq\"\n );\n}\n\nexport function VoiceTranscriptionSection() {\n const [provider, setProvider] = useState<Provider | null>(null);\n const [instructions, setInstructions] = useState(\"\");\n const [hasStoredProvider, setHasStoredProvider] = useState(false);\n const [openAiConfigured, setOpenAiConfigured] = useState<boolean | null>(\n null,\n );\n const [geminiConfigured, setGeminiConfigured] = useState<boolean | null>(\n null,\n );\n const [groqConfigured, setGroqConfigured] = useState<boolean | null>(null);\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [showAdvanced, setShowAdvanced] = useState(false);\n const [cleanupEnabled, setCleanupEnabled] = useState<boolean | null>(null);\n const { status: builderStatus } = useBuilderStatus();\n\n // Read cleanup pref (default: true if Builder is connected).\n useEffect(() => {\n let cancelled = false;\n fetch(CLEANUP_PREFS_URL)\n .then((r) => (r.ok ? r.json() : null))\n .then(\n (\n body:\n | { enabled?: boolean }\n | { value?: { enabled?: boolean } }\n | null,\n ) => {\n if (cancelled) return;\n const stored =\n (body as { enabled?: boolean } | null)?.enabled ??\n (body as { value?: { enabled?: boolean } } | null)?.value?.enabled;\n if (typeof stored === \"boolean\") setCleanupEnabled(stored);\n else setCleanupEnabled(null); // resolve once builderStatus arrives\n },\n )\n .catch(() => !cancelled && setCleanupEnabled(null));\n return () => {\n cancelled = true;\n };\n }, []);\n\n useEffect(() => {\n if (cleanupEnabled !== null) return;\n if (builderStatus?.configured !== undefined) {\n setCleanupEnabled(!!builderStatus.configured);\n }\n }, [builderStatus?.configured, cleanupEnabled]);\n\n const toggleCleanup = (next: boolean) => {\n const previous = cleanupEnabled;\n setCleanupEnabled(next);\n fetch(CLEANUP_PREFS_URL, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ enabled: next }),\n }).catch(() => setCleanupEnabled(previous));\n };\n\n useEffect(() => {\n let cancelled = false;\n fetch(PREFS_URL)\n .then((r) => (r.ok ? r.json() : null))\n .then((body: Prefs | { value?: Prefs } | null) => {\n if (cancelled) return;\n const p =\n (body as Prefs | null)?.provider ??\n (body as { value?: Prefs } | null)?.value?.provider;\n const savedInstructions =\n (body as Prefs | null)?.instructions ??\n (body as { value?: Prefs } | null)?.value?.instructions;\n setHasStoredProvider(isProvider(p));\n setProvider(\n isProvider(p)\n ? p === \"builder\"\n ? \"builder-gemini\"\n : p\n : DEFAULT_PROVIDER,\n );\n if (typeof savedInstructions === \"string\") {\n setInstructions(savedInstructions);\n }\n })\n .catch(() => !cancelled && setProvider(DEFAULT_PROVIDER));\n return () => {\n cancelled = true;\n };\n }, []);\n\n useEffect(() => {\n if (hasStoredProvider || provider === null) return;\n if (builderStatus?.configured) setProvider(\"builder-gemini\");\n }, [builderStatus?.configured, hasStoredProvider, provider]);\n\n useEffect(() => {\n let cancelled = false;\n fetch(PROVIDER_STATUS_URL)\n .then((r) => (r.ok ? r.json() : null))\n .then((status: ProviderStatus | null) => {\n if (cancelled) return;\n if (status) {\n setOpenAiConfigured(status.openai);\n setGeminiConfigured(status.gemini);\n setGroqConfigured(status.groq);\n return;\n }\n return fetch(SECRETS_URL)\n .then((r) => (r.ok ? r.json() : []))\n .then((list: SecretStatus[]) => {\n if (cancelled) return;\n const find = (key: string) =>\n Array.isArray(list) ? list.find((s) => s.key === key) : null;\n setOpenAiConfigured(find(\"OPENAI_API_KEY\")?.status === \"set\");\n setGeminiConfigured(find(\"GEMINI_API_KEY\")?.status === \"set\");\n setGroqConfigured(find(\"GROQ_API_KEY\")?.status === \"set\");\n });\n })\n .catch(() => {\n if (!cancelled) {\n setOpenAiConfigured(false);\n setGeminiConfigured(false);\n setGroqConfigured(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, []);\n\n const persist = useCallback(\n async (\n nextProvider: Provider,\n nextInstructions: string,\n previous: { provider: Provider | null; instructions: string },\n ) => {\n setSaving(true);\n setSaveError(null);\n try {\n const res = await fetch(PREFS_URL, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n provider: nextProvider,\n instructions: nextInstructions.trim(),\n }),\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n } catch (err) {\n // Revert the optimistic update so the UI matches server state.\n setProvider(previous.provider);\n setInstructions(previous.instructions);\n setSaveError(\n `Couldn't save: ${(err as Error)?.message ?? \"network error\"}. Try again.`,\n );\n } finally {\n setSaving(false);\n }\n },\n [],\n );\n\n const choose = (next: Provider) => {\n if (next === provider) return;\n const previous = { provider, instructions };\n setHasStoredProvider(true);\n setProvider(next);\n void persist(next, instructions, previous);\n };\n\n const updateInstructions = (next: string) => {\n const previous = { provider, instructions };\n setInstructions(next);\n if (provider) void persist(provider, next, previous);\n };\n\n if (provider === null) {\n return (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading…\n </div>\n );\n }\n\n const focusKey = (key: string) => {\n if (typeof window === \"undefined\") return;\n window.location.hash = `#secrets:${key}`;\n };\n\n return (\n <div className=\"space-y-2\">\n <ProviderOption\n id=\"builder-gemini\"\n selected={provider === \"builder-gemini\"}\n onSelect={() => choose(\"builder-gemini\")}\n disabled={!builderStatus?.configured}\n title=\"Builder.io Connect (recommended)\"\n subtitle={\n builderStatus?.configured\n ? \"Fast Gemini Flash-Lite transcription and cleanup through Builder.io. No Google key needed.\"\n : \"One-click connect — uses Gemini Flash-Lite without a Google key.\"\n }\n rightSlot={\n builderStatus?.configured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Connected\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n const url = new URL(\n agentNativePath(\"/_agent-native/builder/connect\"),\n window.location.origin,\n ).href;\n window.open(\n url,\n \"_blank\",\n \"noopener,noreferrer,width=600,height=700\",\n );\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Connect Builder.io\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n {/* Cleanup-with-AI toggle — defaults to on if Builder is connected. */}\n <div className=\"flex items-start justify-between gap-3 rounded-md border border-border bg-accent/30 px-2.5 py-2\">\n <div className=\"min-w-0\">\n <div className=\"text-[11px] font-medium text-foreground\">\n Cleanup transcripts with AI\n </div>\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">\n Polish punctuation, casing, and remove filler words after each\n recording.\n </p>\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={!!cleanupEnabled}\n onClick={() => toggleCleanup(!cleanupEnabled)}\n className={`relative inline-flex h-4 w-7 shrink-0 cursor-pointer items-center rounded-full transition-colors ${\n cleanupEnabled\n ? \"bg-[#625DF5]\"\n : \"bg-muted-foreground/30 hover:bg-muted-foreground/50\"\n }`}\n >\n <span\n className={`inline-block h-3 w-3 transform rounded-full bg-background transition-transform ${\n cleanupEnabled ? \"translate-x-3.5\" : \"translate-x-0.5\"\n }`}\n />\n </button>\n </div>\n\n {/* Single \"Add API keys\" disclosure — collapses BYOK rows + browser. */}\n <div className=\"rounded-md border border-border bg-background\">\n <button\n type=\"button\"\n onClick={() => setShowAdvanced((v) => !v)}\n className=\"w-full flex items-center justify-between gap-2 px-2.5 py-2 cursor-pointer\"\n >\n <span className=\"text-[11px] font-medium text-foreground inline-flex items-center gap-1\">\n {showAdvanced ? (\n <IconChevronDown size={12} />\n ) : (\n <IconChevronRight size={12} />\n )}\n Add API keys\n </span>\n <span className=\"text-[10px] text-muted-foreground\">\n OpenAI · Gemini · Groq · browser\n </span>\n </button>\n\n {showAdvanced && (\n <div className=\"px-2 pb-2 space-y-2\">\n <ProviderOption\n id=\"openai\"\n selected={provider === \"openai\"}\n onSelect={() => choose(\"openai\")}\n title=\"OpenAI Whisper\"\n subtitle=\"Best quality. Requires an OpenAI API key.\"\n rightSlot={\n openAiConfigured === null ? null : openAiConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"OPENAI_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"gemini\"\n selected={provider === \"gemini\"}\n onSelect={() => choose(\"gemini\")}\n title=\"Google Gemini\"\n subtitle=\"Fast transcription via Gemini Flash Lite. Requires a Gemini API key.\"\n rightSlot={\n geminiConfigured === null ? null : geminiConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"GEMINI_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"groq\"\n selected={provider === \"groq\"}\n onSelect={() => choose(\"groq\")}\n title=\"Groq Whisper\"\n subtitle=\"Fastest Whisper inference. Requires a Groq API key.\"\n rightSlot={\n groqConfigured === null ? null : groqConfigured ? (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Key set\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n focusKey(\"GROQ_API_KEY\");\n }}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n Add key\n <IconExternalLink size={10} />\n </button>\n )\n }\n />\n\n <ProviderOption\n id=\"browser\"\n selected={provider === \"browser\"}\n onSelect={() => choose(\"browser\")}\n title=\"Native browser\"\n subtitle=\"Free built-in speech recognition. No key required.\"\n />\n </div>\n )}\n </div>\n\n {provider !== \"browser\" && (\n <div className=\"rounded-md border border-border bg-accent/20 px-2.5 py-2\">\n <label\n htmlFor=\"voice-transcription-instructions\"\n className=\"block text-[10px] font-medium text-foreground\"\n >\n Custom instructions\n </label>\n <textarea\n id=\"voice-transcription-instructions\"\n value={instructions}\n onChange={(event) => updateInstructions(event.target.value)}\n placeholder=\"Names, casing, punctuation, style, or terms to preserve.\"\n className=\"mt-1 min-h-16 w-full resize-y rounded border border-border bg-background px-2 py-1.5 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n />\n <p className=\"mt-1 text-[10px] text-muted-foreground\">\n Included with LLM-based transcription and cleanup.\n </p>\n </div>\n )}\n\n {saving && <p className=\"text-[10px] text-muted-foreground\">Saving…</p>}\n {saveError && !saving && (\n <p className=\"text-[10px] text-red-500\" role=\"alert\">\n {saveError}\n </p>\n )}\n </div>\n );\n}\n\ninterface ProviderOptionProps {\n id: string;\n selected: boolean;\n disabled?: boolean;\n onSelect: () => void;\n title: string;\n subtitle?: React.ReactNode;\n rightSlot?: React.ReactNode;\n}\n\nfunction ProviderOption({\n id,\n selected,\n disabled,\n onSelect,\n title,\n subtitle,\n rightSlot,\n}: ProviderOptionProps) {\n const select = () => {\n if (!disabled) onSelect();\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onSelect();\n }\n };\n\n return (\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onClick={select}\n onKeyDown={onKeyDown}\n aria-pressed={selected}\n aria-disabled={disabled || undefined}\n className={`w-full text-left rounded-md border px-2.5 py-2 flex items-start gap-2 ${\n selected\n ? \"border-[#625DF5] bg-[#625DF5]/10\"\n : \"border-border bg-accent/30 hover:bg-accent/50\"\n } ${disabled ? \"opacity-60 cursor-not-allowed\" : \"\"}`}\n >\n <span\n className={`mt-[2px] shrink-0 flex h-3.5 w-3.5 items-center justify-center rounded-full border ${\n selected\n ? \"border-[#625DF5] bg-[#625DF5]\"\n : \"border-muted-foreground/40 bg-background\"\n }`}\n >\n {selected && (\n <span className=\"h-1.5 w-1.5 rounded-full bg-background\" />\n )}\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"text-[11px] font-medium text-foreground\">{title}</div>\n {rightSlot && <div className=\"shrink-0\">{rightSlot}</div>}\n </div>\n {subtitle && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">{subtitle}</p>\n )}\n </div>\n </div>\n );\n}\n\nexport function VoiceTranscriptionIcon() {\n return <IconMicrophone size={14} />;\n}\n"]}
|
|
@@ -16,13 +16,13 @@ A2A is the substrate for cross-app delegation in this framework — most promine
|
|
|
16
16
|
Key concepts:
|
|
17
17
|
|
|
18
18
|
- **Agent card** — public metadata at `/.well-known/agent-card.json` describing skills and capabilities
|
|
19
|
-
- **JSON-RPC** —
|
|
19
|
+
- **JSON-RPC** — agent-native apps use `POST /_agent-native/a2a`; external/legacy peers may use `POST /a2a`
|
|
20
20
|
- **Tasks** — each message creates a task with a lifecycle (submitted, working, completed, failed, canceled)
|
|
21
|
-
- **
|
|
21
|
+
- **JWT bearer auth** — production A2A requires `A2A_SECRET` or an explicit legacy `apiKeyEnv`
|
|
22
22
|
|
|
23
23
|
## Server setup {#server-setup}
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Most templates get A2A through the framework agent chat plugin. If you are mounting it yourself, call `mountA2A()` in a server plugin:
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
28
|
// server/plugins/a2a.ts
|
|
@@ -41,13 +41,21 @@ export default defineNitroPlugin((nitro) => {
|
|
|
41
41
|
examples: ["Show me signups by source this month"],
|
|
42
42
|
},
|
|
43
43
|
],
|
|
44
|
-
|
|
44
|
+
// Optional legacy external-peer bearer key. Prefer A2A_SECRET for
|
|
45
|
+
// agent-native workspace calls and production deployments.
|
|
46
|
+
apiKeyEnv: "A2A_API_KEY",
|
|
45
47
|
streaming: true, // enable message/stream
|
|
46
48
|
});
|
|
47
49
|
});
|
|
48
50
|
```
|
|
49
51
|
|
|
50
|
-
This mounts
|
|
52
|
+
This mounts:
|
|
53
|
+
|
|
54
|
+
- `GET /.well-known/agent-card.json` — public discovery metadata.
|
|
55
|
+
- `POST /_agent-native/a2a` — primary agent-native JSON-RPC endpoint.
|
|
56
|
+
- `POST /_agent-native/a2a/_process-task` — internal async processor route, signed with `A2A_SECRET`.
|
|
57
|
+
|
|
58
|
+
The client also falls back to `/a2a` for external agents that expose the legacy/simple path. Production agent-native deployments should set `A2A_SECRET`; without it, hosted runtimes fail closed instead of accepting unauthenticated remote work.
|
|
51
59
|
|
|
52
60
|
## Agent card {#agent-card}
|
|
53
61
|
|
|
@@ -87,7 +95,7 @@ The card endpoint is public, so the framework redacts skills whose IDs reveal pe
|
|
|
87
95
|
|
|
88
96
|
## JSON-RPC methods {#json-rpc-methods}
|
|
89
97
|
|
|
90
|
-
All methods are called via `POST /a2a` with JSON-RPC 2.0 format:
|
|
98
|
+
All methods are called via `POST /_agent-native/a2a` with JSON-RPC 2.0 format:
|
|
91
99
|
|
|
92
100
|
| Method | Description | Key params |
|
|
93
101
|
| ---------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
|
|
@@ -179,7 +187,9 @@ Tasks persist in the `a2a_tasks` SQL table and can be retrieved later via `tasks
|
|
|
179
187
|
|
|
180
188
|
## Security {#security}
|
|
181
189
|
|
|
182
|
-
Set `
|
|
190
|
+
Set `A2A_SECRET` on every production app that calls or receives A2A traffic. Agent-native callers sign JWT bearer tokens with this secret so receivers can verify the caller identity before the agent loop starts.
|
|
191
|
+
|
|
192
|
+
For external peers that still use a shared static token, set `apiKeyEnv` in your config to the name of an environment variable containing the expected bearer token:
|
|
183
193
|
|
|
184
194
|
```ts
|
|
185
195
|
// Config
|
|
@@ -192,7 +202,7 @@ mountA2A(app, {
|
|
|
192
202
|
const client = new A2AClient(url, process.env.A2A_API_KEY);
|
|
193
203
|
```
|
|
194
204
|
|
|
195
|
-
The agent card endpoint is always public (no auth) so other agents can discover capabilities. The `/a2a` JSON-RPC endpoint
|
|
205
|
+
The agent card endpoint is always public (no auth) so other agents can discover capabilities. The `/_agent-native/a2a` JSON-RPC endpoint accepts JWT bearer tokens signed by `A2A_SECRET`, and also accepts the legacy `apiKeyEnv` token when configured. In local development, auth can be omitted; in hosted production runtimes, missing A2A auth returns 503 instead of running unauthenticated.
|
|
196
206
|
|
|
197
207
|
### Auth policy boundary {#auth-policy}
|
|
198
208
|
|
|
@@ -253,7 +263,7 @@ The framework's pattern, used by both A2A async dispatch and the [integration we
|
|
|
253
263
|
3. Authenticate the self-fire with an HMAC token bound to the row id, signed with `A2A_SECRET`.
|
|
254
264
|
4. A recurring retry job sweeps any rows that were claimed but not finished, so a crashed function doesn't strand the work.
|
|
255
265
|
|
|
256
|
-
When you write your own A2A handler or integration adapter, follow the same shape. Don't attach work to a detached promise after `return`. The `integration-webhooks` skill is the canonical reference.
|
|
266
|
+
When you write your own A2A handler or integration adapter, follow the same shape. Don't attach work to a detached promise after `return`. If you must self-fire from a serverless handler, start the fetch before returning and give it a tiny head start (the framework uses a short timeout) so Lambda-style runtimes do not freeze before the outbound request leaves the process. The `integration-webhooks` skill is the canonical reference.
|
|
257
267
|
|
|
258
268
|
## Agent mentions {#agent-mentions}
|
|
259
269
|
|
|
@@ -60,7 +60,7 @@ Agents become available for mentioning through several mechanisms:
|
|
|
60
60
|
|
|
61
61
|
- **Custom workspace agents** — create agent profiles in the Workspace tab as `agents/*.md`
|
|
62
62
|
- **Auto-discovery** — the framework automatically discovers connected agents running on known ports or configured URLs
|
|
63
|
-
- **Remote manifests** — add connected-agent manifests as `agents/*.json`
|
|
63
|
+
- **Remote manifests** — add connected-agent manifests as `remote-agents/*.json`
|
|
64
64
|
|
|
65
65
|
### Custom workspace agents
|
|
66
66
|
|
|
@@ -91,7 +91,7 @@ You can create them from the Workspace tab using:
|
|
|
91
91
|
Remote A2A agents still use JSON manifests:
|
|
92
92
|
|
|
93
93
|
```json
|
|
94
|
-
// agents/analytics.json
|
|
94
|
+
// remote-agents/analytics.json
|
|
95
95
|
{
|
|
96
96
|
"name": "Analytics Agent",
|
|
97
97
|
"url": "https://analytics.example.com",
|
|
@@ -52,12 +52,12 @@ import { spawnTask } from "@agent-native/core/server";
|
|
|
52
52
|
|
|
53
53
|
const task = await spawnTask({
|
|
54
54
|
description: "Draft an outreach email to this lead",
|
|
55
|
-
instructions: "Match Steve's voice from
|
|
55
|
+
instructions: "Match Steve's voice from memory/MEMORY.md.",
|
|
56
56
|
ownerEmail: user.email,
|
|
57
57
|
systemPrompt: mailAgentSystemPrompt,
|
|
58
58
|
actions: mailActions,
|
|
59
59
|
apiKey: process.env.ANTHROPIC_API_KEY!,
|
|
60
|
-
parentSend: emit, //
|
|
60
|
+
parentSend: emit, // streaming sender for the parent chat response
|
|
61
61
|
});
|
|
62
62
|
```
|
|
63
63
|
|
package/docs/content/client.md
CHANGED
|
@@ -158,7 +158,7 @@ function App() {
|
|
|
158
158
|
| `queryClient` | `QueryClient?` | React-query client for cache invalidation |
|
|
159
159
|
| `queryKeys` | `string[]?` | Query key prefixes to invalidate. Default: `["file", "fileTree"]` |
|
|
160
160
|
| `pollUrl` | `string?` | Poll endpoint URL. Default: `"/_agent-native/poll"` |
|
|
161
|
-
| `onEvent` | `(data) => void` | Optional callback
|
|
161
|
+
| `onEvent` | `(data) => void` | Optional callback when a poll detects a newer sync version |
|
|
162
162
|
|
|
163
163
|
## cn(...inputs) {#cn}
|
|
164
164
|
|
|
@@ -15,19 +15,19 @@ We call them **cloneable SaaS**, not templates. You're not starting from scratch
|
|
|
15
15
|
|
|
16
16
|
Each one is a real app you could use today, and the launching pad for your own version of it.
|
|
17
17
|
|
|
18
|
-
| Template | What it is
|
|
19
|
-
| ------------- |
|
|
20
|
-
| **Mail** | An agent-native Superhuman. Inbox, labels, AI triage, keyboard-first, drafts and sends through the agent.
|
|
21
|
-
| **Calendar** | An agent-native Google Calendar. Events, sync, public booking links, agent-driven scheduling.
|
|
22
|
-
| **Content** | An agent-native Notion / Google Docs. Markdown + Tiptap editor, Notion sync, real-time multi-user collab.
|
|
23
|
-
| **Slides** | An agent-native Google Slides. React-based decks the agent generates and edits directly.
|
|
24
|
-
| **Video** | An agent-native video editor on Remotion. Prompt for a cut, the agent assembles it.
|
|
25
|
-
| **Analytics** | An agent-native Amplitude/Mixpanel. Connect data sources, prompt for charts, pin to dashboards.
|
|
26
|
-
| **Clips** | An agent-native Loom. Async screen + camera recording with transcription, chapters, AI summaries.
|
|
27
|
-
| **Design** |
|
|
28
|
-
| **Forms** | An agent-native Typeform. Build, share, and
|
|
29
|
-
| **Dispatch** | The workspace control plane: shared secrets, cross-app integrations, Slack/Telegram, scheduled jobs.
|
|
30
|
-
| **Starter** | The minimal scaffold. Agent chat plus the architecture, nothing else. Build something new.
|
|
18
|
+
| Template | What it is |
|
|
19
|
+
| ------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
20
|
+
| **Mail** | An agent-native Superhuman. Inbox, labels, AI triage, keyboard-first, drafts and sends through the agent. |
|
|
21
|
+
| **Calendar** | An agent-native Google Calendar. Events, sync, public booking links, agent-driven scheduling. |
|
|
22
|
+
| **Content** | An agent-native Notion / Google Docs. Markdown + Tiptap editor, Notion sync, real-time multi-user collab. |
|
|
23
|
+
| **Slides** | An agent-native Google Slides. React-based decks the agent generates and edits directly. |
|
|
24
|
+
| **Video** | An agent-native video editor on Remotion. Prompt for a cut, the agent assembles it. |
|
|
25
|
+
| **Analytics** | An agent-native Amplitude/Mixpanel. Connect data sources, prompt for charts, pin to dashboards. |
|
|
26
|
+
| **Clips** | An agent-native Loom. Async screen + camera recording with transcription, chapters, AI summaries. |
|
|
27
|
+
| **Design** | Agent-native HTML prototyping studio for interactive Alpine/Tailwind designs. |
|
|
28
|
+
| **Forms** | An agent-native Typeform. Build, share, collect, and route submissions to Slack, Sheets, webhooks, or Discord. |
|
|
29
|
+
| **Dispatch** | The workspace control plane: shared secrets, cross-app integrations, Slack/Telegram, scheduled jobs. |
|
|
30
|
+
| **Starter** | The minimal scaffold. Agent chat plus the architecture, nothing else. Build something new. |
|
|
31
31
|
|
|
32
32
|
See the full catalog under [Templates](/templates), or jump straight to one — for example, [Dispatch](/docs/template-dispatch) is a great place to start if you want a workspace-style app.
|
|
33
33
|
|