diff --git a/README.md b/README.md index ef240f86..6a064850 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Test quality, measure performance, & ship with confidence. EfficientAI Demo - [๐Ÿ“… Book a Demo](https://cal.com/aadhar-singh-bhadauria/30min) โ€ข [๐Ÿ’ป GitHub](https://github.com/EfficientAI-tech/efficientAI) + [๐Ÿ“… Book a Demo](https://cal.com/aadhar-singh-bhadauria/30min) โ€ข [๐Ÿ’ป GitHub](https://github.com/EfficientAI-tech/efficientAI) โ€ข [๐Ÿ’ฌ Discord](https://discord.gg/Saz9b2NA7) โญ If this saves you time, please consider starring the repo โ€” it helps us a lot. @@ -977,6 +977,7 @@ See `CONTRIBUTING.md` for PR format, review expectations, and release label conv - ๐Ÿ’ฌ **LinkedIn**: [Connect with us](https://www.linkedin.com/company/efficientaicloud) - ๐Ÿฆ **X (Twitter)**: [Follow us](https://x.com/AiEfficient) - ๐Ÿ’ป **GitHub**: [View on GitHub](https://github.com/EfficientAI-tech/efficientAI) +- ๐Ÿ’ฌ **Discord**: [Join our community](https://discord.gg/Saz9b2NA7) --- diff --git a/docs-fumadocs/app/(home)/page.tsx b/docs-fumadocs/app/(home)/page.tsx index 4b094bd8..1bdead38 100644 --- a/docs-fumadocs/app/(home)/page.tsx +++ b/docs-fumadocs/app/(home)/page.tsx @@ -1,5 +1,5 @@ import { redirect } from 'next/navigation'; export default function HomePage() { - redirect('/docs/intro/'); + redirect('/docs/quickstart/'); } diff --git a/docs-fumadocs/app/docs/[[...slug]]/page.tsx b/docs-fumadocs/app/docs/[[...slug]]/page.tsx index 83e8a4a9..3db4b61c 100644 --- a/docs-fumadocs/app/docs/[[...slug]]/page.tsx +++ b/docs-fumadocs/app/docs/[[...slug]]/page.tsx @@ -1,13 +1,17 @@ import { source } from '@/lib/source'; -import { DocsBody, DocsPage } from 'fumadocs-ui/layouts/docs/page'; +import { DocsBody, DocsPage } from 'fumadocs-ui/layouts/notebook/page'; import { notFound } from 'next/navigation'; import { getMDXComponents } from '@/components/mdx'; import type { Metadata } from 'next'; import { createRelativeLink } from 'fumadocs-ui/mdx'; import { ContributorsTocFooter } from '@/components/contributors'; -import { TocHeaderControls } from '@/components/toc-header-controls'; -import type { ComponentPropsWithoutRef } from 'react'; +import { OpenAPIPage } from '@/components/api-page'; +import { CopyPageMarkdown } from '@/components/copy-page-markdown'; +import { CommunityContactFooter } from '@/components/community-contact-footer'; +import type { ComponentPropsWithoutRef, ComponentType } from 'react'; import { ExternalLink } from 'lucide-react'; +import type { TOCItemType } from 'fumadocs-core/toc'; +import { openapi } from '@/lib/openapi'; function DocsRelativeLink(props: ComponentPropsWithoutRef<'a'> & { resolver: ReturnType }) { const { resolver, className, ...rest } = props; @@ -37,36 +41,71 @@ export default async function Page(props: PageProps<'/docs/[[...slug]]'>) { const page = source.getPage(params.slug); if (!page) notFound(); - const MDX = page.data.body; + const pageData = page.data as typeof page.data & { + body: ComponentType<{ components?: ReturnType }>; + toc?: TOCItemType[]; + full?: boolean; + _openapi?: { method?: string }; + }; + const MDX = pageData.body; + const markdownPath = + page.slugs[0] === 'api-reference' && page.slugs.length > 2 && pageData._openapi?.method + ? `/api-md/${page.slugs.slice(1).join('/')}.md` + : null; + const isEnterprisePage = (page.slugs[0] ?? '') === 'enterprise'; + const showToc = !isEnterprisePage; + const toc = showToc ? pageData.toc : undefined; + const full = isEnterprisePage || Boolean(pageData.full); return ( , - footer: , - }} - tableOfContentPopover={{ - header: , - footer: , - }} + toc={toc} + full={full} + breadcrumb={{ enabled: !isEnterprisePage }} + tableOfContent={ + showToc + ? { + footer: , + } + : undefined + } + tableOfContentPopover={ + showToc + ? { + footer: , + } + : undefined + } > - + + {markdownPath ? ( +
+ +
+ ) : null} , + OpenAPIPage: async (props) => ( + + ), })} /> + {!isEnterprisePage ? : null}
); } export async function generateStaticParams() { - return source.generateParams(); + const params = source.generateParams(); + if (params.length === 0) { + throw new Error( + 'Docs source returned no static params. Run `npx fumadocs-mdx` in docs-fumadocs and restart the dev server.', + ); + } + return params; } export async function generateMetadata(props: PageProps<'/docs/[[...slug]]'>): Promise { diff --git a/docs-fumadocs/app/docs/layout.tsx b/docs-fumadocs/app/docs/layout.tsx index a373143b..f17d78dc 100644 --- a/docs-fumadocs/app/docs/layout.tsx +++ b/docs-fumadocs/app/docs/layout.tsx @@ -1,11 +1,54 @@ import { source } from '@/lib/source'; -import { DocsLayout } from 'fumadocs-ui/layouts/docs'; import { baseOptions } from '@/lib/layout.shared'; +import type * as PageTree from 'fumadocs-core/page-tree'; +import type { LayoutTab } from 'fumadocs-ui/layouts/shared'; +import { DocsShell } from '@/components/docs-shell'; -export default function Layout({ children }: LayoutProps<'/docs'>) { - return ( - - {children} - +function folderUrls(folder: PageTree.Folder): string[] { + const urls: string[] = []; + if (folder.index?.url) urls.push(folder.index.url); + for (const child of folder.children) { + if (child.type === 'page') urls.push(child.url); + if (child.type === 'folder') urls.push(...folderUrls(child)); + } + return urls; +} + +function findRootFolder(tree: PageTree.Root, title: string): PageTree.Folder | undefined { + return tree.children.find( + (node): node is PageTree.Folder => node.type === 'folder' && node.name === title, ); } + +export default async function Layout({ children }: LayoutProps<'/docs'>) { + const options = baseOptions(); + const tree = source.getPageTree(); + const docsRoot = findRootFolder(tree, 'Docs'); + const apiRoot = findRootFolder(tree, 'API Reference'); + const tabs: LayoutTab[] = [ + { + title: 'Docs', + url: '/docs/quickstart/', + urls: new Set(docsRoot ? folderUrls(docsRoot) : ['/docs/', '/docs/quickstart/']), + }, + { + title: 'API Reference', + url: '/docs/api-reference/', + urls: new Set(apiRoot ? folderUrls(apiRoot) : ['/docs/api-reference/']), + }, + { + title: 'Enterprise', + url: '/docs/enterprise/', + }, + { + title: 'Changelog', + url: '/docs/changelog/', + }, + { + title: 'Blogs', + url: '/docs/blog/', + }, + ]; + + return {children}; +} diff --git a/docs-fumadocs/app/global.css b/docs-fumadocs/app/global.css index 15d5948a..0fd2727b 100644 --- a/docs-fumadocs/app/global.css +++ b/docs-fumadocs/app/global.css @@ -1,10 +1,13 @@ @import 'tailwindcss'; @import 'fumadocs-ui/css/neutral.css'; @import 'fumadocs-ui/css/preset.css'; +/* Tailwind cannot resolve the fumadocs-openapi package CSS export from app/. */ +@import '../node_modules/@fumadocs/api-docs/css/generated/shared.css'; +@import '../node_modules/fumadocs-openapi/css/generated/shared.css'; :root { --color-docs-warm: oklch(0.68 0.18 60); - --color-fd-background: oklch(0.995 0 0); + --color-fd-background: oklch(0.954 0.004 95); --color-fd-foreground: oklch(0.19 0 0); --color-fd-muted: oklch(0.972 0 0); --color-fd-muted-foreground: oklch(0.5 0 0); @@ -19,7 +22,7 @@ .dark { --color-docs-warm: oklch(0.78 0.17 65); - --color-fd-background: oklch(0.14 0.003 0); + --color-fd-background: oklch(0.17 0.004 95); --color-fd-foreground: oklch(0.95 0 0); --color-fd-muted: oklch(0.19 0.003 0); --color-fd-muted-foreground: oklch(0.73 0 0); @@ -34,6 +37,10 @@ html { scrollbar-gutter: stable; + scroll-behavior: smooth; + scroll-padding-top: calc(var(--fd-docs-row-2, 3.5rem) + 0.75rem); + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; } html > body[data-scroll-locked] { @@ -44,73 +51,99 @@ html > body[data-scroll-locked] { body { background: var(--color-fd-background); color: var(--color-fd-foreground); + font-family: var(--font-docs-sans), ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; } -[data-pagefind-body] { - line-height: 1.6; +body::before { + content: ''; + position: fixed; + inset: 0; + z-index: -1; + pointer-events: none; + background: var(--color-fd-background); +} + +/* Content lives in #nd-page .prose โ€” not [data-pagefind-body]. */ +#nd-page .prose { font-size: 0.95rem; + line-height: 1.65; color: var(--color-fd-foreground); } -[data-pagefind-body] h1 { - margin-top: 0.2rem; - letter-spacing: -0.025em; - font-size: clamp(1.88rem, 1.64rem + 0.86vw, 2.3rem); - line-height: 1.08; - font-weight: 700; - text-wrap: balance; - background-image: linear-gradient( - to top, - color-mix(in oklab, var(--color-docs-warm) 24%, transparent) 0.48em, - transparent 0.48em - ); - width: fit-content; +#nd-page .prose img { + width: 100%; + max-width: min(100%, 56rem); + margin: 1rem auto 1.25rem; + border-radius: 0.7rem; + border: 1px solid color-mix(in oklab, var(--color-fd-border) 90%, transparent); + background: color-mix(in oklab, var(--color-fd-card) 88%, transparent); + outline: none; + box-shadow: none; } -[data-pagefind-body] h2 { - margin-top: 2.1rem; - padding-top: 0.75rem; - border-top: 1px solid color-mix(in oklab, var(--color-fd-border) 76%, transparent); - letter-spacing: -0.018em; - font-size: clamp(1.45rem, 1.3rem + 0.55vw, 1.8rem); - line-height: 1.2; - font-weight: 650; +/* Provider logos on integration detail pages should stay compact. */ +#nd-page .prose img.docs-provider-hero-logo { + display: block; + width: auto; + max-width: 14rem; + height: 4rem; + margin: 0.65rem auto 1rem; + border: 0; + border-radius: 0; + background: transparent; +} + +#nd-page .prose h1 { + margin-top: 0.25rem; + margin-bottom: 0.85rem; + letter-spacing: -0.024em; + font-size: clamp(1.72rem, 1.58rem + 0.56vw, 2.08rem); + line-height: 1.12; + font-weight: 660; text-wrap: balance; - background-image: linear-gradient( - to top, - color-mix(in oklab, var(--color-docs-warm) 18%, transparent) 0.42em, - transparent 0.42em - ); - width: fit-content; -} - -[data-pagefind-body] h3 { - margin-top: 1.45rem; - letter-spacing: -0.012em; - font-size: clamp(1.17rem, 1.11rem + 0.28vw, 1.32rem); - line-height: 1.28; +} + +#nd-page .prose h2 { + margin-top: 2rem; + margin-bottom: 0.6rem; + padding-top: 0; + border-top: none; + letter-spacing: -0.014em; + font-size: clamp(1.22rem, 1.12rem + 0.34vw, 1.46rem); + line-height: 1.24; font-weight: 620; + text-wrap: balance; } -[data-pagefind-body] p, -[data-pagefind-body] li { - line-height: 1.68; +#nd-page .prose h3 { + margin-top: 1.35rem; + margin-bottom: 0.38rem; + letter-spacing: -0.009em; + font-size: clamp(1.02rem, 0.98rem + 0.2vw, 1.12rem); + line-height: 1.32; + font-weight: 590; +} + +#nd-page .prose p, +#nd-page .prose li { + line-height: 1.65; + text-wrap: pretty; } -[data-pagefind-body] p { +#nd-page .prose p { margin-block: 0.82rem; } -[data-pagefind-body] ul, -[data-pagefind-body] ol { +#nd-page .prose ul, +#nd-page .prose ol { margin-block: 0.85rem; } -[data-pagefind-body] li + li { +#nd-page .prose li + li { margin-top: 0.28rem; } -[data-pagefind-body] a { +#nd-page .prose a { color: color-mix(in oklab, var(--color-docs-warm) 82%, var(--color-fd-foreground)); text-decoration-color: color-mix(in oklab, var(--color-fd-primary) 45%, transparent); text-underline-offset: 2px; @@ -118,12 +151,12 @@ body { transition: color 160ms ease, text-decoration-color 160ms ease; } -[data-pagefind-body] a:hover { +#nd-page .prose a:hover { color: var(--color-docs-warm); text-decoration-color: color-mix(in oklab, var(--color-docs-warm) 75%, transparent); } -[data-pagefind-body] :not(pre) > code { +#nd-page .prose :not(pre) > code { border: 1px solid color-mix(in oklab, var(--color-fd-border) 70%, transparent); background: color-mix(in oklab, var(--color-fd-muted) 80%, transparent); border-radius: 0.38rem; @@ -131,32 +164,225 @@ body { font-size: 0.88em; } -[data-pagefind-body] blockquote, -[data-pagefind-body] table, -[data-pagefind-body] pre { +#nd-page .prose blockquote, +#nd-page .prose table, +#nd-page .prose pre { border-color: color-mix(in oklab, var(--color-fd-border) 80%, transparent); } -[data-pagefind-body] pre { - border-radius: 0.65rem; +#nd-page .prose pre { + border-radius: 0.55rem; + border: 0; + background: transparent; + box-shadow: none; + margin: 0; +} + +#nd-page .prose pre code { + border: 0; + outline: 0; +} + +.docs-diagram { + margin: 1rem auto 1.15rem; + max-width: min(100%, 45rem); + border: 1px solid color-mix(in oklab, var(--color-fd-border) 90%, transparent); + border-radius: 0.7rem; + background: color-mix(in oklab, var(--color-fd-card) 88%, transparent); + overflow: clip; +} + +.docs-diagram-canvas { + display: flex; + justify-content: center; + overflow-x: auto; + overflow-y: hidden; + padding: 0.9rem 0.8rem; + min-height: 4rem; +} + +.docs-diagram-canvas svg { + width: min(100%, 42rem); + height: auto; + max-width: 42rem; + flex: 0 0 auto; +} + +.docs-diagram-canvas svg text { + font-weight: 550; + letter-spacing: 0.002em; +} + +#nd-page .prose .docs-diagram + .docs-diagram { + margin-top: 0.7rem; +} + +.docs-code-block { + margin: 1rem 0 1.25rem; + border: 1px solid color-mix(in oklab, var(--color-fd-border) 88%, transparent); + border-radius: 0.55rem; background: color-mix(in oklab, var(--color-fd-card) 85%, var(--color-fd-background)); - box-shadow: inset 0 1px 0 color-mix(in oklab, var(--color-fd-primary) 8%, transparent); + overflow: hidden; +} + +.docs-code-block-toolbar { + display: flex; + justify-content: flex-end; + border-bottom: 1px solid color-mix(in oklab, var(--color-fd-border) 84%, transparent); + padding: 0.3rem 0.45rem; } -[data-pagefind-body] blockquote { +.docs-code-copy-markdown { + border: 1px solid color-mix(in oklab, var(--color-fd-border) 84%, transparent); + background: color-mix(in oklab, var(--color-fd-card) 92%, transparent); + border-radius: 0.4rem; + padding: 0.18rem 0.45rem; + font-size: 0.74rem; + font-weight: 550; + color: var(--color-fd-muted-foreground); + cursor: pointer; +} + +.docs-code-copy-markdown:hover { + color: var(--color-fd-foreground); + border-color: color-mix(in oklab, var(--color-docs-warm) 35%, var(--color-fd-border)); +} + +#nd-page .prose blockquote { border-left-width: 2px; border-left-color: color-mix(in oklab, var(--color-fd-primary) 42%, var(--color-fd-border)); color: color-mix(in oklab, var(--color-fd-foreground) 88%, var(--color-fd-muted-foreground)); } :where(#nd-sidebar, #nd-toc) { - background: color-mix(in oklab, var(--color-fd-card) 82%, transparent); + background: color-mix(in oklab, var(--color-fd-background) 92%, var(--color-fd-card)); border-color: color-mix(in oklab, var(--color-fd-border) 86%, transparent); - box-shadow: inset 0 1px 0 color-mix(in oklab, var(--color-fd-primary) 8%, transparent); + border-radius: 0; + box-shadow: none; + scroll-behavior: smooth; + -webkit-overflow-scrolling: touch; +} + +#nd-notebook-layout { + --fd-header-height: 4.5rem; +} + +#nd-sidebar { + border-right: 1px solid color-mix(in oklab, var(--color-fd-border) 92%, transparent); + display: flex; + flex-direction: column; + height: 100%; + min-height: 0; + overflow: hidden; +} + +#nd-sidebar > .overflow-hidden.min-h-0 { + flex: 1 1 0%; + min-height: 0 !important; +} + +/* Fumadocs sidebar uses a Radix viewport with inline overflow-y:hidden. + Force independent vertical scrolling for long expanded nav trees. */ +#nd-sidebar [data-radix-scroll-area-viewport] { + height: 100% !important; + max-height: 100% !important; + overflow-x: hidden !important; + overflow-y: auto !important; + overscroll-behavior: contain; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + mask: none !important; + -webkit-mask: none !important; + scrollbar-width: thin; + scrollbar-color: color-mix(in oklab, var(--color-fd-border) 70%, transparent) transparent; +} + +#nd-sidebar [data-radix-scroll-area-viewport]::-webkit-scrollbar { + display: block; + width: 6px; +} + +#nd-sidebar [data-radix-scroll-area-viewport]::-webkit-scrollbar-thumb { + border-radius: 999px; + background: color-mix(in oklab, var(--color-fd-border) 75%, transparent); +} + +/* Keep long/expanded section trees usable in the left docs nav. */ +@media (min-width: 64rem) { + [data-sidebar-placeholder] { + overflow: hidden; + } + + #nd-sidebar { + max-height: calc(100dvh - var(--fd-docs-row-2, 4.5rem)); + } +} + +.docs-integration-grid-logo { + display: block; + width: auto; + max-width: 100%; + height: 2.1rem; + margin-inline: auto; + border: 0 !important; + outline: none; + border-radius: 0; + background: transparent; + box-shadow: none; + object-fit: contain; } #nd-toc { padding-top: 1.25rem; + border-left: 1px solid color-mix(in oklab, var(--color-fd-border) 92%, transparent); + scroll-behavior: smooth; +} + +/* Make TOC motion and hierarchy styling uniform (remove jagged path connectors). */ +#nd-toc :is(ul, ol) { + list-style: none; + margin: 0; + padding-left: 0.65rem; +} + +#nd-toc li { + margin: 0; +} + +#nd-toc li::before, +#nd-toc li::after { + content: none !important; + display: none !important; +} + +#nd-toc * { + animation: none !important; +} + +#nd-toc :not(a) { + transition: none !important; +} + +#nd-toc a { + border: 0 !important; + border-left: 1px solid transparent !important; + border-radius: 0.35rem; + margin: 0.08rem 0; + padding-block: 0.32rem; + padding-left: 0.55rem; + transition: + color 140ms ease, + background-color 140ms ease, + border-color 140ms ease; +} + +#nd-toc a:hover { + border-left-color: color-mix(in oklab, var(--color-docs-warm) 36%, transparent) !important; +} + +#nd-toc :is(a[aria-current='true'], a[aria-current='page']) { + border-left-color: color-mix(in oklab, var(--color-docs-warm) 62%, transparent) !important; + background: color-mix(in oklab, var(--color-docs-warm) 10%, transparent) !important; } #nd-sidebar p.inline-flex { @@ -170,9 +396,10 @@ body { } :where(#nd-sidebar, #nd-toc) a { - border-radius: 0.45rem; + border-radius: 0.4rem; border: 1px solid transparent; - padding-block: 0.5rem; + padding-block: 0.42rem; + font-size: 0.9rem; transition: border-color 150ms ease, background-color 150ms ease, color 150ms ease; } @@ -217,7 +444,151 @@ body { box-shadow: 0 0 0 2px color-mix(in oklab, var(--color-docs-warm) 45%, transparent); } -:where(a, button, [role='button']):active { - transform: scale(0.985); - transition-duration: 90ms; +.docs-top-nav-tabs { + justify-content: center; + flex: 1; +} + +/* Stronger API method color-coding for sidebar + endpoint panels */ +:where(#nd-page, #nd-sidebar, #nd-toc) :is( + .text-green-600, + .text-blue-600, + .text-red-600, + .text-yellow-600, + .text-orange-600 +).font-mono.font-medium { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 3.2rem; + border-radius: 0.45rem; + padding: 0.12rem 0.48rem; + border: 1px solid transparent; + font-size: 0.7rem; + letter-spacing: 0.01em; +} + +:where(#nd-page, #nd-sidebar, #nd-toc) .text-green-600.font-mono.font-medium { + background: color-mix(in oklab, #16a34a 15%, transparent); + border-color: color-mix(in oklab, #16a34a 46%, transparent); +} + +:where(#nd-page, #nd-sidebar, #nd-toc) .text-blue-600.font-mono.font-medium { + background: color-mix(in oklab, #2563eb 15%, transparent); + border-color: color-mix(in oklab, #2563eb 46%, transparent); +} + +:where(#nd-page, #nd-sidebar, #nd-toc) .text-red-600.font-mono.font-medium { + background: color-mix(in oklab, #dc2626 15%, transparent); + border-color: color-mix(in oklab, #dc2626 46%, transparent); +} + +:where(#nd-page, #nd-sidebar, #nd-toc) .text-yellow-600.font-mono.font-medium { + background: color-mix(in oklab, #ca8a04 16%, transparent); + border-color: color-mix(in oklab, #ca8a04 50%, transparent); +} + +:where(#nd-page, #nd-sidebar, #nd-toc) .text-orange-600.font-mono.font-medium { + background: color-mix(in oklab, #ea580c 16%, transparent); + border-color: color-mix(in oklab, #ea580c 50%, transparent); +} + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } +} + +#nd-subnav { + z-index: 40; +} + +[data-sidebar-placeholder] { + z-index: 20; +} + +.docs-glass-nav { + background: color-mix(in oklab, var(--color-fd-card) 64%, transparent); + border-color: transparent; + box-shadow: + inset 0 1px 0 color-mix(in oklab, white 28%, transparent), + 0 8px 22px color-mix(in oklab, black 8%, transparent); + backdrop-filter: blur(14px) saturate(1.15); +} + +.dark .docs-glass-nav { + background: color-mix(in oklab, var(--color-fd-card) 45%, transparent); + box-shadow: + inset 0 1px 0 color-mix(in oklab, white 8%, transparent), + 0 10px 30px color-mix(in oklab, black 35%, transparent); +} + +.docs-no-sidebar #nd-sidebar, +.docs-no-sidebar #nd-toc, +.docs-no-sidebar [data-sidebar-placeholder] { + display: none !important; +} + +.docs-no-toc #nd-toc { + display: none !important; +} + +#nd-page { + width: 100%; + max-width: min(100%, 104rem); + margin-inline: auto; +} + +#nd-page main { + padding-inline: clamp(1rem, 2vw, 1.8rem); +} + +/* Enterprise page polish */ +#nd-page .enterprise-doc { + --enterprise-accent: color-mix(in oklab, var(--color-docs-warm) 72%, #f59e0b); +} + +#nd-page .enterprise-doc .prose h1 { + color: var(--enterprise-accent); + letter-spacing: -0.02em; +} + +#nd-page .enterprise-doc .prose h2 { + margin-top: 2.1rem; + border-bottom: 1px solid color-mix(in oklab, var(--enterprise-accent) 30%, transparent); + padding-bottom: 0.38rem; +} + +#nd-page .enterprise-doc .prose :is(h3, h4) { + color: color-mix(in oklab, var(--enterprise-accent) 65%, var(--color-fd-foreground)); +} + +#nd-page .enterprise-doc .prose :is(p, li) { + line-height: 1.68; +} + +#nd-page .enterprise-doc .prose a { + color: color-mix(in oklab, var(--enterprise-accent) 78%, var(--color-fd-foreground)); + text-decoration-color: color-mix(in oklab, var(--enterprise-accent) 40%, transparent); +} + +#nd-page .enterprise-doc .prose a:hover { + color: var(--enterprise-accent); + text-decoration-color: var(--enterprise-accent); +} + +#nd-page .enterprise-doc .prose .info { + border: 1px solid color-mix(in oklab, var(--enterprise-accent) 35%, transparent); + background: color-mix(in oklab, var(--enterprise-accent) 11%, var(--color-fd-card)); + box-shadow: 0 0 0 1px color-mix(in oklab, var(--enterprise-accent) 12%, transparent) inset; +} + +#nd-page .enterprise-doc .prose table { + border-radius: 0.6rem; + overflow: clip; + border-color: color-mix(in oklab, var(--enterprise-accent) 24%, var(--color-fd-border)); +} + +#nd-page .enterprise-doc .prose thead tr { + background: color-mix(in oklab, var(--enterprise-accent) 16%, transparent); } diff --git a/docs-fumadocs/app/layout.tsx b/docs-fumadocs/app/layout.tsx index 440fb9e1..77c7a603 100644 --- a/docs-fumadocs/app/layout.tsx +++ b/docs-fumadocs/app/layout.tsx @@ -1,9 +1,9 @@ import './global.css'; -import { Inter } from 'next/font/google'; +import { Plus_Jakarta_Sans } from 'next/font/google'; import type { Metadata } from 'next'; import { DocsProvider } from '@/components/docs-provider'; -const inter = Inter({ +const plusJakartaSans = Plus_Jakarta_Sans({ subsets: ['latin'], display: 'swap', variable: '--font-docs-sans', @@ -21,7 +21,7 @@ export const metadata: Metadata = { export default function Layout({ children }: LayoutProps<'/'>) { return ( - + {children} diff --git a/docs-fumadocs/components/api-page.tsx b/docs-fumadocs/components/api-page.tsx new file mode 100644 index 00000000..6a8bd1a0 --- /dev/null +++ b/docs-fumadocs/components/api-page.tsx @@ -0,0 +1,13 @@ +'use client'; + +import { createOpenAPIPage } from 'fumadocs-openapi/ui'; +import { createCodeUsageGeneratorRegistry } from 'fumadocs-openapi/requests/generators'; +import { registerDefault } from 'fumadocs-openapi/requests/generators/all'; + +const codeUsages = registerDefault(createCodeUsageGeneratorRegistry()); +for (const languageId of ['java', 'csharp', 'rust']) codeUsages.remove(languageId); + +export const OpenAPIPage = createOpenAPIPage({ + codeUsages, + playground: { enabled: true }, +}); diff --git a/docs-fumadocs/components/changelog-releases.tsx b/docs-fumadocs/components/changelog-releases.tsx new file mode 100644 index 00000000..77326fc2 --- /dev/null +++ b/docs-fumadocs/components/changelog-releases.tsx @@ -0,0 +1,78 @@ +import { fetchGitHubReleases } from '@/lib/github-releases'; + +function formatReleaseDate(iso: string) { + return new Date(iso).toLocaleDateString('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric', + }); +} + +export async function ChangelogReleases() { + let releases: Awaited> = []; + + try { + releases = await fetchGitHubReleases(); + } catch { + return ( +

+ Release notes are temporarily unavailable. View them on{' '} + + GitHub Releases + + . +

+ ); + } + + if (releases.length === 0) { + return

No releases found yet.

; + } + + return ( +
+ {releases.map((release) => ( +
+
+

{release.tagName}

+ + + View on GitHub + +
+ + {release.changes.length > 0 ? ( +
    + {release.changes.map((change) => ( +
  • {change}
  • + ))} +
+ ) : null} + + {release.contributors.length > 0 ? ( +
+ + Contributors + + {release.contributors.map((handle) => ( + + @{handle} + + ))} +
+ ) : null} +
+ ))} +
+ ); +} diff --git a/docs-fumadocs/components/community-contact-footer.tsx b/docs-fumadocs/components/community-contact-footer.tsx new file mode 100644 index 00000000..093bb61b --- /dev/null +++ b/docs-fumadocs/components/community-contact-footer.tsx @@ -0,0 +1,35 @@ +import { communityLinks } from '@/lib/shared'; + +export function CommunityContactFooter() { + return ( +
+

Community & contact

+
    +
  1. + Found a bug or have a feature request?{' '} + + Open a GitHub issue + + . +
  2. +
  3. + Join our{' '} + + Discord + {' '} + for faster replies! +
  4. +
+
+ ); +} diff --git a/docs-fumadocs/components/contributors.tsx b/docs-fumadocs/components/contributors.tsx index 2fd576a8..efaa05ea 100644 --- a/docs-fumadocs/components/contributors.tsx +++ b/docs-fumadocs/components/contributors.tsx @@ -1,5 +1,7 @@ import data from '@/content/feature-contributors.json'; import profiles from '@/content/contributor-profiles.json'; +import { resolveFeatureId } from '@/lib/resolve-feature-id'; +import { fetchGitHubReleases } from '@/lib/github-releases'; import { DocsActionLink } from './docs-action-link'; type ContributorEntry = { @@ -30,6 +32,8 @@ const featureMap = new Map( const profileMap = profiles as Record; +const DEFAULT_OWNERS = ['aadhar-EAI', 'Tejas Narayan']; + function toGithubUrl(name: string, email?: string) { const mapped = profileMap[name]?.github; if (mapped) return `https://github.com/${mapped}`; @@ -55,9 +59,20 @@ function uniqueContributors(values: ContributorItem[]) { return items; } -export function getFeatureContributors(featureId: string): ContributorItem[] { +function defaultContributors(): ContributorItem[] { + return DEFAULT_OWNERS.map((name) => ({ + name, + url: toGithubUrl(name), + })); +} + +export function getFeatureContributors(slugPath: string): ContributorItem[] { + const featureId = resolveFeatureId(slugPath); const feature = featureMap.get(featureId); - if (!feature) return []; + + if (!feature) { + return defaultContributors(); + } const ownerEntries = feature.owners.map((name) => ({ name, @@ -68,8 +83,37 @@ export function getFeatureContributors(featureId: string): ContributorItem[] { url: toGithubUrl(contributor.name, contributor.email), })); - // Prefer manually curated owners first, then include git-derived contributors. - return uniqueContributors([...ownerEntries, ...gitEntries]).slice(0, 6); + const resolved = uniqueContributors([...ownerEntries, ...gitEntries]); + return (resolved.length > 0 ? resolved : defaultContributors()).slice(0, 6); +} + +async function getChangelogContributors(): Promise { + try { + const releases = await fetchGitHubReleases(); + const handles = new Set(); + for (const release of releases) { + for (const handle of release.contributors) { + handles.add(handle); + } + } + + if (handles.size === 0) return defaultContributors(); + + return [...handles].slice(0, 8).map((handle) => ({ + name: `@${handle}`, + url: `https://github.com/${handle}`, + })); + } catch { + return defaultContributors(); + } +} + +async function resolveContributors(slugPath: string): Promise { + if (slugPath === 'changelog' || slugPath.startsWith('changelog/')) { + return getChangelogContributors(); + } + + return getFeatureContributors(slugPath); } export function Contributors({ featureId }: { featureId: string }) { @@ -162,9 +206,8 @@ export function DocsBottomMeta({ ); } -export function ContributorsTocFooter({ featureId }: { featureId: string }) { - const contributors = getFeatureContributors(featureId); - if (contributors.length === 0) return null; +export async function ContributorsTocFooter({ featureId }: { featureId: string }) { + const contributors = await resolveContributors(featureId); return (
@@ -174,10 +217,14 @@ export function ContributorsTocFooter({ featureId }: { featureId: string }) {
    {contributors.map((contributor) => (
  • - - - {contributor.name} - + + {contributor.name} +
  • ))}
diff --git a/docs-fumadocs/components/copy-page-markdown.tsx b/docs-fumadocs/components/copy-page-markdown.tsx new file mode 100644 index 00000000..b413cdbb --- /dev/null +++ b/docs-fumadocs/components/copy-page-markdown.tsx @@ -0,0 +1,34 @@ +'use client'; + +import { useState } from 'react'; + +export function CopyPageMarkdown({ mdPath }: { mdPath: string }) { + const [status, setStatus] = useState<'idle' | 'loading' | 'copied' | 'error'>('idle'); + + async function handleCopy() { + try { + setStatus('loading'); + const response = await fetch(mdPath, { cache: 'no-store' }); + if (!response.ok) throw new Error(`Failed to load markdown at ${mdPath}`); + const markdown = await response.text(); + await navigator.clipboard.writeText(markdown); + setStatus('copied'); + window.setTimeout(() => setStatus('idle'), 1400); + } catch { + setStatus('error'); + window.setTimeout(() => setStatus('idle'), 1800); + } + } + + return ( + + ); +} diff --git a/docs-fumadocs/components/docs-shell.tsx b/docs-fumadocs/components/docs-shell.tsx new file mode 100644 index 00000000..fd8aefff --- /dev/null +++ b/docs-fumadocs/components/docs-shell.tsx @@ -0,0 +1,127 @@ +'use client'; + +import type * as PageTree from 'fumadocs-core/page-tree'; +import { usePathname } from 'fumadocs-core/framework'; +import type { BaseLayoutProps, LayoutTab } from 'fumadocs-ui/layouts/shared'; +import { DocsLayout } from 'fumadocs-ui/layouts/notebook'; +import type { ReactNode } from 'react'; +import { DocsSidebarScrollFix } from '@/components/docs-sidebar-scroll-fix'; +import { DocsTopNav } from '@/components/docs-top-nav'; + +function findRootFolder(tree: PageTree.Root, title: string): PageTree.Folder | undefined { + return tree.children.find( + (node): node is PageTree.Folder => node.type === 'folder' && node.name === title, + ); +} + +function routeMode(pathname: string): 'docs' | 'api' | 'enterprise' | 'changelog' | 'blog' { + if (pathname.startsWith('/docs/api-reference')) return 'api'; + if (pathname.startsWith('/docs/enterprise')) return 'enterprise'; + if (pathname.startsWith('/docs/changelog')) return 'changelog'; + if (pathname.startsWith('/docs/blog')) return 'blog'; + return 'docs'; +} + +function matchesModeUrl(url: string, mode: ReturnType): boolean { + if (mode === 'api') return url.startsWith('/docs/api-reference/'); + if (mode === 'enterprise') return url.startsWith('/docs/enterprise/'); + if (mode === 'changelog') return url.startsWith('/docs/changelog/'); + if (mode === 'blog') return url.startsWith('/docs/blog/'); + return ( + url.startsWith('/docs/') && + !url.startsWith('/docs/api-reference/') && + !url.startsWith('/docs/enterprise/') && + !url.startsWith('/docs/changelog/') && + !url.startsWith('/docs/blog/') + ); +} + +function filterNodeByMode(node: PageTree.Node, mode: ReturnType): PageTree.Node | null { + if (node.type === 'page') return matchesModeUrl(node.url, mode) ? node : null; + + if (node.type === 'folder') { + const filteredChildren = node.children + .map((child) => filterNodeByMode(child, mode)) + .filter((child): child is PageTree.Node => child !== null); + const keepIndex = node.index && matchesModeUrl(node.index.url, mode); + if (!keepIndex && filteredChildren.length === 0) return null; + return { + ...node, + index: keepIndex ? node.index : undefined, + children: filteredChildren, + }; + } + + return null; +} + +function makeSidebarTree(tree: PageTree.Root, mode: ReturnType): PageTree.Root { + if (mode === 'enterprise') return { ...tree, children: [] }; + + const byName = + mode === 'api' + ? findRootFolder(tree, 'API Reference') + : mode === 'docs' + ? findRootFolder(tree, 'Docs') + : mode === 'changelog' + ? findRootFolder(tree, 'Changelog') + : findRootFolder(tree, 'Blogs'); + if (byName) return { ...tree, children: byName.children }; + + const filteredChildren = tree.children + .map((node) => filterNodeByMode(node, mode)) + .filter((node): node is PageTree.Node => node !== null); + + const filteredTree: PageTree.Root = { ...tree, children: filteredChildren }; + if (filteredTree.children.length === 1 && filteredTree.children[0]?.type === 'folder') { + return { ...filteredTree, children: filteredTree.children[0].children }; + } + return filteredTree; +} + +export function DocsShell({ + tree, + options, + tabs, + children, +}: { + tree: PageTree.Root; + options: BaseLayoutProps; + tabs: LayoutTab[]; + children: ReactNode; +}) { + const pathname = usePathname(); + const mode = routeMode(pathname); + const sidebarTree = makeSidebarTree(tree, mode); + const isNoSidebar = mode === 'enterprise'; + + return ( +
+ + , + }} + tabs={tabs} + > + {children} + +
+ ); +} diff --git a/docs-fumadocs/components/docs-sidebar-scroll-fix.tsx b/docs-fumadocs/components/docs-sidebar-scroll-fix.tsx new file mode 100644 index 00000000..7f6b4609 --- /dev/null +++ b/docs-fumadocs/components/docs-sidebar-scroll-fix.tsx @@ -0,0 +1,40 @@ +'use client'; + +import { usePathname } from 'fumadocs-core/framework'; +import { useEffect } from 'react'; + +function enableSidebarScroll() { + const sidebar = document.getElementById('nd-sidebar'); + if (!sidebar) return; + + const viewport = sidebar.querySelector('[data-radix-scroll-area-viewport]') as HTMLElement | null; + if (!viewport) return; + + viewport.style.overflowY = 'auto'; + viewport.style.overflowX = 'hidden'; + viewport.style.maxHeight = '100%'; + viewport.style.height = '100%'; + viewport.style.mask = 'none'; + viewport.style.webkitMask = 'none'; +} + +export function DocsSidebarScrollFix() { + const pathname = usePathname(); + + useEffect(() => { + enableSidebarScroll(); + + const observer = new MutationObserver(() => { + enableSidebarScroll(); + }); + + const sidebar = document.getElementById('nd-sidebar'); + if (sidebar) { + observer.observe(sidebar, { childList: true, subtree: true }); + } + + return () => observer.disconnect(); + }, [pathname]); + + return null; +} diff --git a/docs-fumadocs/components/docs-top-nav.tsx b/docs-fumadocs/components/docs-top-nav.tsx new file mode 100644 index 00000000..1a79379b --- /dev/null +++ b/docs-fumadocs/components/docs-top-nav.tsx @@ -0,0 +1,71 @@ +'use client'; + +import Link from 'fumadocs-core/link'; +import { usePathname } from 'fumadocs-core/framework'; +import { isLayoutTabActive } from 'fumadocs-ui/layouts/shared'; +import type { ReactNode } from 'react'; +import { Logo } from '@/components/logo'; +import { NavHeaderActions } from '@/components/nav-header-actions'; + +interface DocsTopNavTab { + title: ReactNode; + url: string; + urls?: Set; +} + +function TabLink({ href, active, children }: { href: string; active: boolean; children: ReactNode }) { + return ( + + {children} + + ); +} + +export function DocsTopNav({ tabs }: { tabs: DocsTopNavTab[] }) { + const pathname = usePathname(); + + return ( +
+
+
+ + + +
+ + + +
+ +
+
+ +
+
+ {tabs.map((tab, idx) => ( + + {tab.title} + + ))} +
+
+
+ ); +} diff --git a/docs-fumadocs/components/integration-provider-nav.tsx b/docs-fumadocs/components/integration-provider-nav.tsx new file mode 100644 index 00000000..0e9f1a65 --- /dev/null +++ b/docs-fumadocs/components/integration-provider-nav.tsx @@ -0,0 +1,52 @@ +import Link from 'fumadocs-core/link'; + +type Provider = { + id: string; + label: string; + href: string; + logo?: string; +}; + +const providers: Provider[] = [ + { id: 'overview', label: 'Overview', href: '/docs/integrations/' }, + { id: 'retell', label: 'Retell', href: '/docs/integrations/retell/', logo: '/retellai.png' }, + { id: 'elevenlabs', label: 'ElevenLabs', href: '/docs/integrations/elevenlabs/', logo: '/elevenlabs.jpg' }, + { id: 'vapi', label: 'Vapi', href: '/docs/integrations/vapi/', logo: '/vapiai.jpg' }, + { id: 'smallest', label: 'Smallest', href: '/docs/integrations/smallest/', logo: '/smallest.jpeg' }, + { id: 'plivo', label: 'Plivo', href: '/docs/integrations/plivo/', logo: '/plivo.png' }, + { id: 'vobiz', label: 'Vobiz', href: '/docs/integrations/vobiz/', logo: '/vobiz.png' }, +]; + +export function IntegrationProviderNav({ active }: { active: Provider['id'] }) { + return ( +
+
+ {providers.map((provider) => { + const isActive = provider.id === active; + return ( + + {provider.logo ? ( + {`${provider.label} + ) : null} + {provider.label} + + ); + })} +
+
+ ); +} diff --git a/docs-fumadocs/components/logo.tsx b/docs-fumadocs/components/logo.tsx index bfac9686..91465deb 100644 --- a/docs-fumadocs/components/logo.tsx +++ b/docs-fumadocs/components/logo.tsx @@ -1,22 +1,22 @@ -interface LogoProps { - className?: string; - showText?: boolean; -} - -export function Logo({ className = '', showText = true }: LogoProps) { - return ( -
- EfficientAI - {showText && ( - - Efficient - AI - - )} -
- ); -} +interface LogoProps { + className?: string; + showText?: boolean; +} + +export function Logo({ className = '', showText = true }: LogoProps) { + return ( +
+ EfficientAI + {showText && ( + + Efficient + AI + + )} +
+ ); +} diff --git a/docs-fumadocs/components/mdx-pre.tsx b/docs-fumadocs/components/mdx-pre.tsx new file mode 100644 index 00000000..4c7016e1 --- /dev/null +++ b/docs-fumadocs/components/mdx-pre.tsx @@ -0,0 +1,62 @@ +'use client'; + +import type { ComponentPropsWithoutRef, ReactNode } from 'react'; +import { useMemo, useState } from 'react'; + +function collectText(node: ReactNode): string { + if (typeof node === 'string') return node; + if (typeof node === 'number') return String(node); + if (!node) return ''; + if (Array.isArray(node)) return node.map(collectText).join(''); + if (typeof node === 'object' && 'props' in node) { + const children = (node as { props?: { children?: ReactNode } }).props?.children; + return collectText(children); + } + return ''; +} + +function inferLanguage(className?: string): string { + if (!className) return ''; + const langToken = className + .split(/\s+/) + .find((token) => token.startsWith('language-') || token.startsWith('lang-')); + if (!langToken) return ''; + return langToken.replace(/^language-/, '').replace(/^lang-/, '').trim(); +} + +export function MdxPre(props: ComponentPropsWithoutRef<'pre'>) { + const [copied, setCopied] = useState(false); + + const extracted = useMemo(() => { + const codeNode = Array.isArray(props.children) + ? props.children.find((child) => typeof child === 'object' && child && 'props' in child) + : props.children; + + const codeClassName = + typeof codeNode === 'object' && codeNode && 'props' in codeNode + ? ((codeNode as { props?: { className?: string } }).props?.className ?? '') + : ''; + const language = inferLanguage(codeClassName); + const code = collectText(props.children).replace(/\n+$/, ''); + const markdown = ['```' + language, code, '```'].join('\n'); + + return { markdown }; + }, [props.children]); + + async function copyMarkdown() { + await navigator.clipboard.writeText(extracted.markdown); + setCopied(true); + window.setTimeout(() => setCopied(false), 1400); + } + + return ( +
+
+ +
+
+    
+ ); +} diff --git a/docs-fumadocs/components/mdx.tsx b/docs-fumadocs/components/mdx.tsx index 2dc097df..0817d57c 100644 --- a/docs-fumadocs/components/mdx.tsx +++ b/docs-fumadocs/components/mdx.tsx @@ -3,6 +3,10 @@ import type { MDXComponents } from 'mdx/types'; import type { ComponentPropsWithoutRef } from 'react'; import { ExternalLink } from 'lucide-react'; import { Contributors } from './contributors'; +import { ChangelogReleases } from './changelog-releases'; +import { IntegrationProviderNav } from './integration-provider-nav'; +import { MdxPre } from './mdx-pre'; +import { ScreenshotPlaceholder } from './screenshot-placeholder'; function DocsBodyLink({ className, ...props }: ComponentPropsWithoutRef<'a'>) { const mergedClassName = ['font-medium', className].filter(Boolean).join(' '); @@ -23,7 +27,11 @@ export function getMDXComponents(components?: MDXComponents) { return { ...defaultMdxComponents, a: DocsBodyLink, + pre: MdxPre, Contributors, + ChangelogReleases, + IntegrationProviderNav, + ScreenshotPlaceholder, ...components, } satisfies MDXComponents; } diff --git a/docs-fumadocs/components/nav-header-actions.tsx b/docs-fumadocs/components/nav-header-actions.tsx new file mode 100644 index 00000000..75733f0e --- /dev/null +++ b/docs-fumadocs/components/nav-header-actions.tsx @@ -0,0 +1,25 @@ +'use client'; + +import { ThemeSwitch } from 'fumadocs-ui/layouts/shared/slots/theme-switch'; +import { ExternalLink } from 'lucide-react'; +import { communityLinks } from '@/lib/shared'; + +export function NavHeaderActions() { + return ( + + ); +} diff --git a/docs-fumadocs/components/screenshot-placeholder.tsx b/docs-fumadocs/components/screenshot-placeholder.tsx new file mode 100644 index 00000000..c1606a1d --- /dev/null +++ b/docs-fumadocs/components/screenshot-placeholder.tsx @@ -0,0 +1,7 @@ +export function ScreenshotPlaceholder({ label }: { label: string }) { + return ( +
+ Screenshot coming soon - {label} +
+ ); +} diff --git a/docs-fumadocs/components/toc-header-controls.tsx b/docs-fumadocs/components/toc-header-controls.tsx index f8b57761..4f5af35d 100644 --- a/docs-fumadocs/components/toc-header-controls.tsx +++ b/docs-fumadocs/components/toc-header-controls.tsx @@ -1,24 +1,11 @@ 'use client'; -import { ThemeSwitch } from 'fumadocs-ui/layouts/shared/slots/theme-switch'; -import { ExternalLink } from 'lucide-react'; -import { gitConfig } from '@/lib/shared'; - -const githubUrl = `https://github.com/${gitConfig.user}/${gitConfig.repo}`; +import { NavHeaderActions } from '@/components/nav-header-actions'; export function TocHeaderControls() { return ( -
- - GitHub - - - +
+
); } diff --git a/docs-fumadocs/content/contributor-profiles.json b/docs-fumadocs/content/contributor-profiles.json index 1c6a9286..dcb385b6 100644 --- a/docs-fumadocs/content/contributor-profiles.json +++ b/docs-fumadocs/content/contributor-profiles.json @@ -4,5 +4,11 @@ }, "Tejas Narayan": { "github": "stejasnarayan" + }, + "MSami625": { + "github": "MSami625" + }, + "TEJASNARAYANS": { + "github": "TEJASNARAYANS" } } diff --git a/docs-fumadocs/content/docs/(docs)/advanced/alerting.mdx b/docs-fumadocs/content/docs/(docs)/advanced/alerting.mdx new file mode 100644 index 00000000..839640cb --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/advanced/alerting.mdx @@ -0,0 +1,196 @@ +--- +title: Alerting +icon: Bell +description: Automatic notifications when voice AI metrics cross thresholds. +--- + +# Alerting + +> **Enterprise feature** โ€” requires the `alerting` feature in your `EFFICIENTAI_LICENSE`. See [Enterprise](/docs/enterprise/) for licensing details. + +## What alerting is + +**Alerting** lets you set up automatic notifications when something important happens with your voice AI agents. Instead of manually checking dashboards, you define rules โ€” and EfficientAI notifies you via **Slack**, **email**, or both when those rules are triggered. + +Think of it as a smoke detector for your voice AI operations. You tell it what to watch (for example, "error rate is above 10%"), and it rings the alarm when something goes wrong. + +### Quick example + +> "If the **average latency** of my Customer Support Agent exceeds **3 seconds** over the last **30 minutes**, send a Slack notification to #ops-alerts." + +## Key concepts + +### Alert + +An **alert** is a monitoring rule. It defines: + +- **What** to measure (metric + aggregation) +- **When** to fire (threshold + operator) +- **How far back** to look (time window) +- **Who** to notify (emails + webhooks) +- **How often** to notify (frequency / cooldown) + +### Alert history + +Every time an alert's condition is met and fires, an **Alert History** record is created. This gives you a full audit trail of when alerts were triggered, what the value was, and whether notifications were sent. + +## Configure an alert + +### What you configure + +- Alert name and optional description +- Metric condition (metric, aggregation, operator, threshold, time window) +- Agent scope (all agents or specific agents) +- Notification channels (email recipients, Slack webhooks) +- Notification frequency (cooldown between repeat notifications) + +### Recommended flow + +1. Confirm SMTP is configured if you want email notifications (see [Configuration](/docs/reference/configuration/)). +2. Create a Slack incoming webhook if you want Slack notifications. +3. Create the alert from **Alerting โ†’ Alerts**. +4. Use **Test Notification** to verify delivery, then **Trigger** to validate the condition. + +## How to set up an alert + +1. Go to **Alerting โ†’ Alerts** in the sidebar. +2. Click **Create Alert**. + +![Alert detail page](/screenshots/Alerts/alerts.png) + +### Basic information + +| Field | Required | Description | +| --- | --- | --- | +| **Alert Name** | Yes | A descriptive name, e.g., "High Error Rate - Production" | +| **Description** | No | Optional notes about what this alert monitors | + +### Metric condition + +| Field | Required | Description | +| --- | --- | --- | +| **Metric** | Yes | What to measure (see [Available metrics](#available-metrics)) | +| **Aggregation** | Yes | How to combine values over the time window | +| **Operator** | Yes | Comparison operator (`>`, `<`, `>=`, `<=`, `=`, `!=`) | +| **Threshold** | Yes | The value to compare against | +| **Time Window** | Yes | Minutes of data to look back (e.g., `60` = last 1 hour) | + +**Example:** `Average of Latency > 3` over a `30 minute` window means: if the average latency across all calls in the last 30 minutes exceeds 3 seconds, fire the alert. + +### Agent selection + +- **All Agents** โ€” monitors every agent in your organization (default) +- **Specific Agents** โ€” select one or more agents to scope the alert + +### Notification settings + +| Field | Required | Description | +| --- | --- | --- | +| **Notification Frequency** | Yes | How often to re-notify if the condition persists | +| **Email Recipients** | No | One or more email addresses | +| **Webhooks** | No | Slack incoming webhook URLs | + +You must configure at least one email or webhook for notifications to work. + +3. Click **Create Alert**. Your alert is now **Active** and will be evaluated automatically. + +## Available metrics + +| Metric | Value | Description | +| --- | --- | --- | +| **Number of Calls** | `number_of_calls` | Total count of calls in the time window | +| **Call Duration** | `call_duration` | Duration of calls (in seconds) | +| **Error Rate** | `error_rate` | Percentage of calls that resulted in errors | +| **Success Rate** | `success_rate` | Percentage of calls that completed successfully | +| **Latency** | `latency` | Response latency of the voice AI agent | +| **Custom** | `custom` | Custom metric (for advanced use cases) | + +## Aggregations + +| Aggregation | Value | Description | +| --- | --- | --- | +| **Sum** | `sum` | Total sum of all values | +| **Average** | `avg` | Arithmetic mean of all values | +| **Count** | `count` | Number of data points | +| **Minimum** | `min` | Lowest value in the window | +| **Maximum** | `max` | Highest value in the window | + +## Notification channels + +### Slack webhooks + +EfficientAI sends rich Slack messages using [Block Kit](https://api.slack.com/block-kit) formatting. Each notification includes the alert name, triggered value vs. threshold, timestamp, and agent scope. + +1. Go to your Slack workspace's **Apps** settings. +2. Create or select an **Incoming Webhook** app. +3. Choose the channel to post to. +4. Copy the webhook URL and paste it in the alert's **Webhook** field. + +### Email notifications + +Email alerts require SMTP to be configured in your EfficientAI deployment. See [Configuration](/docs/reference/configuration/) for SMTP settings. + +## Notification frequency + +| Frequency | Cooldown | Description | +| --- | --- | --- | +| **Immediate** | None | Notify every time the alert evaluates as triggered | +| **Hourly** | 1 hour | At most one notification per hour | +| **Daily** | 24 hours | At most one notification per day | +| **Weekly** | 7 days | At most one notification per week | + +## Alert lifecycle + +| Status | Description | +| --- | --- | +| **Active** | The alert is being evaluated on every cycle (default) | +| **Paused** | Temporarily not being evaluated | +| **Disabled** | Fully disabled | + +From the alert detail page you can **Pause**, **Resume**, **Edit**, **Delete**, **Trigger** (manual evaluation), or send a **Test Notification**. + +Alert history entries progress through **Triggered โ†’ Notified โ†’ Acknowledged โ†’ Resolved**. + +## Automatic evaluation + +Alerts are automatically evaluated every **5 minutes** by a Celery Beat schedule (`evaluate_alerts`, routed to the **`platform`** queue). Beat only enqueues tasks โ€” you must also run a worker that consumes the `platform` queue, or evaluations and notifications will not run. + +Recommended (starts Beat plus a co-located `platform` worker): + +```bash +eai beat --config config.yml +``` + +Or run Beat and the platform worker separately: + +```bash +# Worker for alert evaluation (and other platform tasks) +celery -A app.workers.celery_app worker --queues=platform --pool=threads --loglevel=info + +# Scheduler (single replica) +celery -A app.workers.celery_app beat --loglevel=info +``` + +A default-queue worker (`celery -A app.workers.celery_app worker` with no `--queues`) does **not** process `evaluate_alerts`. + +## Common patterns + +### Monitor error rate spikes + +``` +Metric: Error Rate | Aggregation: Average | Operator: > | Threshold: 5 | Window: 30 min +``` + +### Detect call volume drops + +``` +Metric: Number of Calls | Aggregation: Count | Operator: < | Threshold: 10 | Window: 60 min +``` + +### Track high latency + +``` +Metric: Latency | Aggregation: Max | Operator: > | Threshold: 5 | Window: 15 min +``` + +See also: [Enterprise](/docs/enterprise/) for licensing and the full product reference at [Alerting (products)](/docs/products/alerting/). diff --git a/docs-fumadocs/content/docs/(docs)/advanced/architecture-guide.mdx b/docs-fumadocs/content/docs/(docs)/advanced/architecture-guide.mdx new file mode 100644 index 00000000..207ab254 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/advanced/architecture-guide.mdx @@ -0,0 +1,9 @@ +--- +title: Architecture +--- + +# Architecture + +Architecture details are now grouped under Advanced in Docs v2. + +See [/docs/advanced/architecture/](/docs/advanced/architecture/). diff --git a/docs-fumadocs/content/docs/(docs)/advanced/calls.mdx b/docs-fumadocs/content/docs/(docs)/advanced/calls.mdx new file mode 100644 index 00000000..21e76955 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/advanced/calls.mdx @@ -0,0 +1,9 @@ +--- +title: Calls +--- + +# Calls + +Calls monitoring documentation is now grouped under Advanced in Docs v2. + +See [/docs/monitoring/calls/](/docs/monitoring/calls/). diff --git a/docs-fumadocs/content/docs/(docs)/advanced/cli-commands.mdx b/docs-fumadocs/content/docs/(docs)/advanced/cli-commands.mdx new file mode 100644 index 00000000..fa344d6c --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/advanced/cli-commands.mdx @@ -0,0 +1,9 @@ +--- +title: CLI Commands +--- + +# CLI Commands + +This content moved under Advanced in Docs v2. + +See the full reference at [/docs/reference/cli-commands/](/docs/reference/cli-commands/). diff --git a/docs-fumadocs/content/docs/(docs)/advanced/configuration.mdx b/docs-fumadocs/content/docs/(docs)/advanced/configuration.mdx new file mode 100644 index 00000000..5728b8bf --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/advanced/configuration.mdx @@ -0,0 +1,9 @@ +--- +title: Configuration +--- + +# Configuration + +This content moved under Advanced in Docs v2. + +See the full reference at [/docs/reference/configuration/](/docs/reference/configuration/). diff --git a/docs-fumadocs/content/docs/(docs)/advanced/cron-jobs.mdx b/docs-fumadocs/content/docs/(docs)/advanced/cron-jobs.mdx new file mode 100644 index 00000000..65843347 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/advanced/cron-jobs.mdx @@ -0,0 +1,9 @@ +--- +title: Cron Jobs +--- + +# Cron Jobs + +Cron-job operational documentation is now grouped under Advanced in Docs v2. + +See [/docs/monitoring/cron-jobs/](/docs/monitoring/cron-jobs/). diff --git a/docs-fumadocs/content/docs/(docs)/advanced/database-guide.mdx b/docs-fumadocs/content/docs/(docs)/advanced/database-guide.mdx new file mode 100644 index 00000000..f799735f --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/advanced/database-guide.mdx @@ -0,0 +1,9 @@ +--- +title: Database +--- + +# Database + +Database internals are now grouped under Advanced in Docs v2. + +See [/docs/advanced/database/](/docs/advanced/database/). diff --git a/docs-fumadocs/content/docs/(docs)/advanced/development-guide.mdx b/docs-fumadocs/content/docs/(docs)/advanced/development-guide.mdx new file mode 100644 index 00000000..f6fe0f92 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/advanced/development-guide.mdx @@ -0,0 +1,9 @@ +--- +title: Development +--- + +# Development + +Developer workflow details are now grouped under Advanced in Docs v2. + +See [/docs/advanced/development/](/docs/advanced/development/). diff --git a/docs-fumadocs/content/docs/(docs)/advanced/iam.mdx b/docs-fumadocs/content/docs/(docs)/advanced/iam.mdx new file mode 100644 index 00000000..4f4fe704 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/advanced/iam.mdx @@ -0,0 +1,135 @@ +--- +title: IAM +icon: Shield +description: Organization and workspace access control, roles, and membership management. +--- + +# IAM + +## What IAM is + +**Identity & Access Management (IAM)** controls who can access your EfficientAI organization and what they can do inside each workspace. EfficientAI uses two independent permission layers on every request: + +1. **Organization role** โ€” set per membership (`reader`, `writer`, or `admin`). +2. **Workspace role** โ€” set per workspace (`Viewer`, `Editor`, or `Workspace Admin`, plus optional custom roles). + +A user must satisfy **both** layers to perform an action. Your organization role controls whether you can write anywhere in the org; your workspace role controls what you can do inside the active workspace. + +Open-source deployments are capped at **1 org member** and **1 default workspace**. Multi-member orgs and additional workspaces require an [Enterprise license](/docs/enterprise/). + +## Organization roles + +Manage organization roles from **IAM โ†’ Organization** (admin only) or **Settings โ†’ Team**. + +| Role | Scope | Typical use | +| --- | --- | --- | +| **Reader** | Read-only for the **entire organization** | Auditors, stakeholders who only view dashboards | +| **Writer** | Create, update, and delete most org resources | Engineers and operators doing day-to-day work | +| **Admin** | Everything a writer can do, plus user/team management, API keys, and org settings | Org owners and IT admins | + +> **Org readers are always read-only** +> If your organization role is **Reader**, every mutating API call (`POST`, `PATCH`, `DELETE`) is blocked โ€” even if you hold **Workspace Admin** in a workspace. Workspace roles cannot override an org-level read-only membership. + +Org admins **bypass workspace membership checks** and receive all workspace capabilities in every workspace. + +**API keys** behave differently depending on whether they are linked to a user: + +- **User-bound keys** (created while signed in) carry the linked user's organization role, workspace memberships, and capabilities. They are subject to the same RBAC rules as that user's session. +- **Unbound keys** (legacy keys with no linked user) bypass workspace membership and capability checks and receive full workspace access within the key's organization. Prefer user-bound keys for least-privilege automation. + +## Workspace roles + +Each workspace has its own membership list. When you are added to a workspace, you receive one of three seeded system roles (or a custom role defined by an org admin): + +| Workspace role | Can do | Cannot do | +| --- | --- | --- | +| **Viewer** | View calls, metrics, evals, simulations, reports, and workspace members | Import, edit, delete, run evaluations, change settings, manage members | +| **Editor** | Everything Viewer can do, plus create/update resources | Delete call imports, rename workspace, add/remove members, change workspace roles | +| **Workspace Admin** | Full access in that workspace, including delete, workspace settings, and member management | โ€” | + +Roles are **cumulative**: Editor includes all Viewer permissions; Workspace Admin includes all Editor permissions. + +### What each role needs for common actions + +| Action | Minimum org role | Minimum workspace role | +| --- | --- | --- | +| View call imports, agents, metrics | Reader | Viewer | +| Upload / import calls, edit rows | Writer | Editor | +| Delete call imports or batches | Writer | **Workspace Admin** | +| Create or edit metrics (workspace-scoped) | Writer | Editor | +| Run evaluations | Writer | Editor | +| Rename a workspace | Writer | **Workspace Admin** | +| Add/remove workspace members | Writer | **Workspace Admin** | +| Create a new workspace | Writer | *(creator becomes Workspace Admin automatically)* | +| Delete a workspace | Admin | *(org admin only)* | +| Manage organization users & invitations | Admin | *(not workspace-scoped)* | + +## Configure IAM + +### What you configure + +- Organization name and membership (invitations, roles, password resets) +- Workspace membership and per-workspace roles +- Custom workspace roles (capability bundles for narrow access slices) + +### IAM tabs + +Open **IAM** in the sidebar. The page has three tabs: + +| Tab | Who can access | Purpose | +| --- | --- | --- | +| **Organization** | Admin | Org name, member list, invitations, password resets | +| **Workspace Members** | All members | Assign org users to workspaces with roles | +| **Workspace Roles** | Admin | Define custom workspace roles from the capability registry | + +![IAM organization management](/screenshots/IAM/iam.png) + +### Recommended flow + +1. Invite org members from **Organization** (admin only). +2. Create workspaces from the workspace switcher in the sidebar. +3. Assign members and roles from **Workspace Members**. +4. Define custom roles under **Workspace Roles** when system roles are too broad. + +Org admins should review **Workspace Members** after creating workspaces and remove or downgrade memberships that are too broad for your team model. + +## How to manage workspace access + +1. Open **IAM** in the sidebar. +2. Go to **Workspace Members**, select a workspace, and assign roles to org members. +3. Org admins can define custom roles under **Workspace Roles**. + +The workspace dropdown shows your current role in the selected workspace (for example, **Viewer**). Use the members table to review who has access and change roles โ€” if you hold **Workspace Admin** in that workspace and are an org Writer or Admin. + +Notes: + +- You can only manage members in a workspace if you are an **org Writer or Admin** **and** hold **Workspace Admin** (or org admin) in that workspace. +- **Workspace Admins cannot demote their own role**; another admin must change it. +- Users with org **Reader** can see member lists where allowed but cannot change memberships. + +## Workspaces and scoping + +Workspaces provide **in-organization project isolation**. Multiple teams or projects can share one EfficientAI organization while keeping their agents, metrics, call imports, and prompt libraries separate. + +The workspace switcher lives at the top of the left sidebar, directly under the EfficientAI logo. When you switch workspaces, all data views refetch automatically so you never see stale rows from the previous workspace. + +The UI stores your active workspace in the browser and sends it on every API request as the `X-Workspace-Id` header. If a request arrives without the header, the backend falls back to the organization's **Default** workspace. + +## Custom workspace roles + +Workspace permissions are implemented as **capabilities** grouped by product area. System roles are bundles of these capabilities; org admins can define **custom workspace roles** in **IAM โ†’ Workspace Roles** by picking capabilities from this registry: + +| Domain | View | Create / edit / run | Delete / admin | +| --- | --- | --- | --- | +| **Calls** (call imports) | View batches and rows | Import and update | Delete imports | +| **Metrics** | View definitions | Manage metrics | โ€” | +| **Evaluations** | View runs and results | Run evaluations | โ€” | +| **Simulation** | View agents, personas, scenarios | Manage simulation resources | โ€” | +| **Reports** | View reports | Generate reports | โ€” | +| **Workspace** | View member list | โ€” | Rename workspace; add/remove members and roles | + +Custom roles are useful when a user needs a narrow slice of access (for example, view + run evals but not import calls). Assign them per workspace from **IAM โ†’ Workspace Members**. + +## Enterprise IAM + +Multi-member organizations and additional workspaces require an [Enterprise license](/docs/enterprise/). Enterprise also unlocks advanced authentication (OIDC, SAML, SCIM, MFA enforcement, audit export). See the [Authentication guide](https://docs.efficientai.cloud/docs/getting-started/authentication/) for deployment recipes. diff --git a/docs-fumadocs/content/docs/(docs)/advanced/index.mdx b/docs-fumadocs/content/docs/(docs)/advanced/index.mdx new file mode 100644 index 00000000..f8bc4513 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/advanced/index.mdx @@ -0,0 +1,12 @@ +--- +title: Advanced +--- + +# Advanced + +Advanced documentation covers identity and access management, plus operational alerting for production deployments. + +## Guides + +- [IAM](/docs/advanced/iam/) โ€” organization roles, workspace access, and custom roles +- [Alerting](/docs/advanced/alerting/) โ€” metric thresholds, notifications, and alert history diff --git a/docs-fumadocs/content/docs/(docs)/advanced/usage.mdx b/docs-fumadocs/content/docs/(docs)/advanced/usage.mdx new file mode 100644 index 00000000..24be2962 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/advanced/usage.mdx @@ -0,0 +1,9 @@ +--- +title: Usage +--- + +# Usage + +Usage monitoring documentation is now grouped under Advanced in Docs v2. + +See [/docs/monitoring/usage/](/docs/monitoring/usage/). diff --git a/docs-fumadocs/content/docs/(docs)/index.mdx b/docs-fumadocs/content/docs/(docs)/index.mdx new file mode 100644 index 00000000..8116201c --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/index.mdx @@ -0,0 +1,27 @@ +--- +title: Docs +icon: BookOpenText +--- + +
+

+ Efficient + AI +

+ EfficientAI logo + EfficientAI logo +

+ EfficientAI is an open-source evaluation platform for testing voice AI agents +

+
+ +# EfficientAI Docs + +Evaluate voice agents with repeatable tests, metrics, and provider integrations. + +## Start here + +- [Quickstart](/docs/quickstart/) โ€” what EfficientAI is, and how to run it locally or in the cloud +- [Platform & Concepts](/docs/platform/) โ€” agents, personas, scenarios, evaluators and metrics, each explained and configured in one place +- [Integrations](/docs/integrations/) โ€” Retell, ElevenLabs, Vapi, Smallest, Plivo, Vobiz +- [Advanced](/docs/advanced/) โ€” IAM and alerting diff --git a/docs-fumadocs/content/docs/(docs)/integrations/elevenlabs.mdx b/docs-fumadocs/content/docs/(docs)/integrations/elevenlabs.mdx new file mode 100644 index 00000000..efa18c7e --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/integrations/elevenlabs.mdx @@ -0,0 +1,31 @@ +--- +title: ElevenLabs +icon: AudioLines +--- + +# ElevenLabs Integration + + + +ElevenLabs integration allows EfficientAI to connect voice-platform agents and speech components configured in ElevenLabs. + +ElevenLabs logo + +## Configure + +1. Open Configurations -> Integrations. +2. Add ElevenLabs API credentials. +3. Save and test connectivity. +4. Link your agent configuration to the ElevenLabs integration and provider-side agent identifier. + +## Use with EfficientAI + +- Evaluate production-like provider behavior. +- Compare prompt and voice quality outcomes against other providers. + +Next: [Configure Agent](/docs/platform/agent/) diff --git a/docs-fumadocs/content/docs/(docs)/integrations/index.mdx b/docs-fumadocs/content/docs/(docs)/integrations/index.mdx new file mode 100644 index 00000000..58b61a93 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/integrations/index.mdx @@ -0,0 +1,100 @@ +--- +title: Integrations +icon: Plug +--- + +# Integrations Overview + + + +EfficientAI integrations are organized across three layers: + +1. Voice platform integrations +2. AI model provider integrations +3. Telephony integrations + +This section focuses on platform-level integration guides for teams connecting external voice systems to EfficientAI. + +![Integrations configuration page](/screenshots/Integrations/integration-section.png) + +## Integration model + +1. Configure credentials and endpoints in **Configurations -> Integrations**. +2. Attach integration records to your agent definitions. +3. Run evaluations and compare outcomes across integrations with shared metrics. + +## Voice platform integrations + +
+ {[ + { name: 'Retell', logo: '/retellai.png' }, + { name: 'Vapi', logo: '/vapiai.jpg' }, + { name: 'ElevenLabs', logo: '/elevenlabs.jpg' }, + { name: 'Deepgram', logo: '/deepgram.png' }, + { name: 'Cartesia', logo: '/cartesia.jpg' }, + { name: 'Murf', logo: '/murf.png' }, + { name: 'Sarvam', logo: '/sarvam.png' }, + { name: 'VoiceMaker', logo: '/voiceMaker.png' }, + { name: 'Smallest.ai', logo: '/smallest.jpeg' }, + ].map((item) => ( +
+ {`${item.name} +

{item.name}

+
+ ))} +
+ +## AI provider integrations + +
+ {[ + { name: 'OpenAI', logo: '/openai-logo.png' }, + { name: 'Anthropic', logo: '/anthropic.png' }, + { name: 'Google', logo: '/geminiai.png' }, + { name: 'xAI', logo: '/xai.svg' }, + { name: 'Cohere', logo: '/cohere.svg' }, + { name: 'Mistral', logo: '/mistral.svg' }, + { name: 'Meta', logo: '/metaai.png' }, + { name: 'Together', logo: '/togetherai.svg' }, + { name: 'Perplexity', logo: '/perplexity-ai.svg' }, + { name: 'Azure', logo: '/azureai.png' }, + { name: 'AWS', logo: '/AWS_logo.png' }, + ].map((item) => ( +
+ {`${item.name} +

{item.name}

+
+ ))} +
+ +## Telephony integrations + +
+ {[ + { name: 'Plivo', logo: '/plivo.png' }, + { name: 'Exotel', logo: '/exotel.jpg' }, + { name: 'Vobiz', logo: '/vobiz.png' }, + ].map((item) => ( +
+ {`${item.name} +

{item.name}

+
+ ))} +
+ +## Platform guides + +- [Retell](/docs/integrations/retell/) +- [ElevenLabs](/docs/integrations/elevenlabs/) +- [Vapi](/docs/integrations/vapi/) +- [Smallest (Alpha)](/docs/integrations/smallest/) +- [Plivo](/docs/integrations/plivo/) +- [Vobiz](/docs/integrations/vobiz/) + +For broader provider coverage and advanced routing details, see [Platform Setup](/docs/platform/setup/). + +## Common outcomes + +- compare provider behavior using the same scenario set, +- isolate transport/provider issues vs prompt issues, +- standardize rollout checks across platforms. diff --git a/docs-fumadocs/content/docs/(docs)/integrations/plivo.mdx b/docs-fumadocs/content/docs/(docs)/integrations/plivo.mdx new file mode 100644 index 00000000..68396f27 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/integrations/plivo.mdx @@ -0,0 +1,31 @@ +--- +title: Plivo +icon: Phone +--- + +# Plivo Integration + + + +Plivo integration is used for phone-number and telephony routing workflows that require PSTN execution paths. + +Plivo logo + +## Configure + +1. Open Configurations -> Integrations. +2. Add Plivo credentials. +3. Sync or map numbers as needed. +4. Use telephony-capable agent settings (`call_medium = phone_call`). + +## Use with EfficientAI + +- Test inbound and outbound phone-call flows. +- Evaluate telephony behavior alongside conversational quality metrics. + +Next: [Configure Agent](/docs/platform/agent/) diff --git a/docs-fumadocs/content/docs/(docs)/integrations/retell.mdx b/docs-fumadocs/content/docs/(docs)/integrations/retell.mdx new file mode 100644 index 00000000..54c070ff --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/integrations/retell.mdx @@ -0,0 +1,31 @@ +--- +title: Retell +icon: Radio +--- + +# Retell Integration + + + +Retell integration connects externally hosted Retell agents to EfficientAI for evaluation workflows. + +Retell logo + +## Configure + +1. Open Configurations -> Integrations. +2. Add Retell credentials and connection details. +3. Save and verify the integration status. +4. In Agent configuration, set the integration and Retell agent ID. + +## Use with EfficientAI + +- Run external-provider comparisons with internal bundle runs. +- Use evaluator suites to score Retell call outcomes with shared metrics. + +Next: [Configure Agent](/docs/platform/agent/) diff --git a/docs-fumadocs/content/docs/(docs)/integrations/smallest.mdx b/docs-fumadocs/content/docs/(docs)/integrations/smallest.mdx new file mode 100644 index 00000000..7b011ba4 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/integrations/smallest.mdx @@ -0,0 +1,31 @@ +--- +title: Smallest (Alpha) +icon: FlaskConical +--- + +# Smallest Integration (Alpha) + + + +Smallest integration is currently in alpha support mode. + +Smallest logo + +## Configure + +1. Open Configurations -> Integrations. +2. Add Smallest credentials and endpoint details. +3. Save and validate that the integration is active. +4. Map the integration to your target agent and provider-side agent ID. + +## Notes + +- Treat this integration as evolving functionality. +- Validate flows in a controlled workspace before broad rollout. + +Next: [Configure Agent](/docs/platform/agent/) diff --git a/docs-fumadocs/content/docs/(docs)/integrations/vapi.mdx b/docs-fumadocs/content/docs/(docs)/integrations/vapi.mdx new file mode 100644 index 00000000..2db65f4c --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/integrations/vapi.mdx @@ -0,0 +1,31 @@ +--- +title: Vapi +icon: PhoneCall +--- + +# Vapi Integration + + + +Vapi integration maps your Vapi agent configuration into EfficientAI test workflows. + +Vapi logo + +## Configure + +1. Open Configurations -> Integrations. +2. Add Vapi credentials. +3. Save and confirm integration health. +4. In Agent setup, set the Vapi integration and provider agent ID. + +## Use with EfficientAI + +- Run scenario-driven tests on Vapi-backed calls. +- Score outcomes with the same evaluator and metric suite used elsewhere. + +Next: [Configure Agent](/docs/platform/agent/) diff --git a/docs-fumadocs/content/docs/(docs)/integrations/vobiz.mdx b/docs-fumadocs/content/docs/(docs)/integrations/vobiz.mdx new file mode 100644 index 00000000..01cc9713 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/integrations/vobiz.mdx @@ -0,0 +1,31 @@ +--- +title: Vobiz +icon: PhoneIncoming +--- + +# Vobiz Integration + + + +Vobiz integration supports telephony webhook and media workflows for live phone-call evaluation paths. + +Vobiz logo + +## Configure + +1. Open Configurations -> Integrations. +2. Add Vobiz credentials and webhook base URL values. +3. Ensure telephony/media endpoints are reachable from your Vobiz account. +4. Configure agents for phone-call flows and run evaluator suites. + +## Notes + +- Vobiz setup depends on correct webhook routing and media endpoint availability. +- Use a staging environment to validate inbound and recording event flows before production. + +Next: [Configure Agent](/docs/platform/agent/) diff --git a/docs-fumadocs/content/docs/(docs)/meta.json b/docs-fumadocs/content/docs/(docs)/meta.json new file mode 100644 index 00000000..f5a58cfb --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/meta.json @@ -0,0 +1,11 @@ +{ + "title": "Docs", + "icon": "BookText", + "root": true, + "pages": [ + "quickstart", + "platform", + "integrations", + "advanced" + ] +} diff --git a/docs-fumadocs/content/docs/(docs)/platform/agent.mdx b/docs-fumadocs/content/docs/(docs)/platform/agent.mdx new file mode 100644 index 00000000..10c275da --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/agent.mdx @@ -0,0 +1,130 @@ +--- +title: Agent +icon: Bot +description: What an agent is in EfficientAI, how call mediums differ, and how to configure one. +--- + +# Agent + +## What an agent is + +In EfficientAI, an **agent** is the system under test. It captures the conversation context, +the prompt behavior, and the execution path used for every evaluation run. + +An agent can point at one of two execution paths: internal (EfficientAI voice bundle) or external (provider platform mapping). + +Use the **internal path** when you want to isolate and A/B individual model layers. Use the +**external path** when you want to evaluate the exact agent that serves production traffic on +a provider platform. + +## Telephony vs WebRTC + +Every agent is also tested over one of two call mediums, set by the `phone_call` / `web_call` +medium field. + +| | Telephony (`phone_call`) | WebRTC (`web_call`) | +|---|---|---| +| Transport | PSTN through a telephony provider and carrier webhooks | Browser-style real-time streaming over WebSockets | +| Requires | Phone numbers, carrier routing, telephony credentials | No phone network dependency | +| Use when | Production depends on real phone behavior, DTMF, carrier latency and codecs | Your experience is browser-native | + +Both mediums are evaluated with the same personas, scenarios, and metrics. They differ only in +call transport and the integration setup they require, so scores stay comparable across the two +as long as you don't mix mediums inside one comparison. + +## Configure an agent + +### What you configure + +- Agent identity (name, language) +- Call type and medium (`inbound` / `outbound`, `phone_call` / `web_call`) +- Internal voice bundle mapping +- External voice-platform mapping (integration + provider agent ID) +- Test prompt and provider prompt surfaces + +### Creating a test agent + +Use **Create Test Agent** to add a new evaluation configuration. You can create either: + +- **Telephony** agents for PSTN call flows. +- **Existing Platform Integration** agents for Retell, Vapi, ElevenLabs, and other external providers. + +For both paths, you configure the production-side prompt and a complementary test prompt that +EfficientAI uses during evaluations. + +### Prompt surfaces + +- `provider_prompt`: production prompt used by the external/system agent. +- `description`: test prompt generated or authored for evaluator-driven simulations. + +Use **Generate test prompt** to bootstrap the test prompt from your production prompt, then +refine it for coverage and repeatability. + +### Recommended flow + +1. Create a voice bundle and required integrations โ€” see [Setup](/docs/platform/setup/). +2. Create a test agent. +3. Attach [personas](/docs/platform/persona/) and [scenarios](/docs/platform/scenario/) through + [evaluation suites](/docs/platform/evaluation-suite/). + +See also: [How It Works](/docs/platform/) for how the agent connects to the rest of the object model. + +## How to set up an agent + +1. Go to **Simulations > Agents** in the left navigation. +2. Click **Create Agent** in the top-right. + +![Creating an agent](/screenshots/Agents/Agent_homepage.png) + +### If you choose telephony + +Enter: + +- Name +- Phone number +- Language (the language EfficientAI uses with your bot) +- Call type (`outbound` or `inbound`) +- End call after silence (how many silence seconds before hang up) + +![Telephony agent setup](/screenshots/Agents/Agent_telephony.png) + +Then configure your phone integration in [Integrations](/docs/integrations/). + +### If you choose web agent + +1. Enter the agent name. +2. Open your provider (Vapi, ElevenLabs, Retell, Smallest, and others). +3. Click **Connect** so EfficientAI can fetch available provider agent IDs. +4. If needed, enter the provider agent ID manually. + +![WebRTC agent setup](/screenshots/Agents/Agent_webRTC.png) + +If your provider is missing, open an issue on [GitHub](https://github.com/EfficientAI-tech/efficientAI/issues/new). + +### Prompt setup + +You can either: + +1. Paste your production prompt and use **Generate test prompt** with provider/model/context settings to produce an adversarial prompt, or +2. Write the test prompt manually. + +For first message behavior, choose: + +- **Production agent speaks first** (default) +- **Test caller speaks first** (the EfficientAI test agent starts) + +For the EfficientAI system prompt, define: + +1. Role and goal +2. Talking style +3. Questions to ask +4. Information to relay +5. Constraints + +![Prompt partial setup](/screenshots/Agents/Agent_prompt_partial.png) + +### Voice bundle + +For voice bundle setup, see [Setup](/docs/platform/setup/) and [Persona](/docs/platform/persona/). + +Create the agent to finish setup. Editing flow and custom agent testing docs are coming soon. diff --git a/docs-fumadocs/content/docs/(docs)/platform/evaluation-suite.mdx b/docs-fumadocs/content/docs/(docs)/platform/evaluation-suite.mdx new file mode 100644 index 00000000..7d6f85ea --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/evaluation-suite.mdx @@ -0,0 +1,58 @@ +--- +title: Evaluation Suite +icon: Layers +description: What an evaluation suite is, how combinations expand, and how to configure one. +--- + +# Evaluation Suite + +## What an evaluation suite is + +An **evaluation suite** (called **Evaluator Suite** in some UI and API surfaces) groups one +agent, one or more personas, and multiple scenarios into run combinations. Every +persona ร— scenario pair becomes a test combination, and each combination can be run once or +many times. + +Two personas and two scenarios produce four combinations; with a run count of three that is +twelve calls. The combination count is the product of your inputs, so grow personas and +scenarios deliberately. + +### How combinations are calculated + +EfficientAI executes a Cartesian product across personas and scenarios for each suite. + +
+
+ {'Total combinations = Personas ร— Scenarios'} +
+
+ {'Example: 2 personas ร— 5 scenarios = 10 combinations'} +
+
+ +If you run each combination multiple times, multiply by run count (for example, 10 combinations ร— +3 runs = 30 total calls). If you first choose subsets from larger pools, that selection stage can +be modeled with nCr before expanding into persona-scenario pairs. + +Suites are what make regression testing practical. They let you standardize a fixed set of +tests, compare the same tests over time as prompts and models change, and rotate scenarios for +inbound flows. + +## Configure an evaluation suite + +### What you configure + +- One agent +- One or more personas +- One or more scenarios +- Run count and metric set + +### Execution behavior + +- **Outbound and web calls:** all combinations run in batches. +- **Inbound calls:** activate one suite per agent and rotate scenarios, since the agent receives + rather than places the call. + +See also: [How It Works](/docs/platform/) for how suites sit between your definitions and your results. + +For UI steps to create suites and queue runs, see [Evaluator](/docs/platform/evaluator/). diff --git a/docs-fumadocs/content/docs/(docs)/platform/evaluator.mdx b/docs-fumadocs/content/docs/(docs)/platform/evaluator.mdx new file mode 100644 index 00000000..58ab2748 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/evaluator.mdx @@ -0,0 +1,81 @@ +--- +title: Evaluator +icon: ListChecks +description: What evaluators and metrics are, the metric families available, and how to configure scoring. +--- + +# Evaluator + +## What an evaluator is + +An **evaluator** is the engine that executes runs and applies metrics to score them. It is the +piece that brings every other object together: + +Because the inputs are fixed configuration, an evaluator gives you controlled comparisons: hold +the agent constant and vary the model, or hold the model constant and vary the prompt, and the +score delta is attributable. + +## What metrics are + +**Metrics** are the scoring rules applied to a finished run. EfficientAI ships four families, +and you enable the ones that match your quality goals per workspace/agent context. + +| Family | Measures | Examples | +|---|---|---| +| LLM-evaluated conversation | Whether the agent behaved correctly in dialogue | Instruction following, professionalism | +| Acoustic | Raw signal quality of the audio | Jitter, shimmer, pitch variance | +| AI voice quality | Perceived voice naturalness and consistency | MOS-style scores, consistency signals | +| Custom | Anything specific to your product | `boolean`, `enum`, `number_range`, `text`, `rating` | + +Custom metrics are the escape hatch: when a business rule matters to you and to nobody else โ€” +"did the agent quote the correct policy number?" โ€” define it as a custom metric with the return +type that fits, and it is scored alongside the built-ins. + +## Configure an evaluator + +### What you configure + +- Metric selection and enablement +- Suite-level run behavior +- Inbound or outbound execution mode + +### Recommended flow + +1. Enable metrics that match your quality goals. +2. Group agent/persona/scenario combinations into + [evaluation suites](/docs/platform/evaluation-suite/). +3. Run and inspect evaluator results. + +Keep the enabled metric set stable between comparison runs. Adding or removing a metric changes +the score card shape, which makes before/after runs harder to read. + +See also: [How It Works](/docs/platform/) for the full evaluation lifecycle. + +## How to create an evaluator suite + +1. Open [Evaluators](/docs/platform/evaluation-suite/) under **Evaluations**. +2. Click **Create Suite** in the top-right. +3. Select agent and persona. +4. Select one or more scenarios. + +![Evaluator suite setup](/screenshots/Evaluator/Evaluator_suite.png) + +5. Choose the number of metrics for success criteria. +6. Click **Review**. +7. Enter suite name and default run count. + +## How to run evaluations + +1. Open [Evaluators](/docs/platform/evaluation-suite/) under **Evaluations**. +2. Under evaluator suites, find the suite you want to run. +3. Select the checkbox next to a suite and click **Run**. +4. Open **Runs**, set the number of runs, then click **Queue Runs**. +5. Track progress in **Evaluation Results**. + +![Evaluation results](/screenshots/Evaluator/Evaluation_results.png) + +Results appear in the **Evaluation Results** section once runs complete. + +## Judge alignment + +Judge alignment is available under **Evaluations > Judge Alignment**. Detailed public documentation is pending. diff --git a/docs-fumadocs/content/docs/(docs)/platform/index.mdx b/docs-fumadocs/content/docs/(docs)/platform/index.mdx new file mode 100644 index 00000000..e4c1cd96 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/index.mdx @@ -0,0 +1,57 @@ +--- +title: How It Works +icon: Lightbulb +description: The EfficientAI object model and evaluation lifecycle, end to end. +--- + +# How It Works + +EfficientAI evaluates voice agents the way your customers experience them: by placing real +calls against the agent and driving those calls with simulated callers. + +Everything on the platform is built from six objects. Each one is explained in full on its own +page in this section โ€” this page shows how they fit together. + +## The object model + +An **evaluation suite** is the join table: it pairs one agent with every combination of the +personas and scenarios you attach. Each combination becomes one or more **runs**, and each run +is scored by the **metrics** you enabled. + +### Combination math (nCr + pairing) + +Evaluation suite runs are based on persona-scenario pairing: + +- If personas and scenarios are already selected in the suite, total combinations are `P x S` + (Cartesian product). +- If subsets are selected from larger pools first, use nCr for each selection stage: + - Personas selected: `nCk` + - Scenarios selected: `mCr` + - Then suite combinations expand to `(nCk) x (mCr)` before applying run count. + +## The evaluation lifecycle + +Because the persona, scenario, and voice mapping are all pinned configuration, re-running a +suite after a prompt or model change produces a comparison you can trust rather than a +one-off anecdote. + +## Where each concept is explained + +| Concept | What it is | Explained in | +|---|---|---| +| Agent | The system under test, plus its call medium and prompts. | [Agent](/docs/platform/agent/) | +| Persona | The simulated caller: behavior profile plus a pinned voice. | [Persona](/docs/platform/persona/) | +| Scenario | The goal, context, and success criteria for a conversation. | [Scenario](/docs/platform/scenario/) | +| Metrics | The scoring rules applied to a finished run. | [Evaluator](/docs/platform/evaluator/) | +| Evaluator | The engine that runs combinations and applies metrics. | [Evaluator](/docs/platform/evaluator/) | +| Evaluation suite | The grouping that turns personas and scenarios into run combinations. | [Evaluation Suite](/docs/platform/evaluation-suite/) | +| STT / LLM / TTS | The three model layers inside a voice bundle. | [Setup](/docs/platform/setup/) | +| Telephony vs WebRTC | The two call mediums an agent can be tested over. | [Agent](/docs/platform/agent/) | + +## Suggested reading order + +1. [Setup](/docs/platform/setup/) โ€” credentials, voice bundles, storage. +2. [Agent](/docs/platform/agent/) โ€” define the system under test. +3. [Persona](/docs/platform/persona/) and [Scenario](/docs/platform/scenario/) โ€” define who calls and why. +4. [Evaluation Suite](/docs/platform/evaluation-suite/) โ€” assemble the combinations. +5. [Evaluator](/docs/platform/evaluator/) โ€” choose metrics and read results. diff --git a/docs-fumadocs/content/docs/(docs)/platform/metrics.mdx b/docs-fumadocs/content/docs/(docs)/platform/metrics.mdx new file mode 100644 index 00000000..2e76bd58 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/metrics.mdx @@ -0,0 +1,47 @@ +--- +title: Metrics +icon: Target +description: Define success criteria and the metrics to track while evaluating voice agents. +--- + +# Metrics + +Metrics in EfficientAI are the way to describe success criteria and the list of metrics you want to track while evaluating your voice agents. + +![Metrics homepage](/screenshots/Metrics/Metrics_homepage.png) + +## What metrics are + +Metrics are the scoring rules applied to completed runs. They define what "good" means for your agent, and let you compare changes in prompts, providers, and configurations with consistent criteria. + +EfficientAI supports four metric families: + +| Family | Measures | Examples | +|---|---|---| +| LLM-evaluated conversation | Whether the agent behaved correctly in dialogue | Instruction following, professionalism | +| Acoustic | Raw signal quality of audio | Jitter, shimmer, pitch variance | +| AI voice quality | Perceived naturalness and consistency | MOS-style scores, consistency signals | +| Custom | Product-specific requirements | `boolean`, `enum`, `number_range`, `text`, `rating` | + +Custom metrics are useful when a business rule matters to your workflow and should be scored on every run. + +## Metric types + +There are two core parts in metrics: + +- Single metric +- Categorisation labels + +### Single-metric + +Use a single metric when you want one direct score or pass/fail signal for a specific behavior. + +![Single metric](/screenshots/Metrics/Single_metric.png) + +### Categorisation labels + +Use categorisation labels when you want to break performance into structured buckets for easier analysis and reporting. + +![Categorisation labels](/screenshots/Metrics/Categorizaion_labels.png) + +Next: [Evaluator](/docs/platform/evaluator/) and [Evaluation Suite](/docs/platform/evaluation-suite/) diff --git a/docs-fumadocs/content/docs/(docs)/platform/observability.mdx b/docs-fumadocs/content/docs/(docs)/platform/observability.mdx new file mode 100644 index 00000000..3180cad2 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/observability.mdx @@ -0,0 +1,14 @@ +--- +title: Observability +icon: Activity +--- + +# Observability + +> **Coming soon** +> Expanded observability documentation for traces, run analytics, and operational dashboards is coming soon. + +Current usage and operational tracking references: + +- [Usage](/docs/advanced/usage/) +- [Calls](/docs/advanced/calls/) diff --git a/docs-fumadocs/content/docs/(docs)/platform/persona.mdx b/docs-fumadocs/content/docs/(docs)/platform/persona.mdx new file mode 100644 index 00000000..2abc9042 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/persona.mdx @@ -0,0 +1,85 @@ +--- +title: Persona +icon: UserRound +description: What a persona is, why voice mapping is pinned, and how to configure one. +--- + +# Persona + +## What a persona is + +A **persona** is the simulated caller on the other end of the line. It combines caller behavior +instructions with a concrete voice identity, so the agent under test hears a realistic and โ€” +crucially โ€” repeatable caller on every run. + +A persona controls speaking style and intent, response timing and turn behavior, and the LLM +settings used to drive the simulation. Pair it with a [scenario](/docs/platform/scenario/) to +say *why* this caller is calling. + +## Why the voice mapping is pinned + +Every persona is bound to a specific provider voice rather than "any female voice": + +- `tts_provider` +- `tts_voice_id` +- `tts_voice_name` +- `gender` + +Audio characteristics change acoustic and voice-quality scores. Pinning the voice means that +when a score moves between runs, the cause is the change you made โ€” a prompt revision, a model +swap, an evaluator update โ€” and not a different voice on the caller side. You can use built-in +provider voices or custom catalog voices from your organization. + +## Configure a persona + +### What you configure + +- Persona profile and description +- Voice provider and voice mapping +- Simulation controls (temperature, delay, max turns, interruption behavior) + +### Recommended flow + +1. Create the persona profile. +2. Select the provider voice. +3. Tune behavior controls for realism. +4. Reuse the persona across [evaluation suites](/docs/platform/evaluation-suite/). + +Reuse matters: a small, stable library of personas gives you a consistent baseline to compare +against over months, instead of a new caller definition for every test. + +See also: [How It Works](/docs/platform/) for how personas combine with scenarios into runs. + +## How to create a persona + +1. Go to **Simulations > Personas**. +2. Click **Create Persona** on the top-right. + +![Creating a persona](/screenshots/Persona/Persona_Page.png) + +Then complete: + +- Persona name +- Target agent mapping (the persona is tied to a specific agent) +- Optional **Generate agent prompt** for a faster first draft + +![Persona prompt generation](/screenshots/Persona/Persona_prompt.png) + +### Voice section + +Select the voice configuration for the persona. Example: + +- Provider: ElevenLabs +- Model/voice: Rachel +- Gender: female + +If voice providers are not configured yet, see [Integrations](/docs/integrations/). + +![Persona voice selection](/screenshots/Persona/Persona_voice.png) + +### TTS and behavior controls + +Tune TTS settings and behavior settings as needed. Recommended default is to keep these unchanged unless you have a clear reason to modify them. + +![Persona TTS settings](/screenshots/Persona/Persona_TTS.png) +![Persona behavior settings](/screenshots/Persona/Persona_behaviour.png) diff --git a/docs-fumadocs/content/docs/(docs)/platform/playground.mdx b/docs-fumadocs/content/docs/(docs)/platform/playground.mdx new file mode 100644 index 00000000..8eb7a563 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/playground.mdx @@ -0,0 +1,84 @@ +--- +title: Playground +icon: Gamepad2 +description: Manually test test-agent and voice-agent connectivity before running simulations. +--- + +# Playground + +Agent Playground is a real-time environment to validate connectivity before running larger simulated evaluations. + +## What it does + +From one place, you can: + +- Start live tests +- Monitor call/test status +- Inspect transcripts and recordings +- Compare test-agent and voice-agent behavior + +## Test modes + +### Voice AI Agent mode + +Uses external provider configuration and runs a live web call against your provider-side agent. + +Supported providers commonly include Retell, Vapi, and ElevenLabs. + +Typical flow: + +1. Create a web call with the selected agent. +2. Connect through provider session/client. +3. Store call recording metadata. +4. Poll provider call details (status, transcript, audio). +5. Create evaluator result and run metrics. + +### Test Agent mode + +Uses the internal EfficientAI voice path with your configured voice bundle. This is useful for controlled comparisons of STT, LLM, and TTS choices. + +## Prerequisites + +For external live web-call testing: + +- `call_medium: web_call` +- `voice_ai_integration_id` configured +- `voice_ai_agent_id` configured + +For richer playback/storage workflows, ensure storage is configured in [Setup](/docs/platform/setup/). + +## How to test in Agent Playground + +Agent Playground lets you test either the EfficientAI test agent or your own voice AI agent. + +### Test the EfficientAI test agent + +Method 1: + +1. Go to **Simulations > Agents**. +2. Click **Test Agent**. +3. Start speaking with the EfficientAI test agent. + +Method 2: + +1. Go to **Playground > Agent Playground**. +2. Click **Test Agent**. +3. Start speaking with the EfficientAI test agent. + +![Playground test agent flow](/screenshots/Playground/Playground_testagent.png) + +### Test your voice AI agent + +Method 1: + +1. Go to **Simulations > Agents**. +2. Click **Voice Agent**. +3. Start speaking with your voice AI agent. + +Method 2: + +1. Go to **Playground > Agent Playground**. +2. Click **Voice Agent**. +3. Start speaking with your voice AI agent. + +![Playground voice agent flow](/screenshots/Playground/Agent_voiceAI.png) diff --git a/docs-fumadocs/content/docs/(docs)/platform/prompts.mdx b/docs-fumadocs/content/docs/(docs)/platform/prompts.mdx new file mode 100644 index 00000000..ff453a53 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/prompts.mdx @@ -0,0 +1,86 @@ +--- +title: Prompts +icon: ScrollText +description: Create and manage reusable prompt partials and agent prompts. +--- + +# Prompts + +Prompts in EfficientAI are reusable instructions you save and apply across agents and evaluations. + +## Core workflows + +### Create and edit + +- Open **Prompts > Partials** in the sidebar. +- Click **New Prompt** to create a prompt partial or agent prompt. +- Save updates to version your content over time. + +### Search and organize + +- Search by name or description. +- Add tags for filtering and discovery (for example: `evaluation`, `compliance`, `sales`). + +### Preview + +Switch between **Preview** (rendered markdown) and **Raw** (source markdown) while reviewing content. + +## Version history + +Each save creates a new version snapshot. + +| Action | Description | +|---|---| +| View versions | Browse version history with timestamps | +| Compare | Compare current vs a historical version | +| Revert | Restore an earlier version (creates a new latest version) | +| Clone | Duplicate a prompt into a new prompt | + +## AI-assisted authoring + +Prompt tooling requires at least one configured AI provider. + +- **AI Generate:** create a first draft from your objective, tone, and format. +- **AI Improve:** refine existing content while preserving intent. + +Both support provider/model selection, or auto-detecting a default provider. + +## Where prompts are used + +Saved prompts can be reused in: + +- [Evaluator](/docs/platform/evaluator/) flows +- [Agent](/docs/platform/agent/) configuration +- Cross-team workflows scoped to the current workspace + +## Workspace scoping + +Prompts are scoped to the active workspace. Switching workspaces shows a different prompt library. For shared standards, clone prompts into each workspace where needed. + +## How to use prompts + +1. Go to **Prompts > Partials**. +2. Click **New Prompt**. +3. Choose either **Prompt Partial** or **Agent Prompt**. + +![Prompt partial form](/screenshots/Prompts/Prompt_partial.png) + +### Prompt Partial + +1. Enter name. +2. Add description. +3. Add tags. +4. Write or paste content. +5. Optionally click **Improve with AI**. + +![Create prompt flow](/screenshots/Prompts/Create_prompt,partial.png) + +### Agent Prompt + +1. Enter name. +2. Add optional description. +3. Write or paste content. +4. Optionally click **Improve with AI**. +5. Click **Create Prompt**. + +![Agent prompt form](/screenshots/Prompts/Agent_prompt,partial.png) diff --git a/docs-fumadocs/content/docs/(docs)/platform/scenario.mdx b/docs-fumadocs/content/docs/(docs)/platform/scenario.mdx new file mode 100644 index 00000000..99f5d293 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/scenario.mdx @@ -0,0 +1,71 @@ +--- +title: Scenario +icon: Route +description: What a scenario is, how it shapes a simulated call, and how to configure one. +--- + +# Scenario + +## What a scenario is + +A **scenario** defines the goal and context for a conversation test. Where a +[persona](/docs/platform/persona/) says *who* is calling, the scenario says *why* they are +calling and what a good outcome looks like. + +The scenario feeds two places at once: it shapes the simulation prompt that drives the caller, +and its `required_info` gives the metric engine concrete expectations to validate against. That +is what keeps scoring consistent across repeated runs while the conversation itself still flows +naturally. + +## Configure a scenario + +### Creation paths + +- Generate from agent prompt +- Generate from call data +- Create manually + +### Scenario structure + +| Field | Description | +|---|---| +| `name` | Scenario title. | +| `description` | Conversation intent, flow, and success expectation. | +| `required_info` | Structured key/value expectations for validation. | +| `agent_id` | Optional linked agent for context and filtering. | + +### Recommended flow + +1. Write or generate scenario descriptions. +2. Add required success information where needed. +3. Link scenarios to target agents. +4. Use scenarios in [evaluation suites](/docs/platform/evaluation-suite/). + +See also: [How It Works](/docs/platform/) for how scenarios expand into run combinations. + +## How to create a scenario + +1. Go to **Simulations > Scenarios**. +2. Click **Create Scenario** on the top-right. + +![Creating a scenario](/screenshots/Scenario/creating-scenarios.png) + +EfficientAI supports three creation paths: + +### A) Generate from test agent + +1. Select the target agent. +2. Choose how many scenarios to generate. +3. Select AI provider. +4. Select model. +5. Click **Generate**. + +### B) Generate from calls + +This path is currently in beta. + +### C) Generate manually + +1. Enter scenario name. +2. Link the scenario to an agent. +3. Enter manual description or paste the agent prompt. diff --git a/docs-fumadocs/content/docs/(docs)/platform/setup.mdx b/docs-fumadocs/content/docs/(docs)/platform/setup.mdx new file mode 100644 index 00000000..9b9af2d4 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/setup.mdx @@ -0,0 +1,73 @@ +--- +title: Setup +icon: Settings +--- + +# Setup + +Use this page to configure the foundational platform prerequisites before creating test assets. + +## 1) BYOK and provider credentials + +Configure integrations for voice platforms, model providers, and telephony providers. + +See: [Integrations](/docs/integrations/) + +At minimum, most teams configure: + +- one voice platform integration (if using external agents), +- one or more AI model providers (LLM/STT/TTS), +- telephony credentials for phone-call workflows. + +## 2) Voice bundles + +### The STT, LLM, and TTS pipeline + +A voice bundle is a pipeline built from three model layers: + +- **STT (Speech-to-Text):** converts incoming audio to text. +- **LLM (Language Model):** generates the reasoning and response text. +- **TTS (Text-to-Speech):** converts the response text back to audio. + +Each layer is configurable, so you can hold the agent behavior constant and test it across +different model and provider combinations โ€” swapping only the STT provider, for example, and +attributing the score change to that layer alone. + +### Create a bundle + +Create voice bundles for controlled internal testing paths: + +- STT + LLM + TTS bundles +- S2S (speech-to-speech) bundles, where enabled, which collapse the three layers into one model + +Bundles help you run stable, repeatable test-agent evaluations even when external providers change behavior over time. + +![Voice bundle setup](/screenshots/Integrations/voice-bundle.png) + +## 3) Cloud storage + +Set up object storage for recordings and audio assets: + +- S3 and S3-compatible providers +- Google Cloud Storage +- Azure Blob Storage + +See: [Configuration](/docs/advanced/configuration/) + +Use cloud storage when you need durable recording retention, larger media throughput, or integration with existing data infrastructure. + +## 4) Authentication and enterprise SSO + +Choose auth providers for local or enterprise usage. + +See: [Enterprise](/docs/enterprise/) + +For a full open-source vs enterprise feature breakdown, see the [Enterprise comparison](/docs/enterprise/). + +## Setup checklist + +- Integrations connected and verified +- Voice bundle created +- Storage configured +- Auth mode confirmed +- First agent ready for evaluation diff --git a/docs-fumadocs/content/docs/(docs)/platform/traces-and-logs.mdx b/docs-fumadocs/content/docs/(docs)/platform/traces-and-logs.mdx new file mode 100644 index 00000000..1f20bdd4 --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/platform/traces-and-logs.mdx @@ -0,0 +1,11 @@ +--- +title: Traces and Logs +icon: FileSearch +--- + +# Traces and Logs + +> **Coming soon** +> Detailed tracing and log workflow documentation is being prepared for this section. + +For now, use existing run outputs in evaluator results and call-level pages for debugging. diff --git a/docs-fumadocs/content/docs/(docs)/quickstart/index.mdx b/docs-fumadocs/content/docs/(docs)/quickstart/index.mdx new file mode 100644 index 00000000..f647196f --- /dev/null +++ b/docs-fumadocs/content/docs/(docs)/quickstart/index.mdx @@ -0,0 +1,472 @@ +--- +title: Quickstart +icon: Rocket +--- + +
+ EfficientAI Quickstart +
+ +## Quick Start + +There are two ways to run the application: + +### Method 1: Using Docker Compose (Recommended) + +#### Start all services + +```bash +docker compose up -d +``` + +This will automatically: + +- Pull pre-built images from GitHub Container Registry (no build required!) +- Start all services: `db`, `redis`, `api`, `media`, `worker`, `beat`, `worker-imports`, `worker-usage` +- Run database migrations automatically on startup + +| Service | Purpose | +|---|---| +| `db` | PostgreSQL | +| `redis` | Redis (Celery broker + usage counters) | +| `api` | HTTP API + frontend | +| `media` | Live voice WebSocket media server | +| `worker` | Celery: `celery` (evaluator cron runs), `audio-metrics` queues | +| `beat` | Celery Beat scheduler + `platform` queue worker (alerts, FX, OSS prune) โ€” single replica | +| `worker-imports` | Celery: `imports`, `diarization`, `eval-control`, `evaluations` | +| `worker-usage` | Celery: `usage` queue (flush Redis counters, cost recompute, evaluator cron dispatch) | + +Usage costs: token/cost rollups stay stale without `beat`, `worker-usage`, and default `worker` (evaluator cron runs; or `eai start-all`). + +#### Using a specific version + +```bash +# Pin to a specific release version +EFFICIENTAI_VERSION=1.0.0 docker compose up -d + +# Or add to your .env file +echo "EFFICIENTAI_VERSION=1.0.0" >> .env +docker compose up -d +``` + +#### Configure your settings + +Edit `config.yml` and `config.docker.yml` with your settings (S3, API keys, etc.). See the Configuration section for details. + +Version note: `EFFICIENTAI_VERSION` must match a published Docker image tag (for example `1.0.0`). If a tag is not available yet, use `latest`. + +#### Optional: enable observability + +```bash +docker compose -f docker-compose.yml -f docker-compose.observability.yml up -d +``` + +To expose app metrics at `/metrics` and enable in-app Loki/org logging, also set `observability.enabled: true` in `config.docker.yml`. Set `observability.loki.enabled: true` when Loki logging should be active. + +#### Create an account + +Option A โ€” sign up in the browser (recommended): + +```bash +# Open the app and hit "Create account" on the login screen. +open http://localhost:8000/ +``` + +Option B โ€” create an API key from the CLI: + +```bash +docker compose exec api python -m scripts.create_api_key \ + --new-org "My Organization" --name "My API Key" +``` + +#### Access the application + +- Frontend: `http://localhost:8000/` +- API Docs: `http://localhost:8000/docs` + +#### Building Locally (for development) + +If you want to build images locally instead of pulling pre-built ones: + +```bash +# Edit docker-compose.yml to uncomment the 'build' sections, then: +docker compose up -d --build + +# Or rebuild without cache for a clean build +docker compose build --no-cache api worker +docker compose up -d +``` + +### Method 2: Using Command Line (CLI) + +#### Install the package + +```bash +pip install -e . +``` + +#### Generate configuration file + +```bash +eai init-config +``` + +#### Edit `config.yml` with your database and Redis connection strings + +```yaml +database: + url: "postgresql://efficientai:password@localhost:5432/efficientai" + +redis: + url: "redis://localhost:6379/0" +``` + +#### Start the application and workers + +Infra only (optional): if Postgres/Redis run in Docker but the app runs locally: + +```bash +docker compose up -d db redis +``` + +Option A: Start everything together (Recommended) + +```bash +eai start-all --config config.yml +``` + +This single command spawns: + +- API server (uvicorn) +- Telephony media server (`media` port, default 8001) +- Celery worker (`celery`, `audio-metrics`) +- Celery worker (`imports`, `diarization`, `eval-control`, `evaluations`) +- Celery worker (`usage` โ€” flush + cost recompute) +- Celery Beat (platform schedules: usage flush, alerts, FX refresh, OSS prune) + +It also runs database migrations and builds the frontend when needed. + +Press `Ctrl+C` to stop all processes. + +Option B: Start separately (for advanced use) + +In one terminal, start the application: + +```bash +eai start --config config.yml +``` + +In another terminal, start the Celery worker: + +```bash +eai worker --config config.yml +``` + +For platform periodic tasks (usage flush, alerts, etc.), start Celery Beat in a separate terminal (single replica): + +```bash +eai beat --config config.yml +``` + +Or use the Celery command directly: + +```bash +celery -A app.workers.celery_app worker --loglevel=info +``` + +The application will automatically: + +- Run database migrations (ensures schema is up to date) +- Build the frontend (if needed) +- Start the API server +- Serve both API and frontend from the same server + +Important: Migrations run automatically before startup. If migrations fail, the app won't start. + +For development with hot reload: + +```bash +# Enable auto-rebuild of frontend on file changes +eai start-all --config config.yml --watch-frontend +``` + +This will: + +- Automatically rebuild the frontend when source files change +- Keep the backend hot-reload enabled (by default) +- Perfect for active frontend development + +#### Access the application + +- Frontend: `http://localhost:8000/` +- API Docs: `http://localhost:8000/docs` + +### Prerequisites + +For Docker Compose: + +- Docker and Docker Compose installed +- ~4GB disk space for pre-built images + +For CLI: + +- Python 3.11+ +- Node.js 18+ and npm +- PostgreSQL running (locally or remote) +- Redis running (locally or remote) + +### Test Commands (Make) + +If you prefer shorthand commands, use the root `Makefile`: + +```bash +# Run all backend tests +make test + +# Run tests against a running Docker Compose Postgres +make test-docker-db + +# Run current Phase 1 suites +make test-phase1 + +# Run only unit or integration tests +make test-unit +make test-integration + +# Run a specific file +make test-file FILE=tests/test_core/test_password.py + +# Run tests by keyword +make test-k K=password +``` + +You can also pass extra pytest args: + +```bash +make test PYTEST_ARGS="-x -vv" +``` + +To override DB connection values for `make test-docker-db`: + +```bash +make test-docker-db TEST_DB_HOST=localhost TEST_DB_PORT=5432 TEST_DB_NAME=efficientai TEST_DB_USER=efficientai TEST_DB_PASSWORD=password +``` + +## CLI Commands + +### Start Application and Worker Together (Recommended) + +```bash +# Start API + all workers with default config.yml +eai start-all + +# Start with custom config +eai start-all --config production.yml + +# Start with frontend file watching (auto-rebuild on changes) +eai start-all --watch-frontend + +# Start without building frontend (if already built) +eai start-all --no-build-frontend + +# Start without auto-reload (production mode) +eai start-all --no-reload --no-build-frontend + +# Customize worker log level +eai start-all --worker-loglevel debug + +# Skip dedicated workers (not recommended for production) +eai start-all --no-imports-worker +eai start-all --no-usage-worker +eai start-all --no-telephony-worker + +# Tune usage worker concurrency (default: 4, thread pool) +eai start-all --usage-worker-concurrency 8 +``` + +Note: This is the recommended local-dev workflow. One command spawns the API, telephony media server, three Celery workers (`celery,audio-metrics` ยท `imports,โ€ฆ` ยท `usage`), and Celery Beat. Press `Ctrl+C` to stop all processes. For Docker deployments, use `docker compose up -d` instead (separate containers per role; see Quick Start). + +### Start Application Only + +```bash +# Start just the API server (worker must be started separately) +eai start --config config.yml + +# Start with auto-reload for development +eai start --reload + +# Start with frontend file watching +eai start --watch-frontend +``` + +### Start Worker Only + +```bash +# Start Celery worker with default config.yml +eai worker + +# Start with custom config +eai worker --config production.yml + +# Start with custom log level +eai worker --loglevel debug + +# Or use Celery command directly +celery -A app.workers.celery_app worker --loglevel=info +``` + +Development Mode: + +```bash +# Full development setup with both backend and frontend hot reload +eai start-all --watch-frontend --reload +``` + +### Usage Pricing Ops + +Manage model pricing rates and backfill stored usage costs on `llm_usage_daily` rollups. Requires `beat`, `worker-usage`, and default `worker` (or `eai start-all`). + +```bash +# Upsert model_pricing_rates from app/config/models.json +eai usage seed-rates --config config.yml + +# Compare models.json pricing vs Postgres +eai usage diff-rates --config config.yml + +# Backfill costs in-process (all orgs; use after migrate or catalog change) +eai usage recompute --config config.yml --sync + +# Async recompute via usage queue (requires --organization-id) +eai usage recompute --config config.yml --organization-id + +# Optional: fetch LiteLLM prices into pricing_catalog.json +eai usage sync-litellm --local +eai usage sync-litellm --local --write-models +``` + +After migrations or catalog changes: + +```bash +eai migrate +eai usage seed-rates --config config.yml +eai usage recompute --config config.yml --sync +``` + +### Generate Config File + +```bash +# Generate default config.yml +eai init-config + +# Generate custom config file +eai init-config --output my-config.yml +``` + +### Database Migrations + +```bash +# Run pending migrations manually +eai migrate + +# Run migrations with verbose output +eai migrate --verbose +``` + +Note: Migrations run automatically on application startup. You only need to run them manually if you want to apply migrations before starting the server. + +## Configuration + +### YAML Configuration + +EfficientAI uses YAML configuration files for both CLI and Docker deployments. Generate a default config with: + +```bash +eai init-config +``` + +```yaml +# Application Settings +app: + name: "EfficientAI Voice AI Evaluation Platform" + version: "0.1.0" + debug: true + secret_key: "your-secret-key-here-change-in-production" + +# Server Settings +server: + host: "0.0.0.0" + port: 8000 + +# Database Configuration +database: + url: "postgresql://user:password@host:port/dbname" + +# Redis Configuration +redis: + url: "redis://host:port/db" + +# Celery Configuration (for background tasks) +celery: + broker_url: "redis://host:port/db" + result_backend: "redis://host:port/db" + +# File Storage +storage: + upload_dir: "./uploads" + max_file_size_mb: 500 + blob_provider: s3 + allowed_audio_formats: + - "wav" + - "mp3" + - "flac" + - "m4a" +``` + +### Environment Variables (Optional) + +```bash +POSTGRES_USER=efficientai +POSTGRES_PASSWORD=password +POSTGRES_DB=efficientai +SECRET_KEY=your-secret-key-here + +# Optional: GCS blob storage +BLOB_STORAGE_PROVIDER=gcs +GCS_BUCKET_NAME=your-gcs-bucket +GCS_PROJECT_ID=your-gcp-project +GOOGLE_APPLICATION_CREDENTIALS=/app/secrets/gcp-sa.json +``` + +## Troubleshooting + +### Database Migration Issues + +Problem: + +```txt +psycopg2.errors.UndefinedColumn: column "organization_id" of relation "api_keys" does not exist +``` + +Check migration status: + +```bash +python scripts/check_migrations.py +``` + +Run migrations manually: + +```bash +eai migrate --verbose +python -c "from app.core.migrations import run_migrations; run_migrations()" +``` + +For Docker setups: + +```bash +docker compose exec api eai migrate --verbose +``` diff --git a/docs-fumadocs/content/docs/advanced/architecture.mdx b/docs-fumadocs/content/docs/advanced/architecture.mdx index 64cc10e4..9704624f 100644 --- a/docs-fumadocs/content/docs/advanced/architecture.mdx +++ b/docs-fumadocs/content/docs/advanced/architecture.mdx @@ -32,25 +32,6 @@ The platform consists of four primary components: 3. **Frontend (React/Vite)**: The user interface. 4. **Data Stores**: PostgreSQL (State) and Redis (Queue/Cache). -```mermaid -graph TD - User["User / Client"] --> |HTTP/WS| API["API Server (FastAPI)"] - User --> |HTTP| FE["Frontend (React)"] - - subgraph "EfficientAI Platform" - API --> DB[("PostgreSQL")] - API --> |Task Queue| Redis[("Redis")] - - Worker["Celery Worker"] --> |Consume Tasks| Redis - Worker --> |Write Results| DB - - API --> |Orchestrates| TestAgent["Test Agent Service"] - TestAgent --> |LLM Inference| LLM["LLM Provider"] - TestAgent --> |TTS| TTS["TTS Provider"] - TestAgent --> |Audio Stream| Agent["Voice Agent (SUT)"] - end -``` - ## Core Services ### 1. API Server (`app/api`) diff --git a/docs-fumadocs/content/docs/advanced/database.mdx b/docs-fumadocs/content/docs/advanced/database.mdx index 6ec7f28a..20ae69a3 100644 --- a/docs-fumadocs/content/docs/advanced/database.mdx +++ b/docs-fumadocs/content/docs/advanced/database.mdx @@ -4,7 +4,7 @@ title: Database sidebar_position: 1 --- -# ๐Ÿ—„๏ธ Database Migrations +# Database Migrations The application includes an automatic migration system that runs database schema changes on startup. @@ -44,12 +44,12 @@ def upgrade(db): **Automatic (Recommended - Default Behavior):** -- โœ… Migrations run automatically when you start the app with `eai start` -- โœ… Migrations also run automatically when the application starts (via lifespan handler) -- โœ… If migrations fail, the application will NOT start - this ensures database consistency -- โœ… API requests are blocked if migrations are pending -- โœ… When cloning from main, migrations will run automatically on first startup -- โœ… Each migration only runs once (tracked in `schema_migrations` table) +- Migrations run automatically when you start the app with `eai start` +- Migrations also run automatically when the application starts (via lifespan handler) +- If migrations fail, the application will NOT start - this ensures database consistency +- API requests are blocked if migrations are pending +- When cloning from main, migrations will run automatically on first startup +- Each migration only runs once (tracked in `schema_migrations` table) **Manual:** @@ -76,7 +76,7 @@ eai start --skip-migrations 4. Use `IF NOT EXISTS` checks for idempotent operations 5. See `migrations/README.md` for detailed documentation. -# ๐Ÿ“Š Database ER Diagram +# Database ER Diagram Generate a visual Entity-Relationship (ER) diagram of your database schema to visualize table structures and relationships. diff --git a/docs-fumadocs/content/docs/advanced/development.mdx b/docs-fumadocs/content/docs/advanced/development.mdx index ad26f05f..85024c16 100644 --- a/docs-fumadocs/content/docs/advanced/development.mdx +++ b/docs-fumadocs/content/docs/advanced/development.mdx @@ -4,7 +4,7 @@ title: Development & Troubleshooting sidebar_position: 2 --- -# ๐Ÿ› ๏ธ Development +# Development ## Running Locally @@ -50,7 +50,7 @@ This runs Vite dev server on http://localhost:3000 with instant hot module repla **Note**: You'll need to run the backend separately on port 8000. -# ๐Ÿ”ง Troubleshooting +# Troubleshooting ## Database Migration Issues @@ -122,14 +122,14 @@ docker compose exec api eai migrate --verbose **Prevention**: Always ensure migrations run successfully before using the application. Check the startup logs for migration status messages. -# ๐Ÿ“ž Support +# Support -- ๐Ÿ“ง Email: tejas@efficientai.cloud -- ๐Ÿ“… Book a Demo: Schedule a call -- ๐Ÿ’ฌ LinkedIn: Connect with us -- ๐Ÿฆ X (Twitter): Follow us -- ๐Ÿ’ป GitHub: View on GitHub +- Email: tejas@efficientai.cloud +- Book a Demo: Schedule a call +- LinkedIn: Connect with us +- X (Twitter): Follow us +- GitHub: View on GitHub -# ๐Ÿ“„ License +# License MIT License - see LICENSE file for details diff --git a/docs-fumadocs/content/docs/api-reference/agents/check_phone_assignment_api_v1_agents_check_phone_assignment_get.mdx b/docs-fumadocs/content/docs/api-reference/agents/check_phone_assignment_api_v1_agents_check_phone_assignment_get.mdx new file mode 100644 index 00000000..abf52cec --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/check_phone_assignment_api_v1_agents_check_phone_assignment_get.mdx @@ -0,0 +1,30 @@ +--- +title: Check Phone Assignment +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Check whether a phone number is available for agent assignment in this + org. +mdPath: "/api-md/agents/check_phone_assignment_api_v1_agents_check_phone_assignment_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/agents/create_agent_api_v1_agents_post.mdx b/docs-fumadocs/content/docs/api-reference/agents/create_agent_api_v1_agents_post.mdx new file mode 100644 index 00000000..4b3bfb55 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/create_agent_api_v1_agents_post.mdx @@ -0,0 +1,33 @@ +--- +title: Create Agent +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Create a new test agent. + + The agent is stamped with the active workspace from the + ``X-Workspace-Id`` header (falling back to the org's Default). +mdPath: "/api-md/agents/create_agent_api_v1_agents_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/agents/delete_agent_api_v1_agents__agent_id__delete.mdx b/docs-fumadocs/content/docs/api-reference/agents/delete_agent_api_v1_agents__agent_id__delete.mdx new file mode 100644 index 00000000..3a702e40 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/delete_agent_api_v1_agents__agent_id__delete.mdx @@ -0,0 +1,30 @@ +--- +title: Delete Agent +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete an agent (scoped to the active workspace). Returns 409 if + dependent records exist unless force=true. +mdPath: "/api-md/agents/delete_agent_api_v1_agents__agent_id__delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/agents/generate_agent_description_api_v1_agents_generate_description_post.mdx b/docs-fumadocs/content/docs/api-reference/agents/generate_agent_description_api_v1_agents_generate_description_post.mdx new file mode 100644 index 00000000..ae0df2c1 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/generate_agent_description_api_v1_agents_generate_description_post.mdx @@ -0,0 +1,29 @@ +--- +title: Generate Agent Description +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Generate an agent description using AI from a brief description. +mdPath: "/api-md/agents/generate_agent_description_api_v1_agents_generate_description_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/agents/generate_scenarios_from_prompt_api_v1_agents_generate_scenarios_from_prompt_post.mdx b/docs-fumadocs/content/docs/api-reference/agents/generate_scenarios_from_prompt_api_v1_agents_generate_scenarios_from_prompt_post.mdx new file mode 100644 index 00000000..b3d9c07f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/generate_scenarios_from_prompt_api_v1_agents_generate_scenarios_from_prompt_post.mdx @@ -0,0 +1,29 @@ +--- +title: Generate Scenarios From Prompt +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: 'Stage 2: generate scenario drafts from a test agent prompt.' +mdPath: "/api-md/agents/generate_scenarios_from_prompt_api_v1_agents_generate_scenarios_from_prompt_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/agents/generate_test_prompt_api_v1_agents_generate_test_prompt_post.mdx b/docs-fumadocs/content/docs/api-reference/agents/generate_test_prompt_api_v1_agents_generate_test_prompt_post.mdx new file mode 100644 index 00000000..29605f8f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/generate_test_prompt_api_v1_agents_generate_test_prompt_post.mdx @@ -0,0 +1,30 @@ +--- +title: Generate Test Prompt +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: 'Stage 1: generate foundational test agent prompt from production + prompt.' +mdPath: "/api-md/agents/generate_test_prompt_api_v1_agents_generate_test_prompt_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/agents/generate_test_setup_api_v1_agents_generate_test_setup_post.mdx b/docs-fumadocs/content/docs/api-reference/agents/generate_test_setup_api_v1_agents_generate_test_setup_post.mdx new file mode 100644 index 00000000..11308fa4 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/generate_test_setup_api_v1_agents_generate_test_setup_post.mdx @@ -0,0 +1,29 @@ +--- +title: Generate Test Setup +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: 'Run stage 1 then stage 2: foundational test prompt + scenario drafts.' +mdPath: "/api-md/agents/generate_test_setup_api_v1_agents_generate_test_setup_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/agents/get_agent_api_v1_agents__agent_id__get.mdx b/docs-fumadocs/content/docs/api-reference/agents/get_agent_api_v1_agents__agent_id__get.mdx new file mode 100644 index 00000000..c2b4e7fb --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/get_agent_api_v1_agents__agent_id__get.mdx @@ -0,0 +1,30 @@ +--- +title: Get Agent +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Get a specific agent by ID (UUID) or agent_id (6-digit) within the + active workspace. +mdPath: "/api-md/agents/get_agent_api_v1_agents__agent_id__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/agents/get_agent_delete_impact_api_v1_agents__agent_id__delete_impact_get.mdx b/docs-fumadocs/content/docs/api-reference/agents/get_agent_delete_impact_api_v1_agents__agent_id__delete_impact_get.mdx new file mode 100644 index 00000000..b5922fb6 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/get_agent_delete_impact_api_v1_agents__agent_id__delete_impact_get.mdx @@ -0,0 +1,30 @@ +--- +title: Get Agent Delete Impact +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Preview dependent records that would be affected by force delete + (scoped to the active workspace). +mdPath: "/api-md/agents/get_agent_delete_impact_api_v1_agents__agent_id__delete_impact_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/agents/list_agents_api_v1_agents_get.mdx b/docs-fumadocs/content/docs/api-reference/agents/list_agents_api_v1_agents_get.mdx new file mode 100644 index 00000000..84c816f7 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/list_agents_api_v1_agents_get.mdx @@ -0,0 +1,33 @@ +--- +title: List Agents +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Get list of all agents for the active workspace. + + Scoped to (organization_id, workspace_id) so users only see agents + in the workspace they're currently in. +mdPath: "/api-md/agents/list_agents_api_v1_agents_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/agents/sync_agent_provider_prompt_api_v1_agents__agent_id__sync_provider_prompt_post.mdx b/docs-fumadocs/content/docs/api-reference/agents/sync_agent_provider_prompt_api_v1_agents__agent_id__sync_provider_prompt_post.mdx new file mode 100644 index 00000000..18004a7e --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/sync_agent_provider_prompt_api_v1_agents__agent_id__sync_provider_prompt_post.mdx @@ -0,0 +1,29 @@ +--- +title: Sync Agent Provider Prompt +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Fetch and store the current system prompt from the voice provider. +mdPath: "/api-md/agents/sync_agent_provider_prompt_api_v1_agents__agent_id__sync_provider_prompt_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/agents/update_agent_api_v1_agents__agent_id__put.mdx b/docs-fumadocs/content/docs/api-reference/agents/update_agent_api_v1_agents__agent_id__put.mdx new file mode 100644 index 00000000..123ff4a0 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/agents/update_agent_api_v1_agents__agent_id__put.mdx @@ -0,0 +1,30 @@ +--- +title: Update Agent +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Update an existing agent by ID (UUID) or agent_id (6-digit) within the + active workspace. +mdPath: "/api-md/agents/update_agent_api_v1_agents__agent_id__put.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/ai-providers/createAIProvider.mdx b/docs-fumadocs/content/docs/api-reference/ai-providers/createAIProvider.mdx new file mode 100644 index 00000000..77d11b1e --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/ai-providers/createAIProvider.mdx @@ -0,0 +1,29 @@ +--- +title: Create Aiprovider +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Create a new AI Provider credential row. +mdPath: "/api-md/ai-providers/createAIProvider.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/ai-providers/deleteAIProvider.mdx b/docs-fumadocs/content/docs/api-reference/ai-providers/deleteAIProvider.mdx new file mode 100644 index 00000000..73134c99 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/ai-providers/deleteAIProvider.mdx @@ -0,0 +1,29 @@ +--- +title: Delete Aiprovider +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete an AI Provider +mdPath: "/api-md/ai-providers/deleteAIProvider.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/ai-providers/get_aiprovider_api_v1_aiproviders__aiprovider_id__get.mdx b/docs-fumadocs/content/docs/api-reference/ai-providers/get_aiprovider_api_v1_aiproviders__aiprovider_id__get.mdx new file mode 100644 index 00000000..b9efde9d --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/ai-providers/get_aiprovider_api_v1_aiproviders__aiprovider_id__get.mdx @@ -0,0 +1,29 @@ +--- +title: Get Aiprovider +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Get a specific AI Provider +mdPath: "/api-md/ai-providers/get_aiprovider_api_v1_aiproviders__aiprovider_id__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/ai-providers/listAIProviders.mdx b/docs-fumadocs/content/docs/api-reference/ai-providers/listAIProviders.mdx new file mode 100644 index 00000000..abd5cec2 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/ai-providers/listAIProviders.mdx @@ -0,0 +1,29 @@ +--- +title: List Aiproviders +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: List all AI Providers for the organization. +mdPath: "/api-md/ai-providers/listAIProviders.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/ai-providers/setDefaultAIProvider.mdx b/docs-fumadocs/content/docs/api-reference/ai-providers/setDefaultAIProvider.mdx new file mode 100644 index 00000000..ba0b68c0 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/ai-providers/setDefaultAIProvider.mdx @@ -0,0 +1,29 @@ +--- +title: Set Default Aiprovider +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Mark this AIProvider row as the default for its (org, provider). +mdPath: "/api-md/ai-providers/setDefaultAIProvider.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/ai-providers/testAIProvider.mdx b/docs-fumadocs/content/docs/api-reference/ai-providers/testAIProvider.mdx new file mode 100644 index 00000000..6dceca4f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/ai-providers/testAIProvider.mdx @@ -0,0 +1,29 @@ +--- +title: Test Aiprovider +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Test an AI Provider API key +mdPath: "/api-md/ai-providers/testAIProvider.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/ai-providers/updateAIProvider.mdx b/docs-fumadocs/content/docs/api-reference/ai-providers/updateAIProvider.mdx new file mode 100644 index 00000000..ec160abf --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/ai-providers/updateAIProvider.mdx @@ -0,0 +1,29 @@ +--- +title: Update Aiprovider +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Update an existing AI Provider +mdPath: "/api-md/ai-providers/updateAIProvider.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication.mdx b/docs-fumadocs/content/docs/api-reference/authentication.mdx new file mode 100644 index 00000000..efe60527 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication.mdx @@ -0,0 +1,38 @@ +--- +title: Authentication Guide +description: How to authenticate requests against EfficientAI API endpoints. +--- + +# Authentication Guide + +EfficientAI accepts either bearer tokens or organization API keys on most authenticated endpoints. + +## Header options + +- `Authorization: Bearer ` +- `X-API-Key: ` +- Optional workspace scoping: `X-Workspace-Id: ` + +## Bearer token flow + +1. Create a session with `POST /api/v1/auth/login`. +2. Use the returned access token in `Authorization` for subsequent requests. +3. Refresh with `POST /api/v1/auth/refresh` when required. + +## API key flow + +1. Authenticate once with bearer credentials. +2. Generate a key using `POST /api/v1/auth/generate-key`. +3. Send that key in `X-API-Key` for service-to-service usage. + +## Public endpoints + +These routes are intentionally unauthenticated: + +- `GET /api/v1/auth/config` +- `POST /api/v1/auth/login` +- `POST /api/v1/auth/signup` +- `POST /api/v1/auth/refresh` +- `GET /api/v1/auth/invitations/preview/{token}` + +All other pages in this API Reference assume authenticated access unless explicitly marked otherwise. diff --git a/docs-fumadocs/content/docs/api-reference/authentication/accept_invitation_by_token_api_v1_auth_invitations_accept_by_token_post.mdx b/docs-fumadocs/content/docs/api-reference/authentication/accept_invitation_by_token_api_v1_auth_invitations_accept_by_token_post.mdx new file mode 100644 index 00000000..a00a4d99 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/accept_invitation_by_token_api_v1_auth_invitations_accept_by_token_post.mdx @@ -0,0 +1,30 @@ +--- +title: Accept Invitation By Token +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Accept an invitation and return a session scoped to the invited + organization. +mdPath: "/api-md/authentication/accept_invitation_by_token_api_v1_auth_invitations_accept_by_token_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication/generate_api_key_api_v1_auth_generate_key_post.mdx b/docs-fumadocs/content/docs/api-reference/authentication/generate_api_key_api_v1_auth_generate_key_post.mdx new file mode 100644 index 00000000..3773946e --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/generate_api_key_api_v1_auth_generate_key_post.mdx @@ -0,0 +1,41 @@ +--- +title: Generate Api Key +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Issue a new API key bound to the caller's organization. + + + This used to be anonymous and created a fresh org on every call - a + + security hole in any multi-tenant deployment. It now requires the + caller + + to already be authenticated (Bearer or an existing API key). The + created + + key inherits `principal.organization_id` and `principal.user_id`. +mdPath: "/api-md/authentication/generate_api_key_api_v1_auth_generate_key_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication/get_auth_config_api_v1_auth_config_get.mdx b/docs-fumadocs/content/docs/api-reference/authentication/get_auth_config_api_v1_auth_config_get.mdx new file mode 100644 index 00000000..ea50cbb5 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/get_auth_config_api_v1_auth_config_get.mdx @@ -0,0 +1,29 @@ +--- +title: Get Auth Config +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Return which login methods the frontend should render on /login. +mdPath: "/api-md/authentication/get_auth_config_api_v1_auth_config_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication/login_api_v1_auth_login_post.mdx b/docs-fumadocs/content/docs/api-reference/authentication/login_api_v1_auth_login_post.mdx new file mode 100644 index 00000000..f5c41b3b --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/login_api_v1_auth_login_post.mdx @@ -0,0 +1,29 @@ +--- +title: Login +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Verify email/password and return a short-lived Bearer token. +mdPath: "/api-md/authentication/login_api_v1_auth_login_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication/logout_api_v1_auth_logout_post.mdx b/docs-fumadocs/content/docs/api-reference/authentication/logout_api_v1_auth_logout_post.mdx new file mode 100644 index 00000000..154c94f8 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/logout_api_v1_auth_logout_post.mdx @@ -0,0 +1,30 @@ +--- +title: Logout +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Revoke the current session's refresh token and blacklist the access + token. +mdPath: "/api-md/authentication/logout_api_v1_auth_logout_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication/me_api_v1_auth_me_get.mdx b/docs-fumadocs/content/docs/api-reference/authentication/me_api_v1_auth_me_get.mdx new file mode 100644 index 00000000..e4b56cb8 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/me_api_v1_auth_me_get.mdx @@ -0,0 +1,29 @@ +--- +title: Me +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Return the current authenticated user (Bearer or API key). +mdPath: "/api-md/authentication/me_api_v1_auth_me_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication/preview_invitation_api_v1_auth_invitations_preview__token__get.mdx b/docs-fumadocs/content/docs/api-reference/authentication/preview_invitation_api_v1_auth_invitations_preview__token__get.mdx new file mode 100644 index 00000000..b1b66fae --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/preview_invitation_api_v1_auth_invitations_preview__token__get.mdx @@ -0,0 +1,29 @@ +--- +title: Preview Invitation +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Public preview of an organization invite (no auth required). +mdPath: "/api-md/authentication/preview_invitation_api_v1_auth_invitations_preview__token__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication/refresh_session_api_v1_auth_refresh_post.mdx b/docs-fumadocs/content/docs/api-reference/authentication/refresh_session_api_v1_auth_refresh_post.mdx new file mode 100644 index 00000000..15490f5f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/refresh_session_api_v1_auth_refresh_post.mdx @@ -0,0 +1,29 @@ +--- +title: Refresh Session +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Rotate a refresh token and issue a new short-lived access token. +mdPath: "/api-md/authentication/refresh_session_api_v1_auth_refresh_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication/set_password_api_v1_auth_password_post.mdx b/docs-fumadocs/content/docs/api-reference/authentication/set_password_api_v1_auth_password_post.mdx new file mode 100644 index 00000000..6392b2df --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/set_password_api_v1_auth_password_post.mdx @@ -0,0 +1,39 @@ +--- +title: Set Password +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Set or change the password on the authenticated user. + + + Use cases: + 1. User signed up via API key only and now wants an email/password login + for the same identity -> call this once to set the password (and, + if their email is still `api_user_*@efficientai.local`, pass a real + `email` to replace it). + 2. User already has a password and wants to rotate it -> supply both + `current_password` and `new_password`. +mdPath: "/api-md/authentication/set_password_api_v1_auth_password_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication/signup_api_v1_auth_signup_post.mdx b/docs-fumadocs/content/docs/api-reference/authentication/signup_api_v1_auth_signup_post.mdx new file mode 100644 index 00000000..7b5ea4bd --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/signup_api_v1_auth_signup_post.mdx @@ -0,0 +1,34 @@ +--- +title: Signup +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Create a new User + Organization pair and return a login token. + + Only available in OSS/self-hosted deployments where + `auth.local_password.allow_signup = true` (the default). Cloud SaaS + turns this off and routes signup through the billing flow. +mdPath: "/api-md/authentication/signup_api_v1_auth_signup_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication/switch_organization_api_v1_auth_switch_org_post.mdx b/docs-fumadocs/content/docs/api-reference/authentication/switch_organization_api_v1_auth_switch_org_post.mdx new file mode 100644 index 00000000..bedc5020 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/switch_organization_api_v1_auth_switch_org_post.mdx @@ -0,0 +1,35 @@ +--- +title: Switch Organization +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Issue a new Bearer token bound to a different organization. + + The caller must be an interactive user (not an API key) and must be an + active member of the target organization. Role is re-derived from the + new org's OrganizationMember row - switching orgs can legitimately + change your role. +mdPath: "/api-md/authentication/switch_organization_api_v1_auth_switch_org_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/authentication/validate_api_key_api_v1_auth_validate_post.mdx b/docs-fumadocs/content/docs/api-reference/authentication/validate_api_key_api_v1_auth_validate_post.mdx new file mode 100644 index 00000000..ac011592 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/authentication/validate_api_key_api_v1_auth_validate_post.mdx @@ -0,0 +1,30 @@ +--- +title: Validate Api Key +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Lightweight endpoint the frontend uses to confirm the stored key still + works. +mdPath: "/api-md/authentication/validate_api_key_api_v1_auth_validate_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/appendCallImportAudio.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/appendCallImportAudio.mdx new file mode 100644 index 00000000..e356811f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/appendCallImportAudio.mdx @@ -0,0 +1,29 @@ +--- +title: Append Call Import Audio +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Append manually uploaded recordings to an existing audio batch. +mdPath: "/api-md/call-imports/appendCallImportAudio.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/bulkDeleteCallImportRows.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/bulkDeleteCallImportRows.mdx new file mode 100644 index 00000000..379c306f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/bulkDeleteCallImportRows.mdx @@ -0,0 +1,35 @@ +--- +title: Bulk Delete Call Import Rows +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Delete multiple ``CallImportRow`` rows in one request. + + Unknown / cross-tenant row ids are silently skipped โ€” the response + reports how many actually went away so a UI that holds onto stale + ids (e.g. after another tab already deleted a row) doesn't 404 + the entire bulk action. +mdPath: "/api-md/call-imports/bulkDeleteCallImportRows.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/cancelCallImportDiarisation.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/cancelCallImportDiarisation.mdx new file mode 100644 index 00000000..658a902e --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/cancelCallImportDiarisation.mdx @@ -0,0 +1,38 @@ +--- +title: Cancel Call Import Diarisation +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Abort in-flight diarisation for many rows in a single call. + + Default body (no ``row_ids``) cancels every row in this import + whose ``diarised_transcript_status`` is ``pending`` or + ``running`` โ€” the "stop everything" button. Pass ``row_ids`` to + scope the cancel to the rows the operator has selected. + + Returns ``(cancelled, skipped)`` so the UI can render a tight + toast ("Cancelled 3 rows ยท 1 skipped (already completed)"). +mdPath: "/api-md/call-imports/cancelCallImportDiarisation.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/cancelCallImportRowDiarisation.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/cancelCallImportRowDiarisation.mdx new file mode 100644 index 00000000..8f2f9c06 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/cancelCallImportRowDiarisation.mdx @@ -0,0 +1,45 @@ +--- +title: Cancel Call Import Row Diarisation +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Abort an in-flight (or queued) diarisation for a single row. + + Idempotent: calling on a row that's already terminal (``completed`` + / ``failed`` / ``idle``) returns the row unchanged with a 200, so + the UI can fire this from a "Stop" button without having to + pre-check the state. + + Race notes: + + * The row's ``diarised_transcript_status`` is flipped to ``failed`` + with :data:`CANCELLED_BY_USER_ERROR` BEFORE the Celery revoke, + so the polling UI sees the cancel immediately. + * If the worker happens to finish between our DB flip and the + SIGTERM landing, its finaliser will detect the cancelled + sentinel on the row and skip its own status / score writes + (see :mod:`app.workers.tasks.transcribe_call_import_row`). +mdPath: "/api-md/call-imports/cancelCallImportRowDiarisation.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/createCallImport.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/createCallImport.mdx new file mode 100644 index 00000000..221f76e5 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/createCallImport.mdx @@ -0,0 +1,37 @@ +--- +title: Create Call Import +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + UPLOAD stage of the staged call-import flow. + + Persists the source file to S3 and creates a ``CallImport`` row with + ``status='uploaded'``. No mapping, no provider, no rows yet โ€” the + user moves through MAP and IMPORT as separate idempotent steps. + + Dataset is collected here (rather than at IMPORT) so the batch is + filterable from the moment it appears in the list view. +mdPath: "/api-md/call-imports/createCallImport.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/createCallImportSchema.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/createCallImportSchema.mdx new file mode 100644 index 00000000..1f6f1c05 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/createCallImportSchema.mdx @@ -0,0 +1,35 @@ +--- +title: Create Call Import Schema +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Create a new schema + parameters in the active workspace. + + Pydantic validates the cross-parameter invariants (single + ``conversation_id``, unique names) before the body reaches this + handler; we still rely on the DB-level unique index to catch the + name-collision race. +mdPath: "/api-md/call-imports/createCallImportSchema.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/createCallImportTag.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/createCallImportTag.mdx new file mode 100644 index 00000000..a5857c59 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/createCallImportTag.mdx @@ -0,0 +1,29 @@ +--- +title: Create Call Import Tag +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Create a new tag scoped to this organization. +mdPath: "/api-md/call-imports/createCallImportTag.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImport.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImport.mdx new file mode 100644 index 00000000..225e8e6e --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImport.mdx @@ -0,0 +1,33 @@ +--- +title: Delete Call Import +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Delete a call-import batch asynchronously. + + Flips the batch to ``deleting`` and enqueues background teardown so + large imports (thousands of rows + S3 objects) do not block the API. +mdPath: "/api-md/call-imports/deleteCallImport.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImportRow.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImportRow.mdx new file mode 100644 index 00000000..4ccbf637 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImportRow.mdx @@ -0,0 +1,38 @@ +--- +title: Delete Call Import Row +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Delete a single CallImportRow and its S3 recording. + + + The parent ``CallImport`` is left in place. After deletion we + recompute + + its ``total_rows`` / ``completed_rows`` / ``failed_rows`` / ``status`` + + so the UI's progress bar stays consistent with reality. +mdPath: "/api-md/call-imports/deleteCallImportRow.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImportSchema.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImportSchema.mdx new file mode 100644 index 00000000..79a1c9ef --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImportSchema.mdx @@ -0,0 +1,43 @@ +--- +title: Delete Call Import Schema +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Delete a schema. + + By default refuses with 409 when any ``CallImport`` row still + references the schema (matches the ``ON DELETE RESTRICT`` FK + behavior); the user must either delete the dependent batches + first, migrate them to a different schema, or retry with + ``?force=true`` to detach them in one shot. + + ``force=true`` is safe for completed batches: every batch keeps + its own ``parameter_mapping`` snapshot, and downstream rendering + (detail page, evaluation export) already handles a NULL + ``schema_id`` gracefully. Batches still in the staged ``uploaded`` + state will need a fresh schema before they can be imported - the + existing import endpoint already enforces that. +mdPath: "/api-md/call-imports/deleteCallImportSchema.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImportTag.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImportTag.mdx new file mode 100644 index 00000000..acaef52d --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/deleteCallImportTag.mdx @@ -0,0 +1,30 @@ +--- +title: Delete Call Import Tag +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete a tag. Existing tag assignments are removed by ON DELETE + CASCADE. +mdPath: "/api-md/call-imports/deleteCallImportTag.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportDetail.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportDetail.mdx new file mode 100644 index 00000000..e6a47504 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportDetail.mdx @@ -0,0 +1,34 @@ +--- +title: Get Call Import Detail +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Fetch a single import batch with a slice of its rows. + + ``row_limit=0`` is intentionally allowed so callers that only need the + batch metadata (e.g. the evaluation-detail page rendering the parent's + column mapping) can skip the rows payload entirely. +mdPath: "/api-md/call-imports/getCallImportDetail.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportDiarisationPromptDefault.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportDiarisationPromptDefault.mdx new file mode 100644 index 00000000..bd4e1840 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportDiarisationPromptDefault.mdx @@ -0,0 +1,40 @@ +--- +title: Get Call Import Diarisation Prompt Default +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Return the canonical LLM diariser prompt. + + The Transcribe / Run Evaluation modals call this on open so they + can pre-fill the prompt textarea. Returning the constant from the + backend (rather than hard-coding it in the frontend) keeps the + fallback used by the worker and the placeholder shown in the UI + in lock-step โ€” operators always see the *actual* default they'd + get if they leave the field blank. + + Registered before ``GET /{call_import_id}`` so the static path is + not mistaken for a UUID import id (which would 422). +mdPath: "/api-md/call-imports/getCallImportDiarisationPromptDefault.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportDispatchDiagnostics.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportDispatchDiagnostics.mdx new file mode 100644 index 00000000..5839d5c1 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportDispatchDiagnostics.mdx @@ -0,0 +1,39 @@ +--- +title: Get Call Import Dispatch Diagnostics +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Live eval slot usage and fair-dispatch state for operators. + + + Org admins use this to diagnose cross-workspace starvation (e.g. one + + workspace's 10k run blocking another's pending eval rows) by + inspecting + + Redis in-flight counters, pending dispatch rows, and scheduler + cursors. +mdPath: "/api-md/call-imports/getCallImportDispatchDiagnostics.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportInsights.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportInsights.mdx new file mode 100644 index 00000000..db39832f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportInsights.mdx @@ -0,0 +1,37 @@ +--- +title: Get Call Import Insights +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Aggregate signals across every evaluation run on this import. + + Powers the Insights tab on the call-import detail page: returns + per-metric "latest run" summaries plus a trend series of mean values + across runs so the UI can render a small line chart per metric. Also + bundles transcript coverage stats since those are the cheapest + pre-eval health-check (e.g. "30 of 50 rows still missing + transcripts"). +mdPath: "/api-md/call-imports/getCallImportInsights.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportSchema.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportSchema.mdx new file mode 100644 index 00000000..9a8155de --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/getCallImportSchema.mdx @@ -0,0 +1,29 @@ +--- +title: Get Call Import Schema +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Fetch a single schema with its parameters + usage count. +mdPath: "/api-md/call-imports/getCallImportSchema.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportDatasets.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportDatasets.mdx new file mode 100644 index 00000000..0dab59f7 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportDatasets.mdx @@ -0,0 +1,34 @@ +--- +title: List Call Import Datasets +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Return the distinct, non-null dataset labels in use for the active + workspace. + + Scoped per-workspace so each workspace's Dataset dropdown only shows + its own segregation labels. +mdPath: "/api-md/call-imports/listCallImportDatasets.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportRowIds.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportRowIds.mdx new file mode 100644 index 00000000..3093030f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportRowIds.mdx @@ -0,0 +1,37 @@ +--- +title: List Call Import Row Ids +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Return every matching ``CallImportRow.id`` for cross-page bulk select. + + Lightweight companion to ``GET /{call_import_id}`` โ€” the detail + endpoint caps ``row_limit`` at 5000 and ships the entire row body + on each page, so harvesting ids that way is wasteful when the + user just wants to bulk-delete or bulk-transcribe everything that + matches the current filters. This endpoint applies the same ``q`` + and ``diarised_status`` filters and returns only the ids. +mdPath: "/api-md/call-imports/listCallImportRowIds.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportSchemas.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportSchemas.mdx new file mode 100644 index 00000000..7ad3996e --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportSchemas.mdx @@ -0,0 +1,33 @@ +--- +title: List Call Import Schemas +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + List schemas in the active workspace (alphabetical by name). + + Each entry includes ``usage_count`` so the UI can warn the user + before deleting a schema that batches are still pinned to. +mdPath: "/api-md/call-imports/listCallImportSchemas.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportTags.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportTags.mdx new file mode 100644 index 00000000..e1a4b79f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/listCallImportTags.mdx @@ -0,0 +1,29 @@ +--- +title: List Call Import Tags +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: List every tag defined for this organization (alphabetical by name). +mdPath: "/api-md/call-imports/listCallImportTags.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/listCallImports.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/listCallImports.mdx new file mode 100644 index 00000000..602eb605 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/listCallImports.mdx @@ -0,0 +1,36 @@ +--- +title: List Call Imports +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + List call-import batches for the active workspace, newest first. + + Scoped to (organization_id, workspace_id) so users only see imports + for the workspace they're currently in. Supports a high-level + ``dataset`` filter (powers the segregation dropdown at the top of + the imports page) plus an AND-style multi-tag filter via repeated + ``tag_id`` parameters. +mdPath: "/api-md/call-imports/listCallImports.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/previewCallImportFile.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/previewCallImportFile.mdx new file mode 100644 index 00000000..02770bca --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/previewCallImportFile.mdx @@ -0,0 +1,36 @@ +--- +title: Preview Call Import File +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Inspect an uploaded CSV / Excel file and return its sheets + headers. + + Drives the column-mapping UI without forcing the frontend to parse + CSV / xlsx itself โ€” keeps client and server in lockstep on quoted + fields, encodings, and Excel cell coercion. CSVs return a single + synthetic sheet named after the filename; Excel workbooks return one + entry per worksheet (in workbook order). +mdPath: "/api-md/call-imports/previewCallImportFile.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/retryFailedCallImportRows.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/retryFailedCallImportRows.mdx new file mode 100644 index 00000000..b87f60f4 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/retryFailedCallImportRows.mdx @@ -0,0 +1,46 @@ +--- +title: Retry Failed Call Import Rows +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Re-enqueue every failed import row in this batch. + + + Useful when transient provider issues are resolved and the operator + wants + + a one-click "try failed downloads again" pass without re-uploading the + CSV. + + + Pass ``provider`` + ``telephony_integration_id`` (or both omitted for + + direct-URL retry) to change how recordings are fetched on this pass. + + When the body is omitted entirely, the batch keeps its existing pinned + + credentials. +mdPath: "/api-md/call-imports/retryFailedCallImportRows.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/startCallImport.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/startCallImport.mdx new file mode 100644 index 00000000..9ccd01fd --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/startCallImport.mdx @@ -0,0 +1,34 @@ +--- +title: Start Call Import +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Deprecated IMPORT stage โ€” use Run Evaluation for new batches. + + Recording fetch is part of the unified evaluation pipeline. This + endpoint remains available only with ``?legacy=true`` for backward + compatibility. +mdPath: "/api-md/call-imports/startCallImport.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/toggleCallImportRowSpeakerSwap.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/toggleCallImportRowSpeakerSwap.mdx new file mode 100644 index 00000000..6ef1d979 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/toggleCallImportRowSpeakerSwap.mdx @@ -0,0 +1,43 @@ +--- +title: Toggle Call Import Row Speaker Swap +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Flip the user <-> agent mapping on a diarised row. + + The worker's "first speaker is the agent" heuristic is right most of + the time but does fail on inbound recordings where the customer + greets first, on recordings where the agent stays silent for the + intro, etc. Rather than rerun the (expensive) STT + pyannote + pipeline for those cases, we let reviewers flip the mapping in + place: the structured ``diarised_segments`` are the source of truth + and we re-render the plain-text ``diarised_transcript`` from them + with the swap applied. The next CSV export will then show the + corrected labels. + + Returns the updated row so the frontend can refresh without an + extra round-trip. +mdPath: "/api-md/call-imports/toggleCallImportRowSpeakerSwap.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/transcribeCallImport.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/transcribeCallImport.mdx new file mode 100644 index 00000000..77b3bde6 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/transcribeCallImport.mdx @@ -0,0 +1,35 @@ +--- +title: Transcribe Call Import +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Fan out diarization tasks for many rows in a single call. + + Returns a summary with how many rows were queued and how many were + skipped (broken down by reason) so the UI can show a meaningful + toast even when nothing actually got enqueued (e.g. "All 12 rows + already have transcripts"). +mdPath: "/api-md/call-imports/transcribeCallImport.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/transcribeCallImportRow.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/transcribeCallImportRow.mdx new file mode 100644 index 00000000..4514b6ac --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/transcribeCallImportRow.mdx @@ -0,0 +1,34 @@ +--- +title: Transcribe Call Import Row +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Diarize / transcribe a single row. + + Thin wrapper over the batch endpoint that hard-codes a single + ``row_ids`` filter. Skip counts still surface so the UI can render + "Skipped โ€” transcript present" diagnostics consistently. +mdPath: "/api-md/call-imports/transcribeCallImportRow.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImport.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImport.mdx new file mode 100644 index 00000000..b43f102d --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImport.mdx @@ -0,0 +1,38 @@ +--- +title: Update Call Import +full: true +_openapi: + preload: + - efficientai + method: PATCH + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Edit dataset / tag assignments (and schema, pre-import) on a batch. + + ``dataset = ""`` clears the label; ``tag_ids = []`` removes all tag + assignments. Fields omitted from the body are left untouched. + + ``schema_id`` is only honoured while the batch is in + ``uploaded`` / ``mapped`` state โ€” once rows have been materialised + the schema is locked. Changing the schema resets any persisted + mapping (the user must re-MAP) and rewinds status to ``uploaded``. +mdPath: "/api-md/call-imports/updateCallImport.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImportMapping.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImportMapping.mdx new file mode 100644 index 00000000..f0e96ed4 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImportMapping.mdx @@ -0,0 +1,35 @@ +--- +title: Update Call Import Mapping +full: true +_openapi: + preload: + - efficientai + method: PATCH + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + MAP stage of the staged call-import flow. + + Validates ``parameter_mapping`` + ``skipped_columns`` against the + sheet headers captured at UPLOAD time and persists them on the + batch. Idempotent: callers may submit this multiple times while + the batch is in ``uploaded`` or ``mapped`` state. +mdPath: "/api-md/call-imports/updateCallImportMapping.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImportSchema.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImportSchema.mdx new file mode 100644 index 00000000..ffbfed8d --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImportSchema.mdx @@ -0,0 +1,37 @@ +--- +title: Update Call Import Schema +full: true +_openapi: + preload: + - efficientai + method: PATCH + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Update a schema's metadata and/or replace its parameter list. + + When ``parameters`` is included in the body, the new list FULLY + REPLACES the existing parameters (delete-then-insert in one + transaction). Existing CallImport batches that reference this + schema keep their snapshotted ``parameter_mapping`` unchanged - we + don't try to retro-validate historical mappings against the new + schema shape. +mdPath: "/api-md/call-imports/updateCallImportSchema.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImportTag.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImportTag.mdx new file mode 100644 index 00000000..d130775c --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/updateCallImportTag.mdx @@ -0,0 +1,29 @@ +--- +title: Update Call Import Tag +full: true +_openapi: + preload: + - efficientai + method: PATCH + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Rename or recolor an existing tag. +mdPath: "/api-md/call-imports/updateCallImportTag.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/uploadCallImportAudio.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/uploadCallImportAudio.mdx new file mode 100644 index 00000000..8ef54911 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/uploadCallImportAudio.mdx @@ -0,0 +1,40 @@ +--- +title: Upload Call Import Audio +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Persist manually uploaded recordings as completed CallImport rows. + + + The rows skip the provider-download worker entirely because the audio + + bytes are already in hand. From this point onward they behave exactly + + like completed CSV-import rows: playback reads ``recording_s3_key`` + and + + the existing diarisation/evaluation endpoints can operate on them. +mdPath: "/api-md/call-imports/uploadCallImportAudio.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/call-imports/uploadCallImportCsv.mdx b/docs-fumadocs/content/docs/api-reference/call-imports/uploadCallImportCsv.mdx new file mode 100644 index 00000000..20af7c27 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/call-imports/uploadCallImportCsv.mdx @@ -0,0 +1,37 @@ +--- +title: Upload Call Import Csv +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + deprecated: true + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Legacy one-shot upload kept for backward compatibility. + + DEPRECATED: prefer the staged flow + (``POST /`` โ†’ ``PATCH /{id}/mapping`` โ†’ ``POST /{id}/import``) so + each step is idempotent and resumable. This endpoint runs all three + stages inline in a single transaction so existing scripts / + integrations keep working unchanged. +mdPath: "/api-md/call-imports/uploadCallImportCsv.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/errors.mdx b/docs-fumadocs/content/docs/api-reference/errors.mdx new file mode 100644 index 00000000..6639c727 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/errors.mdx @@ -0,0 +1,37 @@ +--- +title: Error Model +description: Common HTTP status and error envelope conventions in EfficientAI APIs. +--- + +# Error Model + +EfficientAI endpoints return standard HTTP status codes and JSON error payloads. + +## Common status codes + +- `400` invalid request payload or unsupported parameter. +- `401` invalid or missing authentication credentials. +- `403` authenticated but not authorized for the requested scope. +- `404` resource does not exist in the current workspace context. +- `409` conflict state (duplicate or invalid transition). +- `422` validation errors (schema or business-rule failures). +- `500` unexpected server-side failure. + +## Typical error payload + +Most route handlers return an HTTP exception style envelope with a `detail` field: + +```json +{ + "detail": "Human-readable error message" +} +``` + +Some endpoints can return richer validation payloads (for example `422` with field-level details). + +## Troubleshooting checklist + +- Verify `Authorization` or `X-API-Key` is present. +- Confirm `X-Workspace-Id` matches an accessible workspace when supplied. +- Ensure request body fields and enum values match the schema shown on each endpoint page. +- Retry idempotent operations only after transient `5xx` failures. diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/cancelEvaluatorResultMetricClusters.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/cancelEvaluatorResultMetricClusters.mdx new file mode 100644 index 00000000..108cb625 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/cancelEvaluatorResultMetricClusters.mdx @@ -0,0 +1,28 @@ +--- +title: Cancel Evaluator Result Metric Clusters +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-results/cancelEvaluatorResultMetricClusters.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/create_evaluator_result_manual_api_v1_evaluator_results_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/create_evaluator_result_manual_api_v1_evaluator_results_post.mdx new file mode 100644 index 00000000..9fb26f30 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/create_evaluator_result_manual_api_v1_evaluator_results_post.mdx @@ -0,0 +1,34 @@ +--- +title: Create Evaluator Result Manual +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Manually create an evaluator result in the active workspace from an + existing audio file. + + + The referenced evaluator must already belong to the active workspace. +mdPath: "/api-md/evaluator-results/create_evaluator_result_manual_api_v1_evaluator_results_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/deleteEvaluatorResultMetricClusters.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/deleteEvaluatorResultMetricClusters.mdx new file mode 100644 index 00000000..1e920558 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/deleteEvaluatorResultMetricClusters.mdx @@ -0,0 +1,28 @@ +--- +title: Delete Evaluator Result Metric Clusters +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-results/deleteEvaluatorResultMetricClusters.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/delete_evaluator_result_api_v1_evaluator_results__id__delete.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/delete_evaluator_result_api_v1_evaluator_results__id__delete.mdx new file mode 100644 index 00000000..33cda1c3 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/delete_evaluator_result_api_v1_evaluator_results__id__delete.mdx @@ -0,0 +1,30 @@ +--- +title: Delete Evaluator Result +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete a specific evaluator result in the active workspace by UUID or + result_id. +mdPath: "/api-md/evaluator-results/delete_evaluator_result_api_v1_evaluator_results__id__delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/delete_evaluator_results_bulk_api_v1_evaluator_results_delete.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/delete_evaluator_results_bulk_api_v1_evaluator_results_delete.mdx new file mode 100644 index 00000000..f29f186f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/delete_evaluator_results_bulk_api_v1_evaluator_results_delete.mdx @@ -0,0 +1,29 @@ +--- +title: Delete Evaluator Results Bulk +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete multiple evaluator results in the active workspace by their IDs. +mdPath: "/api-md/evaluator-results/delete_evaluator_results_bulk_api_v1_evaluator_results_delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/generateEvaluatorResultMetricClusters.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/generateEvaluatorResultMetricClusters.mdx new file mode 100644 index 00000000..d1fce1cf --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/generateEvaluatorResultMetricClusters.mdx @@ -0,0 +1,28 @@ +--- +title: Generate Evaluator Result Metric Clusters +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-results/generateEvaluatorResultMetricClusters.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/getEvaluatorResultMetricClusterFailurePolicies.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/getEvaluatorResultMetricClusterFailurePolicies.mdx new file mode 100644 index 00000000..d5a0a66d --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/getEvaluatorResultMetricClusterFailurePolicies.mdx @@ -0,0 +1,28 @@ +--- +title: Get Evaluator Result Metric Cluster Failure Policies +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-results/getEvaluatorResultMetricClusterFailurePolicies.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/getEvaluatorResultMetricClusters.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/getEvaluatorResultMetricClusters.mdx new file mode 100644 index 00000000..cf1918fa --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/getEvaluatorResultMetricClusters.mdx @@ -0,0 +1,28 @@ +--- +title: Get Evaluator Result Metric Clusters +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-results/getEvaluatorResultMetricClusters.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_result_api_v1_evaluator_results__id__get.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_result_api_v1_evaluator_results__id__get.mdx new file mode 100644 index 00000000..3e32bb98 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_result_api_v1_evaluator_results__id__get.mdx @@ -0,0 +1,30 @@ +--- +title: Get Evaluator Result +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Get a specific evaluator result in the active workspace by UUID or + result_id (6-digit). +mdPath: "/api-md/evaluator-results/get_evaluator_result_api_v1_evaluator_results__id__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_result_metrics_api_v1_evaluator_results__id__metrics_get.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_result_metrics_api_v1_evaluator_results__id__metrics_get.mdx new file mode 100644 index 00000000..9d979fb9 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_result_metrics_api_v1_evaluator_results__id__metrics_get.mdx @@ -0,0 +1,29 @@ +--- +title: Get Evaluator Result Metrics +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Get metric scores for an evaluator result in the active workspace. +mdPath: "/api-md/evaluator-results/get_evaluator_result_metrics_api_v1_evaluator_results__id__metrics_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_results_aggregate_api_v1_evaluator_results_aggregate_get.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_results_aggregate_api_v1_evaluator_results_aggregate_get.mdx new file mode 100644 index 00000000..8d5ad5d0 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_results_aggregate_api_v1_evaluator_results_aggregate_get.mdx @@ -0,0 +1,29 @@ +--- +title: Get Evaluator Results Aggregate +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Metric distributions for completed evaluator results in a scope. +mdPath: "/api-md/evaluator-results/get_evaluator_results_aggregate_api_v1_evaluator_results_aggregate_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_results_overview_api_v1_evaluator_results_overview_get.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_results_overview_api_v1_evaluator_results_overview_get.mdx new file mode 100644 index 00000000..7184c232 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/get_evaluator_results_overview_api_v1_evaluator_results_overview_get.mdx @@ -0,0 +1,29 @@ +--- +title: Get Evaluator Results Overview +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Workspace rollups for agent โ†’ suite โ†’ scenario navigation. +mdPath: "/api-md/evaluator-results/get_evaluator_results_overview_api_v1_evaluator_results_overview_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/listEvaluatorResultMetricClusterEligibleRows.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/listEvaluatorResultMetricClusterEligibleRows.mdx new file mode 100644 index 00000000..6772014b --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/listEvaluatorResultMetricClusterEligibleRows.mdx @@ -0,0 +1,28 @@ +--- +title: List Evaluator Result Metric Cluster Eligible Rows +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-results/listEvaluatorResultMetricClusterEligibleRows.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/listEvaluatorResultMetricClusterScopes.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/listEvaluatorResultMetricClusterScopes.mdx new file mode 100644 index 00000000..79eaafd0 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/listEvaluatorResultMetricClusterScopes.mdx @@ -0,0 +1,28 @@ +--- +title: List Evaluator Result Metric Cluster Scopes +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-results/listEvaluatorResultMetricClusterScopes.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/list_evaluator_results_api_v1_evaluator_results_get.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/list_evaluator_results_api_v1_evaluator_results_get.mdx new file mode 100644 index 00000000..9d974118 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/list_evaluator_results_api_v1_evaluator_results_get.mdx @@ -0,0 +1,40 @@ +--- +title: List Evaluator Results +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + List evaluator results within the active workspace. + + + By default, excludes playground test results (where evaluator_id is + NULL). + + Use playground=true to get only playground results, or + playground=false to explicitly exclude them. + + Use test_agents_only=true to filter out Voice AI Agent results (those + with provider_platform set). +mdPath: "/api-md/evaluator-results/list_evaluator_results_api_v1_evaluator_results_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/re_evaluate_result_api_v1_evaluator_results__id__re_evaluate_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/re_evaluate_result_api_v1_evaluator_results__id__re_evaluate_post.mdx new file mode 100644 index 00000000..a8c1fa58 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/re_evaluate_result_api_v1_evaluator_results__id__re_evaluate_post.mdx @@ -0,0 +1,43 @@ +--- +title: Re Evaluate Result +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Re-evaluate an existing evaluator result. + + + If the result already has audio in S3, reuses it. Otherwise attempts + to + + download the recording from the voice provider (ElevenLabs / Retell / + Vapi), + + uploads it to S3, and stores the key so that audio-dependent quality + + metrics (pitch, jitter, MOS, emotion, etc.) can run alongside the + + LLM-based transcript metrics. +mdPath: "/api-md/evaluator-results/re_evaluate_result_api_v1_evaluator_results__id__re_evaluate_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/saveEvaluatorResultMetricClusterFailurePolicies.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/saveEvaluatorResultMetricClusterFailurePolicies.mdx new file mode 100644 index 00000000..b5263334 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/saveEvaluatorResultMetricClusterFailurePolicies.mdx @@ -0,0 +1,28 @@ +--- +title: Save Evaluator Result Metric Cluster Failure Policies +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-results/saveEvaluatorResultMetricClusterFailurePolicies.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/stream_evaluator_result_audio_api_v1_evaluator_results__id__audio_get.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/stream_evaluator_result_audio_api_v1_evaluator_results__id__audio_get.mdx new file mode 100644 index 00000000..9ae34b26 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/stream_evaluator_result_audio_api_v1_evaluator_results__id__audio_get.mdx @@ -0,0 +1,30 @@ +--- +title: Stream Evaluator Result Audio +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Stream evaluator result audio from S3 or proxy auth-gated provider + URLs. +mdPath: "/api-md/evaluator-results/stream_evaluator_result_audio_api_v1_evaluator_results__id__audio_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-results/stream_evaluator_result_live_events_api_v1_evaluator_results__id__live_events_get.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-results/stream_evaluator_result_live_events_api_v1_evaluator_results__id__live_events_get.mdx new file mode 100644 index 00000000..6b53817f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-results/stream_evaluator_result_live_events_api_v1_evaluator_results__id__live_events_get.mdx @@ -0,0 +1,30 @@ +--- +title: Stream Evaluator Result Live Events +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: SSE stream of live transcript turns for an in-progress eval telephony + call. +mdPath: "/api-md/evaluator-results/stream_evaluator_result_live_events_api_v1_evaluator_results__id__live_events_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/activate_suite_api_v1_evaluator_suites__suite_id__activate_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/activate_suite_api_v1_evaluator_suites__suite_id__activate_post.mdx new file mode 100644 index 00000000..2c6e1803 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/activate_suite_api_v1_evaluator_suites__suite_id__activate_post.mdx @@ -0,0 +1,29 @@ +--- +title: Activate Suite +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Set this suite as the active inbound configuration for its agent. +mdPath: "/api-md/evaluator-suites/activate_suite_api_v1_evaluator_suites__suite_id__activate_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/add_personas_api_v1_evaluator_suites__suite_id__personas_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/add_personas_api_v1_evaluator_suites__suite_id__personas_post.mdx new file mode 100644 index 00000000..e15f21be --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/add_personas_api_v1_evaluator_suites__suite_id__personas_post.mdx @@ -0,0 +1,28 @@ +--- +title: Add Personas +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/add_personas_api_v1_evaluator_suites__suite_id__personas_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/add_scenarios_api_v1_evaluator_suites__suite_id__scenarios_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/add_scenarios_api_v1_evaluator_suites__suite_id__scenarios_post.mdx new file mode 100644 index 00000000..8d9ddd5f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/add_scenarios_api_v1_evaluator_suites__suite_id__scenarios_post.mdx @@ -0,0 +1,28 @@ +--- +title: Add Scenarios +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/add_scenarios_api_v1_evaluator_suites__suite_id__scenarios_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/choose_next_combination_api_v1_evaluator_suites__suite_id__choose_next_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/choose_next_combination_api_v1_evaluator_suites__suite_id__choose_next_post.mdx new file mode 100644 index 00000000..6f8f27b7 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/choose_next_combination_api_v1_evaluator_suites__suite_id__choose_next_post.mdx @@ -0,0 +1,30 @@ +--- +title: Choose Next Combination +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Advance inbound round-robin to the next scenario without placing a + call. +mdPath: "/api-md/evaluator-suites/choose_next_combination_api_v1_evaluator_suites__suite_id__choose_next_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/create_suite_api_v1_evaluator_suites_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/create_suite_api_v1_evaluator_suites_post.mdx new file mode 100644 index 00000000..839ec509 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/create_suite_api_v1_evaluator_suites_post.mdx @@ -0,0 +1,28 @@ +--- +title: Create Suite +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/create_suite_api_v1_evaluator_suites_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/delete_suite_api_v1_evaluator_suites__suite_id__delete.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/delete_suite_api_v1_evaluator_suites__suite_id__delete.mdx new file mode 100644 index 00000000..2c542afe --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/delete_suite_api_v1_evaluator_suites__suite_id__delete.mdx @@ -0,0 +1,28 @@ +--- +title: Delete Suite +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/delete_suite_api_v1_evaluator_suites__suite_id__delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/get_suite_api_v1_evaluator_suites__suite_id__get.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/get_suite_api_v1_evaluator_suites__suite_id__get.mdx new file mode 100644 index 00000000..cf5bbb92 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/get_suite_api_v1_evaluator_suites__suite_id__get.mdx @@ -0,0 +1,28 @@ +--- +title: Get Suite +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/get_suite_api_v1_evaluator_suites__suite_id__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/list_suites_api_v1_evaluator_suites_get.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/list_suites_api_v1_evaluator_suites_get.mdx new file mode 100644 index 00000000..8a1f5e33 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/list_suites_api_v1_evaluator_suites_get.mdx @@ -0,0 +1,28 @@ +--- +title: List Suites +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/list_suites_api_v1_evaluator_suites_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/remove_persona_api_v1_evaluator_suites__suite_id__personas__persona_id__delete.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/remove_persona_api_v1_evaluator_suites__suite_id__personas__persona_id__delete.mdx new file mode 100644 index 00000000..0c8ea1cf --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/remove_persona_api_v1_evaluator_suites__suite_id__personas__persona_id__delete.mdx @@ -0,0 +1,28 @@ +--- +title: Remove Persona +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/remove_persona_api_v1_evaluator_suites__suite_id__personas__persona_id__delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/remove_scenario_api_v1_evaluator_suites__suite_id__scenarios__scenario_id__delete.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/remove_scenario_api_v1_evaluator_suites__suite_id__scenarios__scenario_id__delete.mdx new file mode 100644 index 00000000..0eeaa01e --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/remove_scenario_api_v1_evaluator_suites__suite_id__scenarios__scenario_id__delete.mdx @@ -0,0 +1,28 @@ +--- +title: Remove Scenario +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/remove_scenario_api_v1_evaluator_suites__suite_id__scenarios__scenario_id__delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/replace_personas_api_v1_evaluator_suites__suite_id__personas_put.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/replace_personas_api_v1_evaluator_suites__suite_id__personas_put.mdx new file mode 100644 index 00000000..d5ab65fe --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/replace_personas_api_v1_evaluator_suites__suite_id__personas_put.mdx @@ -0,0 +1,28 @@ +--- +title: Replace Personas +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/replace_personas_api_v1_evaluator_suites__suite_id__personas_put.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/run_next_combination_api_v1_evaluator_suites__suite_id__run_next_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/run_next_combination_api_v1_evaluator_suites__suite_id__run_next_post.mdx new file mode 100644 index 00000000..50ef94bd --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/run_next_combination_api_v1_evaluator_suites__suite_id__run_next_post.mdx @@ -0,0 +1,28 @@ +--- +title: Run Next Combination +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/run_next_combination_api_v1_evaluator_suites__suite_id__run_next_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/run_suite_api_v1_evaluator_suites__suite_id__run_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/run_suite_api_v1_evaluator_suites__suite_id__run_post.mdx new file mode 100644 index 00000000..153be22d --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/run_suite_api_v1_evaluator_suites__suite_id__run_post.mdx @@ -0,0 +1,28 @@ +--- +title: Run Suite +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/run_suite_api_v1_evaluator_suites__suite_id__run_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluator-suites/update_suite_api_v1_evaluator_suites__suite_id__put.mdx b/docs-fumadocs/content/docs/api-reference/evaluator-suites/update_suite_api_v1_evaluator_suites__suite_id__put.mdx new file mode 100644 index 00000000..bd334fce --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluator-suites/update_suite_api_v1_evaluator_suites__suite_id__put.mdx @@ -0,0 +1,28 @@ +--- +title: Update Suite +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/evaluator-suites/update_suite_api_v1_evaluator_suites__suite_id__put.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluators/create_evaluator_api_v1_evaluators_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluators/create_evaluator_api_v1_evaluators_post.mdx new file mode 100644 index 00000000..67351895 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluators/create_evaluator_api_v1_evaluators_post.mdx @@ -0,0 +1,30 @@ +--- +title: Create Evaluator +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Create a single standard evaluator (legacy). Use POST /evaluator-suites + for new setups. +mdPath: "/api-md/evaluators/create_evaluator_api_v1_evaluators_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluators/create_evaluators_bulk_api_v1_evaluators_bulk_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluators/create_evaluators_bulk_api_v1_evaluators_bulk_post.mdx new file mode 100644 index 00000000..e055f23c --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluators/create_evaluators_bulk_api_v1_evaluators_bulk_post.mdx @@ -0,0 +1,31 @@ +--- +title: Create Evaluators Bulk +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + deprecated: true + toc: [] + structuredData: + headings: [] + contents: + - content: Create multiple evaluators in the active workspace for the same + agent/scenario. +mdPath: "/api-md/evaluators/create_evaluators_bulk_api_v1_evaluators_bulk_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluators/delete_evaluator_api_v1_evaluators__evaluator_id__delete.mdx b/docs-fumadocs/content/docs/api-reference/evaluators/delete_evaluator_api_v1_evaluators__evaluator_id__delete.mdx new file mode 100644 index 00000000..aefc620c --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluators/delete_evaluator_api_v1_evaluators__evaluator_id__delete.mdx @@ -0,0 +1,30 @@ +--- +title: Delete Evaluator +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete an evaluator in the active workspace while preserving dependent + results. +mdPath: "/api-md/evaluators/delete_evaluator_api_v1_evaluators__evaluator_id__delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluators/format_custom_prompt_api_v1_evaluators_format_prompt_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluators/format_custom_prompt_api_v1_evaluators_format_prompt_post.mdx new file mode 100644 index 00000000..a9af6291 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluators/format_custom_prompt_api_v1_evaluators_format_prompt_post.mdx @@ -0,0 +1,30 @@ +--- +title: Format Custom Prompt +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Reformat a raw custom prompt into well-structured markdown using the + org's LLM. +mdPath: "/api-md/evaluators/format_custom_prompt_api_v1_evaluators_format_prompt_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluators/get_evaluator_api_v1_evaluators__evaluator_id__get.mdx b/docs-fumadocs/content/docs/api-reference/evaluators/get_evaluator_api_v1_evaluators__evaluator_id__get.mdx new file mode 100644 index 00000000..35f86278 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluators/get_evaluator_api_v1_evaluators__evaluator_id__get.mdx @@ -0,0 +1,30 @@ +--- +title: Get Evaluator +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Get an evaluator in the active workspace by UUID or evaluator_id + (6-digit). +mdPath: "/api-md/evaluators/get_evaluator_api_v1_evaluators__evaluator_id__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluators/list_evaluators_api_v1_evaluators_get.mdx b/docs-fumadocs/content/docs/api-reference/evaluators/list_evaluators_api_v1_evaluators_get.mdx new file mode 100644 index 00000000..647a4531 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluators/list_evaluators_api_v1_evaluators_get.mdx @@ -0,0 +1,29 @@ +--- +title: List Evaluators +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: List evaluators in the active workspace. +mdPath: "/api-md/evaluators/list_evaluators_api_v1_evaluators_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluators/run_evaluators_api_v1_evaluators_run_post.mdx b/docs-fumadocs/content/docs/api-reference/evaluators/run_evaluators_api_v1_evaluators_run_post.mdx new file mode 100644 index 00000000..8a4c3e9d --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluators/run_evaluators_api_v1_evaluators_run_post.mdx @@ -0,0 +1,30 @@ +--- +title: Run Evaluators +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Run multiple evaluators in the active workspace in parallel using + Celery workers. +mdPath: "/api-md/evaluators/run_evaluators_api_v1_evaluators_run_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/evaluators/update_evaluator_api_v1_evaluators__evaluator_id__put.mdx b/docs-fumadocs/content/docs/api-reference/evaluators/update_evaluator_api_v1_evaluators__evaluator_id__put.mdx new file mode 100644 index 00000000..60b5eb61 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/evaluators/update_evaluator_api_v1_evaluators__evaluator_id__put.mdx @@ -0,0 +1,29 @@ +--- +title: Update Evaluator +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Update an evaluator within the active workspace. +mdPath: "/api-md/evaluators/update_evaluator_api_v1_evaluators__evaluator_id__put.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/index.mdx b/docs-fumadocs/content/docs/api-reference/index.mdx new file mode 100644 index 00000000..4ce3b97a --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/index.mdx @@ -0,0 +1,41 @@ +--- +title: API Reference +description: REST API reference for EfficientAI platform integrations. +--- + +# API Reference + +This section documents the public EfficientAI platform API surface under `/api/v1/`. + +## Base URL + +- Self-hosted default: `http://localhost:8000` +- Runtime override: set `DOCS_API_URL` while generating docs. + +## Authentication + +Most endpoints accept either: + +- `Authorization: Bearer ` +- `X-API-Key: ` + +Optional workspace scoping header: + +- `X-Workspace-Id: ` + +See [Authentication Guide](/docs/api-reference/authentication/). + +## Versioning + +All documented REST endpoints are versioned under `/api/v1/`. + +## Endpoint groups + +Use the left sidebar to browse generated operation pages by functional area: + +- Agents, Personas, Scenarios +- Evaluators, Suites, Metrics, Results +- Integrations, Voice Bundles, AI Providers +- Observability, Call Imports, Workspaces + +See [Error Model](/docs/api-reference/errors/) for error envelope conventions. diff --git a/docs-fumadocs/content/docs/api-reference/integrations/createIntegration.mdx b/docs-fumadocs/content/docs/api-reference/integrations/createIntegration.mdx new file mode 100644 index 00000000..24fbe75a --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/integrations/createIntegration.mdx @@ -0,0 +1,46 @@ +--- +title: Create Integration +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Create a new credential row for a voice AI platform. + + + Multiple credentials per platform are now supported. The first row + + created for a given (org, platform) automatically becomes the + + default; subsequent rows can be promoted via + + ``POST /integrations/{id}/set-default``. + ``integration_data.is_default`` + + can also be set explicitly to mark the new row as the default at + + creation time. + + Requires at least WRITER role. +mdPath: "/api-md/integrations/createIntegration.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/integrations/deleteIntegration.mdx b/docs-fumadocs/content/docs/api-reference/integrations/deleteIntegration.mdx new file mode 100644 index 00000000..04eabf68 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/integrations/deleteIntegration.mdx @@ -0,0 +1,33 @@ +--- +title: Delete Integration +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Delete an integration. Returns 409 if agents are using it unless + force=true. + + Requires at least WRITER role. +mdPath: "/api-md/integrations/deleteIntegration.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/integrations/get_integration_api_key_api_v1_integrations__integration_id__api_key_get.mdx b/docs-fumadocs/content/docs/api-reference/integrations/get_integration_api_key_api_v1_integrations__integration_id__api_key_get.mdx new file mode 100644 index 00000000..89535256 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/integrations/get_integration_api_key_api_v1_integrations__integration_id__api_key_get.mdx @@ -0,0 +1,32 @@ +--- +title: Get Integration Api Key +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Get the decrypted API key for an integration. + This endpoint is used for client-side operations like web calls. + Requires at least READER role. +mdPath: "/api-md/integrations/get_integration_api_key_api_v1_integrations__integration_id__api_key_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/integrations/get_integration_api_v1_integrations__integration_id__get.mdx b/docs-fumadocs/content/docs/api-reference/integrations/get_integration_api_v1_integrations__integration_id__get.mdx new file mode 100644 index 00000000..9f33a614 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/integrations/get_integration_api_v1_integrations__integration_id__get.mdx @@ -0,0 +1,31 @@ +--- +title: Get Integration +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Get a specific integration. + Requires at least READER role. +mdPath: "/api-md/integrations/get_integration_api_v1_integrations__integration_id__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/integrations/listIntegrations.mdx b/docs-fumadocs/content/docs/api-reference/integrations/listIntegrations.mdx new file mode 100644 index 00000000..49beac75 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/integrations/listIntegrations.mdx @@ -0,0 +1,31 @@ +--- +title: List Integrations +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + List all integrations for the organization. + Requires at least READER role. +mdPath: "/api-md/integrations/listIntegrations.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/integrations/previewIntegrationAgentPrompt.mdx b/docs-fumadocs/content/docs/api-reference/integrations/previewIntegrationAgentPrompt.mdx new file mode 100644 index 00000000..d6cbae28 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/integrations/previewIntegrationAgentPrompt.mdx @@ -0,0 +1,29 @@ +--- +title: Preview Integration Agent Prompt +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Fetch a provider agent prompt before an EfficientAI agent exists. +mdPath: "/api-md/integrations/previewIntegrationAgentPrompt.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/integrations/setDefaultIntegration.mdx b/docs-fumadocs/content/docs/api-reference/integrations/setDefaultIntegration.mdx new file mode 100644 index 00000000..58f9b15c --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/integrations/setDefaultIntegration.mdx @@ -0,0 +1,33 @@ +--- +title: Set Default Integration +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Mark this integration as the default for its (org, platform). + + Atomically clears the default flag on every other row for the same + (org, platform) so the partial unique index in migration 028 holds. +mdPath: "/api-md/integrations/setDefaultIntegration.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/integrations/updateIntegration.mdx b/docs-fumadocs/content/docs/api-reference/integrations/updateIntegration.mdx new file mode 100644 index 00000000..6652555e --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/integrations/updateIntegration.mdx @@ -0,0 +1,31 @@ +--- +title: Update Integration +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Update an integration. + Requires at least WRITER role. +mdPath: "/api-md/integrations/updateIntegration.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/meta.json b/docs-fumadocs/content/docs/api-reference/meta.json new file mode 100644 index 00000000..4012565c --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/meta.json @@ -0,0 +1,21 @@ +{ + "pages": [ + "index", + "authentication", + "agents", + "personas", + "scenarios", + "integrations", + "voice-bundles", + "ai-providers", + "evaluators", + "evaluator-suites", + "metrics", + "evaluator-results", + "observability", + "call-imports", + "workspaces", + "errors" + ], + "title": "API Reference" +} diff --git a/docs-fumadocs/content/docs/api-reference/metrics/addMetricChild.mdx b/docs-fumadocs/content/docs/api-reference/metrics/addMetricChild.mdx new file mode 100644 index 00000000..5b5ca965 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/addMetricChild.mdx @@ -0,0 +1,29 @@ +--- +title: Add Metric Child +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Append a new child sub-metric under an existing parent. +mdPath: "/api-md/metrics/addMetricChild.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/createMetricDraft.mdx b/docs-fumadocs/content/docs/api-reference/metrics/createMetricDraft.mdx new file mode 100644 index 00000000..ae5fbb21 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/createMetricDraft.mdx @@ -0,0 +1,30 @@ +--- +title: Create Metric Draft +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Create a draft metric for Metrics Studio (hidden from production + flows). +mdPath: "/api-md/metrics/createMetricDraft.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/createMetricDraftWithChildren.mdx b/docs-fumadocs/content/docs/api-reference/metrics/createMetricDraftWithChildren.mdx new file mode 100644 index 00000000..b9ea0261 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/createMetricDraftWithChildren.mdx @@ -0,0 +1,29 @@ +--- +title: Create Metric Draft With Children +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Atomically create a draft parent category metric plus its children. +mdPath: "/api-md/metrics/createMetricDraftWithChildren.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/createMetricWithChildren.mdx b/docs-fumadocs/content/docs/api-reference/metrics/createMetricWithChildren.mdx new file mode 100644 index 00000000..5fb2c670 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/createMetricWithChildren.mdx @@ -0,0 +1,38 @@ +--- +title: Create Metric With Children +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Atomically create a parent category metric plus its children. + + The parent gets ``metric_type=text`` (it's a category label, not a + score) and ``selection_mode`` from the payload. Every child is + forced to ``boolean`` so the LLM-evaluation path treats them as + yes/no labels. Both the parent and all children are stamped with + the same scope: either the active workspace (``scope="workspace"``, + default) or ``workspace_id=NULL`` (``scope="organization"``, the + org-shared shape). +mdPath: "/api-md/metrics/createMetricWithChildren.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/create_metric_api_v1_metrics_post.mdx b/docs-fumadocs/content/docs/api-reference/metrics/create_metric_api_v1_metrics_post.mdx new file mode 100644 index 00000000..bc07dfa8 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/create_metric_api_v1_metrics_post.mdx @@ -0,0 +1,47 @@ +--- +title: Create Metric +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Create a new metric. + + Supports flat metrics, parent "category" metrics (set + ``selection_mode``), and child sub-metrics (set + ``parent_metric_id``). Name uniqueness is scoped to + ``(organization_id, workspace_id, parent_metric_id)`` so the same + label can exist in multiple workspaces (and under multiple parents). + + Scope: + * ``scope="workspace"`` (default) stamps the metric with the + active ``X-Workspace-Id`` (existing behavior). + * ``scope="organization"`` stamps ``workspace_id=NULL`` so the + metric appears in every workspace of the caller's org. + + Children always inherit their parent's scope (workspace UUID or + NULL) - we override the request's workspace + scope when + ``parent_metric_id`` is set so a stale UI can't accidentally split + a tree across workspaces or scopes. +mdPath: "/api-md/metrics/create_metric_api_v1_metrics_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/delete_metric_api_v1_metrics__metric_id__delete.mdx b/docs-fumadocs/content/docs/api-reference/metrics/delete_metric_api_v1_metrics__metric_id__delete.mdx new file mode 100644 index 00000000..e028200a --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/delete_metric_api_v1_metrics__metric_id__delete.mdx @@ -0,0 +1,29 @@ +--- +title: Delete Metric +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete a metric. +mdPath: "/api-md/metrics/delete_metric_api_v1_metrics__metric_id__delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/generate_metric_api_v1_metrics_generate_post.mdx b/docs-fumadocs/content/docs/api-reference/metrics/generate_metric_api_v1_metrics_generate_post.mdx new file mode 100644 index 00000000..17c0d96d --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/generate_metric_api_v1_metrics_generate_post.mdx @@ -0,0 +1,29 @@ +--- +title: Generate Metric +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Use an LLM to suggest a metric definition. Does NOT persist anything. +mdPath: "/api-md/metrics/generate_metric_api_v1_metrics_generate_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/get_metric_api_v1_metrics__metric_id__get.mdx b/docs-fumadocs/content/docs/api-reference/metrics/get_metric_api_v1_metrics__metric_id__get.mdx new file mode 100644 index 00000000..210295b6 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/get_metric_api_v1_metrics__metric_id__get.mdx @@ -0,0 +1,29 @@ +--- +title: Get Metric +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Get a specific metric, with children inlined for parents. +mdPath: "/api-md/metrics/get_metric_api_v1_metrics__metric_id__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/list_metrics_api_v1_metrics_get.mdx b/docs-fumadocs/content/docs/api-reference/metrics/list_metrics_api_v1_metrics_get.mdx new file mode 100644 index 00000000..3b8584a9 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/list_metrics_api_v1_metrics_get.mdx @@ -0,0 +1,39 @@ +--- +title: List Metrics +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + List metrics with optional nesting for the parent/child hierarchy. + + Returns the union of: + * Metrics scoped to the active workspace (``workspace_id == ws``). + * Metrics shared at the org level (``workspace_id IS NULL``). + + This is what makes org-shared metrics appear inside every workspace + of the org without the user having to recreate them. Switching + workspace in the UI still narrows the workspace-scoped half; the + org-shared half is identical across workspaces. +mdPath: "/api-md/metrics/list_metrics_api_v1_metrics_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/parse_bulk_metric_api_v1_metrics_parse_bulk_post.mdx b/docs-fumadocs/content/docs/api-reference/metrics/parse_bulk_metric_api_v1_metrics_parse_bulk_post.mdx new file mode 100644 index 00000000..4aba688b --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/parse_bulk_metric_api_v1_metrics_parse_bulk_post.mdx @@ -0,0 +1,38 @@ +--- +title: Parse Bulk Metric +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Parse a multi-label rubric into a *list* of independent metric drafts. + + Each "Label #N" block becomes its own un-persisted draft metric the + user can edit (name, type, capture_rationale, ...) before POSTing to + ``/metrics`` individually. Defaults are chosen so the most common + case ("did happen?") is one click away: ``metric_type="boolean"`` + with ``capture_rationale=True``. + + The endpoint does NOT write to the database. +mdPath: "/api-md/metrics/parse_bulk_metric_api_v1_metrics_parse_bulk_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/promoteDiscoveredChild.mdx b/docs-fumadocs/content/docs/api-reference/metrics/promoteDiscoveredChild.mdx new file mode 100644 index 00000000..f527a519 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/promoteDiscoveredChild.mdx @@ -0,0 +1,39 @@ +--- +title: Promote Discovered Child +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Promote an LLM-discovered candidate label into a real child metric. + + Mirrors ``add_metric_child`` but: + * Works on any parent (single_choice OR multi_label) that has + ``allow_discovery=true``. + * The new child's name is normalized so that ``slug(name)`` equals + the supplied ``key``. This is critical โ€” without it, the + already-scored rows' ``sequence`` arrays would not resolve + against the promoted child once the candidate disappears from + ``discovered_labels``. +mdPath: "/api-md/metrics/promoteDiscoveredChild.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/promoteDiscoveredMetric.mdx b/docs-fumadocs/content/docs/api-reference/metrics/promoteDiscoveredMetric.mdx new file mode 100644 index 00000000..c970beba --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/promoteDiscoveredMetric.mdx @@ -0,0 +1,43 @@ +--- +title: Promote Discovered Metric +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Promote an LLM-discovered top-level metric into a real Metric row. + + Parallel to :func:`promote_discovered_child` but creates a + standalone metric (``parent_metric_id=None``) instead of a child. + The new metric's name is normalized so ``slug(name) == key`` โ€” + this keeps any already-scored rows that referenced the candidate + under the promoted slug resolvable without a backfill, and + prevents duplicate promotions from sneaking in under slightly + different casing. + + ``metric_type`` selects how future evaluation runs will score the + new metric: ``boolean`` / ``rating`` are scored standalone; + ``category`` creates a ``multi_label`` parent with no children + that the user can populate via the Metrics page. +mdPath: "/api-md/metrics/promoteDiscoveredMetric.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/promoteMetricDraft.mdx b/docs-fumadocs/content/docs/api-reference/metrics/promoteMetricDraft.mdx new file mode 100644 index 00000000..e260211f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/promoteMetricDraft.mdx @@ -0,0 +1,29 @@ +--- +title: Promote Metric Draft +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Promote a draft metric to active production use. +mdPath: "/api-md/metrics/promoteMetricDraft.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/seed_default_metrics_api_v1_metrics_seed_defaults_post.mdx b/docs-fumadocs/content/docs/api-reference/metrics/seed_default_metrics_api_v1_metrics_seed_defaults_post.mdx new file mode 100644 index 00000000..ecf9871a --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/seed_default_metrics_api_v1_metrics_seed_defaults_post.mdx @@ -0,0 +1,34 @@ +--- +title: Seed Default Metrics +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: |- + Seed default metrics for an organization (in the active workspace). + + Default metrics live in the workspace the caller is currently in; + this matches the rest of the metrics surface and lets a user seed + the same defaults independently per workspace if they want to. +mdPath: "/api-md/metrics/seed_default_metrics_api_v1_metrics_seed_defaults_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/metrics/update_metric_api_v1_metrics__metric_id__put.mdx b/docs-fumadocs/content/docs/api-reference/metrics/update_metric_api_v1_metrics__metric_id__put.mdx new file mode 100644 index 00000000..8dabd4eb --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/metrics/update_metric_api_v1_metrics__metric_id__put.mdx @@ -0,0 +1,29 @@ +--- +title: Update Metric +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Update a metric. +mdPath: "/api-md/metrics/update_metric_api_v1_metrics__metric_id__put.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/observability/delete_call_api_v1_observability_calls__call_short_id__delete.mdx b/docs-fumadocs/content/docs/api-reference/observability/delete_call_api_v1_observability_calls__call_short_id__delete.mdx new file mode 100644 index 00000000..22123b94 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/observability/delete_call_api_v1_observability_calls__call_short_id__delete.mdx @@ -0,0 +1,29 @@ +--- +title: Delete Call +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete a webhook ingested call recording in the active workspace. +mdPath: "/api-md/observability/delete_call_api_v1_observability_calls__call_short_id__delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/observability/evaluate_call_api_v1_observability_calls__call_short_id__evaluate_post.mdx b/docs-fumadocs/content/docs/api-reference/observability/evaluate_call_api_v1_observability_calls__call_short_id__evaluate_post.mdx new file mode 100644 index 00000000..ad5daafd --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/observability/evaluate_call_api_v1_observability_calls__call_short_id__evaluate_post.mdx @@ -0,0 +1,36 @@ +--- +title: Evaluate Call +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Trigger an LLM evaluation on an ingested call in the active workspace. + + + Both the call recording and the evaluator must already live in the + same + + workspace as the caller. +mdPath: "/api-md/observability/evaluate_call_api_v1_observability_calls__call_short_id__evaluate_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/observability/get_call_api_v1_observability_calls__call_short_id__get.mdx b/docs-fumadocs/content/docs/api-reference/observability/get_call_api_v1_observability_calls__call_short_id__get.mdx new file mode 100644 index 00000000..54a129d8 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/observability/get_call_api_v1_observability_calls__call_short_id__get.mdx @@ -0,0 +1,29 @@ +--- +title: Get Call +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Retrieve a specific call in the active workspace by its short ID. +mdPath: "/api-md/observability/get_call_api_v1_observability_calls__call_short_id__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/observability/ingest_call_via_webhook_url_api_v1_observability_calls_webhook__api_key__post.mdx b/docs-fumadocs/content/docs/api-reference/observability/ingest_call_via_webhook_url_api_v1_observability_calls_webhook__api_key__post.mdx new file mode 100644 index 00000000..9ddfb6ea --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/observability/ingest_call_via_webhook_url_api_v1_observability_calls_webhook__api_key__post.mdx @@ -0,0 +1,38 @@ +--- +title: Ingest Call Via Webhook Url +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Generic webhook โ€” API key embedded in the URL (Slack-style). + + + Usage: + POST https://your-domain.com/api/v1/observability/calls/webhook/ + + Accepts the flat call ingestion format: + + ``{"id": "...", "messages": [...], "startedAt": "...", ...}`` +mdPath: "/api-md/observability/ingest_call_via_webhook_url_api_v1_observability_calls_webhook__api_key__post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/observability/ingest_retell_webhook_api_v1_observability_calls_webhook_retell__api_key__post.mdx b/docs-fumadocs/content/docs/api-reference/observability/ingest_retell_webhook_api_v1_observability_calls_webhook_retell__api_key__post.mdx new file mode 100644 index 00000000..bed6f586 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/observability/ingest_retell_webhook_api_v1_observability_calls_webhook_retell__api_key__post.mdx @@ -0,0 +1,38 @@ +--- +title: Ingest Retell Webhook +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Retell-specific webhook โ€” API key embedded in the URL. + + + Usage: + POST https://your-domain.com/api/v1/observability/calls/webhook/retell/ + + Accepts Retell's native webhook payload format: + + ``{"event": "call_ended", "call": {...}}`` +mdPath: "/api-md/observability/ingest_retell_webhook_api_v1_observability_calls_webhook_retell__api_key__post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/observability/list_calls_api_v1_observability_calls_get.mdx b/docs-fumadocs/content/docs/api-reference/observability/list_calls_api_v1_observability_calls_get.mdx new file mode 100644 index 00000000..a07978b2 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/observability/list_calls_api_v1_observability_calls_get.mdx @@ -0,0 +1,29 @@ +--- +title: List Calls +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: List ingested call records in the active workspace. +mdPath: "/api-md/observability/list_calls_api_v1_observability_calls_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/observability/stream_call_live_events_api_v1_observability_calls__call_short_id__live_events_get.mdx b/docs-fumadocs/content/docs/api-reference/observability/stream_call_live_events_api_v1_observability_calls__call_short_id__live_events_get.mdx new file mode 100644 index 00000000..96a7764c --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/observability/stream_call_live_events_api_v1_observability_calls__call_short_id__live_events_get.mdx @@ -0,0 +1,30 @@ +--- +title: Stream Call Live Events +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Server-sent events stream for live transcript turns during an active + call. +mdPath: "/api-md/observability/stream_call_live_events_api_v1_observability_calls__call_short_id__live_events_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/observability/stream_observability_call_audio_api_v1_observability_calls__call_short_id__audio_get.mdx b/docs-fumadocs/content/docs/api-reference/observability/stream_observability_call_audio_api_v1_observability_calls__call_short_id__audio_get.mdx new file mode 100644 index 00000000..13bb929a --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/observability/stream_observability_call_audio_api_v1_observability_calls__call_short_id__audio_get.mdx @@ -0,0 +1,30 @@ +--- +title: Stream Observability Call Audio +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Stream call recording audio for observability calls (S3 or provider + URL). +mdPath: "/api-md/observability/stream_observability_call_audio_api_v1_observability_calls__call_short_id__audio_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/clone_persona_api_v1_personas__persona_id__clone_post.mdx b/docs-fumadocs/content/docs/api-reference/personas/clone_persona_api_v1_personas__persona_id__clone_post.mdx new file mode 100644 index 00000000..16ba3af9 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/clone_persona_api_v1_personas__persona_id__clone_post.mdx @@ -0,0 +1,29 @@ +--- +title: Clone Persona +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Clone an existing persona within the active workspace. +mdPath: "/api-md/personas/clone_persona_api_v1_personas__persona_id__clone_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/createPersonaCustomVoice.mdx b/docs-fumadocs/content/docs/api-reference/personas/createPersonaCustomVoice.mdx new file mode 100644 index 00000000..89172a8c --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/createPersonaCustomVoice.mdx @@ -0,0 +1,29 @@ +--- +title: Create Custom Voice +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Create a custom TTS voice (org-scoped). +mdPath: "/api-md/personas/createPersonaCustomVoice.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/create_persona_api_v1_personas_post.mdx b/docs-fumadocs/content/docs/api-reference/personas/create_persona_api_v1_personas_post.mdx new file mode 100644 index 00000000..2304bdae --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/create_persona_api_v1_personas_post.mdx @@ -0,0 +1,29 @@ +--- +title: Create Persona +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Create a new persona stamped with the active workspace. +mdPath: "/api-md/personas/create_persona_api_v1_personas_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/deleteAmbientLibraryAsset.mdx b/docs-fumadocs/content/docs/api-reference/personas/deleteAmbientLibraryAsset.mdx new file mode 100644 index 00000000..f7d816e5 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/deleteAmbientLibraryAsset.mdx @@ -0,0 +1,28 @@ +--- +title: Delete Ambient Library Asset +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/personas/deleteAmbientLibraryAsset.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/deletePersonaAmbientAudio.mdx b/docs-fumadocs/content/docs/api-reference/personas/deletePersonaAmbientAudio.mdx new file mode 100644 index 00000000..0e93ca28 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/deletePersonaAmbientAudio.mdx @@ -0,0 +1,29 @@ +--- +title: Delete Persona Ambient Audio +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete custom ambient audio for a persona (enterprise). +mdPath: "/api-md/personas/deletePersonaAmbientAudio.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/deletePersonaCustomVoice.mdx b/docs-fumadocs/content/docs/api-reference/personas/deletePersonaCustomVoice.mdx new file mode 100644 index 00000000..4960ada9 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/deletePersonaCustomVoice.mdx @@ -0,0 +1,29 @@ +--- +title: Delete Custom Voice +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete a custom TTS voice. +mdPath: "/api-md/personas/deletePersonaCustomVoice.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/delete_persona_api_v1_personas__persona_id__delete.mdx b/docs-fumadocs/content/docs/api-reference/personas/delete_persona_api_v1_personas__persona_id__delete.mdx new file mode 100644 index 00000000..6f954f9b --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/delete_persona_api_v1_personas__persona_id__delete.mdx @@ -0,0 +1,30 @@ +--- +title: Delete Persona +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete a persona within the active workspace. Returns 409 if dependent + records exist unless force=true. +mdPath: "/api-md/personas/delete_persona_api_v1_personas__persona_id__delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/generatePersonaPrompt.mdx b/docs-fumadocs/content/docs/api-reference/personas/generatePersonaPrompt.mdx new file mode 100644 index 00000000..43d4ed7e --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/generatePersonaPrompt.mdx @@ -0,0 +1,29 @@ +--- +title: Generate Persona Prompt +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Generate a persona caller prompt from an agent prompt via LLM. +mdPath: "/api-md/personas/generatePersonaPrompt.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/getAmbientLibraryPreviewUrl.mdx b/docs-fumadocs/content/docs/api-reference/personas/getAmbientLibraryPreviewUrl.mdx new file mode 100644 index 00000000..a7208caa --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/getAmbientLibraryPreviewUrl.mdx @@ -0,0 +1,30 @@ +--- +title: Get Ambient Library Preview Url +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Return a presigned URL for streaming ambient library preview in the + browser. +mdPath: "/api-md/personas/getAmbientLibraryPreviewUrl.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/getPersonaAgentPromptSources.mdx b/docs-fumadocs/content/docs/api-reference/personas/getPersonaAgentPromptSources.mdx new file mode 100644 index 00000000..8ea523cf --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/getPersonaAgentPromptSources.mdx @@ -0,0 +1,29 @@ +--- +title: Get Agent Prompt Sources +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Return agent prompts that can seed a persona description. +mdPath: "/api-md/personas/getPersonaAgentPromptSources.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/getPersonaVoiceOptions.mdx b/docs-fumadocs/content/docs/api-reference/personas/getPersonaVoiceOptions.mdx new file mode 100644 index 00000000..6b626ac1 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/getPersonaVoiceOptions.mdx @@ -0,0 +1,36 @@ +--- +title: Get Voice Options +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: >- + Return available TTS voices grouped by provider. + + + Merges built-in static voices, model-config voices (e.g. Murf voice + files), + + and the org's custom voices. Not enterprise-gated. +mdPath: "/api-md/personas/getPersonaVoiceOptions.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/get_persona_api_v1_personas__persona_id__get.mdx b/docs-fumadocs/content/docs/api-reference/personas/get_persona_api_v1_personas__persona_id__get.mdx new file mode 100644 index 00000000..215469b6 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/get_persona_api_v1_personas__persona_id__get.mdx @@ -0,0 +1,29 @@ +--- +title: Get Persona +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Get a specific persona within the active workspace. +mdPath: "/api-md/personas/get_persona_api_v1_personas__persona_id__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/listAmbientLibrary.mdx b/docs-fumadocs/content/docs/api-reference/personas/listAmbientLibrary.mdx new file mode 100644 index 00000000..787892b4 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/listAmbientLibrary.mdx @@ -0,0 +1,28 @@ +--- +title: List Ambient Library +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: [] +mdPath: "/api-md/personas/listAmbientLibrary.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/listAmbientPresets.mdx b/docs-fumadocs/content/docs/api-reference/personas/listAmbientPresets.mdx new file mode 100644 index 00000000..c9569705 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/listAmbientPresets.mdx @@ -0,0 +1,29 @@ +--- +title: List Platform Ambient Presets +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: List platform ambient presets available from installed asset packs. +mdPath: "/api-md/personas/listAmbientPresets.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/listPersonaCustomVoices.mdx b/docs-fumadocs/content/docs/api-reference/personas/listPersonaCustomVoices.mdx new file mode 100644 index 00000000..12a9e6ac --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/listPersonaCustomVoices.mdx @@ -0,0 +1,29 @@ +--- +title: List Custom Voices +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: List custom TTS voices for the organization. +mdPath: "/api-md/personas/listPersonaCustomVoices.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/list_personas_api_v1_personas_get.mdx b/docs-fumadocs/content/docs/api-reference/personas/list_personas_api_v1_personas_get.mdx new file mode 100644 index 00000000..7fbb52be --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/list_personas_api_v1_personas_get.mdx @@ -0,0 +1,29 @@ +--- +title: List Personas +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: List personas for the active workspace. +mdPath: "/api-md/personas/list_personas_api_v1_personas_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/previewAmbientLibraryAsset.mdx b/docs-fumadocs/content/docs/api-reference/personas/previewAmbientLibraryAsset.mdx new file mode 100644 index 00000000..96ea444a --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/previewAmbientLibraryAsset.mdx @@ -0,0 +1,29 @@ +--- +title: Preview Ambient Library Asset +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Stream a library ambient bed for in-browser preview. +mdPath: "/api-md/personas/previewAmbientLibraryAsset.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/previewAmbientPreset.mdx b/docs-fumadocs/content/docs/api-reference/personas/previewAmbientPreset.mdx new file mode 100644 index 00000000..bcc45ee4 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/previewAmbientPreset.mdx @@ -0,0 +1,29 @@ +--- +title: Preview Ambient Preset +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Stream a platform preset for in-browser preview. +mdPath: "/api-md/personas/previewAmbientPreset.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/seed_demo_data_api_v1_personas_seed_data_post.mdx b/docs-fumadocs/content/docs/api-reference/personas/seed_demo_data_api_v1_personas_seed_data_post.mdx new file mode 100644 index 00000000..32a847a1 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/seed_demo_data_api_v1_personas_seed_data_post.mdx @@ -0,0 +1,30 @@ +--- +title: Seed Demo Data +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Seed database with example personas and scenarios for the active + workspace. +mdPath: "/api-md/personas/seed_demo_data_api_v1_personas_seed_data_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/updateAmbientLibraryAsset.mdx b/docs-fumadocs/content/docs/api-reference/personas/updateAmbientLibraryAsset.mdx new file mode 100644 index 00000000..cf80cdb4 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/updateAmbientLibraryAsset.mdx @@ -0,0 +1,29 @@ +--- +title: Update Ambient Library Asset +full: true +_openapi: + preload: + - efficientai + method: PATCH + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Rename a library ambient bed. +mdPath: "/api-md/personas/updateAmbientLibraryAsset.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/updatePersonaCustomVoice.mdx b/docs-fumadocs/content/docs/api-reference/personas/updatePersonaCustomVoice.mdx new file mode 100644 index 00000000..5661a451 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/updatePersonaCustomVoice.mdx @@ -0,0 +1,29 @@ +--- +title: Update Custom Voice +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Update a custom TTS voice. +mdPath: "/api-md/personas/updatePersonaCustomVoice.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/update_persona_api_v1_personas__persona_id__put.mdx b/docs-fumadocs/content/docs/api-reference/personas/update_persona_api_v1_personas__persona_id__put.mdx new file mode 100644 index 00000000..b3661a94 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/update_persona_api_v1_personas__persona_id__put.mdx @@ -0,0 +1,29 @@ +--- +title: Update Persona +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Update a persona within the active workspace. +mdPath: "/api-md/personas/update_persona_api_v1_personas__persona_id__put.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/uploadAmbientLibraryAsset.mdx b/docs-fumadocs/content/docs/api-reference/personas/uploadAmbientLibraryAsset.mdx new file mode 100644 index 00000000..0357f51f --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/uploadAmbientLibraryAsset.mdx @@ -0,0 +1,29 @@ +--- +title: Upload Ambient Library Asset +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Upload a reusable ambient bed to the workspace library. +mdPath: "/api-md/personas/uploadAmbientLibraryAsset.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/personas/uploadPersonaAmbientAudio.mdx b/docs-fumadocs/content/docs/api-reference/personas/uploadPersonaAmbientAudio.mdx new file mode 100644 index 00000000..330ca92e --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/personas/uploadPersonaAmbientAudio.mdx @@ -0,0 +1,29 @@ +--- +title: Upload Persona Ambient Audio +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Upload or replace custom ambient audio for a persona (enterprise). +mdPath: "/api-md/personas/uploadPersonaAmbientAudio.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/scenarios/create_scenario_api_v1_scenarios_post.mdx b/docs-fumadocs/content/docs/api-reference/scenarios/create_scenario_api_v1_scenarios_post.mdx new file mode 100644 index 00000000..4b03755d --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/scenarios/create_scenario_api_v1_scenarios_post.mdx @@ -0,0 +1,29 @@ +--- +title: Create Scenario +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Create a new scenario stamped with the active workspace. +mdPath: "/api-md/scenarios/create_scenario_api_v1_scenarios_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/scenarios/delete_scenario_api_v1_scenarios__scenario_id__delete.mdx b/docs-fumadocs/content/docs/api-reference/scenarios/delete_scenario_api_v1_scenarios__scenario_id__delete.mdx new file mode 100644 index 00000000..e2670dd9 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/scenarios/delete_scenario_api_v1_scenarios__scenario_id__delete.mdx @@ -0,0 +1,30 @@ +--- +title: Delete Scenario +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete a scenario within the active workspace. Returns 409 if dependent + records exist unless force=true. +mdPath: "/api-md/scenarios/delete_scenario_api_v1_scenarios__scenario_id__delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/scenarios/get_scenario_api_v1_scenarios__scenario_id__get.mdx b/docs-fumadocs/content/docs/api-reference/scenarios/get_scenario_api_v1_scenarios__scenario_id__get.mdx new file mode 100644 index 00000000..029342a7 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/scenarios/get_scenario_api_v1_scenarios__scenario_id__get.mdx @@ -0,0 +1,29 @@ +--- +title: Get Scenario +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Get a specific scenario within the active workspace. +mdPath: "/api-md/scenarios/get_scenario_api_v1_scenarios__scenario_id__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/scenarios/list_scenarios_api_v1_scenarios_get.mdx b/docs-fumadocs/content/docs/api-reference/scenarios/list_scenarios_api_v1_scenarios_get.mdx new file mode 100644 index 00000000..b31ae9e5 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/scenarios/list_scenarios_api_v1_scenarios_get.mdx @@ -0,0 +1,29 @@ +--- +title: List Scenarios +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: List scenarios for the active workspace. +mdPath: "/api-md/scenarios/list_scenarios_api_v1_scenarios_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/scenarios/update_scenario_api_v1_scenarios__scenario_id__put.mdx b/docs-fumadocs/content/docs/api-reference/scenarios/update_scenario_api_v1_scenarios__scenario_id__put.mdx new file mode 100644 index 00000000..bc23e787 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/scenarios/update_scenario_api_v1_scenarios__scenario_id__put.mdx @@ -0,0 +1,29 @@ +--- +title: Update Scenario +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Update a scenario within the active workspace. +mdPath: "/api-md/scenarios/update_scenario_api_v1_scenarios__scenario_id__put.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/voice-bundles/createVoiceBundle.mdx b/docs-fumadocs/content/docs/api-reference/voice-bundles/createVoiceBundle.mdx new file mode 100644 index 00000000..13c8d09d --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/voice-bundles/createVoiceBundle.mdx @@ -0,0 +1,29 @@ +--- +title: Create Voicebundle +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Create a new VoiceBundle +mdPath: "/api-md/voice-bundles/createVoiceBundle.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/voice-bundles/deleteVoiceBundle.mdx b/docs-fumadocs/content/docs/api-reference/voice-bundles/deleteVoiceBundle.mdx new file mode 100644 index 00000000..1783cffd --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/voice-bundles/deleteVoiceBundle.mdx @@ -0,0 +1,30 @@ +--- +title: Delete Voicebundle +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete a VoiceBundle. Returns 409 if dependent records exist unless + force=true. +mdPath: "/api-md/voice-bundles/deleteVoiceBundle.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/voice-bundles/get_voicebundle_api_v1_voicebundles__voicebundle_id__get.mdx b/docs-fumadocs/content/docs/api-reference/voice-bundles/get_voicebundle_api_v1_voicebundles__voicebundle_id__get.mdx new file mode 100644 index 00000000..107aa7d0 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/voice-bundles/get_voicebundle_api_v1_voicebundles__voicebundle_id__get.mdx @@ -0,0 +1,29 @@ +--- +title: Get Voicebundle +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Get a specific VoiceBundle +mdPath: "/api-md/voice-bundles/get_voicebundle_api_v1_voicebundles__voicebundle_id__get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/voice-bundles/listVoiceBundles.mdx b/docs-fumadocs/content/docs/api-reference/voice-bundles/listVoiceBundles.mdx new file mode 100644 index 00000000..93257843 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/voice-bundles/listVoiceBundles.mdx @@ -0,0 +1,29 @@ +--- +title: List Voicebundles +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: List all VoiceBundles for the organization +mdPath: "/api-md/voice-bundles/listVoiceBundles.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/voice-bundles/updateVoiceBundle.mdx b/docs-fumadocs/content/docs/api-reference/voice-bundles/updateVoiceBundle.mdx new file mode 100644 index 00000000..2790179e --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/voice-bundles/updateVoiceBundle.mdx @@ -0,0 +1,29 @@ +--- +title: Update Voicebundle +full: true +_openapi: + preload: + - efficientai + method: PUT + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Update an existing VoiceBundle +mdPath: "/api-md/voice-bundles/updateVoiceBundle.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/workspaces/create_workspace_api_v1_workspaces_post.mdx b/docs-fumadocs/content/docs/api-reference/workspaces/create_workspace_api_v1_workspaces_post.mdx new file mode 100644 index 00000000..b9288851 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/workspaces/create_workspace_api_v1_workspaces_post.mdx @@ -0,0 +1,29 @@ +--- +title: Create Workspace +full: true +_openapi: + preload: + - efficientai + method: POST + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Create a new (non-default) workspace; creator becomes Workspace Admin. +mdPath: "/api-md/workspaces/create_workspace_api_v1_workspaces_post.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/workspaces/delete_workspace_api_v1_workspaces__workspace_id__delete.mdx b/docs-fumadocs/content/docs/api-reference/workspaces/delete_workspace_api_v1_workspaces__workspace_id__delete.mdx new file mode 100644 index 00000000..a659065a --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/workspaces/delete_workspace_api_v1_workspaces__workspace_id__delete.mdx @@ -0,0 +1,29 @@ +--- +title: Delete Workspace +full: true +_openapi: + preload: + - efficientai + method: DELETE + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Delete a non-default workspace (org admin only). +mdPath: "/api-md/workspaces/delete_workspace_api_v1_workspaces__workspace_id__delete.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/workspaces/list_workspaces_api_v1_workspaces_get.mdx b/docs-fumadocs/content/docs/api-reference/workspaces/list_workspaces_api_v1_workspaces_get.mdx new file mode 100644 index 00000000..e676da66 --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/workspaces/list_workspaces_api_v1_workspaces_get.mdx @@ -0,0 +1,29 @@ +--- +title: List Workspaces +full: true +_openapi: + preload: + - efficientai + method: GET + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: List workspaces the caller can access. +mdPath: "/api-md/workspaces/list_workspaces_api_v1_workspaces_get.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/api-reference/workspaces/update_workspace_api_v1_workspaces__workspace_id__patch.mdx b/docs-fumadocs/content/docs/api-reference/workspaces/update_workspace_api_v1_workspaces__workspace_id__patch.mdx new file mode 100644 index 00000000..074a91cb --- /dev/null +++ b/docs-fumadocs/content/docs/api-reference/workspaces/update_workspace_api_v1_workspaces__workspace_id__patch.mdx @@ -0,0 +1,30 @@ +--- +title: Update Workspace +full: true +_openapi: + preload: + - efficientai + method: PATCH + webhook: false + toc: [] + structuredData: + headings: [] + contents: + - content: Rename a workspace or change active status (org admin only for the + latter). +mdPath: "/api-md/workspaces/update_workspace_api_v1_workspaces__workspace_id__patch.md" +--- + +{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} + +export default function Layout(props) { + const { APIPage, OpenAPIPage } = props.components ?? {}; + // "APIPage" is the old name from v10, this allows both for backward compatibility + const Comp = OpenAPIPage ?? APIPage; + return ( + <> + {props.children} + + + ); +} \ No newline at end of file diff --git a/docs-fumadocs/content/docs/blog/index.mdx b/docs-fumadocs/content/docs/blog/index.mdx new file mode 100644 index 00000000..0a026fe8 --- /dev/null +++ b/docs-fumadocs/content/docs/blog/index.mdx @@ -0,0 +1,7 @@ +--- +title: Blogs +--- + +# Blogs + +Coming soon. diff --git a/docs-fumadocs/content/docs/changelog/index.mdx b/docs-fumadocs/content/docs/changelog/index.mdx new file mode 100644 index 00000000..463132c1 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/index.mdx @@ -0,0 +1,7 @@ +--- +title: Changelog +--- + +# Changelog + +Release notes are synced from [GitHub Releases](https://github.com/EfficientAI-tech/efficientAI/releases). Select a version from the sidebar to view its notes. diff --git a/docs-fumadocs/content/docs/changelog/meta.json b/docs-fumadocs/content/docs/changelog/meta.json new file mode 100644 index 00000000..22351297 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/meta.json @@ -0,0 +1,36 @@ +{ + "title": "Changelog", + "pages": [ + "index", + "v1.5.33", + "v1.5.32", + "v1.5.31", + "v1.5.30", + "v1.5.29", + "v1.5.28", + "v1.5.27", + "v1.5.26", + "v1.5.25", + "v1.5.24", + "v1.5.23", + "v1.5.22", + "v1.5.21", + "v1.5.20", + "v1.5.19", + "v1.5.18", + "v1.5.17", + "v1.5.16", + "v1.5.15", + "v1.5.14", + "v1.5.13", + "v1.5.12", + "v1.5.11", + "v1.5.10", + "v1.5.9", + "v1.5.8", + "v1.5.7", + "v1.5.6", + "v1.5.5", + "v1.5.4" + ] +} diff --git a/docs-fumadocs/content/docs/changelog/v1.5.10.mdx b/docs-fumadocs/content/docs/changelog/v1.5.10.mdx new file mode 100644 index 00000000..c4c44aeb --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.10.mdx @@ -0,0 +1,17 @@ +--- +title: v1.5.10 +description: Release notes for v1.5.10. +--- + +# v1.5.10 + +Released Jun 28, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.10). + +## What changed + +- feat: updating azure storage by @TEJASNARAYANS in https://github.com/EfficientAI-tech/efficientAI/pull/95 + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.11.mdx b/docs-fumadocs/content/docs/changelog/v1.5.11.mdx new file mode 100644 index 00000000..cf0b389f --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.11.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.11 +description: Release notes for v1.5.11. +--- + +# v1.5.11 + +Released Jul 3, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.11). + +Primary pull request: [#97](https://github.com/EfficientAI-tech/efficientAI/pull/97) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.12.mdx b/docs-fumadocs/content/docs/changelog/v1.5.12.mdx new file mode 100644 index 00000000..935e8c46 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.12.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.12 +description: Release notes for v1.5.12. +--- + +# v1.5.12 + +Released Jul 3, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.12). + +Primary pull request: [#96](https://github.com/EfficientAI-tech/efficientAI/pull/96) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Adding flexprice changes + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.13.mdx b/docs-fumadocs/content/docs/changelog/v1.5.13.mdx new file mode 100644 index 00000000..438caad4 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.13.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.13 +description: Release notes for v1.5.13. +--- + +# v1.5.13 + +Released Jul 9, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.13). + +Primary pull request: [#98](https://github.com/EfficientAI-tech/efficientAI/pull/98) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.14.mdx b/docs-fumadocs/content/docs/changelog/v1.5.14.mdx new file mode 100644 index 00000000..38ecbb8f --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.14.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.14 +description: Release notes for v1.5.14. +--- + +# v1.5.14 + +Released Jul 10, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.14). + +Primary pull request: [#99](https://github.com/EfficientAI-tech/efficientAI/pull/99) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.15.mdx b/docs-fumadocs/content/docs/changelog/v1.5.15.mdx new file mode 100644 index 00000000..394c1e4e --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.15.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.15 +description: Release notes for v1.5.15. +--- + +# v1.5.15 + +Released Jul 11, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.15). + +Primary pull request: [#100](https://github.com/EfficientAI-tech/efficientAI/pull/100) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.16.mdx b/docs-fumadocs/content/docs/changelog/v1.5.16.mdx new file mode 100644 index 00000000..72eea505 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.16.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.16 +description: Release notes for v1.5.16. +--- + +# v1.5.16 + +Released Jul 13, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.16). + +Primary pull request: [#102](https://github.com/EfficientAI-tech/efficientAI/pull/102) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.17.mdx b/docs-fumadocs/content/docs/changelog/v1.5.17.mdx new file mode 100644 index 00000000..3c644677 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.17.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.17 +description: Release notes for v1.5.17. +--- + +# v1.5.17 + +Released Jul 17, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.17). + +Primary pull request: [#103](https://github.com/EfficientAI-tech/efficientAI/pull/103) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.18.mdx b/docs-fumadocs/content/docs/changelog/v1.5.18.mdx new file mode 100644 index 00000000..94280299 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.18.mdx @@ -0,0 +1,26 @@ +--- +title: v1.5.18 +description: Release notes for v1.5.18. +--- + +# v1.5.18 + +Released Jul 21, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.18). + +Primary pull request: [#104](https://github.com/EfficientAI-tech/efficientAI/pull/104) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## Why + +Large call imports and evaluations (70k+ rows) were slow or unstable due to full-shard scans, aggressive UI polling, eval rows failing while imports retried, and Exotel 400 responses blocking all workers sharing a credential. + +## How to test + +- [ ] Run evaluation on a large sharded import; confirm page 1 loads quickly and progress polling is reasonable +- [ ] Start eval with rows needing recording fetch; confirm transient import errors do not permanently fail eval rows +- [ ] Import 300+ Exotel rows; confirm flaky 400s retry without credential-wide 60s blocks +- [ ] `pytest tests/test_db_sharding/test_eval_rows_pagination.py tests/test_workers/test_eval_dispatch_import.py tests/test_services/test_telephony/test_recording_download.py tests/test_workers/test_process_call_import_row.py` + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.19.mdx b/docs-fumadocs/content/docs/changelog/v1.5.19.mdx new file mode 100644 index 00000000..f1a222b1 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.19.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.19 +description: Release notes for v1.5.19. +--- + +# v1.5.19 + +Released Jul 27, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.19). + +Primary pull request: [#105](https://github.com/EfficientAI-tech/efficientAI/pull/105) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.20.mdx b/docs-fumadocs/content/docs/changelog/v1.5.20.mdx new file mode 100644 index 00000000..6c93a71a --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.20.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.20 +description: Release notes for v1.5.20. +--- + +# v1.5.20 + +Released Aug 3, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.20). + +Primary pull request: [#106](https://github.com/EfficientAI-tech/efficientAI/pull/106) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.21.mdx b/docs-fumadocs/content/docs/changelog/v1.5.21.mdx new file mode 100644 index 00000000..39d31a18 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.21.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.21 +description: Release notes for v1.5.21. +--- + +# v1.5.21 + +Released Aug 3, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.21). + +Primary pull request: [#108](https://github.com/EfficientAI-tech/efficientAI/pull/108) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.22.mdx b/docs-fumadocs/content/docs/changelog/v1.5.22.mdx new file mode 100644 index 00000000..2b04f731 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.22.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.22 +description: Release notes for v1.5.22. +--- + +# v1.5.22 + +Released Aug 4, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.22). + +Primary pull request: [#101](https://github.com/EfficientAI-tech/efficientAI/pull/101) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.23.mdx b/docs-fumadocs/content/docs/changelog/v1.5.23.mdx new file mode 100644 index 00000000..ba042b17 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.23.mdx @@ -0,0 +1,19 @@ +--- +title: v1.5.23 +description: Release notes for v1.5.23. +--- + +# v1.5.23 + +Released Aug 5, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.23). + +Primary pull request: [#109](https://github.com/EfficientAI-tech/efficientAI/pull/109) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +- Revert "fix: updating metric library" by @TEJASNARAYANS in https://github.com/EfficientAI-tech/efficientAI/pull/109 + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.24.mdx b/docs-fumadocs/content/docs/changelog/v1.5.24.mdx new file mode 100644 index 00000000..a5785bc8 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.24.mdx @@ -0,0 +1,19 @@ +--- +title: v1.5.24 +description: Release notes for v1.5.24. +--- + +# v1.5.24 + +Released Aug 12, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.24). + +Primary pull request: [#113](https://github.com/EfficientAI-tech/efficientAI/pull/113) by [@MSami625](https://github.com/MSami625). + +## What changed + +- Import metadata by @MSami625 in https://github.com/EfficientAI-tech/efficientAI/pull/113 + +## Contributors + +- [@MSami625](https://github.com/MSami625) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.25.mdx b/docs-fumadocs/content/docs/changelog/v1.5.25.mdx new file mode 100644 index 00000000..ed415e2a --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.25.mdx @@ -0,0 +1,19 @@ +--- +title: v1.5.25 +description: Release notes for v1.5.25. +--- + +# v1.5.25 + +Released Aug 14, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.25). + +Primary pull request: [#111](https://github.com/EfficientAI-tech/efficientAI/pull/111) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +- fix: updating metric library by @TEJASNARAYANS in https://github.com/EfficientAI-tech/efficientAI/pull/111 + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.26.mdx b/docs-fumadocs/content/docs/changelog/v1.5.26.mdx new file mode 100644 index 00000000..5d80470e --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.26.mdx @@ -0,0 +1,42 @@ +--- +title: v1.5.26 +description: Release notes for v1.5.26. +--- + +# v1.5.26 + +Released Aug 19, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.26). + +Primary pull request: [#114](https://github.com/EfficientAI-tech/efficientAI/pull/114) by [@MSami625](https://github.com/MSami625). + +## What changed + +Added usage tracking for LLM, STT, and TTS calls, including voice agent usage. + +* Track LLM input/output, cache, reasoning tokens, and call count. +* Track STT and TTS usage from voice agent calls. +* Added Redis-based usage counters with batched Postgres rollups. +* Added usage context for organization, workspace, product, and resource. +* Added Usage API for summary and breakdown. +* Added a single `/usage` page with filters and grouping. +* Added scheduled flushing of usage data from Redis to Postgres. + +## Why + +We need a centralized way to track AI usage across different products and voice agents without adding significant overhead to individual calls. + +Usage is aggregated in Redis first and periodically flushed to Postgres, instead of creating a database record for every request. This keeps the system scalable while allowing usage to be viewed from a single Usage page. + +## How to test + +1. Run an LLM request/evaluation. +2. Run a voice agent call using STT, LLM, and TTS. +3. Open the `/usage` page. +4. Verify that the usage data is recorded correctly. +5. Test filters for workspace, product, model, and resource. +6. Verify that usage data is updated after the Redis flush. + +## Contributors + +- [@MSami625](https://github.com/MSami625) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.27.mdx b/docs-fumadocs/content/docs/changelog/v1.5.27.mdx new file mode 100644 index 00000000..2251e0a4 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.27.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.27 +description: Release notes for v1.5.27. +--- + +# v1.5.27 + +Released Aug 22, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.27). + +Primary pull request: [#116](https://github.com/EfficientAI-tech/efficientAI/pull/116) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.28.mdx b/docs-fumadocs/content/docs/changelog/v1.5.28.mdx new file mode 100644 index 00000000..ec2e62a5 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.28.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.28 +description: Release notes for v1.5.28. +--- + +# v1.5.28 + +Released Aug 28, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.28). + +Primary pull request: [#121](https://github.com/EfficientAI-tech/efficientAI/pull/121) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.29.mdx b/docs-fumadocs/content/docs/changelog/v1.5.29.mdx new file mode 100644 index 00000000..7bdfd893 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.29.mdx @@ -0,0 +1,39 @@ +--- +title: v1.5.29 +description: Release notes for v1.5.29. +--- + +# v1.5.29 + +Released Aug 31, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.29). + +Primary pull request: [#119](https://github.com/EfficientAI-tech/efficientAI/pull/119) by [@MSami625](https://github.com/MSami625). + +## What changed + +- Expanded LLM/STT/TTS usage tracking across pre-prod flows: evaluator results, Metrics Studio runs, persona generation, playground voice calls, and test-agent LLM-to-LLM simulation +- Added `external_agent_usage.py` to extract and record provider usage from Vapi, Retell, ElevenLabs, and Smallest call payloads +- Wired usage recording into playground polling, evaluator result processing, and test-agent bridge/simulation paths (with dedup via `external_usage_recorded`) +- Added LLM-to-LLM evaluator simulation for voice-bundle-only agents (no external voice provider) +- Fixed Celery `run_evaluator` asyncio event loop handling for voice-bridge runs +- Improved playground polling (skip duplicate processing, Vapi polls on refresh only) +- Relaxed CSP `connect-src` / `worker-src` for voice provider WebRTC connections +- Added tests for pre-prod usage, simulation usage, LLM-to-LLM simulation, and CSP voice provider rules + +## Why + +Pre-prod testing (evaluators, playground, personas, Metrics Studio) was not consistently attributing LLM/STT/TTS usage, and external voice provider token usage from call payloads was not being captured. This gives accurate per-workspace usage/cost tracking across synthetic testing and live provider calls. + +## How to test + +1. `pytest tests/test_services/test_usage/test_pre_prod_usage.py tests/test_services/test_usage/test_test_agent_simulation_usage.py tests/test_services/test_testing/test_llm_to_llm_evaluator_simulation.py tests/test_core/test_security_headers_middleware.py -v` +2. Run an evaluator with voice bundle only โ†’ confirm LLM-to-LLM simulation completes and usage is recorded under `TEST_AGENT` +3. Run an evaluator with voice bridge โ†’ confirm bridge call works (no asyncio event loop error) and usage is tracked +4. Make a playground web call (Vapi/Retell/ElevenLabs) โ†’ confirm provider LLM/STT/TTS usage is recorded once +5. Run a Metrics Studio batch โ†’ confirm usage is attributed to the metric studio run +6. Verify playground loads and connects to voice providers without CSP errors + +## Contributors + +- [@MSami625](https://github.com/MSami625) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.30.mdx b/docs-fumadocs/content/docs/changelog/v1.5.30.mdx new file mode 100644 index 00000000..31ab4914 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.30.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.30 +description: Release notes for v1.5.30. +--- + +# v1.5.30 + +Released Sep 4, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.30). + +Primary pull request: [#120](https://github.com/EfficientAI-tech/efficientAI/pull/120) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.31.mdx b/docs-fumadocs/content/docs/changelog/v1.5.31.mdx new file mode 100644 index 00000000..443e86bb --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.31.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.31 +description: Release notes for v1.5.31. +--- + +# v1.5.31 + +Released Sep 7, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.31). + +Primary pull request: [#122](https://github.com/EfficientAI-tech/efficientAI/pull/122) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.32.mdx b/docs-fumadocs/content/docs/changelog/v1.5.32.mdx new file mode 100644 index 00000000..f55080d0 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.32.mdx @@ -0,0 +1,27 @@ +--- +title: v1.5.32 +description: Release notes for v1.5.32. +--- + +# v1.5.32 + +Released Sep 15, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.32). + +Primary pull request: [#125](https://github.com/EfficientAI-tech/efficientAI/pull/125) by [@TEJASNARAYANS](https://github.com/TEJASNARAYANS). + +## What changed + +Briefly describe what this PR changes. + +## Why + +Explain the problem this solves and why this approach was chosen. + +## How to test + +List clear steps for reviewers to verify the change. + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.33.mdx b/docs-fumadocs/content/docs/changelog/v1.5.33.mdx new file mode 100644 index 00000000..03e92c23 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.33.mdx @@ -0,0 +1,48 @@ +--- +title: v1.5.33 +description: Release notes for v1.5.33. +--- + +# v1.5.33 + +Released Sep 17, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.33). + +Primary pull request: [#124](https://github.com/EfficientAI-tech/efficientAI/pull/124) by [@MSami625](https://github.com/MSami625). + +## What changed + +Security remediation from the audit, cherry-picked onto `main` (replaces the old `security-patches` branch): + +- **Auth:** httpOnly cookie sessions (`eai_access` / `eai_refresh` / `eai_csrf`), CSRF middleware, session epoch invalidation on password change, strong `SECRET_KEY` enforcement when `debug: false` +- **API hardening:** SSRF checks on recording/audio URLs, reader RBAC query-token bypass fix, abuse-only rate limits on auth/resource creates, LLM config sanitization +- **Headers:** TrustedHost + HSTS support +- **Frontend:** Cookie-session bootstrap, silent refresh, CSRF on axios + Pipecat voice-agent connect, profile/password UX fixes +- **Fixes:** Duplicate invite โ†’ 409, wrong password โ†’ 400, expanded recording URL allowlist (incl. R2), App.tsx route cleanup + +## Why + +The audit flagged token exposure in `localStorage`, missing CSRF protection, SSRF via recording URLs, weak session invalidation, and several auth/RBAC gaps. Cookie-based sessions with double-submit CSRF address browser auth without storing tokens in JS-accessible storage, while SSRF allowlists and outbound URL validation block server-side fetch abuse. Cherry-picking onto `main` keeps the PR focused (~6 commits) instead of the prior branch that included unrelated otel work. + +## How to test + +1. **Migrate:** `eai migrate` (confirms `086_user_session_epoch`) +2. **Config:** ensure `auth.local_password.cookie_session.enabled: true` and `security.trusted_hosts` includes `localhost` +3. **Login:** sign in โ†’ DevTools cookies show `eai_access`, `eai_refresh`, `eai_csrf` โ†’ refresh page stays logged in +4. **Voice call:** Agent Playground โ†’ start test call โ†’ should connect (no CSRF 403) +5. **Password:** Profile โ†’ wrong current password โ†’ error toast, **not** logged out; correct change โ†’ redirected to login +6. **Invite:** IAM โ†’ invite same email twice โ†’ toast: *"An invitation is already pending for this email"* +7. **Recording:** play audio on a call with R2/Cloudflare URL โ†’ no allowlist error +8. **Tests:** + ```bash + .venv/bin/pytest tests/test_core/test_auth_cookies.py \ + tests/test_security_remediation.py tests/test_api/test_security_rbac.py \ + tests/test_services/test_telephony/test_recording_download.py -v + cd frontend && npm run build + ``` + +**Deploy note:** production needs `debug: false`, strong `secret_key`, `cookie_session.secure: true`, `trusted_hosts`, and `hsts_enabled: true`. + +## Contributors + +- [@MSami625](https://github.com/MSami625) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.4.mdx b/docs-fumadocs/content/docs/changelog/v1.5.4.mdx new file mode 100644 index 00000000..e4590272 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.4.mdx @@ -0,0 +1,17 @@ +--- +title: v1.5.4 +description: Release notes for v1.5.4. +--- + +# v1.5.4 + +Released Jun 14, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.4). + +## What changed + +- fix: updating entrprise gated docs by @TEJASNARAYANS in https://github.com/EfficientAI-tech/efficientAI/pull/90 + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.5.mdx b/docs-fumadocs/content/docs/changelog/v1.5.5.mdx new file mode 100644 index 00000000..c1eb3a9f --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.5.mdx @@ -0,0 +1,17 @@ +--- +title: v1.5.5 +description: Release notes for v1.5.5. +--- + +# v1.5.5 + +Released Jun 14, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.5). + +## What changed + +- fix: updating lambda fixes by @TEJASNARAYANS in https://github.com/EfficientAI-tech/efficientAI/pull/91 + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.6.mdx b/docs-fumadocs/content/docs/changelog/v1.5.6.mdx new file mode 100644 index 00000000..1b8a2c83 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.6.mdx @@ -0,0 +1,17 @@ +--- +title: v1.5.6 +description: Release notes for v1.5.6. +--- + +# v1.5.6 + +Released Jun 14, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.6). + +## What changed + +- fix: lambda fixes by @TEJASNARAYANS in https://github.com/EfficientAI-tech/efficientAI/pull/92 + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.7.mdx b/docs-fumadocs/content/docs/changelog/v1.5.7.mdx new file mode 100644 index 00000000..e4ad90bc --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.7.mdx @@ -0,0 +1,17 @@ +--- +title: v1.5.7 +description: Release notes for v1.5.7. +--- + +# v1.5.7 + +Released Jun 15, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.7). + +## What changed + +- feat: Workspace upgrades by @TEJASNARAYANS in https://github.com/EfficientAI-tech/efficientAI/pull/89 + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.8.mdx b/docs-fumadocs/content/docs/changelog/v1.5.8.mdx new file mode 100644 index 00000000..45fe885e --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.8.mdx @@ -0,0 +1,17 @@ +--- +title: v1.5.8 +description: Release notes for v1.5.8. +--- + +# v1.5.8 + +Released Jun 22, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.8). + +## What changed + +- fix: updating bugs by @TEJASNARAYANS in https://github.com/EfficientAI-tech/efficientAI/pull/93 + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/changelog/v1.5.9.mdx b/docs-fumadocs/content/docs/changelog/v1.5.9.mdx new file mode 100644 index 00000000..d5534ea3 --- /dev/null +++ b/docs-fumadocs/content/docs/changelog/v1.5.9.mdx @@ -0,0 +1,17 @@ +--- +title: v1.5.9 +description: Release notes for v1.5.9. +--- + +# v1.5.9 + +Released Jun 23, 2026. [View on GitHub](https://github.com/EfficientAI-tech/efficientAI/releases/tag/v1.5.9). + +## What changed + +- fix: updating security fixes by @TEJASNARAYANS in https://github.com/EfficientAI-tech/efficientAI/pull/94 + +## Contributors + +- [@TEJASNARAYANS](https://github.com/TEJASNARAYANS) + diff --git a/docs-fumadocs/content/docs/enterprise/index.mdx b/docs-fumadocs/content/docs/enterprise/index.mdx new file mode 100644 index 00000000..4a16bd4a --- /dev/null +++ b/docs-fumadocs/content/docs/enterprise/index.mdx @@ -0,0 +1,115 @@ +--- +title: Enterprise +--- + +# Enterprise + +> **Enterprise quickstart** +> - Start with: [Authentication guide](https://docs.efficientai.cloud/docs/getting-started/authentication/) +> - Free trial: [Book a demo](https://cal.com/aadhar-singh-bhadauria/30min) +> - Licensing: [contact@efficientai.cloud](mailto:contact@efficientai.cloud) + +## Who is Enterprise for? + +Enterprise is for teams running voice agent evaluation in production who need multi-member IAM, extended analytics, gateway routing, and operational controls beyond the open-source limits. + +## License model (BSL) + +EfficientAI open source is released under the **Business Source License (BSL)**, following the same approach as [LiteLLM](https://github.com/BerriAI/litellm) and [Bifrost](https://github.com/maximhq/bifrost): + +- Core evaluation workflows remain free to self-host under BSL. +- Specific production-scale capabilities require an **Enterprise license key**. +- After the license change date defined in the repository `LICENSE` file, covered code converts to Apache 2.0. + +Enterprise contracts unlock gated features for your organization (or deployment-wide when no `org_id` is set in the license payload). + +## Open source vs Enterprise + +| Capability | Open source (BSL) | Enterprise | +|---|---|---| +| Voice bundles and BYOK integrations | Included | โœ… Included | +| Agents | Up to **3** agents | โœ… Unlimited | +| Custom metrics | Up to **5** metrics | โœ… Unlimited | +| Evaluators, suites, results | Included | โœ… Included + failure clustering | +| Prompt partials | Included | โœ… Included | +| GEPA / prompt optimization | **Included** | โœ… Included | +| Agent playground | Included | โœ… Included | +| Voice playground (blind testing) | Not included | โœ… Included | +| Call imports (post-production analytics) | Not included | โœ… Included | +| Metric Studio | Not included | โœ… Included | +| Alerts | Not included | โœ… Included | +| Usage analytics history | Last **7 days** | โœ… Unlimited | +| Org members | **1 member** per org | โœ… Unlimited | +| Workspaces | **1 default workspace** | โœ… Unlimited | +| Gateway enablement (integrations) | Not included | โœ… Included | +| Authentication | API keys + local email/password | โœ… OIDC, SAML, SCIM, MFA enforcement, audit export | + +## Already gated (Enterprise license required) + +These features are already enforced behind an Enterprise license key: + +| Feature ID | Capability | +|---|---| +| `call_imports` | Post-production call imports and batch analytics | +| `voice_playground` | Voice Playground with blind TTS comparison | + +## Included in open source + +- Voice bundles and integrations (BYOK and platform providers) +- Agents, personas, and scenarios (within agent cap) +- Evaluators, evaluator suites, and evaluation results +- Metrics and categorisation labels (within metric cap) +- Prompt partials, GEPA / prompt optimization, and agent playground +- Traces, observability, and judge alignment +- API key and local password authentication + +## Set up a license + +Provide the Enterprise license key in environment variables or config: + +```bash title=".env" +EFFICIENTAI_LICENSE=eyJhbGciOi... +``` + +```yaml title="config.yml" +license: + key: "eyJhbGciOi..." +``` + +Restart the EfficientAI backend after updating the license. + +License scope behavior: + +- If `org_id` is not set in the license payload, features are enabled deployment-wide. +- If `org_id` is set, features are enabled only for that organization. + +Verify current state: + +- `GET /api/v1/license-info` + +## FAQ + +### What happens without a license? + +Feature-gated routes return `403` with `enterprise_feature_required` or `enterprise_license_required`. Open-source limits (agents, metrics, IAM, usage history) apply automatically. + +### What is the OSS usage analytics limit? + +Open-source deployments retain a **7-day** usage analytics history. + +### Is GEPA / prompt optimization Enterprise-only? + +No. GEPA / prompt optimization is included in the open-source BSL distribution. + +### How do I verify whether my org is licensed? + +Check `GET /api/v1/license-info` and confirm `enabled_features` is populated for your organization. + +### Where do I configure authentication modes? + +See [Authentication guide](https://docs.efficientai.cloud/docs/getting-started/authentication/) and [Configuration reference](/docs/reference/configuration/). + +## Talk to us + +- Sales and licensing: [contact@efficientai.cloud](mailto:contact@efficientai.cloud) +- Book a demo: [cal.com/aadhar-singh-bhadauria/30min](https://cal.com/aadhar-singh-bhadauria/30min) diff --git a/docs-fumadocs/content/docs/getting-started/authentication.mdx b/docs-fumadocs/content/docs/getting-started/authentication.mdx index df723fca..0aed711c 100644 --- a/docs-fumadocs/content/docs/getting-started/authentication.mdx +++ b/docs-fumadocs/content/docs/getting-started/authentication.mdx @@ -1,490 +1,465 @@ ---- -id: authentication -title: Authentication -sidebar_position: 3 ---- - -# ๐Ÿ” Authentication - -EfficientAI ships with a pluggable authentication system that scales from a -single-operator OSS install to an enterprise deployment behind your existing -identity provider. You pick the providers you want in `config.yml` (or via -`AUTH_PROVIDERS` in `.env`) and the API/frontend adapt automatically. - -## Deployment models - -| Model | Providers | License needed | -| ------------------------- | ----------------------------- | -------------- | -| OSS self-hosted (default) | `api_key`, `local_password` | None | -| Enterprise SSO (BYO IdP) | `api_key`, `external_oidc` | `oidc_sso` | - -- **`api_key`** โ€” the `X-API-Key` header, always available, for programmatic - access (CI pipelines, SDKs, scripts). -- **`local_password`** โ€” email + password, verified against the local users - table, returns an app-signed HS256 Bearer token. Enabled by default. -- **`external_oidc`** โ€” license-gated. Verifies a Bearer JWT issued by your - OIDC-compliant IdP (Okta, Azure AD / Entra ID, Google Workspace, AWS - Cognito, Auth0, Ping, JumpCloud, OneLogin, โ€ฆ) against the issuer's JWKS. - -:::info Why no bundled IdP? -In practice every enterprise already runs one. Shipping our own Keycloak -alongside the app just added another thing for you to operate and lock -down. `external_oidc` talks to whatever you already have. -::: - ---- - -## Self-hosted (OSS) - -This is the default after `docker compose up -d` or `eai start-all`. No -license, no IdP, no external dependencies. - -```yaml title="config.yml" -auth: - providers: - - api_key - - local_password - local_password: - # Lifetime of the short-lived access token minted at sign-in. - token_ttl_minutes: 15 - refresh_token_ttl_days: 7 - # Let anyone who reaches the login page create an account + new org. - # Set to false once you've finished bootstrapping. - allow_signup: true -``` - -The equivalent environment variables (for Docker Compose / `.env`): - -```bash title=".env" -AUTH_PROVIDERS=api_key,local_password -AUTH_LOCAL_TOKEN_TTL_MINUTES=15 -AUTH_REFRESH_TOKEN_TTL_DAYS=7 -AUTH_LOCAL_ALLOW_SIGNUP=true - -# HS256 signing key for locally-issued Bearer tokens. Change this in prod! -SECRET_KEY=replace-me-with-a-long-random-string -``` - -### First-time bootstrap - -1. Start the stack. -2. Open `http://localhost:8000/` and click **Create account** on the login - screen. The first user you create becomes the admin of a fresh - organization. -3. Mint an API key from **Profile โ†’ API Keys** (or via - `scripts/create_api_key.py`) for programmatic access. - -### Password login (email + password) - -When `local_password` is enabled, the login screen shows a **Sign in** and -(if `allow_signup: true`) a **Create account** tab. Signing up provisions a -new user and a new organization, and makes that user the `admin` of it. If -you leave the organization name blank, the server derives one from the -email's local-part. - -Once signed in, the SPA holds a short-lived access token (15 minutes by -default) plus a refresh token. The client silently refreshes the access -token before it expires. You can change lifetimes with `token_ttl_minutes` -and `refresh_token_ttl_days`. Logout revokes the refresh token and -blacklists the current access token server-side. - -### Linking a password to an API-key-only account - -If you bootstrapped with `scripts/create_api_key.py`, the backend -provisions a placeholder user behind that key (its email ends in -`@efficientai.local`). You can upgrade this identity to a real email + -password login so you can sign in interactively with the same user. - -Do it from **Profile โ†’ Sign-in Password** while signed in via the API key -โ€” the page detects the placeholder email and prompts you to pick a real -one and a password. After saving, the same user can log in either with -the original API key (for machines) or with email + password (for humans). - -Rules the UI enforces: - -- If the user already has a password, the form asks for the current one - before accepting a new one. -- You can only set the email from that screen while it's still the - placeholder `@efficientai.local` address; "real" users change their - email from the main profile edit flow. - -### Hardening before you expose it to the internet - -- Turn off self-service signup once your team is in: - - ```yaml - auth: - local_password: - allow_signup: false - ``` - -- Rotate `SECRET_KEY` to invalidate existing sessions. -- Put the app behind a reverse proxy (Nginx, Caddy, Cloudflare) that - terminates TLS and enforces HSTS. -- The bundled FastAPI server sends baseline security headers on all - responses (`X-Frame-Options`, `X-Content-Type-Options`, `Referrer-Policy`, - `Cache-Control`, and `Content-Security-Policy-Report-Only` by default). If - you terminate traffic at an external reverse proxy, keep those headers (or - stricter CSP `frame-ancestors`) enabled there too. After reviewing CSP - violation reports, set `CSP_REPORT_ONLY=false` to enforce the policy. -- Pin third-party observability container images to fixed tags and rebuild - external reverse-proxy images on patched runtimes. If a scanner reports - a Go stdlib CVE in a binary this repo does not build, identify the - flagged container or proxy artifact and upgrade it separately. -- Restrict `cors.origins` to the exact domain(s) serving the SPA. -- Set `app.debug: false` in production so `/docs`, `/redoc`, and `/openapi.json` - are not served on the public hostname. -- Keep `operational.public: false` so `/health` and `/metrics` return **404** - to anonymous public clients (including vulnerability scanners hitting your ALB - hostname). AWS ALB target health checks connect directly from VPC addresses - (no `X-Forwarded-For`); include your VPC/LB CIDRs in - `operational.trusted_ips`. Full migration diagnostics are available at - `GET /health/detail` for org admins. - ---- - -## Team management: invitations & organizations - -EfficientAI is multi-tenant from the ground up. Every piece of data is -scoped to an **organization**, a user can be a member of more than one -organization, and each membership has a **role** that controls what -they can do. - -### Roles - -| Role | Can do | -| -------- | ---------------------------------------------------------- | -| `reader` | Read-only access to everything in the org. | -| `writer` | Everything a reader can + create/update/delete most resources. | -| `admin` | Everything a writer can + manage users, invitations, roles, API keys, and org settings. | - -The role is stored per membership, so the *same user* can be an `admin` -in one org and a `reader` in another. - -:::note Organization role is not the same as workspace role -Organization roles (`reader` / `writer` / `admin`) apply org-wide. **Workspace roles** (`Viewer` / `Editor` / `Workspace Admin`) apply per workspace and control access to call imports, metrics, agents, and other scoped data in the active workspace. Both layers apply together โ€” for example, an org **writer** with workspace **Viewer** can browse a workspace but cannot import or delete calls there. See [Workspaces โ€” Access control](/docs/getting-started/workspaces/#access-control-organization-vs-workspace) for the full hierarchy and action matrix. -::: - -### Inviting a teammate - -Admins invite teammates from **Settings โ†’ Team**. An invitation captures -an email and a role and stays valid for 7 days. From the same page, -admins can also: - -- See the current members of the org and change their role (with a - guard so you can't demote the last admin). -- Remove a member from the organization. -- Revoke a pending invitation. - -> **Delivery.** The backend creates the invitation record but does **not** -> send email out of the box โ€” plug in your own SMTP / transactional-mail -> provider in front of the invite creation event, or simply share the app -> URL with the invitee and let them discover the invitation on their -> profile page. - -### Accepting or declining an invitation - -When someone with a pending invitation signs in, their **Profile** page -lists the invitation with **Accept** and **Decline** buttons. Accepting -adds them to the organization with the role the admin chose; declining -clears the invitation. - -Accepting does **not** automatically switch the user into the new org โ€” -they stay in their current session until they decide to switch (see the -next section). To make this painless, the profile page shows a green -"Switch to <Org Name>" banner right after a successful acceptance. - -### Switching between organizations - -EfficientAI uses **scoped tokens**: every Bearer token is pinned to -exactly one organization. To act on behalf of a different org, the user -mints a new token for it โ€” this happens automatically from the UI. - -The header's **Organization Switcher** (building icon, top right) lists -every org the user belongs to. Picking one replaces the session token -with a fresh token scoped to that org, and invalidates all in-memory -caches so the dashboard re-fetches with the new scope. The user's role -in the target org can differ from their role in the source org. - -API keys can't switch organizations โ€” each key is bound to the org it -was minted in. For programmatic multi-tenant access, create a separate -API key inside each org you need to reach. - -:::tip Why scoped tokens instead of an ambient `X-Organization-Id` header? -A single-org token keeps every DB query, rate limiter, and audit log -automatically correct โ€” they only ever see one `organization_id`. An -ambient header would require auditing every query and rewriting the -org-resolution layer everywhere, with a much bigger blast radius if a -check is ever missed. This is also the model Stripe, Linear, and GitHub -use. -::: - ---- - -## Enterprise self-hosted (SSO via your IdP) - -For companies that already run Okta, Entra ID, Google Workspace, Cognito, -Auth0, or any other OIDC-compliant identity provider. Humans sign in via -SSO; machines keep using API keys. - -### 1. Drop in a license - -Request an enterprise license from the EfficientAI team (the JWT must -include the `oidc_sso` feature). Add it to `.env`: - -```bash title=".env" -EFFICIENTAI_LICENSE=eyJhbGciOi... -``` - -Or inline in `config.yml`: - -```yaml title="config.yml" -license: - key: "eyJhbGciOi..." -``` - -Without the `oidc_sso` feature, the `external_oidc` provider is -advertised by the backend but rejects sign-ins with a pointer to the -missing license feature. - -### 2. Register EfficientAI as an app in your IdP - -Create a **public OIDC client** (single-page app โ€” no client secret) with: - -| Field | Value | -| ---------------- | ----------------------------------------------------- | -| Application type | Single-page application (SPA) | -| Grant type | `authorization_code` (+ PKCE if your IdP requires it) | -| Redirect URI | `https:///login/callback` | -| Scopes | `openid profile email` | - -### 3. Point EfficientAI at the IdP - -```yaml title="config.yml" -auth: - # Drop local_password to force all humans through SSO. - providers: - - api_key - - external_oidc - - oidc: - issuer: "https://.okta.com" # REQUIRED - audience: "efficientai" # REQUIRED โ€” expected `aud` claim - client_id: "0oa..." # SPA client id from step 2 - - # Default org for new users whose token has no org claim. - default_org_name: "My Company" - - # Optional. If your IdP emits a custom claim (e.g. a group or tenant - # attribute), point to it here so a single IdP tenant can route users - # into different EfficientAI organizations. - # org_claim_path: ["https://efficientai.com/org"] -``` - -The backend verifies every incoming Bearer token against the IdP's JWKS, -which it auto-discovers from `/.well-known/openid-configuration`. -You never copy public keys by hand. - -When `external_oidc` is enabled, `issuer` and `audience` are mandatory. -The application fails at startup if either is unset, and every token's `aud` -claim must match `audience` โ€” tokens issued for other applications at the -same IdP are rejected. - -The same settings as env vars: - -```bash title=".env" -AUTH_PROVIDERS=api_key,external_oidc -AUTH_OIDC_ISSUER=https://.okta.com -AUTH_OIDC_AUDIENCE=efficientai -AUTH_OIDC_CLIENT_ID=0oa... -AUTH_OIDC_DEFAULT_ORG_NAME=My Company -# AUTH_OIDC_ORG_CLAIM_PATH=https://efficientai.com/org -``` - -### 4. Restart and sign in - -```bash -docker compose up -d -``` - -Open `https:///login` โ€” the SSO button appears automatically and -redirects to your IdP. - ---- - -## IdP recipes - -The shape of `issuer` / `audience` / `client_id` is always the same. Only -the issuer URL and a few registration clicks differ per IdP. - -
-Okta - -```yaml -auth: - oidc: - issuer: "https://.okta.com" - audience: "api://efficientai" # or the Okta API "audience" value - client_id: "0oa..." # SPA application client id -``` - -*Applications โ†’ Create App Integration โ†’ OIDC ยท Single-Page App*, then add -the redirect URI and assign the app to the users/groups that should be -allowed in. - -
- -
-Azure AD / Entra ID - -```yaml -auth: - oidc: - issuer: "https://login.microsoftonline.com//v2.0" - audience: "" - client_id: "" -``` - -*Entra ID โ†’ App registrations โ†’ New registration โ†’ SPA platform*, add the -redirect URI. Under *Token configuration* add the `email` optional claim. -For multi-tenant access, use `organizations` or `common` in the issuer -URL. - -
- -
-Google Workspace - -```yaml -auth: - oidc: - issuer: "https://accounts.google.com" - audience: ".apps.googleusercontent.com" - client_id: ".apps.googleusercontent.com" - default_org_name: "Example Inc" -``` - -*Google Cloud Console โ†’ APIs & Services โ†’ Credentials โ†’ Create OAuth -client ID โ†’ Web application*. Restrict the Workspace domain via the -consent screen so only your employees can sign in. - -
- -
-AWS Cognito - -```yaml -auth: - oidc: - issuer: "https://cognito-idp..amazonaws.com/" - audience: "" - client_id: "" -``` - -Cognito User Pool โ†’ *App integration โ†’ App client* (public, no secret), -enable the authorization code grant and `openid profile email` scopes, and -register the callback URL. - -
- -
-Auth0 - -```yaml -auth: - oidc: - issuer: "https://.auth0.com/" - audience: "https://api.efficientai.local" - client_id: "" -``` - -Auth0 *Applications โ†’ Single Page Application*. Define the API audience in -*APIs* and reference it here โ€” Auth0 issues access tokens for that -audience which the backend validates. - -
- ---- - -## How it fits together - -Every route depends on a single authentication step. The provider -registry walks each enabled provider in a fixed order and authenticates -the request against the first one whose credential is present: - -```mermaid -flowchart LR - Client["Request
(Bearer or X-API-Key)"] - Registry[ProviderRegistry] - ApiKey[ApiKeyProvider] - Local[LocalPasswordProvider] - OIDC["ExternalOIDCProvider
(license-gated)"] - IdP["Your IdP
(Okta / AAD / Google / Cognito / โ€ฆ)"] - Principal["Principal
(org_id, user_id, auth_method)"] - Route[Protected route] - - Client --> Registry - Registry -->|X-API-Key header| ApiKey - Registry -->|"bearer iss=efficientai-local"| Local - Registry -->|"bearer (any other issuer)"| OIDC - OIDC -.verify via JWKS.-> IdP - ApiKey --> Principal - Local --> Principal - OIDC --> Principal - Principal --> Route -``` - -- **API key** requests are matched on the `X-API-Key` header. -- **Bearer** tokens issued by EfficientAI itself are validated locally - with `SECRET_KEY`. -- All other Bearer tokens are treated as OIDC and validated against the - configured IdP's JWKS. - -The resulting principal always carries `(organization_id, user_id, -auth_method)`, so every downstream endpoint is multi-tenant and -audit-friendly out of the box. - ---- - -## Troubleshooting - -**"No authentication providers are enabled on this deployment."** -Your `auth.providers` list is empty or only names providers the current -license can't unlock. Include at least `api_key` and `local_password`, and -verify `EFFICIENTAI_LICENSE` grants the features you reference. - -**SSO tab is missing on the login screen even though `external_oidc` is in -`providers`.** -Either the license doesn't include `oidc_sso`, or `auth.oidc.issuer` is -empty. Check the live config in the backend's `/api/v1/auth/config` -response. - -**Users sign in via SSO but keep landing in a fresh org.** -Set `auth.oidc.default_org_name` to your company name, or emit a -deterministic `org` claim from your IdP and map it via -`auth.oidc.org_claim_path`. - -**Bearer tokens are rejected with "signature verification failed".** -Make sure the app pod can reach `/.well-known/openid-configuration` -and the JWKS endpoint it advertises. Egress proxies commonly block this. - -**Signup is disabled.** -`auth.local_password.allow_signup` is set to `false`. Re-enable it -temporarily, or invite the user from **Settings โ†’ Team** using an admin -account instead. - -**Setting a password from Profile says "This credential is not bound to a -user."** -You authenticated with a legacy API key that has no user attached. Open -your **Profile** page once (the backend lazily provisions a placeholder -user on that call), then retry. - -**After accepting an invitation nothing in the UI changes.** -Expected โ€” accepting only adds the membership, it doesn't switch your -session. Click the org switcher in the top bar (or use the green "Switch -to โ€ฆ" banner on the profile page) to mint a token scoped to the new org. - -**Org switcher says "API keys are bound to a single organization."** -Switching is only available for interactive (Bearer token) sessions. For -CI pipelines, generate a separate API key inside each organization you -need to reach. +--- +id: authentication +title: Authentication +sidebar_position: 3 +--- + +# Authentication + +EfficientAI ships with a pluggable authentication system that scales from a +single-operator OSS install to an enterprise deployment behind your existing +identity provider. You pick the providers you want in `config.yml` (or via +`AUTH_PROVIDERS` in `.env`) and the API/frontend adapt automatically. + +## Deployment models + +| Model | Providers | License needed | +| ------------------------- | ----------------------------- | -------------- | +| OSS self-hosted (default) | `api_key`, `local_password` | None | +| Enterprise SSO (BYO IdP) | `api_key`, `external_oidc` | `oidc_sso` | + +- **`api_key`** โ€” the `X-API-Key` header, always available, for programmatic + access (CI pipelines, SDKs, scripts). +- **`local_password`** โ€” email + password, verified against the local users + table, returns an app-signed HS256 Bearer token. Enabled by default. +- **`external_oidc`** โ€” license-gated. Verifies a Bearer JWT issued by your + OIDC-compliant IdP (Okta, Azure AD / Entra ID, Google Workspace, AWS + Cognito, Auth0, Ping, JumpCloud, OneLogin, โ€ฆ) against the issuer's JWKS. + +> **Why no bundled IdP?** +> In practice every enterprise already runs one. Shipping our own Keycloak +> alongside the app just added another thing for you to operate and lock +> down. `external_oidc` talks to whatever you already have. + +--- + +## Self-hosted (OSS) + +This is the default after `docker compose up -d` or `eai start-all`. No +license, no IdP, no external dependencies. + +```yaml title="config.yml" +auth: + providers: + - api_key + - local_password + local_password: + # Lifetime of the short-lived access token minted at sign-in. + token_ttl_minutes: 15 + refresh_token_ttl_days: 7 + # Let anyone who reaches the login page create an account + new org. + # Set to false once you've finished bootstrapping. + allow_signup: true +``` + +The equivalent environment variables (for Docker Compose / `.env`): + +```bash title=".env" +AUTH_PROVIDERS=api_key,local_password +AUTH_LOCAL_TOKEN_TTL_MINUTES=15 +AUTH_REFRESH_TOKEN_TTL_DAYS=7 +AUTH_LOCAL_ALLOW_SIGNUP=true + +# HS256 signing key for locally-issued Bearer tokens. Change this in prod! +SECRET_KEY=replace-me-with-a-long-random-string +``` + +### First-time bootstrap + +1. Start the stack. +2. Open `http://localhost:8000/` and click **Create account** on the login + screen. The first user you create becomes the admin of a fresh + organization. +3. Mint an API key from **Profile โ†’ API Keys** (or via + `scripts/create_api_key.py`) for programmatic access. + +### Password login (email + password) + +When `local_password` is enabled, the login screen shows a **Sign in** and +(if `allow_signup: true`) a **Create account** tab. Signing up provisions a +new user and a new organization, and makes that user the `admin` of it. If +you leave the organization name blank, the server derives one from the +email's local-part. + +Once signed in, the SPA holds a short-lived access token (15 minutes by +default) plus a refresh token. The client silently refreshes the access +token before it expires. You can change lifetimes with `token_ttl_minutes` +and `refresh_token_ttl_days`. Logout revokes the refresh token and +blacklists the current access token server-side. + +### Linking a password to an API-key-only account + +If you bootstrapped with `scripts/create_api_key.py`, the backend +provisions a placeholder user behind that key (its email ends in +`@efficientai.local`). You can upgrade this identity to a real email + +password login so you can sign in interactively with the same user. + +Do it from **Profile โ†’ Sign-in Password** while signed in via the API key +โ€” the page detects the placeholder email and prompts you to pick a real +one and a password. After saving, the same user can log in either with +the original API key (for machines) or with email + password (for humans). + +Rules the UI enforces: + +- If the user already has a password, the form asks for the current one + before accepting a new one. +- You can only set the email from that screen while it's still the + placeholder `@efficientai.local` address; "real" users change their + email from the main profile edit flow. + +### Hardening before you expose it to the internet + +- Turn off self-service signup once your team is in: + + ```yaml + auth: + local_password: + allow_signup: false + ``` + +- Rotate `SECRET_KEY` to invalidate existing sessions. +- Put the app behind a reverse proxy (Nginx, Caddy, Cloudflare) that + terminates TLS and enforces HSTS. +- The bundled FastAPI server sends baseline security headers on all + responses (`X-Frame-Options`, `X-Content-Type-Options`, `Referrer-Policy`, + `Cache-Control`, and `Content-Security-Policy-Report-Only` by default). If + you terminate traffic at an external reverse proxy, keep those headers (or + stricter CSP `frame-ancestors`) enabled there too. After reviewing CSP + violation reports, set `CSP_REPORT_ONLY=false` to enforce the policy. +- Pin third-party observability container images to fixed tags and rebuild + external reverse-proxy images on patched runtimes. If a scanner reports + a Go stdlib CVE in a binary this repo does not build, identify the + flagged container or proxy artifact and upgrade it separately. +- Restrict `cors.origins` to the exact domain(s) serving the SPA. +- Set `app.debug: false` in production so `/docs`, `/redoc`, and `/openapi.json` + are not served on the public hostname. +- Keep `operational.public: false` so `/health` and `/metrics` return **404** + to anonymous public clients (including vulnerability scanners hitting your ALB + hostname). AWS ALB target health checks connect directly from VPC addresses + (no `X-Forwarded-For`); include your VPC/LB CIDRs in + `operational.trusted_ips`. Full migration diagnostics are available at + `GET /health/detail` for org admins. + +--- + +## Team management: invitations & organizations + +EfficientAI is multi-tenant from the ground up. Every piece of data is +scoped to an **organization**, a user can be a member of more than one +organization, and each membership has a **role** that controls what +they can do. + +### Roles + +| Role | Can do | +| -------- | ---------------------------------------------------------- | +| `reader` | Read-only access to everything in the org. | +| `writer` | Everything a reader can + create/update/delete most resources. | +| `admin` | Everything a writer can + manage users, invitations, roles, API keys, and org settings. | + +The role is stored per membership, so the *same user* can be an `admin` +in one org and a `reader` in another. + +> **Organization role is not the same as workspace role** +> Organization roles (`reader` / `writer` / `admin`) apply org-wide. **Workspace roles** (`Viewer` / `Editor` / `Workspace Admin`) apply per workspace and control access to call imports, metrics, agents, and other scoped data in the active workspace. Both layers apply together โ€” for example, an org **writer** with workspace **Viewer** can browse a workspace but cannot import or delete calls there. See [Workspaces โ€” Access control](/docs/getting-started/workspaces/#access-control-organization-vs-workspace) for the full hierarchy and action matrix. + +### Inviting a teammate + +Admins invite teammates from **Settings โ†’ Team**. An invitation captures +an email and a role and stays valid for 7 days. From the same page, +admins can also: + +- See the current members of the org and change their role (with a + guard so you can't demote the last admin). +- Remove a member from the organization. +- Revoke a pending invitation. + +> **Delivery.** The backend creates the invitation record but does **not** +> send email out of the box โ€” plug in your own SMTP / transactional-mail +> provider in front of the invite creation event, or simply share the app +> URL with the invitee and let them discover the invitation on their +> profile page. + +### Accepting or declining an invitation + +When someone with a pending invitation signs in, their **Profile** page +lists the invitation with **Accept** and **Decline** buttons. Accepting +adds them to the organization with the role the admin chose; declining +clears the invitation. + +Accepting does **not** automatically switch the user into the new org โ€” +they stay in their current session until they decide to switch (see the +next section). To make this painless, the profile page shows a green +"Switch to <Org Name>" banner right after a successful acceptance. + +### Switching between organizations + +EfficientAI uses **scoped tokens**: every Bearer token is pinned to +exactly one organization. To act on behalf of a different org, the user +mints a new token for it โ€” this happens automatically from the UI. + +The header's **Organization Switcher** (building icon, top right) lists +every org the user belongs to. Picking one replaces the session token +with a fresh token scoped to that org, and invalidates all in-memory +caches so the dashboard re-fetches with the new scope. The user's role +in the target org can differ from their role in the source org. + +API keys can't switch organizations โ€” each key is bound to the org it +was minted in. For programmatic multi-tenant access, create a separate +API key inside each org you need to reach. + +> **Why scoped tokens instead of an ambient `X-Organization-Id` header?** +> A single-org token keeps every DB query, rate limiter, and audit log +> automatically correct โ€” they only ever see one `organization_id`. An +> ambient header would require auditing every query and rewriting the +> org-resolution layer everywhere, with a much bigger blast radius if a +> check is ever missed. This is also the model Stripe, Linear, and GitHub +> use. + +--- + +## Enterprise self-hosted (SSO via your IdP) + +For companies that already run Okta, Entra ID, Google Workspace, Cognito, +Auth0, or any other OIDC-compliant identity provider. Humans sign in via +SSO; machines keep using API keys. + +### 1. Drop in a license + +Request an enterprise license from the EfficientAI team (the JWT must +include the `oidc_sso` feature). Add it to `.env`: + +```bash title=".env" +EFFICIENTAI_LICENSE=eyJhbGciOi... +``` + +Or inline in `config.yml`: + +```yaml title="config.yml" +license: + key: "eyJhbGciOi..." +``` + +Without the `oidc_sso` feature, the `external_oidc` provider is +advertised by the backend but rejects sign-ins with a pointer to the +missing license feature. + +### 2. Register EfficientAI as an app in your IdP + +Create a **public OIDC client** (single-page app โ€” no client secret) with: + +| Field | Value | +| ---------------- | ----------------------------------------------------- | +| Application type | Single-page application (SPA) | +| Grant type | `authorization_code` (+ PKCE if your IdP requires it) | +| Redirect URI | `https:///login/callback` | +| Scopes | `openid profile email` | + +### 3. Point EfficientAI at the IdP + +```yaml title="config.yml" +auth: + # Drop local_password to force all humans through SSO. + providers: + - api_key + - external_oidc + + oidc: + issuer: "https://.okta.com" # REQUIRED + audience: "efficientai" # REQUIRED โ€” expected `aud` claim + client_id: "0oa..." # SPA client id from step 2 + + # Default org for new users whose token has no org claim. + default_org_name: "My Company" + + # Optional. If your IdP emits a custom claim (e.g. a group or tenant + # attribute), point to it here so a single IdP tenant can route users + # into different EfficientAI organizations. + # org_claim_path: ["https://efficientai.com/org"] +``` + +The backend verifies every incoming Bearer token against the IdP's JWKS, +which it auto-discovers from `/.well-known/openid-configuration`. +You never copy public keys by hand. + +When `external_oidc` is enabled, `issuer` and `audience` are mandatory. +The application fails at startup if either is unset, and every token's `aud` +claim must match `audience` โ€” tokens issued for other applications at the +same IdP are rejected. + +The same settings as env vars: + +```bash title=".env" +AUTH_PROVIDERS=api_key,external_oidc +AUTH_OIDC_ISSUER=https://.okta.com +AUTH_OIDC_AUDIENCE=efficientai +AUTH_OIDC_CLIENT_ID=0oa... +AUTH_OIDC_DEFAULT_ORG_NAME=My Company +# AUTH_OIDC_ORG_CLAIM_PATH=https://efficientai.com/org +``` + +### 4. Restart and sign in + +```bash +docker compose up -d +``` + +Open `https:///login` โ€” the SSO button appears automatically and +redirects to your IdP. + +--- + +## IdP recipes + +The shape of `issuer` / `audience` / `client_id` is always the same. Only +the issuer URL and a few registration clicks differ per IdP. + +
+Okta + +```yaml +auth: + oidc: + issuer: "https://.okta.com" + audience: "api://efficientai" # or the Okta API "audience" value + client_id: "0oa..." # SPA application client id +``` + +*Applications โ†’ Create App Integration โ†’ OIDC ยท Single-Page App*, then add +the redirect URI and assign the app to the users/groups that should be +allowed in. + +
+ +
+Azure AD / Entra ID + +```yaml +auth: + oidc: + issuer: "https://login.microsoftonline.com//v2.0" + audience: "" + client_id: "" +``` + +*Entra ID โ†’ App registrations โ†’ New registration โ†’ SPA platform*, add the +redirect URI. Under *Token configuration* add the `email` optional claim. +For multi-tenant access, use `organizations` or `common` in the issuer +URL. + +
+ +
+Google Workspace + +```yaml +auth: + oidc: + issuer: "https://accounts.google.com" + audience: ".apps.googleusercontent.com" + client_id: ".apps.googleusercontent.com" + default_org_name: "Example Inc" +``` + +*Google Cloud Console โ†’ APIs & Services โ†’ Credentials โ†’ Create OAuth +client ID โ†’ Web application*. Restrict the Workspace domain via the +consent screen so only your employees can sign in. + +
+ +
+AWS Cognito + +```yaml +auth: + oidc: + issuer: "https://cognito-idp..amazonaws.com/" + audience: "" + client_id: "" +``` + +Cognito User Pool โ†’ *App integration โ†’ App client* (public, no secret), +enable the authorization code grant and `openid profile email` scopes, and +register the callback URL. + +
+ +
+Auth0 + +```yaml +auth: + oidc: + issuer: "https://.auth0.com/" + audience: "https://api.efficientai.local" + client_id: "" +``` + +Auth0 *Applications โ†’ Single Page Application*. Define the API audience in +*APIs* and reference it here โ€” Auth0 issues access tokens for that +audience which the backend validates. + +
+ +--- + +## How it fits together + +Every route depends on a single authentication step. The provider +registry walks each enabled provider in a fixed order and authenticates +the request against the first one whose credential is present: + +- **API key** requests are matched on the `X-API-Key` header. +- **Bearer** tokens issued by EfficientAI itself are validated locally + with `SECRET_KEY`. +- All other Bearer tokens are treated as OIDC and validated against the + configured IdP's JWKS. + +The resulting principal always carries `(organization_id, user_id, +auth_method)`, so every downstream endpoint is multi-tenant and +audit-friendly out of the box. + +--- + +## Troubleshooting + +**"No authentication providers are enabled on this deployment."** +Your `auth.providers` list is empty or only names providers the current +license can't unlock. Include at least `api_key` and `local_password`, and +verify `EFFICIENTAI_LICENSE` grants the features you reference. + +**SSO tab is missing on the login screen even though `external_oidc` is in +`providers`.** +Either the license doesn't include `oidc_sso`, or `auth.oidc.issuer` is +empty. Check the live config in the backend's `/api/v1/auth/config` +response. + +**Users sign in via SSO but keep landing in a fresh org.** +Set `auth.oidc.default_org_name` to your company name, or emit a +deterministic `org` claim from your IdP and map it via +`auth.oidc.org_claim_path`. + +**Bearer tokens are rejected with "signature verification failed".** +Make sure the app pod can reach `/.well-known/openid-configuration` +and the JWKS endpoint it advertises. Egress proxies commonly block this. + +**Signup is disabled.** +`auth.local_password.allow_signup` is set to `false`. Re-enable it +temporarily, or invite the user from **Settings โ†’ Team** using an admin +account instead. + +**Setting a password from Profile says "This credential is not bound to a +user."** +You authenticated with a legacy API key that has no user attached. Open +your **Profile** page once (the backend lazily provisions a placeholder +user on that call), then retry. + +**After accepting an invitation nothing in the UI changes.** +Expected โ€” accepting only adds the membership, it doesn't switch your +session. Click the org switcher in the top bar (or use the green "Switch +to โ€ฆ" banner on the profile page) to mint a token scoped to the new org. + +**Org switcher says "API keys are bound to a single organization."** +Switching is only available for interactive (Bearer token) sessions. For +CI pipelines, generate a separate API key inside each organization you +need to reach. diff --git a/docs-fumadocs/content/docs/getting-started/installation.mdx b/docs-fumadocs/content/docs/getting-started/installation.mdx index e6c792ef..217dcb81 100644 --- a/docs-fumadocs/content/docs/getting-started/installation.mdx +++ b/docs-fumadocs/content/docs/getting-started/installation.mdx @@ -1,289 +1,9 @@ --- -id: installation -title: Installation -sidebar_position: 1 +title: Installation (Moved) --- -# ๐Ÿš€ Quick Start +# This page moved -There are two ways to run the application: +Installation content moved to the new Quickstart section. -## Method 1: Using Docker Compose (Recommended) - -Start all services with a single command: - -```bash -docker compose up -d -``` - -This will automatically: - -- **Pull pre-built images** from GitHub Container Registry (no build required!) -- Start all services (database, Redis, API, worker) -- Run database migrations automatically on startup - -The first run will download ~4GB of images, which typically takes 1-2 minutes depending on your internet speed. - -### Configure for Docker - -Docker Compose mounts **`config.docker.yml`** from your project root into every app container as `/app/config.yml`. Containers do **not** read the host `config.yml` used by CLI mode. - -1. Copy the example config: - -```bash -cp config.yml.example config.docker.yml -``` - -2. Edit `config.docker.yml` for Docker networking and your integrations: - -```yaml -database: - url: "postgresql://efficientai:password@db:5432/efficientai" - -redis: - url: "redis://redis:6379/0" - -celery: - broker_url: "redis://redis:6379/0" - result_backend: "redis://redis:6379/0" - -storage: - upload_dir: "/app/uploads" - blob_provider: s3 # or gcs or azure - -# Enable and fill in s3: or gcs: for Data Sources, plus auth, diarization, etc. -``` - -Use the Docker service hostnames `db` and `redis` (not `localhost`). Match database credentials to your `.env` or `docker-compose.yml` defaults (`POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB`). - -`docker-compose.yml` also sets some values via environment variables (`DATABASE_URL`, `REDIS_URL`, `SECRET_KEY`, โ€ฆ), but **cloud storage, auth, diarization, and other YAML-only settings must live in `config.docker.yml`**. - -See [Configuration](/docs/reference/configuration/) and [Cloud Storage](/docs/getting-started/cloud-storage/) for the full option reference. - -### Using a Specific Version - -You can pin to a specific release version for stability: - -```bash -# Use a specific version -EFFICIENTAI_VERSION=1.0.0 docker compose up -d - -# Or add to your .env file for persistence -echo "EFFICIENTAI_VERSION=1.0.0" >> .env -docker compose up -d -``` - -### Initialize database - -Migrations run automatically on startup, but you can also run manually: - -```bash -# Option 1: Let migrations run automatically on startup -# (No action needed - migrations run when the app starts) - -# Option 2: Run migrations manually before starting -docker compose exec api eai migrate -``` - -### Create an API key - -```bash -docker compose exec api python scripts/create_api_key.py "My API Key" -``` - -### Access the application - -- Frontend: http://localhost:8000/ -- API Docs: http://localhost:8000/docs - -### Building Locally (for development) - -If you want to build images locally instead of pulling pre-built ones (e.g., for development): - -```bash -# Edit docker-compose.yml to uncomment the 'build' sections, then: -docker compose up -d --build - -# Or rebuild without cache for a clean build -docker compose build --no-cache api worker -docker compose up -d -``` - -## Method 2: Using Command Line (CLI) - -### Install the package - -```bash -pip install -e . -``` - -### Generate configuration file - -```bash -eai init-config -``` - -Edit `config.yml` with your settings: - -```yaml -# EfficientAI Configuration File - -# Application Settings -app: - name: "Voice AI Evaluation Platform" - version: "0.1.0" - debug: true # Set to false in production - secret_key: "your-secret-key-here-change-in-production" - -# Server Settings -server: - host: "0.0.0.0" - port: 8000 - -# Database Configuration (Required) -database: - url: "postgresql://efficientai:password@localhost:5432/efficientai" - -# Redis Configuration (Required) -redis: - url: "redis://localhost:6379/0" - -# Celery Configuration -celery: - broker_url: "redis://localhost:6379/0" - result_backend: "redis://localhost:6379/0" - -# File Storage -storage: - upload_dir: "./uploads" - max_file_size_mb: 500 - allowed_audio_formats: - - "wav" - - "mp3" - - "flac" - - "m4a" - -# S3 Configuration (Optional - for cloud audio storage) -s3: - enabled: false - bucket_name: "your-s3-bucket-name" - region: "us-east-1" - access_key_id: "your-access-key-id" - secret_access_key: "your-secret-access-key" - endpoint_url: null # For S3-compatible services (MinIO, DigitalOcean Spaces) - prefix: "audio/" - -# CORS Settings -cors: - origins: - - "http://localhost:3000" - - "http://localhost:8000" - -# API Settings -api: - prefix: "/api/v1" - key_header: "X-API-Key" - rate_limit_per_minute: 60 -``` - -> **Important**: Make sure to change `secret_key` to a secure random value in production! - -### Start the application and worker - -**Option A: Start both together (Recommended)** - -```bash -eai start-all --config config.yml -``` - -This single command will: - -- Start the API server -- Start the Celery worker (for background task processing) -- Run database migrations automatically -- Build the frontend (if needed) - -Press `Ctrl+C` to stop both services together. - -**Option B: Start separately (for advanced use)** - -In one terminal, start the application: - -```bash -eai start --config config.yml -``` - -In another terminal, start the Celery worker: - -```bash -eai worker --config config.yml -``` - -Or use the Celery command directly: - -```bash -celery -A app.workers.celery_app worker --loglevel=info -``` - -The application will automatically: - -- Run database migrations (ensures schema is up to date) -- Build the frontend (if needed) -- Start the API server -- Serve both API and frontend from the same server - -**Important**: Migrations run automatically before startup. If migrations fail, the app won't start. - -### For development with hot reload - -```bash -# Enable auto-rebuild of frontend on file changes -eai start-all --config config.yml --watch-frontend -``` - -This will: - -- Automatically rebuild the frontend when source files change -- Keep the backend hot-reload enabled (by default) -- Perfect for active frontend development - -### Access the application - -- Frontend: http://localhost:8000/ -- API Docs: http://localhost:8000/docs - -## Prerequisites - -**For Docker Compose**: -- Docker and Docker Compose installed -- ~4GB disk space for pre-built images - -**For CLI**: -- Python 3.11+ -- Node.js 18+ and npm -- PostgreSQL running (locally or remote) -- Redis running (locally or remote) - -## Docker Images - -EfficientAI provides pre-built Docker images hosted on GitHub Container Registry: - -| Image | Description | Size | -|-------|-------------|------| -| `ghcr.io/efficientai-tech/efficientai-api` | API server + frontend | ~1.5GB | -| `ghcr.io/efficientai-tech/efficientai-worker` | Celery worker with ML models | ~4GB | - -### Available Tags - -- `latest` - Most recent build from main branch -- `x.y.z` - Specific version (e.g., `1.0.0`) -- `x.y` - Latest patch of a minor version (e.g., `1.0`) - -### Manual Pull (Optional) - -Images are pulled automatically by `docker compose up`, but you can pre-pull them: - -```bash -docker pull ghcr.io/efficientai-tech/efficientai-api:latest -docker pull ghcr.io/efficientai-tech/efficientai-worker:latest -``` +Go to [Quickstart](/docs/quickstart/). diff --git a/docs-fumadocs/content/docs/getting-started/integrations.mdx b/docs-fumadocs/content/docs/getting-started/integrations.mdx index 3a2002d7..33b1053d 100644 --- a/docs-fumadocs/content/docs/getting-started/integrations.mdx +++ b/docs-fumadocs/content/docs/getting-started/integrations.mdx @@ -1,217 +1,9 @@ --- -id: integrations -title: Integrations -sidebar_position: 4 +title: Integrations (Moved) --- -# Integrations +# This page moved -Integrations in EfficientAI are not limited to external voice-agent platforms. You can connect integrations across three layers of the stack: +Integrations now have dedicated pages in the new Integrations section. -1. **Voice agent platforms** (agent/runtime side) -2. **AI providers** (LLM/STT/TTS model side) -3. **Telephony providers** (PSTN/number/routing side) - -This lets you test and evaluate the complete call path from model behavior to phone-network delivery. - -## Integrations UI - -![Integrations configuration page](/screenshots/integration-section.png) - -## 1) Voice platform integrations (agent side) - -Voice platform integrations connect EfficientAI to externally hosted voice agents. - -
- {[ - { name: 'Retell', logo: '/retellai.png' }, - { name: 'Vapi', logo: '/vapiai.jpg' }, - { name: 'ElevenLabs', logo: '/elevenlabs.jpg' }, - { name: 'Deepgram', logo: '/deepgram.png' }, - { name: 'Cartesia', logo: '/cartesia.jpg' }, - { name: 'Murf', logo: '/murf.png' }, - { name: 'Sarvam', logo: '/sarvam.png' }, - { name: 'VoiceMaker', logo: '/voiceMaker.png' }, - { name: 'Smallest.ai', logo: '/smallest.jpeg' }, - ].map((item) => ( -
- {`${item.name} -

{item.name}

-
- ))} -
- -With these integrations, you can run provider-backed calls, ingest transcripts/call metadata, and evaluate outcomes in EfficientAI. - -## 2) AI provider integrations (LLM layer) - -AI provider integrations connect model vendors used by your Voice Bundles and evaluation workflows. - -
- {[ - { name: 'OpenAI', logo: '/openai-logo.png' }, - { name: 'Anthropic', logo: '/anthropic.png' }, - { name: 'Google', logo: '/geminiai.png' }, - { name: 'xAI', logo: '/xai.svg' }, - { name: 'Cohere', logo: '/cohere.svg' }, - { name: 'Mistral', logo: '/mistral.svg' }, - { name: 'Meta', logo: '/metaai.png' }, - { name: 'Together', logo: '/togetherai.svg' }, - { name: 'Perplexity', logo: '/perplexity-ai.svg' }, - { name: 'Azure', logo: '/azureai.png' }, - { name: 'AWS', logo: '/AWS_logo.png' }, - ].map((item) => ( -
- {`${item.name} -

{item.name}

-
- ))} -
- -These providers power model-side capabilities for generation and speech pipelines depending on your configuration. - -## 3) Telephony provider integrations - -Telephony integrations connect your phone-network provider to EfficientAI. - -
- {[ - { name: 'Plivo', logo: '/plivo.png' }, - { name: 'Exotel', logo: '/exotel.jpg' }, - ].map((item) => ( -
- {`${item.name} -

{item.name}

-
- ))} -
- -These integrations handle telephony-specific setup like credentials, number sync, and routing-related configuration used by call workflows. - -## LLM Gateway (batch/eval routing) - -Batch and evaluation LLM workloads (evaluators, GEPA, call-import LLM steps) can be routed through an optional **LLM Gateway** instead of calling providers directly. Real-time voice agents are **not** routed through the gateway. - -Configure a **platform default** in `config.yml` and optional **per-organization overrides** from **Configurations โ†’ Integrations โ†’ LLM Gateway**. - -Supported gateway types: - -- **Bifrost** โ€” point at your Bifrost LiteLLM proxy (URL must include the `/litellm` path, e.g. `http://localhost:8080/litellm`). -- **LiteLLM Proxy** โ€” point at a self-hosted LiteLLM Proxy instance (e.g. `http://localhost:4000`). - -### Platform default (`config.yml`) - -```yaml -llm_gateway: - enabled: true - type: bifrost # bifrost | litellm_proxy - base_url: "http://localhost:8080/litellm" - virtual_key: null # Bifrost only (sent as x-bf-vk) - master_key: null # LiteLLM Proxy only - passthrough_provider_keys: false # false = provider keys live in the gateway -``` - -When `passthrough_provider_keys` is `false`, AI provider integrations can omit API keys and use a **Gateway managed** placeholder instead. That setting is **platform-wide only** โ€” it cannot be overridden per organization. - -### Organization settings (Integrations UI) - -Each organization can choose how it uses the gateway. The modal shows an **Effective routing** badge after save โ€” that is the merged result actually used for LLM calls (`Bifrost`, `LiteLLM Proxy`, or `Direct`). - -#### Organization mode - -| Mode | Behavior | -|------|----------| -| **Inherit platform default** | Follows the platform `llm_gateway.enabled` flag. When the platform has the gateway enabled, this org uses the gateway. Choose **Disabled** to opt out, or override type, URL, or keys below. | -| **Enabled (use gateway)** | Forces gateway routing for this org even if the platform default is disabled. You must have a resolvable base URL (org override or platform default). | -| **Disabled (direct to providers)** | Opts this org out entirely. LLM calls go straight to provider APIs; gateway type, URL, and key overrides are ignored. | - -#### Partial overrides (while inheriting) - -When organization mode is **Inherit** or **Enabled**, you can override individual fields without replacing the whole configuration. Anything left blank or set to **Inherit platform** falls back to the platform default. - -| Field | Inherit / blank | Org override | -|-------|-----------------|--------------| -| **Gateway type** | Platform `type` | Org value (`Bifrost` or `LiteLLM Proxy`) | -| **Base URL** | Platform `base_url` | Org URL | -| **Virtual key** (Bifrost) | Platform `virtual_key` | Org-stored key (org wins if set) | -| **Master key** (LiteLLM Proxy) | Platform `master_key` | Org-stored key (org wins if set) | -| **Passthrough provider keys** | Platform setting only | Not configurable per org | - -**Important:** Inherit mode does **not** mean โ€œignore my overrides.โ€ You can inherit platform enablement while still overriding gateway type, base URL, or keys. Those overrides are applied on top of the inherited on/off decision. - -If organization mode is **Inherit** but the platform has the gateway **disabled**, the org routes **direct** regardless of any stored type or URL overrides (overrides remain saved but inactive until the platform enables the gateway or you switch the org to **Enabled**). - -### How settings merge - -Resolution is field-by-field: - -1. **On/off** โ€” org **Disabled** โ†’ direct. Org **Enabled** โ†’ gateway on. Org **Inherit** โ†’ follow platform `enabled`. -2. **Gateway type** โ€” org override if set, else platform `type`. -3. **Base URL** โ€” org override if set, else platform `base_url`. If no URL resolves, the org falls back to direct routing. -4. **Keys** โ€” org virtual key / master key if stored, else platform keys. - -### Examples - -Platform default: - -```yaml -llm_gateway: - enabled: true - type: bifrost - base_url: "http://localhost:8080/litellm" - passthrough_provider_keys: false -``` - -| Org mode | Gateway type | Base URL override | Effective result | -|----------|--------------|-------------------|------------------| -| Inherit | Inherit | *(blank)* | Bifrost @ platform URL, platform keys | -| Inherit | Inherit | `http://customer:9090/litellm` | Bifrost @ org URL, platform keys | -| Inherit | LiteLLM Proxy | `http://org-proxy:4000` | LiteLLM Proxy @ org URL | -| Inherit | LiteLLM Proxy | *(blank)* | LiteLLM Proxy type + **platform URL** โ€” override the URL too if the platform URL is Bifrost-specific | -| Enabled | Bifrost | `http://customer:9090/litellm` | Gateway forced on even if platform is disabled | -| Disabled | *(any)* | *(any)* | Direct to providers | - -### Practical guidance - -- **Different Bifrost instance for one customer?** Keep mode and gateway type on inherit; set **Base URL override** only. -- **Different gateway product for one org?** Override **both** gateway type and base URL so they match. -- **Different auth for one org?** Set an org **virtual key** (Bifrost) or **master key** (LiteLLM Proxy). Org keys take precedence over platform keys. -- **Confirm behavior** โ€” after saving, check the **Effective routing** badge and resolved base URL shown in the LLM Gateway modal. - -### Scope and limitations - -- Routes batch/eval LiteLLM calls only (evaluators, GEPA, call-import LLM steps). -- Does not route real-time voice agent sessions. -- Gemini and other native-path providers are automatically sent through the gatewayโ€™s OpenAI-compatible chat-completions API (not provider-native URLs like `:generateContent`). -- File uploads used by some Gemini diarisation flows (`litellm.create_file`) are not proxied through the gateway. - -## What integrations enable in practice - -Once linked, an agent can: - -- execute tests through external voice providers, -- use configured AI providers for model operations, -- run telephony-connected flows when phone network integration is needed, -- evaluate all of the above inside the same metrics/reporting loop. - -## Agent fields commonly used for external voice platforms - -When mapping an agent to an external voice platform, these fields are typically configured on the agent: - -- `voice_ai_integration_id`: integration connection reference. -- `voice_ai_agent_id`: provider-side agent identifier. -- `call_medium = web_call`: required for web-call testing workflows. - -## Recommended setup flow - -1. Configure your required integrations (voice platform, AI provider, telephony as needed). -2. Link the agent to the relevant voice platform integration and provider-side agent ID. -3. Configure Voice Bundles to use your chosen AI providers. -4. Add telephony configuration if your flow requires phone-network execution. -5. Run and compare outcomes in Playground/evaluator workflows. - -## Backlinks - -- Agent-level capability overview: [Agents](/docs/products/agents/) -- Internal test stack alternative: [Voice Bundles](/docs/getting-started/voice-bundles/) -- Product walkthrough where integrations are managed: [Configuration - Integrations](/docs/reference/configuration/) +Go to [Integrations Overview](/docs/integrations/). diff --git a/docs-fumadocs/content/docs/getting-started/voice-bundles.mdx b/docs-fumadocs/content/docs/getting-started/voice-bundles.mdx index e66ba18a..e594a4bb 100644 --- a/docs-fumadocs/content/docs/getting-started/voice-bundles.mdx +++ b/docs-fumadocs/content/docs/getting-started/voice-bundles.mdx @@ -1,45 +1,9 @@ --- -id: voice-bundles -title: Voice Bundles -sidebar_position: 5 +title: Voice Bundles (Moved) --- -# Voice Bundles +# This page moved -Voice Bundles define the internal speech pipeline used by the EfficientAI Test Agent path. +Voice bundle setup is now covered in the Platform setup flow. -## Voice Bundle UI - -![Voice bundle setup](/screenshots/voice-bundle.png) - -## Why voice bundles matter - -A voice bundle gives you repeatable, controlled test conditions so you can compare prompt and model changes without provider-side drift. - -## Supported bundle types - -- **STT + LLM + TTS** -- **S2S (speech-to-speech)** - -For STT + LLM + TTS bundles, you configure provider/model settings per stage and optional parameters like temperature, token limits, and **TTS output frequency** (8, 16, or 22 kHz where the provider supports it; default 8 kHz). - -## Live call silence timeout - -Inbound phone calls and outbound simulation calls automatically end if no voice activity is detected from either party for **15 seconds** after the call connects. - -## When to use voice bundles vs integrations - -- Use **voice bundles** when you want tightly controlled internal testing. -- Use **integrations** when you want to test external provider behavior end-to-end. - -## Typical workflow - -1. Configure a voice bundle in the platform. -2. Attach `voice_bundle_id` to an agent. -3. Run tests in Playground or evaluator flows. -4. Compare outcomes over time using consistent bundle settings. - -## Backlinks - -- Agent capability overview: [Agents](/docs/products/agents/) -- External provider path setup: [Integrations](/docs/getting-started/integrations/) +Go to [Platform Setup](/docs/platform/setup/). diff --git a/docs-fumadocs/content/docs/getting-started/workspaces.mdx b/docs-fumadocs/content/docs/getting-started/workspaces.mdx index abb7fdf5..72838cfc 100644 --- a/docs-fumadocs/content/docs/getting-started/workspaces.mdx +++ b/docs-fumadocs/content/docs/getting-started/workspaces.mdx @@ -1,221 +1,205 @@ ---- -id: workspaces -title: Workspaces -sidebar_position: 2 ---- - -# Workspaces - -## Overview - -Workspaces provide **in-organization project isolation**. Multiple teams or projects can share one EfficientAI organization while keeping their agents, metrics, call imports, and prompt libraries separate. - -Every organization starts with a **Default** workspace. You can create additional workspaces for individual teams, customers, or pilots without provisioning separate orgs. - ---- - -## Workspace switcher - -The workspace switcher lives at the top of the left sidebar, directly under the EfficientAI logo. - -From the switcher you can: - -- See which workspace is currently active -- Switch to another workspace in your organization -- Create a new workspace (display name + slug) - -![Create workspace modal](/screenshots/create_workspace.png) - -When creating a workspace, you set a display name and optional slug. You are added automatically as **Workspace Admin**; you can optionally invite org members and assign each a workspace role (Viewer, Editor, or Workspace Admin) before saving. - -When you switch workspaces, all data views refetch automatically so you never see stale rows from the previous workspace. - ---- - -## How scoping works - -The UI stores your active workspace in the browser and sends it on every API request as the `X-Workspace-Id` header. The backend uses this header to scope listings and creates to the selected workspace. - -If a request arrives without the header, the backend falls back to the organization's **Default** workspace. - ---- - -## Access control: organization vs workspace - -EfficientAI uses **two independent permission layers**. Both apply on every request: - -1. **Organization role** โ€” set per membership in **Settings โ†’ Team** (`reader`, `writer`, or `admin`). -2. **Workspace role** โ€” set per workspace in **Identity & Access Management โ†’ Workspace Members** (`Viewer`, `Editor`, or `Workspace Admin`, plus optional custom roles). - -A user must satisfy **both** layers to perform an action. Your organization role controls whether you can write **anywhere** in the org; your workspace role controls what you can do **inside the active workspace**. - -```mermaid -flowchart TD - request[API request with X-Workspace-Id] - orgCheck{Org role} - wsCheck{Workspace capabilities} - allow[Action succeeds] - denyOrg["403: org reader cannot mutate"] - denyWs["403: insufficient workspace role"] - - request --> orgCheck - orgCheck -->|reader + POST/PATCH/DELETE| denyOrg - orgCheck -->|writer or admin| wsCheck - wsCheck -->|capability present| allow - wsCheck -->|capability missing| denyWs -``` - -### Organization roles - -| Role | Scope | Typical use | -| ---- | ----- | ----------- | -| **Reader** | Read-only for the **entire organization** | Auditors, stakeholders who only view dashboards | -| **Writer** | Create, update, and delete most org resources | Engineers and operators doing day-to-day work | -| **Admin** | Everything a writer can do, plus user/team management, API keys, and org settings | Org owners and IT admins | - -:::info Org readers are always read-only -If your organization role is **Reader**, every mutating API call (`POST`, `PATCH`, `DELETE`) is blocked โ€” even if you hold **Workspace Admin** in a workspace. Workspace roles cannot override an org-level read-only membership. -::: - -Org admins **bypass workspace membership checks** and receive all workspace capabilities in every workspace. API keys also bypass workspace RBAC (they remain org-scoped). - -Manage organization roles from **Settings โ†’ Team** (admin only). See [Authentication โ€” Team management](/docs/getting-started/authentication/#team-management-invitations--organizations). - -### Workspace roles (system) - -Each workspace has its own membership list. When you are added to a workspace, you receive one of three seeded system roles (or a custom role defined by an org admin): - -| Workspace role | Can do | Cannot do | -| -------------- | ------ | --------- | -| **Viewer** | View calls, metrics, evals, simulations, reports, and workspace members | Import, edit, delete, run evaluations, change settings, manage members | -| **Editor** | Everything Viewer can do, plus create/update resources (import calls, manage metrics, run evals, manage simulations, generate reports) | Delete call imports, rename workspace, add/remove members, change workspace roles | -| **Workspace Admin** | Full access in that workspace, including delete, workspace settings, and member management | โ€” | - -Roles are **cumulative**: Editor includes all Viewer permissions; Workspace Admin includes all Editor permissions. - -### What each role needs for common actions - -Use this table when planning access. โ€œOrgโ€ = organization role; โ€œWorkspaceโ€ = role in the **active** workspace (from the switcher). - -| Action | Minimum org role | Minimum workspace role | -| ------ | ---------------- | ---------------------- | -| View call imports, agents, metrics | Reader | Viewer | -| Upload / import calls, edit rows | Writer | Editor | -| Delete call imports or batches | Writer | **Workspace Admin** | -| Create or edit metrics (workspace-scoped) | Writer | Editor | -| Run evaluations | Writer | Editor | -| Rename a workspace | Writer | **Workspace Admin** | -| Add/remove workspace members | Writer | **Workspace Admin** | -| Create a new workspace | Writer | *(creator becomes Workspace Admin automatically)* | -| Delete a workspace | Admin | *(org admin only)* | -| Manage organization users & invitations | Admin | *(not workspace-scoped)* | - -When a workspace check fails, the API returns a plain-language message such as *โ€œThis action requires at least the Editor role in the active workspace. Your current workspace role is Viewer.โ€* Delete operations require **Workspace Admin**, not Editor. - -### Capability domains (reference) - -Workspace permissions are implemented as **capabilities** grouped by product area. System roles are bundles of these capabilities; org admins can also define **custom workspace roles** in **IAM โ†’ Workspace Roles** by picking capabilities from this registry. - -| Domain | View | Create / edit / run | Delete / admin | -| ------ | ---- | ------------------- | -------------- | -| **Calls** (call imports) | View batches and rows | Import and update | Delete imports | -| **Metrics** | View definitions | Manage metrics | โ€” | -| **Evaluations** | View runs and results | Run evaluations | โ€” | -| **Simulation** | View agents, personas, scenarios | Manage simulation resources | โ€” | -| **Reports** | View reports | Generate reports | โ€” | -| **Workspace** | View member list | โ€” | Rename workspace; add/remove members and roles | - -Custom roles are useful when a user needs a narrow slice of access (for example, view + run evals but not import calls). Assign them per workspace from **IAM โ†’ Workspace Members**. - -### Default access for new members - -When workspace RBAC is enabled or a new workspace is created: - -- New workspaces: the **creator** is added as **Workspace Admin**. -- Existing org members may be backfilled into workspaces with roles mapped from their org role: org admin โ†’ Workspace Admin, writer โ†’ Editor, reader โ†’ Viewer. - -Org admins should review **IAM โ†’ Workspace Members** after creating workspaces and remove or downgrade memberships that are too broad for your team model. - -### Managing workspace access - -1. Open **Identity & Access Management** in the sidebar. -2. Go to **Workspace Members**, select a workspace, and assign roles to org members. -3. Org admins can define custom roles under **Workspace Roles**. - -![IAM Workspace Members](/screenshots/iam_workspaces.png) - -The workspace dropdown shows your current role in the selected workspace (for example, **Viewer**). Use the members table to review who has access and change roles โ€” if you hold **Workspace Admin** in that workspace and are an org Writer or Admin. - -Notes: - -- You can only manage members in a workspace if you are an **org Writer or Admin** **and** hold **Workspace Admin** (or org admin) in that workspace. -- **Workspace Admins cannot demote their own role**; another admin must change it. -- Users with org **Reader** can see member lists where allowed but cannot change memberships. - ---- - -## What is workspace-scoped - -Workspaces isolate the resources you interact with day to day, including: - -| Category | Resources | -|----------|-----------| -| Simulation | Agents, Personas, Scenarios, Evaluators | -| Evaluation | Evaluator results, legacy evaluations | -| Metrics | Custom and built-in metrics (when created with workspace scope) | -| Call imports | Call import batches and evaluations | -| Prompt tooling | Prompt partials, prompt optimization runs | -| Voice playground | Comparisons, samples, blind-test shares | -| Judge alignment | Judge datasets and runs | - -Switching workspace changes which rows appear in each of these sections. - ---- - -## Organization-wide resources - -Some metrics can be created with **organization** scope instead of workspace scope. Organization-scoped metrics: - -- Are stored with `workspace_id = null` -- Appear in **every** workspace in the org -- Are useful for shared rubrics, compliance checks, or standard evaluation criteria - -When creating a metric or categorization label group, choose **Organization** visibility if the rubric should be shared; choose **Workspace** (the default) to keep it project-specific. - -See [Metrics](/docs/products/metrics/) for details on scope and categorization. - ---- - -## Default workspace rules - -- Every organization has exactly one Default workspace (created automatically). -- The Default workspace **cannot be deleted**. -- If your stored workspace ID is invalid (for example after an org switch), the UI resets to Default. - ---- - -## Recommended usage - -- **One workspace per team or project** โ€” e.g., `support_pilot`, `sales_eval`, `customer_acme`. -- **Keep shared rubrics org-wide** โ€” compliance metrics or standard QA scorecards that every team uses. -- **Switch before creating resources** โ€” agents, metrics, and prompt partials are created in the active workspace. - ---- - -## API - -Workspace management endpoints live under `/api/v1/workspaces`: - -- `GET /workspaces` โ€” list workspaces you can access (includes your role name and capabilities per workspace) -- `POST /workspaces` โ€” create a workspace (name, optional slug); requires org **writer** or **admin** -- `PATCH /workspaces/{id}` โ€” rename a workspace; requires **Workspace Admin** in that workspace -- `DELETE /workspaces/{id}` โ€” delete a non-default workspace; requires org **admin** - -Workspace membership and roles: - -- `GET /workspaces/{id}/members` โ€” list members (requires `workspace.members.view`) -- `POST/PATCH/DELETE โ€ฆ/members` โ€” manage membership (requires `workspace.members.manage`) -- `GET /workspace-roles` โ€” list org workspace roles (for IAM UI) -- `GET /capabilities` โ€” capability registry for custom role builder (authenticated) - -All other scoped API calls should include `X-Workspace-Id` with the target workspace UUID. Routes enforce the minimum workspace capability for the HTTP method (view vs create/update vs delete). See [Access control](#access-control-organization-vs-workspace) above for how this maps to Viewer / Editor / Workspace Admin. +--- +id: workspaces +title: Workspaces +sidebar_position: 2 +--- + +# Workspaces + +## Overview + +Workspaces provide **in-organization project isolation**. Multiple teams or projects can share one EfficientAI organization while keeping their agents, metrics, call imports, and prompt libraries separate. + +Every organization starts with a **Default** workspace. You can create additional workspaces for individual teams, customers, or pilots without provisioning separate orgs. + +--- + +## Workspace switcher + +The workspace switcher lives at the top of the left sidebar, directly under the EfficientAI logo. + +From the switcher you can: + +- See which workspace is currently active +- Switch to another workspace in your organization +- Create a new workspace (display name + slug) + +When creating a workspace, you set a display name and optional slug. You are added automatically as **Workspace Admin**; you can optionally invite org members and assign each a workspace role (Viewer, Editor, or Workspace Admin) before saving. + +When you switch workspaces, all data views refetch automatically so you never see stale rows from the previous workspace. + +--- + +## How scoping works + +The UI stores your active workspace in the browser and sends it on every API request as the `X-Workspace-Id` header. The backend uses this header to scope listings and creates to the selected workspace. + +If a request arrives without the header, the backend falls back to the organization's **Default** workspace. + +--- + +## Access control: organization vs workspace + +EfficientAI uses **two independent permission layers**. Both apply on every request: + +1. **Organization role** โ€” set per membership in **Settings โ†’ Team** (`reader`, `writer`, or `admin`). +2. **Workspace role** โ€” set per workspace in **Identity & Access Management โ†’ Workspace Members** (`Viewer`, `Editor`, or `Workspace Admin`, plus optional custom roles). + +A user must satisfy **both** layers to perform an action. Your organization role controls whether you can write **anywhere** in the org; your workspace role controls what you can do **inside the active workspace**. + +### Organization roles + +| Role | Scope | Typical use | +| ---- | ----- | ----------- | +| **Reader** | Read-only for the **entire organization** | Auditors, stakeholders who only view dashboards | +| **Writer** | Create, update, and delete most org resources | Engineers and operators doing day-to-day work | +| **Admin** | Everything a writer can do, plus user/team management, API keys, and org settings | Org owners and IT admins | + +> **Org readers are always read-only** +> If your organization role is **Reader**, every mutating API call (`POST`, `PATCH`, `DELETE`) is blocked โ€” even if you hold **Workspace Admin** in a workspace. Workspace roles cannot override an org-level read-only membership. + +Org admins **bypass workspace membership checks** and receive all workspace capabilities in every workspace. + +**API keys** behave differently depending on whether they are linked to a user: + +- **User-bound keys** (created while signed in) carry the linked user's organization role, workspace memberships, and capabilities. They are subject to the same RBAC rules as that user's session. +- **Unbound keys** (legacy keys with no linked user) bypass workspace membership and capability checks and receive full workspace access within the key's organization. Prefer user-bound keys for least-privilege automation. + +Manage organization roles from **Settings โ†’ Team** (admin only). See [Authentication โ€” Team management](/docs/getting-started/authentication/#team-management-invitations--organizations). + +### Workspace roles (system) + +Each workspace has its own membership list. When you are added to a workspace, you receive one of three seeded system roles (or a custom role defined by an org admin): + +| Workspace role | Can do | Cannot do | +| -------------- | ------ | --------- | +| **Viewer** | View calls, metrics, evals, simulations, reports, and workspace members | Import, edit, delete, run evaluations, change settings, manage members | +| **Editor** | Everything Viewer can do, plus create/update resources (import calls, manage metrics, run evals, manage simulations, generate reports) | Delete call imports, rename workspace, add/remove members, change workspace roles | +| **Workspace Admin** | Full access in that workspace, including delete, workspace settings, and member management | โ€” | + +Roles are **cumulative**: Editor includes all Viewer permissions; Workspace Admin includes all Editor permissions. + +### What each role needs for common actions + +Use this table when planning access. โ€œOrgโ€ = organization role; โ€œWorkspaceโ€ = role in the **active** workspace (from the switcher). + +| Action | Minimum org role | Minimum workspace role | +| ------ | ---------------- | ---------------------- | +| View call imports, agents, metrics | Reader | Viewer | +| Upload / import calls, edit rows | Writer | Editor | +| Delete call imports or batches | Writer | **Workspace Admin** | +| Create or edit metrics (workspace-scoped) | Writer | Editor | +| Run evaluations | Writer | Editor | +| Rename a workspace | Writer | **Workspace Admin** | +| Add/remove workspace members | Writer | **Workspace Admin** | +| Create a new workspace | Writer | *(creator becomes Workspace Admin automatically)* | +| Delete a workspace | Admin | *(org admin only)* | +| Manage organization users & invitations | Admin | *(not workspace-scoped)* | + +When a workspace check fails, the API returns a plain-language message such as *โ€œThis action requires at least the Editor role in the active workspace. Your current workspace role is Viewer.โ€* Delete operations require **Workspace Admin**, not Editor. + +### Capability domains (reference) + +Workspace permissions are implemented as **capabilities** grouped by product area. System roles are bundles of these capabilities; org admins can also define **custom workspace roles** in **IAM โ†’ Workspace Roles** by picking capabilities from this registry. + +| Domain | View | Create / edit / run | Delete / admin | +| ------ | ---- | ------------------- | -------------- | +| **Calls** (call imports) | View batches and rows | Import and update | Delete imports | +| **Metrics** | View definitions | Manage metrics | โ€” | +| **Evaluations** | View runs and results | Run evaluations | โ€” | +| **Simulation** | View agents, personas, scenarios | Manage simulation resources | โ€” | +| **Reports** | View reports | Generate reports | โ€” | +| **Workspace** | View member list | โ€” | Rename workspace; add/remove members and roles | + +Custom roles are useful when a user needs a narrow slice of access (for example, view + run evals but not import calls). Assign them per workspace from **IAM โ†’ Workspace Members**. + +### Default access for new members + +When workspace RBAC is enabled or a new workspace is created: + +- New workspaces: the **creator** is added as **Workspace Admin**. +- Existing org members may be backfilled into workspaces with roles mapped from their org role: org admin โ†’ Workspace Admin, writer โ†’ Editor, reader โ†’ Viewer. + +Org admins should review **IAM โ†’ Workspace Members** after creating workspaces and remove or downgrade memberships that are too broad for your team model. + +### Managing workspace access + +1. Open **Identity & Access Management** in the sidebar. +2. Go to **Workspace Members**, select a workspace, and assign roles to org members. +3. Org admins can define custom roles under **Workspace Roles**. + +The workspace dropdown shows your current role in the selected workspace (for example, **Viewer**). Use the members table to review who has access and change roles โ€” if you hold **Workspace Admin** in that workspace and are an org Writer or Admin. + +Notes: + +- You can only manage members in a workspace if you are an **org Writer or Admin** **and** hold **Workspace Admin** (or org admin) in that workspace. +- **Workspace Admins cannot demote their own role**; another admin must change it. +- Users with org **Reader** can see member lists where allowed but cannot change memberships. + +--- + +## What is workspace-scoped + +Workspaces isolate the resources you interact with day to day, including: + +| Category | Resources | +|----------|-----------| +| Simulation | Agents, Personas, Scenarios, Evaluators | +| Evaluation | Evaluator results, legacy evaluations | +| Metrics | Custom and built-in metrics (when created with workspace scope) | +| Call imports | Call import batches and evaluations | +| Prompt tooling | Prompt partials, prompt optimization runs | +| Voice playground | Comparisons, samples, blind-test shares | +| Judge alignment | Judge datasets and runs | + +Switching workspace changes which rows appear in each of these sections. + +--- + +## Organization-wide resources + +Some metrics can be created with **organization** scope instead of workspace scope. Organization-scoped metrics: + +- Are stored with `workspace_id = null` +- Appear in **every** workspace in the org +- Are useful for shared rubrics, compliance checks, or standard evaluation criteria + +When creating a metric or categorization label group, choose **Organization** visibility if the rubric should be shared; choose **Workspace** (the default) to keep it project-specific. + +See [Metrics](/docs/products/metrics/) for details on scope and categorization. + +--- + +## Default workspace rules + +- Every organization has exactly one Default workspace (created automatically). +- The Default workspace **cannot be deleted**. +- If your stored workspace ID is invalid (for example after an org switch), the UI resets to Default. + +--- + +## Recommended usage + +- **One workspace per team or project** โ€” e.g., `support_pilot`, `sales_eval`, `customer_acme`. +- **Keep shared rubrics org-wide** โ€” compliance metrics or standard QA scorecards that every team uses. +- **Switch before creating resources** โ€” agents, metrics, and prompt partials are created in the active workspace. + +--- + +## API + +Workspace management endpoints live under `/api/v1/workspaces`: + +- `GET /workspaces` โ€” list workspaces you can access (includes your role name and capabilities per workspace) +- `POST /workspaces` โ€” create a workspace (name, optional slug); requires org **writer** or **admin** +- `PATCH /workspaces/{id}` โ€” rename a workspace; requires **Workspace Admin** in that workspace +- `DELETE /workspaces/{id}` โ€” delete a non-default workspace; requires org **admin** + +Workspace membership and roles: + +- `GET /workspaces/{id}/members` โ€” list members (requires `workspace.members.view`) +- `POST/PATCH/DELETE โ€ฆ/members` โ€” manage membership (requires `workspace.members.manage`) +- `GET /workspace-roles` โ€” list org workspace roles (for IAM UI) +- `GET /capabilities` โ€” capability registry for custom role builder (authenticated) + +All other scoped API calls should include `X-Workspace-Id` with the target workspace UUID. Routes enforce the minimum workspace capability for the HTTP method (view vs create/update vs delete). See [Access control](#access-control-organization-vs-workspace) above for how this maps to Viewer / Editor / Workspace Admin. diff --git a/docs-fumadocs/content/docs/intro.mdx b/docs-fumadocs/content/docs/intro.mdx index f95f6f49..6b30c7c3 100644 --- a/docs-fumadocs/content/docs/intro.mdx +++ b/docs-fumadocs/content/docs/intro.mdx @@ -1,56 +1,21 @@ --- -id: intro -title: Introduction -sidebar_position: 1 +title: Introduction (Moved) --- -# Introduction +
+

+ Efficient + AI +

+ EfficientAI logo + EfficientAI logo +

+ EfficientAI is an open-source evaluation platform for testing voice AI agents +

+
-EfficientAI is a voice AI evaluation platform for testing, measuring, and improving conversational agents before they reach production. +# This page moved -It helps teams run realistic simulations, analyze outcomes with explicit metrics, and iterate quickly on agent behavior, prompts, and voice quality. +The introduction content moved to the new Quickstart section. -## What the platform does - -EfficientAI gives you an end-to-end loop for voice AI quality: - -1. Configure the **Agent** you want to test. -2. Configure **Personas** with mapped voices for caller simulation. -3. Define **Scenarios** that represent conversation goals. -4. Run tests in the **Agent Playground** or evaluator workflows. -5. Score calls using enabled **Metrics**. -6. Improve prompts and re-test to track quality over time. - -## Core capabilities - -- **Workspaces**: isolate agents, metrics, call imports, and prompt libraries per team or project within one organization. -- **Agent testing across call setups**: supports inbound/outbound context and phone/web call mediums. -- **Prompt management**: maintain an internal test-agent prompt and sync provider prompts from external voice platforms. -- **Prompt partials**: reusable, versioned prompt templates with AI generate/improve, shared across metrics, agents, and call imports. -- **Voice bundle composition**: configure STT, LLM, and TTS stacks (or S2S where configured) for test-agent behavior. -- **Persona voice mapping**: personas are tied to concrete provider and voice identities. -- **Scenario generation and curation**: generate from agent prompts, derive from call transcripts/call data, or create manually. -- **Metric-driven evaluation**: built-in and custom metrics with categorization labels, surface targeting, and org-wide or workspace scope. -- **Cloud storage**: store audio in Amazon S3, S3-compatible services, or Google Cloud Storage via the Data Sources UI. -- **Prompt optimization workflows**: run optimization loops, compare candidates, accept winners, and push selected prompts to providers. -- **Usage tracking**: org-wide LLM, STT, and TTS consumption with cost estimates and drill-down by workspace and product area. - -## Platform model - -At a high level: - -- **Agents** are the systems under test. -- **Personas** represent simulated callers with specific voice identities. -- **Scenarios** define goals and test context. -- **Metrics** evaluate objective completion and voice quality. -- **Results** provide run-level evidence for iteration decisions. - -This structure keeps testing reproducible while still reflecting real-world voice interactions. - -## Key guides - -- [Usage](/docs/monitoring/usage/) โ€” LLM/STT/TTS consumption, cost estimates, and drill-down by workspace and product area -- [Workspaces](/docs/getting-started/workspaces/) โ€” project isolation within your organization, plus workspace roles (Viewer / Editor / Workspace Admin) and how they interact with org roles -- [Cloud Storage](/docs/getting-started/cloud-storage/) โ€” S3 and GCS configuration -- [Metrics](/docs/products/metrics/) โ€” custom rubrics, surfaces, and evaluation scope -- [Prompt Partials](/docs/products/prompt-partials/) โ€” versioned prompt templates +Go to [Quickstart](/docs/quickstart/). diff --git a/docs-fumadocs/content/docs/meta.json b/docs-fumadocs/content/docs/meta.json index 61851900..d760c21e 100644 --- a/docs-fumadocs/content/docs/meta.json +++ b/docs-fumadocs/content/docs/meta.json @@ -1,12 +1,10 @@ { "title": "EfficientAI Docs", "pages": [ - "intro", - "getting-started", - "products", - "monitoring", - "reference", - "advanced", - "more" + "(docs)", + "api-reference", + "enterprise", + "changelog", + "blog" ] } diff --git a/docs-fumadocs/content/docs/monitoring/calls.mdx b/docs-fumadocs/content/docs/monitoring/calls.mdx index 6f4be389..76d3bbc7 100644 --- a/docs-fumadocs/content/docs/monitoring/calls.mdx +++ b/docs-fumadocs/content/docs/monitoring/calls.mdx @@ -99,9 +99,8 @@ Each request sends **one call** at a time. The payload is flat (not nested insid | `recording_url` | String | No | URL to the call recording file (WAV, MP3, etc.) โ€” used later for audio-based evaluations | | `provider_platform` | String | No | Name of the voice AI platform (e.g., `"vapi"`, `"retell"`, `"custom"`). Defaults to `"external"`. | -:::tip Extra Fields -The endpoint accepts additional fields beyond those listed above. Any extra fields are automatically captured and stored in the call data, so you can forward your provider's full payload without stripping fields. -::: +> **Extra fields** +> The endpoint accepts additional fields beyond those listed above. Any extra fields are automatically captured and stored in the call data, so you can forward your provider's full payload without stripping fields. ### Message Object @@ -258,9 +257,8 @@ Forwarding https://a1b2c3d4.ngrok-free.app -> http://localhost:8000 Copy the `https://....ngrok-free.app` URL โ€” this is your public webhook URL. -:::info ngrok dashboard -ngrok also starts a local inspection dashboard at `http://localhost:4040` where you can see all incoming webhook requests, replay them, and inspect payloads โ€” useful for debugging. -::: +> **ngrok dashboard** +> ngrok also starts a local inspection dashboard at `http://localhost:4040` where you can see all incoming webhook requests, replay them, and inspect payloads โ€” useful for debugging. ### Step 5: Configure your Voice AI provider @@ -282,9 +280,8 @@ Paste the appropriate URL into your provider's webhook/server-url configuration. Make a call to your Voice AI agent. You should see the webhook hit in the ngrok terminal and the call appear in the EfficientAI Calls dashboard. -:::caution ngrok URL Changes -The free tier of ngrok generates a new URL each time you restart it. If you need a stable URL, consider ngrok's paid plan with custom domains, or use a tool like [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/). -::: +> **Caution: ngrok URL changes** +> The free tier of ngrok generates a new URL each time you restart it. If you need a stable URL, consider ngrok's paid plan with custom domains, or use a tool like [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/). --- diff --git a/docs-fumadocs/content/docs/monitoring/usage.mdx b/docs-fumadocs/content/docs/monitoring/usage.mdx index 1c2cb701..a1e596c6 100644 --- a/docs-fumadocs/content/docs/monitoring/usage.mdx +++ b/docs-fumadocs/content/docs/monitoring/usage.mdx @@ -1,198 +1,186 @@ ---- -id: usage -title: Usage -sidebar_position: 1 ---- - -# Usage - -**Usage** is org-scoped analytics for LLM, STT, and TTS consumption with estimated costs. It helps you see how much each workspace, product area, call import, and model is consuming โ€” and what that usage likely costs. - -Usage is **not** a quota or billing portal. Optional Flexprice event metering is a separate system and is not shown in the Usage UI. - -Models and providers tracked here come from your enabled [integrations](/docs/getting-started/integrations/). Usage is attributed per [workspace](/docs/getting-started/workspaces/) when the underlying workflow is workspace-scoped. - ---- - -## Opening the Usage page - -In the sidebar, go to **Usage โ†’ Overview** (`/usage`). - -The page has two tabs when your org is licensed for enterprise features and you are an org admin: - -| Tab | URL | Who can access | -|-----|-----|----------------| -| **Overview** | `/usage` | All org members | -| **Pricing overrides** | `/usage?tab=pricing` | Org admins with enterprise license | - ---- - -## Summary metrics - -The top of the Overview tab shows rollup cards for the selected date range and filters: - -| Metric | Description | -|--------|-------------| -| **Input tokens** | Prompt or input tokens sent to LLM providers | -| **Output tokens** | Completion or output tokens returned by LLMs | -| **Total tokens** | Sum of input and output tokens | -| **LLM calls** | Number of LLM API calls | -| **STT audio** | Speech-to-text audio duration (shown when non-zero) | -| **TTS characters** | Text-to-speech characters synthesized (shown when non-zero) | -| **Cache read** | Tokens read from provider prompt cache (shown when non-zero) | -| **Cache write** | Tokens written to provider prompt cache (shown when non-zero) | -| **Reasoning** | Reasoning tokens billed separately by some providers (shown when non-zero) | -| **Estimated cost** | Total estimated cost for the filtered range | - -Click **Cost breakdown** to open a modal with line items: - -- Input, output, cache read, cache write, reasoning -- Audio (STT), TTS -- Total estimated cost - -If any usage in the range has no matching catalog rate, the breakdown shows an **unpriced usage** warning. Those rows still appear in token/volume metrics but do not contribute to cost totals. - -### Currency display - -Toggle between **USD** and **INR** in the filter bar. INR amounts use a live USDโ†’INR rate from Frankfurter when available, with a fallback estimate when the FX service is unreachable. - ---- - -## Filters - -Filters narrow the summary cards and drill-down table. All filter state is stored in the URL, so you can bookmark or share a specific view. - -| Filter | Description | -|--------|-------------| -| **Date range** | Start and end dates, interpreted in your browser's IANA timezone | -| **Workspace** | Limit to one workspace | -| **Call import** | Limit to one call import batch | -| **Dataset** | Filter by dataset name on call import rows | -| **Tag** | Filter by call import tag | -| **Evaluation run** | Filter by evaluation resource | -| **Usage kind** | `LLM`, `STT`, or `TTS` | -| **Model** | Provider model identifier | -| **Source / product section** | Product area (playground, evaluators, call imports, etc.) | - ---- - -## Drill-down navigation - -Click rows in the breakdown table to drill deeper. Breadcrumbs at the top show your current path; click a breadcrumb to go back up. - -```mermaid -flowchart TD - Org[Organization] --> Workspace[Workspace] - Workspace --> Composite[Call imports and product areas] - Composite --> CallImport[Call import batch] - CallImport --> EvalRun[Evaluation run] - EvalRun --> Model[Model] - Model --> Kind[Usage kind] - Composite --> ProductSection[Product section] - ProductSection --> Model -``` - -At the organization level, the table groups by **workspace**. Inside a workspace you see a composite view: - -- **Call import batches** โ€” CSV uploads or manual audio recordings -- **Product areas** โ€” usage from other parts of the platform (not tied to a single call import) - -From a call import batch you can drill into evaluation runs, then model, then usage kind. From a product area you drill into model, then usage kind. - -Each drill level returns at most **100 rows**. If more exist, results are truncated at that level. - -### Product sections - -| Section | What it tracks | -|---------|----------------| -| **Call imports** | Call import batch processing | -| **Call import evaluations** | Evaluations run on imported calls | -| **Playground** | Text playground and experiments | -| **Voice playground** | Voice agent playground โ€” LLM, STT, and TTS | -| **Chat** | Chat conversations | -| **Telephony** | Telephony and live calls | -| **Evaluators** | Evaluator definitions and runs | -| **Metrics** | Metrics and scoring | -| **Judge alignment** | Judge alignment workflows | -| **Prompt optimization** | Prompt optimization jobs | -| **Personas** | Persona generation | -| **Agents** | Agent configuration | -| **Prompt partials** | Prompt partials | -| **Conversation evaluations** | Conversation evaluations | -| **Test agent** | Test agent sessions | -| **Other** | Usage not attributed to a named product area | - ---- - -## Data freshness and history - -### Freshness - -Usage counters are buffered in Redis and flushed to Postgres by the `worker-usage` service on a Celery Beat schedule (default: every **2 minutes**). The UI reads Postgres only. - -The page shows **Updated** with a `last_updated_at` timestamp when available. Expect roughly **2 minutes** of lag between new API usage and what appears on this page. - -For fresh data in self-hosted deployments, ensure `beat`, `worker-usage`, and the default `worker` are running (or use `eai start-all`). - -### History limits - -| Deployment | History window | Pricing overrides tab | -|------------|----------------|----------------------| -| **OSS** (no license) | Last **7 days** | Hidden | -| **Enterprise** (`EFFICIENTAI_LICENSE`) | Unlimited | Org admins only | - -On OSS deployments, an amber banner explains the 7-day cap and points to `EFFICIENTAI_LICENSE`. If you pick a wider date range, it is automatically clamped to the allowed window. - -See [Configuration](/docs/reference/configuration/) for license setup. - ---- - -## Pricing overrides - -Enterprise org admins can open **Pricing overrides** (`/usage?tab=pricing`) to set per-model rates that override the built-in catalog for cost estimation. - -### Override fields by usage kind - -| Usage kind | Rate fields (USD) | -|------------|-------------------| -| **LLM** | Input / 1M tokens, output / 1M tokens, cache read / 1M, cache write / 1M, reasoning / 1M, audio / minute | -| **STT** | Audio / minute | -| **TTS** | Characters / 1M | - -For each override you set: - -- **Provider credential** โ€” models come from enabled integrations -- **Usage kind** โ€” LLM, STT, or TTS -- **Model** โ€” provider model identifier -- **Effective from** โ€” date the override starts applying -- **Rates** โ€” USD values for the fields above - -You can prefill rates from the catalog or an existing override. Saving creates or updates the override; deleting removes it. - -### How overrides affect costs - -Overrides apply to **new usage** recorded on or after `effective_from`. Costs already stamped on daily rollup rows are **not** changed automatically. - -To backfill historical costs after a catalog or override change, use the CLI or API recompute workflow. The Usage UI does not expose recompute jobs today โ€” see [CLI Commands](/docs/reference/cli-commands/#usage-pricing). - ---- - -## Operations - -Self-hosted operators manage pricing catalogs and cost backfills outside the UI. - -| Requirement | Purpose | -|-------------|---------| -| `beat` | Schedules usage flush, FX refresh, OSS history prune | -| `worker-usage` | Flushes Redis counters and runs cost recompute jobs | -| Default `worker` | Evaluator cron dispatch (indirectly drives much platform usage) | - -Common tuning variables (see `env.example`): - -| Variable | Default | Purpose | -|----------|---------|---------| -| `USAGE_FLUSH_BEAT_SECONDS` | `120` | Flush interval (~2 min UI lag) | -| `USAGE_READ_CACHE_TTL_SECONDS` | `90` | Redis cache TTL for summary/breakdown/filters | -| `USAGE_FLUSH_MAX_BATCHES_PER_RUN` | `30` | Batches per flush tick | - -For seeding rates, diffing catalogs, and recomputing stored costs, see [CLI Commands โ€” Usage pricing](/docs/reference/cli-commands/#usage-pricing). +--- +id: usage +title: Usage +sidebar_position: 1 +--- + +# Usage + +**Usage** is org-scoped analytics for LLM, STT, and TTS consumption with estimated costs. It helps you see how much each workspace, product area, call import, and model is consuming โ€” and what that usage likely costs. + +Usage is **not** a quota or billing portal. Optional Flexprice event metering is a separate system and is not shown in the Usage UI. + +Models and providers tracked here come from your enabled [integrations](/docs/getting-started/integrations/). Usage is attributed per [workspace](/docs/getting-started/workspaces/) when the underlying workflow is workspace-scoped. + +--- + +## Opening the Usage page + +In the sidebar, go to **Usage โ†’ Overview** (`/usage`). + +The page has two tabs when your org is licensed for enterprise features and you are an org admin: + +| Tab | URL | Who can access | +|-----|-----|----------------| +| **Overview** | `/usage` | All org members | +| **Pricing overrides** | `/usage?tab=pricing` | Org admins with enterprise license | + +--- + +## Summary metrics + +The top of the Overview tab shows rollup cards for the selected date range and filters: + +| Metric | Description | +|--------|-------------| +| **Input tokens** | Prompt or input tokens sent to LLM providers | +| **Output tokens** | Completion or output tokens returned by LLMs | +| **Total tokens** | Sum of input and output tokens | +| **LLM calls** | Number of LLM API calls | +| **STT audio** | Speech-to-text audio duration (shown when non-zero) | +| **TTS characters** | Text-to-speech characters synthesized (shown when non-zero) | +| **Cache read** | Tokens read from provider prompt cache (shown when non-zero) | +| **Cache write** | Tokens written to provider prompt cache (shown when non-zero) | +| **Reasoning** | Reasoning tokens billed separately by some providers (shown when non-zero) | +| **Estimated cost** | Total estimated cost for the filtered range | + +Click **Cost breakdown** to open a modal with line items: + +- Input, output, cache read, cache write, reasoning +- Audio (STT), TTS +- Total estimated cost + +If any usage in the range has no matching catalog rate, the breakdown shows an **unpriced usage** warning. Those rows still appear in token/volume metrics but do not contribute to cost totals. + +### Currency display + +Toggle between **USD** and **INR** in the filter bar. INR amounts use a live USDโ†’INR rate from Frankfurter when available, with a fallback estimate when the FX service is unreachable. + +--- + +## Filters + +Filters narrow the summary cards and drill-down table. All filter state is stored in the URL, so you can bookmark or share a specific view. + +| Filter | Description | +|--------|-------------| +| **Date range** | Start and end dates, interpreted in your browser's IANA timezone | +| **Workspace** | Limit to one workspace | +| **Call import** | Limit to one call import batch | +| **Dataset** | Filter by dataset name on call import rows | +| **Tag** | Filter by call import tag | +| **Evaluation run** | Filter by evaluation resource | +| **Usage kind** | `LLM`, `STT`, or `TTS` | +| **Model** | Provider model identifier | +| **Source / product section** | Product area (playground, evaluators, call imports, etc.) | + +--- + +## Drill-down navigation + +Click rows in the breakdown table to drill deeper. Breadcrumbs at the top show your current path; click a breadcrumb to go back up. + +At the organization level, the table groups by **workspace**. Inside a workspace you see a composite view: + +- **Call import batches** โ€” CSV uploads or manual audio recordings +- **Product areas** โ€” usage from other parts of the platform (not tied to a single call import) + +From a call import batch you can drill into evaluation runs, then model, then usage kind. From a product area you drill into model, then usage kind. + +Each drill level returns at most **100 rows**. If more exist, results are truncated at that level. + +### Product sections + +| Section | What it tracks | +|---------|----------------| +| **Call imports** | Call import batch processing | +| **Call import evaluations** | Evaluations run on imported calls | +| **Playground** | Text playground and experiments | +| **Voice playground** | Voice agent playground โ€” LLM, STT, and TTS | +| **Chat** | Chat conversations | +| **Telephony** | Telephony and live calls | +| **Evaluators** | Evaluator definitions and runs | +| **Metrics** | Metrics and scoring | +| **Judge alignment** | Judge alignment workflows | +| **Prompt optimization** | Prompt optimization jobs | +| **Personas** | Persona generation | +| **Agents** | Agent configuration | +| **Prompt partials** | Prompt partials | +| **Conversation evaluations** | Conversation evaluations | +| **Test agent** | Test agent sessions | +| **Other** | Usage not attributed to a named product area | + +--- + +## Data freshness and history + +### Freshness + +Usage counters are buffered in Redis and flushed to Postgres by the `worker-usage` service on a Celery Beat schedule (default: every **2 minutes**). The UI reads Postgres only. + +The page shows **Updated** with a `last_updated_at` timestamp when available. Expect roughly **2 minutes** of lag between new API usage and what appears on this page. + +For fresh data in self-hosted deployments, ensure `beat`, `worker-usage`, and the default `worker` are running (or use `eai start-all`). + +### History limits + +| Deployment | History window | Pricing overrides tab | +|------------|----------------|----------------------| +| **OSS** (no license) | Last **7 days** | Hidden | +| **Enterprise** (`EFFICIENTAI_LICENSE`) | Unlimited | Org admins only | + +On OSS deployments, an amber banner explains the 7-day cap and points to `EFFICIENTAI_LICENSE`. If you pick a wider date range, it is automatically clamped to the allowed window. + +See [Configuration](/docs/reference/configuration/) for license setup. + +--- + +## Pricing overrides + +Enterprise org admins can open **Pricing overrides** (`/usage?tab=pricing`) to set per-model rates that override the built-in catalog for cost estimation. + +### Override fields by usage kind + +| Usage kind | Rate fields (USD) | +|------------|-------------------| +| **LLM** | Input / 1M tokens, output / 1M tokens, cache read / 1M, cache write / 1M, reasoning / 1M, audio / minute | +| **STT** | Audio / minute | +| **TTS** | Characters / 1M | + +For each override you set: + +- **Provider credential** โ€” models come from enabled integrations +- **Usage kind** โ€” LLM, STT, or TTS +- **Model** โ€” provider model identifier +- **Effective from** โ€” date the override starts applying +- **Rates** โ€” USD values for the fields above + +You can prefill rates from the catalog or an existing override. Saving creates or updates the override; deleting removes it. + +### How overrides affect costs + +Overrides apply to **new usage** recorded on or after `effective_from`. Costs already stamped on daily rollup rows are **not** changed automatically. + +To backfill historical costs after a catalog or override change, use the CLI or API recompute workflow. The Usage UI does not expose recompute jobs today โ€” see [CLI Commands](/docs/reference/cli-commands/#usage-pricing). + +--- + +## Operations + +Self-hosted operators manage pricing catalogs and cost backfills outside the UI. + +| Requirement | Purpose | +|-------------|---------| +| `beat` | Schedules usage flush, FX refresh, OSS history prune | +| `worker-usage` | Flushes Redis counters and runs cost recompute jobs | +| Default `worker` | Evaluator cron dispatch (indirectly drives much platform usage) | + +Common tuning variables (see `env.example`): + +| Variable | Default | Purpose | +|----------|---------|---------| +| `USAGE_FLUSH_BEAT_SECONDS` | `120` | Flush interval (~2 min UI lag) | +| `USAGE_READ_CACHE_TTL_SECONDS` | `90` | Redis cache TTL for summary/breakdown/filters | +| `USAGE_FLUSH_MAX_BATCHES_PER_RUN` | `30` | Batches per flush tick | + +For seeding rates, diffing catalogs, and recomputing stored costs, see [CLI Commands โ€” Usage pricing](/docs/reference/cli-commands/#usage-pricing). diff --git a/docs-fumadocs/content/docs/products/agents.mdx b/docs-fumadocs/content/docs/products/agents.mdx index 488d4e3d..97f9f641 100644 --- a/docs-fumadocs/content/docs/products/agents.mdx +++ b/docs-fumadocs/content/docs/products/agents.mdx @@ -1,112 +1,10 @@ --- -id: agents -title: Agents -sidebar_position: 1 +title: Agents (Moved) --- -# Agents +# This page moved -In EfficientAI, an **Agent** is a **test agent** โ€” the voice AI configuration you set up to evaluate behavior, prompts, and call quality before or alongside production rollout. - -A test agent is not a live production deployment on its own. It is the evaluation target you define in EfficientAI: call context, prompts, and how tests run (via an internal voice bundle or an external voice platform). - -## What the Agents section is for - -The **Test Agents** page is your control plane for: - -- defining which voice system you want to test, -- choosing call context (language, medium, inbound/outbound), -- managing test-agent and provider prompt surfaces, -- linking the test agent to internal or external execution paths. - -Use the **agent list on the left** (public Agent ID + name) to switch between test agents without leaving the page. The main panel shows **Overview**, **Test Agent**, and **Voice AI Agent** tabs for the selected agent. Deep links use `/agents/{agentId}` with optional `?tab=test_agent` or `?tab=voice_ai_agent`. - -## Creating a test agent - -![Creating an agent](/screenshots/creating-agents.png) - -Use **Create Test Agent** to add a new evaluation configuration. Choose one of two paths: - -- **Telephony** โ€” phone-based agent with telephony number, inbound/outbound direction, and silence hangup settings. Paste a production prompt, generate the complementary test agent prompt, then select a voice bundle. -- **Existing Platform Integration** โ€” connect VAPI, Retell, ElevenLabs, or Smallest with integration credentials and an external Agent ID, select a voice bundle, then import the production prompt and generate the test agent prompt. - -The **production prompt** is stored in `provider_prompt` and shown on the **Voice AI Agent** tab. The generated **test agent prompt** is stored in `description` and shown on the **Test Agent** tab. - -### Generate test prompt from production prompt - -On the prompts step, paste (Telephony) or import (Platform) your production system prompt, then click **Generate test prompt**. EfficientAI produces a complementary caller prompt stored in `description`. Review and edit before creating the agent. - -Use **Use Saved**, **Save Prompt**, manual authoring, and **AI Generate** when editing an existing agent in the detail view. - -## Execution paths - -A test agent can run on one or both paths: - -- **Test Agent path (internal)** via `voice_bundle_id`. -- **Voice AI Agent path (external)** via integration + provider agent mapping. - -If both are configured, you can compare outcomes across both paths from Playground and evaluator workflows. - -## Core configuration - -| Property | Type | Description | -|---|---|---| -| `name` | String | Human-readable test agent name. | -| `language` | Enum | Primary language context for evaluation. | -| `call_type` | Enum | `inbound` or `outbound` behavior context. | -| `call_medium` | Enum | `phone_call` or `web_call`. | -| `phone_number` | String | Required when `call_medium = phone_call`. | -| `voice_bundle_id` | UUID | **Required on create.** Internal test stack for voice-bundle testing. | -| `voice_ai_integration_id` | UUID | External provider integration reference. | -| `voice_ai_agent_id` | String | External provider agent identifier. | -| `silence_hangup_secs` | Integer | End live voice sessions after this many seconds without speech from either party (default `15`; `0` disables). | - -## Inbound vs outbound calls - -Use `call_type` to model the call direction the system under test is designed for: - -- **Inbound**: user initiates call to the agent. -- **Outbound**: agent initiates call to the user. - -This setting should match your real deployment pattern so evaluation conditions are realistic. - -## Prompt management - -Each test agent can carry two prompt surfaces: - -- **Test Agent Prompt (`description`)** - The EfficientAI test-agent prompt โ€” used for internal test-agent behavior, scenario generation, and evaluation context. -- **Provider Prompt (`provider_prompt`)** - Production prompt โ€” pasted during Telephony create, imported from a linked external provider, or synced via **Sync Now**. - -### Provider prompt sync - -When a test agent is linked to an external provider, EfficientAI can fetch and store the current provider prompt. - -Sync can happen: - -- automatically on relevant create/update operations, and -- manually through "Sync Now" in the agent view. - -This keeps local review and optimization aligned with what is currently running on the provider. - -### Test agent prompt composer - -When editing the **Test Agent Prompt**, use inline triggers while writing markdown: - -- Type **`{`** to insert **variables** (built-in placeholders such as `{agent_name}`, `{call_type}`, plus **custom variables** you define on the agent). -- Type **`@`** to insert **prompt partials** (full markdown from your workspace library) or variables from the same menu. - -Built-in variables are placeholders for authoring; runtime substitution during calls is not applied automatically yet. Custom variables are stored on the agent as `prompt_variables` (key โ†’ optional description). - -AI **Generate Description** can optionally use scenarios linked via `Scenario.agent_id` as **LLM context only**; it does not append a scenario reference block to your prompt. - -During evaluator runs, the simulator LLM uses a composed **test agent simulation prompt** (core agent prompt, plus the **active scenario** for that run) plus a separate **Persona** section. Legacy **Test scenarios (reference)** sections in stored prompts are ignored at runtime. See [Scenarios](/docs/products/scenarios/) and [Prompt Partials](/docs/products/prompt-partials/). - -## Related setup guides - -For setup details, use these getting-started guides: - -- Voice bundle setup: [Voice Bundles](/docs/getting-started/voice-bundles/) -- Provider integration setup: [Integrations](/docs/getting-started/integrations/) +Agent docs were split into concepts and configuration guides. +- Concept: [Agent](/docs/platform/agent/) +- Configuration: [Platform Agent](/docs/platform/agent/) diff --git a/docs-fumadocs/content/docs/products/alerting.mdx b/docs-fumadocs/content/docs/products/alerting.mdx index b74fbc74..40fc4d01 100644 --- a/docs-fumadocs/content/docs/products/alerting.mdx +++ b/docs-fumadocs/content/docs/products/alerting.mdx @@ -267,7 +267,7 @@ From the alerts list page, the **Evaluate All** button triggers evaluation of ev ## Automatic Evaluation -Alerts are automatically evaluated every **60 seconds** by a background worker (Celery Beat). You do not need to manually trigger evaluations โ€” they run continuously as long as your workers are running. +Alerts are automatically evaluated every **5 minutes** by a Celery Beat schedule (`evaluate_alerts`, routed to the **`platform`** queue). You do not need to manually trigger evaluations โ€” they run continuously as long as Beat and a `platform` queue worker are running. The evaluation cycle: 1. Fetches all **active** alerts for the organization @@ -379,16 +379,26 @@ Or via environment variables: ### Celery Workers -Alert evaluation runs as a Celery Beat periodic task. Ensure your Celery workers and Beat scheduler are running: +Alert evaluation runs as a Celery Beat periodic task on the **`platform`** queue. Beat only enqueues tasks โ€” you must also run a worker that consumes `platform`. + +Recommended: + +```bash +eai beat --config config.yml +``` + +Or run Beat and the platform worker separately: ```bash -# Start Celery worker -celery -A app.workers.celery_app worker --loglevel=info +# Worker for alert evaluation (and other platform tasks) +celery -A app.workers.celery_app worker --queues=platform --pool=threads --loglevel=info -# Start Celery Beat scheduler +# Scheduler (single replica) celery -A app.workers.celery_app beat --loglevel=info ``` +A default-queue worker does **not** process `evaluate_alerts`. + --- ## Common Patterns diff --git a/docs-fumadocs/content/docs/products/call-imports.mdx b/docs-fumadocs/content/docs/products/call-imports.mdx deleted file mode 100644 index c8eac357..00000000 --- a/docs-fumadocs/content/docs/products/call-imports.mdx +++ /dev/null @@ -1,46 +0,0 @@ ---- -id: call-imports -title: Call Imports -sidebar_position: 9 ---- - -# Call Imports - -Call Imports lets you bulk-import production call recordings via CSV and run batch evaluations on them. - -> **Enterprise feature** โ€” requires `call_imports` in your `EFFICIENTAI_LICENSE`. - -## At a glance - -- Upload CSV datasets and optional audio files -- Map columns with reusable schemas -- Run metrics and insights across imported production calls - -Contact the EfficientAI team for a license. - -## Sharded evaluation pipeline (ops) - -If evaluation runs stall after recordings import (rows show `completed` import but no diarization/scoring): - -1. Restart API and `worker-imports` after deploying fixes. -2. **Retry evaluation** from the UI (use *Overwrite existing transcripts* if diarization previously failed). -3. Or clear stale dispatch locks on shard DBs: - -```sql -UPDATE call_import_evaluation_rows er -SET celery_task_id = NULL -FROM call_import_rows sr -WHERE er.call_import_row_id = sr.id - AND er.status = 'pending' - AND er.celery_task_id IS NOT NULL - AND sr.status = 'completed' - AND sr.recording_s3_key IS NOT NULL; -``` - -Abort and force-fail run on the `eval-control` queue (before `evaluations` on `worker-imports`) so they are not blocked behind large scoring backlogs. - -When running locally via `eai start` or `eai worker`, the imports worker must consume **`imports,diarization,eval-control,evaluations`**. If `eval-control` is missing, Run Evaluation will enqueue materialize tasks that never run and recording imports will not start. - -## Database sharding (enterprise scale) - -For large batches (10k+ rows), call-import row data can be spread across multiple PostgreSQL data shards with a catalog database for metadata and routing. See [Call Import Sharding](/docs/advanced/call-import-sharding/) for the full system design, configuration, and scaling guide. diff --git a/docs-fumadocs/content/docs/products/evaluators.mdx b/docs-fumadocs/content/docs/products/evaluators.mdx index 6e968cd6..913711eb 100644 --- a/docs-fumadocs/content/docs/products/evaluators.mdx +++ b/docs-fumadocs/content/docs/products/evaluators.mdx @@ -1,73 +1,10 @@ --- -id: evaluators -title: Evaluators -sidebar_position: 4 +title: Evaluators (Moved) --- -# Evaluators +# This page moved -## What is an Evaluator Suite? +Evaluator docs were split into concepts and configuration guides. -An **Evaluator Suite** groups one **Agent**, one or more **Personas**, and **multiple Scenarios** into test combinations. - -Each persona ร— scenario pair becomes one combination (1:M:N). You can: - -- Choose **metrics** to score at the suite level (optional โ€” defaults to all enabled agent metrics) -- **Outbound / web**: run every combination **X times** (total runs = N ร— X) -- **Inbound**: one **active suite** per agent handles incoming calls; additional suites for the same agent stay inactive until you activate them. Each active suite rotates **scenarios** for that agent + persona. - ---- - -## Creating a Suite (4-step wizard) - -1. **Agent & Personas** โ€” pick one agent and one or more TTS-compatible personas -2. **Scenarios** โ€” multi-select scenarios (each persona ร— scenario becomes a combination) -3. **Metrics** โ€” optional metric picker -4. **Review** โ€” name, tags, default runs per combination - ---- - -## Running - -| Agent type | Behavior | -|---|---| -| Web call | Queue Celery bridge runs for all combinations ร— runs | -| Phone outbound | Batch outbound calls (requires dial target) | -| Phone inbound | **Round-robin** on incoming calls; **Choose next** to advance manually (no outbound dial) | - ---- - -## API - -| Method | Path | Purpose | -|---|---|---| -| POST | `/api/v1/evaluator-suites` | Create suite + combinations | -| PUT | `/api/v1/evaluator-suites/{id}/personas` | Replace persona set on a suite | -| POST | `/api/v1/evaluator-suites/{id}/personas` | Add personas to a suite | -| DELETE | `/api/v1/evaluator-suites/{id}/personas/{persona_id}` | Remove a persona from a suite | -| GET | `/api/v1/evaluator-suites` | List suites | -| POST | `/api/v1/evaluator-suites/{id}/run` | Batch run (outbound/web) | -| POST | `/api/v1/evaluator-suites/{id}/activate` | Set active inbound suite for the agent | -| POST | `/api/v1/evaluator-suites/{id}/choose-next` | Inbound: advance round-robin without a call | - -Legacy single-evaluator endpoints remain for backward compatibility. - ---- - -## Evaluation results (UI) - -Open **Evaluation Results** in the sidebar to browse runs in hierarchy: - -**Agent workspace** โ€” select an agent, then use the **left sidebar** (suites โ†’ scenarios). The main panel shows suite summary and quality metrics, or individual runs when a scenario is selected. URLs use `?suite=` and `?scenario=` query params for sharing. - -Legacy or manual runs without a suite appear under **Unassigned runs**. - -### Results API - -| Method | Path | Purpose | -|---|---|---| -| GET | `/api/v1/evaluator-results` | Paginated list (`items`, `total`); filters: `agent_id`, `suite_id`, `scenario_id`, `status`, `unassigned_only`, `skip`, `limit` | -| GET | `/api/v1/evaluator-results/overview` | Workspace rollups; optional `agent_id` or `suite_id` for drill-down | -| GET | `/api/v1/evaluator-results/aggregate` | Metric distributions for `suite_id` or `agent_id` + `scenario_id` | - -**Phase 2 (planned):** LLM failure clustering and RCA for suite/scenario scopes, similar to Call Import **Visualizations โ†’ Clusters**. +- Concept: [Evaluators](/docs/platform/evaluator/) +- Configuration: [Platform Evaluator](/docs/platform/evaluator/) diff --git a/docs-fumadocs/content/docs/products/meta.json b/docs-fumadocs/content/docs/products/meta.json index 557b361f..9f34cf24 100644 --- a/docs-fumadocs/content/docs/products/meta.json +++ b/docs-fumadocs/content/docs/products/meta.json @@ -7,11 +7,6 @@ "evaluators", "metrics", "metrics-studio", - "playground", - "voice-playground", - "call-imports", - "alerting", - "prompt-optimization", - "prompt-partials" + "alerting" ] } diff --git a/docs-fumadocs/content/docs/products/metrics.mdx b/docs-fumadocs/content/docs/products/metrics.mdx index 6e80ce96..6fe23a78 100644 --- a/docs-fumadocs/content/docs/products/metrics.mdx +++ b/docs-fumadocs/content/docs/products/metrics.mdx @@ -1,155 +1,10 @@ --- -id: metrics -title: Metrics -sidebar_position: 5 +title: Metrics (Moved) --- -# Metrics +# This page moved -Metrics are the scoring rules used to evaluate calls, playground runs, and blind tests. Only **enabled** metrics run during processing โ€” there is no hidden global default set beyond what you turn on in the Metrics page. +Metrics docs were split into concepts and configuration guides. -Metrics are scoped to your active [workspace](/docs/getting-started/workspaces/) unless you create them with organization-wide visibility. - ---- - -## Metric groups - -EfficientAI ships built-in metrics across three evaluation methods: - -### LLM-evaluated conversation metrics - -Examples: Follow Instructions, Professionalism. - -- Evaluates transcript and context against metric definitions -- Supports custom prompts and [prompt partials](/docs/products/prompt-partials/) import/save - -### Acoustic metrics (signal-based) - -Examples: Pitch Variance, Jitter, Shimmer, HNR. - -- Computed from raw audio signal characteristics (Parselmouth) -- Require audio; skipped when audio is unavailable - -### AI voice quality metrics (model-based) - -Examples: MOS Score, Emotion Category, Emotion Confidence, Valence, Arousal, Speaker Consistency, Prosody Score. - -- Uses audio-based ML models for quality, emotion, and consistency -- Require audio; skipped when audio is unavailable - ---- - -## Custom metrics - -Beyond built-in defaults, you can create **custom metrics** with these types: - -| Type | Output | Use case | -|------|--------|----------| -| `boolean` | true / false | Pass-fail checks | -| `enum` | One of defined values | Categorical judgments | -| `number_range` | Numeric score in a range | Quantitative ratings | -| `text` | Free-text response | Open-ended notes | -| `rating` | Star or scale rating | Subjective scores | - -Custom metrics use your LLM evaluation prompt (editable in the Metrics UI) and respect the same enable/disable and surface rules as built-in metrics. - ---- - -## Categorization labels - -For multi-class evaluations, create a **categorization** metric: - -- A **parent** metric holds the overall evaluation name and LLM prompt -- **Child labels** define each category (name, definition, optional example) -- Output is **single-choice** โ€” one label per run, which maps cleanly to a single CSV column on export - -Enable **Capture LLM Rationale** on the parent or children to store the model's reasoning alongside the chosen label. - ---- - -## Evaluation surfaces - -Metrics can run on one or more **surfaces**: - -| Surface | Where it runs | -|---------|---------------| -| **Agent** | Evaluator and agent test workflows | -| **Voice Playground** | TTS comparison and playground analytics | -| **Blind Test** | Blind listening test responses | - -Use the surface filter on the Metrics page to focus on a workflow. Toggle **enabled surfaces** per metric to control where each metric is evaluated. - ---- - -## Visibility scope - -When creating a metric, choose who can see it: - -| Scope | Behavior | -|-------|----------| -| **Workspace** (default) | Metric belongs to the active workspace only | -| **Organization** | Metric is shared across all workspaces in the org | - -Organization scope is ideal for standard rubrics. Workspace scope keeps project-specific metrics isolated. Scope is set at create time for metrics and categorization groups. - ---- - -## Advanced options - -### Capture LLM rationale - -When enabled, the evaluator stores the LLM's explanation alongside the score. Useful for auditing subjective metrics and debugging prompt behavior. - -### Transcript-compare judge - -Enable **Compare transcripts** on a metric to run a transcript-pair judge at call-import evaluation time. The worker feeds **both** the production transcript and the diarized transcript to the LLM as a labeled pair. The run's transcript-source toggle is ignored for this metric. - -Transcript-compare judges are mutually exclusive with categorization parent/child structure. - ---- - -## Prompt partials integration - -Metric evaluation prompts can be managed with [Prompt Partials](/docs/products/prompt-partials/): - -- **Import** a saved partial into a metric's prompt field -- **Save** the current prompt as a new partial or as a new version of an existing partial - -This keeps rubric prompts versioned and reusable across metrics and workspaces. - ---- - -## How metrics run during processing - -1. Call audio and transcript are collected. -2. Only **enabled** metrics for the relevant surface are considered. -3. Metrics are split by evaluation method (LLM, acoustic, AI voice). -4. Audio-required metrics run only when audio is available. -5. LLM metrics run on transcript and context (or transcript pairs for compare judges). -6. Scores are written to evaluator results for reporting and comparison. - -If audio is missing, audio-dependent metrics are skipped โ€” scores are never fabricated. - ---- - -## Defaults and deprecation - -Out of the box: - -- **Pitch Variance** starts enabled. -- **Jitter**, **Shimmer**, and **HNR** start disabled. - -Legacy defaults **Response Time** and **Customer Satisfaction** are deprecated and can be removed from your metric library if no longer needed. - ---- - -## Managing metrics - -Open **Metrics** in the sidebar to: - -- Enable or disable metrics -- Create custom metrics or categorization label groups -- Edit evaluation prompts -- Configure surfaces and rationale capture -- Filter by surface (Agent, Voice Playground, Blind Test) -- Import or save prompts via prompt partials +- Concept: [Metrics](/docs/platform/evaluator/) +- Configuration context: [Platform Evaluator](/docs/platform/evaluator/) diff --git a/docs-fumadocs/content/docs/products/personas.mdx b/docs-fumadocs/content/docs/products/personas.mdx index ba22d914..538705bb 100644 --- a/docs-fumadocs/content/docs/products/personas.mdx +++ b/docs-fumadocs/content/docs/products/personas.mdx @@ -1,76 +1,10 @@ --- -id: personas -title: Personas -sidebar_position: 2 +title: Personas (Moved) --- -# Personas +# This page moved -A Persona is the caller profile used to test your agent, including a concrete voice mapped from your integrated providers. - -## Creating a persona - -![Creating a persona](/screenshots/creating-personas.png) - -## Persona = profile + provider voice mapping - -Each persona is explicitly mapped to a concrete voice identity pulled from your configured voice providers: - -- `tts_provider` -- `tts_voice_id` -- `tts_voice_name` -- `gender` - -This keeps test behavior realistic and reproducible across repeated runs. - -## Mapping flow - -The current flow is: - -1. Select or create a persona profile. -2. Pick a specific voice from an integrated provider (or custom catalog). -3. Map that persona to an agent in your test setup. - -This ensures each persona-agent pairing uses a known, repeatable voice path during simulation. - -## Voice sources - -Personas can use: - -- built-in voices from integrated providers, or -- custom voices registered by your organization. - -Custom voices appear in the same selection flow as built-in voices during persona creation and edits. - -## Why this matters - -Persona voice mapping enables: - -- consistent replay of the same caller profile and agent mapping, -- cleaner comparison across model and prompt changes, -- easier debugging when quality shifts between runs. - -## Persona fields - -| Field | Description | -|---|---| -| `name` | Persona label used in tests. | -| `gender` | Persona gender metadata. | -| `tts_provider` | Voice provider used for synthesis. | -| `tts_voice_id` | Provider-specific voice identifier. | -| `tts_voice_name` | Human-readable voice name. | -| `is_custom` | Whether the selected voice is from custom catalog. | -| `description` | Persona prompt appended to the test caller system prompt during synthetic calls. | -| `tts_config` | Provider-specific TTS tuning (speed, stability, pitch, etc.). | -| `llm_temperature` | Caller LLM creativity during simulations. | -| `llm_max_tokens` | Max tokens per caller reply (verbosity cap). | -| `response_delay_ms` | Patience โ€” delay before the caller responds. | -| `max_turns` | Conversation length before the caller wraps up. | -| `allow_interruptions` | Whether the caller may speak while the agent is talking. | - -## Persona prompt - -Use **Persona prompt** (`description`) to define caller traits, tone, and speaking style. During evaluator runs this text is merged into the test caller LLM prompt under the `PERSONA` section. - -Provider-specific **TTS settings** control how the selected voice sounds. **Caller behavior** settings control how the simulated caller acts (creativity, verbosity, patience, interruptions). +Persona docs were split into concepts and configuration guides. +- Concept: [Persona](/docs/platform/persona/) +- Configuration: [Platform Persona](/docs/platform/persona/) diff --git a/docs-fumadocs/content/docs/products/playground.mdx b/docs-fumadocs/content/docs/products/playground.mdx deleted file mode 100644 index 1c5aa47d..00000000 --- a/docs-fumadocs/content/docs/products/playground.mdx +++ /dev/null @@ -1,61 +0,0 @@ ---- -id: playground -title: Playground -sidebar_position: 6 ---- - -# Playground - -The Agent Playground is a real-time environment for quickly testing agents and reviewing outcomes. - -## What it does - -From one place, you can: - -- start live tests, -- monitor call/test status, -- inspect transcripts and recordings, -- observe evaluation progress and metric outcomes. - -## Test modes - -When an agent is configured, you can run two test modes: - -### Voice AI Agent mode - -Uses external voice provider configuration and runs a live web call against the provider agent. - -Current supported providers: - -- Retell -- Vapi -- ElevenLabs - -Typical flow: - -1. Create web call using selected agent. -2. Connect through provider session/client. -3. Store call recording metadata. -4. Poll provider call details (status, transcript, audio). -5. Create evaluator result and run metric evaluation. - -### Test Agent mode - -Uses the internal voice-agent path backed by a configured voice bundle. - -This is useful for controlled comparisons where you want to test the bundle-defined STT, LLM, and TTS stack. - -## Result views - -Playground keeps Voice AI Agent and Test Agent runs visible in separate views so teams can inspect each workflow clearly and compare outcomes over time. - -## Prerequisites - -For external live web-call testing: - -- set `call_medium` to `web_call`, -- configure `voice_ai_integration_id`, -- configure `voice_ai_agent_id`. - -For richer playback and storage workflows, ensure storage is configured. - diff --git a/docs-fumadocs/content/docs/products/prompt-optimization.mdx b/docs-fumadocs/content/docs/products/prompt-optimization.mdx deleted file mode 100644 index 7c9142f7..00000000 --- a/docs-fumadocs/content/docs/products/prompt-optimization.mdx +++ /dev/null @@ -1,20 +0,0 @@ ---- -id: prompt-optimization -title: Prompt Optimization -sidebar_position: 7 ---- - -# Prompt Optimization - -Prompt Optimization is an enterprise feature for iteratively improving agent prompts using evaluation feedback. - -> **Enterprise feature** โ€” requires `gepa_optimization` in your `EFFICIENTAI_LICENSE`. - -## At a glance - -- Generate and rank candidate prompts from evaluation feedback -- Accept winning candidates and optionally push to your voice provider -- Control optimization depth with `max_metric_calls` and `minibatch_size` - -Contact the EfficientAI team for a license. - diff --git a/docs-fumadocs/content/docs/products/prompt-partials.mdx b/docs-fumadocs/content/docs/products/prompt-partials.mdx deleted file mode 100644 index 0d4c86c4..00000000 --- a/docs-fumadocs/content/docs/products/prompt-partials.mdx +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: prompt-partials -title: Prompt Partials -sidebar_position: 8 ---- - -# Prompt Partials - -Prompt partials are **reusable, versioned markdown prompt templates** scoped to your active [workspace](/docs/getting-started/workspaces/). Use them to standardize evaluation rubrics, agent instructions, and call-import prompts without copying text across pages. - ---- - -## Core workflows - -### Create and edit - -- Open **Prompt Partials** in the sidebar -- Click **New Prompt** to create a partial with name, description, content, and optional tags -- Edit content in the split view; each save creates a new version automatically - -### Search and organize - -- Search by name or description from the list panel -- Tag partials for filtering and discovery (e.g., `evaluation`, `compliance`, `sales`) - -### Preview - -Toggle between **Preview** (rendered markdown) and **Raw** (source markdown) when reviewing content. - ---- - -## Version history - -Every save increments the version number and stores a snapshot in history. - -| Action | Description | -|--------|-------------| -| **View versions** | Browse all versions with timestamps and change summaries | -| **Compare** | Side-by-side diff of current vs a historical version | -| **Revert** | Restore a prior version as the current content (creates a new version entry) | -| **Clone** | Duplicate a partial under a new name | - -Deleting a partial removes all version history permanently. - ---- - -## AI-assisted authoring - -Prompt partials include AI tools that require at least one configured **AI Provider** integration. - -### AI Generate - -Describe what you need (use case, tone, format style). The system drafts a complete markdown prompt using your selected LLM provider and model, or auto-detects the first available provider. - -### AI Improve - -Submit existing prompt content with optional instructions. The model restructures and clarifies the text while preserving intent โ€” useful for turning rough notes into production-ready rubrics. - -Both flows let you pick provider and model, or leave provider empty for auto-detect. - ---- - -## Where partials are used - -Saved partials can be imported and exported across the platform: - -| Location | Usage | -|----------|-------| -| **Metrics** | Import a partial into a metric evaluation prompt; save metric prompts back as partials | -| **Call Imports** | Import/save evaluation and insights prompts during call-import workflows | -| **Agents** | Save agent prompts as partials for reuse | - -Import opens a searchable picker of partials in the active workspace. Save supports **new partial** or **update existing** (which appends a version). - ---- - -## Workspace scoping - -Prompt partials belong to the **active workspace**. Switching workspaces shows a different partial library. To share prompts across projects, clone a partial into each workspace or manage the canonical version in one workspace and copy as needed. - ---- - -## API - -REST endpoints under `/api/v1/prompt-partials`: - -| Method | Path | Description | -|--------|------|-------------| -| `GET` | `/prompt-partials` | List partials (optional `search` query) | -| `POST` | `/prompt-partials` | Create partial with initial version | -| `GET` | `/prompt-partials/{id}` | Get partial with full version history | -| `PUT` | `/prompt-partials/{id}` | Update content (new version) | -| `DELETE` | `/prompt-partials/{id}` | Delete partial and all versions | -| `POST` | `/prompt-partials/{id}/clone` | Clone to a new partial | -| `POST` | `/prompt-partials/{id}/revert` | Revert to a specific version | -| `POST` | `/prompt-partials/generate` | AI-generate prompt from description | -| `POST` | `/prompt-partials/improve` | AI-improve existing prompt content | - -All scoped endpoints require `X-Workspace-Id` (see [Workspaces](/docs/getting-started/workspaces/)). - ---- - -## Related - -- [Metrics](/docs/products/metrics/) โ€” evaluation rubrics and prompt import/save -- [Prompt Optimization](/docs/products/prompt-optimization/) โ€” automated prompt improvement loops -- [Agents](/docs/products/agents/) โ€” agent prompt management diff --git a/docs-fumadocs/content/docs/products/scenarios.mdx b/docs-fumadocs/content/docs/products/scenarios.mdx index 6afe1650..52a50a05 100644 --- a/docs-fumadocs/content/docs/products/scenarios.mdx +++ b/docs-fumadocs/content/docs/products/scenarios.mdx @@ -1,49 +1,10 @@ --- -id: scenarios -title: Scenarios -sidebar_position: 3 +title: Scenarios (Moved) --- -# Scenarios +# This page moved -A Scenario defines the goal and context for a test conversation. - -## Creating a scenario - -![Creating a scenario](/screenshots/creating-scenarios.png) - -## How scenarios are created - -EfficientAI supports three scenario creation paths: - -1. **Generate from Agent Prompt (AI-assisted)** - Generate scenario drafts from the selected agent's **test agent prompt** (`description`). Uses the same backend generator as agent creation stage 2. Each draft includes structured markdown sections: Background, Caller Intent, Conversation Flow, Success Criteria, and Edge Cases to Probe (150-300 words per scenario), plus an optional `goal` in `required_info`. -2. **Generate from Call data** - Derive scenario content from call transcripts or call data. -3. **Create Manually** - Write a fully custom scenario. - -## Scenario structure - -| Field | Description | -|---|---| -| `name` | Scenario title. | -| `description` | What should happen in the conversation. AI-generated scenarios use structured sections (Background, Caller Intent, Conversation Flow, Success Criteria, Edge Cases) at 150-300 words. | -| `required_info` | Structured key/value expectations for the test. | -| `agent_id` | Optional linked agent for context. | - -## How scenarios are used - -Scenarios are used to: - -- compose the **test agent simulation prompt** with the linked agent's core prompt during evaluator runs (web and phone simulator paths), -- guide persona behavior during tests via a dedicated **Persona** section in the simulator LLM prompt, -- provide evaluation context for scoring, -- keep testing reproducible across repeated runs. - -Link scenarios to an agent with `agent_id` for organization and filtering on the Scenarios page. Linked scenarios can also inform AI **Generate Description** on the agent (context only). - -Filter the scenario list by **linked agent** (all, unlinked, or a specific test agent) from the Scenarios header. - -A good scenario is specific enough to be measurable, but open enough to preserve natural conversation flow. +Scenario docs were split into concepts and configuration guides. +- Concept: [Scenario](/docs/platform/scenario/) +- Configuration: [Platform Scenario](/docs/platform/scenario/) diff --git a/docs-fumadocs/content/docs/products/voice-playground.mdx b/docs-fumadocs/content/docs/products/voice-playground.mdx deleted file mode 100644 index a9235595..00000000 --- a/docs-fumadocs/content/docs/products/voice-playground.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -id: voice-playground -title: Voice Playground -sidebar_position: 8 ---- - -# Voice Playground - -Voice Playground lets you A/B test TTS providers with real synthesis, blind tests, and automated evaluation. - -> **Enterprise feature** โ€” requires `voice_playground` in your `EFFICIENTAI_LICENSE`. - -## At a glance - -- Compare multiple voices on the same script -- Run benchmark simulations and blind-test shares -- Evaluate with metrics enabled for the Voice Playground surface - -Contact the EfficientAI team for a license. diff --git a/docs-fumadocs/content/docs/reference/cli-commands.mdx b/docs-fumadocs/content/docs/reference/cli-commands.mdx index c0ce1658..9b4a430f 100644 --- a/docs-fumadocs/content/docs/reference/cli-commands.mdx +++ b/docs-fumadocs/content/docs/reference/cli-commands.mdx @@ -4,7 +4,7 @@ title: CLI Commands sidebar_position: 1 --- -# ๐Ÿ’ป CLI Commands +# CLI Commands ## Start Application and Worker Together (Recommended) diff --git a/docs-fumadocs/content/docs/reference/configuration.mdx b/docs-fumadocs/content/docs/reference/configuration.mdx index 19adbdb1..b9fb35d7 100644 --- a/docs-fumadocs/content/docs/reference/configuration.mdx +++ b/docs-fumadocs/content/docs/reference/configuration.mdx @@ -4,7 +4,7 @@ title: Configuration sidebar_position: 2 --- -# โš™๏ธ Configuration +# Configuration EfficientAI reads configuration from (in order of precedence): @@ -140,11 +140,10 @@ auth: # passthrough_provider_keys: true ``` -:::tip -Keep `secret_key`, database credentials, S3/GCS credentials, and the license JWT -**out of version control**. Put them in `.env` or your secret manager of -choice and reference them from there. -::: +> **Tip** +> Keep `secret_key`, database credentials, S3/GCS credentials, and the license JWT +> **out of version control**. Put them in `.env` or your secret manager of +> choice and reference them from there. --- diff --git a/docs-fumadocs/lib/github-releases.ts b/docs-fumadocs/lib/github-releases.ts new file mode 100644 index 00000000..5f4fecea --- /dev/null +++ b/docs-fumadocs/lib/github-releases.ts @@ -0,0 +1,72 @@ +export type GitHubRelease = { + tagName: string; + name: string; + publishedAt: string; + htmlUrl: string; + changes: string[]; + contributors: string[]; +}; + +const RELEASES_URL = + 'https://api.github.com/repos/EfficientAI-tech/efficientAI/releases?per_page=30'; + +function parseReleaseBody(body: string): { changes: string[]; contributors: string[] } { + const changes: string[] = []; + const contributors = new Set(); + + for (const line of body.split('\n')) { + const trimmed = line.trim(); + if (!trimmed) continue; + + const contributorMatch = trimmed.match(/^[*-]\s*@([A-Za-z0-9-]+)/); + if (contributorMatch) { + contributors.add(contributorMatch[1]); + continue; + } + + const inlineContributor = trimmed.match(/\sby\s@([A-Za-z0-9-]+)\s/i); + if (inlineContributor) { + contributors.add(inlineContributor[1]); + } + + if (/^[*-]\s/.test(trimmed) && !trimmed.startsWith('**Full Changelog')) { + changes.push(trimmed.replace(/^[*-]\s*/, '')); + } + } + + return { changes, contributors: [...contributors] }; +} + +export async function fetchGitHubReleases(): Promise { + const response = await fetch(RELEASES_URL, { + next: { revalidate: 3600 }, + headers: { + Accept: 'application/vnd.github+json', + 'X-GitHub-Api-Version': '2022-11-28', + }, + }); + + if (!response.ok) { + throw new Error(`GitHub releases request failed (${response.status})`); + } + + const data = (await response.json()) as Array<{ + tag_name: string; + name: string; + published_at: string; + html_url: string; + body: string | null; + }>; + + return data.map((release) => { + const parsed = parseReleaseBody(release.body ?? ''); + return { + tagName: release.tag_name, + name: release.name || release.tag_name, + publishedAt: release.published_at, + htmlUrl: release.html_url, + changes: parsed.changes, + contributors: parsed.contributors, + }; + }); +} diff --git a/docs-fumadocs/lib/layout.shared.tsx b/docs-fumadocs/lib/layout.shared.tsx index 05100ac6..a333978b 100644 --- a/docs-fumadocs/lib/layout.shared.tsx +++ b/docs-fumadocs/lib/layout.shared.tsx @@ -5,8 +5,12 @@ export function baseOptions(): BaseLayoutProps { return { nav: { title: , - url: '/docs/intro/', + url: '/docs/quickstart/', + }, + links: [], + themeSwitch: { + enabled: true, + mode: 'light-dark', }, - themeSwitch: { enabled: false }, }; } diff --git a/docs-fumadocs/lib/openapi.ts b/docs-fumadocs/lib/openapi.ts new file mode 100644 index 00000000..a2ab621d --- /dev/null +++ b/docs-fumadocs/lib/openapi.ts @@ -0,0 +1,6 @@ +import { createOpenAPI } from 'fumadocs-openapi/server'; +import { join } from 'node:path'; + +export const openapi = createOpenAPI({ + input: { efficientai: join(process.cwd(), 'openapi', 'efficientai.json') }, +}); diff --git a/docs-fumadocs/lib/parse-pr-body.ts b/docs-fumadocs/lib/parse-pr-body.ts new file mode 100644 index 00000000..842739a6 --- /dev/null +++ b/docs-fumadocs/lib/parse-pr-body.ts @@ -0,0 +1,60 @@ +const PULL_URL_PATTERN = /https:\/\/github\.com\/[^/\s]+\/[^/\s]+\/pull\/(\d+)/gi; + +function linkifyUrls(text: string): string { + return text.replace(/(? `[${url}](${url})`); +} + +function parseSectionMap(body: string): Map { + const sectionMap = new Map(); + let current = '__intro__'; + sectionMap.set(current, []); + + for (const rawLine of body.split('\n')) { + const heading = rawLine.match(/^##\s+(.+?)\s*$/); + if (heading) { + current = heading[1].trim().toLowerCase().replace(/[^\w]+/g, ' ').trim(); + sectionMap.set(current, []); + continue; + } + + sectionMap.get(current)?.push(rawLine); + } + + return sectionMap; +} + +function pickSection( + sectionMap: Map, + candidates: string[], +): string | undefined { + for (const candidate of candidates) { + const normalized = candidate.toLowerCase().replace(/[^\w]+/g, ' ').trim(); + const lines = sectionMap.get(normalized); + if (!lines) continue; + const text = linkifyUrls(lines.join('\n').trim()); + if (text) return text; + } + return undefined; +} + +export function extractPullNumbers(text: string): number[] { + const numbers = new Set(); + for (const match of text.matchAll(PULL_URL_PATTERN)) { + const value = Number.parseInt(match[1] ?? '', 10); + if (Number.isFinite(value)) numbers.add(value); + } + return [...numbers]; +} + +export function parsePrSections(body: string): { + whatChanged?: string; + why?: string; + howToTest?: string; +} { + const sectionMap = parseSectionMap(body); + return { + whatChanged: pickSection(sectionMap, ['What Changed', 'Changes']), + why: pickSection(sectionMap, ['Why']), + howToTest: pickSection(sectionMap, ['How to Test', 'Testing', 'Test Plan']), + }; +} diff --git a/docs-fumadocs/lib/resolve-feature-id.ts b/docs-fumadocs/lib/resolve-feature-id.ts new file mode 100644 index 00000000..89267ad7 --- /dev/null +++ b/docs-fumadocs/lib/resolve-feature-id.ts @@ -0,0 +1,62 @@ +const FEATURE_ALIASES: Record = { + platform: 'intro', + 'platform/index': 'intro', + 'platform/agent': 'products/agents', + 'platform/persona': 'products/personas', + 'platform/scenario': 'products/scenarios', + 'platform/evaluator': 'products/evaluators', + 'platform/evaluation-suite': 'products/evaluators', + 'platform/metrics': 'products/metrics', + 'platform/playground': 'products/playground', + 'platform/prompts': 'products/prompt-partials', + quickstart: 'getting-started/installation', + 'key-concepts': 'intro', + 'key-concepts/index': 'intro', + integrations: 'getting-started/integrations', + 'integrations/index': 'getting-started/integrations', + 'integrations/retell': 'getting-started/integrations', + 'integrations/vapi': 'getting-started/integrations', + 'integrations/elevenlabs': 'getting-started/integrations', + 'integrations/plivo': 'getting-started/integrations', + 'integrations/smallest': 'getting-started/integrations', + 'integrations/vobiz': 'getting-started/integrations', + enterprise: 'enterprise/overview', + 'enterprise/index': 'enterprise/overview', + blog: 'intro', + 'blog/index': 'intro', + changelog: 'intro', + 'changelog/index': 'intro', + 'api-reference': 'reference/configuration', + 'api-reference/agents': 'products/agents', + 'api-reference/personas': 'products/personas', + 'api-reference/scenarios': 'products/scenarios', + 'api-reference/evaluators': 'products/evaluators', + 'api-reference/evaluator-suites': 'products/evaluators', + 'api-reference/evaluator-results': 'products/evaluators', + 'api-reference/metrics': 'products/metrics', + 'api-reference/authentication': 'getting-started/authentication', + 'api-reference/observability': 'monitoring/calls', + 'api-reference/call-imports': 'enterprise/call-imports', + 'api-reference/workspaces': 'getting-started/workspaces', + 'api-reference/integrations': 'getting-started/integrations', + 'api-reference/voice-bundles': 'getting-started/voice-bundles', + 'api-reference/ai-providers': 'reference/configuration', +}; + +export function resolveFeatureId(slugPath: string): string { + const normalized = slugPath.replace(/\/index$/, '').replace(/\/$/, ''); + + if (FEATURE_ALIASES[normalized]) { + return FEATURE_ALIASES[normalized]; + } + + const apiMatch = normalized.match(/^api-reference\/([^/]+)/); + if (apiMatch) { + const tagKey = `api-reference/${apiMatch[1]}`; + if (FEATURE_ALIASES[tagKey]) { + return FEATURE_ALIASES[tagKey]; + } + } + + return normalized; +} diff --git a/docs-fumadocs/lib/shared.ts b/docs-fumadocs/lib/shared.ts index 62fc844d..9141d629 100644 --- a/docs-fumadocs/lib/shared.ts +++ b/docs-fumadocs/lib/shared.ts @@ -6,3 +6,12 @@ export const gitConfig = { repo: 'efficientAI', branch: 'main', }; + +const githubRepo = `https://github.com/${gitConfig.user}/${gitConfig.repo}`; + +export const communityLinks = { + githubRepo, + githubIssues: `${githubRepo}/issues/new`, + discord: 'https://discord.gg/Saz9b2NA7', + bookDemo: 'https://cal.com/aadhar-singh-bhadauria/30min', +}; diff --git a/docs-fumadocs/lib/source.ts b/docs-fumadocs/lib/source.ts index 99dfd6e0..517e2bb6 100644 --- a/docs-fumadocs/lib/source.ts +++ b/docs-fumadocs/lib/source.ts @@ -1,11 +1,26 @@ -import { docs } from 'collections/server'; import { loader } from 'fumadocs-core/source'; import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons'; import { docsRoute } from './shared'; +import * as collections from 'collections/server'; +import { openapi } from './openapi'; + +type DocsCollection = { + toFumadocsSource: () => unknown; +}; + +function getDocsCollection(): DocsCollection { + const maybeDocs = (collections as { docs?: DocsCollection }).docs; + if (!maybeDocs) { + throw new Error( + "Docs collection missing from collections/server. Run `npx fumadocs-mdx` and restart the dev server.", + ); + } + return maybeDocs; +} // See https://fumadocs.dev/docs/headless/source-api for more info export const source = loader({ baseUrl: docsRoute, - source: docs.toFumadocsSource(), - plugins: [lucideIconsPlugin()], + source: getDocsCollection().toFumadocsSource() as Parameters[0]['source'], + plugins: [lucideIconsPlugin(), openapi.loaderPlugin()], }); diff --git a/docs-fumadocs/next.config.mjs b/docs-fumadocs/next.config.mjs index c065a117..2ba98ae7 100644 --- a/docs-fumadocs/next.config.mjs +++ b/docs-fumadocs/next.config.mjs @@ -8,7 +8,9 @@ const dirname = path.dirname(fileURLToPath(import.meta.url)); /** @type {import('next').NextConfig} */ const config = { reactStrictMode: true, - output: 'export', + // Static export is required for production deploys; skip in dev so Turbopack + // can serve new doc routes without pre-registering every slug. + ...(process.env.NODE_ENV === 'production' ? { output: 'export' } : {}), trailingSlash: true, images: { unoptimized: true, diff --git a/docs-fumadocs/openapi/efficientai.json b/docs-fumadocs/openapi/efficientai.json new file mode 100644 index 00000000..26fb44ad --- /dev/null +++ b/docs-fumadocs/openapi/efficientai.json @@ -0,0 +1,32683 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "EfficientAI Platform API", + "description": "EfficientAI Voice AI Evaluation Platform", + "version": "0.1.0" + }, + "paths": { + "/api/v1/auth/config": { + "get": { + "tags": [ + "Authentication" + ], + "summary": "Get Auth Config", + "description": "Return which login methods the frontend should render on /login.", + "operationId": "get_auth_config_api_v1_auth_config_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthConfigResponse" + } + } + } + } + }, + "security": [] + } + }, + "/api/v1/auth/invitations/preview/{token}": { + "get": { + "tags": [ + "Authentication" + ], + "summary": "Preview Invitation", + "description": "Public preview of an organization invite (no auth required).", + "operationId": "preview_invitation_api_v1_auth_invitations_preview__token__get", + "parameters": [ + { + "name": "token", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Token" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvitationPreviewResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [] + } + }, + "/api/v1/auth/invitations/accept-by-token": { + "post": { + "tags": [ + "Authentication" + ], + "summary": "Accept Invitation By Token", + "description": "Accept an invitation and return a session scoped to the invited organization.", + "operationId": "accept_invitation_by_token_api_v1_auth_invitations_accept_by_token_post", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AcceptInviteByTokenRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/auth/signup": { + "post": { + "tags": [ + "Authentication" + ], + "summary": "Signup", + "description": "Create a new User + Organization pair and return a login token.\n\nOnly available in OSS/self-hosted deployments where\n`auth.local_password.allow_signup = true` (the default). Cloud SaaS\nturns this off and routes signup through the billing flow.", + "operationId": "signup_api_v1_auth_signup_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SignupRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [] + } + }, + "/api/v1/auth/login": { + "post": { + "tags": [ + "Authentication" + ], + "summary": "Login", + "description": "Verify email/password and return a short-lived Bearer token.", + "operationId": "login_api_v1_auth_login_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoginRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/TokenResponse" + }, + { + "$ref": "#/components/schemas/LoginOrgSelectionResponse" + } + ], + "title": "Response Login Api V1 Auth Login Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [] + } + }, + "/api/v1/auth/me": { + "get": { + "tags": [ + "Authentication" + ], + "summary": "Me", + "description": "Return the current authenticated user (Bearer or API key).", + "operationId": "me_api_v1_auth_me_get", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserSummary" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/auth/logout": { + "post": { + "tags": [ + "Authentication" + ], + "summary": "Logout", + "description": "Revoke the current session's refresh token and blacklist the access token.", + "operationId": "logout_api_v1_auth_logout_post", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/LogoutRequest" + }, + { + "type": "null" + } + ], + "title": "Payload" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Response Logout Api V1 Auth Logout Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/auth/refresh": { + "post": { + "tags": [ + "Authentication" + ], + "summary": "Refresh Session", + "description": "Rotate a refresh token and issue a new short-lived access token.", + "operationId": "refresh_session_api_v1_auth_refresh_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [] + } + }, + "/api/v1/auth/switch-org": { + "post": { + "tags": [ + "Authentication" + ], + "summary": "Switch Organization", + "description": "Issue a new Bearer token bound to a different organization.\n\nThe caller must be an interactive user (not an API key) and must be an\nactive member of the target organization. Role is re-derived from the\nnew org's OrganizationMember row - switching orgs can legitimately\nchange your role.", + "operationId": "switch_organization_api_v1_auth_switch_org_post", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SwitchOrgRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/auth/password": { + "post": { + "tags": [ + "Authentication" + ], + "summary": "Set Password", + "description": "Set or change the password on the authenticated user.\n\nUse cases:\n 1. User signed up via API key only and now wants an email/password login\n for the same identity -> call this once to set the password (and,\n if their email is still `api_user_*@efficientai.local`, pass a real\n `email` to replace it).\n 2. User already has a password and wants to rotate it -> supply both\n `current_password` and `new_password`.", + "operationId": "set_password_api_v1_auth_password_post", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetPasswordRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserSummary" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/auth/generate-key": { + "post": { + "tags": [ + "Authentication" + ], + "summary": "Generate Api Key", + "description": "Issue a new API key bound to the caller's organization.\n\nThis used to be anonymous and created a fresh org on every call - a\nsecurity hole in any multi-tenant deployment. It now requires the caller\nto already be authenticated (Bearer or an existing API key). The created\nkey inherits `principal.organization_id` and `principal.user_id`.", + "operationId": "generate_api_key_api_v1_auth_generate_key_post", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIKeyCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/APIKeyResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/auth/validate": { + "post": { + "tags": [ + "Authentication" + ], + "summary": "Validate Api Key", + "description": "Lightweight endpoint the frontend uses to confirm the stored key still works.", + "operationId": "validate_api_key_api_v1_auth_validate_post", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Response Validate Api Key Api V1 Auth Validate Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/agents/generate-description": { + "post": { + "tags": [ + "agents" + ], + "summary": "Generate Agent Description", + "description": "Generate an agent description using AI from a brief description.", + "operationId": "generate_agent_description_api_v1_agents_generate_description_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateAgentDescriptionRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/agents/generate-test-prompt": { + "post": { + "tags": [ + "agents" + ], + "summary": "Generate Test Prompt", + "description": "Stage 1: generate foundational test agent prompt from production prompt.", + "operationId": "generate_test_prompt_api_v1_agents_generate_test_prompt_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateTestPromptRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateTestPromptResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/agents/generate-scenarios-from-prompt": { + "post": { + "tags": [ + "agents" + ], + "summary": "Generate Scenarios From Prompt", + "description": "Stage 2: generate scenario drafts from a test agent prompt.", + "operationId": "generate_scenarios_from_prompt_api_v1_agents_generate_scenarios_from_prompt_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateScenariosFromPromptRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateScenariosFromPromptResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/agents/generate-test-setup": { + "post": { + "tags": [ + "agents" + ], + "summary": "Generate Test Setup", + "description": "Run stage 1 then stage 2: foundational test prompt + scenario drafts.", + "operationId": "generate_test_setup_api_v1_agents_generate_test_setup_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateTestSetupRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateTestSetupResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/agents": { + "get": { + "tags": [ + "agents" + ], + "summary": "List Agents", + "description": "Get list of all agents for the active workspace.\n\nScoped to (organization_id, workspace_id) so users only see agents\nin the workspace they're currently in.", + "operationId": "list_agents_api_v1_agents_get", + "parameters": [ + { + "name": "skip", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Skip" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 100, + "title": "Limit" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AgentResponse" + }, + "title": "Response List Agents Api V1 Agents Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "agents" + ], + "summary": "Create Agent", + "description": "Create a new test agent.\n\nThe agent is stamped with the active workspace from the\n``X-Workspace-Id`` header (falling back to the org's Default).", + "operationId": "create_agent_api_v1_agents_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/agents/check-phone-assignment": { + "get": { + "tags": [ + "agents" + ], + "summary": "Check Phone Assignment", + "description": "Check whether a phone number is available for agent assignment in this org.", + "operationId": "check_phone_assignment_api_v1_agents_check_phone_assignment_get", + "parameters": [ + { + "name": "phone_number", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Phone Number" + } + }, + { + "name": "telephony_phone_number_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Telephony Phone Number Id" + } + }, + { + "name": "exclude_agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Exclude Agent Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentPhoneAssignmentCheckResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/agents/{agent_id}": { + "get": { + "tags": [ + "agents" + ], + "summary": "Get Agent", + "description": "Get a specific agent by ID (UUID) or agent_id (6-digit) within the active workspace.", + "operationId": "get_agent_api_v1_agents__agent_id__get", + "parameters": [ + { + "name": "agent_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Agent Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "put": { + "tags": [ + "agents" + ], + "summary": "Update Agent", + "description": "Update an existing agent by ID (UUID) or agent_id (6-digit) within the active workspace.", + "operationId": "update_agent_api_v1_agents__agent_id__put", + "parameters": [ + { + "name": "agent_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Agent Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "agents" + ], + "summary": "Delete Agent", + "description": "Delete an agent (scoped to the active workspace). Returns 409 if dependent records exist unless force=true.", + "operationId": "delete_agent_api_v1_agents__agent_id__delete", + "parameters": [ + { + "name": "agent_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Agent Id" + } + }, + { + "name": "force", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "Force delete with all dependent records", + "default": false, + "title": "Force" + }, + "description": "Force delete with all dependent records" + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/agents/{agent_id}/sync-provider-prompt": { + "post": { + "tags": [ + "agents" + ], + "summary": "Sync Agent Provider Prompt", + "description": "Fetch and store the current system prompt from the voice provider.", + "operationId": "sync_agent_provider_prompt_api_v1_agents__agent_id__sync_provider_prompt_post", + "parameters": [ + { + "name": "agent_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Agent Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/agents/{agent_id}/delete-impact": { + "get": { + "tags": [ + "agents" + ], + "summary": "Get Agent Delete Impact", + "description": "Preview dependent records that would be affected by force delete (scoped to the active workspace).", + "operationId": "get_agent_delete_impact_api_v1_agents__agent_id__delete_impact_get", + "parameters": [ + { + "name": "agent_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Agent Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas": { + "get": { + "tags": [ + "personas" + ], + "summary": "List Personas", + "description": "List personas for the active workspace.", + "operationId": "list_personas_api_v1_personas_get", + "parameters": [ + { + "name": "skip", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Skip" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 100, + "title": "Limit" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PersonaResponse" + }, + "title": "Response List Personas Api V1 Personas Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "personas" + ], + "summary": "Create Persona", + "description": "Create a new persona stamped with the active workspace.", + "operationId": "create_persona_api_v1_personas_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersonaCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersonaResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/voice-options": { + "get": { + "tags": [ + "personas" + ], + "summary": "Get Voice Options", + "description": "Return available TTS voices grouped by provider.\n\nMerges built-in static voices, model-config voices (e.g. Murf voice files),\nand the org's custom voices. Not enterprise-gated.", + "operationId": "getPersonaVoiceOptions", + "parameters": [ + { + "name": "provider", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/agent-prompt-sources/{agent_id}": { + "get": { + "tags": [ + "personas" + ], + "summary": "Get Agent Prompt Sources", + "description": "Return agent prompts that can seed a persona description.", + "operationId": "getPersonaAgentPromptSources", + "parameters": [ + { + "name": "agent_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Agent Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentPromptSourcesResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/generate-prompt": { + "post": { + "tags": [ + "personas" + ], + "summary": "Generate Persona Prompt", + "description": "Generate a persona caller prompt from an agent prompt via LLM.", + "operationId": "generatePersonaPrompt", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GeneratePersonaPromptRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GeneratePersonaPromptResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/custom-voices": { + "get": { + "tags": [ + "personas" + ], + "summary": "List Custom Voices", + "description": "List custom TTS voices for the organization.", + "operationId": "listPersonaCustomVoices", + "parameters": [ + { + "name": "provider", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "personas" + ], + "summary": "Create Custom Voice", + "description": "Create a custom TTS voice (org-scoped).", + "operationId": "createPersonaCustomVoice", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomVoiceCreateRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/custom-voices/{custom_voice_id}": { + "put": { + "tags": [ + "personas" + ], + "summary": "Update Custom Voice", + "description": "Update a custom TTS voice.", + "operationId": "updatePersonaCustomVoice", + "parameters": [ + { + "name": "custom_voice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Custom Voice Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomVoiceUpdateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "personas" + ], + "summary": "Delete Custom Voice", + "description": "Delete a custom TTS voice.", + "operationId": "deletePersonaCustomVoice", + "parameters": [ + { + "name": "custom_voice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Custom Voice Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/ambient-presets": { + "get": { + "tags": [ + "personas" + ], + "summary": "List Platform Ambient Presets", + "description": "List platform ambient presets available from installed asset packs.", + "operationId": "listAmbientPresets", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/ambient-presets/{preset_id}/preview": { + "get": { + "tags": [ + "personas" + ], + "summary": "Preview Ambient Preset", + "description": "Stream a platform preset for in-browser preview.", + "operationId": "previewAmbientPreset", + "parameters": [ + { + "name": "preset_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Preset Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/ambient-library": { + "get": { + "tags": [ + "personas" + ], + "summary": "List Ambient Library", + "operationId": "listAmbientLibrary", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AmbientNoiseAssetResponse" + }, + "title": "Response Listambientlibrary" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "personas" + ], + "summary": "Upload Ambient Library Asset", + "description": "Upload a reusable ambient bed to the workspace library.", + "operationId": "uploadAmbientLibraryAsset", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_uploadAmbientLibraryAsset" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AmbientNoiseAssetResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/ambient-library/{asset_id}": { + "patch": { + "tags": [ + "personas" + ], + "summary": "Update Ambient Library Asset", + "description": "Rename a library ambient bed.", + "operationId": "updateAmbientLibraryAsset", + "parameters": [ + { + "name": "asset_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Asset Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AmbientNoiseAssetUpdateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AmbientNoiseAssetResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "personas" + ], + "summary": "Delete Ambient Library Asset", + "operationId": "deleteAmbientLibraryAsset", + "parameters": [ + { + "name": "asset_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Asset Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/ambient-library/{asset_id}/preview": { + "get": { + "tags": [ + "personas" + ], + "summary": "Preview Ambient Library Asset", + "description": "Stream a library ambient bed for in-browser preview.", + "operationId": "previewAmbientLibraryAsset", + "parameters": [ + { + "name": "asset_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Asset Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/ambient-library/{asset_id}/preview-url": { + "get": { + "tags": [ + "personas" + ], + "summary": "Get Ambient Library Preview Url", + "description": "Return a presigned URL for streaming ambient library preview in the browser.", + "operationId": "getAmbientLibraryPreviewUrl", + "parameters": [ + { + "name": "asset_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Asset Id" + } + }, + { + "name": "expiration", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 86400, + "minimum": 60, + "default": 3600, + "title": "Expiration" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AmbientLibraryPreviewUrlResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/{persona_id}": { + "get": { + "tags": [ + "personas" + ], + "summary": "Get Persona", + "description": "Get a specific persona within the active workspace.", + "operationId": "get_persona_api_v1_personas__persona_id__get", + "parameters": [ + { + "name": "persona_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Persona Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersonaResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "put": { + "tags": [ + "personas" + ], + "summary": "Update Persona", + "description": "Update a persona within the active workspace.", + "operationId": "update_persona_api_v1_personas__persona_id__put", + "parameters": [ + { + "name": "persona_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Persona Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersonaUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersonaResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "personas" + ], + "summary": "Delete Persona", + "description": "Delete a persona within the active workspace. Returns 409 if dependent records exist unless force=true.", + "operationId": "delete_persona_api_v1_personas__persona_id__delete", + "parameters": [ + { + "name": "persona_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Persona Id" + } + }, + { + "name": "force", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "Force delete with all dependent records", + "default": false, + "title": "Force" + }, + "description": "Force delete with all dependent records" + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/{persona_id}/clone": { + "post": { + "tags": [ + "personas" + ], + "summary": "Clone Persona", + "description": "Clone an existing persona within the active workspace.", + "operationId": "clone_persona_api_v1_personas__persona_id__clone_post", + "parameters": [ + { + "name": "persona_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Persona Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersonaCloneRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersonaResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/{persona_id}/ambient-audio": { + "post": { + "tags": [ + "personas" + ], + "summary": "Upload Persona Ambient Audio", + "description": "Upload or replace custom ambient audio for a persona (enterprise).", + "operationId": "uploadPersonaAmbientAudio", + "parameters": [ + { + "name": "persona_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Persona Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_uploadPersonaAmbientAudio" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersonaResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "personas" + ], + "summary": "Delete Persona Ambient Audio", + "description": "Delete custom ambient audio for a persona (enterprise).", + "operationId": "deletePersonaAmbientAudio", + "parameters": [ + { + "name": "persona_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Persona Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersonaResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/personas/seed-data": { + "post": { + "tags": [ + "personas" + ], + "summary": "Seed Demo Data", + "description": "Seed database with example personas and scenarios for the active workspace.", + "operationId": "seed_demo_data_api_v1_personas_seed_data_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/scenarios": { + "get": { + "tags": [ + "scenarios" + ], + "summary": "List Scenarios", + "description": "List scenarios for the active workspace.", + "operationId": "list_scenarios_api_v1_scenarios_get", + "parameters": [ + { + "name": "skip", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Skip" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 100, + "title": "Limit" + } + }, + { + "name": "agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ScenarioResponse" + }, + "title": "Response List Scenarios Api V1 Scenarios Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "scenarios" + ], + "summary": "Create Scenario", + "description": "Create a new scenario stamped with the active workspace.", + "operationId": "create_scenario_api_v1_scenarios_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScenarioCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScenarioResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/scenarios/{scenario_id}": { + "get": { + "tags": [ + "scenarios" + ], + "summary": "Get Scenario", + "description": "Get a specific scenario within the active workspace.", + "operationId": "get_scenario_api_v1_scenarios__scenario_id__get", + "parameters": [ + { + "name": "scenario_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Scenario Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScenarioResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "put": { + "tags": [ + "scenarios" + ], + "summary": "Update Scenario", + "description": "Update a scenario within the active workspace.", + "operationId": "update_scenario_api_v1_scenarios__scenario_id__put", + "parameters": [ + { + "name": "scenario_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Scenario Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScenarioUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScenarioResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "scenarios" + ], + "summary": "Delete Scenario", + "description": "Delete a scenario within the active workspace. Returns 409 if dependent records exist unless force=true.", + "operationId": "delete_scenario_api_v1_scenarios__scenario_id__delete", + "parameters": [ + { + "name": "scenario_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Scenario Id" + } + }, + { + "name": "force", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "Force delete with all dependent records", + "default": false, + "title": "Force" + }, + "description": "Force delete with all dependent records" + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/integrations": { + "get": { + "tags": [ + "Integrations" + ], + "summary": "List Integrations", + "description": "List all integrations for the organization.\nRequires at least READER role.", + "operationId": "listIntegrations", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IntegrationResponse" + }, + "title": "Response Listintegrations" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "Integrations" + ], + "summary": "Create Integration", + "description": "Create a new credential row for a voice AI platform.\n\nMultiple credentials per platform are now supported. The first row\ncreated for a given (org, platform) automatically becomes the\ndefault; subsequent rows can be promoted via\n``POST /integrations/{id}/set-default``. ``integration_data.is_default``\ncan also be set explicitly to mark the new row as the default at\ncreation time.\nRequires at least WRITER role.", + "operationId": "createIntegration", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IntegrationCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IntegrationResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/integrations/{integration_id}/set-default": { + "post": { + "tags": [ + "Integrations" + ], + "summary": "Set Default Integration", + "description": "Mark this integration as the default for its (org, platform).\n\nAtomically clears the default flag on every other row for the same\n(org, platform) so the partial unique index in migration 028 holds.", + "operationId": "setDefaultIntegration", + "parameters": [ + { + "name": "integration_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Integration Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IntegrationResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/integrations/{integration_id}": { + "get": { + "tags": [ + "Integrations" + ], + "summary": "Get Integration", + "description": "Get a specific integration.\nRequires at least READER role.", + "operationId": "get_integration_api_v1_integrations__integration_id__get", + "parameters": [ + { + "name": "integration_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Integration Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IntegrationResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "put": { + "tags": [ + "Integrations" + ], + "summary": "Update Integration", + "description": "Update an integration.\nRequires at least WRITER role.", + "operationId": "updateIntegration", + "parameters": [ + { + "name": "integration_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Integration Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IntegrationUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IntegrationResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Integrations" + ], + "summary": "Delete Integration", + "description": "Delete an integration. Returns 409 if agents are using it unless force=true.\nRequires at least WRITER role.", + "operationId": "deleteIntegration", + "parameters": [ + { + "name": "integration_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Integration Id" + } + }, + { + "name": "force", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "Force delete and unlink all agents using this integration", + "default": false, + "title": "Force" + }, + "description": "Force delete and unlink all agents using this integration" + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/integrations/{integration_id}/api-key": { + "get": { + "tags": [ + "Integrations" + ], + "summary": "Get Integration Api Key", + "description": "Get the decrypted API key for an integration.\nThis endpoint is used for client-side operations like web calls.\nRequires at least READER role.", + "operationId": "get_integration_api_key_api_v1_integrations__integration_id__api_key_get", + "parameters": [ + { + "name": "integration_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Integration Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/integrations/{integration_id}/preview-agent-prompt": { + "post": { + "tags": [ + "Integrations" + ], + "summary": "Preview Integration Agent Prompt", + "description": "Fetch a provider agent prompt before an EfficientAI agent exists.", + "operationId": "previewIntegrationAgentPrompt", + "parameters": [ + { + "name": "integration_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Integration Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreviewIntegrationAgentPromptRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreviewIntegrationAgentPromptResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/voicebundles": { + "get": { + "tags": [ + "voicebundles" + ], + "summary": "List Voicebundles", + "description": "List all VoiceBundles for the organization", + "operationId": "listVoiceBundles", + "parameters": [ + { + "name": "skip", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Skip" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 100, + "title": "Limit" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VoiceBundleResponse" + }, + "title": "Response Listvoicebundles" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "voicebundles" + ], + "summary": "Create Voicebundle", + "description": "Create a new VoiceBundle", + "operationId": "createVoiceBundle", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoiceBundleCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoiceBundleResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/voicebundles/{voicebundle_id}": { + "get": { + "tags": [ + "voicebundles" + ], + "summary": "Get Voicebundle", + "description": "Get a specific VoiceBundle", + "operationId": "get_voicebundle_api_v1_voicebundles__voicebundle_id__get", + "parameters": [ + { + "name": "voicebundle_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Voicebundle Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoiceBundleResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "put": { + "tags": [ + "voicebundles" + ], + "summary": "Update Voicebundle", + "description": "Update an existing VoiceBundle", + "operationId": "updateVoiceBundle", + "parameters": [ + { + "name": "voicebundle_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Voicebundle Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoiceBundleUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoiceBundleResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "voicebundles" + ], + "summary": "Delete Voicebundle", + "description": "Delete a VoiceBundle. Returns 409 if dependent records exist unless force=true.", + "operationId": "deleteVoiceBundle", + "parameters": [ + { + "name": "voicebundle_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Voicebundle Id" + } + }, + { + "name": "force", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "Force delete with all dependent records", + "default": false, + "title": "Force" + }, + "description": "Force delete with all dependent records" + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/aiproviders": { + "get": { + "tags": [ + "aiproviders" + ], + "summary": "List Aiproviders", + "description": "List all AI Providers for the organization.", + "operationId": "listAIProviders", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AIProviderResponse" + }, + "title": "Response Listaiproviders" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "aiproviders" + ], + "summary": "Create Aiprovider", + "description": "Create a new AI Provider credential row.", + "operationId": "createAIProvider", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AIProviderCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AIProviderResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/aiproviders/{aiprovider_id}": { + "get": { + "tags": [ + "aiproviders" + ], + "summary": "Get Aiprovider", + "description": "Get a specific AI Provider", + "operationId": "get_aiprovider_api_v1_aiproviders__aiprovider_id__get", + "parameters": [ + { + "name": "aiprovider_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Aiprovider Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AIProviderResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "put": { + "tags": [ + "aiproviders" + ], + "summary": "Update Aiprovider", + "description": "Update an existing AI Provider", + "operationId": "updateAIProvider", + "parameters": [ + { + "name": "aiprovider_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Aiprovider Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AIProviderUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AIProviderResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "aiproviders" + ], + "summary": "Delete Aiprovider", + "description": "Delete an AI Provider", + "operationId": "deleteAIProvider", + "parameters": [ + { + "name": "aiprovider_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Aiprovider Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/aiproviders/{aiprovider_id}/set-default": { + "post": { + "tags": [ + "aiproviders" + ], + "summary": "Set Default Aiprovider", + "description": "Mark this AIProvider row as the default for its (org, provider).", + "operationId": "setDefaultAIProvider", + "parameters": [ + { + "name": "aiprovider_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Aiprovider Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AIProviderResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/aiproviders/{aiprovider_id}/test": { + "post": { + "tags": [ + "aiproviders" + ], + "summary": "Test Aiprovider", + "description": "Test an AI Provider API key", + "operationId": "testAIProvider", + "parameters": [ + { + "name": "aiprovider_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Aiprovider Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluators/format-prompt": { + "post": { + "tags": [ + "evaluators" + ], + "summary": "Format Custom Prompt", + "description": "Reformat a raw custom prompt into well-structured markdown using the org's LLM.", + "operationId": "format_custom_prompt_api_v1_evaluators_format_prompt_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FormatPromptRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FormatPromptResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluators": { + "get": { + "tags": [ + "evaluators" + ], + "summary": "List Evaluators", + "description": "List evaluators in the active workspace.", + "operationId": "list_evaluators_api_v1_evaluators_get", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EvaluatorResponse" + }, + "title": "Response List Evaluators Api V1 Evaluators Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "evaluators" + ], + "summary": "Create Evaluator", + "description": "Create a single standard evaluator (legacy). Use POST /evaluator-suites for new setups.", + "operationId": "create_evaluator_api_v1_evaluators_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluators/bulk": { + "post": { + "tags": [ + "evaluators" + ], + "summary": "Create Evaluators Bulk", + "description": "Create multiple evaluators in the active workspace for the same agent/scenario.", + "operationId": "create_evaluators_bulk_api_v1_evaluators_bulk_post", + "deprecated": true, + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorBulkCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EvaluatorResponse" + }, + "title": "Response Create Evaluators Bulk Api V1 Evaluators Bulk Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluators/{evaluator_id}": { + "get": { + "tags": [ + "evaluators" + ], + "summary": "Get Evaluator", + "description": "Get an evaluator in the active workspace by UUID or evaluator_id (6-digit).", + "operationId": "get_evaluator_api_v1_evaluators__evaluator_id__get", + "parameters": [ + { + "name": "evaluator_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Evaluator Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "put": { + "tags": [ + "evaluators" + ], + "summary": "Update Evaluator", + "description": "Update an evaluator within the active workspace.", + "operationId": "update_evaluator_api_v1_evaluators__evaluator_id__put", + "parameters": [ + { + "name": "evaluator_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Evaluator Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "evaluators" + ], + "summary": "Delete Evaluator", + "description": "Delete an evaluator in the active workspace while preserving dependent results.", + "operationId": "delete_evaluator_api_v1_evaluators__evaluator_id__delete", + "parameters": [ + { + "name": "evaluator_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Evaluator Id" + } + }, + { + "name": "force", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "Deprecated: evaluator deletion keeps dependent results", + "default": false, + "title": "Force" + }, + "description": "Deprecated: evaluator deletion keeps dependent results" + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluators/run": { + "post": { + "tags": [ + "evaluators" + ], + "summary": "Run Evaluators", + "description": "Run multiple evaluators in the active workspace in parallel using Celery workers.", + "operationId": "run_evaluators_api_v1_evaluators_run_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunEvaluatorsRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunEvaluatorsResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-suites": { + "get": { + "tags": [ + "evaluator-suites" + ], + "summary": "List Suites", + "operationId": "list_suites_api_v1_evaluator_suites_get", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EvaluatorSuiteResponse" + }, + "title": "Response List Suites Api V1 Evaluator Suites Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "evaluator-suites" + ], + "summary": "Create Suite", + "operationId": "create_suite_api_v1_evaluator_suites_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-suites/{suite_id}": { + "get": { + "tags": [ + "evaluator-suites" + ], + "summary": "Get Suite", + "operationId": "get_suite_api_v1_evaluator_suites__suite_id__get", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "put": { + "tags": [ + "evaluator-suites" + ], + "summary": "Update Suite", + "operationId": "update_suite_api_v1_evaluator_suites__suite_id__put", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "evaluator-suites" + ], + "summary": "Delete Suite", + "operationId": "delete_suite_api_v1_evaluator_suites__suite_id__delete", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-suites/{suite_id}/scenarios": { + "post": { + "tags": [ + "evaluator-suites" + ], + "summary": "Add Scenarios", + "operationId": "add_scenarios_api_v1_evaluator_suites__suite_id__scenarios_post", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteAddScenariosRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-suites/{suite_id}/scenarios/{scenario_id}": { + "delete": { + "tags": [ + "evaluator-suites" + ], + "summary": "Remove Scenario", + "operationId": "remove_scenario_api_v1_evaluator_suites__suite_id__scenarios__scenario_id__delete", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "scenario_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Scenario Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-suites/{suite_id}/personas": { + "post": { + "tags": [ + "evaluator-suites" + ], + "summary": "Add Personas", + "operationId": "add_personas_api_v1_evaluator_suites__suite_id__personas_post", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteAddPersonasRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "put": { + "tags": [ + "evaluator-suites" + ], + "summary": "Replace Personas", + "operationId": "replace_personas_api_v1_evaluator_suites__suite_id__personas_put", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteReplacePersonasRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-suites/{suite_id}/personas/{persona_id}": { + "delete": { + "tags": [ + "evaluator-suites" + ], + "summary": "Remove Persona", + "operationId": "remove_persona_api_v1_evaluator_suites__suite_id__personas__persona_id__delete", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "persona_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Persona Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-suites/{suite_id}/activate": { + "post": { + "tags": [ + "evaluator-suites" + ], + "summary": "Activate Suite", + "description": "Set this suite as the active inbound configuration for its agent.", + "operationId": "activate_suite_api_v1_evaluator_suites__suite_id__activate_post", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorSuiteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-suites/{suite_id}/run": { + "post": { + "tags": [ + "evaluator-suites" + ], + "summary": "Run Suite", + "operationId": "run_suite_api_v1_evaluator_suites__suite_id__run_post", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunEvaluatorSuiteRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunEvaluatorSuiteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-suites/{suite_id}/choose-next": { + "post": { + "tags": [ + "evaluator-suites" + ], + "summary": "Choose Next Combination", + "description": "Advance inbound round-robin to the next scenario without placing a call.", + "operationId": "choose_next_combination_api_v1_evaluator_suites__suite_id__choose_next_post", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChooseNextCombinationResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-suites/{suite_id}/run-next": { + "post": { + "tags": [ + "evaluator-suites" + ], + "summary": "Run Next Combination", + "operationId": "run_next_combination_api_v1_evaluator_suites__suite_id__run_next_post", + "parameters": [ + { + "name": "suite_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunNextCombinationRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunNextCombinationResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics": { + "get": { + "tags": [ + "metrics" + ], + "summary": "List Metrics", + "description": "List metrics with optional nesting for the parent/child hierarchy.\n\nReturns the union of:\n * Metrics scoped to the active workspace (``workspace_id == ws``).\n * Metrics shared at the org level (``workspace_id IS NULL``).\n\nThis is what makes org-shared metrics appear inside every workspace\nof the org without the user having to recreate them. Switching\nworkspace in the UI still narrows the workspace-scoped half; the\norg-shared half is identical across workspaces.", + "operationId": "list_metrics_api_v1_metrics_get", + "parameters": [ + { + "name": "surface", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Surface" + } + }, + { + "name": "include_drafts", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "When true, include draft metrics (Studio-only) in the listing.", + "default": false, + "title": "Include Drafts" + }, + "description": "When true, include draft metrics (Studio-only) in the listing." + }, + { + "name": "drafts_only", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "When true, return only draft metrics.", + "default": false, + "title": "Drafts Only" + }, + "description": "When true, return only draft metrics." + }, + { + "name": "enabled_only", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "When true, return only metrics enabled in the active workspace. Category parents are included when at least one child is enabled.", + "default": false, + "title": "Enabled Only" + }, + "description": "When true, return only metrics enabled in the active workspace. Category parents are included when at least one child is enabled." + }, + { + "name": "include_children", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "When true (default), children are nested under their parent and not returned as top-level rows. When false, the response is a flat list of every metric (parents + standalone + orphaned children).", + "default": true, + "title": "Include Children" + }, + "description": "When true (default), children are nested under their parent and not returned as top-level rows. When false, the response is a flat list of every metric (parents + standalone + orphaned children)." + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MetricResponse" + }, + "title": "Response List Metrics Api V1 Metrics Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "metrics" + ], + "summary": "Create Metric", + "description": "Create a new metric.\n\nSupports flat metrics, parent \"category\" metrics (set\n``selection_mode``), and child sub-metrics (set\n``parent_metric_id``). Name uniqueness is scoped to\n``(organization_id, workspace_id, parent_metric_id)`` so the same\nlabel can exist in multiple workspaces (and under multiple parents).\n\nScope:\n * ``scope=\"workspace\"`` (default) stamps the metric with the\n active ``X-Workspace-Id`` (existing behavior).\n * ``scope=\"organization\"`` stamps ``workspace_id=NULL`` so the\n metric appears in every workspace of the caller's org.\n\nChildren always inherit their parent's scope (workspace UUID or\nNULL) - we override the request's workspace + scope when\n``parent_metric_id`` is set so a stale UI can't accidentally split\na tree across workspaces or scopes.", + "operationId": "create_metric_api_v1_metrics_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics/drafts": { + "post": { + "tags": [ + "metrics" + ], + "summary": "Create Metric Draft", + "description": "Create a draft metric for Metrics Studio (hidden from production flows).", + "operationId": "createMetricDraft", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricDraftCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics/drafts/with-children": { + "post": { + "tags": [ + "metrics" + ], + "summary": "Create Metric Draft With Children", + "description": "Atomically create a draft parent category metric plus its children.", + "operationId": "createMetricDraftWithChildren", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricDraftCreateWithChildren" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics/{metric_id}/promote": { + "post": { + "tags": [ + "metrics" + ], + "summary": "Promote Metric Draft", + "description": "Promote a draft metric to active production use.", + "operationId": "promoteMetricDraft", + "parameters": [ + { + "name": "metric_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Metric Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricPromoteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics/with-children": { + "post": { + "tags": [ + "metrics" + ], + "summary": "Create Metric With Children", + "description": "Atomically create a parent category metric plus its children.\n\nThe parent gets ``metric_type=text`` (it's a category label, not a\nscore) and ``selection_mode`` from the payload. Every child is\nforced to ``boolean`` so the LLM-evaluation path treats them as\nyes/no labels. Both the parent and all children are stamped with\nthe same scope: either the active workspace (``scope=\"workspace\"``,\ndefault) or ``workspace_id=NULL`` (``scope=\"organization\"``, the\norg-shared shape).", + "operationId": "createMetricWithChildren", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricCreateWithChildren" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics/{metric_id}/children": { + "post": { + "tags": [ + "metrics" + ], + "summary": "Add Metric Child", + "description": "Append a new child sub-metric under an existing parent.", + "operationId": "addMetricChild", + "parameters": [ + { + "name": "metric_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Metric Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricChildDraft" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics/{metric_id}/children/from-discovered": { + "post": { + "tags": [ + "metrics" + ], + "summary": "Promote Discovered Child", + "description": "Promote an LLM-discovered candidate label into a real child metric.\n\nMirrors ``add_metric_child`` but:\n * Works on any parent (single_choice OR multi_label) that has\n ``allow_discovery=true``.\n * The new child's name is normalized so that ``slug(name)`` equals\n the supplied ``key``. This is critical โ€” without it, the\n already-scored rows' ``sequence`` arrays would not resolve\n against the promoted child once the candidate disappears from\n ``discovered_labels``.", + "operationId": "promoteDiscoveredChild", + "parameters": [ + { + "name": "metric_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Metric Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PromoteDiscoveredChildRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics/from-discovered": { + "post": { + "tags": [ + "metrics" + ], + "summary": "Promote Discovered Metric", + "description": "Promote an LLM-discovered top-level metric into a real Metric row.\n\nParallel to :func:`promote_discovered_child` but creates a\nstandalone metric (``parent_metric_id=None``) instead of a child.\nThe new metric's name is normalized so ``slug(name) == key`` โ€”\nthis keeps any already-scored rows that referenced the candidate\nunder the promoted slug resolvable without a backfill, and\nprevents duplicate promotions from sneaking in under slightly\ndifferent casing.\n\n``metric_type`` selects how future evaluation runs will score the\nnew metric: ``boolean`` / ``rating`` are scored standalone;\n``category`` creates a ``multi_label`` parent with no children\nthat the user can populate via the Metrics page.", + "operationId": "promoteDiscoveredMetric", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PromoteDiscoveredMetricRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics/{metric_id}": { + "get": { + "tags": [ + "metrics" + ], + "summary": "Get Metric", + "description": "Get a specific metric, with children inlined for parents.", + "operationId": "get_metric_api_v1_metrics__metric_id__get", + "parameters": [ + { + "name": "metric_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Metric Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "put": { + "tags": [ + "metrics" + ], + "summary": "Update Metric", + "description": "Update a metric.", + "operationId": "update_metric_api_v1_metrics__metric_id__put", + "parameters": [ + { + "name": "metric_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Metric Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "metrics" + ], + "summary": "Delete Metric", + "description": "Delete a metric.", + "operationId": "delete_metric_api_v1_metrics__metric_id__delete", + "parameters": [ + { + "name": "metric_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Metric Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics/seed-defaults": { + "post": { + "tags": [ + "metrics" + ], + "summary": "Seed Default Metrics", + "description": "Seed default metrics for an organization (in the active workspace).\n\nDefault metrics live in the workspace the caller is currently in;\nthis matches the rest of the metrics surface and lets a user seed\nthe same defaults independently per workspace if they want to.", + "operationId": "seed_default_metrics_api_v1_metrics_seed_defaults_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MetricResponse" + }, + "title": "Response Seed Default Metrics Api V1 Metrics Seed Defaults Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics/generate": { + "post": { + "tags": [ + "metrics" + ], + "summary": "Generate Metric", + "description": "Use an LLM to suggest a metric definition. Does NOT persist anything.", + "operationId": "generate_metric_api_v1_metrics_generate_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricGenerateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricGenerateResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/metrics/parse-bulk": { + "post": { + "tags": [ + "metrics" + ], + "summary": "Parse Bulk Metric", + "description": "Parse a multi-label rubric into a *list* of independent metric drafts.\n\nEach \"Label #N\" block becomes its own un-persisted draft metric the\nuser can edit (name, type, capture_rationale, ...) before POSTing to\n``/metrics`` individually. Defaults are chosen so the most common\ncase (\"did happen?\") is one click away: ``metric_type=\"boolean\"``\nwith ``capture_rationale=True``.\n\nThe endpoint does NOT write to the database.", + "operationId": "parse_bulk_metric_api_v1_metrics_parse_bulk_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricParseBulkRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricParseBulkResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/metric-clusters/failure-policies": { + "get": { + "tags": [ + "evaluator-results" + ], + "summary": "Get Evaluator Result Metric Cluster Failure Policies", + "operationId": "getEvaluatorResultMetricClusterFailurePolicies", + "parameters": [ + { + "name": "agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + } + }, + { + "name": "scenario_ids", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "title": "Scenario Ids" + } + }, + { + "name": "since", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Since" + } + }, + { + "name": "until", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Until" + } + }, + { + "name": "suite_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Suite Id" + } + }, + { + "name": "scenario_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + } + }, + { + "name": "scope_key", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Key" + } + }, + { + "name": "job_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricFailurePoliciesResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "put": { + "tags": [ + "evaluator-results" + ], + "summary": "Save Evaluator Result Metric Cluster Failure Policies", + "operationId": "saveEvaluatorResultMetricClusterFailurePolicies", + "parameters": [ + { + "name": "agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + } + }, + { + "name": "scenario_ids", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "title": "Scenario Ids" + } + }, + { + "name": "since", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Since" + } + }, + { + "name": "until", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Until" + } + }, + { + "name": "suite_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Suite Id" + } + }, + { + "name": "scenario_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + } + }, + { + "name": "scope_key", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Key" + } + }, + { + "name": "job_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricFailurePoliciesSaveRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricFailurePoliciesResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/metric-clusters/eligible-rows": { + "get": { + "tags": [ + "evaluator-results" + ], + "summary": "List Evaluator Result Metric Cluster Eligible Rows", + "operationId": "listEvaluatorResultMetricClusterEligibleRows", + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "integer", + "minimum": 1 + }, + { + "type": "null" + } + ], + "title": "Limit" + } + }, + { + "name": "count_only", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": false, + "title": "Count Only" + } + }, + { + "name": "agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + } + }, + { + "name": "scenario_ids", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "title": "Scenario Ids" + } + }, + { + "name": "since", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Since" + } + }, + { + "name": "until", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Until" + } + }, + { + "name": "suite_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Suite Id" + } + }, + { + "name": "scenario_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + } + }, + { + "name": "scope_key", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Key" + } + }, + { + "name": "job_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricClusterEligibleRowsResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/metric-clusters/scopes": { + "get": { + "tags": [ + "evaluator-results" + ], + "summary": "List Evaluator Result Metric Cluster Scopes", + "operationId": "listEvaluatorResultMetricClusterScopes", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorResultClusterScopeListResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/metric-clusters": { + "get": { + "tags": [ + "evaluator-results" + ], + "summary": "Get Evaluator Result Metric Clusters", + "operationId": "getEvaluatorResultMetricClusters", + "parameters": [ + { + "name": "agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + } + }, + { + "name": "scenario_ids", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "title": "Scenario Ids" + } + }, + { + "name": "since", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Since" + } + }, + { + "name": "until", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Until" + } + }, + { + "name": "suite_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Suite Id" + } + }, + { + "name": "scenario_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + } + }, + { + "name": "scope_key", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Key" + } + }, + { + "name": "job_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/EvaluationMetricClustersState" + }, + { + "type": "null" + } + ], + "title": "Response Getevaluatorresultmetricclusters" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "evaluator-results" + ], + "summary": "Generate Evaluator Result Metric Clusters", + "operationId": "generateEvaluatorResultMetricClusters", + "parameters": [ + { + "name": "agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + } + }, + { + "name": "scenario_ids", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "title": "Scenario Ids" + } + }, + { + "name": "since", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Since" + } + }, + { + "name": "until", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Until" + } + }, + { + "name": "suite_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Suite Id" + } + }, + { + "name": "scenario_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + } + }, + { + "name": "scope_key", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Key" + } + }, + { + "name": "job_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluationMetricClustersRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluationMetricClustersState" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "evaluator-results" + ], + "summary": "Delete Evaluator Result Metric Clusters", + "operationId": "deleteEvaluatorResultMetricClusters", + "parameters": [ + { + "name": "agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + } + }, + { + "name": "scenario_ids", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "title": "Scenario Ids" + } + }, + { + "name": "since", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Since" + } + }, + { + "name": "until", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Until" + } + }, + { + "name": "suite_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Suite Id" + } + }, + { + "name": "scenario_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + } + }, + { + "name": "scope_key", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Key" + } + }, + { + "name": "job_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/metric-clusters/cancel": { + "post": { + "tags": [ + "evaluator-results" + ], + "summary": "Cancel Evaluator Result Metric Clusters", + "operationId": "cancelEvaluatorResultMetricClusters", + "parameters": [ + { + "name": "agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + } + }, + { + "name": "scenario_ids", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "title": "Scenario Ids" + } + }, + { + "name": "since", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Since" + } + }, + { + "name": "until", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Until" + } + }, + { + "name": "suite_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Suite Id" + } + }, + { + "name": "scenario_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + } + }, + { + "name": "scope_key", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Key" + } + }, + { + "name": "job_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluationMetricClustersState" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/overview": { + "get": { + "tags": [ + "evaluator-results" + ], + "summary": "Get Evaluator Results Overview", + "description": "Workspace rollups for agent โ†’ suite โ†’ scenario navigation.", + "operationId": "get_evaluator_results_overview_api_v1_evaluator_results_overview_get", + "parameters": [ + { + "name": "agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "When set, return suites for this agent", + "title": "Agent Id" + }, + "description": "When set, return suites for this agent" + }, + { + "name": "suite_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "When set, return scenarios for this suite", + "title": "Suite Id" + }, + "description": "When set, return scenarios for this suite" + }, + { + "name": "since", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Since" + } + }, + { + "name": "until", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Until" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorResultsOverviewResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/aggregate": { + "get": { + "tags": [ + "evaluator-results" + ], + "summary": "Get Evaluator Results Aggregate", + "description": "Metric distributions for completed evaluator results in a scope.", + "operationId": "get_evaluator_results_aggregate_api_v1_evaluator_results_aggregate_get", + "parameters": [ + { + "name": "suite_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Suite Id" + } + }, + { + "name": "agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + } + }, + { + "name": "scenario_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + } + }, + { + "name": "since", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Since" + } + }, + { + "name": "until", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Until" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorResultsAggregateResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results": { + "get": { + "tags": [ + "evaluator-results" + ], + "summary": "List Evaluator Results", + "description": "List evaluator results within the active workspace.\n\nBy default, excludes playground test results (where evaluator_id is NULL).\nUse playground=true to get only playground results, or playground=false to explicitly exclude them.\nUse test_agents_only=true to filter out Voice AI Agent results (those with provider_platform set).", + "operationId": "list_evaluator_results_api_v1_evaluator_results_get", + "parameters": [ + { + "name": "skip", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Skip" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 100, + "title": "Limit" + } + }, + { + "name": "evaluator_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Evaluator Id" + } + }, + { + "name": "agent_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by associated agent UUID", + "title": "Agent Id" + }, + "description": "Filter by associated agent UUID" + }, + { + "name": "suite_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by evaluator suite UUID", + "title": "Suite Id" + }, + "description": "Filter by evaluator suite UUID" + }, + { + "name": "scenario_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by scenario UUID", + "title": "Scenario Id" + }, + "description": "Filter by scenario UUID" + }, + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by display status: completed, failed, in_progress", + "title": "Status" + }, + "description": "Filter by display status: completed, failed, in_progress" + }, + { + "name": "since", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Since" + } + }, + { + "name": "until", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Until" + } + }, + { + "name": "unassigned_only", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "When true, only legacy/manual results without a suite", + "title": "Unassigned Only" + }, + "description": "When true, only legacy/manual results without a suite" + }, + { + "name": "playground", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "If true, only return playground test results (evaluator_id is NULL). If false, exclude playground results. If not provided, exclude playground results by default.", + "title": "Playground" + }, + "description": "If true, only return playground test results (evaluator_id is NULL). If false, exclude playground results. If not provided, exclude playground results by default." + }, + { + "name": "test_agents_only", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "If true, only return Test Agent results (no provider_platform). If false, include all playground results.", + "title": "Test Agents Only" + }, + "description": "If true, only return Test Agent results (no provider_platform). If false, include all playground results." + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorResultListResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "evaluator-results" + ], + "summary": "Create Evaluator Result Manual", + "description": "Manually create an evaluator result in the active workspace from an existing audio file.\n\nThe referenced evaluator must already belong to the active workspace.", + "operationId": "create_evaluator_result_manual_api_v1_evaluator_results_post", + "parameters": [ + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorResultCreateManual" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorResultResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "evaluator-results" + ], + "summary": "Delete Evaluator Results Bulk", + "description": "Delete multiple evaluator results in the active workspace by their IDs.", + "operationId": "delete_evaluator_results_bulk_api_v1_evaluator_results_delete", + "parameters": [ + { + "name": "result_ids", + "in": "query", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "title": "Result Ids" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/{id}": { + "get": { + "tags": [ + "evaluator-results" + ], + "summary": "Get Evaluator Result", + "description": "Get a specific evaluator result in the active workspace by UUID or result_id (6-digit).", + "operationId": "get_evaluator_result_api_v1_evaluator_results__id__get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "include_relations", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": true, + "title": "Include Relations" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorResultResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "evaluator-results" + ], + "summary": "Delete Evaluator Result", + "description": "Delete a specific evaluator result in the active workspace by UUID or result_id.", + "operationId": "delete_evaluator_result_api_v1_evaluator_results__id__delete", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/{id}/live-events": { + "get": { + "tags": [ + "evaluator-results" + ], + "summary": "Stream Evaluator Result Live Events", + "description": "SSE stream of live transcript turns for an in-progress eval telephony call.", + "operationId": "stream_evaluator_result_live_events_api_v1_evaluator_results__id__live_events_get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/{id}/metrics": { + "get": { + "tags": [ + "evaluator-results" + ], + "summary": "Get Evaluator Result Metrics", + "description": "Get metric scores for an evaluator result in the active workspace.", + "operationId": "get_evaluator_result_metrics_api_v1_evaluator_results__id__metrics_get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Response Get Evaluator Result Metrics Api V1 Evaluator Results Id Metrics Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/{id}/audio": { + "get": { + "tags": [ + "evaluator-results" + ], + "summary": "Stream Evaluator Result Audio", + "description": "Stream evaluator result audio from S3 or proxy auth-gated provider URLs.", + "operationId": "stream_evaluator_result_audio_api_v1_evaluator_results__id__audio_get", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/evaluator-results/{id}/re-evaluate": { + "post": { + "tags": [ + "evaluator-results" + ], + "summary": "Re Evaluate Result", + "description": "Re-evaluate an existing evaluator result.\n\nIf the result already has audio in S3, reuses it. Otherwise attempts to\ndownload the recording from the voice provider (ElevenLabs / Retell / Vapi),\nuploads it to S3, and stores the key so that audio-dependent quality\nmetrics (pitch, jitter, MOS, emotion, etc.) can run alongside the\nLLM-based transcript metrics.", + "operationId": "re_evaluate_result_api_v1_evaluator_results__id__re_evaluate_post", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluatorResultResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/observability/calls/webhook/retell/{api_key}": { + "post": { + "tags": [ + "observability" + ], + "summary": "Ingest Retell Webhook", + "description": "Retell-specific webhook โ€” API key embedded in the URL.\n\nUsage:\n POST https://your-domain.com/api/v1/observability/calls/webhook/retell/\n\nAccepts Retell's native webhook payload format:\n``{\"event\": \"call_ended\", \"call\": {...}}``", + "operationId": "ingest_retell_webhook_api_v1_observability_calls_webhook_retell__api_key__post", + "parameters": [ + { + "name": "api_key", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Api Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Body" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Response Ingest Retell Webhook Api V1 Observability Calls Webhook Retell Api Key Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/observability/calls/webhook/{api_key}": { + "post": { + "tags": [ + "observability" + ], + "summary": "Ingest Call Via Webhook Url", + "description": "Generic webhook โ€” API key embedded in the URL (Slack-style).\n\nUsage:\n POST https://your-domain.com/api/v1/observability/calls/webhook/\n\nAccepts the flat call ingestion format:\n``{\"id\": \"...\", \"messages\": [...], \"startedAt\": \"...\", ...}``", + "operationId": "ingest_call_via_webhook_url_api_v1_observability_calls_webhook__api_key__post", + "parameters": [ + { + "name": "api_key", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Api Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Body" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Response Ingest Call Via Webhook Url Api V1 Observability Calls Webhook Api Key Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/observability/calls": { + "get": { + "tags": [ + "observability" + ], + "summary": "List Calls", + "description": "List ingested call records in the active workspace.", + "operationId": "list_calls_api_v1_observability_calls_get", + "parameters": [ + { + "name": "skip", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Skip" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 100, + "title": "Limit" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true + }, + "title": "Response List Calls Api V1 Observability Calls Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/observability/calls/{call_short_id}": { + "get": { + "tags": [ + "observability" + ], + "summary": "Get Call", + "description": "Retrieve a specific call in the active workspace by its short ID.", + "operationId": "get_call_api_v1_observability_calls__call_short_id__get", + "parameters": [ + { + "name": "call_short_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Call Short Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Response Get Call Api V1 Observability Calls Call Short Id Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "observability" + ], + "summary": "Delete Call", + "description": "Delete a webhook ingested call recording in the active workspace.", + "operationId": "delete_call_api_v1_observability_calls__call_short_id__delete", + "parameters": [ + { + "name": "call_short_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Call Short Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Response Delete Call Api V1 Observability Calls Call Short Id Delete" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/observability/calls/{call_short_id}/live-events": { + "get": { + "tags": [ + "observability" + ], + "summary": "Stream Call Live Events", + "description": "Server-sent events stream for live transcript turns during an active call.", + "operationId": "stream_call_live_events_api_v1_observability_calls__call_short_id__live_events_get", + "parameters": [ + { + "name": "call_short_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Call Short Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/observability/calls/{call_short_id}/audio": { + "get": { + "tags": [ + "observability" + ], + "summary": "Stream Observability Call Audio", + "description": "Stream call recording audio for observability calls (S3 or provider URL).", + "operationId": "stream_observability_call_audio_api_v1_observability_calls__call_short_id__audio_get", + "parameters": [ + { + "name": "call_short_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Call Short Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/observability/calls/{call_short_id}/evaluate": { + "post": { + "tags": [ + "observability" + ], + "summary": "Evaluate Call", + "description": "Trigger an LLM evaluation on an ingested call in the active workspace.\n\nBoth the call recording and the evaluator must already live in the same\nworkspace as the caller.", + "operationId": "evaluate_call_api_v1_observability_calls__call_short_id__evaluate_post", + "parameters": [ + { + "name": "call_short_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Call Short Id" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluateCallPayload" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Response Evaluate Call Api V1 Observability Calls Call Short Id Evaluate Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/preview": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Preview Call Import File", + "description": "Inspect an uploaded CSV / Excel file and return its sheets + headers.\n\nDrives the column-mapping UI without forcing the frontend to parse\nCSV / xlsx itself โ€” keeps client and server in lockstep on quoted\nfields, encodings, and Excel cell coercion. CSVs return a single\nsynthetic sheet named after the filename; Excel workbooks return one\nentry per worksheet (in workbook order).", + "operationId": "previewCallImportFile", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_previewCallImportFile" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportPreviewResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports": { + "get": { + "tags": [ + "Call Imports" + ], + "summary": "List Call Imports", + "description": "List call-import batches for the active workspace, newest first.\n\nScoped to (organization_id, workspace_id) so users only see imports\nfor the workspace they're currently in. Supports a high-level\n``dataset`` filter (powers the segregation dropdown at the top of\nthe imports page) plus an AND-style multi-tag filter via repeated\n``tag_id`` parameters.", + "operationId": "listCallImports", + "parameters": [ + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "default": 1, + "title": "Page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 20, + "title": "Page Size" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/CallImportStatus" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + { + "name": "dataset", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by exact dataset string (case-insensitive). Pass the literal value '__none__' to filter to imports with no dataset.", + "title": "Dataset" + }, + "description": "Filter by exact dataset string (case-insensitive). Pass the literal value '__none__' to filter to imports with no dataset." + }, + { + "name": "tag_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + { + "type": "null" + } + ], + "description": "Filter to imports tagged with ALL of the given tag ids.", + "title": "Tag Id" + }, + "description": "Filter to imports tagged with ALL of the given tag ids." + }, + { + "name": "source_format", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by source format. Use 'audio' for manual recordings or '__non_audio__' for CSV/Excel/legacy imports.", + "title": "Source Format" + }, + "description": "Filter by source format. Use 'audio' for manual recordings or '__non_audio__' for CSV/Excel/legacy imports." + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportListResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Create Call Import", + "description": "UPLOAD stage of the staged call-import flow.\n\nPersists the source file to S3 and creates a ``CallImport`` row with\n``status='uploaded'``. No mapping, no provider, no rows yet โ€” the\nuser moves through MAP and IMPORT as separate idempotent steps.\n\nDataset is collected here (rather than at IMPORT) so the batch is\nfilterable from the moment it appears in the list view.", + "operationId": "createCallImport", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_createCallImport" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/mapping": { + "patch": { + "tags": [ + "Call Imports" + ], + "summary": "Update Call Import Mapping", + "description": "MAP stage of the staged call-import flow.\n\nValidates ``parameter_mapping`` + ``skipped_columns`` against the\nsheet headers captured at UPLOAD time and persists them on the\nbatch. Idempotent: callers may submit this multiple times while\nthe batch is in ``uploaded`` or ``mapped`` state.", + "operationId": "updateCallImportMapping", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportMappingUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/import": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Start Call Import", + "description": "Deprecated IMPORT stage โ€” use Run Evaluation for new batches.\n\nRecording fetch is part of the unified evaluation pipeline. This\nendpoint remains available only with ``?legacy=true`` for backward\ncompatibility.", + "operationId": "startCallImport", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "legacy", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "Deprecated escape hatch for import-only processing. New batches should use Run Evaluation instead.", + "default": false, + "title": "Legacy" + }, + "description": "Deprecated escape hatch for import-only processing. New batches should use Run Evaluation instead." + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportStartRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportUploadResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/upload": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Upload Call Import Csv", + "description": "Legacy one-shot upload kept for backward compatibility.\n\nDEPRECATED: prefer the staged flow\n(``POST /`` โ†’ ``PATCH /{id}/mapping`` โ†’ ``POST /{id}/import``) so\neach step is idempotent and resumable. This endpoint runs all three\nstages inline in a single transaction so existing scripts /\nintegrations keep working unchanged.", + "operationId": "uploadCallImportCsv", + "deprecated": true, + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_uploadCallImportCsv" + } + } + } + }, + "responses": { + "202": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportUploadResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/audio-upload": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Upload Call Import Audio", + "description": "Persist manually uploaded recordings as completed CallImport rows.\n\nThe rows skip the provider-download worker entirely because the audio\nbytes are already in hand. From this point onward they behave exactly\nlike completed CSV-import rows: playback reads ``recording_s3_key`` and\nthe existing diarisation/evaluation endpoints can operate on them.", + "operationId": "uploadCallImportAudio", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_uploadCallImportAudio" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportUploadResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/audio-append": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Append Call Import Audio", + "description": "Append manually uploaded recordings to an existing audio batch.", + "operationId": "appendCallImportAudio", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_appendCallImportAudio" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportUploadResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/dispatch-diagnostics": { + "get": { + "tags": [ + "Call Imports" + ], + "summary": "Get Call Import Dispatch Diagnostics", + "description": "Live eval slot usage and fair-dispatch state for operators.\n\nOrg admins use this to diagnose cross-workspace starvation (e.g. one\nworkspace's 10k run blocking another's pending eval rows) by inspecting\nRedis in-flight counters, pending dispatch rows, and scheduler cursors.", + "operationId": "getCallImportDispatchDiagnostics", + "parameters": [ + { + "name": "workspace_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "description": "Optional workspace filter. When omitted, returns every workspace in the organization with active eval dispatch state.", + "title": "Workspace Id" + }, + "description": "Optional workspace filter. When omitted, returns every workspace in the organization with active eval dispatch state." + }, + { + "name": "include_idle_workspaces", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "When true, include org workspaces with zero pending rows and zero in-flight slots.", + "default": false, + "title": "Include Idle Workspaces" + }, + "description": "When true, include org workspaces with zero pending rows and zero in-flight slots." + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportDispatchDiagnosticsResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/datasets": { + "get": { + "tags": [ + "Call Imports" + ], + "summary": "List Call Import Datasets", + "description": "Return the distinct, non-null dataset labels in use for the active\nworkspace.\n\nScoped per-workspace so each workspace's Dataset dropdown only shows\nits own segregation labels.", + "operationId": "listCallImportDatasets", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "title": "Response Listcallimportdatasets" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/diarisation-prompt-default": { + "get": { + "tags": [ + "Call Imports" + ], + "summary": "Get Call Import Diarisation Prompt Default", + "description": "Return the canonical LLM diariser prompt.\n\nThe Transcribe / Run Evaluation modals call this on open so they\ncan pre-fill the prompt textarea. Returning the constant from the\nbackend (rather than hard-coding it in the frontend) keeps the\nfallback used by the worker and the placeholder shown in the UI\nin lock-step โ€” operators always see the *actual* default they'd\nget if they leave the field blank.\n\nRegistered before ``GET /{call_import_id}`` so the static path is\nnot mistaken for a UUID import id (which would 422).", + "operationId": "getCallImportDiarisationPromptDefault", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportDiarisationPromptDefaultResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}": { + "get": { + "tags": [ + "Call Imports" + ], + "summary": "Get Call Import Detail", + "description": "Fetch a single import batch with a slice of its rows.\n\n``row_limit=0`` is intentionally allowed so callers that only need the\nbatch metadata (e.g. the evaluation-detail page rendering the parent's\ncolumn mapping) can skip the rows payload entirely.", + "operationId": "getCallImportDetail", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "row_limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 5000, + "minimum": 0, + "default": 500, + "title": "Row Limit" + } + }, + { + "name": "row_offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 0, + "default": 0, + "title": "Row Offset" + } + }, + { + "name": "q", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Optional case-insensitive substring filter on ``conversation_id``. When set, ``filtered_total_rows`` in the response reflects the post-filter row count so the UI can paginate against the filtered slice.", + "title": "Q" + }, + "description": "Optional case-insensitive substring filter on ``conversation_id``. When set, ``filtered_total_rows`` in the response reflects the post-filter row count so the UI can paginate against the filtered slice." + }, + { + "name": "diarised_status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "pattern": "^(pending|running|completed|failed)$" + }, + { + "type": "null" + } + ], + "description": "Optional filter on ``CallImportRow.diarised_transcript_status``. Accepts one of ``pending``, ``running``, ``completed``, ``failed``. When set, ``filtered_total_rows`` reflects the post-filter row count (combined with the ``q`` filter when both are supplied) so the UI can paginate against the same slice it's displaying.", + "title": "Diarised Status" + }, + "description": "Optional filter on ``CallImportRow.diarised_transcript_status``. Accepts one of ``pending``, ``running``, ``completed``, ``failed``. When set, ``filtered_total_rows`` reflects the post-filter row count (combined with the ``q`` filter when both are supplied) so the UI can paginate against the same slice it's displaying." + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportDetailResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Call Imports" + ], + "summary": "Update Call Import", + "description": "Edit dataset / tag assignments (and schema, pre-import) on a batch.\n\n``dataset = \"\"`` clears the label; ``tag_ids = []`` removes all tag\nassignments. Fields omitted from the body are left untouched.\n\n``schema_id`` is only honoured while the batch is in\n``uploaded`` / ``mapped`` state โ€” once rows have been materialised\nthe schema is locked. Changing the schema resets any persisted\nmapping (the user must re-MAP) and rewinds status to ``uploaded``.", + "operationId": "updateCallImport", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Call Imports" + ], + "summary": "Delete Call Import", + "description": "Delete a call-import batch asynchronously.\n\nFlips the batch to ``deleting`` and enqueues background teardown so\nlarge imports (thousands of rows + S3 objects) do not block the API.", + "operationId": "deleteCallImport", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "202": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportDeleteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/row-ids": { + "get": { + "tags": [ + "Call Imports" + ], + "summary": "List Call Import Row Ids", + "description": "Return every matching ``CallImportRow.id`` for cross-page bulk select.\n\nLightweight companion to ``GET /{call_import_id}`` โ€” the detail\nendpoint caps ``row_limit`` at 5000 and ships the entire row body\non each page, so harvesting ids that way is wasteful when the\nuser just wants to bulk-delete or bulk-transcribe everything that\nmatches the current filters. This endpoint applies the same ``q``\nand ``diarised_status`` filters and returns only the ids.", + "operationId": "listCallImportRowIds", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "q", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Optional case-insensitive substring filter on ``conversation_id``. Same semantics as the detail endpoint.", + "title": "Q" + }, + "description": "Optional case-insensitive substring filter on ``conversation_id``. Same semantics as the detail endpoint." + }, + { + "name": "diarised_status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "pattern": "^(pending|running|completed|failed)$" + }, + { + "type": "null" + } + ], + "description": "Optional filter on ``CallImportRow.diarised_transcript_status``. Accepts ``pending`` / ``running`` / ``completed`` / ``failed``.", + "title": "Diarised Status" + }, + "description": "Optional filter on ``CallImportRow.diarised_transcript_status``. Accepts ``pending`` / ``running`` / ``completed`` / ``failed``." + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportRowIdsResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/rows/{row_id}": { + "delete": { + "tags": [ + "Call Imports" + ], + "summary": "Delete Call Import Row", + "description": "Delete a single CallImportRow and its S3 recording.\n\nThe parent ``CallImport`` is left in place. After deletion we recompute\nits ``total_rows`` / ``completed_rows`` / ``failed_rows`` / ``status``\nso the UI's progress bar stays consistent with reality.", + "operationId": "deleteCallImportRow", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "row_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Row Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/retry-failed": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Retry Failed Call Import Rows", + "description": "Re-enqueue every failed import row in this batch.\n\nUseful when transient provider issues are resolved and the operator wants\na one-click \"try failed downloads again\" pass without re-uploading the CSV.\n\nPass ``provider`` + ``telephony_integration_id`` (or both omitted for\ndirect-URL retry) to change how recordings are fetched on this pass.\nWhen the body is omitted entirely, the batch keeps its existing pinned\ncredentials.", + "operationId": "retryFailedCallImportRows", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/CallImportRetryFailedRowsRequest" + }, + { + "type": "null" + } + ], + "title": "Payload" + } + } + } + }, + "responses": { + "202": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportRetryFailedRowsResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/rows/bulk-delete": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Bulk Delete Call Import Rows", + "description": "Delete multiple ``CallImportRow`` rows in one request.\n\nUnknown / cross-tenant row ids are silently skipped โ€” the response\nreports how many actually went away so a UI that holds onto stale\nids (e.g. after another tab already deleted a row) doesn't 404\nthe entire bulk action.", + "operationId": "bulkDeleteCallImportRows", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportRowBulkDelete" + } + } + } + }, + "responses": { + "202": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportRowBulkDeleteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/transcribe": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Transcribe Call Import", + "description": "Fan out diarization tasks for many rows in a single call.\n\nReturns a summary with how many rows were queued and how many were\nskipped (broken down by reason) so the UI can show a meaningful\ntoast even when nothing actually got enqueued (e.g. \"All 12 rows\nalready have transcripts\").", + "operationId": "transcribeCallImport", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportTranscribeRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportTranscribeResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/rows/{row_id}/transcribe": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Transcribe Call Import Row", + "description": "Diarize / transcribe a single row.\n\nThin wrapper over the batch endpoint that hard-codes a single\n``row_ids`` filter. Skip counts still surface so the UI can render\n\"Skipped โ€” transcript present\" diagnostics consistently.", + "operationId": "transcribeCallImportRow", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "row_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Row Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportTranscribeRequest" + } + } + } + }, + "responses": { + "202": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportTranscribeResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/rows/{row_id}/cancel-diarisation": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Cancel Call Import Row Diarisation", + "description": "Abort an in-flight (or queued) diarisation for a single row.\n\nIdempotent: calling on a row that's already terminal (``completed``\n/ ``failed`` / ``idle``) returns the row unchanged with a 200, so\nthe UI can fire this from a \"Stop\" button without having to\npre-check the state.\n\nRace notes:\n\n* The row's ``diarised_transcript_status`` is flipped to ``failed``\n with :data:`CANCELLED_BY_USER_ERROR` BEFORE the Celery revoke,\n so the polling UI sees the cancel immediately.\n* If the worker happens to finish between our DB flip and the\n SIGTERM landing, its finaliser will detect the cancelled\n sentinel on the row and skip its own status / score writes\n (see :mod:`app.workers.tasks.transcribe_call_import_row`).", + "operationId": "cancelCallImportRowDiarisation", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "row_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Row Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportRowResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/cancel-diarisation": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Cancel Call Import Diarisation", + "description": "Abort in-flight diarisation for many rows in a single call.\n\nDefault body (no ``row_ids``) cancels every row in this import\nwhose ``diarised_transcript_status`` is ``pending`` or\n``running`` โ€” the \"stop everything\" button. Pass ``row_ids`` to\nscope the cancel to the rows the operator has selected.\n\nReturns ``(cancelled, skipped)`` so the UI can render a tight\ntoast (\"Cancelled 3 rows ยท 1 skipped (already completed)\").", + "operationId": "cancelCallImportDiarisation", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/CallImportCancelDiarisationRequest" + }, + { + "type": "null" + } + ], + "title": "Payload" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportCancelDiarisationResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/rows/{row_id}/diarised-speaker-swap": { + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Toggle Call Import Row Speaker Swap", + "description": "Flip the user <-> agent mapping on a diarised row.\n\nThe worker's \"first speaker is the agent\" heuristic is right most of\nthe time but does fail on inbound recordings where the customer\ngreets first, on recordings where the agent stays silent for the\nintro, etc. Rather than rerun the (expensive) STT + pyannote\npipeline for those cases, we let reviewers flip the mapping in\nplace: the structured ``diarised_segments`` are the source of truth\nand we re-render the plain-text ``diarised_transcript`` from them\nwith the swap applied. The next CSV export will then show the\ncorrected labels.\n\nReturns the updated row so the frontend can refresh without an\nextra round-trip.", + "operationId": "toggleCallImportRowSpeakerSwap", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "row_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Row Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportRowResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-imports/{call_import_id}/insights": { + "get": { + "tags": [ + "Call Imports" + ], + "summary": "Get Call Import Insights", + "description": "Aggregate signals across every evaluation run on this import.\n\nPowers the Insights tab on the call-import detail page: returns\nper-metric \"latest run\" summaries plus a trend series of mean values\nacross runs so the UI can render a small line chart per metric. Also\nbundles transcript coverage stats since those are the cheapest\npre-eval health-check (e.g. \"30 of 50 rows still missing\ntranscripts\").", + "operationId": "getCallImportInsights", + "parameters": [ + { + "name": "call_import_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportInsightsResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-import-schemas": { + "get": { + "tags": [ + "Call Imports" + ], + "summary": "List Call Import Schemas", + "description": "List schemas in the active workspace (alphabetical by name).\n\nEach entry includes ``usage_count`` so the UI can warn the user\nbefore deleting a schema that batches are still pinned to.", + "operationId": "listCallImportSchemas", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportSchemaListResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Create Call Import Schema", + "description": "Create a new schema + parameters in the active workspace.\n\nPydantic validates the cross-parameter invariants (single\n``conversation_id``, unique names) before the body reaches this\nhandler; we still rely on the DB-level unique index to catch the\nname-collision race.", + "operationId": "createCallImportSchema", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportSchemaCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportSchemaResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-import-schemas/{schema_id}": { + "get": { + "tags": [ + "Call Imports" + ], + "summary": "Get Call Import Schema", + "description": "Fetch a single schema with its parameters + usage count.", + "operationId": "getCallImportSchema", + "parameters": [ + { + "name": "schema_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Schema Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportSchemaResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Call Imports" + ], + "summary": "Update Call Import Schema", + "description": "Update a schema's metadata and/or replace its parameter list.\n\nWhen ``parameters`` is included in the body, the new list FULLY\nREPLACES the existing parameters (delete-then-insert in one\ntransaction). Existing CallImport batches that reference this\nschema keep their snapshotted ``parameter_mapping`` unchanged - we\ndon't try to retro-validate historical mappings against the new\nschema shape.", + "operationId": "updateCallImportSchema", + "parameters": [ + { + "name": "schema_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Schema Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportSchemaUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportSchemaResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Call Imports" + ], + "summary": "Delete Call Import Schema", + "description": "Delete a schema.\n\nBy default refuses with 409 when any ``CallImport`` row still\nreferences the schema (matches the ``ON DELETE RESTRICT`` FK\nbehavior); the user must either delete the dependent batches\nfirst, migrate them to a different schema, or retry with\n``?force=true`` to detach them in one shot.\n\n``force=true`` is safe for completed batches: every batch keeps\nits own ``parameter_mapping`` snapshot, and downstream rendering\n(detail page, evaluation export) already handles a NULL\n``schema_id`` gracefully. Batches still in the staged ``uploaded``\nstate will need a fresh schema before they can be imported - the\nexisting import endpoint already enforces that.", + "operationId": "deleteCallImportSchema", + "parameters": [ + { + "name": "schema_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Schema Id" + } + }, + { + "name": "force", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "description": "When true, detach this schema from any CallImport batches that reference it (sets ``call_imports.schema_id = NULL``) before deleting the schema row. Use this to drop a schema whose batches you want to keep โ€” already-imported batches keep working via their snapshotted ``parameter_mapping``, while staged-but-not-yet-imported batches will need a new schema picked before they can be imported.", + "default": false, + "title": "Force" + }, + "description": "When true, detach this schema from any CallImport batches that reference it (sets ``call_imports.schema_id = NULL``) before deleting the schema row. Use this to drop a schema whose batches you want to keep โ€” already-imported batches keep working via their snapshotted ``parameter_mapping``, while staged-but-not-yet-imported batches will need a new schema picked before they can be imported." + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Workspace-Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-import-tags": { + "get": { + "tags": [ + "Call Imports" + ], + "summary": "List Call Import Tags", + "description": "List every tag defined for this organization (alphabetical by name).", + "operationId": "listCallImportTags", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CallImportTagResponse" + }, + "title": "Response Listcallimporttags" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "Call Imports" + ], + "summary": "Create Call Import Tag", + "description": "Create a new tag scoped to this organization.", + "operationId": "createCallImportTag", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportTagCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportTagResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/call-import-tags/{tag_id}": { + "patch": { + "tags": [ + "Call Imports" + ], + "summary": "Update Call Import Tag", + "description": "Rename or recolor an existing tag.", + "operationId": "updateCallImportTag", + "parameters": [ + { + "name": "tag_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Tag Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportTagUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CallImportTagResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Call Imports" + ], + "summary": "Delete Call Import Tag", + "description": "Delete a tag. Existing tag assignments are removed by ON DELETE CASCADE.", + "operationId": "deleteCallImportTag", + "parameters": [ + { + "name": "tag_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Tag Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/workspaces": { + "get": { + "tags": [ + "Workspaces" + ], + "summary": "List Workspaces", + "description": "List workspaces the caller can access.", + "operationId": "list_workspaces_api_v1_workspaces_get", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WorkspaceResponse" + }, + "title": "Response List Workspaces Api V1 Workspaces Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "Workspaces" + ], + "summary": "Create Workspace", + "description": "Create a new (non-default) workspace; creator becomes Workspace Admin.", + "operationId": "create_workspace_api_v1_workspaces_post", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkspaceCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkspaceResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/workspaces/{workspace_id}": { + "patch": { + "tags": [ + "Workspaces" + ], + "summary": "Update Workspace", + "description": "Rename a workspace or change active status (org admin only for the latter).", + "operationId": "update_workspace_api_v1_workspaces__workspace_id__patch", + "parameters": [ + { + "name": "workspace_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Workspace Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkspaceUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkspaceResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Workspaces" + ], + "summary": "Delete Workspace", + "description": "Delete a non-default workspace (org admin only).", + "operationId": "delete_workspace_api_v1_workspaces__workspace_id__delete", + "parameters": [ + { + "name": "workspace_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Workspace Id" + } + }, + { + "name": "Authorization", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Authorization" + } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + }, + { + "name": "X-EFFICIENTAI-API-KEY", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Efficientai-Api-Key" + } + }, + { + "$ref": "#/components/parameters/WorkspaceIdHeader" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AuthConfigResponse": { + "properties": { + "providers": { + "items": { + "$ref": "#/components/schemas/AuthProviderConfig" + }, + "type": "array", + "title": "Providers" + }, + "tier": { + "type": "string", + "title": "Tier" + }, + "gated_signup": { + "type": "boolean", + "title": "Gated Signup", + "default": false + } + }, + "type": "object", + "required": [ + "providers", + "tier" + ], + "title": "AuthConfigResponse" + }, + "InvitationPreviewResponse": { + "properties": { + "organization_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Organization Name" + }, + "email": { + "type": "string", + "title": "Email" + }, + "role": { + "type": "string", + "title": "Role" + }, + "expires_at": { + "type": "string", + "format": "date-time", + "title": "Expires At" + }, + "status": { + "type": "string", + "title": "Status" + }, + "user_exists": { + "type": "boolean", + "title": "User Exists", + "default": false + }, + "has_password": { + "type": "boolean", + "title": "Has Password", + "default": false + } + }, + "type": "object", + "required": [ + "email", + "role", + "expires_at", + "status" + ], + "title": "InvitationPreviewResponse" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "AcceptInviteByTokenRequest": { + "properties": { + "token": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Token" + } + }, + "type": "object", + "required": [ + "token" + ], + "title": "AcceptInviteByTokenRequest" + }, + "TokenResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "refresh_token": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Refresh Token" + }, + "token_type": { + "type": "string", + "title": "Token Type", + "default": "Bearer" + }, + "expires_in": { + "type": "integer", + "title": "Expires In" + }, + "user": { + "$ref": "#/components/schemas/UserSummary" + } + }, + "type": "object", + "required": [ + "access_token", + "expires_in", + "user" + ], + "title": "TokenResponse" + }, + "SignupRequest": { + "properties": { + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "password": { + "type": "string", + "maxLength": 32, + "minLength": 8, + "title": "Password" + }, + "organization_name": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Organization Name" + }, + "first_name": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "First Name" + }, + "last_name": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Last Name" + }, + "reference_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 64 + }, + { + "type": "null" + } + ], + "title": "Reference Code" + }, + "invite_token": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Invite Token" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "SignupRequest" + }, + "LoginRequest": { + "properties": { + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "organization_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Organization Id" + }, + "invite_token": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Invite Token" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "LoginRequest" + }, + "LoginOrgSelectionResponse": { + "properties": { + "requires_org_selection": { + "type": "boolean", + "title": "Requires Org Selection", + "default": true + }, + "organizations": { + "items": { + "$ref": "#/components/schemas/LoginOrgOption" + }, + "type": "array", + "title": "Organizations" + } + }, + "type": "object", + "required": [ + "organizations" + ], + "title": "LoginOrgSelectionResponse" + }, + "UserSummary": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "first_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "First Name" + }, + "last_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Name" + }, + "organization_id": { + "type": "string", + "title": "Organization Id" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "has_password": { + "type": "boolean", + "title": "Has Password", + "default": false + }, + "email_is_placeholder": { + "type": "boolean", + "title": "Email Is Placeholder", + "default": false + } + }, + "type": "object", + "required": [ + "id", + "email", + "organization_id" + ], + "title": "UserSummary" + }, + "LogoutRequest": { + "properties": { + "refresh_token": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Refresh Token" + } + }, + "type": "object", + "title": "LogoutRequest" + }, + "RefreshRequest": { + "properties": { + "refresh_token": { + "type": "string", + "title": "Refresh Token" + } + }, + "type": "object", + "required": [ + "refresh_token" + ], + "title": "RefreshRequest" + }, + "SwitchOrgRequest": { + "properties": { + "organization_id": { + "type": "string", + "title": "Organization Id" + }, + "refresh_token": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Refresh Token" + } + }, + "type": "object", + "required": [ + "organization_id" + ], + "title": "SwitchOrgRequest" + }, + "SetPasswordRequest": { + "properties": { + "new_password": { + "type": "string", + "maxLength": 32, + "minLength": 8, + "title": "New Password" + }, + "current_password": { + "anyOf": [ + { + "type": "string", + "maxLength": 32 + }, + { + "type": "null" + } + ], + "title": "Current Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + } + }, + "type": "object", + "required": [ + "new_password" + ], + "title": "SetPasswordRequest" + }, + "APIKeyCreate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + } + }, + "type": "object", + "title": "APIKeyCreate" + }, + "APIKeyResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "key": { + "type": "string", + "title": "Key" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "key", + "is_active" + ], + "title": "APIKeyResponse" + }, + "GenerateAgentDescriptionRequest": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "tone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tone", + "default": "professional" + }, + "format_style": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Format Style", + "default": "structured" + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + }, + "model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model" + }, + "agent_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + }, + "include_linked_scenarios": { + "type": "boolean", + "title": "Include Linked Scenarios", + "default": true + }, + "append_scenarios_to_output": { + "type": "boolean", + "title": "Append Scenarios To Output", + "default": false + } + }, + "type": "object", + "required": [ + "description" + ], + "title": "GenerateAgentDescriptionRequest" + }, + "GenerateTestPromptRequest": { + "properties": { + "production_prompt": { + "type": "string", + "minLength": 1, + "title": "Production Prompt" + }, + "agent_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Agent Name" + }, + "language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Language" + }, + "call_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Call Type" + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + }, + "model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model" + }, + "credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Credential Id" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "additional_context": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Additional Context" + } + }, + "type": "object", + "required": [ + "production_prompt", + "agent_name" + ], + "title": "GenerateTestPromptRequest", + "description": "Stage 1: generate foundational test agent prompt from production prompt." + }, + "GenerateTestPromptResponse": { + "properties": { + "sections": { + "items": { + "$ref": "#/components/schemas/TestPromptSectionResponse" + }, + "type": "array", + "title": "Sections" + }, + "test_agent_prompt": { + "type": "string", + "title": "Test Agent Prompt" + }, + "first_message": { + "$ref": "#/components/schemas/TestAgentFirstMessageResponse" + }, + "test_agent_template": { + "$ref": "#/components/schemas/TestAgentTemplateResponse" + }, + "provider": { + "type": "string", + "title": "Provider" + }, + "model": { + "type": "string", + "title": "Model" + } + }, + "type": "object", + "required": [ + "sections", + "test_agent_prompt", + "first_message", + "test_agent_template", + "provider", + "model" + ], + "title": "GenerateTestPromptResponse" + }, + "GenerateScenariosFromPromptRequest": { + "properties": { + "test_agent_prompt": { + "type": "string", + "minLength": 1, + "title": "Test Agent Prompt" + }, + "agent_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Agent Name" + }, + "scenario_count": { + "type": "integer", + "maximum": 10, + "minimum": 1, + "title": "Scenario Count", + "default": 5 + }, + "language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Language" + }, + "call_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Call Type" + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + }, + "model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model" + }, + "credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Credential Id" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "additional_context": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Additional Context" + } + }, + "type": "object", + "required": [ + "test_agent_prompt", + "agent_name" + ], + "title": "GenerateScenariosFromPromptRequest", + "description": "Stage 2: generate scenario drafts from test agent prompt." + }, + "GenerateScenariosFromPromptResponse": { + "properties": { + "scenarios": { + "items": { + "$ref": "#/components/schemas/GeneratedScenarioDraftResponse" + }, + "type": "array", + "title": "Scenarios" + }, + "provider": { + "type": "string", + "title": "Provider" + }, + "model": { + "type": "string", + "title": "Model" + } + }, + "type": "object", + "required": [ + "scenarios", + "provider", + "model" + ], + "title": "GenerateScenariosFromPromptResponse" + }, + "GenerateTestSetupRequest": { + "properties": { + "production_prompt": { + "type": "string", + "minLength": 1, + "title": "Production Prompt" + }, + "agent_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Agent Name" + }, + "scenario_count": { + "type": "integer", + "maximum": 10, + "minimum": 1, + "title": "Scenario Count", + "default": 5 + }, + "language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Language" + }, + "call_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Call Type" + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + }, + "model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model" + }, + "credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Credential Id" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "additional_context": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Additional Context" + } + }, + "type": "object", + "required": [ + "production_prompt", + "agent_name" + ], + "title": "GenerateTestSetupRequest", + "description": "Convenience: run stage 1 then stage 2 sequentially." + }, + "GenerateTestSetupResponse": { + "properties": { + "sections": { + "items": { + "$ref": "#/components/schemas/TestPromptSectionResponse" + }, + "type": "array", + "title": "Sections" + }, + "test_agent_prompt": { + "type": "string", + "title": "Test Agent Prompt" + }, + "first_message": { + "$ref": "#/components/schemas/TestAgentFirstMessageResponse" + }, + "test_agent_template": { + "$ref": "#/components/schemas/TestAgentTemplateResponse" + }, + "scenarios": { + "items": { + "$ref": "#/components/schemas/GeneratedScenarioDraftResponse" + }, + "type": "array", + "title": "Scenarios" + }, + "provider": { + "type": "string", + "title": "Provider" + }, + "model": { + "type": "string", + "title": "Model" + } + }, + "type": "object", + "required": [ + "sections", + "test_agent_prompt", + "first_message", + "test_agent_template", + "scenarios", + "provider", + "model" + ], + "title": "GenerateTestSetupResponse" + }, + "AgentResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "agent_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "phone_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Phone Number" + }, + "language": { + "$ref": "#/components/schemas/LanguageEnum" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "call_type": { + "$ref": "#/components/schemas/CallTypeEnum" + }, + "call_medium": { + "$ref": "#/components/schemas/CallMediumEnum" + }, + "telephony_phone_number_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Telephony Phone Number Id" + }, + "voice_bundle_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Voice Bundle Id" + }, + "ai_provider_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Ai Provider Id" + }, + "voice_ai_integration_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Voice Ai Integration Id" + }, + "voice_ai_agent_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Voice Ai Agent Id" + }, + "provider_prompt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider Prompt" + }, + "test_agent_template": { + "anyOf": [ + { + "$ref": "#/components/schemas/TestAgentTemplateResponse" + }, + { + "type": "null" + } + ] + }, + "prompt_variables": { + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Prompt Variables" + }, + "silence_hangup_secs": { + "type": "integer", + "maximum": 600, + "minimum": 0, + "title": "Silence Hangup Secs", + "description": "End live calls after this many seconds of silence (0 disables)", + "default": 15 + }, + "provider_prompt_synced_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Provider Prompt Synced At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "language", + "description", + "call_type", + "call_medium", + "voice_bundle_id", + "ai_provider_id", + "voice_ai_integration_id", + "voice_ai_agent_id", + "created_at", + "updated_at" + ], + "title": "AgentResponse", + "description": "Schema for agent response" + }, + "AgentCreate": { + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Name" + }, + "phone_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Phone Number" + }, + "language": { + "$ref": "#/components/schemas/LanguageEnum", + "default": "en" + }, + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "call_type": { + "$ref": "#/components/schemas/CallTypeEnum", + "default": "outbound" + }, + "call_medium": { + "$ref": "#/components/schemas/CallMediumEnum", + "default": "phone_call" + }, + "telephony_phone_number_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Telephony Phone Number Id" + }, + "voice_bundle_id": { + "type": "string", + "format": "uuid", + "title": "Voice Bundle Id", + "description": "Required voice bundle for test agent execution" + }, + "ai_provider_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Ai Provider Id" + }, + "voice_ai_integration_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Voice Ai Integration Id" + }, + "voice_ai_agent_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Voice Ai Agent Id" + }, + "provider_prompt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider Prompt" + }, + "test_agent_template": { + "anyOf": [ + { + "$ref": "#/components/schemas/TestAgentTemplateInput" + }, + { + "type": "null" + } + ] + }, + "silence_hangup_secs": { + "type": "integer", + "maximum": 600, + "minimum": 0, + "title": "Silence Hangup Secs", + "description": "End live calls after this many seconds of silence (0 disables)", + "default": 15 + } + }, + "type": "object", + "required": [ + "name", + "description", + "voice_bundle_id" + ], + "title": "AgentCreate", + "description": "Schema for creating a new agent", + "example": { + "call_type": "outbound", + "description": "A customer support bot that handles inquiries about orders, returns, and general questions", + "language": "en", + "name": "Customer Support Bot", + "phone_number": "+1234567890", + "voice_ai_agent_id": "agent_abc123", + "voice_ai_integration_id": "123e4567-e89b-12d3-a456-426614174001", + "voice_bundle_id": "123e4567-e89b-12d3-a456-426614174000" + } + }, + "AgentPhoneAssignmentCheckResponse": { + "properties": { + "available": { + "type": "boolean", + "title": "Available" + }, + "phone_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Phone Number" + }, + "conflict": { + "anyOf": [ + { + "$ref": "#/components/schemas/AgentPhoneAssignmentConflict" + }, + { + "type": "null" + } + ] + } + }, + "type": "object", + "required": [ + "available" + ], + "title": "AgentPhoneAssignmentCheckResponse", + "description": "Result of checking whether a phone number is free to assign." + }, + "AgentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "phone_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Phone Number" + }, + "language": { + "anyOf": [ + { + "$ref": "#/components/schemas/LanguageEnum" + }, + { + "type": "null" + } + ] + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "call_type": { + "anyOf": [ + { + "$ref": "#/components/schemas/CallTypeEnum" + }, + { + "type": "null" + } + ] + }, + "call_medium": { + "anyOf": [ + { + "$ref": "#/components/schemas/CallMediumEnum" + }, + { + "type": "null" + } + ] + }, + "telephony_phone_number_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Telephony Phone Number Id" + }, + "voice_bundle_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Voice Bundle Id" + }, + "voice_ai_integration_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Voice Ai Integration Id" + }, + "voice_ai_agent_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Voice Ai Agent Id" + }, + "provider_prompt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider Prompt" + }, + "test_agent_template": { + "anyOf": [ + { + "$ref": "#/components/schemas/TestAgentTemplateInput" + }, + { + "type": "null" + } + ] + }, + "prompt_variables": { + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Prompt Variables" + }, + "silence_hangup_secs": { + "anyOf": [ + { + "type": "integer", + "maximum": 600, + "minimum": 0 + }, + { + "type": "null" + } + ], + "title": "Silence Hangup Secs" + } + }, + "type": "object", + "title": "AgentUpdate", + "description": "Schema for updating an agent" + }, + "PersonaResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "gender": { + "type": "string", + "title": "Gender" + }, + "tts_provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Provider" + }, + "tts_voice_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Voice Id" + }, + "tts_voice_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Voice Name" + }, + "is_custom": { + "type": "boolean", + "title": "Is Custom", + "default": false + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "tts_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Tts Config" + }, + "llm_temperature": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Llm Temperature" + }, + "llm_max_tokens": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Llm Max Tokens" + }, + "response_delay_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Response Delay Ms" + }, + "max_turns": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Max Turns" + }, + "allow_interruptions": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Allow Interruptions" + }, + "background_noise_source": { + "type": "string", + "title": "Background Noise Source", + "default": "none" + }, + "background_noise_preset": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Background Noise Preset" + }, + "background_noise_volume": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Background Noise Volume" + }, + "background_noise_s3_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Background Noise S3 Key" + }, + "background_noise_asset_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Background Noise Asset Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "gender", + "created_at", + "updated_at" + ], + "title": "PersonaResponse", + "description": "Schema for persona response" + }, + "PersonaCreate": { + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Name" + }, + "gender": { + "$ref": "#/components/schemas/GenderEnum", + "default": "neutral" + }, + "tts_provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Provider" + }, + "tts_voice_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Voice Id" + }, + "tts_voice_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Voice Name" + }, + "is_custom": { + "type": "boolean", + "title": "Is Custom", + "default": false + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "tts_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Tts Config" + }, + "llm_temperature": { + "anyOf": [ + { + "type": "number", + "maximum": 2, + "minimum": 0 + }, + { + "type": "null" + } + ], + "title": "Llm Temperature" + }, + "llm_max_tokens": { + "anyOf": [ + { + "type": "integer", + "maximum": 8192, + "exclusiveMinimum": 0 + }, + { + "type": "null" + } + ], + "title": "Llm Max Tokens" + }, + "response_delay_ms": { + "anyOf": [ + { + "type": "integer", + "maximum": 10000, + "minimum": 0 + }, + { + "type": "null" + } + ], + "title": "Response Delay Ms" + }, + "max_turns": { + "anyOf": [ + { + "type": "integer", + "maximum": 100, + "minimum": 1 + }, + { + "type": "null" + } + ], + "title": "Max Turns" + }, + "allow_interruptions": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Allow Interruptions" + }, + "background_noise_source": { + "$ref": "#/components/schemas/BackgroundNoiseSourceEnum", + "default": "none" + }, + "background_noise_preset": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Background Noise Preset" + }, + "background_noise_volume": { + "anyOf": [ + { + "type": "number", + "maximum": 0.6, + "minimum": 0.05 + }, + { + "type": "null" + } + ], + "title": "Background Noise Volume" + }, + "background_noise_asset_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Background Noise Asset Id" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "PersonaCreate", + "description": "Schema for creating a new persona (TTS provider-tied voice identity)" + }, + "AgentPromptSourcesResponse": { + "properties": { + "agent_id": { + "type": "string", + "format": "uuid", + "title": "Agent Id" + }, + "agent_name": { + "type": "string", + "title": "Agent Name" + }, + "test_agent_prompt": { + "type": "string", + "title": "Test Agent Prompt" + }, + "agent_prompt": { + "type": "string", + "title": "Agent Prompt" + } + }, + "type": "object", + "required": [ + "agent_id", + "agent_name", + "test_agent_prompt", + "agent_prompt" + ], + "title": "AgentPromptSourcesResponse", + "description": "Prompt texts from an agent that can seed a persona description." + }, + "GeneratePersonaPromptRequest": { + "properties": { + "agent_id": { + "type": "string", + "format": "uuid", + "title": "Agent Id" + }, + "source": { + "type": "string", + "pattern": "^(test_agent|agent|auto)$", + "title": "Source", + "default": "auto" + }, + "persona_name": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Persona Name" + }, + "persona_gender": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Persona Gender" + }, + "additional_context": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Additional Context" + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + }, + "model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model" + }, + "credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Credential Id" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + } + }, + "type": "object", + "required": [ + "agent_id" + ], + "title": "GeneratePersonaPromptRequest", + "description": "Generate a persona caller prompt from an agent prompt via LLM." + }, + "GeneratePersonaPromptResponse": { + "properties": { + "persona_prompt": { + "type": "string", + "title": "Persona Prompt" + }, + "source_used": { + "type": "string", + "title": "Source Used" + }, + "provider": { + "type": "string", + "title": "Provider" + }, + "model": { + "type": "string", + "title": "Model" + } + }, + "type": "object", + "required": [ + "persona_prompt", + "source_used", + "provider", + "model" + ], + "title": "GeneratePersonaPromptResponse" + }, + "CustomVoiceCreateRequest": { + "properties": { + "provider": { + "type": "string", + "title": "Provider" + }, + "voice_id": { + "type": "string", + "title": "Voice Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "gender": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Gender" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + } + }, + "type": "object", + "required": [ + "provider", + "voice_id", + "name" + ], + "title": "CustomVoiceCreateRequest" + }, + "CustomVoiceUpdateRequest": { + "properties": { + "voice_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Voice Id" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "gender": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Gender" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + } + }, + "type": "object", + "title": "CustomVoiceUpdateRequest" + }, + "AmbientNoiseAssetResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "s3_key": { + "type": "string", + "title": "S3 Key" + }, + "original_filename": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Original Filename" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "s3_key", + "created_at", + "updated_at" + ], + "title": "AmbientNoiseAssetResponse" + }, + "Body_uploadAmbientLibraryAsset": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_uploadAmbientLibraryAsset" + }, + "AmbientNoiseAssetUpdateRequest": { + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Name" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "AmbientNoiseAssetUpdateRequest" + }, + "AmbientLibraryPreviewUrlResponse": { + "properties": { + "url": { + "type": "string", + "title": "Url" + }, + "expires_in": { + "type": "integer", + "title": "Expires In" + } + }, + "type": "object", + "required": [ + "url", + "expires_in" + ], + "title": "AmbientLibraryPreviewUrlResponse" + }, + "PersonaUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "gender": { + "anyOf": [ + { + "$ref": "#/components/schemas/GenderEnum" + }, + { + "type": "null" + } + ] + }, + "tts_provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Provider" + }, + "tts_voice_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Voice Id" + }, + "tts_voice_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Voice Name" + }, + "is_custom": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Custom" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "tts_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Tts Config" + }, + "llm_temperature": { + "anyOf": [ + { + "type": "number", + "maximum": 2, + "minimum": 0 + }, + { + "type": "null" + } + ], + "title": "Llm Temperature" + }, + "llm_max_tokens": { + "anyOf": [ + { + "type": "integer", + "maximum": 8192, + "exclusiveMinimum": 0 + }, + { + "type": "null" + } + ], + "title": "Llm Max Tokens" + }, + "response_delay_ms": { + "anyOf": [ + { + "type": "integer", + "maximum": 10000, + "minimum": 0 + }, + { + "type": "null" + } + ], + "title": "Response Delay Ms" + }, + "max_turns": { + "anyOf": [ + { + "type": "integer", + "maximum": 100, + "minimum": 1 + }, + { + "type": "null" + } + ], + "title": "Max Turns" + }, + "allow_interruptions": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Allow Interruptions" + }, + "background_noise_source": { + "anyOf": [ + { + "$ref": "#/components/schemas/BackgroundNoiseSourceEnum" + }, + { + "type": "null" + } + ] + }, + "background_noise_preset": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Background Noise Preset" + }, + "background_noise_volume": { + "anyOf": [ + { + "type": "number", + "maximum": 0.6, + "minimum": 0.05 + }, + { + "type": "null" + } + ], + "title": "Background Noise Volume" + }, + "background_noise_asset_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Background Noise Asset Id" + } + }, + "type": "object", + "title": "PersonaUpdate", + "description": "Schema for updating a persona" + }, + "PersonaCloneRequest": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + } + }, + "type": "object", + "title": "PersonaCloneRequest", + "description": "Schema for cloning a persona" + }, + "Body_uploadPersonaAmbientAudio": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_uploadPersonaAmbientAudio" + }, + "ScenarioResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "agent_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "required_info": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Required Info" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "agent_id", + "description", + "required_info", + "created_at", + "updated_at" + ], + "title": "ScenarioResponse", + "description": "Schema for scenario response" + }, + "ScenarioCreate": { + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Name" + }, + "agent_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "required_info": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Required Info" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ScenarioCreate", + "description": "Schema for creating a new scenario" + }, + "ScenarioUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "agent_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "required_info": { + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Required Info" + } + }, + "type": "object", + "title": "ScenarioUpdate", + "description": "Schema for updating a scenario" + }, + "IntegrationResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "organization_id": { + "type": "string", + "format": "uuid", + "title": "Organization Id" + }, + "platform": { + "$ref": "#/components/schemas/IntegrationPlatform" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "public_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Key" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "is_default": { + "type": "boolean", + "title": "Is Default", + "default": false + }, + "routing_mode": { + "$ref": "#/components/schemas/CredentialRoutingMode", + "default": "inherit" + }, + "effective_routing": { + "type": "string", + "enum": [ + "inherit", + "direct", + "gateway", + "bifrost", + "litellm_proxy" + ], + "title": "Effective Routing", + "default": "inherit" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + }, + "last_tested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Tested At" + } + }, + "type": "object", + "required": [ + "id", + "organization_id", + "platform", + "name", + "is_active", + "created_at", + "updated_at" + ], + "title": "IntegrationResponse", + "description": "Schema for integration response." + }, + "IntegrationCreate": { + "properties": { + "platform": { + "$ref": "#/components/schemas/IntegrationPlatform" + }, + "api_key": { + "type": "string", + "title": "Api Key", + "description": "Private API key for the platform" + }, + "public_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Key", + "description": "Optional public API key (e.g. for Vapi)" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name", + "description": "Optional friendly name for the integration" + }, + "routing_mode": { + "$ref": "#/components/schemas/CredentialRoutingMode", + "description": "LLM routing preference: inherit org default, force gateway, or direct API key.", + "default": "inherit" + }, + "is_default": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Default", + "description": "Mark this credential as the default for the (org, platform). If omitted and no default exists yet, this row becomes the default." + } + }, + "type": "object", + "required": [ + "platform", + "api_key" + ], + "title": "IntegrationCreate", + "description": "Schema for creating an integration." + }, + "IntegrationUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "api_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Api Key" + }, + "public_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Key" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "routing_mode": { + "anyOf": [ + { + "$ref": "#/components/schemas/CredentialRoutingMode" + }, + { + "type": "null" + } + ] + } + }, + "type": "object", + "title": "IntegrationUpdate", + "description": "Schema for updating an integration." + }, + "PreviewIntegrationAgentPromptRequest": { + "properties": { + "voice_ai_agent_id": { + "type": "string", + "minLength": 1, + "title": "Voice Ai Agent Id" + } + }, + "type": "object", + "required": [ + "voice_ai_agent_id" + ], + "title": "PreviewIntegrationAgentPromptRequest", + "description": "Fetch a provider agent prompt before an EfficientAI agent exists." + }, + "PreviewIntegrationAgentPromptResponse": { + "properties": { + "provider_prompt": { + "type": "string", + "title": "Provider Prompt" + } + }, + "type": "object", + "required": [ + "provider_prompt" + ], + "title": "PreviewIntegrationAgentPromptResponse" + }, + "VoiceBundleResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "bundle_type": { + "$ref": "#/components/schemas/VoiceBundleType" + }, + "stt_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "stt_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Stt Model" + }, + "stt_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Stt Credential Id" + }, + "llm_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "llm_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Llm Model" + }, + "llm_temperature": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Llm Temperature" + }, + "llm_max_tokens": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Llm Max Tokens" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "llm_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Llm Credential Id" + }, + "tts_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "tts_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Model" + }, + "tts_voice": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Voice" + }, + "tts_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Tts Config" + }, + "tts_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Tts Credential Id" + }, + "s2s_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "s2s_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "S2S Model" + }, + "s2s_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "S2S Config" + }, + "s2s_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "S2S Credential Id" + }, + "extra_metadata": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Extra Metadata" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + }, + "created_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Created By" + } + }, + "type": "object", + "required": [ + "id", + "name", + "description", + "bundle_type", + "stt_provider", + "stt_model", + "llm_provider", + "llm_model", + "llm_temperature", + "llm_max_tokens", + "llm_config", + "tts_provider", + "tts_model", + "tts_voice", + "tts_config", + "s2s_provider", + "s2s_model", + "s2s_config", + "extra_metadata", + "is_active", + "created_at", + "updated_at", + "created_by" + ], + "title": "VoiceBundleResponse", + "description": "Schema for VoiceBundle response." + }, + "VoiceBundleCreate": { + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "bundle_type": { + "$ref": "#/components/schemas/VoiceBundleType", + "default": "stt_llm_tts" + }, + "stt_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "stt_model": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Stt Model" + }, + "stt_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Stt Credential Id", + "description": "Optional explicit AIProvider/Integration row id to use for STT. When omitted the resolver picks the default credential for stt_provider." + }, + "llm_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "llm_model": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Llm Model" + }, + "llm_temperature": { + "anyOf": [ + { + "type": "number", + "maximum": 2, + "minimum": 0 + }, + { + "type": "null" + } + ], + "title": "Llm Temperature" + }, + "llm_max_tokens": { + "anyOf": [ + { + "type": "integer", + "exclusiveMinimum": 0 + }, + { + "type": "null" + } + ], + "title": "Llm Max Tokens" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "llm_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Llm Credential Id" + }, + "tts_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "tts_model": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Tts Model" + }, + "tts_voice": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Voice" + }, + "tts_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Tts Config" + }, + "tts_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Tts Credential Id" + }, + "s2s_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "s2s_model": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "S2S Model" + }, + "s2s_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "S2S Config" + }, + "s2s_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "S2S Credential Id" + }, + "extra_metadata": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Extra Metadata" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "VoiceBundleCreate", + "description": "Schema for creating a VoiceBundle." + }, + "VoiceBundleUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "bundle_type": { + "anyOf": [ + { + "$ref": "#/components/schemas/VoiceBundleType" + }, + { + "type": "null" + } + ] + }, + "stt_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "stt_model": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Stt Model" + }, + "stt_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Stt Credential Id" + }, + "llm_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "llm_model": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Llm Model" + }, + "llm_temperature": { + "anyOf": [ + { + "type": "number", + "maximum": 2, + "minimum": 0 + }, + { + "type": "null" + } + ], + "title": "Llm Temperature" + }, + "llm_max_tokens": { + "anyOf": [ + { + "type": "integer", + "exclusiveMinimum": 0 + }, + { + "type": "null" + } + ], + "title": "Llm Max Tokens" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "llm_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Llm Credential Id" + }, + "tts_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "tts_model": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Tts Model" + }, + "tts_voice": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Voice" + }, + "tts_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Tts Config" + }, + "tts_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Tts Credential Id" + }, + "s2s_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "s2s_model": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "S2S Model" + }, + "s2s_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "S2S Config" + }, + "s2s_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "S2S Credential Id" + }, + "extra_metadata": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Extra Metadata" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "VoiceBundleUpdate", + "description": "Schema for updating a VoiceBundle." + }, + "AIProviderResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "provider": { + "$ref": "#/components/schemas/ModelProvider" + }, + "api_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Api Key" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "endpoint_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Endpoint Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "is_default": { + "type": "boolean", + "title": "Is Default", + "default": false + }, + "routing_mode": { + "$ref": "#/components/schemas/CredentialRoutingMode", + "default": "inherit" + }, + "gateway_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Gateway Model" + }, + "gateway_interface": { + "$ref": "#/components/schemas/GatewayInterfaceMode", + "default": "inherit" + }, + "gateway_base_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Gateway Base Url" + }, + "gateway_auth_header": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Gateway Auth Header" + }, + "gateway_auth_secret_env": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Gateway Auth Secret Env" + }, + "has_gateway_auth_secret": { + "type": "boolean", + "title": "Has Gateway Auth Secret", + "default": false + }, + "gateway_extra_headers": { + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gateway Extra Headers" + }, + "enabled_models": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Enabled Models" + }, + "gateway_managed": { + "type": "boolean", + "title": "Gateway Managed", + "default": false + }, + "effective_routing": { + "type": "string", + "enum": [ + "inherit", + "direct", + "gateway", + "bifrost", + "litellm_proxy" + ], + "title": "Effective Routing", + "default": "inherit" + }, + "effective_gateway_interface": { + "type": "string", + "enum": [ + "litellm_shim", + "native_openai" + ], + "title": "Effective Gateway Interface", + "default": "litellm_shim" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + }, + "last_tested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Tested At" + } + }, + "type": "object", + "required": [ + "id", + "provider", + "name", + "is_active", + "created_at", + "updated_at", + "last_tested_at" + ], + "title": "AIProviderResponse", + "description": "Schema for AI Provider response." + }, + "AIProviderCreate": { + "properties": { + "provider": { + "$ref": "#/components/schemas/ModelProvider" + }, + "api_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Api Key", + "description": "Provider API key. Optional when routing via gateway with gateway-managed credentials (passthrough_provider_keys: false)." + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "routing_mode": { + "$ref": "#/components/schemas/CredentialRoutingMode", + "description": "LLM routing preference: inherit org default, force gateway, or direct API key.", + "default": "inherit" + }, + "gateway_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Gateway Model", + "description": "Bifrost custom model ID sent when routing via gateway." + }, + "gateway_interface": { + "$ref": "#/components/schemas/GatewayInterfaceMode", + "description": "Bifrost API surface: inherit org default, LiteLLM shim, or native OpenAI-compatible.", + "default": "inherit" + }, + "gateway_base_url": { + "anyOf": [ + { + "type": "string", + "maxLength": 512 + }, + { + "type": "null" + } + ], + "title": "Gateway Base Url", + "description": "Optional per-credential Bifrost/gateway base URL override." + }, + "gateway_auth_header": { + "anyOf": [ + { + "type": "string", + "maxLength": 64 + }, + { + "type": "null" + } + ], + "title": "Gateway Auth Header", + "description": "Auth header name for Bifrost (default x-bf-vk)." + }, + "gateway_auth_secret_env": { + "anyOf": [ + { + "type": "string", + "maxLength": 128 + }, + { + "type": "null" + } + ], + "title": "Gateway Auth Secret Env", + "description": "Environment variable name holding the gateway auth secret." + }, + "gateway_auth_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Gateway Auth Secret", + "description": "Inline gateway auth secret (encrypted at rest). Alternative to env var." + }, + "gateway_extra_headers": { + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gateway Extra Headers", + "description": "Arbitrary HTTP headers sent with gateway-routed LiteLLM calls." + }, + "enabled_models": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Enabled Models", + "description": "Allowlisted model names for this credential. Null or empty means all catalog models for the provider." + }, + "is_default": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Default", + "description": "Mark this credential as the default for the (org, provider). If omitted and no default exists yet, this row becomes the default." + }, + "endpoint_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Endpoint Url", + "description": "Provider endpoint URL (required for Azure OpenAI)." + } + }, + "type": "object", + "required": [ + "provider" + ], + "title": "AIProviderCreate", + "description": "Schema for creating an AI Provider." + }, + "AIProviderUpdate": { + "properties": { + "api_key": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Api Key" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "endpoint_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Endpoint Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "routing_mode": { + "anyOf": [ + { + "$ref": "#/components/schemas/CredentialRoutingMode" + }, + { + "type": "null" + } + ] + }, + "gateway_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Gateway Model" + }, + "gateway_interface": { + "anyOf": [ + { + "$ref": "#/components/schemas/GatewayInterfaceMode" + }, + { + "type": "null" + } + ] + }, + "gateway_base_url": { + "anyOf": [ + { + "type": "string", + "maxLength": 512 + }, + { + "type": "null" + } + ], + "title": "Gateway Base Url" + }, + "gateway_auth_header": { + "anyOf": [ + { + "type": "string", + "maxLength": 64 + }, + { + "type": "null" + } + ], + "title": "Gateway Auth Header" + }, + "gateway_auth_secret_env": { + "anyOf": [ + { + "type": "string", + "maxLength": 128 + }, + { + "type": "null" + } + ], + "title": "Gateway Auth Secret Env" + }, + "gateway_auth_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Gateway Auth Secret" + }, + "clear_gateway_auth_secret": { + "type": "boolean", + "title": "Clear Gateway Auth Secret", + "default": false + }, + "gateway_extra_headers": { + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gateway Extra Headers" + }, + "enabled_models": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Enabled Models" + } + }, + "type": "object", + "title": "AIProviderUpdate", + "description": "Schema for updating an AI Provider." + }, + "FormatPromptRequest": { + "properties": { + "prompt": { + "type": "string", + "title": "Prompt" + } + }, + "type": "object", + "required": [ + "prompt" + ], + "title": "FormatPromptRequest" + }, + "FormatPromptResponse": { + "properties": { + "formatted_prompt": { + "type": "string", + "title": "Formatted Prompt" + } + }, + "type": "object", + "required": [ + "formatted_prompt" + ], + "title": "FormatPromptResponse" + }, + "EvaluatorResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "evaluator_id": { + "type": "string", + "title": "Evaluator Id" + }, + "organization_id": { + "type": "string", + "format": "uuid", + "title": "Organization Id" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "agent_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + }, + "persona_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Persona Id" + }, + "scenario_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + }, + "custom_prompt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Custom Prompt" + }, + "metric_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Metric Ids" + }, + "llm_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "llm_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Llm Model" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + }, + "created_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Created By" + } + }, + "type": "object", + "required": [ + "id", + "evaluator_id", + "organization_id", + "tags", + "created_at", + "updated_at", + "created_by" + ], + "title": "EvaluatorResponse", + "description": "Schema for evaluator response." + }, + "EvaluatorCreate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "agent_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + }, + "persona_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Persona Id" + }, + "scenario_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + }, + "custom_prompt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Custom Prompt" + }, + "metric_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Metric Ids" + }, + "llm_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "llm_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Llm Model" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + } + }, + "type": "object", + "title": "EvaluatorCreate", + "description": "Schema for creating an evaluator. Either provide agent_id+persona_id+scenario_id (standard) or metric_ids/custom_prompt (custom)." + }, + "EvaluatorBulkCreate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "agent_id": { + "type": "string", + "format": "uuid", + "title": "Agent Id" + }, + "scenario_id": { + "type": "string", + "format": "uuid", + "title": "Scenario Id" + }, + "persona_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Persona Ids" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + } + }, + "type": "object", + "required": [ + "agent_id", + "scenario_id", + "persona_ids" + ], + "title": "EvaluatorBulkCreate", + "description": "Schema for creating multiple evaluators at once." + }, + "EvaluatorUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "agent_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + }, + "persona_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Persona Id" + }, + "scenario_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + }, + "custom_prompt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Custom Prompt" + }, + "metric_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Metric Ids" + }, + "llm_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "llm_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Llm Model" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + } + }, + "type": "object", + "title": "EvaluatorUpdate", + "description": "Schema for updating an evaluator." + }, + "RunEvaluatorsRequest": { + "properties": { + "evaluator_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Evaluator Ids", + "description": "List of evaluator IDs to run" + } + }, + "type": "object", + "required": [ + "evaluator_ids" + ], + "title": "RunEvaluatorsRequest", + "description": "Schema for running evaluators." + }, + "RunEvaluatorsResponse": { + "properties": { + "task_ids": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Task Ids", + "description": "List of Celery task IDs for tracking" + }, + "evaluator_results": { + "items": { + "$ref": "#/components/schemas/EvaluatorResultResponse" + }, + "type": "array", + "title": "Evaluator Results", + "description": "List of created evaluator results" + } + }, + "type": "object", + "required": [ + "task_ids" + ], + "title": "RunEvaluatorsResponse", + "description": "Schema for run evaluators response.", + "example": { + "agent_id": "123e4567-e89b-12d3-a456-426614174000", + "persona_ids": [ + "123e4567-e89b-12d3-a456-426614174001", + "123e4567-e89b-12d3-a456-426614174003" + ], + "scenario_id": "123e4567-e89b-12d3-a456-426614174002", + "tags": [ + "test", + "production" + ] + } + }, + "EvaluatorSuiteResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "organization_id": { + "type": "string", + "format": "uuid", + "title": "Organization Id" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "agent_id": { + "type": "string", + "format": "uuid", + "title": "Agent Id" + }, + "persona_id": { + "type": "string", + "format": "uuid", + "title": "Persona Id" + }, + "persona_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Persona Ids" + }, + "personas": { + "items": { + "$ref": "#/components/schemas/EvaluatorSuitePersonaSummary" + }, + "type": "array", + "title": "Personas" + }, + "agent_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Name" + }, + "persona_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Persona Name" + }, + "agent_call_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Call Type" + }, + "agent_call_medium": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Call Medium" + }, + "voice_bundle_tts_provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Voice Bundle Tts Provider" + }, + "metric_ids": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Metric Ids" + }, + "llm_provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Llm Provider" + }, + "llm_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Llm Model" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + }, + "default_runs_per_combination": { + "type": "integer", + "title": "Default Runs Per Combination", + "default": 1 + }, + "round_robin_index": { + "type": "integer", + "title": "Round Robin Index", + "default": 0 + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "agent_suite_count": { + "type": "integer", + "title": "Agent Suite Count", + "default": 1 + }, + "combination_count": { + "type": "integer", + "title": "Combination Count", + "default": 0 + }, + "combinations": { + "items": { + "$ref": "#/components/schemas/EvaluatorSuiteCombinationResponse" + }, + "type": "array", + "title": "Combinations" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + }, + "created_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Created By" + } + }, + "type": "object", + "required": [ + "id", + "organization_id", + "agent_id", + "persona_id", + "created_at", + "updated_at" + ], + "title": "EvaluatorSuiteResponse", + "description": "Schema for evaluator suite response." + }, + "EvaluatorSuiteCreate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "agent_id": { + "type": "string", + "format": "uuid", + "title": "Agent Id" + }, + "persona_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Persona Id" + }, + "persona_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Persona Ids" + }, + "scenario_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Scenario Ids" + }, + "metric_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Metric Ids" + }, + "llm_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "llm_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Llm Model" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + }, + "default_runs_per_combination": { + "type": "integer", + "title": "Default Runs Per Combination", + "default": 1 + } + }, + "type": "object", + "required": [ + "agent_id", + "scenario_ids" + ], + "title": "EvaluatorSuiteCreate", + "description": "Schema for creating an evaluator suite." + }, + "EvaluatorSuiteUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + }, + "default_runs_per_combination": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Default Runs Per Combination" + }, + "llm_provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelProvider" + }, + { + "type": "null" + } + ] + }, + "llm_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Llm Model" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + }, + "metric_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Metric Ids" + } + }, + "type": "object", + "title": "EvaluatorSuiteUpdate", + "description": "Schema for updating an evaluator suite." + }, + "EvaluatorSuiteAddScenariosRequest": { + "properties": { + "scenario_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Scenario Ids" + } + }, + "type": "object", + "required": [ + "scenario_ids" + ], + "title": "EvaluatorSuiteAddScenariosRequest", + "description": "Schema for adding scenarios to an existing suite." + }, + "EvaluatorSuiteAddPersonasRequest": { + "properties": { + "persona_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Persona Ids" + } + }, + "type": "object", + "required": [ + "persona_ids" + ], + "title": "EvaluatorSuiteAddPersonasRequest", + "description": "Schema for adding personas to an existing suite." + }, + "EvaluatorSuiteReplacePersonasRequest": { + "properties": { + "persona_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "minItems": 1, + "title": "Persona Ids" + } + }, + "type": "object", + "required": [ + "persona_ids" + ], + "title": "EvaluatorSuiteReplacePersonasRequest", + "description": "Schema for replacing the persona set on an existing suite." + }, + "RunEvaluatorSuiteRequest": { + "properties": { + "runs_per_combination": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Runs Per Combination" + }, + "to_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "To Number" + }, + "from_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "From Number" + } + }, + "type": "object", + "title": "RunEvaluatorSuiteRequest", + "description": "Schema for running all combinations in a suite." + }, + "RunEvaluatorSuiteResponse": { + "properties": { + "total_runs": { + "type": "integer", + "title": "Total Runs" + }, + "task_ids": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Task Ids" + }, + "evaluator_results": { + "items": { + "$ref": "#/components/schemas/EvaluatorResultResponse" + }, + "type": "array", + "title": "Evaluator Results" + }, + "phone_call_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Phone Call Refs" + } + }, + "type": "object", + "required": [ + "total_runs" + ], + "title": "RunEvaluatorSuiteResponse", + "description": "Schema for suite run response." + }, + "ChooseNextCombinationResponse": { + "properties": { + "evaluator_id": { + "type": "string", + "format": "uuid", + "title": "Evaluator Id" + }, + "persona_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Persona Id" + }, + "persona_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Persona Name" + }, + "scenario_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + }, + "scenario_name": { + "type": "string", + "title": "Scenario Name" + }, + "combination_index": { + "type": "integer", + "title": "Combination Index" + }, + "next_index": { + "type": "integer", + "title": "Next Index" + } + }, + "type": "object", + "required": [ + "evaluator_id", + "scenario_name", + "combination_index", + "next_index" + ], + "title": "ChooseNextCombinationResponse", + "description": "Advance inbound round-robin without initiating a call or evaluation run." + }, + "RunNextCombinationRequest": { + "properties": { + "from_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "From Number" + } + }, + "type": "object", + "title": "RunNextCombinationRequest", + "description": "Schema for running the next round-robin combination." + }, + "RunNextCombinationResponse": { + "properties": { + "evaluator_id": { + "type": "string", + "format": "uuid", + "title": "Evaluator Id" + }, + "persona_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Persona Id" + }, + "persona_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Persona Name" + }, + "scenario_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + }, + "scenario_name": { + "type": "string", + "title": "Scenario Name" + }, + "combination_index": { + "type": "integer", + "title": "Combination Index" + }, + "next_index": { + "type": "integer", + "title": "Next Index" + }, + "evaluator_result_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Evaluator Result Id" + }, + "result_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Result Id" + }, + "task_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Task Id" + }, + "phone_call_ref": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Phone Call Ref" + }, + "call_short_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Call Short Id" + } + }, + "type": "object", + "required": [ + "evaluator_id", + "scenario_name", + "combination_index", + "next_index" + ], + "title": "RunNextCombinationResponse", + "description": "Schema for round-robin run response." + }, + "MetricResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "organization_id": { + "type": "string", + "format": "uuid", + "title": "Organization Id" + }, + "workspace_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Workspace Id" + }, + "scope": { + "type": "string", + "enum": [ + "workspace", + "organization" + ], + "title": "Scope", + "default": "workspace" + }, + "name": { + "type": "string", + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "example": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Example" + }, + "metric_type": { + "$ref": "#/components/schemas/MetricType" + }, + "metric_category": { + "$ref": "#/components/schemas/MetricCategory", + "default": "quality" + }, + "trigger": { + "$ref": "#/components/schemas/MetricTrigger" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "is_default": { + "type": "boolean", + "title": "Is Default" + }, + "metric_origin": { + "type": "string", + "title": "Metric Origin" + }, + "supported_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supported Surfaces" + }, + "enabled_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Enabled Surfaces" + }, + "custom_data_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Custom Data Type" + }, + "custom_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Custom Config" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + }, + "capture_rationale": { + "type": "boolean", + "title": "Capture Rationale", + "default": false + }, + "parent_metric_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Parent Metric Id" + }, + "selection_mode": { + "anyOf": [ + { + "type": "string", + "enum": [ + "single_choice", + "multi_label" + ] + }, + { + "type": "null" + } + ], + "title": "Selection Mode" + }, + "allow_discovery": { + "type": "boolean", + "title": "Allow Discovery", + "default": false + }, + "compare_transcripts": { + "type": "boolean", + "title": "Compare Transcripts", + "default": false + }, + "lifecycle": { + "type": "string", + "title": "Lifecycle", + "default": "active" + }, + "promoted_from_draft_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Promoted From Draft At" + }, + "studio_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Studio Notes" + }, + "children": { + "items": { + "$ref": "#/components/schemas/MetricResponse" + }, + "type": "array", + "title": "Children" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + }, + "created_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Created By" + } + }, + "type": "object", + "required": [ + "id", + "organization_id", + "name", + "description", + "metric_type", + "trigger", + "enabled", + "is_default", + "metric_origin", + "supported_surfaces", + "enabled_surfaces", + "custom_data_type", + "custom_config", + "tags", + "created_at", + "updated_at", + "created_by" + ], + "title": "MetricResponse", + "description": "Schema for metric response.\n\n``children`` is populated for parent metrics (those with\n``selection_mode`` set) and is otherwise an empty list. The list is\nbuilt once at serialization time so callers get a single tree\nstructure without follow-up requests." + }, + "MetricCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "example": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Example" + }, + "metric_type": { + "$ref": "#/components/schemas/MetricType", + "default": "rating" + }, + "metric_category": { + "$ref": "#/components/schemas/MetricCategory", + "default": "quality" + }, + "trigger": { + "$ref": "#/components/schemas/MetricTrigger", + "default": "always" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + }, + "metric_origin": { + "type": "string", + "title": "Metric Origin", + "default": "custom" + }, + "supported_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supported Surfaces", + "default": [ + "agent" + ] + }, + "enabled_surfaces": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Enabled Surfaces" + }, + "custom_data_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Custom Data Type" + }, + "custom_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Custom Config" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + }, + "capture_rationale": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Capture Rationale", + "default": false + }, + "parent_metric_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Parent Metric Id" + }, + "selection_mode": { + "anyOf": [ + { + "type": "string", + "enum": [ + "single_choice", + "multi_label" + ] + }, + { + "type": "null" + } + ], + "title": "Selection Mode" + }, + "allow_discovery": { + "type": "boolean", + "title": "Allow Discovery", + "default": false + }, + "compare_transcripts": { + "type": "boolean", + "title": "Compare Transcripts", + "default": false + }, + "scope": { + "type": "string", + "enum": [ + "workspace", + "organization" + ], + "title": "Scope", + "default": "workspace" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "MetricCreate", + "description": "Schema for creating a metric.\n\nHierarchy:\n- ``parent_metric_id`` set => this is a child sub-metric. ``metric_type``\n is forced to ``boolean`` server-side; ``selection_mode`` must be None.\n- ``selection_mode`` set => this is a parent category metric.\n ``parent_metric_id`` must be None (max depth = 2).\n\nScope:\n- ``scope=\"workspace\"`` (default) stamps the metric with the active\n ``X-Workspace-Id`` so it only shows up inside that workspace.\n- ``scope=\"organization\"`` stamps ``workspace_id=NULL`` so the metric\n is visible in every workspace of the org. Children always inherit\n their parent's scope; setting ``scope`` on a child request body is\n ignored server-side.", + "example": { + "description": "Measures the professional tone and behavior", + "enabled": true, + "metric_type": "rating", + "name": "Professionalism", + "trigger": "always" + } + }, + "MetricDraftCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "example": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Example" + }, + "metric_type": { + "$ref": "#/components/schemas/MetricType", + "default": "rating" + }, + "metric_category": { + "$ref": "#/components/schemas/MetricCategory", + "default": "quality" + }, + "trigger": { + "$ref": "#/components/schemas/MetricTrigger", + "default": "always" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + }, + "metric_origin": { + "type": "string", + "title": "Metric Origin", + "default": "custom" + }, + "supported_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supported Surfaces", + "default": [ + "agent" + ] + }, + "enabled_surfaces": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Enabled Surfaces" + }, + "custom_data_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Custom Data Type" + }, + "custom_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Custom Config" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + }, + "capture_rationale": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Capture Rationale", + "default": false + }, + "parent_metric_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Parent Metric Id" + }, + "selection_mode": { + "anyOf": [ + { + "type": "string", + "enum": [ + "single_choice", + "multi_label" + ] + }, + { + "type": "null" + } + ], + "title": "Selection Mode" + }, + "allow_discovery": { + "type": "boolean", + "title": "Allow Discovery", + "default": false + }, + "compare_transcripts": { + "type": "boolean", + "title": "Compare Transcripts", + "default": false + }, + "scope": { + "type": "string", + "enum": [ + "workspace", + "organization" + ], + "title": "Scope", + "default": "workspace" + }, + "studio_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Studio Notes", + "description": "Optional notes about what this draft is testing." + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "MetricDraftCreate", + "description": "Create a draft metric for Metrics Studio experimentation.", + "example": { + "description": "Measures the professional tone and behavior", + "enabled": true, + "metric_type": "rating", + "name": "Professionalism", + "trigger": "always" + } + }, + "MetricDraftCreateWithChildren": { + "properties": { + "name": { + "type": "string", + "maxLength": 120, + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "selection_mode": { + "type": "string", + "enum": [ + "single_choice", + "multi_label" + ], + "title": "Selection Mode" + }, + "metric_category": { + "$ref": "#/components/schemas/MetricCategory", + "default": "quality" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + }, + "supported_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supported Surfaces" + }, + "enabled_surfaces": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Enabled Surfaces" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + }, + "allow_discovery": { + "type": "boolean", + "title": "Allow Discovery", + "default": false + }, + "capture_rationale": { + "type": "boolean", + "title": "Capture Rationale", + "default": false + }, + "children": { + "items": { + "$ref": "#/components/schemas/MetricChildDraft" + }, + "type": "array", + "title": "Children", + "description": "Child sub-metric labels under this parent." + }, + "scope": { + "type": "string", + "enum": [ + "workspace", + "organization" + ], + "title": "Scope", + "default": "workspace" + }, + "studio_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Studio Notes", + "description": "Optional notes about what this draft category is testing." + } + }, + "type": "object", + "required": [ + "name", + "selection_mode" + ], + "title": "MetricDraftCreateWithChildren", + "description": "Atomically create a draft parent category metric plus its children." + }, + "MetricPromoteResponse": { + "properties": { + "metric": { + "$ref": "#/components/schemas/MetricResponse" + }, + "promoted_at": { + "type": "string", + "format": "date-time", + "title": "Promoted At" + } + }, + "type": "object", + "required": [ + "metric", + "promoted_at" + ], + "title": "MetricPromoteResponse", + "description": "Response after promoting a draft metric to active." + }, + "MetricCreateWithChildren": { + "properties": { + "name": { + "type": "string", + "maxLength": 120, + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "selection_mode": { + "type": "string", + "enum": [ + "single_choice", + "multi_label" + ], + "title": "Selection Mode" + }, + "metric_category": { + "$ref": "#/components/schemas/MetricCategory", + "default": "quality" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + }, + "supported_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supported Surfaces" + }, + "enabled_surfaces": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Enabled Surfaces" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + }, + "allow_discovery": { + "type": "boolean", + "title": "Allow Discovery", + "default": false + }, + "capture_rationale": { + "type": "boolean", + "title": "Capture Rationale", + "default": false + }, + "children": { + "items": { + "$ref": "#/components/schemas/MetricChildDraft" + }, + "type": "array", + "title": "Children", + "description": "Child sub-metric labels under this parent." + }, + "scope": { + "type": "string", + "enum": [ + "workspace", + "organization" + ], + "title": "Scope", + "default": "workspace" + } + }, + "type": "object", + "required": [ + "name", + "selection_mode" + ], + "title": "MetricCreateWithChildren", + "description": "One-shot create body: a parent metric + N children, atomically.\n\nChildren are persisted as full ``Metric`` rows with\n``parent_metric_id`` set to the new parent. ``metric_type`` on every\nchild is forced to ``boolean`` server-side regardless of what's\npassed in the parent body." + }, + "MetricChildDraft": { + "properties": { + "name": { + "type": "string", + "maxLength": 120, + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "example": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Example" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + }, + "capture_rationale": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Capture Rationale", + "default": true + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "MetricChildDraft", + "description": "One child sub-metric in a parent + children atomic create body." + }, + "PromoteDiscoveredChildRequest": { + "properties": { + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "name": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "capture_rationale": { + "type": "boolean", + "title": "Capture Rationale", + "default": true + } + }, + "type": "object", + "required": [ + "key", + "name" + ], + "title": "PromoteDiscoveredChildRequest", + "description": "Body for POST /metrics/{parent_id}/children/from-discovered.\n\n``key`` is the slug under which the candidate is currently stored\non per-row ``metric_scores``. The newly-created child Metric's\nname is normalized so ``slugify(name) == key``, which keeps every\nalready-scored row's ``sequence`` array resolvable against the\npromoted child without a backfill." + }, + "PromoteDiscoveredMetricRequest": { + "properties": { + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "name": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "metric_type": { + "type": "string", + "enum": [ + "boolean", + "rating", + "category" + ], + "title": "Metric Type", + "default": "boolean" + }, + "capture_rationale": { + "type": "boolean", + "title": "Capture Rationale", + "default": true + }, + "custom_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Custom Config" + } + }, + "type": "object", + "required": [ + "key", + "name" + ], + "title": "PromoteDiscoveredMetricRequest", + "description": "Body for POST /metrics/from-discovered.\n\nCreates a standalone :class:`Metric` (``parent_metric_id=None``)\nfrom an LLM-discovered candidate. The new metric's name is\nnormalized so ``slugify(name) == key`` to keep already-scored row\npayloads resolvable against the promoted metric. ``metric_type``\nselects how the new metric will be scored on future runs;\n``\"category\"`` creates a ``multi_label`` parent with no children\n(the user adds children via the existing Metrics page)." + }, + "MetricUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "example": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Example" + }, + "metric_type": { + "anyOf": [ + { + "$ref": "#/components/schemas/MetricType" + }, + { + "type": "null" + } + ] + }, + "trigger": { + "anyOf": [ + { + "$ref": "#/components/schemas/MetricTrigger" + }, + { + "type": "null" + } + ] + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + }, + "metric_origin": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Metric Origin" + }, + "supported_surfaces": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Supported Surfaces" + }, + "enabled_surfaces": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Enabled Surfaces" + }, + "custom_data_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Custom Data Type" + }, + "custom_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Custom Config" + }, + "tags": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tags" + }, + "metric_category": { + "anyOf": [ + { + "$ref": "#/components/schemas/MetricCategory" + }, + { + "type": "null" + } + ] + }, + "capture_rationale": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Capture Rationale" + }, + "selection_mode": { + "anyOf": [ + { + "type": "string", + "enum": [ + "single_choice", + "multi_label" + ] + }, + { + "type": "null" + } + ], + "title": "Selection Mode" + }, + "allow_discovery": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Allow Discovery" + }, + "compare_transcripts": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Compare Transcripts" + } + }, + "type": "object", + "title": "MetricUpdate", + "description": "Schema for updating a metric." + }, + "MetricGenerateRequest": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "description", + "examples" + ], + "title": "Mode" + }, + "surface": { + "type": "string", + "enum": [ + "agent", + "voice_playground", + "blind_test" + ], + "title": "Surface", + "default": "agent" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "Free-form description of what the metric should measure (mode=description)." + }, + "examples": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/MetricGenerateExample" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Examples", + "description": "Labeled examples used to infer the metric (mode=examples)." + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + }, + "model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model" + }, + "credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Credential Id" + }, + "llm_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Llm Config" + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "MetricGenerateRequest", + "description": "Request body for AI-generated metric suggestion." + }, + "MetricGenerateResponse": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "description": { + "type": "string", + "title": "Description" + }, + "metric_type": { + "type": "string", + "enum": [ + "rating", + "boolean", + "number", + "text" + ], + "title": "Metric Type" + }, + "custom_data_type": { + "anyOf": [ + { + "type": "string", + "enum": [ + "boolean", + "enum", + "number_range" + ] + }, + { + "type": "null" + } + ], + "title": "Custom Data Type" + }, + "custom_config": { + "additionalProperties": true, + "type": "object", + "title": "Custom Config", + "default": {} + }, + "supported_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supported Surfaces" + }, + "enabled_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Enabled Surfaces" + }, + "suggested_tags": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Suggested Tags", + "default": [] + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + }, + "model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "type": "object", + "required": [ + "name", + "description", + "metric_type", + "supported_surfaces", + "enabled_surfaces" + ], + "title": "MetricGenerateResponse", + "description": "Suggested (un-persisted) metric definition returned to the client." + }, + "MetricParseBulkRequest": { + "properties": { + "prompt": { + "type": "string", + "title": "Prompt", + "description": "The pasted Label-block prompt." + }, + "surface": { + "type": "string", + "enum": [ + "agent", + "voice_playground", + "blind_test" + ], + "title": "Surface", + "default": "agent" + }, + "parent_name": { + "anyOf": [ + { + "type": "string", + "maxLength": 120 + }, + { + "type": "null" + } + ], + "title": "Parent Name", + "description": "When set, returns ONE parent draft owning every parsed label as a child. Used to build a 'category' metric in one shot." + }, + "parent_description": { + "anyOf": [ + { + "type": "string", + "maxLength": 1000000 + }, + { + "type": "null" + } + ], + "title": "Parent Description", + "description": "Optional description used as the parent's LLM rubric." + }, + "selection_mode": { + "anyOf": [ + { + "type": "string", + "enum": [ + "single_choice", + "multi_label" + ] + }, + { + "type": "null" + } + ], + "title": "Selection Mode", + "description": "Required when ``parent_name`` is set. Controls how the LLM scores children together: single_choice = exactly one true; multi_label = independent yes/no with logical consistency." + } + }, + "type": "object", + "required": [ + "prompt" + ], + "title": "MetricParseBulkRequest", + "description": "Request body for bulk-importing multiple metrics from a prompt.\n\nOptional hierarchy fields let the bulk import produce a parent\ncategory metric with the parsed labels as children instead of N\nindependent top-level metrics." + }, + "MetricParseBulkResponse": { + "properties": { + "metrics": { + "items": { + "$ref": "#/components/schemas/MetricDraft" + }, + "type": "array", + "title": "Metrics" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/components/schemas/MetricParseBulkParentDraft" + }, + { + "type": "null" + } + ] + } + }, + "type": "object", + "required": [ + "metrics" + ], + "title": "MetricParseBulkResponse", + "description": "List of independent un-persisted metric drafts, one per label.\n\n``parent`` is populated only when the request asked for a hierarchy\n(``parent_name`` set); the frontend then POSTs to\n``/metrics/with-children`` instead of N independent ``/metrics`` calls." + }, + "MetricFailurePoliciesResponse": { + "properties": { + "previews": { + "items": { + "$ref": "#/components/schemas/MetricFailurePolicyMetricPreview" + }, + "type": "array", + "title": "Previews" + }, + "policies": { + "additionalProperties": { + "$ref": "#/components/schemas/MetricFailurePolicy" + }, + "type": "object", + "title": "Policies" + }, + "source": { + "type": "string", + "enum": [ + "inferred", + "user" + ], + "title": "Source", + "default": "inferred" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "title": "MetricFailurePoliciesResponse" + }, + "MetricFailurePoliciesSaveRequest": { + "properties": { + "policies": { + "additionalProperties": { + "$ref": "#/components/schemas/MetricFailurePolicy" + }, + "type": "object", + "title": "Policies" + }, + "source": { + "type": "string", + "const": "user", + "title": "Source", + "default": "user" + } + }, + "type": "object", + "title": "MetricFailurePoliciesSaveRequest" + }, + "MetricClusterEligibleRowsResponse": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/MetricClusterEligibleRow" + }, + "type": "array", + "title": "Items" + }, + "total": { + "type": "integer", + "title": "Total", + "default": 0 + } + }, + "type": "object", + "title": "MetricClusterEligibleRowsResponse" + }, + "EvaluatorResultClusterScopeListResponse": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvaluatorResultClusterScopeSummary" + }, + "type": "array", + "title": "Items" + } + }, + "type": "object", + "title": "EvaluatorResultClusterScopeListResponse" + }, + "EvaluationMetricClustersState": { + "properties": { + "status": { + "type": "string", + "enum": [ + "idle", + "running", + "completed", + "failed", + "cancelled" + ], + "title": "Status", + "default": "idle" + }, + "groups": { + "items": { + "$ref": "#/components/schemas/MetricClusterGroup" + }, + "type": "array", + "title": "Groups" + }, + "discovered_problems": { + "items": { + "$ref": "#/components/schemas/DiscoveredProblemCluster" + }, + "type": "array", + "title": "Discovered Problems" + }, + "overview": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Overview" + }, + "generated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Generated At" + }, + "generated_at_completed_rows": { + "type": "integer", + "title": "Generated At Completed Rows", + "default": 0 + }, + "progress": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Progress" + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + }, + "model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model" + }, + "llm_calls_used": { + "type": "integer", + "title": "Llm Calls Used", + "default": 0 + }, + "max_llm_calls": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Max Llm Calls" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "is_stale": { + "type": "boolean", + "title": "Is Stale", + "default": false + }, + "selected_evaluation_row_ids": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Selected Evaluation Row Ids", + "description": "Evaluation row IDs included in the last clustering run." + }, + "failure_policies": { + "additionalProperties": { + "$ref": "#/components/schemas/MetricFailurePolicy" + }, + "type": "object", + "title": "Failure Policies" + }, + "failure_policies_source": { + "type": "string", + "enum": [ + "inferred", + "user" + ], + "title": "Failure Policies Source", + "default": "inferred" + }, + "failure_policies_updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Failure Policies Updated At" + }, + "rca_summary": { + "anyOf": [ + { + "$ref": "#/components/schemas/MetricClustersRcaSummary" + }, + { + "type": "null" + } + ] + }, + "generation_scope": { + "anyOf": [ + { + "$ref": "#/components/schemas/MetricClusterGenerationScope" + }, + { + "type": "null" + } + ] + } + }, + "type": "object", + "title": "EvaluationMetricClustersState", + "description": "Cached per-metric failure clustering for internal diagnostics." + }, + "EvaluationMetricClustersRequest": { + "properties": { + "regenerate": { + "type": "boolean", + "title": "Regenerate", + "default": false + }, + "force": { + "type": "boolean", + "title": "Force", + "default": false + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + }, + "model": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Model" + }, + "credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Credential Id" + }, + "max_llm_calls": { + "anyOf": [ + { + "type": "integer", + "maximum": 500, + "minimum": 20 + }, + { + "type": "null" + } + ], + "title": "Max Llm Calls" + }, + "evaluation_row_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Evaluation Row Ids", + "description": "Subset of completed evaluation row IDs to cluster. When omitted, all completed rows with at least one flagged quality metric are used." + }, + "row_limit": { + "anyOf": [ + { + "type": "integer", + "minimum": 1 + }, + { + "type": "null" + } + ], + "title": "Row Limit", + "description": "Use the first N eligible rows (by row order). Mutually exclusive with evaluation_row_ids." + }, + "failure_policies": { + "anyOf": [ + { + "additionalProperties": { + "$ref": "#/components/schemas/MetricFailurePolicy" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Failure Policies", + "description": "Per-metric failure policies confirmed in the cluster modal." + } + }, + "type": "object", + "title": "EvaluationMetricClustersRequest", + "description": "Body for ``POST /evaluations/{eval_id}/metric-clusters``." + }, + "EvaluatorResultsOverviewResponse": { + "properties": { + "workspace_counts": { + "$ref": "#/components/schemas/EvaluatorResultCounts" + }, + "agents": { + "items": { + "$ref": "#/components/schemas/EvaluatorResultsAgentSummary" + }, + "type": "array", + "title": "Agents" + }, + "unassigned": { + "$ref": "#/components/schemas/EvaluatorResultsUnassignedSummary" + } + }, + "type": "object", + "required": [ + "workspace_counts", + "unassigned" + ], + "title": "EvaluatorResultsOverviewResponse" + }, + "EvaluatorResultsAggregateResponse": { + "properties": { + "scope": { + "type": "string", + "title": "Scope" + }, + "suite_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Suite Id" + }, + "agent_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + }, + "scenario_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + }, + "total_rows": { + "type": "integer", + "title": "Total Rows", + "default": 0 + }, + "completed_rows": { + "type": "integer", + "title": "Completed Rows", + "default": 0 + }, + "failed_rows": { + "type": "integer", + "title": "Failed Rows", + "default": 0 + }, + "metrics": { + "items": { + "$ref": "#/components/schemas/CallImportMetricAggregate" + }, + "type": "array", + "title": "Metrics" + } + }, + "type": "object", + "required": [ + "scope" + ], + "title": "EvaluatorResultsAggregateResponse", + "description": "Chart-friendly metric rollups for evaluator results in a suite or scenario scope." + }, + "EvaluatorResultListResponse": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvaluatorResultResponse" + }, + "type": "array", + "title": "Items" + }, + "total": { + "type": "integer", + "title": "Total" + } + }, + "type": "object", + "required": [ + "items", + "total" + ], + "title": "EvaluatorResultListResponse" + }, + "EvaluatorResultCreateManual": { + "properties": { + "evaluator_id": { + "type": "string", + "format": "uuid", + "title": "Evaluator Id" + }, + "audio_s3_key": { + "type": "string", + "title": "Audio S3 Key" + }, + "duration_seconds": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Duration Seconds" + } + }, + "type": "object", + "required": [ + "evaluator_id", + "audio_s3_key" + ], + "title": "EvaluatorResultCreateManual", + "description": "Schema for manually creating an evaluator result from existing audio file." + }, + "EvaluatorResultResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "result_id": { + "type": "string", + "title": "Result Id" + }, + "organization_id": { + "type": "string", + "format": "uuid", + "title": "Organization Id" + }, + "evaluator_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Evaluator Id" + }, + "agent_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Agent Id" + }, + "persona_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Persona Id" + }, + "scenario_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "duration_seconds": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Duration Seconds" + }, + "status": { + "$ref": "#/components/schemas/EvaluatorResultStatus" + }, + "audio_s3_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Audio S3 Key" + }, + "transcription": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Transcription" + }, + "speaker_segments": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Speaker Segments" + }, + "metric_scores": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Metric Scores" + }, + "celery_task_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Celery Task Id" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "call_event": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Call Event" + }, + "provider_call_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider Call Id" + }, + "provider_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider Platform" + }, + "call_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Call Data" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + }, + "created_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "agent": { + "anyOf": [ + { + "$ref": "#/components/schemas/AgentResponse" + }, + { + "type": "null" + } + ] + }, + "persona": { + "anyOf": [ + { + "$ref": "#/components/schemas/PersonaResponse" + }, + { + "type": "null" + } + ] + }, + "scenario": { + "anyOf": [ + { + "$ref": "#/components/schemas/ScenarioResponse" + }, + { + "type": "null" + } + ] + }, + "evaluator": { + "anyOf": [ + { + "$ref": "#/components/schemas/EvaluatorResponse" + }, + { + "type": "null" + } + ] + } + }, + "type": "object", + "required": [ + "id", + "result_id", + "organization_id", + "timestamp", + "duration_seconds", + "status", + "audio_s3_key", + "transcription", + "metric_scores", + "celery_task_id", + "error_message", + "created_at", + "updated_at", + "created_by" + ], + "title": "EvaluatorResultResponse", + "description": "Schema for evaluator result response." + }, + "EvaluateCallPayload": { + "properties": { + "evaluator_id": { + "type": "string", + "title": "Evaluator Id" + } + }, + "type": "object", + "required": [ + "evaluator_id" + ], + "title": "EvaluateCallPayload", + "description": "Payload to trigger evaluation on an ingested call." + }, + "Body_previewCallImportFile": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_previewCallImportFile" + }, + "CallImportPreviewResponse": { + "properties": { + "format": { + "type": "string", + "title": "Format", + "description": "One of 'csv' or 'xlsx'." + }, + "sheets": { + "items": { + "$ref": "#/components/schemas/CallImportPreviewSheet" + }, + "type": "array", + "title": "Sheets" + } + }, + "type": "object", + "required": [ + "format" + ], + "title": "CallImportPreviewResponse", + "description": "Sheets/headers extracted from an uploaded CSV or Excel workbook.\n\nThe frontend uses this to drive the column-mapping UI without doing\nits own parsing G๏ฟฝ๏ฟฝ keeps client and server in lockstep on quoted\nfields, encodings, and Excel cell coercion." + }, + "CallImportStatus": { + "type": "string", + "enum": [ + "pending", + "uploaded", + "mapped", + "processing", + "completed", + "partial", + "failed", + "deleting" + ], + "title": "CallImportStatus", + "description": "Status of a CSV-driven call import batch.\n\nThe lifecycle is now split into three independent stages so the\nupload, mapping, and import are each idempotent on their own:\n\n ``uploaded`` -> source file landed in S3, no mapping yet.\n ``mapped`` -> user picked a schema + sheet + column mapping;\n no rows materialised yet, no worker enqueued.\n ``processing`` -> rows materialised + workers enqueued (today's\n post-upload state).\n ``deleting`` -> whole-batch teardown queued in background.\n\n``pending`` is kept for backward compatibility with the legacy\none-shot ``POST /upload`` endpoint which still flips through it\nmomentarily before transitioning to ``processing``." + }, + "CallImportListResponse": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/CallImportResponse" + }, + "type": "array", + "title": "Items" + }, + "total": { + "type": "integer", + "title": "Total" + }, + "page": { + "type": "integer", + "title": "Page" + }, + "page_size": { + "type": "integer", + "title": "Page Size" + } + }, + "type": "object", + "required": [ + "items", + "total", + "page", + "page_size" + ], + "title": "CallImportListResponse", + "description": "Paginated list of call-import batches." + }, + "Body_createCallImport": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File", + "description": "CSV / Excel file to stage. Persisted to S3 between stages." + }, + "dataset": { + "type": "string", + "title": "Dataset", + "description": "Required free-text dataset label. Collected up-front so the batch is filterable from the moment it lands." + }, + "tag_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tag Ids", + "description": "Optional list of CallImportTag ids to attach to the new batch." + }, + "schema_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Schema Id", + "description": "Optional schema pre-pick. The user can still change it during the MAP stage; provided here only so the detail page can pre-select the schema dropdown." + } + }, + "type": "object", + "required": [ + "file", + "dataset" + ], + "title": "Body_createCallImport" + }, + "CallImportResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "organization_id": { + "type": "string", + "format": "uuid", + "title": "Organization Id" + }, + "workspace_id": { + "type": "string", + "format": "uuid", + "title": "Workspace Id" + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + }, + "telephony_integration_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Telephony Integration Id" + }, + "original_filename": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Original Filename" + }, + "sheet_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sheet Name" + }, + "dataset": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Dataset" + }, + "tags": { + "items": { + "$ref": "#/components/schemas/CallImportTagResponse" + }, + "type": "array", + "title": "Tags" + }, + "schema_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Schema Id" + }, + "parameter_mapping": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Parameter Mapping" + }, + "column_mapping": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "type": "object", + "title": "Column Mapping" + }, + "extra_columns": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Extra Columns" + }, + "custom_column_mapping": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Custom Column Mapping" + }, + "skipped_columns": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Columns" + }, + "source_row_skips": { + "items": { + "$ref": "#/components/schemas/CallImportSourceRowSkip" + }, + "type": "array", + "title": "Source Row Skips", + "description": "Source rows skipped at parse time because of missing/invalid conversation ID or recording URL." + }, + "source_s3_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source S3 Key" + }, + "source_format": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Format" + }, + "source_size_bytes": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Source Size Bytes" + }, + "source_content_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Content Type" + }, + "available_sheets": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/CallImportPreviewSheet" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Available Sheets" + }, + "total_rows": { + "type": "integer", + "title": "Total Rows" + }, + "completed_rows": { + "type": "integer", + "title": "Completed Rows" + }, + "failed_rows": { + "type": "integer", + "title": "Failed Rows" + }, + "status": { + "$ref": "#/components/schemas/CallImportStatus" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "latest_evaluation_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Latest Evaluation Status", + "description": "Status of the most recent evaluation run for this batch, when any evaluation exists." + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + }, + "created_by_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Created By Email" + }, + "last_updated_by_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Updated By Email" + } + }, + "type": "object", + "required": [ + "id", + "organization_id", + "workspace_id", + "total_rows", + "completed_rows", + "failed_rows", + "status", + "created_at", + "updated_at" + ], + "title": "CallImportResponse", + "description": "Summary of a call-import batch." + }, + "CallImportMappingUpdate": { + "properties": { + "schema_id": { + "type": "string", + "format": "uuid", + "title": "Schema Id", + "description": "Reusable Input Parameter schema this batch is mapped against. Must belong to the active workspace." + }, + "sheet_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sheet Name", + "description": "Worksheet to use when the staged source file is an Excel workbook. REQUIRED for xlsx; ignored / rejected for CSV." + }, + "parameter_mapping": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Parameter Mapping", + "description": "``{schema_parameter_name: source_header}`` map covering every required schema parameter." + }, + "skipped_columns": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Columns", + "description": "Source headers the uploader has explicitly skipped. Every source header must be either mapped or appear here." + } + }, + "type": "object", + "required": [ + "schema_id" + ], + "title": "CallImportMappingUpdate", + "description": "Mapping payload for the MAP stage (``PATCH /call-imports/{id}/mapping``).\n\nIdempotent: callers can submit this multiple times against an\n``uploaded`` or ``mapped`` batch. Validation re-runs against the\npersisted ``available_sheets`` snapshot every time so the user can\ncorrect mistakes without re-uploading the file." + }, + "CallImportStartRequest": { + "properties": { + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider", + "description": "Telephony provider key. Must match the ``telephony_integration_id``'s provider. Omit together with ``telephony_integration_id`` to download recordings directly from CSV-supplied URLs without credentials." + }, + "telephony_integration_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Telephony Integration Id", + "description": "Specific TelephonyIntegration credential row to use when downloading recordings for this batch. Omit together with ``provider`` for direct-URL import." + } + }, + "type": "object", + "title": "CallImportStartRequest", + "description": "Provider + credential picker for the IMPORT stage." + }, + "CallImportUploadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "total_rows": { + "type": "integer", + "title": "Total Rows" + }, + "status": { + "$ref": "#/components/schemas/CallImportStatus" + }, + "dataset": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Dataset" + }, + "tags": { + "items": { + "$ref": "#/components/schemas/CallImportTagResponse" + }, + "type": "array", + "title": "Tags" + }, + "message": { + "type": "string", + "title": "Message" + } + }, + "type": "object", + "required": [ + "id", + "total_rows", + "status", + "message" + ], + "title": "CallImportUploadResponse", + "description": "Response returned right after a CSV is accepted." + }, + "Body_uploadCallImportCsv": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider", + "description": "Telephony provider key (e.g. 'exotel', 'plivo'). Must match the selected telephony_integration_id's provider. Omit together with telephony_integration_id for direct-URL import." + }, + "telephony_integration_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Telephony Integration Id", + "description": "Specific TelephonyIntegration credential row to use when downloading recordings for this batch. Omit together with provider for direct-URL import." + }, + "schema_id": { + "type": "string", + "format": "uuid", + "title": "Schema Id", + "description": "Reusable Input Parameter schema this upload is mapped against. Must belong to the active workspace." + }, + "parameter_mapping": { + "type": "string", + "title": "Parameter Mapping", + "description": "JSON-encoded ``{schema_parameter_name: source_header}`` map covering every required schema parameter. Optional parameters may be omitted or set to an empty string." + }, + "skipped_columns": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Skipped Columns", + "description": "JSON-encoded list of source header strings the uploader has explicitly skipped. Every header in the file must either be mapped or appear here; otherwise the upload is rejected so a forgotten column never silently drops." + }, + "dataset": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Dataset", + "description": "Optional free-text dataset label for high-level segregation. Empty strings are stored as NULL." + }, + "tag_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tag Ids", + "description": "Optional list of CallImportTag ids to attach to the new batch." + }, + "sheet_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sheet Name", + "description": "Worksheet to import when the file is an Excel workbook (.xlsx / .xlsm). REQUIRED for Excel uploads. Ignored for CSV uploads (rejected with 400 if non-empty so typos surface instead of silently importing the wrong source)." + } + }, + "type": "object", + "required": [ + "file", + "schema_id", + "parameter_mapping" + ], + "title": "Body_uploadCallImportCsv" + }, + "Body_uploadCallImportAudio": { + "properties": { + "files": { + "items": { + "type": "string", + "contentMediaType": "application/octet-stream" + }, + "type": "array", + "title": "Files", + "description": "One or more manual call recording audio files." + }, + "dataset": { + "type": "string", + "title": "Dataset", + "description": "Required free-text dataset label for the manual upload batch." + }, + "tag_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tag Ids", + "description": "Optional list of CallImportTag ids to attach to the new batch." + }, + "batch_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Batch Name", + "description": "Optional display name for this manual upload batch. When omitted, a generic label is used for multi-file uploads." + } + }, + "type": "object", + "required": [ + "files", + "dataset" + ], + "title": "Body_uploadCallImportAudio" + }, + "Body_appendCallImportAudio": { + "properties": { + "files": { + "items": { + "type": "string", + "contentMediaType": "application/octet-stream" + }, + "type": "array", + "title": "Files", + "description": "Additional manual call recording audio files for an existing batch." + } + }, + "type": "object", + "required": [ + "files" + ], + "title": "Body_appendCallImportAudio" + }, + "CallImportDispatchDiagnosticsResponse": { + "properties": { + "limits": { + "$ref": "#/components/schemas/CallImportDispatchLimitSnapshot" + }, + "fair_dispatch": { + "$ref": "#/components/schemas/CallImportDispatchFairDispatchSnapshot" + }, + "workspaces": { + "items": { + "$ref": "#/components/schemas/CallImportDispatchWorkspaceSnapshot" + }, + "type": "array", + "title": "Workspaces" + }, + "generated_at": { + "type": "string", + "format": "date-time", + "title": "Generated At" + } + }, + "type": "object", + "required": [ + "limits", + "fair_dispatch", + "workspaces", + "generated_at" + ], + "title": "CallImportDispatchDiagnosticsResponse", + "description": "Live operator snapshot for call-import eval fair dispatch." + }, + "CallImportDiarisationPromptDefaultResponse": { + "properties": { + "prompt": { + "type": "string", + "title": "Prompt", + "description": "The exact prompt the worker falls back to when the caller leaves ``diarization_prompt`` blank. The frontend pre-fills the textarea with this value so the operator can edit it." + } + }, + "type": "object", + "required": [ + "prompt" + ], + "title": "CallImportDiarisationPromptDefaultResponse", + "description": "Wrapper for the canonical diariser-prompt fetched by the modal." + }, + "CallImportDetailResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "organization_id": { + "type": "string", + "format": "uuid", + "title": "Organization Id" + }, + "workspace_id": { + "type": "string", + "format": "uuid", + "title": "Workspace Id" + }, + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider" + }, + "telephony_integration_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Telephony Integration Id" + }, + "original_filename": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Original Filename" + }, + "sheet_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sheet Name" + }, + "dataset": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Dataset" + }, + "tags": { + "items": { + "$ref": "#/components/schemas/CallImportTagResponse" + }, + "type": "array", + "title": "Tags" + }, + "schema_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Schema Id" + }, + "parameter_mapping": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Parameter Mapping" + }, + "column_mapping": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "type": "object", + "title": "Column Mapping" + }, + "extra_columns": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Extra Columns" + }, + "custom_column_mapping": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Custom Column Mapping" + }, + "skipped_columns": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Columns" + }, + "source_row_skips": { + "items": { + "$ref": "#/components/schemas/CallImportSourceRowSkip" + }, + "type": "array", + "title": "Source Row Skips", + "description": "Source rows skipped at parse time because of missing/invalid conversation ID or recording URL." + }, + "source_s3_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source S3 Key" + }, + "source_format": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Format" + }, + "source_size_bytes": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Source Size Bytes" + }, + "source_content_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Content Type" + }, + "available_sheets": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/CallImportPreviewSheet" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Available Sheets" + }, + "total_rows": { + "type": "integer", + "title": "Total Rows" + }, + "completed_rows": { + "type": "integer", + "title": "Completed Rows" + }, + "failed_rows": { + "type": "integer", + "title": "Failed Rows" + }, + "status": { + "$ref": "#/components/schemas/CallImportStatus" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "latest_evaluation_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Latest Evaluation Status", + "description": "Status of the most recent evaluation run for this batch, when any evaluation exists." + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + }, + "created_by_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Created By Email" + }, + "last_updated_by_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Updated By Email" + }, + "rows": { + "items": { + "$ref": "#/components/schemas/CallImportRowResponse" + }, + "type": "array", + "title": "Rows" + }, + "filtered_total_rows": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Filtered Total Rows" + }, + "diarised_pending_rows": { + "type": "integer", + "title": "Diarised Pending Rows", + "default": 0 + }, + "diarised_running_rows": { + "type": "integer", + "title": "Diarised Running Rows", + "default": 0 + }, + "diarised_completed_rows": { + "type": "integer", + "title": "Diarised Completed Rows", + "default": 0 + }, + "diarised_failed_rows": { + "type": "integer", + "title": "Diarised Failed Rows", + "default": 0 + } + }, + "type": "object", + "required": [ + "id", + "organization_id", + "workspace_id", + "total_rows", + "completed_rows", + "failed_rows", + "status", + "created_at", + "updated_at" + ], + "title": "CallImportDetailResponse", + "description": "A call-import batch with its rows expanded.\n\n``filtered_total_rows`` is only set when the caller passed a ``q``\nsearch term G๏ฟฝ๏ฟฝ it lets the UI paginate against the filtered subset\nwhile still showing the unfiltered ``total_rows`` in the header.\n\nThe ``diarised_*_rows`` counters aggregate\n``CallImportRow.diarised_transcript_status`` across the batch so the\nUI can render a transcribe-and-diarise progress bar without paging\nthrough every row. Rows that have never been touched by the\ntranscribe/diarise worker (``status='idle'``) are NOT counted here G๏ฟฝ๏ฟฝ\ncallers compute the idle bucket as\n``total_rows - (pending + running + completed + failed)``." + }, + "CallImportUpdate": { + "properties": { + "original_filename": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Original Filename", + "description": "User-facing batch label shown in the UI. Pass an empty string to clear." + }, + "dataset": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Dataset", + "description": "Free-text dataset label. Pass an empty string to clear the dataset." + }, + "tag_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Tag Ids", + "description": "Replace the full set of tag assignments. Pass an empty list to clear all tags." + }, + "schema_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Schema Id", + "description": "Reassign the Input Parameter schema. Only honoured while the batch is in ``uploaded`` or ``mapped`` state; once the batch has rows it's locked to its original schema." + } + }, + "type": "object", + "title": "CallImportUpdate", + "description": "Partial update of a call-import batch." + }, + "CallImportDeleteResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "status": { + "type": "string", + "enum": [ + "accepted", + "completed" + ], + "title": "Status", + "description": "``accepted`` when teardown was queued to run asynchronously; ``completed`` when the batch was already removed." + } + }, + "type": "object", + "required": [ + "id", + "status" + ], + "title": "CallImportDeleteResponse", + "description": "Response after a whole-batch call-import delete is accepted." + }, + "CallImportRowIdsResponse": { + "properties": { + "ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Ids", + "description": "Every ``CallImportRow.id`` that matches the ``q`` and ``diarised_status`` filters (or every row when neither is supplied), sorted by ``row_index``." + }, + "total": { + "type": "integer", + "title": "Total", + "description": "Length of ``ids``. Sent explicitly so callers can show a count without re-measuring the array." + } + }, + "type": "object", + "required": [ + "total" + ], + "title": "CallImportRowIdsResponse", + "description": "Flat row-id list for cross-page bulk selection.\n\nPowers the \"Select all M rows in this import\" affordance on the\ndetail page G๏ฟฝ๏ฟฝ returning only ids keeps the payload tiny so the UI\ncan hold the full set in memory even for batches with thousands\nof rows. The frontend then passes those ids straight to the\nexisting bulk-delete / bulk-transcribe endpoints." + }, + "CallImportRetryFailedRowsRequest": { + "properties": { + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider", + "description": "Telephony provider key for this retry pass. Omit together with ``telephony_integration_id`` to download from CSV recording URLs." + }, + "telephony_integration_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Telephony Integration Id", + "description": "Telephony credential to use for this retry pass. Omit together with ``provider`` for direct-URL retry." + } + }, + "type": "object", + "title": "CallImportRetryFailedRowsRequest", + "description": "Optional credential override when re-enqueueing failed import rows." + }, + "CallImportRetryFailedRowsResponse": { + "properties": { + "requeued": { + "type": "integer", + "title": "Requeued", + "description": "Rows reset to pending and successfully re-enqueued on the ``imports`` worker queue." + }, + "enqueue_failed": { + "type": "integer", + "title": "Enqueue Failed", + "description": "Rows that were eligible for retry but failed to enqueue again. These rows are left in ``failed`` with an enqueue error.", + "default": 0 + }, + "skipped": { + "type": "integer", + "title": "Skipped", + "description": "Rows skipped because they were no longer in ``failed`` at retry time (for example, already retried from another tab).", + "default": 0 + } + }, + "type": "object", + "required": [ + "requeued" + ], + "title": "CallImportRetryFailedRowsResponse", + "description": "Summary of a retry pass over failed call-import rows." + }, + "CallImportRowBulkDelete": { + "properties": { + "row_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "minItems": 1, + "title": "Row Ids", + "description": "Row ids to delete (must belong to the same call import)." + } + }, + "type": "object", + "required": [ + "row_ids" + ], + "title": "CallImportRowBulkDelete", + "description": "Request body for deleting multiple rows from a call-import batch." + }, + "CallImportRowBulkDeleteResponse": { + "properties": { + "deleted": { + "type": "integer", + "title": "Deleted", + "description": "How many rows were actually removed (unknown ids are skipped)." + }, + "status": { + "type": "string", + "enum": [ + "completed", + "accepted" + ], + "title": "Status", + "description": "``accepted`` when deletion was queued to run asynchronously; ``completed`` when rows were removed before the response.", + "default": "completed" + } + }, + "type": "object", + "required": [ + "deleted" + ], + "title": "CallImportRowBulkDeleteResponse", + "description": "Response after a bulk-delete pass over ``CallImportRow`` rows." + }, + "CallImportTranscribeRequest": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "stt_llm", + "llm_only" + ], + "title": "Mode", + "description": "Pipeline shape. 'stt_llm' (default) runs STT then an LLM diariser over the resulting text. 'llm_only' skips STT and feeds the raw audio to a multimodal LLM together with ``diarization_prompt`` for a single-pass transcribe + diarise.", + "default": "stt_llm" + }, + "stt_provider": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Stt Provider", + "description": "STT provider key, e.g. 'deepgram' or 'openai'. Required when ``mode='stt_llm'``; must be omitted when ``mode='llm_only'``." + }, + "stt_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Stt Model", + "description": "STT model name, e.g. 'nova-2' or 'whisper-1'. Required when ``mode='stt_llm'``; must be omitted when ``mode='llm_only'``." + }, + "credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Credential Id", + "description": "Optional AIProvider/Integration row to pin for this run." + }, + "language": { + "anyOf": [ + { + "type": "string", + "maxLength": 20 + }, + { + "type": "null" + } + ], + "title": "Language", + "description": "Optional ISO language hint, e.g. 'en'." + }, + "only_missing": { + "type": "boolean", + "title": "Only Missing", + "description": "When true, rows with an existing transcript are skipped (the default safe behavior).", + "default": true + }, + "overwrite_existing": { + "type": "boolean", + "title": "Overwrite Existing", + "description": "When true, existing transcripts are replaced. Mutually exclusive with only_missing.", + "default": false + }, + "row_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Row Ids", + "description": "Restrict the run to a specific subset of rows. NULL = every row in the import (subject to only_missing)." + }, + "diarization_llm_provider": { + "type": "string", + "maxLength": 50, + "title": "Diarization Llm Provider", + "description": "LLM provider that diarises the call. In ``stt_llm`` it sees the STT text; in ``llm_only`` it sees the raw audio." + }, + "diarization_llm_model": { + "type": "string", + "maxLength": 100, + "title": "Diarization Llm Model", + "description": "LLM model name. In ``llm_only`` mode this must be a model that accepts audio input (e.g. 'gpt-4o-audio-preview', 'gemini-1.5-pro')." + }, + "diarization_llm_credential_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Diarization Llm Credential Id", + "description": "Optional AIProvider row to pin for the diarisation LLM." + }, + "diarization_prompt": { + "anyOf": [ + { + "type": "string", + "maxLength": 10000 + }, + { + "type": "null" + } + ], + "title": "Diarization Prompt", + "description": "Operator-supplied system prompt for the diariser LLM. When NULL/empty the worker uses the canonical default (see ``GET /api/v1/call-imports/diarisation-prompt-default``)." + } + }, + "type": "object", + "required": [ + "diarization_llm_provider", + "diarization_llm_model" + ], + "title": "CallImportTranscribeRequest", + "description": "Body for kicking off diarization for one or many call-import rows.\n\nThe same shape powers both the per-row endpoint (where ``row_ids``\nis ignored) and the batch-level endpoint. ``only_missing`` is the\nsafe default G๏ฟฝ๏ฟฝ rows with an existing transcript are skipped unless\n``overwrite_existing`` is set.\n\nTwo modes are supported:\n\n* ``mode=\"stt_llm\"`` (default) G๏ฟฝ๏ฟฝ the legacy two-stage pipeline: STT\n produces plain text, an LLM splits it into agent/user turns using\n ``diarization_prompt``. ``stt_provider`` and ``stt_model`` are\n required in this mode.\n* ``mode=\"llm_only\"`` G๏ฟฝ๏ฟฝ skip STT entirely and hand the recording's\n audio bytes to a multimodal chat model along with\n ``diarization_prompt``. The model both transcribes and diarises in\n a single pass. The STT fields are ignored (and must be omitted /\n null). Only providers whose chat API accepts audio input (OpenAI\n ``gpt-4o-audio-*``, Google Gemini ``1.5/2.0``) are usable; other\n providers will surface a typed error on the row." + }, + "CallImportTranscribeResponse": { + "properties": { + "queued": { + "type": "integer", + "title": "Queued", + "description": "How many rows were enqueued for diarization. Skipped rows (missing recording, transcript already present, etc.) are not counted." + }, + "skipped_rows": { + "type": "integer", + "title": "Skipped Rows", + "description": "Rows excluded by only_missing or because they had no recording.", + "default": 0 + }, + "skipped_reason_counts": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Skipped Reason Counts", + "description": "Per-reason breakdown of skipped rows for the UI to surface." + }, + "accepted": { + "type": "boolean", + "title": "Accepted", + "description": "When true, diarization setup was queued to a background worker and ``queued`` reflects zero until the worker finishes enqueue.", + "default": false + } + }, + "type": "object", + "required": [ + "queued" + ], + "title": "CallImportTranscribeResponse", + "description": "Summary of a transcribe fan-out request." + }, + "CallImportRowResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "row_index": { + "type": "integer", + "title": "Row Index" + }, + "conversation_id": { + "type": "string", + "title": "Conversation Id" + }, + "recording_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Recording Url" + }, + "recording_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Recording Date" + }, + "transcript": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Transcript" + }, + "transcript_source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Transcript Source" + }, + "transcript_provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Transcript Provider" + }, + "transcript_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Transcript Model" + }, + "transcript_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Transcript Status" + }, + "transcript_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Transcript Error" + }, + "transcribed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Transcribed At" + }, + "diarised_transcript": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Diarised Transcript" + }, + "diarised_transcript_provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Diarised Transcript Provider" + }, + "diarised_transcript_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Diarised Transcript Model" + }, + "diarised_transcript_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Diarised Transcript Status" + }, + "diarised_transcript_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Diarised Transcript Error" + }, + "diarised_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Diarised At" + }, + "diarised_llm_provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Diarised Llm Provider" + }, + "diarised_llm_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Diarised Llm Model" + }, + "diarised_prompt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Diarised Prompt" + }, + "diarised_segments": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Diarised Segments" + }, + "diarised_speaker_swap": { + "type": "boolean", + "title": "Diarised Speaker Swap", + "default": false + }, + "status": { + "$ref": "#/components/schemas/CallImportRowStatus" + }, + "recording_s3_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Recording S3 Key" + }, + "recording_content_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Recording Content Type" + }, + "recording_size_bytes": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Recording Size Bytes" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "attempts": { + "type": "integer", + "title": "Attempts" + }, + "raw_columns": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Raw Columns" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "row_index", + "conversation_id", + "status", + "attempts", + "created_at", + "updated_at" + ], + "title": "CallImportRowResponse", + "description": "Single row within a call-import batch." + }, + "CallImportCancelDiarisationRequest": { + "properties": { + "row_ids": { + "anyOf": [ + { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Row Ids", + "description": "Optional subset of CallImportRow UUIDs. ``None`` cancels every pending / running diarisation in the import." + } + }, + "type": "object", + "title": "CallImportCancelDiarisationRequest", + "description": "Body for the batch cancel-diarisation endpoint.\n\nOmit ``row_ids`` (or pass ``null``) to cancel every row in the\nimport whose ``diarised_transcript_status`` is currently\n``pending`` or ``running``. Pass an explicit list to scope the\ncancel to a subset (e.g. the rows the operator selected in the\nUI)." + }, + "CallImportCancelDiarisationResponse": { + "properties": { + "cancelled": { + "type": "integer", + "title": "Cancelled", + "description": "Rows whose in-flight Celery task was revoked and whose ``diarised_transcript_status`` was flipped to ``failed`` with a 'Cancelled by user' error message." + }, + "skipped": { + "type": "integer", + "title": "Skipped", + "description": "Rows that were requested but not in a cancellable state (idle / completed / already failed).", + "default": 0 + } + }, + "type": "object", + "required": [ + "cancelled" + ], + "title": "CallImportCancelDiarisationResponse", + "description": "Summary of a cancel-diarisation request.\n\n``cancelled`` counts rows that were actively pending / running\nwhen the cancel landed and got flipped to ``failed`` with a\n\"Cancelled by user\" error. ``skipped`` counts rows that were\nrequested (or matched the implicit \"all rows\" filter) but were\nnot in a cancellable state G๏ฟฝ๏ฟฝ typically because they had already\nfinished or were never queued for diarisation in the first place." + }, + "CallImportInsightsResponse": { + "properties": { + "call_import_id": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + }, + "total_rows": { + "type": "integer", + "title": "Total Rows" + }, + "rows_with_transcript": { + "type": "integer", + "title": "Rows With Transcript" + }, + "rows_without_transcript": { + "type": "integer", + "title": "Rows Without Transcript" + }, + "transcript_source_counts": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Transcript Source Counts" + }, + "evaluation_count": { + "type": "integer", + "title": "Evaluation Count", + "default": 0 + }, + "metrics": { + "items": { + "$ref": "#/components/schemas/CallImportInsightsMetric" + }, + "type": "array", + "title": "Metrics" + } + }, + "type": "object", + "required": [ + "call_import_id", + "total_rows", + "rows_with_transcript", + "rows_without_transcript" + ], + "title": "CallImportInsightsResponse", + "description": "Aggregated cross-run signals for a single call-import batch." + }, + "CallImportSchemaListResponse": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/CallImportSchemaResponse" + }, + "type": "array", + "title": "Items" + }, + "total": { + "type": "integer", + "title": "Total" + } + }, + "type": "object", + "required": [ + "total" + ], + "title": "CallImportSchemaListResponse", + "description": "Paginated list of schemas." + }, + "CallImportSchemaCreate": { + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 2048 + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "parameters": { + "items": { + "$ref": "#/components/schemas/CallImportSchemaParameterCreate" + }, + "type": "array", + "title": "Parameters", + "description": "Ordered list of parameters. Order is preserved; the server stamps ``ordering`` from the list index." + } + }, + "type": "object", + "required": [ + "name", + "parameters" + ], + "title": "CallImportSchemaCreate", + "description": "Create body for a new call-import schema." + }, + "CallImportSchemaResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "organization_id": { + "type": "string", + "format": "uuid", + "title": "Organization Id" + }, + "workspace_id": { + "type": "string", + "format": "uuid", + "title": "Workspace Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "parameters": { + "items": { + "$ref": "#/components/schemas/CallImportSchemaParameterResponse" + }, + "type": "array", + "title": "Parameters" + }, + "usage_count": { + "type": "integer", + "title": "Usage Count", + "default": 0 + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "organization_id", + "workspace_id", + "name", + "created_at", + "updated_at" + ], + "title": "CallImportSchemaResponse", + "description": "Read response for a single schema." + }, + "CallImportSchemaUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 2048 + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "parameters": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/CallImportSchemaParameterCreate" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Parameters", + "description": "If provided, REPLACES the full set of parameters on the schema. Omit to leave parameters untouched." + } + }, + "type": "object", + "title": "CallImportSchemaUpdate", + "description": "Patch body for an existing schema (full parameter replacement)." + }, + "CallImportTagResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Color" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "created_at", + "updated_at" + ], + "title": "CallImportTagResponse", + "description": "Tag attached to call import batches." + }, + "CallImportTagCreate": { + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Name" + }, + "color": { + "anyOf": [ + { + "type": "string", + "maxLength": 32 + }, + { + "type": "null" + } + ], + "title": "Color" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "CallImportTagCreate", + "description": "Create a new call-import tag for the organization." + }, + "CallImportTagUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "color": { + "anyOf": [ + { + "type": "string", + "maxLength": 32 + }, + { + "type": "null" + } + ], + "title": "Color" + } + }, + "type": "object", + "title": "CallImportTagUpdate", + "description": "Partial update for a call-import tag." + }, + "WorkspaceResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "organization_id": { + "type": "string", + "format": "uuid", + "title": "Organization Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "slug": { + "type": "string", + "title": "Slug" + }, + "is_default": { + "type": "boolean", + "title": "Is Default" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + }, + "role_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Role Id" + }, + "role_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role Name" + }, + "capabilities": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Capabilities" + } + }, + "type": "object", + "required": [ + "id", + "organization_id", + "name", + "slug", + "is_default", + "created_at", + "updated_at" + ], + "title": "WorkspaceResponse", + "description": "Response schema for a single workspace." + }, + "WorkspaceCreate": { + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Name" + }, + "slug": { + "anyOf": [ + { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Slug" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "WorkspaceCreate", + "description": "Body for POST /workspaces." + }, + "WorkspaceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string", + "maxLength": 255, + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "WorkspaceUpdate", + "description": "Body for PATCH /workspaces/{id} (rename and/or org-admin activation)." + }, + "AuthProviderConfig": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "display_name": { + "type": "string", + "title": "Display Name" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "supports_password": { + "type": "boolean", + "title": "Supports Password", + "default": false + }, + "supports_signup": { + "type": "boolean", + "title": "Supports Signup", + "default": false + }, + "oidc_issuer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Oidc Issuer" + }, + "oidc_client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Oidc Client Id" + }, + "oidc_authorize_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Oidc Authorize Url" + } + }, + "type": "object", + "required": [ + "name", + "enabled", + "display_name" + ], + "title": "AuthProviderConfig", + "description": "Provider metadata returned to the frontend for login-method discovery." + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "LoginOrgOption": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "type": "string", + "title": "Role" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role" + ], + "title": "LoginOrgOption" + }, + "TestPromptSectionResponse": { + "properties": { + "key": { + "type": "string", + "title": "Key" + }, + "title": { + "type": "string", + "title": "Title" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "key", + "title", + "content" + ], + "title": "TestPromptSectionResponse", + "description": "One canonical section of a generated test agent prompt." + }, + "TestAgentFirstMessageResponse": { + "properties": { + "production_mode": { + "type": "string", + "title": "Production Mode" + }, + "production_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Production Message" + }, + "caller_mode": { + "type": "string", + "title": "Caller Mode" + }, + "caller_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Caller Message" + } + }, + "type": "object", + "required": [ + "production_mode", + "caller_mode" + ], + "title": "TestAgentFirstMessageResponse", + "description": "Who speaks first on production vs test caller sides." + }, + "TestAgentTemplateResponse": { + "properties": { + "sections": { + "items": { + "$ref": "#/components/schemas/TestPromptSectionResponse" + }, + "type": "array", + "title": "Sections" + }, + "first_message": { + "$ref": "#/components/schemas/TestAgentFirstMessageResponse" + } + }, + "type": "object", + "required": [ + "sections", + "first_message" + ], + "title": "TestAgentTemplateResponse", + "description": "Structured test agent template stored on agents." + }, + "GeneratedScenarioDraftResponse": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "description": { + "type": "string", + "title": "Description" + }, + "goal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Goal" + } + }, + "type": "object", + "required": [ + "name", + "description" + ], + "title": "GeneratedScenarioDraftResponse", + "description": "LLM-generated scenario draft before persistence." + }, + "LanguageEnum": { + "type": "string", + "enum": [ + "en", + "es", + "fr", + "de", + "zh", + "ja", + "hi", + "ar" + ], + "title": "LanguageEnum", + "description": "Supported languages" + }, + "CallTypeEnum": { + "type": "string", + "enum": [ + "inbound", + "outbound" + ], + "title": "CallTypeEnum", + "description": "Call direction" + }, + "CallMediumEnum": { + "type": "string", + "enum": [ + "phone_call", + "web_call", + "sip_call" + ], + "title": "CallMediumEnum", + "description": "Call medium" + }, + "TestAgentTemplateInput": { + "properties": { + "sections": { + "items": { + "$ref": "#/components/schemas/TestPromptSectionResponse" + }, + "type": "array", + "title": "Sections" + }, + "first_message": { + "$ref": "#/components/schemas/TestAgentFirstMessageResponse" + } + }, + "type": "object", + "required": [ + "sections", + "first_message" + ], + "title": "TestAgentTemplateInput", + "description": "Structured test agent template for create/update." + }, + "AgentPhoneAssignmentConflict": { + "properties": { + "agent_id": { + "type": "string", + "format": "uuid", + "title": "Agent Id" + }, + "agent_name": { + "type": "string", + "title": "Agent Name" + }, + "phone_number": { + "type": "string", + "title": "Phone Number" + } + }, + "type": "object", + "required": [ + "agent_id", + "agent_name", + "phone_number" + ], + "title": "AgentPhoneAssignmentConflict", + "description": "Another agent already owns this phone number." + }, + "GenderEnum": { + "type": "string", + "enum": [ + "male", + "female", + "neutral" + ], + "title": "GenderEnum", + "description": "Gender options for personas" + }, + "BackgroundNoiseSourceEnum": { + "type": "string", + "enum": [ + "none", + "platform", + "custom" + ], + "title": "BackgroundNoiseSourceEnum", + "description": "Where persona ambient audio is loaded from." + }, + "IntegrationPlatform": { + "type": "string", + "enum": [ + "retell", + "vapi", + "cartesia", + "elevenlabs", + "deepgram", + "murf", + "sarvam", + "voicemaker", + "smallest" + ], + "title": "IntegrationPlatform", + "description": "Integration platform enumeration." + }, + "CredentialRoutingMode": { + "type": "string", + "enum": [ + "inherit", + "gateway", + "direct" + ], + "title": "CredentialRoutingMode", + "description": "Per-credential LLM routing preference." + }, + "VoiceBundleType": { + "type": "string", + "enum": [ + "stt_llm_tts", + "s2s" + ], + "title": "VoiceBundleType", + "description": "VoiceBundle type enumeration." + }, + "ModelProvider": { + "type": "string", + "enum": [ + "openai", + "openrouter", + "anthropic", + "google", + "xai", + "fireworks", + "cohere", + "mistral", + "meta", + "together", + "perplexity", + "azure", + "aws", + "deepgram", + "cartesia", + "elevenlabs", + "murf", + "custom", + "sarvam", + "voicemaker", + "smallest" + ], + "title": "ModelProvider", + "description": "Model provider enumeration for extensibility." + }, + "GatewayInterfaceMode": { + "type": "string", + "enum": [ + "inherit", + "litellm_shim", + "native_openai" + ], + "title": "GatewayInterfaceMode", + "description": "How Bifrost is reached when gateway routing is active." + }, + "EvaluatorSuitePersonaSummary": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "tts_provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tts Provider" + } + }, + "type": "object", + "required": [ + "id" + ], + "title": "EvaluatorSuitePersonaSummary", + "description": "Persona referenced by a suite combination grid." + }, + "EvaluatorSuiteCombinationResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "evaluator_id": { + "type": "string", + "title": "Evaluator Id" + }, + "persona_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Persona Id" + }, + "persona_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Persona Name" + }, + "scenario_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Scenario Id" + }, + "scenario_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scenario Name" + }, + "scenario_description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scenario Description" + }, + "scenario_required_info": { + "anyOf": [ + {}, + { + "type": "null" + } + ], + "title": "Scenario Required Info" + } + }, + "type": "object", + "required": [ + "id", + "evaluator_id" + ], + "title": "EvaluatorSuiteCombinationResponse", + "description": "One agent+persona+scenario combination inside a suite." + }, + "MetricType": { + "type": "string", + "enum": [ + "number", + "boolean", + "rating", + "text" + ], + "title": "MetricType", + "description": "Metric type enumeration.\n\n``TEXT`` is for free-form LLM-generated text (summaries, classifications,\nexplanations) where the value is a string rather than a number/boolean.\nText metrics are *not* aggregated in numeric dashboards." + }, + "MetricCategory": { + "type": "string", + "enum": [ + "quality", + "user_insight" + ], + "title": "MetricCategory", + "description": "High-level grouping for report rendering and call-import insights." + }, + "MetricTrigger": { + "type": "string", + "enum": [ + "always" + ], + "title": "MetricTrigger", + "description": "Metric trigger enumeration." + }, + "MetricGenerateExample": { + "properties": { + "transcript": { + "type": "string", + "title": "Transcript" + }, + "rating": { + "title": "Rating" + }, + "notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Notes" + } + }, + "type": "object", + "required": [ + "transcript", + "rating" + ], + "title": "MetricGenerateExample", + "description": "One labeled example used to infer a metric definition." + }, + "MetricDraft": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "description": { + "type": "string", + "title": "Description" + }, + "metric_type": { + "type": "string", + "enum": [ + "rating", + "boolean", + "number", + "text" + ], + "title": "Metric Type", + "default": "boolean" + }, + "custom_data_type": { + "anyOf": [ + { + "type": "string", + "enum": [ + "boolean", + "enum", + "number_range" + ] + }, + { + "type": "null" + } + ], + "title": "Custom Data Type", + "default": "boolean" + }, + "custom_config": { + "additionalProperties": true, + "type": "object", + "title": "Custom Config" + }, + "supported_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supported Surfaces" + }, + "enabled_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Enabled Surfaces" + }, + "capture_rationale": { + "type": "boolean", + "title": "Capture Rationale", + "default": true + }, + "suggested_tags": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Suggested Tags" + }, + "source_label": { + "$ref": "#/components/schemas/ParsedLabel" + } + }, + "type": "object", + "required": [ + "name", + "description", + "supported_surfaces", + "enabled_surfaces", + "source_label" + ], + "title": "MetricDraft", + "description": "One un-persisted metric draft built from a parsed label.\n\nThe defaults reflect the most common shape of a parsed label\n(\"did happen?\" โ†’ boolean, with a free-form rationale). The user\ncan flip the type / rationale flag in the bulk-import modal before\nsaving each draft to the metrics table." + }, + "MetricParseBulkParentDraft": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "selection_mode": { + "type": "string", + "enum": [ + "single_choice", + "multi_label" + ], + "title": "Selection Mode" + }, + "supported_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supported Surfaces" + }, + "enabled_surfaces": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Enabled Surfaces" + } + }, + "type": "object", + "required": [ + "name", + "selection_mode", + "supported_surfaces", + "enabled_surfaces" + ], + "title": "MetricParseBulkParentDraft", + "description": "Optional parent metric returned when ``parent_name`` was set." + }, + "MetricFailurePolicyMetricPreview": { + "properties": { + "metric_id": { + "type": "string", + "title": "Metric Id" + }, + "metric_name": { + "type": "string", + "title": "Metric Name" + }, + "metric_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Metric Type" + }, + "selection_mode": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Selection Mode" + }, + "is_multi_label_parent": { + "type": "boolean", + "title": "Is Multi Label Parent", + "default": false + }, + "value_counts": { + "items": { + "$ref": "#/components/schemas/MetricFailurePolicyValueCount" + }, + "type": "array", + "title": "Value Counts" + }, + "child_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Child Names" + }, + "row_count_by_value": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Row Count By Value" + }, + "suggested_policy": { + "$ref": "#/components/schemas/MetricFailurePolicy" + }, + "effective_policy": { + "$ref": "#/components/schemas/MetricFailurePolicy" + } + }, + "type": "object", + "required": [ + "metric_id", + "metric_name", + "suggested_policy", + "effective_policy" + ], + "title": "MetricFailurePolicyMetricPreview" + }, + "MetricFailurePolicy": { + "properties": { + "metric_id": { + "type": "string", + "title": "Metric Id" + }, + "failure_values": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Failure Values", + "description": "Normalized lowercase labels that count as failure (single-choice, enum, boolean-as-category)." + }, + "failure_child_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Failure Child Names", + "description": "Child label names that count as failure for multi_label parents." + }, + "numeric_rule": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Numeric Rule", + "description": "Numeric failure rule, e.g. {\"op\": \"lt\", \"threshold\": 0.5}." + } + }, + "type": "object", + "required": [ + "metric_id" + ], + "title": "MetricFailurePolicy", + "description": "Per-metric definition of which scores count as failures for this evaluation." + }, + "MetricClusterEligibleRow": { + "properties": { + "evaluation_row_id": { + "type": "string", + "format": "uuid", + "title": "Evaluation Row Id" + }, + "conversation_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Conversation Id" + }, + "row_index": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Row Index" + }, + "flagged_metric_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Flagged Metric Names" + } + }, + "type": "object", + "required": [ + "evaluation_row_id" + ], + "title": "MetricClusterEligibleRow", + "description": "Completed evaluation row with at least one flagged quality metric." + }, + "EvaluatorResultClusterScopeSummary": { + "properties": { + "job_id": { + "type": "string", + "format": "uuid", + "title": "Job Id" + }, + "scope_key": { + "type": "string", + "title": "Scope Key" + }, + "generation_scope": { + "$ref": "#/components/schemas/MetricClusterGenerationScope" + }, + "status": { + "type": "string", + "enum": [ + "idle", + "running", + "completed", + "failed", + "cancelled" + ], + "title": "Status", + "default": "idle" + }, + "generated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Generated At" + }, + "is_stale": { + "type": "boolean", + "title": "Is Stale", + "default": false + }, + "has_results": { + "type": "boolean", + "title": "Has Results", + "default": false + } + }, + "type": "object", + "required": [ + "job_id", + "scope_key", + "generation_scope" + ], + "title": "EvaluatorResultClusterScopeSummary", + "description": "Workspace cluster report keyed by agent/scenario/date scope." + }, + "MetricClusterGroup": { + "properties": { + "metric_id": { + "type": "string", + "title": "Metric Id" + }, + "metric_name": { + "type": "string", + "title": "Metric Name" + }, + "flagged_count": { + "type": "integer", + "title": "Flagged Count", + "default": 0 + }, + "failure_reason": { + "type": "string", + "title": "Failure Reason", + "default": "" + }, + "clusters": { + "items": { + "$ref": "#/components/schemas/MetricCluster" + }, + "type": "array", + "title": "Clusters" + } + }, + "type": "object", + "required": [ + "metric_id", + "metric_name" + ], + "title": "MetricClusterGroup" + }, + "DiscoveredProblemCluster": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "gap_label": { + "type": "string", + "enum": [ + "LOGIC_GAP", + "UNDERSPEC", + "EXISTS_NO_TRIGGER", + "MISSING" + ], + "title": "Gap Label" + }, + "count": { + "type": "integer", + "title": "Count", + "default": 0 + }, + "share_pct": { + "type": "number", + "title": "Share Pct", + "default": 0 + }, + "observation": { + "type": "string", + "title": "Observation", + "default": "" + }, + "failure_reason": { + "type": "string", + "title": "Failure Reason", + "default": "" + }, + "evidence": { + "$ref": "#/components/schemas/MetricClusterEvidence" + } + }, + "type": "object", + "required": [ + "id", + "label", + "gap_label" + ], + "title": "DiscoveredProblemCluster" + }, + "MetricClustersRcaSummary": { + "properties": { + "total_clusters": { + "type": "integer", + "title": "Total Clusters", + "default": 0 + }, + "total_clustered_instances": { + "type": "integer", + "title": "Total Clustered Instances", + "default": 0 + }, + "total_flagged_instances": { + "type": "integer", + "title": "Total Flagged Instances", + "default": 0 + }, + "analysed_calls": { + "type": "integer", + "title": "Analysed Calls", + "default": 0 + }, + "repeated_patterns": { + "items": { + "$ref": "#/components/schemas/RcaRepeatedPatternRow" + }, + "type": "array", + "title": "Repeated Patterns" + }, + "metric_hotspots": { + "items": { + "$ref": "#/components/schemas/RcaMetricHotspotRow" + }, + "type": "array", + "title": "Metric Hotspots" + }, + "prompt_areas": { + "items": { + "$ref": "#/components/schemas/RcaPromptAreaRow" + }, + "type": "array", + "title": "Prompt Areas" + } + }, + "type": "object", + "title": "MetricClustersRcaSummary" + }, + "MetricClusterGenerationScope": { + "properties": { + "agent_id": { + "type": "string", + "format": "uuid", + "title": "Agent Id" + }, + "agent_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Agent Name" + }, + "scenario_ids": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Scenario Ids" + }, + "scenario_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Scenario Names" + }, + "since": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Since" + }, + "until": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Until" + }, + "eligible_call_count": { + "type": "integer", + "title": "Eligible Call Count", + "default": 0 + }, + "selected_call_count": { + "type": "integer", + "title": "Selected Call Count", + "default": 0 + } + }, + "type": "object", + "required": [ + "agent_id" + ], + "title": "MetricClusterGenerationScope", + "description": "Snapshot of agent/scenario/date scope used for a cluster generation run." + }, + "EvaluatorResultCounts": { + "properties": { + "total": { + "type": "integer", + "title": "Total", + "default": 0 + }, + "completed": { + "type": "integer", + "title": "Completed", + "default": 0 + }, + "failed": { + "type": "integer", + "title": "Failed", + "default": 0 + }, + "in_progress": { + "type": "integer", + "title": "In Progress", + "default": 0 + }, + "last_run_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Run At" + } + }, + "type": "object", + "title": "EvaluatorResultCounts", + "description": "Rollup counts for evaluator result navigation." + }, + "EvaluatorResultsAgentSummary": { + "properties": { + "agent_id": { + "type": "string", + "format": "uuid", + "title": "Agent Id" + }, + "agent_name": { + "type": "string", + "title": "Agent Name" + }, + "counts": { + "$ref": "#/components/schemas/EvaluatorResultCounts" + }, + "suites": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/EvaluatorResultsSuiteSummary" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Suites" + } + }, + "type": "object", + "required": [ + "agent_id", + "agent_name", + "counts" + ], + "title": "EvaluatorResultsAgentSummary" + }, + "EvaluatorResultsUnassignedSummary": { + "properties": { + "counts": { + "$ref": "#/components/schemas/EvaluatorResultCounts" + }, + "recent_result_ids": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Recent Result Ids" + } + }, + "type": "object", + "required": [ + "counts" + ], + "title": "EvaluatorResultsUnassignedSummary" + }, + "CallImportMetricAggregate": { + "properties": { + "metric_id": { + "type": "string", + "title": "Metric Id" + }, + "metric_name": { + "type": "string", + "title": "Metric Name" + }, + "metric_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Metric Type" + }, + "metric_category": { + "type": "string", + "title": "Metric Category", + "default": "quality" + }, + "is_multi_label_parent": { + "type": "boolean", + "title": "Is Multi Label Parent", + "default": false + }, + "count": { + "type": "integer", + "title": "Count", + "default": 0 + }, + "skipped_count": { + "type": "integer", + "title": "Skipped Count", + "default": 0 + }, + "error_count": { + "type": "integer", + "title": "Error Count", + "default": 0 + }, + "mean": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Mean" + }, + "median": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median" + }, + "p25": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "P25" + }, + "p75": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "P75" + }, + "p95": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "P95" + }, + "min": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Min" + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Max" + }, + "stddev": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Stddev" + }, + "histogram_buckets": { + "items": { + "$ref": "#/components/schemas/CallImportMetricHistogramBucket" + }, + "type": "array", + "title": "Histogram Buckets" + }, + "value_counts": { + "items": { + "$ref": "#/components/schemas/CallImportMetricValueCount" + }, + "type": "array", + "title": "Value Counts" + }, + "co_occurrence": { + "items": { + "$ref": "#/components/schemas/CallImportMetricLabelPair" + }, + "type": "array", + "title": "Co Occurrence" + } + }, + "type": "object", + "required": [ + "metric_id", + "metric_name" + ], + "title": "CallImportMetricAggregate", + "description": "Per-metric aggregate computed from an evaluation run's rows.\n\nNumeric metrics return summary statistics + histogram buckets;\ncategorical / pass-fail / text metrics return the top value counts.\nBoth shapes can coexist if a metric mixes types G๏ฟฝ๏ฟฝ the UI prefers\nhistogram when present, falls back to value_counts otherwise." + }, + "EvaluatorResultStatus": { + "type": "string", + "enum": [ + "queued", + "call_initiating", + "call_connecting", + "call_in_progress", + "call_ended", + "fetching_details", + "transcribing", + "evaluating", + "completed", + "failed" + ], + "title": "EvaluatorResultStatus", + "description": "Evaluator result status enumeration." + }, + "CallImportPreviewSheet": { + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "Sheet name for xlsx; filename for csv." + }, + "headers": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Headers", + "description": "Column headers from the first non-empty row." + }, + "row_count": { + "type": "integer", + "title": "Row Count", + "description": "Approximate count of data rows (excluding the header row)." + } + }, + "type": "object", + "required": [ + "name", + "row_count" + ], + "title": "CallImportPreviewSheet", + "description": "One worksheet (or one CSV file synthesized as a single sheet)." + }, + "CallImportSourceRowSkip": { + "properties": { + "source_row": { + "type": "integer", + "title": "Source Row", + "description": "1-based row index in the source file (same semantics as parse errors)." + }, + "reason": { + "type": "string", + "title": "Reason", + "description": "Machine-readable skip reason, e.g. missing_conversation_id, missing_recording_url, invalid_recording_url." + }, + "message": { + "type": "string", + "title": "Message", + "description": "Human-readable explanation shown in the UI." + } + }, + "type": "object", + "required": [ + "source_row", + "reason", + "message" + ], + "title": "CallImportSourceRowSkip", + "description": "One source spreadsheet row skipped during parse (identity / recording URL)." + }, + "CallImportDispatchLimitSnapshot": { + "properties": { + "global_limit": { + "type": "integer", + "title": "Global Limit" + }, + "global_inflight": { + "type": "integer", + "title": "Global Inflight" + }, + "global_at_capacity": { + "type": "boolean", + "title": "Global At Capacity" + }, + "org_limit": { + "type": "integer", + "title": "Org Limit" + }, + "org_inflight": { + "type": "integer", + "title": "Org Inflight" + }, + "org_at_capacity": { + "type": "boolean", + "title": "Org At Capacity" + }, + "workspace_limit": { + "type": "integer", + "title": "Workspace Limit" + }, + "job_limit": { + "type": "integer", + "title": "Job Limit" + }, + "fair_dispatch_batch_size": { + "type": "integer", + "title": "Fair Dispatch Batch Size" + } + }, + "type": "object", + "required": [ + "global_limit", + "global_inflight", + "global_at_capacity", + "org_limit", + "org_inflight", + "org_at_capacity", + "workspace_limit", + "job_limit", + "fair_dispatch_batch_size" + ], + "title": "CallImportDispatchLimitSnapshot", + "description": "Configured and live Redis in-flight caps for eval work." + }, + "CallImportDispatchFairDispatchSnapshot": { + "properties": { + "global_rr_cursor": { + "type": "integer", + "title": "Global Rr Cursor" + }, + "dispatch_dedupe_active": { + "type": "boolean", + "title": "Dispatch Dedupe Active" + }, + "dispatch_queue": { + "type": "string", + "title": "Dispatch Queue" + }, + "at_capacity_backoff_seconds": { + "type": "integer", + "title": "At Capacity Backoff Seconds" + } + }, + "type": "object", + "required": [ + "global_rr_cursor", + "dispatch_dedupe_active", + "dispatch_queue", + "at_capacity_backoff_seconds" + ], + "title": "CallImportDispatchFairDispatchSnapshot", + "description": "Fair-dispatch scheduler metadata from Redis." + }, + "CallImportDispatchWorkspaceSnapshot": { + "properties": { + "workspace_id": { + "type": "string", + "format": "uuid", + "title": "Workspace Id" + }, + "workspace_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Workspace Name" + }, + "workspace_slug": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Workspace Slug" + }, + "inflight": { + "type": "integer", + "title": "Inflight" + }, + "inflight_at_capacity": { + "type": "boolean", + "title": "Inflight At Capacity" + }, + "pending_dispatch_rows": { + "type": "integer", + "title": "Pending Dispatch Rows" + }, + "pending_import_rows": { + "type": "integer", + "title": "Pending Import Rows" + }, + "eval_rr_cursor": { + "type": "integer", + "title": "Eval Rr Cursor" + }, + "active_evaluations": { + "type": "integer", + "title": "Active Evaluations" + }, + "evaluations": { + "items": { + "$ref": "#/components/schemas/CallImportDispatchEvaluationSnapshot" + }, + "type": "array", + "title": "Evaluations" + } + }, + "type": "object", + "required": [ + "workspace_id", + "inflight", + "inflight_at_capacity", + "pending_dispatch_rows", + "pending_import_rows", + "eval_rr_cursor", + "active_evaluations" + ], + "title": "CallImportDispatchWorkspaceSnapshot", + "description": "Per-workspace pending dispatch + slot usage." + }, + "CallImportRowStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "CallImportRowStatus", + "description": "Status of an individual call-import row." + }, + "CallImportInsightsMetric": { + "properties": { + "metric_id": { + "type": "string", + "title": "Metric Id" + }, + "metric_name": { + "type": "string", + "title": "Metric Name" + }, + "metric_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Metric Type" + }, + "latest": { + "anyOf": [ + { + "$ref": "#/components/schemas/CallImportMetricAggregate" + }, + { + "type": "null" + } + ] + }, + "trend": { + "items": { + "$ref": "#/components/schemas/CallImportInsightsRunPoint" + }, + "type": "array", + "title": "Trend" + } + }, + "type": "object", + "required": [ + "metric_id", + "metric_name" + ], + "title": "CallImportInsightsMetric", + "description": "Per-metric history across every evaluation run on this import." + }, + "CallImportSchemaParameterCreate": { + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Name", + "description": "Parameter name as it appears in the schema editor and the upload mapping table. Must be unique within the schema (case-insensitive)." + }, + "type": { + "$ref": "#/components/schemas/CallImportParameterType", + "description": "Parameter type. One of conversation_id / recording_url / recording_date / transcript / text / number / boolean / datetime / url. Exactly one parameter of type 'conversation_id' must be present; at most one each of 'recording_url', 'recording_date', and 'transcript'. Only conversation_id is forced required." + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 2048 + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "Free-text help shown next to the parameter in the mapping UI." + }, + "is_required": { + "type": "boolean", + "title": "Is Required", + "description": "When True, the parameter must be mapped to a CSV column on every upload. The ``conversation_id`` parameter is always required and is force-set to True by the server.", + "default": false + } + }, + "type": "object", + "required": [ + "name", + "type" + ], + "title": "CallImportSchemaParameterCreate", + "description": "Create payload for a single parameter (inside a schema CRUD body)." + }, + "CallImportSchemaParameterResponse": { + "properties": { + "name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Name", + "description": "Parameter name as it appears in the schema editor and the upload mapping table. Must be unique within the schema (case-insensitive)." + }, + "type": { + "$ref": "#/components/schemas/CallImportParameterType", + "description": "Parameter type. One of conversation_id / recording_url / recording_date / transcript / text / number / boolean / datetime / url. Exactly one parameter of type 'conversation_id' must be present; at most one each of 'recording_url', 'recording_date', and 'transcript'. Only conversation_id is forced required." + }, + "description": { + "anyOf": [ + { + "type": "string", + "maxLength": 2048 + }, + { + "type": "null" + } + ], + "title": "Description", + "description": "Free-text help shown next to the parameter in the mapping UI." + }, + "is_required": { + "type": "boolean", + "title": "Is Required", + "description": "When True, the parameter must be mapped to a CSV column on every upload. The ``conversation_id`` parameter is always required and is force-set to True by the server.", + "default": false + }, + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "ordering": { + "type": "integer", + "title": "Ordering" + } + }, + "type": "object", + "required": [ + "name", + "type", + "id", + "ordering" + ], + "title": "CallImportSchemaParameterResponse", + "description": "Response shape including the persisted id + ordering." + }, + "ParsedLabel": { + "properties": { + "label_name": { + "type": "string", + "title": "Label Name" + }, + "definition": { + "type": "string", + "title": "Definition", + "default": "" + }, + "examples": { + "type": "string", + "title": "Examples", + "default": "" + } + }, + "type": "object", + "required": [ + "label_name" + ], + "title": "ParsedLabel", + "description": "One label parsed out of the bulk prompt." + }, + "MetricFailurePolicyValueCount": { + "properties": { + "label": { + "type": "string", + "title": "Label" + }, + "count": { + "type": "integer", + "title": "Count", + "default": 0 + } + }, + "type": "object", + "required": [ + "label" + ], + "title": "MetricFailurePolicyValueCount" + }, + "MetricCluster": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "gap_label": { + "type": "string", + "enum": [ + "LOGIC_GAP", + "UNDERSPEC", + "EXISTS_NO_TRIGGER", + "MISSING" + ], + "title": "Gap Label" + }, + "level": { + "type": "integer", + "title": "Level", + "default": 1 + }, + "count": { + "type": "integer", + "title": "Count", + "default": 0 + }, + "share_pct": { + "type": "number", + "title": "Share Pct", + "default": 0 + }, + "sub_clusters": { + "items": { + "$ref": "#/components/schemas/MetricSubCluster" + }, + "type": "array", + "title": "Sub Clusters" + }, + "observation": { + "type": "string", + "title": "Observation", + "default": "" + }, + "failure_reason": { + "type": "string", + "title": "Failure Reason", + "default": "" + }, + "evidence": { + "$ref": "#/components/schemas/MetricClusterEvidence" + }, + "is_discovered": { + "type": "boolean", + "title": "Is Discovered", + "default": false + } + }, + "type": "object", + "required": [ + "id", + "label", + "gap_label" + ], + "title": "MetricCluster" + }, + "MetricClusterEvidence": { + "properties": { + "conversation_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Conversation Id" + }, + "evaluation_row_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Evaluation Row Id" + }, + "quote": { + "type": "string", + "title": "Quote", + "default": "" + }, + "turns": { + "items": { + "$ref": "#/components/schemas/MetricClusterEvidenceTurn" + }, + "type": "array", + "title": "Turns" + } + }, + "type": "object", + "title": "MetricClusterEvidence" + }, + "RcaRepeatedPatternRow": { + "properties": { + "metric_id": { + "type": "string", + "title": "Metric Id" + }, + "metric_name": { + "type": "string", + "title": "Metric Name" + }, + "top_rca_patterns": { + "type": "string", + "title": "Top Rca Patterns", + "default": "" + }, + "evidence_share_pct": { + "type": "number", + "title": "Evidence Share Pct", + "default": 0 + }, + "evidence_calls": { + "type": "integer", + "title": "Evidence Calls", + "default": 0 + }, + "evidence_cluster_count": { + "type": "integer", + "title": "Evidence Cluster Count", + "default": 0 + }, + "failure_reason": { + "type": "string", + "title": "Failure Reason", + "default": "" + } + }, + "type": "object", + "required": [ + "metric_id", + "metric_name" + ], + "title": "RcaRepeatedPatternRow" + }, + "RcaMetricHotspotRow": { + "properties": { + "metric_id": { + "type": "string", + "title": "Metric Id" + }, + "metric_name": { + "type": "string", + "title": "Metric Name" + }, + "description": { + "type": "string", + "title": "Description", + "default": "" + }, + "metric_rate_pct": { + "type": "number", + "title": "Metric Rate Pct", + "default": 0 + }, + "flagged_calls": { + "type": "integer", + "title": "Flagged Calls", + "default": 0 + } + }, + "type": "object", + "required": [ + "metric_id", + "metric_name" + ], + "title": "RcaMetricHotspotRow" + }, + "RcaPromptAreaRow": { + "properties": { + "label": { + "type": "string", + "title": "Label" + }, + "share_pct": { + "type": "number", + "title": "Share Pct", + "default": 0 + }, + "gap_label": { + "type": "string", + "enum": [ + "LOGIC_GAP", + "UNDERSPEC", + "EXISTS_NO_TRIGGER", + "MISSING" + ], + "title": "Gap Label" + } + }, + "type": "object", + "required": [ + "label", + "gap_label" + ], + "title": "RcaPromptAreaRow" + }, + "EvaluatorResultsSuiteSummary": { + "properties": { + "suite_id": { + "type": "string", + "format": "uuid", + "title": "Suite Id" + }, + "suite_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Suite Name" + }, + "agent_id": { + "type": "string", + "format": "uuid", + "title": "Agent Id" + }, + "persona_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Persona Id" + }, + "counts": { + "$ref": "#/components/schemas/EvaluatorResultCounts" + }, + "scenarios": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/EvaluatorResultsScenarioSummary" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Scenarios" + } + }, + "type": "object", + "required": [ + "suite_id", + "agent_id", + "counts" + ], + "title": "EvaluatorResultsSuiteSummary" + }, + "CallImportMetricHistogramBucket": { + "properties": { + "x0": { + "type": "number", + "title": "X0" + }, + "x1": { + "type": "number", + "title": "X1" + }, + "count": { + "type": "integer", + "title": "Count" + } + }, + "type": "object", + "required": [ + "x0", + "x1", + "count" + ], + "title": "CallImportMetricHistogramBucket", + "description": "One bin of a numeric metric histogram." + }, + "CallImportMetricValueCount": { + "properties": { + "label": { + "type": "string", + "title": "Label" + }, + "count": { + "type": "integer", + "title": "Count" + } + }, + "type": "object", + "required": [ + "label", + "count" + ], + "title": "CallImportMetricValueCount", + "description": "One row of a categorical metric's value frequency table." + }, + "CallImportMetricLabelPair": { + "properties": { + "a": { + "type": "string", + "title": "A" + }, + "b": { + "type": "string", + "title": "B" + }, + "count": { + "type": "integer", + "title": "Count" + } + }, + "type": "object", + "required": [ + "a", + "b", + "count" + ], + "title": "CallImportMetricLabelPair", + "description": "One unordered pair-count cell of a multi-label parent's\nco-occurrence matrix.\n\n``a`` and ``b`` are child label names; ``count`` is the number of\nrows on which both labels fired together (intersection size).\nPairs are emitted with ``a < b`` lexicographically so the matrix\ncan be reconstructed without duplicates on the frontend." + }, + "CallImportDispatchEvaluationSnapshot": { + "properties": { + "evaluation_id": { + "type": "string", + "format": "uuid", + "title": "Evaluation Id" + }, + "call_import_id": { + "type": "string", + "format": "uuid", + "title": "Call Import Id" + }, + "status": { + "type": "string", + "title": "Status" + }, + "total_rows": { + "type": "integer", + "title": "Total Rows" + }, + "pending_rows": { + "type": "integer", + "title": "Pending Rows" + }, + "running_rows": { + "type": "integer", + "title": "Running Rows" + }, + "job_inflight": { + "type": "integer", + "title": "Job Inflight" + }, + "job_at_capacity": { + "type": "boolean", + "title": "Job At Capacity" + } + }, + "type": "object", + "required": [ + "evaluation_id", + "call_import_id", + "status", + "total_rows", + "pending_rows", + "running_rows", + "job_inflight", + "job_at_capacity" + ], + "title": "CallImportDispatchEvaluationSnapshot", + "description": "One in-flight evaluation run with row counters." + }, + "CallImportInsightsRunPoint": { + "properties": { + "evaluation_id": { + "type": "string", + "format": "uuid", + "title": "Evaluation Id" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "mean": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Mean" + }, + "completed_rows": { + "type": "integer", + "title": "Completed Rows", + "default": 0 + } + }, + "type": "object", + "required": [ + "evaluation_id", + "created_at" + ], + "title": "CallImportInsightsRunPoint", + "description": "One run's mean for a metric, used to render trend lines." + }, + "CallImportParameterType": { + "type": "string", + "enum": [ + "conversation_id", + "recording_url", + "recording_date", + "transcript", + "text", + "number", + "boolean", + "datetime", + "url" + ], + "title": "CallImportParameterType", + "description": "Allowed types for a :class:`CallImportSchemaParameter`.\n\nThe first four values feed dedicated columns on\n:class:`CallImportRow` (``conversation_id``, ``recording_url``,\n``recording_date``, ``transcript``); the rest are generic typed text fields whose values\nare preserved per row in ``raw_columns`` and surfaced under the\nparameter name in the evaluation export." + }, + "MetricSubCluster": { + "properties": { + "id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "count": { + "type": "integer", + "title": "Count", + "default": 0 + }, + "share_pct": { + "type": "number", + "title": "Share Pct", + "default": 0 + } + }, + "type": "object", + "required": [ + "label" + ], + "title": "MetricSubCluster" + }, + "MetricClusterEvidenceTurn": { + "properties": { + "speaker": { + "type": "string", + "title": "Speaker" + }, + "text": { + "type": "string", + "title": "Text" + } + }, + "type": "object", + "required": [ + "speaker", + "text" + ], + "title": "MetricClusterEvidenceTurn" + }, + "EvaluatorResultsScenarioSummary": { + "properties": { + "scenario_id": { + "type": "string", + "format": "uuid", + "title": "Scenario Id" + }, + "scenario_name": { + "type": "string", + "title": "Scenario Name" + }, + "counts": { + "$ref": "#/components/schemas/EvaluatorResultCounts" + } + }, + "type": "object", + "required": [ + "scenario_id", + "scenario_name", + "counts" + ], + "title": "EvaluatorResultsScenarioSummary" + } + }, + "parameters": { + "WorkspaceIdHeader": { + "name": "X-Workspace-Id", + "in": "header", + "required": false, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "Optional workspace scope. When omitted, the backend uses the active/default workspace from your organization context." + } + }, + "securitySchemes": { + "BearerAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT", + "description": "JWT access token. Use: Authorization: Bearer ." + }, + "ApiKeyAuth": { + "type": "apiKey", + "in": "header", + "name": "X-API-Key", + "description": "Organization API key generated from the authentication/settings surface." + } + } + }, + "tags": [ + { + "name": "Authentication", + "description": "Session and API-key authentication endpoints.", + "x-displayName": "Authentication" + }, + { + "name": "Workspaces", + "description": "Workspace management endpoints.", + "x-displayName": "Workspaces" + }, + { + "name": "Integrations", + "description": "Voice, telephony, and provider integration endpoints.", + "x-displayName": "Integrations" + }, + { + "name": "agents", + "description": "Agent configuration and lifecycle endpoints.", + "x-displayName": "Agents" + }, + { + "name": "personas", + "description": "Persona management endpoints.", + "x-displayName": "Personas" + }, + { + "name": "scenarios", + "description": "Scenario creation and management endpoints.", + "x-displayName": "Scenarios" + }, + { + "name": "evaluators", + "description": "Evaluator configuration endpoints.", + "x-displayName": "Evaluators" + }, + { + "name": "evaluator-suites", + "description": "Suite-level test combination management endpoints.", + "x-displayName": "Evaluator Suites" + }, + { + "name": "evaluator-results", + "description": "Run and score retrieval endpoints.", + "x-displayName": "Evaluator Results" + }, + { + "name": "metrics", + "description": "Metric definition and execution endpoints.", + "x-displayName": "Metrics" + }, + { + "name": "observability", + "description": "Call logs, traces, and observability endpoints.", + "x-displayName": "Observability" + }, + { + "name": "Call Imports", + "description": "Historical call import workflows.", + "x-displayName": "Call Imports" + }, + { + "name": "voicebundles", + "description": "Voice bundle configuration endpoints.", + "x-displayName": "Voice Bundles" + }, + { + "name": "aiproviders", + "description": "Provider and model credentials endpoints.", + "x-displayName": "AI Providers" + } + ], + "security": [ + { + "BearerAuth": [] + }, + { + "ApiKeyAuth": [] + } + ], + "servers": [ + { + "url": "http://localhost:8000", + "description": "Self-hosted" + } + ] +} diff --git a/docs-fumadocs/package-lock.json b/docs-fumadocs/package-lock.json index f5ee5a0c..2749c5f2 100644 --- a/docs-fumadocs/package-lock.json +++ b/docs-fumadocs/package-lock.json @@ -9,13 +9,17 @@ "version": "0.0.0", "hasInstallScript": true, "dependencies": { - "fumadocs-core": "16.8.11", + "fumadocs-core": "16.15.9", "fumadocs-mdx": "15.0.4", - "fumadocs-ui": "16.8.11", + "fumadocs-openapi": "^11.4.2", + "fumadocs-ui": "16.15.9", "lucide-react": "^1.14.0", + "mermaid": "^12.0.0", "next": "16.2.6", + "next-themes": "^0.4.6", "react": "^19.2.6", "react-dom": "^19.2.6", + "shiki": "^4.4.3", "tailwind-merge": "^3.6.0" }, "devDependencies": { @@ -44,6 +48,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@antfu/install-pkg": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-2.0.1.tgz", + "integrity": "sha512-iCKVQcIC0e3oDxEfs3SHQGW+ovhBMZmS1TE+bTk50rVyMCBmCfClv7Qi3HQKlumYwvjb/iIMeWCW2i67q6kFfQ==", + "license": "MIT", + "dependencies": { + "package-manager-detector": "^1.7.0", + "tinyexec": "^1.2.4" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", @@ -236,6 +253,14 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", @@ -284,10 +309,114 @@ "node": ">=6.9.0" } }, + "node_modules/@base-ui/react": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@base-ui/react/-/react-1.8.0.tgz", + "integrity": "sha512-P0/1sxo6SBVZOklKMIedvTWqw2s2IQzi9x5bIVsXu980cuSOD4NeuRSs+/L7LZQfDkZP/uRZyGPyfFl/B1oH+Q==", + "dependencies": { + "@babel/runtime": "^7.29.7", + "@base-ui/utils": "0.4.0", + "@floating-ui/react-dom": "^2.1.9", + "@floating-ui/utils": "^0.2.12", + "use-sync-external-store": "^1.6.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@date-fns/tz": "^1.2.0", + "@types/react": "^17 || ^18 || ^19", + "date-fns": "^4.0.0", + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@date-fns/tz": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "date-fns": { + "optional": true + } + } + }, + "node_modules/@base-ui/utils": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@base-ui/utils/-/utils-0.4.0.tgz", + "integrity": "sha512-bO9fz25kKtPf+aZVyfQrC0PDmJdmVni31W2hCS5/Owb+inwdIL3XU26pCPRPlt4LSxZrBgLwubXQXQlKaFEZzw==", + "dependencies": { + "@babel/runtime": "^7.29.7", + "@floating-ui/utils": "^0.2.12", + "reselect": "^5.2.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "@types/react": "^17 || ^18 || ^19", + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@braintree/sanitize-url": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz", + "integrity": "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==", + "license": "MIT" + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.1.2.tgz", + "integrity": "sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/gast": "11.1.2", + "@chevrotain/types": "11.1.2", + "lodash-es": "4.17.23" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.1.2.tgz", + "integrity": "sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/types": "11.1.2", + "lodash-es": "4.17.23" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.1.2.tgz", + "integrity": "sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/types": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.1.2.tgz", + "integrity": "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/utils": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.1.2.tgz", + "integrity": "sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==", + "license": "Apache-2.0" + }, "node_modules/@emnapi/core": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -309,6 +438,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -839,31 +969,31 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", - "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.11" + "@floating-ui/utils": "^0.2.12" } }, "node_modules/@floating-ui/dom": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", - "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.7.5", - "@floating-ui/utils": "^0.2.11" + "@floating-ui/core": "^1.8.0", + "@floating-ui/utils": "^0.2.12" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", - "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", + "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.7.6" + "@floating-ui/dom": "^1.8.0" }, "peerDependencies": { "react": ">=16.8.0", @@ -871,29 +1001,107 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", - "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", "license": "MIT" }, - "node_modules/@fumadocs/tailwind": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@fumadocs/tailwind/-/tailwind-0.0.5.tgz", - "integrity": "sha512-ENKPWUDRmriccsrUDE4bDBq3FNr/ms3BP2rWlsAEMV1yP23pcCaan+ceGfeBUsAQjw7sj9Q3R4Kl3g/TCStPzQ==", + "node_modules/@fuma-translate/react": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@fuma-translate/react/-/react-1.0.2.tgz", + "integrity": "sha512-uOiOtBx3nRXR8Nu1GzBf1tApgF1FErDBTHxRIAQeyQdyOoZbrNRN6H4kDCWObY4qyGeGbHydG0DHzgeUgFDMIw==", "license": "MIT", "peerDependencies": { - "@tailwindcss/oxide": "^4.0.0", - "tailwindcss": "^4.0.0" + "@types/react": "*", + "react": "^19.2.0", + "react-dom": "^19.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@fumadocs/api-docs": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@fumadocs/api-docs/-/api-docs-0.2.9.tgz", + "integrity": "sha512-auLnmkiE9pvajLX/FMMc07HQ5LB126OPRFwpAZXrFcRAdq2Pw3qIOwe3OiFZslox2CvOxcyoYCAsKm7gmY05kw==", + "dependencies": { + "@base-ui/react": "^1.8.0", + "@fuma-translate/react": "^1.0.2", + "@fumari/stf": "1.1.1", + "@scalar/json-magic": "^0.13.4", + "class-variance-authority": "^0.7.1", + "cn": "^0.2.6", + "github-slugger": "^2.0.0", + "lucide-react": "^1.43.0" + }, + "peerDependencies": { + "@types/react": "*", + "fumadocs-core": "^16.9.0", + "fumadocs-ui": "^16.9.0", + "json-schema-typed": "*", + "react": "^19.2.0", + "react-dom": "^19.2.0" }, "peerDependenciesMeta": { - "@tailwindcss/oxide": { + "@types/react": { "optional": true }, + "json-schema-typed": { + "optional": true + } + } + }, + "node_modules/@fumadocs/tailwind": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@fumadocs/tailwind/-/tailwind-0.1.1.tgz", + "integrity": "sha512-BnPe52UxSaG8yKlHMKBxXw8h6GpK5qO55ci6+Qd5JnquTvIw6SpfbC1P+qAi82PuPWv1KZAWY8bxRk4+x9ctXw==", + "license": "MIT", + "peerDependencies": { + "tailwindcss": "^4.0.0" + }, + "peerDependenciesMeta": { "tailwindcss": { "optional": true } } }, + "node_modules/@fumari/image-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@fumari/image-size/-/image-size-0.1.0.tgz", + "integrity": "sha512-x2o9u6P8uKUK15B8XgEoRhR3PgLoLSbQKK6FUCd14JzumEw+e8FXZPelij/dZ4VQVMp4r61VD3DcvSo3aEhLAA==", + "license": "MIT" + }, + "node_modules/@fumari/json-schema-ts": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@fumari/json-schema-ts/-/json-schema-ts-1.0.2.tgz", + "integrity": "sha512-1NHGl8Oqg50mhpWMvbhqnwFRLBugkGCRubLSH/TrAzTAS99x4z0xFgOVcbJne+yfaZv94ZNdmRWobDvUiZswPg==", + "license": "MIT", + "peerDependencies": { + "json-schema-typed": "*" + }, + "peerDependenciesMeta": { + "json-schema-typed": { + "optional": true + } + } + }, + "node_modules/@fumari/stf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@fumari/stf/-/stf-1.1.1.tgz", + "integrity": "sha512-W0ISkQFwwX438CYlBxAe3OdCdPRSlHWVNizB1q4ICzrQKR9AYhGZuvKYo+HukSpgaMCUt++cM7VEa4VtSA8rhg==", + "peerDependencies": { + "@types/react": "*", + "react": "^19.2.0", + "react-dom": "^19.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@humanfs/core": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", @@ -960,6 +1168,23 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@iconify/utils": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.7.tgz", + "integrity": "sha512-JZHlwdID+dy+lTgbYC8NEC4zeugqeYsc6jewvzb4c58kHauJn+X7rNwQjxz5p2qSjqaEeQoLkCIQ9v/H4PK0/w==", + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^2.0.1", + "@iconify/types": "^2.0.0", + "import-meta-resolve": "^4.2.0" + } + }, "node_modules/@img/colour": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", @@ -1513,10 +1738,23 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/@mermaid-js/parser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-2.0.0.tgz", + "integrity": "sha512-K8BeapFUfrfxbRAUQAG5oBOCwo1+bNWzaVnPxTCutkfrTBn6T/j91FIhqxWJ32SUeQ9T3iy1zcmPZ5ROZEvDrg==", + "license": "MIT", + "dependencies": { + "@chevrotain/types": "~11.1.2" + }, + "engines": { + "node": ">=22.12.0" + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -1717,42 +1955,33 @@ "node": ">=12.4.0" } }, - "node_modules/@orama/orama": { - "version": "3.1.18", - "resolved": "https://registry.npmjs.org/@orama/orama/-/orama-3.1.18.tgz", - "integrity": "sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA==", - "license": "Apache-2.0", - "engines": { - "node": ">= 20.0.0" - } - }, "node_modules/@radix-ui/number": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", - "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.3.tgz", + "integrity": "sha512-Road2bidD0uu/1BGDOWNdPI06g0lIRy6IF9GZcIrDK2KGItfor8IQwQa+yM2ERgHM1MmHxaxpTzk0/Jp42lNfA==", "license": "MIT" }, "node_modules/@radix-ui/primitive": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", - "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.7.tgz", + "integrity": "sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q==", "license": "MIT" }, "node_modules/@radix-ui/react-accordion": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", - "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "version": "1.2.20", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.20.tgz", + "integrity": "sha512-jDhG9FvAEnlhnjrsINbNXcUa4G+L1KqSkJSunkbKEzFRcAb52jvM0PjPxPRvhe1HNc5F5yc0yzzWeeqlH4yBIg==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collapsible": "1.1.12", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-collapsible": "1.1.20", + "@radix-ui/react-collection": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-controllable-state": "1.2.6" }, "peerDependencies": { "@types/react": "*", @@ -1770,12 +1999,12 @@ } }, "node_modules/@radix-ui/react-arrow": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", - "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.15.tgz", + "integrity": "sha512-v4zggRcjadnI+ClKDuijlQEW4tw3NoaeHc/PwpKnLoLLKNUG4InLegkstooLcRIUWCs+8L22dGURCVuFfOKfnA==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.1.10" }, "peerDependencies": { "@types/react": "*", @@ -1793,19 +2022,19 @@ } }, "node_modules/@radix-ui/react-collapsible": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", - "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.20.tgz", + "integrity": "sha512-mcGesGplBnzN2sbvJETzpCNfSMyPnb29q1GRLU+Ib7bJrpIG2ywmRoh2V5VbA2uNvKikKUlVbAPks7JDjz4A8Q==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -1823,15 +2052,15 @@ } }, "node_modules/@radix-ui/react-collection": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.15.tgz", + "integrity": "sha512-9W+B9NPF0NaaPh/1NJd3+KqsnlLqU9H7T2rvww+fp+T/evVXdNAyYcnfRQZFOjkR1ajQp3yORlqnI8soawLvNA==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3" }, "peerDependencies": { "@types/react": "*", @@ -1848,28 +2077,10 @@ } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.5.tgz", + "integrity": "sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1882,9 +2093,9 @@ } }, "node_modules/@radix-ui/react-context": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", - "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.2.2.tgz", + "integrity": "sha512-RHCUGwKHDr0hDGg4X7ma4JG4/+12qxw8rkh5QKdDldlCvtja6nUx1Ef/8HVrJze81lEsgLQlqjzjGNHantgnQA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1897,25 +2108,26 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", - "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", + "version": "1.1.23", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.23.tgz", + "integrity": "sha512-Ksw4WeROkO4rC9k/onilX/Ao2Cr1ku1unMNH+XSCcP4jSXYu7HDsg9n4ojMjVb22XpYjAQ9qfrFlVbru1vXDUA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-focus-guards": "1.1.6", + "@radix-ui/react-focus-scope": "1.1.16", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-layout-effect": "1.1.4", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -1932,28 +2144,10 @@ } } }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-direction": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", - "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.4.tgz", + "integrity": "sha512-5pzg4FGQNpExhnhT2zlrP1wZFaYCd1K0nYWoFAdcYoYK868IEigqMX3B3f8yIoRlAhAeDWciLI6ZdCKHF9P4Vg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1966,16 +2160,16 @@ } }, "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", - "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.19.tgz", + "integrity": "sha512-8g4pfOL9HoKKLWGiypT+dphVqjFfmcXO5GBnhsG6zI+lxAx/8feQpr+1LSN8Re3hiZ+XkLNS4O9ztK11/LzQ6w==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-escape-keydown": "1.1.1" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-effect-event": "0.0.5" }, "peerDependencies": { "@types/react": "*", @@ -1993,9 +2187,9 @@ } }, "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", - "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.6.tgz", + "integrity": "sha512-RNOJjfZMTyBM6xYmV3IVGXkPjIhcBAuv48POevAXwrGJhkWZ9p1rFoIS1JFooPuT193AZmRsCPhpoVJxx6OPoQ==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2008,14 +2202,14 @@ } }, "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", - "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.16.tgz", + "integrity": "sha512-wmRZ2WWLvmt6KHy2rNPOdPUjwq5xOHY02+m+udwJTn0aNIox/rkskAvJTyTLGhPK6KgrUjlJUJpgmx/+wFiFIQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1" + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2033,12 +2227,12 @@ } }, "node_modules/@radix-ui/react-id": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", - "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.4.tgz", + "integrity": "sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2051,25 +2245,25 @@ } }, "node_modules/@radix-ui/react-navigation-menu": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.14.tgz", - "integrity": "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-visually-hidden": "1.2.3" + "version": "1.2.22", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.22.tgz", + "integrity": "sha512-ou7iLEJ+yrhQndkkA4U21XIdS/CS45F4iXIkTZcb6/Ne9EMsOuDudVmCwmDnfFZZ+y1FZqXRNSIgBy+YMvZVZg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-collection": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-previous": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.11" }, "peerDependencies": { "@types/react": "*", @@ -2087,26 +2281,26 @@ } }, "node_modules/@radix-ui/react-popover": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", - "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", + "version": "1.1.23", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.23.tgz", + "integrity": "sha512-mw58MrBlyHWFisTOYignD0vf/3gdcgAR+9of1s9G/38CbFiUwH1nCDkc0AUM9IrXFgN5Ue8n45j9WCgyM1sbiQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-focus-guards": "1.1.6", + "@radix-ui/react-focus-scope": "1.1.16", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.3.7", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-controllable-state": "1.2.6", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -2123,40 +2317,22 @@ } } }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-popper": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", - "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.3.7.tgz", + "integrity": "sha512-UsJrrd7w4wuKKTdvd/DNERVlwSlUcyXzjhyDwBk+3aPOsCjOY6ZSbxuw8E6lZTjjfP8Cpd0J8VVkrYUWyGYXyg==", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-rect": "1.1.1", - "@radix-ui/react-use-size": "1.1.1", - "@radix-ui/rect": "1.1.1" + "@radix-ui/react-arrow": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-rect": "1.1.4", + "@radix-ui/react-use-size": "1.1.4", + "@radix-ui/rect": "1.1.3" }, "peerDependencies": { "@types/react": "*", @@ -2174,13 +2350,13 @@ } }, "node_modules/@radix-ui/react-portal": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", - "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.17.tgz", + "integrity": "sha512-vKQLcWypUnwZVvfV7UkGahH2g6ySe8M8R+zYBwPrv5byZ9QAW6cQVvNKo7GgmD+p8aYb6D9JBuvy8/WhOno2wQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2198,13 +2374,12 @@ } }, "node_modules/@radix-ui/react-presence": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", - "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.10.tgz", + "integrity": "sha512-3wyzCQ6+ubRA+D4uv9m95JYLXxmOHp05qjrkjeA7uKHHtjpPggQzc6DAb0URl7j67oR0K2foO4ip27TiX037Bw==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2222,12 +2397,12 @@ } }, "node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.10.tgz", + "integrity": "sha512-MucOnzh6hR5mid6VpkbglRAMYMjKLqRnGBbjXkzjK52fuQDd1qbkx78a5P40mkcnVXJdEVxm26E9OPAiUq7nBg==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-slot": "1.3.3" }, "peerDependencies": { "@types/react": "*", @@ -2244,39 +2419,23 @@ } } }, - "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", - "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2" + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.19.tgz", + "integrity": "sha512-V9jI6hDjT7l3jsCQD9bLNvDLM3tH/gdbOTp7Tefp3hbbgCGQoK7tUvrWiRlcoBHIZ809ElXwNQwVo0B98LuTXQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-collection": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-is-hydrated": "0.1.3", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2294,20 +2453,20 @@ } }, "node_modules/@radix-ui/react-scroll-area": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", - "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", + "version": "1.2.18", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.18.tgz", + "integrity": "sha512-Zn5Cd171wxsO3Dfg8HaW6RifTb9CYTKQJHs/G4+LN1GfmJpaQMZQyQxMprVPHpaz7QY4l9BxK2JwQuzHsXC8nA==", "license": "MIT", "dependencies": { - "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/number": "1.1.3", + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2325,12 +2484,12 @@ } }, "node_modules/@radix-ui/react-slot": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", - "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.3.tgz", + "integrity": "sha512-qx7oqnYbxnK9kYI9m317qmFmEgo6ywqWvbTogdj7cL9p3/yx4M48p7Rnw5z3H890cL/ow/EeWJsuTykeZVXP5Q==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" + "@radix-ui/react-compose-refs": "1.1.5" }, "peerDependencies": { "@types/react": "*", @@ -2343,19 +2502,19 @@ } }, "node_modules/@radix-ui/react-tabs": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", - "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.21.tgz", + "integrity": "sha512-UKxJlZid7FVtsk/WTxj4i4uSEgj2Au+KBbS7SQyTlzMhhn+86Cz3tISZdTa87bfEfcuvZezf2ZsxD4xuEKtkog==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-roving-focus": "1.1.19", + "@radix-ui/react-use-controllable-state": "1.2.6" }, "peerDependencies": { "@types/react": "*", @@ -2373,9 +2532,9 @@ } }, "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", - "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.4.tgz", + "integrity": "sha512-R6OUY2e2fA6Yn6s+VSx5KBV6Nx8LQEhu+cz7LCej18rQ1HLyg9PSC9jP/ZNx0o6FAIK9c0F1kHylzSxKsdlkrQ==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2388,13 +2547,14 @@ } }, "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", - "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.6.tgz", + "integrity": "sha512-uEQJGT97ZA/TgP/Hydw47lHu+/vQj6z/0jA+WeTbK1o9Rx45GImjpD0tc3W5ad3D6XTSR6e1yEO0FvGq6WQfVQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-effect-event": "0.0.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-use-effect-event": "0.0.5", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2407,12 +2567,12 @@ } }, "node_modules/@radix-ui/react-use-effect-event": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", - "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.5.tgz", + "integrity": "sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2424,14 +2584,11 @@ } } }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", - "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.3.tgz", + "integrity": "sha512-umO/aJ+82CpOnhDZUTbILCQf7kU/g0iv+oGs/Q8jw7IkhWBzaEP4sA268PhFAJTFetbwp3ICc6ktpI4TqtxcIw==", "license": "MIT", - "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.1" - }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -2443,9 +2600,9 @@ } }, "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", - "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.4.tgz", + "integrity": "sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2458,9 +2615,9 @@ } }, "node_modules/@radix-ui/react-use-previous": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", - "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.4.tgz", + "integrity": "sha512-XoSLhbRbqxFtgJoi2fNHA3C6pDlY34x508vUpUGoFZfvePfHXHbE1lC4FYFMnJWgiCRroSTw6fOsXQoVS9RwZg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2473,12 +2630,12 @@ } }, "node_modules/@radix-ui/react-use-rect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", - "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.4.tgz", + "integrity": "sha512-cSOCh6JlkmfjLyNcLiu2nB4v+nm+dkZ+Q5KHWk/soo4U7ZLiEQFKHK9/YmtBHjfCEaU43IBKQOc4/uJmCaiCTQ==", "license": "MIT", "dependencies": { - "@radix-ui/rect": "1.1.1" + "@radix-ui/rect": "1.1.3" }, "peerDependencies": { "@types/react": "*", @@ -2491,12 +2648,12 @@ } }, "node_modules/@radix-ui/react-use-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", - "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.4.tgz", + "integrity": "sha512-D3anSY15EJoxrihpsXI6SMrmmonnQtR2ni7arO+Lfdg3O95b9hNXxONk8jA5C8ANdF/h5HMAxejgs8PWJ6rlhw==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2509,12 +2666,12 @@ } }, "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", - "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.11.tgz", + "integrity": "sha512-NFS86RYYZb4/exihaESBGOpMJFz8MGLAfu3mOBSGByVnVPC9JPASfYubxd/8KbkQK0sYAv8lVQDEQukDX/qXvQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.1.10" }, "peerDependencies": { "@types/react": "*", @@ -2532,9 +2689,9 @@ } }, "node_modules/@radix-ui/rect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", - "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.3.tgz", + "integrity": "sha512-JtyZR+mqgBibTo8xea3B6ZRmzZiM/YeVBtUkas6zMuXjAlfIFIW2FgqeM9eLyvEaYX66vr6DJMK+4U6LV0KhNw==", "license": "MIT" }, "node_modules/@rtsao/scc": { @@ -2544,43 +2701,65 @@ "dev": true, "license": "MIT" }, - "node_modules/@shikijs/core": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.0.2.tgz", - "integrity": "sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw==", - "license": "MIT", + "node_modules/@scalar/helpers": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@scalar/helpers/-/helpers-0.12.0.tgz", + "integrity": "sha512-rcX0rFLiWWc0VBr/E+HkatubL0I0ZzxASQkd3032NWEMAEfNd2TiJ9kH46HwbSAOOl696ghxymWegjpjjvxwzA==", + "engines": { + "node": ">=22" + } + }, + "node_modules/@scalar/json-magic": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/@scalar/json-magic/-/json-magic-0.13.5.tgz", + "integrity": "sha512-w5eENfKAkc4CYiLva3nGUhTaJfyi3szmZ3E7+EHlzahOUnbDmB9rAWyzt8GFCXbwxeTuR+1m7lO1PyV/QAid4A==", "dependencies": { - "@shikijs/primitive": "4.0.2", - "@shikijs/types": "4.0.2", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4", - "hast-util-to-html": "^9.0.5" + "@scalar/helpers": "0.12.0", + "pathe": "^2.0.3", + "undici": "7.24.4", + "yaml": "^2.9.0" }, "engines": { - "node": ">=20" + "node": ">=22" + } + }, + "node_modules/@shikijs/core": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.4.3.tgz", + "integrity": "sha512-QCR4q2ZO/ILJEuwiBMel4wdcTDb1JGwfjKTxPDF6x8ixOaluPrVqIn06C99AcRPhmYlBR56d/Fb+GN58GzExpg==", + "license": "MIT", + "dependencies": { + "@shikijs/primitive": "4.4.3", + "@shikijs/types": "4.4.3", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.5", + "hast-util-to-html": "^9.0.5" + }, + "engines": { + "node": ">=20" } }, "node_modules/@shikijs/engine-javascript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.0.2.tgz", - "integrity": "sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.4.3.tgz", + "integrity": "sha512-FbOjFJp9VLdo1Wevs10BBtVxiTWwNLqZh5Gkhjgda/ioL15YOgeSl9n+6XMa3qRlPQzfhFNe641SrynFHYG0nQ==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.0.2", + "@shikijs/types": "4.4.3", "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^4.3.4" + "oniguruma-to-es": "^4.3.6" }, "engines": { "node": ">=20" } }, "node_modules/@shikijs/engine-oniguruma": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.0.2.tgz", - "integrity": "sha512-UpCB9Y2sUKlS9z8juFSKz7ZtysmeXCgnRF0dlhXBkmQnek7lAToPte8DkxmEYGNTMii72zU/lyXiCB6StuZeJg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.4.3.tgz", + "integrity": "sha512-EcOQkxdxGQrc1Row/cC2c96/v1dbZqGnEVu1qTuT/MJmp6+cXCvQussowVmCv5Tqr3KuY3c7IbM6HTW3LJ1k9w==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.0.2", + "@shikijs/types": "4.4.3", "@shikijs/vscode-textmate": "^10.0.2" }, "engines": { @@ -2588,51 +2767,51 @@ } }, "node_modules/@shikijs/langs": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.0.2.tgz", - "integrity": "sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.4.3.tgz", + "integrity": "sha512-ePic0yfAJGOF83D5wBHK/00EjK65oahBYxFk5epgq33WRv7X9UuxLEV8PtR0szC0z8dl7INIpIodB99JRFlR+A==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.0.2" + "@shikijs/types": "4.4.3" }, "engines": { "node": ">=20" } }, "node_modules/@shikijs/primitive": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.0.2.tgz", - "integrity": "sha512-M6UMPrSa3fN5ayeJwFVl9qWofl273wtK1VG8ySDZ1mQBfhCpdd8nEx7nPZ/tk7k+TYcpqBZzj/AnwxT9lO+HJw==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.4.3.tgz", + "integrity": "sha512-m0wBeLDQDeIxRdUmrCPdQqfuUamDwRL5isCfYbguKD6NiaKpVbsv+3J81DyIKgNW5h4WAIIr8T4EkgQrBBxvaQ==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.0.2", + "@shikijs/types": "4.4.3", "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" + "@types/hast": "^3.0.5" }, "engines": { "node": ">=20" } }, "node_modules/@shikijs/themes": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.0.2.tgz", - "integrity": "sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.4.3.tgz", + "integrity": "sha512-w8UHjeUnIR965KMWJHUPXOc2mNJUnK3vpVLYLvw5IYU2mnTTJ89E24OrJDBNiJDQ0qzb0tc4l7mrIXx5cFeIyw==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.0.2" + "@shikijs/types": "4.4.3" }, "engines": { "node": ">=20" } }, "node_modules/@shikijs/types": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.0.2.tgz", - "integrity": "sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.4.3.tgz", + "integrity": "sha512-UEJxmRR++MAGR6hugn0vgVS2W/6lWAts84FFSrnlH9sP0LNol7E5+NQ792pH8liWUhyMyjhTgSUH3k7iD7tc5g==", "license": "MIT", "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" + "@types/hast": "^3.0.5" }, "engines": { "node": ">=20" @@ -2679,7 +2858,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.0.tgz", "integrity": "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">= 20" @@ -2706,6 +2885,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2722,6 +2902,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2738,6 +2919,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2754,6 +2936,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2770,6 +2953,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2786,6 +2970,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2802,6 +2987,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2818,6 +3004,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2834,6 +3021,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2858,6 +3046,7 @@ "cpu": [ "wasm32" ], + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -2879,6 +3068,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2895,6 +3085,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2922,12 +3113,266 @@ "version": "0.10.2", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", + "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-65Emv9fQiQQqphLlRkuQ5ypPsOmWPhtBGCMv61JDPEPMvsx+gzhGf74yw1a78xFKPj6zw4AgQICJoQv0vK9M2w==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.4.tgz", + "integrity": "sha512-UHYId5WTCx4L4YNel7NU00XUXXgvgpgZOvp10PuvsQENjMDXhh2RyFc0KBjO7B45ne4Ha1yVH7ii0vnzKkuzWA==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.13", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", @@ -2959,10 +3404,16 @@ "@types/estree": "*" } }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT" + }, "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", "license": "MIT", "dependencies": { "@types/unist": "*" @@ -3033,6 +3484,13 @@ "@types/react": "^19.2.0" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -3557,6 +4015,16 @@ "win32" ] }, + "node_modules/@upsetjs/venn.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@upsetjs/venn.js/-/venn.js-2.0.0.tgz", + "integrity": "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==", + "license": "MIT", + "optionalDependencies": { + "d3-selection": "^3.0.0", + "d3-transition": "^3.0.1" + } + }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", @@ -4057,6 +4525,20 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/chevrotain": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.1.2.tgz", + "integrity": "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.1.2", + "@chevrotain/gast": "11.1.2", + "@chevrotain/regexp-to-ast": "11.1.2", + "@chevrotain/types": "11.1.2", + "@chevrotain/utils": "11.1.2", + "lodash-es": "4.17.23" + } + }, "node_modules/chokidar": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", @@ -4096,70 +4578,599 @@ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=6" + } + }, + "node_modules/cn": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/cn/-/cn-0.2.6.tgz", + "integrity": "sha512-+i4L0zUGgRcEnhsxueVrP7iBGxBx5iD0WOTYg1MwFEu2ZyCmH5Ov2V1cul2Ht5UchRQQgftCf4be/RxspuW6QQ==", + "license": "MIT", + "bin": { + "cn": "bin/cn.mjs" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/compute-scroll-into-view": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz", + "integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "license": "MIT", + "dependencies": { + "layout-base": "^1.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/cytoscape": { + "version": "3.34.3", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.34.3.tgz", + "integrity": "sha512-yfYGhRcGAntq6YBD583j4n0Eg3jIxvWmZtz/5uz9UYkeIStSlMxuUja+ec5j3iBD8nv1rwaOAYMW09tBdkSeaQ==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "license": "MIT", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", + "license": "MIT" + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "license": "BSD-3-Clause", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "license": "ISC" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" } }, - "node_modules/collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" } }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" } }, - "node_modules/compute-scroll-into-view": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz", - "integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" }, "engines": { - "node": ">= 8" + "node": ">=12" } }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "devOptional": true, - "license": "MIT" + "node_modules/dagre-d3-es": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz", + "integrity": "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==", + "license": "MIT", + "dependencies": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -4222,6 +5233,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/dayjs": { + "version": "1.11.23", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.23.tgz", + "integrity": "sha512-QDTCU0M0MxR3hQfnlDJfwekQiaanm1ubOD231u73WBckQ/fsamwRLiE2GBz6D3a/xF1NgfiDLJjXBa1hYOYTtQ==", + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -4295,6 +5312,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delaunator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.1.0.tgz", + "integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -4346,6 +5372,15 @@ "node": ">=0.10.0" } }, + "node_modules/dompurify": { + "version": "3.4.15", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.15.tgz", + "integrity": "sha512-EUBjM+B+lkDE41iE82DDSCfkoPGfXx8IxFxPMjNzm/Uk4xDet77rTN9wqlxlVg71kK7XGuUMv6wUxJUwwv+Xyw==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -4368,6 +5403,12 @@ "dev": true, "license": "ISC" }, + "node_modules/elkjs": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", + "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==", + "license": "EPL-2.0" + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -4578,6 +5619,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-toolkit": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.52.0.tgz", + "integrity": "sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks", + "tests/types", + "tests/browser-compat" + ] + }, "node_modules/esast-util-from-estree": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", @@ -5364,24 +6417,20 @@ } }, "node_modules/framer-motion": { - "version": "12.38.0", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz", - "integrity": "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-13.2.0.tgz", + "integrity": "sha512-9E33ebgMaO33w1nN/jEdW8z3/GO483fMi4rqbMG9rt83XgW9QLKRe4NcmJ8s+fQ3O34++UHrIQwlIWGIWTITjA==", "license": "MIT", "dependencies": { - "motion-dom": "^12.38.0", - "motion-utils": "^12.36.0", + "motion-dom": "^13.2.0", + "motion-utils": "^13.0.0", "tslib": "^2.4.0" }, "peerDependencies": { - "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, "react": { "optional": true }, @@ -5391,32 +6440,35 @@ } }, "node_modules/fumadocs-core": { - "version": "16.8.11", - "resolved": "https://registry.npmjs.org/fumadocs-core/-/fumadocs-core-16.8.11.tgz", - "integrity": "sha512-HphKuDwPXgVsmRd82Bu5VHZZ8b7uR4ewgCUbUewhElNKIJXDPuyt7ju6LTQbD0E0Sos/cAN5k40Ym1agOirquA==", + "version": "16.15.9", + "resolved": "https://registry.npmjs.org/fumadocs-core/-/fumadocs-core-16.15.9.tgz", + "integrity": "sha512-aefFBU1e9w+pX23qpM2QT9g99hhGYe7fV1H19A8ozcyU9DqW0iBL3kH9/c6wMKOnVd643xaY8JzMdSiVA7XKIA==", "license": "MIT", "dependencies": { - "@orama/orama": "^3.1.18", + "@fumari/image-size": "^0.1.0", "estree-util-value-to-estree": "^3.5.0", "github-slugger": "^2.0.0", "hast-util-to-estree": "^3.1.3", "hast-util-to-jsx-runtime": "^2.3.6", - "js-yaml": "^4.1.1", "mdast-util-mdx": "^3.0.0", "mdast-util-to-markdown": "^2.1.2", + "npm-to-yarn": "3.2.0", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-rehype": "^11.1.2", "scroll-into-view-if-needed": "^3.1.0", - "shiki": "^4.0.2", - "tinyglobby": "^0.2.16", + "shiki": "^4.4.3", + "tinyglobby": "^0.2.17", "unified": "^11.0.5", "unist-util-visit": "^5.1.0", - "vfile": "^6.0.3" + "vfile": "^6.0.3", + "yaml": "^2.9.0", + "zbsearch": "^4.0.0" }, "peerDependencies": { "@mdx-js/mdx": "*", "@mixedbread/sdk": "0.x.x", + "@modelcontextprotocol/server": "2.x.x", "@orama/core": "1.x.x", "@oramacloud/client": "2.x.x", "@tanstack/react-router": "1.x.x", @@ -5430,7 +6482,7 @@ "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", - "react-router": "7.x.x", + "react-router": "7.x.x || 8.x.x", "waku": "*", "zod": "4.x.x" }, @@ -5441,6 +6493,9 @@ "@mixedbread/sdk": { "optional": true }, + "@modelcontextprotocol/server": { + "optional": true + }, "@orama/core": { "optional": true }, @@ -5555,47 +6610,87 @@ } } }, + "node_modules/fumadocs-openapi": { + "version": "11.4.3", + "resolved": "https://registry.npmjs.org/fumadocs-openapi/-/fumadocs-openapi-11.4.3.tgz", + "integrity": "sha512-U30oRZ2PKRWRVl7iH83Y2JUhC12V134UF1dADvdRY3+urCQf7C7s/mk6eOe4/v4kPmjVGPkxvuVZsC5ZIGCr7A==", + "dependencies": { + "@fuma-translate/react": "^1.0.2", + "@fumadocs/api-docs": "0.2.9", + "@fumari/json-schema-ts": "^1.0.2", + "@fumari/stf": "1.1.1", + "@scalar/json-magic": "^0.13.4", + "chokidar": "^5.0.0", + "class-variance-authority": "^0.7.1", + "cn": "^0.2.6", + "github-slugger": "^2.0.0", + "hast-util-to-jsx-runtime": "^2.3.6", + "lucide-react": "^1.43.0", + "remark": "^15.0.1", + "remark-rehype": "^11.1.2", + "shiki": "^4.4.3", + "yaml": "^2.9.0" + }, + "peerDependencies": { + "@scalar/api-client-react": "^2.0.20", + "@types/react": "*", + "fumadocs-core": "^16.15.0", + "fumadocs-ui": "^16.15.0", + "json-schema-typed": "*", + "react": "^19.2.0", + "react-dom": "^19.2.0" + }, + "peerDependenciesMeta": { + "@scalar/api-client-react": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "json-schema-typed": { + "optional": true + } + } + }, "node_modules/fumadocs-ui": { - "version": "16.8.11", - "resolved": "https://registry.npmjs.org/fumadocs-ui/-/fumadocs-ui-16.8.11.tgz", - "integrity": "sha512-+yQVy1/wPLuw6X7plmz8fiuQu/xJd8pCEApUoUXaB14Ts658GC+1bXuz97yDFslL0uLrA6y2yAaaMdztNlLeeQ==", - "license": "MIT", - "dependencies": { - "@fumadocs/tailwind": "0.0.5", - "@radix-ui/react-accordion": "^1.2.12", - "@radix-ui/react-collapsible": "^1.1.12", - "@radix-ui/react-dialog": "^1.1.15", - "@radix-ui/react-direction": "^1.1.1", - "@radix-ui/react-navigation-menu": "^1.2.14", - "@radix-ui/react-popover": "^1.1.15", - "@radix-ui/react-presence": "^1.1.5", - "@radix-ui/react-scroll-area": "^1.2.10", - "@radix-ui/react-slot": "^1.2.4", - "@radix-ui/react-tabs": "^1.1.13", + "version": "16.15.9", + "resolved": "https://registry.npmjs.org/fumadocs-ui/-/fumadocs-ui-16.15.9.tgz", + "integrity": "sha512-enwf49j9VzJLKD9Lkr2nQJiHMIMCk8on5MzlTE63KawdW5gPJh8t8qYTFhPtAcg5xSTdfP8I0Dbdr5B3Qtmk2g==", + "license": "MIT", + "dependencies": { + "@fuma-translate/react": "^1.0.2", + "@fumadocs/tailwind": "0.1.1", + "@radix-ui/react-accordion": "^1.2.20", + "@radix-ui/react-collapsible": "^1.1.20", + "@radix-ui/react-dialog": "^1.1.23", + "@radix-ui/react-direction": "^1.1.4", + "@radix-ui/react-navigation-menu": "^1.2.22", + "@radix-ui/react-popover": "^1.1.23", + "@radix-ui/react-presence": "^1.1.10", + "@radix-ui/react-scroll-area": "^1.2.18", + "@radix-ui/react-slot": "^1.3.3", + "@radix-ui/react-tabs": "^1.1.21", "class-variance-authority": "^0.7.1", - "lucide-react": "^1.14.0", - "motion": "^12.38.0", + "cn": "^0.2.6", + "lucide-react": "^1.43.0", + "motion": "^13.2.0", "next-themes": "^0.4.6", "react-remove-scroll": "^2.7.2", "rehype-raw": "^7.0.0", "scroll-into-view-if-needed": "^3.1.0", - "shiki": "^4.0.2", - "tailwind-merge": "^3.6.0", + "shiki": "^4.4.3", "unist-util-visit": "^5.1.0" }, "peerDependencies": { - "@takumi-rs/image-response": "*", "@types/mdx": "*", "@types/react": "*", - "fumadocs-core": "16.8.11", + "fumadocs-core": "16.15.9", "next": "16.x.x", "react": "^19.2.0", - "react-dom": "^19.2.0" + "react-dom": "^19.2.0", + "takumi-js": "*" }, "peerDependenciesMeta": { - "@takumi-rs/image-response": { - "optional": true - }, "@types/mdx": { "optional": true }, @@ -5604,6 +6699,9 @@ }, "next": { "optional": true + }, + "takumi-js": { + "optional": true } } }, @@ -5816,6 +6914,12 @@ "dev": true, "license": "ISC" }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", + "license": "MIT" + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -6112,6 +7216,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -6122,6 +7238,16 @@ "node": ">= 4" } }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6153,6 +7279,15 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/is-alphabetical": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", @@ -6748,6 +7883,31 @@ "node": ">=4.0" } }, + "node_modules/katex": { + "version": "0.16.47", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz", + "integrity": "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -6758,6 +7918,11 @@ "json-buffer": "3.0.1" } }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -6778,6 +7943,12 @@ "node": ">=0.10" } }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", + "license": "MIT" + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -7069,6 +8240,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash-es": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz", + "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==", + "license": "MIT" + }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -7103,9 +8280,9 @@ } }, "node_modules/lucide-react": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.14.0.tgz", - "integrity": "sha512-+1mdWcfSJVUsaTIjN9zoezmUhfXo5l0vP7ekBMPo3jcS/aIkxHnXqAPsByszMZx/Y8oQBRJxJx5xg+RH3urzxA==", + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.45.0.tgz", + "integrity": "sha512-yH1ubCAduho9UR7oJhRXIQXogksRILBiTuZC4/bQIGeB9JOkxMlSuEHyyZpo1Z3S0yWJO2KTSUZbjiNvVxeOUw==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -7143,6 +8320,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", + "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -7462,6 +8651,40 @@ "node": ">= 8" } }, + "node_modules/mermaid": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-12.0.0.tgz", + "integrity": "sha512-/wQXC9iBxoGV8p3erbvaXs9h77VyLDBH6GdayVjj3hEcSQhFU4N1WUhUppotCEqlIxI2pRMwjwBSwTB1MfZBgQ==", + "license": "MIT", + "dependencies": { + "@braintree/sanitize-url": "^7.1.2", + "@iconify/utils": "^3.0.2", + "@mermaid-js/parser": "^2.0.0", + "@types/d3": "^7.4.3", + "@upsetjs/venn.js": "^2.0.0", + "chevrotain": "~11.1.2", + "cytoscape": "^3.34.0", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.14", + "dayjs": "^1.11.21", + "dompurify": "^3.4.12", + "elkjs": "^0.9.3", + "es-toolkit": "^1.45.1", + "katex": "^0.16.47", + "khroma": "^2.1.0", + "marked": "^16.3.0", + "roughjs": "^4.6.6", + "stylis": "^4.3.6", + "ts-dedent": "^2.2.0", + "uuid": "^11.1.0 || ^12 || ^13 || ^14.0.0" + }, + "engines": { + "node": ">=22.12.0" + } + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -8233,23 +9456,19 @@ } }, "node_modules/motion": { - "version": "12.38.0", - "resolved": "https://registry.npmjs.org/motion/-/motion-12.38.0.tgz", - "integrity": "sha512-uYfXzeHlgThchzwz5Te47dlv5JOUC7OB4rjJ/7XTUgtBZD8CchMN8qEJ4ZVsUmTyYA44zjV0fBwsiktRuFnn+w==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/motion/-/motion-13.2.0.tgz", + "integrity": "sha512-4Hrb5vD6HhjFstLUiCmWvtpsw+WTpP4R+QXfSDYZBz7+uxE/LrRg3aV0ReJxHrTRffHhbIE6svEqnotngXvesQ==", "license": "MIT", "dependencies": { - "framer-motion": "^12.38.0", + "framer-motion": "^13.2.0", "tslib": "^2.4.0" }, "peerDependencies": { - "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, "react": { "optional": true }, @@ -8259,18 +9478,18 @@ } }, "node_modules/motion-dom": { - "version": "12.38.0", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.38.0.tgz", - "integrity": "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-13.2.0.tgz", + "integrity": "sha512-N6gdSoWRDk0Rh/fVtlqUtLs+fEN3ELFZI3cn3IQE9Mnf3E+Mh8wjO6MstzCOPFh4Yf0L1as5m2eUyYWj8ylVSQ==", "license": "MIT", "dependencies": { - "motion-utils": "^12.36.0" + "motion-utils": "^13.0.0" } }, "node_modules/motion-utils": { - "version": "12.36.0", - "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.36.0.tgz", - "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-13.0.0.tgz", + "integrity": "sha512-7DnN7TmbLcYXcG4RVadXIihWlyuM9afoUww8Y5Agg431kGKiuL2/OMyP4mJ5wLz+pvN3t5ySClLOaVXJ+wekRQ==", "license": "MIT" }, "node_modules/ms": { @@ -8437,6 +9656,18 @@ "dev": true, "license": "MIT" }, + "node_modules/npm-to-yarn": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/npm-to-yarn/-/npm-to-yarn-3.2.0.tgz", + "integrity": "sha512-K1HmQeZT2HrjpsR6KgqbN2FAXL2NrJJmNUSD9ck7HGTVu1JKXox8n9SB+tjbU8m8JGLF4OscrroPepew/L7/Xw==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/nebrelbug/npm-to-yarn?sponsor=1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -8645,6 +9876,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-manager-detector": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.8.0.tgz", + "integrity": "sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==", + "license": "MIT" + }, "node_modules/parse-entities": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", @@ -8682,6 +9919,12 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==", + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8709,6 +9952,11 @@ "dev": true, "license": "MIT" }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -8727,6 +9975,22 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", + "license": "MIT" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "license": "MIT", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -9200,6 +10464,11 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/reselect": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.3.0.tgz", + "integrity": "sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg==" + }, "node_modules/resolve": { "version": "2.0.0-next.6", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", @@ -9245,6 +10514,24 @@ "node": ">=0.10.0" } }, + "node_modules/robust-predicates": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz", + "integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==", + "license": "Unlicense" + }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "license": "MIT", + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -9269,6 +10556,12 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, "node_modules/safe-array-concat": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", @@ -9324,6 +10617,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", @@ -9480,19 +10779,19 @@ } }, "node_modules/shiki": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.0.2.tgz", - "integrity": "sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.4.3.tgz", + "integrity": "sha512-Mb/GvXPHBAXdgGIcnfU5L3ldpn1XcxrGkPHwqgRx17/I2XRfqlFKk2vGkHWINn1kdXvzJZeuO3is6I9KLPFm0g==", "license": "MIT", "dependencies": { - "@shikijs/core": "4.0.2", - "@shikijs/engine-javascript": "4.0.2", - "@shikijs/engine-oniguruma": "4.0.2", - "@shikijs/langs": "4.0.2", - "@shikijs/themes": "4.0.2", - "@shikijs/types": "4.0.2", + "@shikijs/core": "4.4.3", + "@shikijs/engine-javascript": "4.4.3", + "@shikijs/engine-oniguruma": "4.4.3", + "@shikijs/langs": "4.4.3", + "@shikijs/themes": "4.4.3", + "@shikijs/types": "4.4.3", "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" + "@types/hast": "^3.0.5" }, "engines": { "node": ">=20" @@ -9801,6 +11100,12 @@ } } }, + "node_modules/stylis": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.4.0.tgz", + "integrity": "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==", + "license": "MIT" + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -9846,18 +11151,18 @@ } }, "node_modules/tinyexec": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", - "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/tinyglobby": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", - "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -9916,6 +11221,15 @@ "typescript": ">=4.8.4" } }, + "node_modules/ts-dedent": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.3.0.tgz", + "integrity": "sha512-JfJeIHke7y2egdGGgRAvpCwYFUsHlM2gPcrVOxFkznt/4uzQ7HFmvE63iFHVLBJNDuyDOQgijDK/tXH/f6Msjg==", + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -10096,6 +11410,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.4.tgz", + "integrity": "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/undici-types": { "version": "7.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.21.0.tgz", @@ -10336,6 +11658,27 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.7.0.tgz", + "integrity": "sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/uuid": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.2.tgz", + "integrity": "sha512-xZe/16rV4aa+HGSOCiY2YeLT1OybRLrrkL/Rqaq7p7GMVXjFh+6wN4oMYgjFmnSnhY8t6Xpdl2l9qmnHYuMHwQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, "node_modules/vfile": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", @@ -10510,6 +11853,21 @@ "dev": true, "license": "ISC" }, + "node_modules/yaml": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz", + "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -10523,6 +11881,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zbsearch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/zbsearch/-/zbsearch-4.0.0.tgz", + "integrity": "sha512-gm4zfO31n2ZdruTTRQoWVWO4Q2+zrDt2GlrvIc+5JulRQNAm4IanCxER82vQ7Ug96FYkGqWUJBXFe1kGAcDWaQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 20.0.0" + } + }, "node_modules/zod": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", diff --git a/docs-fumadocs/package.json b/docs-fumadocs/package.json index 8ff36ab2..0f2ebf83 100644 --- a/docs-fumadocs/package.json +++ b/docs-fumadocs/package.json @@ -4,11 +4,17 @@ "private": true, "scripts": { "sync:logo": "node scripts/sync-logo.mjs", - "build": "npm run sync:logo && npm run search:generate && next build", - "dev": "npm run sync:logo && next dev", + "openapi:export": "python3 scripts/export-openapi.py", + "openapi:enrich": "node scripts/enrich-openapi.mjs", + "openapi:generate": "node scripts/generate-api-docs.mjs", + "changelog:generate": "node scripts/generate-changelog-nav.mjs", + "prebuild": "npm run openapi:enrich && npm run openapi:generate", + "build": "node scripts/ensure-collections.mjs && npm run sync:logo && npm run prebuild && npm run search:generate && next build", + "dev:stop": "lsof -ti:3000 | xargs kill 2>/dev/null || true", + "dev": "node scripts/ensure-collections.mjs && npm run sync:logo && next dev --hostname 127.0.0.1 --port 3000", "start": "next start", - "types:check": "fumadocs-mdx && next typegen && tsc --noEmit", - "postinstall": "fumadocs-mdx && npm run sync:logo", + "types:check": "node scripts/ensure-collections.mjs && next typegen && tsc --noEmit", + "postinstall": "node scripts/ensure-collections.mjs && npm run sync:logo", "lint": "eslint", "search:generate": "node scripts/generate-search-index.mjs", "validate:docs": "node scripts/validate-docs.mjs", @@ -17,13 +23,17 @@ "ci:check": "npm run validate:docs && npm run check:links && npm run types:check && npm run build && npm run verify:routes" }, "dependencies": { - "fumadocs-core": "16.8.11", + "fumadocs-core": "16.15.9", "fumadocs-mdx": "15.0.4", - "fumadocs-ui": "16.8.11", + "fumadocs-openapi": "^11.4.2", + "fumadocs-ui": "16.15.9", "lucide-react": "^1.14.0", + "mermaid": "^12.0.0", "next": "16.2.6", + "next-themes": "^0.4.6", "react": "^19.2.6", "react-dom": "^19.2.6", + "shiki": "^4.4.3", "tailwind-merge": "^3.6.0" }, "devDependencies": { diff --git a/docs-fumadocs/public/EfficientAI docs.jpg b/docs-fumadocs/public/EfficientAI docs.jpg new file mode 100644 index 00000000..51b1df8c Binary files /dev/null and b/docs-fumadocs/public/EfficientAI docs.jpg differ diff --git a/docs-fumadocs/public/api-md/agents/check_phone_assignment_api_v1_agents_check_phone_assignment_get.md b/docs-fumadocs/public/api-md/agents/check_phone_assignment_api_v1_agents_check_phone_assignment_get.md new file mode 100644 index 00000000..014e4202 --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/check_phone_assignment_api_v1_agents_check_phone_assignment_get.md @@ -0,0 +1,32 @@ +# GET /api/v1/agents/check-phone-assignment + +Check Phone Assignment + +- Operation ID: `check_phone_assignment_api_v1_agents_check_phone_assignment_get` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `phone_number` (query, optional) +- `telephony_phone_number_id` (query, optional) +- `exclude_agent_id` (query, optional) +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/agents/check-phone-assignment" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/agents/create_agent_api_v1_agents_post.md b/docs-fumadocs/public/api-md/agents/create_agent_api_v1_agents_post.md new file mode 100644 index 00000000..e428f430 --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/create_agent_api_v1_agents_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/agents + +Create Agent + +- Operation ID: `create_agent_api_v1_agents_post` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/agents" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/agents/delete_agent_api_v1_agents__agent_id__delete.md b/docs-fumadocs/public/api-md/agents/delete_agent_api_v1_agents__agent_id__delete.md new file mode 100644 index 00000000..f2678567 --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/delete_agent_api_v1_agents__agent_id__delete.md @@ -0,0 +1,32 @@ +# DELETE /api/v1/agents/{agent_id} + +Delete Agent + +- Operation ID: `delete_agent_api_v1_agents__agent_id__delete` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (path, required) `string` +- `force` (query, optional) `boolean` + - Force delete with all dependent records +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/agents/{agent_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/agents/generate_agent_description_api_v1_agents_generate_description_post.md b/docs-fumadocs/public/api-md/agents/generate_agent_description_api_v1_agents_generate_description_post.md new file mode 100644 index 00000000..17ecc51b --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/generate_agent_description_api_v1_agents_generate_description_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/agents/generate-description + +Generate Agent Description + +- Operation ID: `generate_agent_description_api_v1_agents_generate_description_post` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/agents/generate-description" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/agents/generate_scenarios_from_prompt_api_v1_agents_generate_scenarios_from_prompt_post.md b/docs-fumadocs/public/api-md/agents/generate_scenarios_from_prompt_api_v1_agents_generate_scenarios_from_prompt_post.md new file mode 100644 index 00000000..f7608c89 --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/generate_scenarios_from_prompt_api_v1_agents_generate_scenarios_from_prompt_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/agents/generate-scenarios-from-prompt + +Generate Scenarios From Prompt + +- Operation ID: `generate_scenarios_from_prompt_api_v1_agents_generate_scenarios_from_prompt_post` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/agents/generate-scenarios-from-prompt" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/agents/generate_test_prompt_api_v1_agents_generate_test_prompt_post.md b/docs-fumadocs/public/api-md/agents/generate_test_prompt_api_v1_agents_generate_test_prompt_post.md new file mode 100644 index 00000000..e993c041 --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/generate_test_prompt_api_v1_agents_generate_test_prompt_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/agents/generate-test-prompt + +Generate Test Prompt + +- Operation ID: `generate_test_prompt_api_v1_agents_generate_test_prompt_post` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/agents/generate-test-prompt" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/agents/generate_test_setup_api_v1_agents_generate_test_setup_post.md b/docs-fumadocs/public/api-md/agents/generate_test_setup_api_v1_agents_generate_test_setup_post.md new file mode 100644 index 00000000..9c9bb2cf --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/generate_test_setup_api_v1_agents_generate_test_setup_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/agents/generate-test-setup + +Generate Test Setup + +- Operation ID: `generate_test_setup_api_v1_agents_generate_test_setup_post` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/agents/generate-test-setup" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/agents/get_agent_api_v1_agents__agent_id__get.md b/docs-fumadocs/public/api-md/agents/get_agent_api_v1_agents__agent_id__get.md new file mode 100644 index 00000000..44bde6a2 --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/get_agent_api_v1_agents__agent_id__get.md @@ -0,0 +1,30 @@ +# GET /api/v1/agents/{agent_id} + +Get Agent + +- Operation ID: `get_agent_api_v1_agents__agent_id__get` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/agents/{agent_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/agents/get_agent_delete_impact_api_v1_agents__agent_id__delete_impact_get.md b/docs-fumadocs/public/api-md/agents/get_agent_delete_impact_api_v1_agents__agent_id__delete_impact_get.md new file mode 100644 index 00000000..45a77b3f --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/get_agent_delete_impact_api_v1_agents__agent_id__delete_impact_get.md @@ -0,0 +1,30 @@ +# GET /api/v1/agents/{agent_id}/delete-impact + +Get Agent Delete Impact + +- Operation ID: `get_agent_delete_impact_api_v1_agents__agent_id__delete_impact_get` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/agents/{agent_id}/delete-impact" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/agents/list_agents_api_v1_agents_get.md b/docs-fumadocs/public/api-md/agents/list_agents_api_v1_agents_get.md new file mode 100644 index 00000000..214711b6 --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/list_agents_api_v1_agents_get.md @@ -0,0 +1,31 @@ +# GET /api/v1/agents + +List Agents + +- Operation ID: `list_agents_api_v1_agents_get` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `skip` (query, optional) `integer` +- `limit` (query, optional) `integer` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/agents" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/agents/sync_agent_provider_prompt_api_v1_agents__agent_id__sync_provider_prompt_post.md b/docs-fumadocs/public/api-md/agents/sync_agent_provider_prompt_api_v1_agents__agent_id__sync_provider_prompt_post.md new file mode 100644 index 00000000..8b3d7a4e --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/sync_agent_provider_prompt_api_v1_agents__agent_id__sync_provider_prompt_post.md @@ -0,0 +1,30 @@ +# POST /api/v1/agents/{agent_id}/sync-provider-prompt + +Sync Agent Provider Prompt + +- Operation ID: `sync_agent_provider_prompt_api_v1_agents__agent_id__sync_provider_prompt_post` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/agents/{agent_id}/sync-provider-prompt" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/agents/update_agent_api_v1_agents__agent_id__put.md b/docs-fumadocs/public/api-md/agents/update_agent_api_v1_agents__agent_id__put.md new file mode 100644 index 00000000..dbe3905e --- /dev/null +++ b/docs-fumadocs/public/api-md/agents/update_agent_api_v1_agents__agent_id__put.md @@ -0,0 +1,34 @@ +# PUT /api/v1/agents/{agent_id} + +Update Agent + +- Operation ID: `update_agent_api_v1_agents__agent_id__put` +- Tags: `Agents` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/agents/{agent_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/ai-providers/createAIProvider.md b/docs-fumadocs/public/api-md/ai-providers/createAIProvider.md new file mode 100644 index 00000000..0fb8cb37 --- /dev/null +++ b/docs-fumadocs/public/api-md/ai-providers/createAIProvider.md @@ -0,0 +1,32 @@ +# POST /api/v1/aiproviders + +Create Aiprovider + +- Operation ID: `createAIProvider` +- Tags: `AI Providers` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/aiproviders" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/ai-providers/deleteAIProvider.md b/docs-fumadocs/public/api-md/ai-providers/deleteAIProvider.md new file mode 100644 index 00000000..fab32ca5 --- /dev/null +++ b/docs-fumadocs/public/api-md/ai-providers/deleteAIProvider.md @@ -0,0 +1,29 @@ +# DELETE /api/v1/aiproviders/{aiprovider_id} + +Delete Aiprovider + +- Operation ID: `deleteAIProvider` +- Tags: `AI Providers` +- Auth: Bearer or API Key + +## Parameters + +- `aiprovider_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `204` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/aiproviders/{aiprovider_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/ai-providers/get_aiprovider_api_v1_aiproviders__aiprovider_id__get.md b/docs-fumadocs/public/api-md/ai-providers/get_aiprovider_api_v1_aiproviders__aiprovider_id__get.md new file mode 100644 index 00000000..10428371 --- /dev/null +++ b/docs-fumadocs/public/api-md/ai-providers/get_aiprovider_api_v1_aiproviders__aiprovider_id__get.md @@ -0,0 +1,29 @@ +# GET /api/v1/aiproviders/{aiprovider_id} + +Get Aiprovider + +- Operation ID: `get_aiprovider_api_v1_aiproviders__aiprovider_id__get` +- Tags: `AI Providers` +- Auth: Bearer or API Key + +## Parameters + +- `aiprovider_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/aiproviders/{aiprovider_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/ai-providers/listAIProviders.md b/docs-fumadocs/public/api-md/ai-providers/listAIProviders.md new file mode 100644 index 00000000..d9ae2c38 --- /dev/null +++ b/docs-fumadocs/public/api-md/ai-providers/listAIProviders.md @@ -0,0 +1,28 @@ +# GET /api/v1/aiproviders + +List Aiproviders + +- Operation ID: `listAIProviders` +- Tags: `AI Providers` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/aiproviders" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/ai-providers/setDefaultAIProvider.md b/docs-fumadocs/public/api-md/ai-providers/setDefaultAIProvider.md new file mode 100644 index 00000000..ba7b46ac --- /dev/null +++ b/docs-fumadocs/public/api-md/ai-providers/setDefaultAIProvider.md @@ -0,0 +1,29 @@ +# POST /api/v1/aiproviders/{aiprovider_id}/set-default + +Set Default Aiprovider + +- Operation ID: `setDefaultAIProvider` +- Tags: `AI Providers` +- Auth: Bearer or API Key + +## Parameters + +- `aiprovider_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/aiproviders/{aiprovider_id}/set-default" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/ai-providers/testAIProvider.md b/docs-fumadocs/public/api-md/ai-providers/testAIProvider.md new file mode 100644 index 00000000..2052b16e --- /dev/null +++ b/docs-fumadocs/public/api-md/ai-providers/testAIProvider.md @@ -0,0 +1,29 @@ +# POST /api/v1/aiproviders/{aiprovider_id}/test + +Test Aiprovider + +- Operation ID: `testAIProvider` +- Tags: `AI Providers` +- Auth: Bearer or API Key + +## Parameters + +- `aiprovider_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/aiproviders/{aiprovider_id}/test" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/ai-providers/updateAIProvider.md b/docs-fumadocs/public/api-md/ai-providers/updateAIProvider.md new file mode 100644 index 00000000..358a3dab --- /dev/null +++ b/docs-fumadocs/public/api-md/ai-providers/updateAIProvider.md @@ -0,0 +1,33 @@ +# PUT /api/v1/aiproviders/{aiprovider_id} + +Update Aiprovider + +- Operation ID: `updateAIProvider` +- Tags: `AI Providers` +- Auth: Bearer or API Key + +## Parameters + +- `aiprovider_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/aiproviders/{aiprovider_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/accept_invitation_by_token_api_v1_auth_invitations_accept_by_token_post.md b/docs-fumadocs/public/api-md/authentication/accept_invitation_by_token_api_v1_auth_invitations_accept_by_token_post.md new file mode 100644 index 00000000..56dce37e --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/accept_invitation_by_token_api_v1_auth_invitations_accept_by_token_post.md @@ -0,0 +1,32 @@ +# POST /api/v1/auth/invitations/accept-by-token + +Accept Invitation By Token + +- Operation ID: `accept_invitation_by_token_api_v1_auth_invitations_accept_by_token_post` +- Tags: `Authentication` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/auth/invitations/accept-by-token" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/generate_api_key_api_v1_auth_generate_key_post.md b/docs-fumadocs/public/api-md/authentication/generate_api_key_api_v1_auth_generate_key_post.md new file mode 100644 index 00000000..a6018a88 --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/generate_api_key_api_v1_auth_generate_key_post.md @@ -0,0 +1,32 @@ +# POST /api/v1/auth/generate-key + +Generate Api Key + +- Operation ID: `generate_api_key_api_v1_auth_generate_key_post` +- Tags: `Authentication` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/auth/generate-key" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/get_auth_config_api_v1_auth_config_get.md b/docs-fumadocs/public/api-md/authentication/get_auth_config_api_v1_auth_config_get.md new file mode 100644 index 00000000..c7048906 --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/get_auth_config_api_v1_auth_config_get.md @@ -0,0 +1,21 @@ +# GET /api/v1/auth/config + +Get Auth Config + +- Operation ID: `get_auth_config_api_v1_auth_config_get` +- Tags: `Authentication` +- Auth: Public + +## Responses + +- `200` - Successful Response + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/auth/config" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/login_api_v1_auth_login_post.md b/docs-fumadocs/public/api-md/authentication/login_api_v1_auth_login_post.md new file mode 100644 index 00000000..df62ac4e --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/login_api_v1_auth_login_post.md @@ -0,0 +1,26 @@ +# POST /api/v1/auth/login + +Login + +- Operation ID: `login_api_v1_auth_login_post` +- Tags: `Authentication` +- Auth: Public + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/auth/login" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/logout_api_v1_auth_logout_post.md b/docs-fumadocs/public/api-md/authentication/logout_api_v1_auth_logout_post.md new file mode 100644 index 00000000..6c492cd9 --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/logout_api_v1_auth_logout_post.md @@ -0,0 +1,32 @@ +# POST /api/v1/auth/logout + +Logout + +- Operation ID: `logout_api_v1_auth_logout_post` +- Tags: `Authentication` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/auth/logout" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/me_api_v1_auth_me_get.md b/docs-fumadocs/public/api-md/authentication/me_api_v1_auth_me_get.md new file mode 100644 index 00000000..c9d8d5f6 --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/me_api_v1_auth_me_get.md @@ -0,0 +1,28 @@ +# GET /api/v1/auth/me + +Me + +- Operation ID: `me_api_v1_auth_me_get` +- Tags: `Authentication` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/auth/me" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/preview_invitation_api_v1_auth_invitations_preview__token__get.md b/docs-fumadocs/public/api-md/authentication/preview_invitation_api_v1_auth_invitations_preview__token__get.md new file mode 100644 index 00000000..7dff757b --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/preview_invitation_api_v1_auth_invitations_preview__token__get.md @@ -0,0 +1,26 @@ +# GET /api/v1/auth/invitations/preview/{token} + +Preview Invitation + +- Operation ID: `preview_invitation_api_v1_auth_invitations_preview__token__get` +- Tags: `Authentication` +- Auth: Public + +## Parameters + +- `token` (path, required) `string` + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/auth/invitations/preview/{token}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/refresh_session_api_v1_auth_refresh_post.md b/docs-fumadocs/public/api-md/authentication/refresh_session_api_v1_auth_refresh_post.md new file mode 100644 index 00000000..1e060b54 --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/refresh_session_api_v1_auth_refresh_post.md @@ -0,0 +1,26 @@ +# POST /api/v1/auth/refresh + +Refresh Session + +- Operation ID: `refresh_session_api_v1_auth_refresh_post` +- Tags: `Authentication` +- Auth: Public + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/auth/refresh" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/set_password_api_v1_auth_password_post.md b/docs-fumadocs/public/api-md/authentication/set_password_api_v1_auth_password_post.md new file mode 100644 index 00000000..7628f836 --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/set_password_api_v1_auth_password_post.md @@ -0,0 +1,32 @@ +# POST /api/v1/auth/password + +Set Password + +- Operation ID: `set_password_api_v1_auth_password_post` +- Tags: `Authentication` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/auth/password" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/signup_api_v1_auth_signup_post.md b/docs-fumadocs/public/api-md/authentication/signup_api_v1_auth_signup_post.md new file mode 100644 index 00000000..1a410083 --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/signup_api_v1_auth_signup_post.md @@ -0,0 +1,26 @@ +# POST /api/v1/auth/signup + +Signup + +- Operation ID: `signup_api_v1_auth_signup_post` +- Tags: `Authentication` +- Auth: Public + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/auth/signup" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/switch_organization_api_v1_auth_switch_org_post.md b/docs-fumadocs/public/api-md/authentication/switch_organization_api_v1_auth_switch_org_post.md new file mode 100644 index 00000000..6ac15776 --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/switch_organization_api_v1_auth_switch_org_post.md @@ -0,0 +1,32 @@ +# POST /api/v1/auth/switch-org + +Switch Organization + +- Operation ID: `switch_organization_api_v1_auth_switch_org_post` +- Tags: `Authentication` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/auth/switch-org" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/authentication/validate_api_key_api_v1_auth_validate_post.md b/docs-fumadocs/public/api-md/authentication/validate_api_key_api_v1_auth_validate_post.md new file mode 100644 index 00000000..ad47c658 --- /dev/null +++ b/docs-fumadocs/public/api-md/authentication/validate_api_key_api_v1_auth_validate_post.md @@ -0,0 +1,28 @@ +# POST /api/v1/auth/validate + +Validate Api Key + +- Operation ID: `validate_api_key_api_v1_auth_validate_post` +- Tags: `Authentication` +- Auth: Bearer or API Key + +## Parameters + +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `Authorization` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/auth/validate" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/appendCallImportAudio.md b/docs-fumadocs/public/api-md/call-imports/appendCallImportAudio.md new file mode 100644 index 00000000..4a7d0c19 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/appendCallImportAudio.md @@ -0,0 +1,34 @@ +# POST /api/v1/call-imports/{call_import_id}/audio-append + +Append Call Import Audio + +- Operation ID: `appendCallImportAudio` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/{call_import_id}/audio-append" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/bulkDeleteCallImportRows.md b/docs-fumadocs/public/api-md/call-imports/bulkDeleteCallImportRows.md new file mode 100644 index 00000000..b1f02136 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/bulkDeleteCallImportRows.md @@ -0,0 +1,34 @@ +# POST /api/v1/call-imports/{call_import_id}/rows/bulk-delete + +Bulk Delete Call Import Rows + +- Operation ID: `bulkDeleteCallImportRows` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `202` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/{call_import_id}/rows/bulk-delete" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/cancelCallImportDiarisation.md b/docs-fumadocs/public/api-md/call-imports/cancelCallImportDiarisation.md new file mode 100644 index 00000000..f81eebba --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/cancelCallImportDiarisation.md @@ -0,0 +1,34 @@ +# POST /api/v1/call-imports/{call_import_id}/cancel-diarisation + +Cancel Call Import Diarisation + +- Operation ID: `cancelCallImportDiarisation` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/{call_import_id}/cancel-diarisation" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/cancelCallImportRowDiarisation.md b/docs-fumadocs/public/api-md/call-imports/cancelCallImportRowDiarisation.md new file mode 100644 index 00000000..414fcde4 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/cancelCallImportRowDiarisation.md @@ -0,0 +1,31 @@ +# POST /api/v1/call-imports/{call_import_id}/rows/{row_id}/cancel-diarisation + +Cancel Call Import Row Diarisation + +- Operation ID: `cancelCallImportRowDiarisation` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `row_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/{call_import_id}/rows/{row_id}/cancel-diarisation" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/createCallImport.md b/docs-fumadocs/public/api-md/call-imports/createCallImport.md new file mode 100644 index 00000000..ce9215bf --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/createCallImport.md @@ -0,0 +1,33 @@ +# POST /api/v1/call-imports + +Create Call Import + +- Operation ID: `createCallImport` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/createCallImportSchema.md b/docs-fumadocs/public/api-md/call-imports/createCallImportSchema.md new file mode 100644 index 00000000..b3363f05 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/createCallImportSchema.md @@ -0,0 +1,33 @@ +# POST /api/v1/call-import-schemas + +Create Call Import Schema + +- Operation ID: `createCallImportSchema` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-import-schemas" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/createCallImportTag.md b/docs-fumadocs/public/api-md/call-imports/createCallImportTag.md new file mode 100644 index 00000000..83732a8f --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/createCallImportTag.md @@ -0,0 +1,32 @@ +# POST /api/v1/call-import-tags + +Create Call Import Tag + +- Operation ID: `createCallImportTag` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-import-tags" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/deleteCallImport.md b/docs-fumadocs/public/api-md/call-imports/deleteCallImport.md new file mode 100644 index 00000000..ced15581 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/deleteCallImport.md @@ -0,0 +1,30 @@ +# DELETE /api/v1/call-imports/{call_import_id} + +Delete Call Import + +- Operation ID: `deleteCallImport` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `202` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/call-imports/{call_import_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/deleteCallImportRow.md b/docs-fumadocs/public/api-md/call-imports/deleteCallImportRow.md new file mode 100644 index 00000000..552e43f7 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/deleteCallImportRow.md @@ -0,0 +1,31 @@ +# DELETE /api/v1/call-imports/{call_import_id}/rows/{row_id} + +Delete Call Import Row + +- Operation ID: `deleteCallImportRow` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `row_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `204` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/call-imports/{call_import_id}/rows/{row_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/deleteCallImportSchema.md b/docs-fumadocs/public/api-md/call-imports/deleteCallImportSchema.md new file mode 100644 index 00000000..0da6bf92 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/deleteCallImportSchema.md @@ -0,0 +1,32 @@ +# DELETE /api/v1/call-import-schemas/{schema_id} + +Delete Call Import Schema + +- Operation ID: `deleteCallImportSchema` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `schema_id` (path, required) `string` +- `force` (query, optional) `boolean` + - When true, detach this schema from any CallImport batches that reference it (sets ``call_imports.schema_id = NULL``) before deleting the schema row. Use this to drop a schema whose batches you want to keep โ€” already-imported batches keep working via their snapshotted ``parameter_mapping``, while staged-but-not-yet-imported batches will need a new schema picked before they can be imported. +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `204` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/call-import-schemas/{schema_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/deleteCallImportTag.md b/docs-fumadocs/public/api-md/call-imports/deleteCallImportTag.md new file mode 100644 index 00000000..e2e3b653 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/deleteCallImportTag.md @@ -0,0 +1,29 @@ +# DELETE /api/v1/call-import-tags/{tag_id} + +Delete Call Import Tag + +- Operation ID: `deleteCallImportTag` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `tag_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `204` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/call-import-tags/{tag_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/getCallImportDetail.md b/docs-fumadocs/public/api-md/call-imports/getCallImportDetail.md new file mode 100644 index 00000000..ad2857c4 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/getCallImportDetail.md @@ -0,0 +1,36 @@ +# GET /api/v1/call-imports/{call_import_id} + +Get Call Import Detail + +- Operation ID: `getCallImportDetail` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `row_limit` (query, optional) `integer` +- `row_offset` (query, optional) `integer` +- `q` (query, optional) + - Optional case-insensitive substring filter on ``conversation_id``. When set, ``filtered_total_rows`` in the response reflects the post-filter row count so the UI can paginate against the filtered slice. +- `diarised_status` (query, optional) + - Optional filter on ``CallImportRow.diarised_transcript_status``. Accepts one of ``pending``, ``running``, ``completed``, ``failed``. When set, ``filtered_total_rows`` reflects the post-filter row count (combined with the ``q`` filter when both are supplied) so the UI can paginate against the same slice it's displaying. +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/call-imports/{call_import_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/getCallImportDiarisationPromptDefault.md b/docs-fumadocs/public/api-md/call-imports/getCallImportDiarisationPromptDefault.md new file mode 100644 index 00000000..4e818f0d --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/getCallImportDiarisationPromptDefault.md @@ -0,0 +1,29 @@ +# GET /api/v1/call-imports/diarisation-prompt-default + +Get Call Import Diarisation Prompt Default + +- Operation ID: `getCallImportDiarisationPromptDefault` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/call-imports/diarisation-prompt-default" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/getCallImportDispatchDiagnostics.md b/docs-fumadocs/public/api-md/call-imports/getCallImportDispatchDiagnostics.md new file mode 100644 index 00000000..33fdadf9 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/getCallImportDispatchDiagnostics.md @@ -0,0 +1,33 @@ +# GET /api/v1/call-imports/dispatch-diagnostics + +Get Call Import Dispatch Diagnostics + +- Operation ID: `getCallImportDispatchDiagnostics` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `workspace_id` (query, optional) + - Optional workspace filter. When omitted, returns every workspace in the organization with active eval dispatch state. +- `include_idle_workspaces` (query, optional) `boolean` + - When true, include org workspaces with zero pending rows and zero in-flight slots. +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/call-imports/dispatch-diagnostics" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/getCallImportInsights.md b/docs-fumadocs/public/api-md/call-imports/getCallImportInsights.md new file mode 100644 index 00000000..d9b9f973 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/getCallImportInsights.md @@ -0,0 +1,30 @@ +# GET /api/v1/call-imports/{call_import_id}/insights + +Get Call Import Insights + +- Operation ID: `getCallImportInsights` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/call-imports/{call_import_id}/insights" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/getCallImportSchema.md b/docs-fumadocs/public/api-md/call-imports/getCallImportSchema.md new file mode 100644 index 00000000..9d3af0a0 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/getCallImportSchema.md @@ -0,0 +1,30 @@ +# GET /api/v1/call-import-schemas/{schema_id} + +Get Call Import Schema + +- Operation ID: `getCallImportSchema` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `schema_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/call-import-schemas/{schema_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/listCallImportDatasets.md b/docs-fumadocs/public/api-md/call-imports/listCallImportDatasets.md new file mode 100644 index 00000000..cf8aacaa --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/listCallImportDatasets.md @@ -0,0 +1,29 @@ +# GET /api/v1/call-imports/datasets + +List Call Import Datasets + +- Operation ID: `listCallImportDatasets` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/call-imports/datasets" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/listCallImportRowIds.md b/docs-fumadocs/public/api-md/call-imports/listCallImportRowIds.md new file mode 100644 index 00000000..6b83c929 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/listCallImportRowIds.md @@ -0,0 +1,34 @@ +# GET /api/v1/call-imports/{call_import_id}/row-ids + +List Call Import Row Ids + +- Operation ID: `listCallImportRowIds` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `q` (query, optional) + - Optional case-insensitive substring filter on ``conversation_id``. Same semantics as the detail endpoint. +- `diarised_status` (query, optional) + - Optional filter on ``CallImportRow.diarised_transcript_status``. Accepts ``pending`` / ``running`` / ``completed`` / ``failed``. +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/call-imports/{call_import_id}/row-ids" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/listCallImportSchemas.md b/docs-fumadocs/public/api-md/call-imports/listCallImportSchemas.md new file mode 100644 index 00000000..772027f1 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/listCallImportSchemas.md @@ -0,0 +1,29 @@ +# GET /api/v1/call-import-schemas + +List Call Import Schemas + +- Operation ID: `listCallImportSchemas` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/call-import-schemas" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/listCallImportTags.md b/docs-fumadocs/public/api-md/call-imports/listCallImportTags.md new file mode 100644 index 00000000..3be38d41 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/listCallImportTags.md @@ -0,0 +1,28 @@ +# GET /api/v1/call-import-tags + +List Call Import Tags + +- Operation ID: `listCallImportTags` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/call-import-tags" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/listCallImports.md b/docs-fumadocs/public/api-md/call-imports/listCallImports.md new file mode 100644 index 00000000..abeaf4c2 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/listCallImports.md @@ -0,0 +1,38 @@ +# GET /api/v1/call-imports + +List Call Imports + +- Operation ID: `listCallImports` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `page` (query, optional) `integer` +- `page_size` (query, optional) `integer` +- `status` (query, optional) +- `dataset` (query, optional) + - Filter by exact dataset string (case-insensitive). Pass the literal value '__none__' to filter to imports with no dataset. +- `tag_id` (query, optional) + - Filter to imports tagged with ALL of the given tag ids. +- `source_format` (query, optional) + - Filter by source format. Use 'audio' for manual recordings or '__non_audio__' for CSV/Excel/legacy imports. +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/call-imports" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/previewCallImportFile.md b/docs-fumadocs/public/api-md/call-imports/previewCallImportFile.md new file mode 100644 index 00000000..3720bcbd --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/previewCallImportFile.md @@ -0,0 +1,33 @@ +# POST /api/v1/call-imports/preview + +Preview Call Import File + +- Operation ID: `previewCallImportFile` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/preview" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/retryFailedCallImportRows.md b/docs-fumadocs/public/api-md/call-imports/retryFailedCallImportRows.md new file mode 100644 index 00000000..7a4d0051 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/retryFailedCallImportRows.md @@ -0,0 +1,34 @@ +# POST /api/v1/call-imports/{call_import_id}/retry-failed + +Retry Failed Call Import Rows + +- Operation ID: `retryFailedCallImportRows` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `202` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/{call_import_id}/retry-failed" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/startCallImport.md b/docs-fumadocs/public/api-md/call-imports/startCallImport.md new file mode 100644 index 00000000..9ce95b68 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/startCallImport.md @@ -0,0 +1,36 @@ +# POST /api/v1/call-imports/{call_import_id}/import + +Start Call Import + +- Operation ID: `startCallImport` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `legacy` (query, optional) `boolean` + - Deprecated escape hatch for import-only processing. New batches should use Run Evaluation instead. +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `202` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/{call_import_id}/import" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/toggleCallImportRowSpeakerSwap.md b/docs-fumadocs/public/api-md/call-imports/toggleCallImportRowSpeakerSwap.md new file mode 100644 index 00000000..4e6d13c7 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/toggleCallImportRowSpeakerSwap.md @@ -0,0 +1,31 @@ +# POST /api/v1/call-imports/{call_import_id}/rows/{row_id}/diarised-speaker-swap + +Toggle Call Import Row Speaker Swap + +- Operation ID: `toggleCallImportRowSpeakerSwap` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `row_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/{call_import_id}/rows/{row_id}/diarised-speaker-swap" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/transcribeCallImport.md b/docs-fumadocs/public/api-md/call-imports/transcribeCallImport.md new file mode 100644 index 00000000..c74cf854 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/transcribeCallImport.md @@ -0,0 +1,34 @@ +# POST /api/v1/call-imports/{call_import_id}/transcribe + +Transcribe Call Import + +- Operation ID: `transcribeCallImport` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `202` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/{call_import_id}/transcribe" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/transcribeCallImportRow.md b/docs-fumadocs/public/api-md/call-imports/transcribeCallImportRow.md new file mode 100644 index 00000000..cdc39d02 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/transcribeCallImportRow.md @@ -0,0 +1,35 @@ +# POST /api/v1/call-imports/{call_import_id}/rows/{row_id}/transcribe + +Transcribe Call Import Row + +- Operation ID: `transcribeCallImportRow` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `row_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `202` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/{call_import_id}/rows/{row_id}/transcribe" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/updateCallImport.md b/docs-fumadocs/public/api-md/call-imports/updateCallImport.md new file mode 100644 index 00000000..e66a0903 --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/updateCallImport.md @@ -0,0 +1,34 @@ +# PATCH /api/v1/call-imports/{call_import_id} + +Update Call Import + +- Operation ID: `updateCallImport` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PATCH "http://localhost:8000/api/v1/call-imports/{call_import_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/updateCallImportMapping.md b/docs-fumadocs/public/api-md/call-imports/updateCallImportMapping.md new file mode 100644 index 00000000..4b09b49d --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/updateCallImportMapping.md @@ -0,0 +1,34 @@ +# PATCH /api/v1/call-imports/{call_import_id}/mapping + +Update Call Import Mapping + +- Operation ID: `updateCallImportMapping` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `call_import_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PATCH "http://localhost:8000/api/v1/call-imports/{call_import_id}/mapping" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/updateCallImportSchema.md b/docs-fumadocs/public/api-md/call-imports/updateCallImportSchema.md new file mode 100644 index 00000000..cf75702f --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/updateCallImportSchema.md @@ -0,0 +1,34 @@ +# PATCH /api/v1/call-import-schemas/{schema_id} + +Update Call Import Schema + +- Operation ID: `updateCallImportSchema` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `schema_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PATCH "http://localhost:8000/api/v1/call-import-schemas/{schema_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/updateCallImportTag.md b/docs-fumadocs/public/api-md/call-imports/updateCallImportTag.md new file mode 100644 index 00000000..586a8efc --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/updateCallImportTag.md @@ -0,0 +1,33 @@ +# PATCH /api/v1/call-import-tags/{tag_id} + +Update Call Import Tag + +- Operation ID: `updateCallImportTag` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `tag_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PATCH "http://localhost:8000/api/v1/call-import-tags/{tag_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/uploadCallImportAudio.md b/docs-fumadocs/public/api-md/call-imports/uploadCallImportAudio.md new file mode 100644 index 00000000..60ff4c2b --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/uploadCallImportAudio.md @@ -0,0 +1,33 @@ +# POST /api/v1/call-imports/audio-upload + +Upload Call Import Audio + +- Operation ID: `uploadCallImportAudio` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/audio-upload" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/call-imports/uploadCallImportCsv.md b/docs-fumadocs/public/api-md/call-imports/uploadCallImportCsv.md new file mode 100644 index 00000000..72d24bca --- /dev/null +++ b/docs-fumadocs/public/api-md/call-imports/uploadCallImportCsv.md @@ -0,0 +1,33 @@ +# POST /api/v1/call-imports/upload + +Upload Call Import Csv + +- Operation ID: `uploadCallImportCsv` +- Tags: `Call Imports` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `202` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/call-imports/upload" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/cancelEvaluatorResultMetricClusters.md b/docs-fumadocs/public/api-md/evaluator-results/cancelEvaluatorResultMetricClusters.md new file mode 100644 index 00000000..c83168b7 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/cancelEvaluatorResultMetricClusters.md @@ -0,0 +1,37 @@ +# POST /api/v1/evaluator-results/metric-clusters/cancel + +Cancel Evaluator Result Metric Clusters + +- Operation ID: `cancelEvaluatorResultMetricClusters` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (query, optional) +- `scenario_ids` (query, optional) +- `since` (query, optional) +- `until` (query, optional) +- `suite_id` (query, optional) +- `scenario_id` (query, optional) +- `scope_key` (query, optional) +- `job_id` (query, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluator-results/metric-clusters/cancel" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/create_evaluator_result_manual_api_v1_evaluator_results_post.md b/docs-fumadocs/public/api-md/evaluator-results/create_evaluator_result_manual_api_v1_evaluator_results_post.md new file mode 100644 index 00000000..4d6102b0 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/create_evaluator_result_manual_api_v1_evaluator_results_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/evaluator-results + +Create Evaluator Result Manual + +- Operation ID: `create_evaluator_result_manual_api_v1_evaluator_results_post` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluator-results" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/deleteEvaluatorResultMetricClusters.md b/docs-fumadocs/public/api-md/evaluator-results/deleteEvaluatorResultMetricClusters.md new file mode 100644 index 00000000..5c6f4aeb --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/deleteEvaluatorResultMetricClusters.md @@ -0,0 +1,37 @@ +# DELETE /api/v1/evaluator-results/metric-clusters + +Delete Evaluator Result Metric Clusters + +- Operation ID: `deleteEvaluatorResultMetricClusters` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (query, optional) +- `scenario_ids` (query, optional) +- `since` (query, optional) +- `until` (query, optional) +- `suite_id` (query, optional) +- `scenario_id` (query, optional) +- `scope_key` (query, optional) +- `job_id` (query, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `204` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/evaluator-results/metric-clusters" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/delete_evaluator_result_api_v1_evaluator_results__id__delete.md b/docs-fumadocs/public/api-md/evaluator-results/delete_evaluator_result_api_v1_evaluator_results__id__delete.md new file mode 100644 index 00000000..4f5c4c7f --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/delete_evaluator_result_api_v1_evaluator_results__id__delete.md @@ -0,0 +1,30 @@ +# DELETE /api/v1/evaluator-results/{id} + +Delete Evaluator Result + +- Operation ID: `delete_evaluator_result_api_v1_evaluator_results__id__delete` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `204` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/evaluator-results/{id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/delete_evaluator_results_bulk_api_v1_evaluator_results_delete.md b/docs-fumadocs/public/api-md/evaluator-results/delete_evaluator_results_bulk_api_v1_evaluator_results_delete.md new file mode 100644 index 00000000..26f4c637 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/delete_evaluator_results_bulk_api_v1_evaluator_results_delete.md @@ -0,0 +1,30 @@ +# DELETE /api/v1/evaluator-results + +Delete Evaluator Results Bulk + +- Operation ID: `delete_evaluator_results_bulk_api_v1_evaluator_results_delete` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `result_ids` (query, required) `array` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `204` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/evaluator-results" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/generateEvaluatorResultMetricClusters.md b/docs-fumadocs/public/api-md/evaluator-results/generateEvaluatorResultMetricClusters.md new file mode 100644 index 00000000..24c39645 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/generateEvaluatorResultMetricClusters.md @@ -0,0 +1,41 @@ +# POST /api/v1/evaluator-results/metric-clusters + +Generate Evaluator Result Metric Clusters + +- Operation ID: `generateEvaluatorResultMetricClusters` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (query, optional) +- `scenario_ids` (query, optional) +- `since` (query, optional) +- `until` (query, optional) +- `suite_id` (query, optional) +- `scenario_id` (query, optional) +- `scope_key` (query, optional) +- `job_id` (query, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluator-results/metric-clusters" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/getEvaluatorResultMetricClusterFailurePolicies.md b/docs-fumadocs/public/api-md/evaluator-results/getEvaluatorResultMetricClusterFailurePolicies.md new file mode 100644 index 00000000..e8810c9b --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/getEvaluatorResultMetricClusterFailurePolicies.md @@ -0,0 +1,37 @@ +# GET /api/v1/evaluator-results/metric-clusters/failure-policies + +Get Evaluator Result Metric Cluster Failure Policies + +- Operation ID: `getEvaluatorResultMetricClusterFailurePolicies` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (query, optional) +- `scenario_ids` (query, optional) +- `since` (query, optional) +- `until` (query, optional) +- `suite_id` (query, optional) +- `scenario_id` (query, optional) +- `scope_key` (query, optional) +- `job_id` (query, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-results/metric-clusters/failure-policies" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/getEvaluatorResultMetricClusters.md b/docs-fumadocs/public/api-md/evaluator-results/getEvaluatorResultMetricClusters.md new file mode 100644 index 00000000..b811e32f --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/getEvaluatorResultMetricClusters.md @@ -0,0 +1,37 @@ +# GET /api/v1/evaluator-results/metric-clusters + +Get Evaluator Result Metric Clusters + +- Operation ID: `getEvaluatorResultMetricClusters` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (query, optional) +- `scenario_ids` (query, optional) +- `since` (query, optional) +- `until` (query, optional) +- `suite_id` (query, optional) +- `scenario_id` (query, optional) +- `scope_key` (query, optional) +- `job_id` (query, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-results/metric-clusters" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_result_api_v1_evaluator_results__id__get.md b/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_result_api_v1_evaluator_results__id__get.md new file mode 100644 index 00000000..97a58f38 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_result_api_v1_evaluator_results__id__get.md @@ -0,0 +1,31 @@ +# GET /api/v1/evaluator-results/{id} + +Get Evaluator Result + +- Operation ID: `get_evaluator_result_api_v1_evaluator_results__id__get` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `id` (path, required) `string` +- `include_relations` (query, optional) `boolean` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-results/{id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_result_metrics_api_v1_evaluator_results__id__metrics_get.md b/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_result_metrics_api_v1_evaluator_results__id__metrics_get.md new file mode 100644 index 00000000..9414c561 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_result_metrics_api_v1_evaluator_results__id__metrics_get.md @@ -0,0 +1,30 @@ +# GET /api/v1/evaluator-results/{id}/metrics + +Get Evaluator Result Metrics + +- Operation ID: `get_evaluator_result_metrics_api_v1_evaluator_results__id__metrics_get` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-results/{id}/metrics" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_results_aggregate_api_v1_evaluator_results_aggregate_get.md b/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_results_aggregate_api_v1_evaluator_results_aggregate_get.md new file mode 100644 index 00000000..b4ab6fa9 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_results_aggregate_api_v1_evaluator_results_aggregate_get.md @@ -0,0 +1,34 @@ +# GET /api/v1/evaluator-results/aggregate + +Get Evaluator Results Aggregate + +- Operation ID: `get_evaluator_results_aggregate_api_v1_evaluator_results_aggregate_get` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (query, optional) +- `agent_id` (query, optional) +- `scenario_id` (query, optional) +- `since` (query, optional) +- `until` (query, optional) +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-results/aggregate" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_results_overview_api_v1_evaluator_results_overview_get.md b/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_results_overview_api_v1_evaluator_results_overview_get.md new file mode 100644 index 00000000..00c263bf --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/get_evaluator_results_overview_api_v1_evaluator_results_overview_get.md @@ -0,0 +1,35 @@ +# GET /api/v1/evaluator-results/overview + +Get Evaluator Results Overview + +- Operation ID: `get_evaluator_results_overview_api_v1_evaluator_results_overview_get` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (query, optional) + - When set, return suites for this agent +- `suite_id` (query, optional) + - When set, return scenarios for this suite +- `since` (query, optional) +- `until` (query, optional) +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-results/overview" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/listEvaluatorResultMetricClusterEligibleRows.md b/docs-fumadocs/public/api-md/evaluator-results/listEvaluatorResultMetricClusterEligibleRows.md new file mode 100644 index 00000000..84e05aa8 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/listEvaluatorResultMetricClusterEligibleRows.md @@ -0,0 +1,39 @@ +# GET /api/v1/evaluator-results/metric-clusters/eligible-rows + +List Evaluator Result Metric Cluster Eligible Rows + +- Operation ID: `listEvaluatorResultMetricClusterEligibleRows` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `limit` (query, optional) +- `count_only` (query, optional) `boolean` +- `agent_id` (query, optional) +- `scenario_ids` (query, optional) +- `since` (query, optional) +- `until` (query, optional) +- `suite_id` (query, optional) +- `scenario_id` (query, optional) +- `scope_key` (query, optional) +- `job_id` (query, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-results/metric-clusters/eligible-rows" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/listEvaluatorResultMetricClusterScopes.md b/docs-fumadocs/public/api-md/evaluator-results/listEvaluatorResultMetricClusterScopes.md new file mode 100644 index 00000000..561c8217 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/listEvaluatorResultMetricClusterScopes.md @@ -0,0 +1,29 @@ +# GET /api/v1/evaluator-results/metric-clusters/scopes + +List Evaluator Result Metric Cluster Scopes + +- Operation ID: `listEvaluatorResultMetricClusterScopes` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-results/metric-clusters/scopes" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/list_evaluator_results_api_v1_evaluator_results_get.md b/docs-fumadocs/public/api-md/evaluator-results/list_evaluator_results_api_v1_evaluator_results_get.md new file mode 100644 index 00000000..49d4e344 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/list_evaluator_results_api_v1_evaluator_results_get.md @@ -0,0 +1,48 @@ +# GET /api/v1/evaluator-results + +List Evaluator Results + +- Operation ID: `list_evaluator_results_api_v1_evaluator_results_get` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `skip` (query, optional) `integer` +- `limit` (query, optional) `integer` +- `evaluator_id` (query, optional) +- `agent_id` (query, optional) + - Filter by associated agent UUID +- `suite_id` (query, optional) + - Filter by evaluator suite UUID +- `scenario_id` (query, optional) + - Filter by scenario UUID +- `status` (query, optional) + - Filter by display status: completed, failed, in_progress +- `since` (query, optional) +- `until` (query, optional) +- `unassigned_only` (query, optional) + - When true, only legacy/manual results without a suite +- `playground` (query, optional) + - If true, only return playground test results (evaluator_id is NULL). If false, exclude playground results. If not provided, exclude playground results by default. +- `test_agents_only` (query, optional) + - If true, only return Test Agent results (no provider_platform). If false, include all playground results. +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-results" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/re_evaluate_result_api_v1_evaluator_results__id__re_evaluate_post.md b/docs-fumadocs/public/api-md/evaluator-results/re_evaluate_result_api_v1_evaluator_results__id__re_evaluate_post.md new file mode 100644 index 00000000..ba1f7972 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/re_evaluate_result_api_v1_evaluator_results__id__re_evaluate_post.md @@ -0,0 +1,30 @@ +# POST /api/v1/evaluator-results/{id}/re-evaluate + +Re Evaluate Result + +- Operation ID: `re_evaluate_result_api_v1_evaluator_results__id__re_evaluate_post` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluator-results/{id}/re-evaluate" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/saveEvaluatorResultMetricClusterFailurePolicies.md b/docs-fumadocs/public/api-md/evaluator-results/saveEvaluatorResultMetricClusterFailurePolicies.md new file mode 100644 index 00000000..1a366e64 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/saveEvaluatorResultMetricClusterFailurePolicies.md @@ -0,0 +1,41 @@ +# PUT /api/v1/evaluator-results/metric-clusters/failure-policies + +Save Evaluator Result Metric Cluster Failure Policies + +- Operation ID: `saveEvaluatorResultMetricClusterFailurePolicies` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (query, optional) +- `scenario_ids` (query, optional) +- `since` (query, optional) +- `until` (query, optional) +- `suite_id` (query, optional) +- `scenario_id` (query, optional) +- `scope_key` (query, optional) +- `job_id` (query, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/evaluator-results/metric-clusters/failure-policies" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/stream_evaluator_result_audio_api_v1_evaluator_results__id__audio_get.md b/docs-fumadocs/public/api-md/evaluator-results/stream_evaluator_result_audio_api_v1_evaluator_results__id__audio_get.md new file mode 100644 index 00000000..9a7637fb --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/stream_evaluator_result_audio_api_v1_evaluator_results__id__audio_get.md @@ -0,0 +1,30 @@ +# GET /api/v1/evaluator-results/{id}/audio + +Stream Evaluator Result Audio + +- Operation ID: `stream_evaluator_result_audio_api_v1_evaluator_results__id__audio_get` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-results/{id}/audio" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-results/stream_evaluator_result_live_events_api_v1_evaluator_results__id__live_events_get.md b/docs-fumadocs/public/api-md/evaluator-results/stream_evaluator_result_live_events_api_v1_evaluator_results__id__live_events_get.md new file mode 100644 index 00000000..38c1cb60 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-results/stream_evaluator_result_live_events_api_v1_evaluator_results__id__live_events_get.md @@ -0,0 +1,30 @@ +# GET /api/v1/evaluator-results/{id}/live-events + +Stream Evaluator Result Live Events + +- Operation ID: `stream_evaluator_result_live_events_api_v1_evaluator_results__id__live_events_get` +- Tags: `Evaluator Results` +- Auth: Bearer or API Key + +## Parameters + +- `id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-results/{id}/live-events" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/activate_suite_api_v1_evaluator_suites__suite_id__activate_post.md b/docs-fumadocs/public/api-md/evaluator-suites/activate_suite_api_v1_evaluator_suites__suite_id__activate_post.md new file mode 100644 index 00000000..7eff958a --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/activate_suite_api_v1_evaluator_suites__suite_id__activate_post.md @@ -0,0 +1,30 @@ +# POST /api/v1/evaluator-suites/{suite_id}/activate + +Activate Suite + +- Operation ID: `activate_suite_api_v1_evaluator_suites__suite_id__activate_post` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluator-suites/{suite_id}/activate" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/add_personas_api_v1_evaluator_suites__suite_id__personas_post.md b/docs-fumadocs/public/api-md/evaluator-suites/add_personas_api_v1_evaluator_suites__suite_id__personas_post.md new file mode 100644 index 00000000..a6acc157 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/add_personas_api_v1_evaluator_suites__suite_id__personas_post.md @@ -0,0 +1,34 @@ +# POST /api/v1/evaluator-suites/{suite_id}/personas + +Add Personas + +- Operation ID: `add_personas_api_v1_evaluator_suites__suite_id__personas_post` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluator-suites/{suite_id}/personas" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/add_scenarios_api_v1_evaluator_suites__suite_id__scenarios_post.md b/docs-fumadocs/public/api-md/evaluator-suites/add_scenarios_api_v1_evaluator_suites__suite_id__scenarios_post.md new file mode 100644 index 00000000..da8d0cfb --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/add_scenarios_api_v1_evaluator_suites__suite_id__scenarios_post.md @@ -0,0 +1,34 @@ +# POST /api/v1/evaluator-suites/{suite_id}/scenarios + +Add Scenarios + +- Operation ID: `add_scenarios_api_v1_evaluator_suites__suite_id__scenarios_post` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluator-suites/{suite_id}/scenarios" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/choose_next_combination_api_v1_evaluator_suites__suite_id__choose_next_post.md b/docs-fumadocs/public/api-md/evaluator-suites/choose_next_combination_api_v1_evaluator_suites__suite_id__choose_next_post.md new file mode 100644 index 00000000..5a66c686 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/choose_next_combination_api_v1_evaluator_suites__suite_id__choose_next_post.md @@ -0,0 +1,30 @@ +# POST /api/v1/evaluator-suites/{suite_id}/choose-next + +Choose Next Combination + +- Operation ID: `choose_next_combination_api_v1_evaluator_suites__suite_id__choose_next_post` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluator-suites/{suite_id}/choose-next" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/create_suite_api_v1_evaluator_suites_post.md b/docs-fumadocs/public/api-md/evaluator-suites/create_suite_api_v1_evaluator_suites_post.md new file mode 100644 index 00000000..a385d643 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/create_suite_api_v1_evaluator_suites_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/evaluator-suites + +Create Suite + +- Operation ID: `create_suite_api_v1_evaluator_suites_post` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluator-suites" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/delete_suite_api_v1_evaluator_suites__suite_id__delete.md b/docs-fumadocs/public/api-md/evaluator-suites/delete_suite_api_v1_evaluator_suites__suite_id__delete.md new file mode 100644 index 00000000..2d3438fc --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/delete_suite_api_v1_evaluator_suites__suite_id__delete.md @@ -0,0 +1,30 @@ +# DELETE /api/v1/evaluator-suites/{suite_id} + +Delete Suite + +- Operation ID: `delete_suite_api_v1_evaluator_suites__suite_id__delete` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `204` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/evaluator-suites/{suite_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/get_suite_api_v1_evaluator_suites__suite_id__get.md b/docs-fumadocs/public/api-md/evaluator-suites/get_suite_api_v1_evaluator_suites__suite_id__get.md new file mode 100644 index 00000000..159d5cc9 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/get_suite_api_v1_evaluator_suites__suite_id__get.md @@ -0,0 +1,30 @@ +# GET /api/v1/evaluator-suites/{suite_id} + +Get Suite + +- Operation ID: `get_suite_api_v1_evaluator_suites__suite_id__get` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-suites/{suite_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/list_suites_api_v1_evaluator_suites_get.md b/docs-fumadocs/public/api-md/evaluator-suites/list_suites_api_v1_evaluator_suites_get.md new file mode 100644 index 00000000..0b88da46 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/list_suites_api_v1_evaluator_suites_get.md @@ -0,0 +1,29 @@ +# GET /api/v1/evaluator-suites + +List Suites + +- Operation ID: `list_suites_api_v1_evaluator_suites_get` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluator-suites" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/remove_persona_api_v1_evaluator_suites__suite_id__personas__persona_id__delete.md b/docs-fumadocs/public/api-md/evaluator-suites/remove_persona_api_v1_evaluator_suites__suite_id__personas__persona_id__delete.md new file mode 100644 index 00000000..50260499 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/remove_persona_api_v1_evaluator_suites__suite_id__personas__persona_id__delete.md @@ -0,0 +1,31 @@ +# DELETE /api/v1/evaluator-suites/{suite_id}/personas/{persona_id} + +Remove Persona + +- Operation ID: `remove_persona_api_v1_evaluator_suites__suite_id__personas__persona_id__delete` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `persona_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/evaluator-suites/{suite_id}/personas/{persona_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/remove_scenario_api_v1_evaluator_suites__suite_id__scenarios__scenario_id__delete.md b/docs-fumadocs/public/api-md/evaluator-suites/remove_scenario_api_v1_evaluator_suites__suite_id__scenarios__scenario_id__delete.md new file mode 100644 index 00000000..76eb1471 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/remove_scenario_api_v1_evaluator_suites__suite_id__scenarios__scenario_id__delete.md @@ -0,0 +1,31 @@ +# DELETE /api/v1/evaluator-suites/{suite_id}/scenarios/{scenario_id} + +Remove Scenario + +- Operation ID: `remove_scenario_api_v1_evaluator_suites__suite_id__scenarios__scenario_id__delete` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `scenario_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/evaluator-suites/{suite_id}/scenarios/{scenario_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/replace_personas_api_v1_evaluator_suites__suite_id__personas_put.md b/docs-fumadocs/public/api-md/evaluator-suites/replace_personas_api_v1_evaluator_suites__suite_id__personas_put.md new file mode 100644 index 00000000..4047b7a0 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/replace_personas_api_v1_evaluator_suites__suite_id__personas_put.md @@ -0,0 +1,34 @@ +# PUT /api/v1/evaluator-suites/{suite_id}/personas + +Replace Personas + +- Operation ID: `replace_personas_api_v1_evaluator_suites__suite_id__personas_put` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/evaluator-suites/{suite_id}/personas" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/run_next_combination_api_v1_evaluator_suites__suite_id__run_next_post.md b/docs-fumadocs/public/api-md/evaluator-suites/run_next_combination_api_v1_evaluator_suites__suite_id__run_next_post.md new file mode 100644 index 00000000..48e4cf92 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/run_next_combination_api_v1_evaluator_suites__suite_id__run_next_post.md @@ -0,0 +1,34 @@ +# POST /api/v1/evaluator-suites/{suite_id}/run-next + +Run Next Combination + +- Operation ID: `run_next_combination_api_v1_evaluator_suites__suite_id__run_next_post` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluator-suites/{suite_id}/run-next" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/run_suite_api_v1_evaluator_suites__suite_id__run_post.md b/docs-fumadocs/public/api-md/evaluator-suites/run_suite_api_v1_evaluator_suites__suite_id__run_post.md new file mode 100644 index 00000000..4444390e --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/run_suite_api_v1_evaluator_suites__suite_id__run_post.md @@ -0,0 +1,34 @@ +# POST /api/v1/evaluator-suites/{suite_id}/run + +Run Suite + +- Operation ID: `run_suite_api_v1_evaluator_suites__suite_id__run_post` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluator-suites/{suite_id}/run" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluator-suites/update_suite_api_v1_evaluator_suites__suite_id__put.md b/docs-fumadocs/public/api-md/evaluator-suites/update_suite_api_v1_evaluator_suites__suite_id__put.md new file mode 100644 index 00000000..30621193 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluator-suites/update_suite_api_v1_evaluator_suites__suite_id__put.md @@ -0,0 +1,34 @@ +# PUT /api/v1/evaluator-suites/{suite_id} + +Update Suite + +- Operation ID: `update_suite_api_v1_evaluator_suites__suite_id__put` +- Tags: `Evaluator Suites` +- Auth: Bearer or API Key + +## Parameters + +- `suite_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/evaluator-suites/{suite_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluators/create_evaluator_api_v1_evaluators_post.md b/docs-fumadocs/public/api-md/evaluators/create_evaluator_api_v1_evaluators_post.md new file mode 100644 index 00000000..4281bc07 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluators/create_evaluator_api_v1_evaluators_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/evaluators + +Create Evaluator + +- Operation ID: `create_evaluator_api_v1_evaluators_post` +- Tags: `Evaluators` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluators" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluators/create_evaluators_bulk_api_v1_evaluators_bulk_post.md b/docs-fumadocs/public/api-md/evaluators/create_evaluators_bulk_api_v1_evaluators_bulk_post.md new file mode 100644 index 00000000..9fed26a4 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluators/create_evaluators_bulk_api_v1_evaluators_bulk_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/evaluators/bulk + +Create Evaluators Bulk + +- Operation ID: `create_evaluators_bulk_api_v1_evaluators_bulk_post` +- Tags: `Evaluators` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluators/bulk" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluators/delete_evaluator_api_v1_evaluators__evaluator_id__delete.md b/docs-fumadocs/public/api-md/evaluators/delete_evaluator_api_v1_evaluators__evaluator_id__delete.md new file mode 100644 index 00000000..e87fbef0 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluators/delete_evaluator_api_v1_evaluators__evaluator_id__delete.md @@ -0,0 +1,32 @@ +# DELETE /api/v1/evaluators/{evaluator_id} + +Delete Evaluator + +- Operation ID: `delete_evaluator_api_v1_evaluators__evaluator_id__delete` +- Tags: `Evaluators` +- Auth: Bearer or API Key + +## Parameters + +- `evaluator_id` (path, required) `string` +- `force` (query, optional) `boolean` + - Deprecated: evaluator deletion keeps dependent results +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/evaluators/{evaluator_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluators/format_custom_prompt_api_v1_evaluators_format_prompt_post.md b/docs-fumadocs/public/api-md/evaluators/format_custom_prompt_api_v1_evaluators_format_prompt_post.md new file mode 100644 index 00000000..33974989 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluators/format_custom_prompt_api_v1_evaluators_format_prompt_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/evaluators/format-prompt + +Format Custom Prompt + +- Operation ID: `format_custom_prompt_api_v1_evaluators_format_prompt_post` +- Tags: `Evaluators` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluators/format-prompt" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluators/get_evaluator_api_v1_evaluators__evaluator_id__get.md b/docs-fumadocs/public/api-md/evaluators/get_evaluator_api_v1_evaluators__evaluator_id__get.md new file mode 100644 index 00000000..6a440e27 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluators/get_evaluator_api_v1_evaluators__evaluator_id__get.md @@ -0,0 +1,30 @@ +# GET /api/v1/evaluators/{evaluator_id} + +Get Evaluator + +- Operation ID: `get_evaluator_api_v1_evaluators__evaluator_id__get` +- Tags: `Evaluators` +- Auth: Bearer or API Key + +## Parameters + +- `evaluator_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluators/{evaluator_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluators/list_evaluators_api_v1_evaluators_get.md b/docs-fumadocs/public/api-md/evaluators/list_evaluators_api_v1_evaluators_get.md new file mode 100644 index 00000000..ac2b3c27 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluators/list_evaluators_api_v1_evaluators_get.md @@ -0,0 +1,29 @@ +# GET /api/v1/evaluators + +List Evaluators + +- Operation ID: `list_evaluators_api_v1_evaluators_get` +- Tags: `Evaluators` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/evaluators" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluators/run_evaluators_api_v1_evaluators_run_post.md b/docs-fumadocs/public/api-md/evaluators/run_evaluators_api_v1_evaluators_run_post.md new file mode 100644 index 00000000..c245657f --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluators/run_evaluators_api_v1_evaluators_run_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/evaluators/run + +Run Evaluators + +- Operation ID: `run_evaluators_api_v1_evaluators_run_post` +- Tags: `Evaluators` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/evaluators/run" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/evaluators/update_evaluator_api_v1_evaluators__evaluator_id__put.md b/docs-fumadocs/public/api-md/evaluators/update_evaluator_api_v1_evaluators__evaluator_id__put.md new file mode 100644 index 00000000..10d9f408 --- /dev/null +++ b/docs-fumadocs/public/api-md/evaluators/update_evaluator_api_v1_evaluators__evaluator_id__put.md @@ -0,0 +1,34 @@ +# PUT /api/v1/evaluators/{evaluator_id} + +Update Evaluator + +- Operation ID: `update_evaluator_api_v1_evaluators__evaluator_id__put` +- Tags: `Evaluators` +- Auth: Bearer or API Key + +## Parameters + +- `evaluator_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/evaluators/{evaluator_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/integrations/createIntegration.md b/docs-fumadocs/public/api-md/integrations/createIntegration.md new file mode 100644 index 00000000..0c4597cf --- /dev/null +++ b/docs-fumadocs/public/api-md/integrations/createIntegration.md @@ -0,0 +1,32 @@ +# POST /api/v1/integrations + +Create Integration + +- Operation ID: `createIntegration` +- Tags: `Integrations` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/integrations" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/integrations/deleteIntegration.md b/docs-fumadocs/public/api-md/integrations/deleteIntegration.md new file mode 100644 index 00000000..66eccf18 --- /dev/null +++ b/docs-fumadocs/public/api-md/integrations/deleteIntegration.md @@ -0,0 +1,31 @@ +# DELETE /api/v1/integrations/{integration_id} + +Delete Integration + +- Operation ID: `deleteIntegration` +- Tags: `Integrations` +- Auth: Bearer or API Key + +## Parameters + +- `integration_id` (path, required) `string` +- `force` (query, optional) `boolean` + - Force delete and unlink all agents using this integration +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/integrations/{integration_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/integrations/get_integration_api_key_api_v1_integrations__integration_id__api_key_get.md b/docs-fumadocs/public/api-md/integrations/get_integration_api_key_api_v1_integrations__integration_id__api_key_get.md new file mode 100644 index 00000000..4dea1245 --- /dev/null +++ b/docs-fumadocs/public/api-md/integrations/get_integration_api_key_api_v1_integrations__integration_id__api_key_get.md @@ -0,0 +1,29 @@ +# GET /api/v1/integrations/{integration_id}/api-key + +Get Integration Api Key + +- Operation ID: `get_integration_api_key_api_v1_integrations__integration_id__api_key_get` +- Tags: `Integrations` +- Auth: Bearer or API Key + +## Parameters + +- `integration_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/integrations/{integration_id}/api-key" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/integrations/get_integration_api_v1_integrations__integration_id__get.md b/docs-fumadocs/public/api-md/integrations/get_integration_api_v1_integrations__integration_id__get.md new file mode 100644 index 00000000..65b0ec82 --- /dev/null +++ b/docs-fumadocs/public/api-md/integrations/get_integration_api_v1_integrations__integration_id__get.md @@ -0,0 +1,29 @@ +# GET /api/v1/integrations/{integration_id} + +Get Integration + +- Operation ID: `get_integration_api_v1_integrations__integration_id__get` +- Tags: `Integrations` +- Auth: Bearer or API Key + +## Parameters + +- `integration_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/integrations/{integration_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/integrations/listIntegrations.md b/docs-fumadocs/public/api-md/integrations/listIntegrations.md new file mode 100644 index 00000000..993fe2e9 --- /dev/null +++ b/docs-fumadocs/public/api-md/integrations/listIntegrations.md @@ -0,0 +1,28 @@ +# GET /api/v1/integrations + +List Integrations + +- Operation ID: `listIntegrations` +- Tags: `Integrations` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/integrations" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/integrations/previewIntegrationAgentPrompt.md b/docs-fumadocs/public/api-md/integrations/previewIntegrationAgentPrompt.md new file mode 100644 index 00000000..5dc418d1 --- /dev/null +++ b/docs-fumadocs/public/api-md/integrations/previewIntegrationAgentPrompt.md @@ -0,0 +1,33 @@ +# POST /api/v1/integrations/{integration_id}/preview-agent-prompt + +Preview Integration Agent Prompt + +- Operation ID: `previewIntegrationAgentPrompt` +- Tags: `Integrations` +- Auth: Bearer or API Key + +## Parameters + +- `integration_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/integrations/{integration_id}/preview-agent-prompt" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/integrations/setDefaultIntegration.md b/docs-fumadocs/public/api-md/integrations/setDefaultIntegration.md new file mode 100644 index 00000000..63147283 --- /dev/null +++ b/docs-fumadocs/public/api-md/integrations/setDefaultIntegration.md @@ -0,0 +1,29 @@ +# POST /api/v1/integrations/{integration_id}/set-default + +Set Default Integration + +- Operation ID: `setDefaultIntegration` +- Tags: `Integrations` +- Auth: Bearer or API Key + +## Parameters + +- `integration_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/integrations/{integration_id}/set-default" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/integrations/updateIntegration.md b/docs-fumadocs/public/api-md/integrations/updateIntegration.md new file mode 100644 index 00000000..295377af --- /dev/null +++ b/docs-fumadocs/public/api-md/integrations/updateIntegration.md @@ -0,0 +1,33 @@ +# PUT /api/v1/integrations/{integration_id} + +Update Integration + +- Operation ID: `updateIntegration` +- Tags: `Integrations` +- Auth: Bearer or API Key + +## Parameters + +- `integration_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/integrations/{integration_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/addMetricChild.md b/docs-fumadocs/public/api-md/metrics/addMetricChild.md new file mode 100644 index 00000000..ea1e4c5f --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/addMetricChild.md @@ -0,0 +1,34 @@ +# POST /api/v1/metrics/{metric_id}/children + +Add Metric Child + +- Operation ID: `addMetricChild` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `metric_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/metrics/{metric_id}/children" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/createMetricDraft.md b/docs-fumadocs/public/api-md/metrics/createMetricDraft.md new file mode 100644 index 00000000..292d3ff1 --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/createMetricDraft.md @@ -0,0 +1,33 @@ +# POST /api/v1/metrics/drafts + +Create Metric Draft + +- Operation ID: `createMetricDraft` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/metrics/drafts" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/createMetricDraftWithChildren.md b/docs-fumadocs/public/api-md/metrics/createMetricDraftWithChildren.md new file mode 100644 index 00000000..ffe37972 --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/createMetricDraftWithChildren.md @@ -0,0 +1,33 @@ +# POST /api/v1/metrics/drafts/with-children + +Create Metric Draft With Children + +- Operation ID: `createMetricDraftWithChildren` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/metrics/drafts/with-children" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/createMetricWithChildren.md b/docs-fumadocs/public/api-md/metrics/createMetricWithChildren.md new file mode 100644 index 00000000..d0c288be --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/createMetricWithChildren.md @@ -0,0 +1,33 @@ +# POST /api/v1/metrics/with-children + +Create Metric With Children + +- Operation ID: `createMetricWithChildren` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/metrics/with-children" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/create_metric_api_v1_metrics_post.md b/docs-fumadocs/public/api-md/metrics/create_metric_api_v1_metrics_post.md new file mode 100644 index 00000000..ad5d24da --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/create_metric_api_v1_metrics_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/metrics + +Create Metric + +- Operation ID: `create_metric_api_v1_metrics_post` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/metrics" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/delete_metric_api_v1_metrics__metric_id__delete.md b/docs-fumadocs/public/api-md/metrics/delete_metric_api_v1_metrics__metric_id__delete.md new file mode 100644 index 00000000..5e94fa5d --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/delete_metric_api_v1_metrics__metric_id__delete.md @@ -0,0 +1,30 @@ +# DELETE /api/v1/metrics/{metric_id} + +Delete Metric + +- Operation ID: `delete_metric_api_v1_metrics__metric_id__delete` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `metric_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `204` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/metrics/{metric_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/generate_metric_api_v1_metrics_generate_post.md b/docs-fumadocs/public/api-md/metrics/generate_metric_api_v1_metrics_generate_post.md new file mode 100644 index 00000000..7c0b61aa --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/generate_metric_api_v1_metrics_generate_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/metrics/generate + +Generate Metric + +- Operation ID: `generate_metric_api_v1_metrics_generate_post` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/metrics/generate" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/get_metric_api_v1_metrics__metric_id__get.md b/docs-fumadocs/public/api-md/metrics/get_metric_api_v1_metrics__metric_id__get.md new file mode 100644 index 00000000..224abd8f --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/get_metric_api_v1_metrics__metric_id__get.md @@ -0,0 +1,30 @@ +# GET /api/v1/metrics/{metric_id} + +Get Metric + +- Operation ID: `get_metric_api_v1_metrics__metric_id__get` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `metric_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/metrics/{metric_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/list_metrics_api_v1_metrics_get.md b/docs-fumadocs/public/api-md/metrics/list_metrics_api_v1_metrics_get.md new file mode 100644 index 00000000..ca9d510c --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/list_metrics_api_v1_metrics_get.md @@ -0,0 +1,38 @@ +# GET /api/v1/metrics + +List Metrics + +- Operation ID: `list_metrics_api_v1_metrics_get` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `surface` (query, optional) +- `include_drafts` (query, optional) `boolean` + - When true, include draft metrics (Studio-only) in the listing. +- `drafts_only` (query, optional) `boolean` + - When true, return only draft metrics. +- `enabled_only` (query, optional) `boolean` + - When true, return only metrics enabled in the active workspace. Category parents are included when at least one child is enabled. +- `include_children` (query, optional) `boolean` + - When true (default), children are nested under their parent and not returned as top-level rows. When false, the response is a flat list of every metric (parents + standalone + orphaned children). +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/metrics" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/parse_bulk_metric_api_v1_metrics_parse_bulk_post.md b/docs-fumadocs/public/api-md/metrics/parse_bulk_metric_api_v1_metrics_parse_bulk_post.md new file mode 100644 index 00000000..2d413d8d --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/parse_bulk_metric_api_v1_metrics_parse_bulk_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/metrics/parse-bulk + +Parse Bulk Metric + +- Operation ID: `parse_bulk_metric_api_v1_metrics_parse_bulk_post` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/metrics/parse-bulk" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/promoteDiscoveredChild.md b/docs-fumadocs/public/api-md/metrics/promoteDiscoveredChild.md new file mode 100644 index 00000000..121cfa3e --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/promoteDiscoveredChild.md @@ -0,0 +1,34 @@ +# POST /api/v1/metrics/{metric_id}/children/from-discovered + +Promote Discovered Child + +- Operation ID: `promoteDiscoveredChild` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `metric_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/metrics/{metric_id}/children/from-discovered" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/promoteDiscoveredMetric.md b/docs-fumadocs/public/api-md/metrics/promoteDiscoveredMetric.md new file mode 100644 index 00000000..b5396aa0 --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/promoteDiscoveredMetric.md @@ -0,0 +1,33 @@ +# POST /api/v1/metrics/from-discovered + +Promote Discovered Metric + +- Operation ID: `promoteDiscoveredMetric` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/metrics/from-discovered" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/promoteMetricDraft.md b/docs-fumadocs/public/api-md/metrics/promoteMetricDraft.md new file mode 100644 index 00000000..fd446fe5 --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/promoteMetricDraft.md @@ -0,0 +1,30 @@ +# POST /api/v1/metrics/{metric_id}/promote + +Promote Metric Draft + +- Operation ID: `promoteMetricDraft` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `metric_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/metrics/{metric_id}/promote" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/seed_default_metrics_api_v1_metrics_seed_defaults_post.md b/docs-fumadocs/public/api-md/metrics/seed_default_metrics_api_v1_metrics_seed_defaults_post.md new file mode 100644 index 00000000..8b8bc219 --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/seed_default_metrics_api_v1_metrics_seed_defaults_post.md @@ -0,0 +1,29 @@ +# POST /api/v1/metrics/seed-defaults + +Seed Default Metrics + +- Operation ID: `seed_default_metrics_api_v1_metrics_seed_defaults_post` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/metrics/seed-defaults" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/metrics/update_metric_api_v1_metrics__metric_id__put.md b/docs-fumadocs/public/api-md/metrics/update_metric_api_v1_metrics__metric_id__put.md new file mode 100644 index 00000000..706b1bc3 --- /dev/null +++ b/docs-fumadocs/public/api-md/metrics/update_metric_api_v1_metrics__metric_id__put.md @@ -0,0 +1,34 @@ +# PUT /api/v1/metrics/{metric_id} + +Update Metric + +- Operation ID: `update_metric_api_v1_metrics__metric_id__put` +- Tags: `Metrics` +- Auth: Bearer or API Key + +## Parameters + +- `metric_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/metrics/{metric_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/observability/delete_call_api_v1_observability_calls__call_short_id__delete.md b/docs-fumadocs/public/api-md/observability/delete_call_api_v1_observability_calls__call_short_id__delete.md new file mode 100644 index 00000000..c3b7c34a --- /dev/null +++ b/docs-fumadocs/public/api-md/observability/delete_call_api_v1_observability_calls__call_short_id__delete.md @@ -0,0 +1,30 @@ +# DELETE /api/v1/observability/calls/{call_short_id} + +Delete Call + +- Operation ID: `delete_call_api_v1_observability_calls__call_short_id__delete` +- Tags: `Observability` +- Auth: Bearer or API Key + +## Parameters + +- `call_short_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/observability/calls/{call_short_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/observability/evaluate_call_api_v1_observability_calls__call_short_id__evaluate_post.md b/docs-fumadocs/public/api-md/observability/evaluate_call_api_v1_observability_calls__call_short_id__evaluate_post.md new file mode 100644 index 00000000..85d2d039 --- /dev/null +++ b/docs-fumadocs/public/api-md/observability/evaluate_call_api_v1_observability_calls__call_short_id__evaluate_post.md @@ -0,0 +1,34 @@ +# POST /api/v1/observability/calls/{call_short_id}/evaluate + +Evaluate Call + +- Operation ID: `evaluate_call_api_v1_observability_calls__call_short_id__evaluate_post` +- Tags: `Observability` +- Auth: Bearer or API Key + +## Parameters + +- `call_short_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/observability/calls/{call_short_id}/evaluate" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/observability/get_call_api_v1_observability_calls__call_short_id__get.md b/docs-fumadocs/public/api-md/observability/get_call_api_v1_observability_calls__call_short_id__get.md new file mode 100644 index 00000000..edf1a6c9 --- /dev/null +++ b/docs-fumadocs/public/api-md/observability/get_call_api_v1_observability_calls__call_short_id__get.md @@ -0,0 +1,30 @@ +# GET /api/v1/observability/calls/{call_short_id} + +Get Call + +- Operation ID: `get_call_api_v1_observability_calls__call_short_id__get` +- Tags: `Observability` +- Auth: Bearer or API Key + +## Parameters + +- `call_short_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/observability/calls/{call_short_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/observability/ingest_call_via_webhook_url_api_v1_observability_calls_webhook__api_key__post.md b/docs-fumadocs/public/api-md/observability/ingest_call_via_webhook_url_api_v1_observability_calls_webhook__api_key__post.md new file mode 100644 index 00000000..feaf4ef0 --- /dev/null +++ b/docs-fumadocs/public/api-md/observability/ingest_call_via_webhook_url_api_v1_observability_calls_webhook__api_key__post.md @@ -0,0 +1,34 @@ +# POST /api/v1/observability/calls/webhook/{api_key} + +Ingest Call Via Webhook Url + +- Operation ID: `ingest_call_via_webhook_url_api_v1_observability_calls_webhook__api_key__post` +- Tags: `Observability` +- Auth: Bearer or API Key + +## Parameters + +- `api_key` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/observability/calls/webhook/{api_key}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/observability/ingest_retell_webhook_api_v1_observability_calls_webhook_retell__api_key__post.md b/docs-fumadocs/public/api-md/observability/ingest_retell_webhook_api_v1_observability_calls_webhook_retell__api_key__post.md new file mode 100644 index 00000000..6bf2bbd7 --- /dev/null +++ b/docs-fumadocs/public/api-md/observability/ingest_retell_webhook_api_v1_observability_calls_webhook_retell__api_key__post.md @@ -0,0 +1,34 @@ +# POST /api/v1/observability/calls/webhook/retell/{api_key} + +Ingest Retell Webhook + +- Operation ID: `ingest_retell_webhook_api_v1_observability_calls_webhook_retell__api_key__post` +- Tags: `Observability` +- Auth: Bearer or API Key + +## Parameters + +- `api_key` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/observability/calls/webhook/retell/{api_key}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/observability/list_calls_api_v1_observability_calls_get.md b/docs-fumadocs/public/api-md/observability/list_calls_api_v1_observability_calls_get.md new file mode 100644 index 00000000..520fedc9 --- /dev/null +++ b/docs-fumadocs/public/api-md/observability/list_calls_api_v1_observability_calls_get.md @@ -0,0 +1,31 @@ +# GET /api/v1/observability/calls + +List Calls + +- Operation ID: `list_calls_api_v1_observability_calls_get` +- Tags: `Observability` +- Auth: Bearer or API Key + +## Parameters + +- `skip` (query, optional) `integer` +- `limit` (query, optional) `integer` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/observability/calls" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/observability/stream_call_live_events_api_v1_observability_calls__call_short_id__live_events_get.md b/docs-fumadocs/public/api-md/observability/stream_call_live_events_api_v1_observability_calls__call_short_id__live_events_get.md new file mode 100644 index 00000000..01453b21 --- /dev/null +++ b/docs-fumadocs/public/api-md/observability/stream_call_live_events_api_v1_observability_calls__call_short_id__live_events_get.md @@ -0,0 +1,30 @@ +# GET /api/v1/observability/calls/{call_short_id}/live-events + +Stream Call Live Events + +- Operation ID: `stream_call_live_events_api_v1_observability_calls__call_short_id__live_events_get` +- Tags: `Observability` +- Auth: Bearer or API Key + +## Parameters + +- `call_short_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/observability/calls/{call_short_id}/live-events" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/observability/stream_observability_call_audio_api_v1_observability_calls__call_short_id__audio_get.md b/docs-fumadocs/public/api-md/observability/stream_observability_call_audio_api_v1_observability_calls__call_short_id__audio_get.md new file mode 100644 index 00000000..087f6630 --- /dev/null +++ b/docs-fumadocs/public/api-md/observability/stream_observability_call_audio_api_v1_observability_calls__call_short_id__audio_get.md @@ -0,0 +1,30 @@ +# GET /api/v1/observability/calls/{call_short_id}/audio + +Stream Observability Call Audio + +- Operation ID: `stream_observability_call_audio_api_v1_observability_calls__call_short_id__audio_get` +- Tags: `Observability` +- Auth: Bearer or API Key + +## Parameters + +- `call_short_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/observability/calls/{call_short_id}/audio" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/clone_persona_api_v1_personas__persona_id__clone_post.md b/docs-fumadocs/public/api-md/personas/clone_persona_api_v1_personas__persona_id__clone_post.md new file mode 100644 index 00000000..91cc7979 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/clone_persona_api_v1_personas__persona_id__clone_post.md @@ -0,0 +1,34 @@ +# POST /api/v1/personas/{persona_id}/clone + +Clone Persona + +- Operation ID: `clone_persona_api_v1_personas__persona_id__clone_post` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `persona_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/personas/{persona_id}/clone" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/createPersonaCustomVoice.md b/docs-fumadocs/public/api-md/personas/createPersonaCustomVoice.md new file mode 100644 index 00000000..bc5c4b4f --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/createPersonaCustomVoice.md @@ -0,0 +1,33 @@ +# POST /api/v1/personas/custom-voices + +Create Custom Voice + +- Operation ID: `createPersonaCustomVoice` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/personas/custom-voices" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/create_persona_api_v1_personas_post.md b/docs-fumadocs/public/api-md/personas/create_persona_api_v1_personas_post.md new file mode 100644 index 00000000..8cf5a91f --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/create_persona_api_v1_personas_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/personas + +Create Persona + +- Operation ID: `create_persona_api_v1_personas_post` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/personas" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/deleteAmbientLibraryAsset.md b/docs-fumadocs/public/api-md/personas/deleteAmbientLibraryAsset.md new file mode 100644 index 00000000..1580fc6a --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/deleteAmbientLibraryAsset.md @@ -0,0 +1,30 @@ +# DELETE /api/v1/personas/ambient-library/{asset_id} + +Delete Ambient Library Asset + +- Operation ID: `deleteAmbientLibraryAsset` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `asset_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/personas/ambient-library/{asset_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/deletePersonaAmbientAudio.md b/docs-fumadocs/public/api-md/personas/deletePersonaAmbientAudio.md new file mode 100644 index 00000000..e6d7e397 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/deletePersonaAmbientAudio.md @@ -0,0 +1,30 @@ +# DELETE /api/v1/personas/{persona_id}/ambient-audio + +Delete Persona Ambient Audio + +- Operation ID: `deletePersonaAmbientAudio` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `persona_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/personas/{persona_id}/ambient-audio" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/deletePersonaCustomVoice.md b/docs-fumadocs/public/api-md/personas/deletePersonaCustomVoice.md new file mode 100644 index 00000000..59ed3ccd --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/deletePersonaCustomVoice.md @@ -0,0 +1,30 @@ +# DELETE /api/v1/personas/custom-voices/{custom_voice_id} + +Delete Custom Voice + +- Operation ID: `deletePersonaCustomVoice` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `custom_voice_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/personas/custom-voices/{custom_voice_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/delete_persona_api_v1_personas__persona_id__delete.md b/docs-fumadocs/public/api-md/personas/delete_persona_api_v1_personas__persona_id__delete.md new file mode 100644 index 00000000..0cedc837 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/delete_persona_api_v1_personas__persona_id__delete.md @@ -0,0 +1,32 @@ +# DELETE /api/v1/personas/{persona_id} + +Delete Persona + +- Operation ID: `delete_persona_api_v1_personas__persona_id__delete` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `persona_id` (path, required) `string` +- `force` (query, optional) `boolean` + - Force delete with all dependent records +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/personas/{persona_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/generatePersonaPrompt.md b/docs-fumadocs/public/api-md/personas/generatePersonaPrompt.md new file mode 100644 index 00000000..d36c8e71 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/generatePersonaPrompt.md @@ -0,0 +1,33 @@ +# POST /api/v1/personas/generate-prompt + +Generate Persona Prompt + +- Operation ID: `generatePersonaPrompt` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/personas/generate-prompt" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/getAmbientLibraryPreviewUrl.md b/docs-fumadocs/public/api-md/personas/getAmbientLibraryPreviewUrl.md new file mode 100644 index 00000000..7a858398 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/getAmbientLibraryPreviewUrl.md @@ -0,0 +1,31 @@ +# GET /api/v1/personas/ambient-library/{asset_id}/preview-url + +Get Ambient Library Preview Url + +- Operation ID: `getAmbientLibraryPreviewUrl` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `asset_id` (path, required) `string` +- `expiration` (query, optional) `integer` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/personas/ambient-library/{asset_id}/preview-url" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/getPersonaAgentPromptSources.md b/docs-fumadocs/public/api-md/personas/getPersonaAgentPromptSources.md new file mode 100644 index 00000000..9d2eb52a --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/getPersonaAgentPromptSources.md @@ -0,0 +1,30 @@ +# GET /api/v1/personas/agent-prompt-sources/{agent_id} + +Get Agent Prompt Sources + +- Operation ID: `getPersonaAgentPromptSources` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `agent_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/personas/agent-prompt-sources/{agent_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/getPersonaVoiceOptions.md b/docs-fumadocs/public/api-md/personas/getPersonaVoiceOptions.md new file mode 100644 index 00000000..1d18b252 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/getPersonaVoiceOptions.md @@ -0,0 +1,30 @@ +# GET /api/v1/personas/voice-options + +Get Voice Options + +- Operation ID: `getPersonaVoiceOptions` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `provider` (query, optional) +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/personas/voice-options" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/get_persona_api_v1_personas__persona_id__get.md b/docs-fumadocs/public/api-md/personas/get_persona_api_v1_personas__persona_id__get.md new file mode 100644 index 00000000..643c2054 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/get_persona_api_v1_personas__persona_id__get.md @@ -0,0 +1,30 @@ +# GET /api/v1/personas/{persona_id} + +Get Persona + +- Operation ID: `get_persona_api_v1_personas__persona_id__get` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `persona_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/personas/{persona_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/listAmbientLibrary.md b/docs-fumadocs/public/api-md/personas/listAmbientLibrary.md new file mode 100644 index 00000000..0ae9a1f7 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/listAmbientLibrary.md @@ -0,0 +1,29 @@ +# GET /api/v1/personas/ambient-library + +List Ambient Library + +- Operation ID: `listAmbientLibrary` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/personas/ambient-library" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/listAmbientPresets.md b/docs-fumadocs/public/api-md/personas/listAmbientPresets.md new file mode 100644 index 00000000..e8f4feba --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/listAmbientPresets.md @@ -0,0 +1,29 @@ +# GET /api/v1/personas/ambient-presets + +List Platform Ambient Presets + +- Operation ID: `listAmbientPresets` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/personas/ambient-presets" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/listPersonaCustomVoices.md b/docs-fumadocs/public/api-md/personas/listPersonaCustomVoices.md new file mode 100644 index 00000000..a4ded251 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/listPersonaCustomVoices.md @@ -0,0 +1,30 @@ +# GET /api/v1/personas/custom-voices + +List Custom Voices + +- Operation ID: `listPersonaCustomVoices` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `provider` (query, optional) +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/personas/custom-voices" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/list_personas_api_v1_personas_get.md b/docs-fumadocs/public/api-md/personas/list_personas_api_v1_personas_get.md new file mode 100644 index 00000000..1a82fe10 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/list_personas_api_v1_personas_get.md @@ -0,0 +1,31 @@ +# GET /api/v1/personas + +List Personas + +- Operation ID: `list_personas_api_v1_personas_get` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `skip` (query, optional) `integer` +- `limit` (query, optional) `integer` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/personas" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/previewAmbientLibraryAsset.md b/docs-fumadocs/public/api-md/personas/previewAmbientLibraryAsset.md new file mode 100644 index 00000000..163ae32d --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/previewAmbientLibraryAsset.md @@ -0,0 +1,30 @@ +# GET /api/v1/personas/ambient-library/{asset_id}/preview + +Preview Ambient Library Asset + +- Operation ID: `previewAmbientLibraryAsset` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `asset_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/personas/ambient-library/{asset_id}/preview" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/previewAmbientPreset.md b/docs-fumadocs/public/api-md/personas/previewAmbientPreset.md new file mode 100644 index 00000000..3a68cd23 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/previewAmbientPreset.md @@ -0,0 +1,30 @@ +# GET /api/v1/personas/ambient-presets/{preset_id}/preview + +Preview Ambient Preset + +- Operation ID: `previewAmbientPreset` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `preset_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/personas/ambient-presets/{preset_id}/preview" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/seed_demo_data_api_v1_personas_seed_data_post.md b/docs-fumadocs/public/api-md/personas/seed_demo_data_api_v1_personas_seed_data_post.md new file mode 100644 index 00000000..262a1367 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/seed_demo_data_api_v1_personas_seed_data_post.md @@ -0,0 +1,29 @@ +# POST /api/v1/personas/seed-data + +Seed Demo Data + +- Operation ID: `seed_demo_data_api_v1_personas_seed_data_post` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/personas/seed-data" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/updateAmbientLibraryAsset.md b/docs-fumadocs/public/api-md/personas/updateAmbientLibraryAsset.md new file mode 100644 index 00000000..f791d417 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/updateAmbientLibraryAsset.md @@ -0,0 +1,34 @@ +# PATCH /api/v1/personas/ambient-library/{asset_id} + +Update Ambient Library Asset + +- Operation ID: `updateAmbientLibraryAsset` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `asset_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PATCH "http://localhost:8000/api/v1/personas/ambient-library/{asset_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/updatePersonaCustomVoice.md b/docs-fumadocs/public/api-md/personas/updatePersonaCustomVoice.md new file mode 100644 index 00000000..ad1d8e1d --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/updatePersonaCustomVoice.md @@ -0,0 +1,34 @@ +# PUT /api/v1/personas/custom-voices/{custom_voice_id} + +Update Custom Voice + +- Operation ID: `updatePersonaCustomVoice` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `custom_voice_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/personas/custom-voices/{custom_voice_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/update_persona_api_v1_personas__persona_id__put.md b/docs-fumadocs/public/api-md/personas/update_persona_api_v1_personas__persona_id__put.md new file mode 100644 index 00000000..d51f015a --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/update_persona_api_v1_personas__persona_id__put.md @@ -0,0 +1,34 @@ +# PUT /api/v1/personas/{persona_id} + +Update Persona + +- Operation ID: `update_persona_api_v1_personas__persona_id__put` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `persona_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/personas/{persona_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/uploadAmbientLibraryAsset.md b/docs-fumadocs/public/api-md/personas/uploadAmbientLibraryAsset.md new file mode 100644 index 00000000..ad68da15 --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/uploadAmbientLibraryAsset.md @@ -0,0 +1,33 @@ +# POST /api/v1/personas/ambient-library + +Upload Ambient Library Asset + +- Operation ID: `uploadAmbientLibraryAsset` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/personas/ambient-library" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/personas/uploadPersonaAmbientAudio.md b/docs-fumadocs/public/api-md/personas/uploadPersonaAmbientAudio.md new file mode 100644 index 00000000..bb8c96de --- /dev/null +++ b/docs-fumadocs/public/api-md/personas/uploadPersonaAmbientAudio.md @@ -0,0 +1,34 @@ +# POST /api/v1/personas/{persona_id}/ambient-audio + +Upload Persona Ambient Audio + +- Operation ID: `uploadPersonaAmbientAudio` +- Tags: `Personas` +- Auth: Bearer or API Key + +## Parameters + +- `persona_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) +- `X-Workspace-Id` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/personas/{persona_id}/ambient-audio" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/scenarios/create_scenario_api_v1_scenarios_post.md b/docs-fumadocs/public/api-md/scenarios/create_scenario_api_v1_scenarios_post.md new file mode 100644 index 00000000..ed9d4e27 --- /dev/null +++ b/docs-fumadocs/public/api-md/scenarios/create_scenario_api_v1_scenarios_post.md @@ -0,0 +1,33 @@ +# POST /api/v1/scenarios + +Create Scenario + +- Operation ID: `create_scenario_api_v1_scenarios_post` +- Tags: `Scenarios` +- Auth: Bearer or API Key + +## Parameters + +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/scenarios" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/scenarios/delete_scenario_api_v1_scenarios__scenario_id__delete.md b/docs-fumadocs/public/api-md/scenarios/delete_scenario_api_v1_scenarios__scenario_id__delete.md new file mode 100644 index 00000000..45a70e24 --- /dev/null +++ b/docs-fumadocs/public/api-md/scenarios/delete_scenario_api_v1_scenarios__scenario_id__delete.md @@ -0,0 +1,32 @@ +# DELETE /api/v1/scenarios/{scenario_id} + +Delete Scenario + +- Operation ID: `delete_scenario_api_v1_scenarios__scenario_id__delete` +- Tags: `Scenarios` +- Auth: Bearer or API Key + +## Parameters + +- `scenario_id` (path, required) `string` +- `force` (query, optional) `boolean` + - Force delete with all dependent records +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/scenarios/{scenario_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/scenarios/get_scenario_api_v1_scenarios__scenario_id__get.md b/docs-fumadocs/public/api-md/scenarios/get_scenario_api_v1_scenarios__scenario_id__get.md new file mode 100644 index 00000000..7d60001c --- /dev/null +++ b/docs-fumadocs/public/api-md/scenarios/get_scenario_api_v1_scenarios__scenario_id__get.md @@ -0,0 +1,30 @@ +# GET /api/v1/scenarios/{scenario_id} + +Get Scenario + +- Operation ID: `get_scenario_api_v1_scenarios__scenario_id__get` +- Tags: `Scenarios` +- Auth: Bearer or API Key + +## Parameters + +- `scenario_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/scenarios/{scenario_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/scenarios/list_scenarios_api_v1_scenarios_get.md b/docs-fumadocs/public/api-md/scenarios/list_scenarios_api_v1_scenarios_get.md new file mode 100644 index 00000000..ba1c9510 --- /dev/null +++ b/docs-fumadocs/public/api-md/scenarios/list_scenarios_api_v1_scenarios_get.md @@ -0,0 +1,32 @@ +# GET /api/v1/scenarios + +List Scenarios + +- Operation ID: `list_scenarios_api_v1_scenarios_get` +- Tags: `Scenarios` +- Auth: Bearer or API Key + +## Parameters + +- `skip` (query, optional) `integer` +- `limit` (query, optional) `integer` +- `agent_id` (query, optional) +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/scenarios" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/scenarios/update_scenario_api_v1_scenarios__scenario_id__put.md b/docs-fumadocs/public/api-md/scenarios/update_scenario_api_v1_scenarios__scenario_id__put.md new file mode 100644 index 00000000..59ed12bc --- /dev/null +++ b/docs-fumadocs/public/api-md/scenarios/update_scenario_api_v1_scenarios__scenario_id__put.md @@ -0,0 +1,34 @@ +# PUT /api/v1/scenarios/{scenario_id} + +Update Scenario + +- Operation ID: `update_scenario_api_v1_scenarios__scenario_id__put` +- Tags: `Scenarios` +- Auth: Bearer or API Key + +## Parameters + +- `scenario_id` (path, required) `string` +- `X-Workspace-Id` (header, optional) +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/scenarios/{scenario_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/voice-bundles/createVoiceBundle.md b/docs-fumadocs/public/api-md/voice-bundles/createVoiceBundle.md new file mode 100644 index 00000000..bfb65deb --- /dev/null +++ b/docs-fumadocs/public/api-md/voice-bundles/createVoiceBundle.md @@ -0,0 +1,32 @@ +# POST /api/v1/voicebundles + +Create Voicebundle + +- Operation ID: `createVoiceBundle` +- Tags: `Voice Bundles` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/voicebundles" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/voice-bundles/deleteVoiceBundle.md b/docs-fumadocs/public/api-md/voice-bundles/deleteVoiceBundle.md new file mode 100644 index 00000000..8a57a391 --- /dev/null +++ b/docs-fumadocs/public/api-md/voice-bundles/deleteVoiceBundle.md @@ -0,0 +1,31 @@ +# DELETE /api/v1/voicebundles/{voicebundle_id} + +Delete Voicebundle + +- Operation ID: `deleteVoiceBundle` +- Tags: `Voice Bundles` +- Auth: Bearer or API Key + +## Parameters + +- `voicebundle_id` (path, required) `string` +- `force` (query, optional) `boolean` + - Force delete with all dependent records +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/voicebundles/{voicebundle_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/voice-bundles/get_voicebundle_api_v1_voicebundles__voicebundle_id__get.md b/docs-fumadocs/public/api-md/voice-bundles/get_voicebundle_api_v1_voicebundles__voicebundle_id__get.md new file mode 100644 index 00000000..be91545d --- /dev/null +++ b/docs-fumadocs/public/api-md/voice-bundles/get_voicebundle_api_v1_voicebundles__voicebundle_id__get.md @@ -0,0 +1,29 @@ +# GET /api/v1/voicebundles/{voicebundle_id} + +Get Voicebundle + +- Operation ID: `get_voicebundle_api_v1_voicebundles__voicebundle_id__get` +- Tags: `Voice Bundles` +- Auth: Bearer or API Key + +## Parameters + +- `voicebundle_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/voicebundles/{voicebundle_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/voice-bundles/listVoiceBundles.md b/docs-fumadocs/public/api-md/voice-bundles/listVoiceBundles.md new file mode 100644 index 00000000..e070f55e --- /dev/null +++ b/docs-fumadocs/public/api-md/voice-bundles/listVoiceBundles.md @@ -0,0 +1,30 @@ +# GET /api/v1/voicebundles + +List Voicebundles + +- Operation ID: `listVoiceBundles` +- Tags: `Voice Bundles` +- Auth: Bearer or API Key + +## Parameters + +- `skip` (query, optional) `integer` +- `limit` (query, optional) `integer` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/voicebundles" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/voice-bundles/updateVoiceBundle.md b/docs-fumadocs/public/api-md/voice-bundles/updateVoiceBundle.md new file mode 100644 index 00000000..d460bdc2 --- /dev/null +++ b/docs-fumadocs/public/api-md/voice-bundles/updateVoiceBundle.md @@ -0,0 +1,33 @@ +# PUT /api/v1/voicebundles/{voicebundle_id} + +Update Voicebundle + +- Operation ID: `updateVoiceBundle` +- Tags: `Voice Bundles` +- Auth: Bearer or API Key + +## Parameters + +- `voicebundle_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PUT "http://localhost:8000/api/v1/voicebundles/{voicebundle_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/workspaces/create_workspace_api_v1_workspaces_post.md b/docs-fumadocs/public/api-md/workspaces/create_workspace_api_v1_workspaces_post.md new file mode 100644 index 00000000..2ca4ab9d --- /dev/null +++ b/docs-fumadocs/public/api-md/workspaces/create_workspace_api_v1_workspaces_post.md @@ -0,0 +1,32 @@ +# POST /api/v1/workspaces + +Create Workspace + +- Operation ID: `create_workspace_api_v1_workspaces_post` +- Tags: `Workspaces` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `201` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X POST "http://localhost:8000/api/v1/workspaces" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/workspaces/delete_workspace_api_v1_workspaces__workspace_id__delete.md b/docs-fumadocs/public/api-md/workspaces/delete_workspace_api_v1_workspaces__workspace_id__delete.md new file mode 100644 index 00000000..03d5def6 --- /dev/null +++ b/docs-fumadocs/public/api-md/workspaces/delete_workspace_api_v1_workspaces__workspace_id__delete.md @@ -0,0 +1,29 @@ +# DELETE /api/v1/workspaces/{workspace_id} + +Delete Workspace + +- Operation ID: `delete_workspace_api_v1_workspaces__workspace_id__delete` +- Tags: `Workspaces` +- Auth: Bearer or API Key + +## Parameters + +- `workspace_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `204` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X DELETE "http://localhost:8000/api/v1/workspaces/{workspace_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/workspaces/list_workspaces_api_v1_workspaces_get.md b/docs-fumadocs/public/api-md/workspaces/list_workspaces_api_v1_workspaces_get.md new file mode 100644 index 00000000..4eeca3ce --- /dev/null +++ b/docs-fumadocs/public/api-md/workspaces/list_workspaces_api_v1_workspaces_get.md @@ -0,0 +1,28 @@ +# GET /api/v1/workspaces + +List Workspaces + +- Operation ID: `list_workspaces_api_v1_workspaces_get` +- Tags: `Workspaces` +- Auth: Bearer or API Key + +## Parameters + +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X GET "http://localhost:8000/api/v1/workspaces" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/api-md/workspaces/update_workspace_api_v1_workspaces__workspace_id__patch.md b/docs-fumadocs/public/api-md/workspaces/update_workspace_api_v1_workspaces__workspace_id__patch.md new file mode 100644 index 00000000..3a9cc5f5 --- /dev/null +++ b/docs-fumadocs/public/api-md/workspaces/update_workspace_api_v1_workspaces__workspace_id__patch.md @@ -0,0 +1,33 @@ +# PATCH /api/v1/workspaces/{workspace_id} + +Update Workspace + +- Operation ID: `update_workspace_api_v1_workspaces__workspace_id__patch` +- Tags: `Workspaces` +- Auth: Bearer or API Key + +## Parameters + +- `workspace_id` (path, required) `string` +- `Authorization` (header, optional) +- `X-API-Key` (header, optional) +- `X-EFFICIENTAI-API-KEY` (header, optional) + +## Request Body + +See schema in API reference UI. + +## Responses + +- `200` - Successful Response +- `422` - Validation Error + +## cURL + +```bash +curl -X PATCH "http://localhost:8000/api/v1/workspaces/{workspace_id}" \ + -H "Authorization: Bearer " \ + -H "X-API-Key: " \ + -H "Content-Type: application/json" +``` + diff --git a/docs-fumadocs/public/favicon_dark.png b/docs-fumadocs/public/favicon_dark.png index adde4a99..653f1d63 100644 Binary files a/docs-fumadocs/public/favicon_dark.png and b/docs-fumadocs/public/favicon_dark.png differ diff --git a/docs-fumadocs/public/favicon_light.png b/docs-fumadocs/public/favicon_light.png index a282a2d2..d7e72b99 100644 Binary files a/docs-fumadocs/public/favicon_light.png and b/docs-fumadocs/public/favicon_light.png differ diff --git a/docs-fumadocs/public/screenshots/Agents/Agent_homepage.png b/docs-fumadocs/public/screenshots/Agents/Agent_homepage.png new file mode 100644 index 00000000..559d5db5 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Agents/Agent_homepage.png differ diff --git a/docs-fumadocs/public/screenshots/Agents/Agent_prompt_partial.png b/docs-fumadocs/public/screenshots/Agents/Agent_prompt_partial.png new file mode 100644 index 00000000..8c054654 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Agents/Agent_prompt_partial.png differ diff --git a/docs-fumadocs/public/screenshots/Agents/Agent_telephony.png b/docs-fumadocs/public/screenshots/Agents/Agent_telephony.png new file mode 100644 index 00000000..77f1e9dd Binary files /dev/null and b/docs-fumadocs/public/screenshots/Agents/Agent_telephony.png differ diff --git a/docs-fumadocs/public/screenshots/Agents/Agent_webRTC.png b/docs-fumadocs/public/screenshots/Agents/Agent_webRTC.png new file mode 100644 index 00000000..3e21a3a3 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Agents/Agent_webRTC.png differ diff --git a/docs-fumadocs/public/screenshots/Alerts/alerts.png b/docs-fumadocs/public/screenshots/Alerts/alerts.png new file mode 100644 index 00000000..69b85794 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Alerts/alerts.png differ diff --git a/docs-fumadocs/public/screenshots/Evaluator/Evaluation_results.png b/docs-fumadocs/public/screenshots/Evaluator/Evaluation_results.png new file mode 100644 index 00000000..85f9ec7f Binary files /dev/null and b/docs-fumadocs/public/screenshots/Evaluator/Evaluation_results.png differ diff --git a/docs-fumadocs/public/screenshots/Evaluator/Evaluator_suite.png b/docs-fumadocs/public/screenshots/Evaluator/Evaluator_suite.png new file mode 100644 index 00000000..661a144e Binary files /dev/null and b/docs-fumadocs/public/screenshots/Evaluator/Evaluator_suite.png differ diff --git a/docs-fumadocs/public/screenshots/IAM/iam.png b/docs-fumadocs/public/screenshots/IAM/iam.png new file mode 100644 index 00000000..b356f878 Binary files /dev/null and b/docs-fumadocs/public/screenshots/IAM/iam.png differ diff --git a/docs-fumadocs/public/screenshots/integration-section.png b/docs-fumadocs/public/screenshots/Integrations/integration-section.png similarity index 100% rename from docs-fumadocs/public/screenshots/integration-section.png rename to docs-fumadocs/public/screenshots/Integrations/integration-section.png diff --git a/docs-fumadocs/public/screenshots/voice-bundle.png b/docs-fumadocs/public/screenshots/Integrations/voice-bundle.png similarity index 100% rename from docs-fumadocs/public/screenshots/voice-bundle.png rename to docs-fumadocs/public/screenshots/Integrations/voice-bundle.png diff --git a/docs-fumadocs/public/screenshots/Metrics/Categorizaion_labels.png b/docs-fumadocs/public/screenshots/Metrics/Categorizaion_labels.png new file mode 100644 index 00000000..b20f7c52 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Metrics/Categorizaion_labels.png differ diff --git a/docs-fumadocs/public/screenshots/Metrics/Metrics_homepage.png b/docs-fumadocs/public/screenshots/Metrics/Metrics_homepage.png new file mode 100644 index 00000000..17f74e15 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Metrics/Metrics_homepage.png differ diff --git a/docs-fumadocs/public/screenshots/Metrics/Single_metric.png b/docs-fumadocs/public/screenshots/Metrics/Single_metric.png new file mode 100644 index 00000000..34aed162 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Metrics/Single_metric.png differ diff --git a/docs-fumadocs/public/screenshots/Persona/Persona_Page.png b/docs-fumadocs/public/screenshots/Persona/Persona_Page.png new file mode 100644 index 00000000..a961f02a Binary files /dev/null and b/docs-fumadocs/public/screenshots/Persona/Persona_Page.png differ diff --git a/docs-fumadocs/public/screenshots/Persona/Persona_TTS.png b/docs-fumadocs/public/screenshots/Persona/Persona_TTS.png new file mode 100644 index 00000000..37b042d3 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Persona/Persona_TTS.png differ diff --git a/docs-fumadocs/public/screenshots/Persona/Persona_behaviour.png b/docs-fumadocs/public/screenshots/Persona/Persona_behaviour.png new file mode 100644 index 00000000..bc2bd8a1 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Persona/Persona_behaviour.png differ diff --git a/docs-fumadocs/public/screenshots/Persona/Persona_prompt.png b/docs-fumadocs/public/screenshots/Persona/Persona_prompt.png new file mode 100644 index 00000000..5370455c Binary files /dev/null and b/docs-fumadocs/public/screenshots/Persona/Persona_prompt.png differ diff --git a/docs-fumadocs/public/screenshots/Persona/Persona_voice.png b/docs-fumadocs/public/screenshots/Persona/Persona_voice.png new file mode 100644 index 00000000..05efd65c Binary files /dev/null and b/docs-fumadocs/public/screenshots/Persona/Persona_voice.png differ diff --git a/docs-fumadocs/public/screenshots/Playground/Agent_voiceAI.png b/docs-fumadocs/public/screenshots/Playground/Agent_voiceAI.png new file mode 100644 index 00000000..3db88fd4 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Playground/Agent_voiceAI.png differ diff --git a/docs-fumadocs/public/screenshots/Playground/Playground_testagent.png b/docs-fumadocs/public/screenshots/Playground/Playground_testagent.png new file mode 100644 index 00000000..0a190e10 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Playground/Playground_testagent.png differ diff --git a/docs-fumadocs/public/screenshots/Prompts/Agent_prompt,partial.png b/docs-fumadocs/public/screenshots/Prompts/Agent_prompt,partial.png new file mode 100644 index 00000000..ded34c3e Binary files /dev/null and b/docs-fumadocs/public/screenshots/Prompts/Agent_prompt,partial.png differ diff --git a/docs-fumadocs/public/screenshots/Prompts/Create_prompt,partial.png b/docs-fumadocs/public/screenshots/Prompts/Create_prompt,partial.png new file mode 100644 index 00000000..1e7b7281 Binary files /dev/null and b/docs-fumadocs/public/screenshots/Prompts/Create_prompt,partial.png differ diff --git a/docs-fumadocs/public/screenshots/Prompts/Prompt_partial.png b/docs-fumadocs/public/screenshots/Prompts/Prompt_partial.png new file mode 100644 index 00000000..3c28573d Binary files /dev/null and b/docs-fumadocs/public/screenshots/Prompts/Prompt_partial.png differ diff --git a/docs-fumadocs/public/screenshots/creating-scenarios.png b/docs-fumadocs/public/screenshots/Scenario/creating-scenarios.png similarity index 100% rename from docs-fumadocs/public/screenshots/creating-scenarios.png rename to docs-fumadocs/public/screenshots/Scenario/creating-scenarios.png diff --git a/docs-fumadocs/public/screenshots/create_workspace.png b/docs-fumadocs/public/screenshots/create_workspace.png deleted file mode 100644 index fae06b85..00000000 Binary files a/docs-fumadocs/public/screenshots/create_workspace.png and /dev/null differ diff --git a/docs-fumadocs/public/screenshots/creating-agents.png b/docs-fumadocs/public/screenshots/creating-agents.png deleted file mode 100644 index f9714dd3..00000000 Binary files a/docs-fumadocs/public/screenshots/creating-agents.png and /dev/null differ diff --git a/docs-fumadocs/public/screenshots/creating-personas.png b/docs-fumadocs/public/screenshots/creating-personas.png deleted file mode 100644 index 4189966c..00000000 Binary files a/docs-fumadocs/public/screenshots/creating-personas.png and /dev/null differ diff --git a/docs-fumadocs/public/screenshots/iam_workspaces.png b/docs-fumadocs/public/screenshots/iam_workspaces.png deleted file mode 100644 index 43ecfb19..00000000 Binary files a/docs-fumadocs/public/screenshots/iam_workspaces.png and /dev/null differ diff --git a/docs-fumadocs/public/search-index.json b/docs-fumadocs/public/search-index.json index 2d7daadc..9a0a219a 100644 --- a/docs-fumadocs/public/search-index.json +++ b/docs-fumadocs/public/search-index.json @@ -1,42 +1,2193 @@ { - "generatedAt": "2026-08-18T13:39:50.745Z", - "count": 35, + "generatedAt": "2026-09-21T05:22:20.310Z", + "count": 271, "records": [ + { + "id": "(docs)/index", + "url": "/docs/", + "title": "Docs", + "breadcrumbs": [], + "content": "