hololake-system-architecture/product-source/hololake-platform/src/lib/personaRuntimeProjection.ts

242 lines
8.3 KiB
TypeScript

import { invoke } from '@tauri-apps/api/core'
import { isTauri, mockInvoke } from '../mock-tauri'
export interface PersonaRuntimeAttribution {
humanResponsibilitySubject: string
personaCognitiveAuthor: string
executionRuntime: string
developmentId: string
authorizationScope: string
sourceLanguageAnchor: string
}
export interface PersonaRuntimeCognitiveGravityEvidence {
schema: 'hololake.persona-cognitive-gravity-evidence/v1'
subjectPersonaId: string
sourcePath: string
sourceHash: string
frameSchema: 'guanghu.zhuyuan-cognitive-gravity-frame/v1'
}
export interface PersonaRuntimeSessionReceipt {
sessionId: string
state: string
gitHead: string
nodeId: string
modelInstanceId: string
activeOrgan: string | null
eventCount: number
firstEventAt: string
lastEventAt: string
lastEvent: string
eventChainHead: string
cognitiveGravity: PersonaRuntimeCognitiveGravityEvidence
attribution: PersonaRuntimeAttribution
}
export interface PersonaRuntimeQueryReceipt {
schema: 'hololake.pncc-runtime-query/v1'
personaId: string
repositoryPath: string
observedGitHead: string
repositoryClean: boolean
matchingSessionCount: number
returnedSessionCount: number
sessions: PersonaRuntimeSessionReceipt[]
}
export interface PersonaRuntimeSessionProjection extends PersonaRuntimeSessionReceipt {
repositoryPath: string
observedGitHead: string
repositoryClean: boolean
}
export interface PersonaRuntimeProjectionError {
code: string
repositoryPath: string
}
export interface PersonaRuntimeProjection {
errors: PersonaRuntimeProjectionError[]
inspectedRepositoryCount: number
phase: 'unavailable' | 'verified' | 'error'
sessions: PersonaRuntimeSessionProjection[]
}
interface LoadPersonaRuntimeProjectionInput {
personaId: string
repositoryPaths: readonly string[]
query?: (personaId: string, repositoryPath: string) => Promise<unknown>
}
function errorCode(error: unknown): string {
if (typeof error === 'string') return error
if (error instanceof Error) return error.message
return 'PERSONA_RUNTIME_QUERY_FAILED'
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null
}
function requiredString(record: Record<string, unknown>, key: string): string {
const value = Reflect.get(record, key)
if (typeof value !== 'string' || value.length === 0) throw new Error('PERSONA_RUNTIME_RECEIPT_INVALID')
return value
}
function requiredNumber(record: Record<string, unknown>, key: string): number {
const value = Reflect.get(record, key)
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {
throw new Error('PERSONA_RUNTIME_RECEIPT_INVALID')
}
return value
}
function parseAttribution(value: unknown): PersonaRuntimeAttribution {
if (!isRecord(value)) throw new Error('PERSONA_RUNTIME_RECEIPT_INVALID')
return {
humanResponsibilitySubject: requiredString(value, 'humanResponsibilitySubject'),
personaCognitiveAuthor: requiredString(value, 'personaCognitiveAuthor'),
executionRuntime: requiredString(value, 'executionRuntime'),
developmentId: requiredString(value, 'developmentId'),
authorizationScope: requiredString(value, 'authorizationScope'),
sourceLanguageAnchor: requiredString(value, 'sourceLanguageAnchor'),
}
}
function parseCognitiveGravity(value: unknown): PersonaRuntimeCognitiveGravityEvidence {
if (!isRecord(value)) throw new Error('PERSONA_RUNTIME_RECEIPT_INVALID')
const schema = requiredString(value, 'schema')
const frameSchema = requiredString(value, 'frameSchema')
const sourceHash = requiredString(value, 'sourceHash')
if (
schema !== 'hololake.persona-cognitive-gravity-evidence/v1'
|| frameSchema !== 'guanghu.zhuyuan-cognitive-gravity-frame/v1'
|| !/^[a-f0-9]{64}$/.test(sourceHash)
) {
throw new Error('PERSONA_RUNTIME_RECEIPT_INVALID')
}
return {
schema,
subjectPersonaId: requiredString(value, 'subjectPersonaId'),
sourcePath: requiredString(value, 'sourcePath'),
sourceHash,
frameSchema,
}
}
function parseSession(value: unknown): PersonaRuntimeSessionReceipt {
if (!isRecord(value)) throw new Error('PERSONA_RUNTIME_RECEIPT_INVALID')
const activeOrgan = Reflect.get(value, 'activeOrgan')
if (activeOrgan !== null && typeof activeOrgan !== 'string') {
throw new Error('PERSONA_RUNTIME_RECEIPT_INVALID')
}
return {
sessionId: requiredString(value, 'sessionId'),
state: requiredString(value, 'state'),
gitHead: requiredString(value, 'gitHead'),
nodeId: requiredString(value, 'nodeId'),
modelInstanceId: requiredString(value, 'modelInstanceId'),
activeOrgan,
eventCount: requiredNumber(value, 'eventCount'),
firstEventAt: requiredString(value, 'firstEventAt'),
lastEventAt: requiredString(value, 'lastEventAt'),
lastEvent: requiredString(value, 'lastEvent'),
eventChainHead: requiredString(value, 'eventChainHead'),
cognitiveGravity: parseCognitiveGravity(Reflect.get(value, 'cognitiveGravity')),
attribution: parseAttribution(Reflect.get(value, 'attribution')),
}
}
function parseReceipt(
value: unknown,
expectedPersonaId: string,
expectedRepositoryPath: string,
): PersonaRuntimeQueryReceipt {
if (!isRecord(value)) throw new Error('PERSONA_RUNTIME_RECEIPT_INVALID')
const schema = requiredString(value, 'schema')
const personaId = requiredString(value, 'personaId')
const repositoryPath = requiredString(value, 'repositoryPath')
const observedGitHead = requiredString(value, 'observedGitHead')
const repositoryClean = Reflect.get(value, 'repositoryClean')
const sessionsValue = Reflect.get(value, 'sessions')
if (
schema !== 'hololake.pncc-runtime-query/v1'
|| personaId !== expectedPersonaId
|| repositoryPath !== expectedRepositoryPath
|| typeof repositoryClean !== 'boolean'
|| !Array.isArray(sessionsValue)
) {
throw new Error('PERSONA_RUNTIME_RECEIPT_INVALID')
}
const matchingSessionCount = requiredNumber(value, 'matchingSessionCount')
const returnedSessionCount = requiredNumber(value, 'returnedSessionCount')
const sessions = sessionsValue.map(parseSession)
if (returnedSessionCount !== sessions.length || matchingSessionCount < returnedSessionCount) {
throw new Error('PERSONA_RUNTIME_RECEIPT_INVALID')
}
return {
schema,
personaId,
repositoryPath,
observedGitHead,
repositoryClean,
matchingSessionCount,
returnedSessionCount,
sessions,
}
}
async function queryNativeRuntime(personaId: string, repositoryPath: string): Promise<unknown> {
const args = {
input: {
expectedPersonaId: personaId,
expectedRepositoryPath: repositoryPath,
limit: 25,
},
}
return isTauri()
? invoke<unknown>('query_persona_code_channel_runtime', args)
: mockInvoke<unknown>('query_persona_code_channel_runtime', args)
}
export async function loadPersonaRuntimeProjection({
personaId,
repositoryPaths,
query = queryNativeRuntime,
}: LoadPersonaRuntimeProjectionInput): Promise<PersonaRuntimeProjection> {
const uniqueRepositoryPaths = [...new Set(repositoryPaths.map((path) => path.trim()).filter(Boolean))]
if (uniqueRepositoryPaths.length === 0) {
return { errors: [], inspectedRepositoryCount: 0, phase: 'unavailable', sessions: [] }
}
const results = await Promise.all(uniqueRepositoryPaths.map(async (repositoryPath) => {
try {
const receipt = parseReceipt(await query(personaId, repositoryPath), personaId, repositoryPath)
return { receipt, repositoryPath, error: null }
} catch (error) {
return { receipt: null, repositoryPath, error: errorCode(error) }
}
}))
const verified = results.flatMap((result) => result.receipt ? [result.receipt] : [])
const errors = results.flatMap((result) => result.error
? [{ code: result.error, repositoryPath: result.repositoryPath }]
: [])
const sessions = verified.flatMap((receipt) => receipt.sessions.map((session) => ({
...session,
repositoryPath: receipt.repositoryPath,
observedGitHead: receipt.observedGitHead,
repositoryClean: receipt.repositoryClean,
}))).sort((left, right) => (
right.lastEventAt.localeCompare(left.lastEventAt)
|| right.sessionId.localeCompare(left.sessionId)
))
return {
errors,
inspectedRepositoryCount: verified.length,
phase: verified.length > 0 ? 'verified' : 'error',
sessions,
}
}