- {importedConnections.map((conn, idx) => (
-
-
-
-
-
-
-
- {conn.name || conn.provider}
-
-
-
- {conn.provider}
-
-
- {conn.status}
-
-
+ ) : importedConnections.length > 0 ? (
+
+ {importedConnections.map((conn, idx) => (
+
+
+
+
+
+
+
{conn.name || conn.provider}
+
+
+ {conn.provider}
+
+ {conn.status}
-
- ))}
-
- ) : (
-
} title="No credentials" desc="Connect integrations from the chat or configure defaults in Integrations." />
- )
+
+
+ ))}
+
+ ) : (
+
}
+ title="No credentials"
+ desc="Connect integrations from the chat or configure defaults in Integrations."
+ />
)}
)}
diff --git a/studio/web/src/app/dashboard/agents/import/page.tsx b/studio/web/src/app/dashboard/agents/import/page.tsx
index afe1318..9d44288 100644
--- a/studio/web/src/app/dashboard/agents/import/page.tsx
+++ b/studio/web/src/app/dashboard/agents/import/page.tsx
@@ -69,11 +69,7 @@ export default function ImportAgentPage() {
const [submitting, setSubmitting] = useState(false);
const handleParsedChange = useCallback(
- (
- nextParsed: unknown,
- nextError: string | null,
- nextStatus: ImportConfigParseStatus
- ) => {
+ (nextParsed: unknown, nextError: string | null, nextStatus: ImportConfigParseStatus) => {
if (!nextParsed || nextError) {
setFullConfig(null);
setParsedConfig(null);
@@ -103,10 +99,7 @@ export default function ImportAgentPage() {
() => allIssues.filter((issue) => issue.blocking && issue.severity === "error"),
[allIssues]
);
- const fulfillmentIssues = useMemo(
- () => validation?.fulfillment_issues ?? [],
- [validation]
- );
+ const fulfillmentIssues = useMemo(() => validation?.fulfillment_issues ?? [], [validation]);
const hasFulfillmentIssues = fulfillmentIssues.length > 0;
const mappingRows = useMemo(
@@ -118,10 +111,7 @@ export default function ImportAgentPage() {
fromValue: String(
validation?.normalized_config?.[issue.path as keyof AgentGraphConfig] ?? ""
),
- mappedTo:
- mappings[issue.path as string] ||
- issue.suggested_value ||
- "",
+ mappedTo: mappings[issue.path as string] || issue.suggested_value || "",
})),
[fulfillmentIssues, mappings, validation]
);
@@ -137,8 +127,7 @@ export default function ImportAgentPage() {
[blockingIssues, mappings]
);
- const canProceedFromStep2 =
- blockingIssues.length === 0 || canResolveBlockingViaMappings;
+ const canProceedFromStep2 = blockingIssues.length === 0 || canResolveBlockingViaMappings;
const runValidation = async () => {
if (!parsedConfig) return;
@@ -191,9 +180,7 @@ export default function ImportAgentPage() {
full_config: {
$schema: fullConfig?.$schema ?? FULL_CONFIG_SCHEMA_URL,
name: fullConfig?.name ?? name.trim(),
- description:
- fullConfig?.description ??
- (description.trim() ? description.trim() : null),
+ description: fullConfig?.description ?? (description.trim() ? description.trim() : null),
config: validation.normalized_config,
mermaid_diagram: fullConfig?.mermaid_diagram ?? null,
connections: fullConfig?.connections ?? [],
@@ -208,14 +195,8 @@ export default function ImportAgentPage() {
if (error instanceof ApiError && error.detail && typeof error.detail === "object") {
const detail = error.detail as { issues?: unknown };
if (Array.isArray(detail.issues)) {
- const parsedIssues = detail.issues.filter(
- (item): item is ImportIssue =>
- Boolean(
- item &&
- typeof item === "object" &&
- "message" in item &&
- "code" in item
- )
+ const parsedIssues = detail.issues.filter((item): item is ImportIssue =>
+ Boolean(item && typeof item === "object" && "message" in item && "code" in item)
);
setSubmitIssueDetails(parsedIssues);
}
@@ -226,9 +207,7 @@ export default function ImportAgentPage() {
const renderSchemaIssues = (issues: ImportIssue[]) => (
-
- Schema
-
+
Schema
{issues.length === 0 ? (
@@ -239,7 +218,10 @@ export default function ImportAgentPage() {
) : (
{issues.map((issue, index) => (
-
+
{issue.message}
{issue.code}
@@ -269,7 +251,10 @@ export default function ImportAgentPage() {
<>
{issues.map((issue, index) => (
-
+
{issue.message}
{issue.code}
@@ -290,11 +275,18 @@ export default function ImportAgentPage() {
{row.property}
-
+
{row.fromValue || "unknown"}
-
-
+
+
{row.mappedTo || "no default"}
@@ -326,7 +318,10 @@ export default function ImportAgentPage() {
Validate imported config, resolve issues, and finalize metadata.
-
+
@@ -361,10 +356,10 @@ export default function ImportAgentPage() {
parseError
? "text-destructive"
: parseStatus === "invalid"
- ? "text-destructive"
- : parseStatus === "valid"
- ? "text-success"
- : "text-muted-foreground"
+ ? "text-destructive"
+ : parseStatus === "valid"
+ ? "text-success"
+ : "text-muted-foreground"
}`}
>
{parseError ? parseError : null}
@@ -389,7 +384,11 @@ export default function ImportAgentPage() {
disabled={!parsedConfig || Boolean(parseError) || validating}
className="h-8"
>
- {validating ? : }
+ {validating ? (
+
+ ) : (
+
+ )}
Validate config
@@ -403,10 +402,19 @@ export default function ImportAgentPage() {
{renderFulfillmentSection(validation.fulfillment_issues)}
-
@@ -440,11 +448,24 @@ export default function ImportAgentPage() {
- setStep(2)} className="gap-1.5">
+ setStep(2)}
+ className="gap-1.5"
+ >
Back
-
- {submitting ? : }
+
+ {submitting ? (
+
+ ) : (
+
+ )}
Import agent
@@ -459,7 +480,12 @@ export default function ImportAgentPage() {
{submitIssueDetails.map((issue, index) => (
{issue.code}
- {issue.path ? • {issue.path} : null}
+ {issue.path ? (
+
+ {" "}
+ • {issue.path}
+
+ ) : null}
• {issue.message}
{issue.suggested_value ? (
diff --git a/studio/web/src/app/dashboard/agents/page.tsx b/studio/web/src/app/dashboard/agents/page.tsx
index b23ca63..d5f769d 100644
--- a/studio/web/src/app/dashboard/agents/page.tsx
+++ b/studio/web/src/app/dashboard/agents/page.tsx
@@ -1,7 +1,13 @@
"use client";
import { HugeiconsIcon } from "@hugeicons/react";
-import { Add01Icon, AiScanIcon, HardDriveUploadIcon, Robot01Icon, Search01Icon } from "@hugeicons/core-free-icons";
+import {
+ Add01Icon,
+ AiScanIcon,
+ HardDriveUploadIcon,
+ Robot01Icon,
+ Search01Icon,
+} from "@hugeicons/core-free-icons";
import { useEffect, useState } from "react";
import { api, type Agent } from "@/lib/api/client";
import { Button } from "@/components/ui/button";
diff --git a/studio/web/src/components/agent/import-config-input.tsx b/studio/web/src/components/agent/import-config-input.tsx
index 1a45f5c..886e0ed 100644
--- a/studio/web/src/components/agent/import-config-input.tsx
+++ b/studio/web/src/components/agent/import-config-input.tsx
@@ -19,11 +19,7 @@ interface ImportConfigInputProps {
rawValue: string;
mode: "file" | "manual";
onRawValueChange: (value: string) => void;
- onParsedChange: (
- config: unknown,
- error: string | null,
- status: ImportConfigParseStatus
- ) => void;
+ onParsedChange: (config: unknown, error: string | null, status: ImportConfigParseStatus) => void;
}
export function ImportConfigInput({
@@ -169,7 +165,6 @@ export function ImportConfigInput({
className="field-sizing-fixed min-h-[280px] max-h-[66vh] overflow-y-auto font-mono text-xs"
/>
)}
-
);
}
diff --git a/studio/web/src/lib/api/client.ts b/studio/web/src/lib/api/client.ts
index 1031ea2..ea3af5a 100644
--- a/studio/web/src/lib/api/client.ts
+++ b/studio/web/src/lib/api/client.ts
@@ -100,7 +100,8 @@ export interface ImportedConnection {
status: "connected" | "inherited" | "missing";
}
-export const FULL_CONFIG_SCHEMA_URL = "https://feros.ai/schemas/agent-config-v1.schema.json" as const;
+export const FULL_CONFIG_SCHEMA_URL =
+ "https://feros.ai/schemas/agent-config-v1.schema.json" as const;
export interface AgentFullConfig {
$schema: typeof FULL_CONFIG_SCHEMA_URL;
@@ -563,8 +564,7 @@ export const api = {
}).toString()}`
),
get: (id: string) => apiFetch
(`/agents/${id}`),
- export: (id: string) =>
- apiFetch(`/agents/${id}/export`),
+ export: (id: string) => apiFetch(`/agents/${id}/export`),
create: (data: { name: string; description?: string }) =>
apiFetch("/agents", {
method: "POST",
diff --git a/voice/engine/src/native_session.rs b/voice/engine/src/native_session.rs
index 7411e9a..f7d704c 100644
--- a/voice/engine/src/native_session.rs
+++ b/voice/engine/src/native_session.rs
@@ -17,8 +17,8 @@ use voice_trace::{Event, Tracer};
use voice_transport::TransportHandle;
use crate::audio_ml::vad::{VadConfig, VAD_THRESHOLD_IDLE, VAD_THRESHOLD_PLAYBACK_RAW};
-use crate::reactor::AgentAudioCursor;
use crate::reactor::proc::vad::VadStage;
+use crate::reactor::AgentAudioCursor;
use crate::session::NativeMultimodalConfig;
use crate::types::VadEvent;
use crate::utils::{AudioRingBuffer, PlaybackTracker, SAMPLE_RATE};
@@ -114,9 +114,8 @@ pub(crate) async fn run_native_multimodal(
// ── Resamplers ─────────────────────────────────────────────────
// Input: client rate (e.g. 48kHz) → 16kHz (Gemini input requirement).
- let mut in_resampler =
- SoxrStreamResampler::new(input_sample_rate, SAMPLE_RATE)
- .expect("Native in-resampler creation failed");
+ let mut in_resampler = SoxrStreamResampler::new(input_sample_rate, SAMPLE_RATE)
+ .expect("Native in-resampler creation failed");
// Output: Gemini 24kHz → WebRTC 48kHz.
let mut out_resampler = SoxrStreamResampler::new(OUTPUT_SAMPLE_RATE, WEBRTC_RATE)
@@ -124,10 +123,7 @@ pub(crate) async fn run_native_multimodal(
// ── Local VAD for barge-in ─────────────────────────────────────
let vad_path = format!("{}/silero_vad/silero_vad.onnx", models_dir);
- let mut vad = VadStage::new(
- &vad_path,
- VadConfig::default(),
- );
+ let mut vad = VadStage::new(&vad_path, VadConfig::default());
let vad_ok = vad.initialize().is_ok();
if !vad_ok {
warn!("[native] VAD init failed — barge-in disabled");