mirror of
https://github.com/sortedcord/omnia.git
synced 2026-07-22 03:52:48 +05:30
FEAT!(voice): Implement intent hydration, dehydration system fixes: #29
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
"@omnia/memory": "workspace:*",
|
||||
"@omnia/scenario": "workspace:*",
|
||||
"@omnia/spatial": "workspace:*",
|
||||
"@omnia/voice": "workspace:*",
|
||||
"@radix-ui/react-dialog": "^1.1.19",
|
||||
"@radix-ui/react-separator": "^1.1.11",
|
||||
"@radix-ui/react-slot": "^1.3.0",
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Spinner } from "@/components/ui/spinner";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { hydrate } from "@omnia/voice";
|
||||
import {
|
||||
Alert,
|
||||
AlertAction,
|
||||
@@ -17,9 +18,13 @@ import {
|
||||
function IntentTag({
|
||||
intent,
|
||||
isSelf,
|
||||
playerAliases,
|
||||
playerId,
|
||||
}: {
|
||||
intent: SimSnapshot["log"][number]["intents"][number];
|
||||
isSelf?: boolean;
|
||||
playerAliases: Record<string, string>;
|
||||
playerId: string;
|
||||
}) {
|
||||
const labels: Record<string, string> = {
|
||||
monologue: "thought",
|
||||
@@ -35,10 +40,13 @@ function IntentTag({
|
||||
outcome = intent.isValid ? " ✅" : ` ❌ (${intent.reason})`;
|
||||
}
|
||||
|
||||
const textToDisplay =
|
||||
isSelf && intent.selfDescription
|
||||
? intent.selfDescription
|
||||
: intent.description;
|
||||
const viewerAliasesMap = new Map(Object.entries(playerAliases || {}));
|
||||
const viewerEntityMock = {
|
||||
id: playerId || "",
|
||||
aliases: viewerAliasesMap,
|
||||
};
|
||||
|
||||
const textToDisplay = hydrate(intent.content, viewerEntityMock as any);
|
||||
|
||||
const modifiersStr =
|
||||
intent.modifiers && intent.modifiers.length > 0 ? (
|
||||
@@ -76,10 +84,14 @@ function LogEntryCard({
|
||||
entry,
|
||||
onShowPrompt,
|
||||
isPlayerCard,
|
||||
playerAliases,
|
||||
playerId,
|
||||
}: {
|
||||
entry: SimSnapshot["log"][number];
|
||||
onShowPrompt: (entry: SimSnapshot["log"][number]) => void;
|
||||
isPlayerCard: boolean;
|
||||
playerAliases: Record<string, string>;
|
||||
playerId: string;
|
||||
}) {
|
||||
const showMenu = !!(entry.rawPrompt || entry.decoderPrompt);
|
||||
|
||||
@@ -117,7 +129,13 @@ function LogEntryCard({
|
||||
</div>
|
||||
<div className="flex flex-col gap-1.5 mt-2 border-t border-dotted border-border/10 pt-2">
|
||||
{entry.intents.map((intent, i) => (
|
||||
<IntentTag key={i} intent={intent} isSelf={isPlayerCard} />
|
||||
<IntentTag
|
||||
key={i}
|
||||
intent={intent}
|
||||
isSelf={isPlayerCard}
|
||||
playerAliases={playerAliases}
|
||||
playerId={playerId}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
@@ -184,12 +202,17 @@ export function InteractView({
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
const playerAliases = playerEntity?.aliases || {};
|
||||
const playerId = playerEntity?.id || "";
|
||||
|
||||
return (
|
||||
<LogEntryCard
|
||||
key={i}
|
||||
entry={entry}
|
||||
onShowPrompt={onShowPrompt}
|
||||
isPlayerCard={entry.entityId === playerEntity?.id}
|
||||
playerAliases={playerAliases}
|
||||
playerId={playerId}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
export interface IntentInfo {
|
||||
type: string;
|
||||
description: string;
|
||||
selfDescription?: string;
|
||||
content: string;
|
||||
modifiers: string[];
|
||||
targetIds: string[];
|
||||
isValid?: boolean;
|
||||
@@ -49,6 +48,7 @@ export interface EntityInfo {
|
||||
name: string;
|
||||
isPlayer: boolean;
|
||||
isAgent: boolean;
|
||||
aliases?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface WaitingContext {
|
||||
|
||||
@@ -468,6 +468,21 @@ export class SimulationManager {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
private snapshot(session: SimSession): SimSnapshot {
|
||||
const worldState = session.coreRepo.loadWorldState(session.worldInstanceId);
|
||||
const hydratedEntities = session.entities.map((e) => {
|
||||
const actualEntity = worldState?.getEntity(e.id);
|
||||
const aliases: Record<string, string> = {};
|
||||
if (actualEntity) {
|
||||
for (const [targetId, alias] of actualEntity.aliases.entries()) {
|
||||
aliases[targetId] = alias;
|
||||
}
|
||||
}
|
||||
return {
|
||||
...e,
|
||||
aliases,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
id: session.worldInstanceId,
|
||||
status: session.status,
|
||||
@@ -475,7 +490,7 @@ export class SimulationManager {
|
||||
maxTurns: session.maxTurns,
|
||||
scenarioName: session.scenarioName,
|
||||
scenarioDescription: session.scenarioDescription,
|
||||
entities: session.entities,
|
||||
entities: hydratedEntities,
|
||||
log: session.log,
|
||||
entityIndex: session.entityIndex,
|
||||
waitingEntity: session.waitingEntity,
|
||||
|
||||
@@ -58,8 +58,7 @@ async function processIntents(
|
||||
|
||||
intentInfos.push({
|
||||
type: intent.type,
|
||||
description: intent.description,
|
||||
selfDescription: intent.selfDescription,
|
||||
content: intent.content,
|
||||
modifiers: intent.modifiers || [],
|
||||
targetIds: intent.targetIds,
|
||||
isValid: outcome.isValid,
|
||||
|
||||
Reference in New Issue
Block a user