Files
Project_Velocity/app/src/oracle/hooks/useOracleExecution.ts
sayan eeb684b46c feat: Ipad app production readiness, Colony orchestration, Social posting (#44)
#38 Ipad app production readiness, Colony orchestration, Social posting

Co-authored-by: Sayan Datta <sayan@Sayans-MacBook-Air.local>
Reviewed-on: sagnik/Project_Velocity#44
2026-05-03 18:30:38 +05:30

147 lines
4.4 KiB
TypeScript

/**
* useOracleExecution — manages prompt submission and durable execution history.
*/
import { useState, useCallback, useRef } from 'react';
import type { PromptExecution, CanvasComponent, PlacementMode, OracleExecutionMode } from '../types/canvas';
import { submitPrompt } from '../lib/oracleApiClient';
export interface ExecutionEntry {
execution: PromptExecution;
componentsCreated: string[];
}
export interface OracleExecutionState {
history: ExecutionEntry[];
inFlight: PromptExecution | null;
lastError: string | null;
submit: (params: {
pageId: string;
branchId: string;
prompt: string;
tenantId: string;
actorId: string;
executionMode?: OracleExecutionMode;
placementMode?: PlacementMode;
conversationContext?: Array<{ role: 'user' | 'assistant'; content: string }>;
onExecutionCommitted?: (commit: {
headRevision: number;
components: CanvasComponent[];
execution: PromptExecution;
}) => void;
}) => Promise<void>;
clearError: () => void;
resetHistory: () => void;
}
export function useOracleExecution(): OracleExecutionState {
const [history, setHistory] = useState<ExecutionEntry[]>([]);
const [inFlight, setInFlight] = useState<PromptExecution | null>(null);
const [lastError, setLastError] = useState<string | null>(null);
const requestIdRef = useRef(0);
const submit = useCallback(
async ({
pageId,
branchId,
prompt,
tenantId,
actorId,
executionMode = 'auto',
placementMode = 'append_after_last_visible_component',
conversationContext = [],
onExecutionCommitted,
}: {
pageId: string;
branchId: string;
prompt: string;
tenantId: string;
actorId: string;
executionMode?: OracleExecutionMode;
placementMode?: PlacementMode;
conversationContext?: Array<{ role: 'user' | 'assistant'; content: string }>;
onExecutionCommitted?: (commit: {
headRevision: number;
components: CanvasComponent[];
execution: PromptExecution;
}) => void;
}) => {
const clientRequestId = `cli_${Date.now()}_${++requestIdRef.current}`;
const now = new Date().toISOString();
const optimistic: PromptExecution = {
executionId: `pex_${clientRequestId}`,
tenantId,
pageId,
branchId,
actorId,
prompt,
intentClass: 'analytical',
status: 'planning',
modelRuntime: executionMode === 'thinking' ? 'colony_orchestrator' : 'oracle_runtime',
semanticModelVersion: 'oracle_semantic_v2026_04_08_01',
warnings: [],
createdAt: now,
executionMode,
};
setInFlight(optimistic);
setLastError(null);
try {
setInFlight((prev) => (prev ? { ...prev, status: 'executing' } : prev));
const response = await submitPrompt(pageId, {
clientRequestId,
branchId,
prompt,
conversationContext,
placementMode,
executionMode,
});
const completed: PromptExecution = {
...optimistic,
executionId: response.executionId,
status: response.status,
summary: response.summary,
warnings: response.warnings,
componentsCreated: response.componentsCreated,
executionMode: response.executionMode ?? executionMode,
resolvedMode: response.resolvedMode,
colonyMissionId: response.colonyMissionId,
completedAt: new Date().toISOString(),
};
onExecutionCommitted?.({
headRevision: response.headRevision,
components: response.components,
execution: completed,
});
setHistory((prev) => [...prev, { execution: completed, componentsCreated: response.componentsCreated }]);
setInFlight(null);
} catch (err) {
const msg = err instanceof Error ? err.message : 'Prompt execution failed';
const failed: PromptExecution = {
...optimistic,
status: 'failed',
warnings: [msg],
completedAt: new Date().toISOString(),
};
setHistory((prev) => [...prev, { execution: failed, componentsCreated: [] }]);
setInFlight(null);
setLastError(msg);
}
},
[],
);
return {
history,
inFlight,
lastError,
submit,
clearError: () => setLastError(null),
resetHistory: () => setHistory([]),
};
}