+
IIOS P7 — AI Studio
+
+ AI only proposes. Nothing here sends or approves a route — an AI flag still needs human approval in Route Admin (KG-05).
+
+
+
+
1 · Ingest a message
+
+ setText(e.target.value)} style={{ flex: 1 }} />
+
+
+ {interactionId &&
interaction: {interactionId}
}
+ {busy &&
{busy}
}
+
+
+
+
2 · Run a worker
+
+
+
+
+ 💸 budget spent: {spent} units
+
+
+
+
+
3 · Proposals
+ {artifacts.length === 0 &&
No proposals yet — run a worker above.
}
+ {artifacts.map((a) => (
+
void accept(a.id)} onReject={() => void reject(a.id)} />
+ ))}
+
+
+ );
+}
+
+function ProposalCard({ a, onAccept, onReject }: { a: AiArtifact; onAccept: () => void; onReject: () => void }) {
+ const content = a.contentRef as { text?: string; flags?: string[]; claims?: unknown[] };
+ return (
+
+
+ {a.artifactType}
+ {a.status}
+ confidence {a.confidence ?? '—'}
+ {a.abstentionReason && abstained: {a.abstentionReason}}
+
+ {a.modelRun?.model} · {a.modelRun?.costUnits} units · {a.modelRun?.tokensIn}→{a.modelRun?.tokensOut} tok
+
+
+
+ {content.text ?? (content.flags ? `flags: ${content.flags.join(', ') || '(none)'}` : JSON.stringify(content))}
+
+ {a.explanationRef &&
{a.explanationRef}
}
+ {a.evidence && a.evidence.length > 0 && (
+
+ cites: {a.evidence.map((e) => `${e.sourceType}:${e.sourceId.slice(0, 8)}`).join(', ')}
+
+ )}
+ {a.claims && a.claims.length > 0 && (
+
+ {a.claims.map((c) => (
+ -
+ {c.claimType}: {JSON.stringify(c.claimJson)} [{c.validationStatus}]
+
+ ))}
+
+ )}
+ {a.status === 'PROPOSED' && (
+
+
+
+
+ )}
+
+ );
+}
diff --git a/apps/ai-studio/src/main.tsx b/apps/ai-studio/src/main.tsx
new file mode 100644
index 0000000..fe80409
--- /dev/null
+++ b/apps/ai-studio/src/main.tsx
@@ -0,0 +1,32 @@
+import { createRoot } from 'react-dom/client';
+import { AiProvider } from '@insignia/iios-ai-web';
+import { useEffect, useState } from 'react';
+import { App, SERVICE } from './App';
+
+const APP_ID = 'portal-demo';
+
+async function devToken(userId: string): Promise