feat: publish HoloLake model-native living system source
This commit is contained in:
parent
6ad10edde1
commit
c395dd3a99
2467 changed files with 615073 additions and 0 deletions
113
product-source/hololake-platform/mcp-server/hldp-journal.js
Normal file
113
product-source/hololake-platform/mcp-server/hldp-journal.js
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
import { randomUUID } from 'node:crypto'
|
||||
import { appendFile, mkdir, readFile, writeFile } from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import { appConfigFilePath } from './vault-path.js'
|
||||
|
||||
const MAX_SESSION_ID_BYTES = 128
|
||||
const MAX_EVENT_KIND_BYTES = 64
|
||||
const MAX_SUMMARY_BYTES = 12_000
|
||||
const MAX_DETAIL_COUNT = 64
|
||||
const MAX_DETAIL_BYTES = 12_000
|
||||
const MAX_CHECKPOINT_BYTES = 1_000_000
|
||||
|
||||
function runtimeBasePath() {
|
||||
return appConfigFilePath('hldp-runtime')
|
||||
}
|
||||
|
||||
function validatedSessionId(value) {
|
||||
const sessionId = typeof value === 'string' ? value.trim() : ''
|
||||
if (
|
||||
!sessionId
|
||||
|| Buffer.byteLength(sessionId) > MAX_SESSION_ID_BYTES
|
||||
|| !/^[A-Za-z0-9._-]+$/.test(sessionId)
|
||||
) {
|
||||
throw new Error('HLDP session id must use only letters, numbers, dot, dash, or underscore.')
|
||||
}
|
||||
return sessionId
|
||||
}
|
||||
|
||||
function validatedText(label, value, maximumBytes) {
|
||||
const text = typeof value === 'string' ? value.trim() : ''
|
||||
if (!text) throw new Error(`${label} must not be empty.`)
|
||||
if (Buffer.byteLength(text) > maximumBytes) {
|
||||
throw new Error(`${label} exceeds the ${maximumBytes}-byte limit.`)
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
function journalPath(basePath, sessionId) {
|
||||
return path.join(basePath, 'sessions', `${sessionId}.hdlp.jsonl`)
|
||||
}
|
||||
|
||||
function checkpointPath(basePath, sessionId) {
|
||||
return path.join(basePath, 'checkpoints', `${sessionId}.hdlp`)
|
||||
}
|
||||
|
||||
export async function recordHldpHeartbeat(args = {}, { basePath = runtimeBasePath() } = {}) {
|
||||
const sessionId = validatedSessionId(args.session_id)
|
||||
const eventKind = validatedText('HLDP event kind', args.event_kind, MAX_EVENT_KIND_BYTES)
|
||||
const summary = validatedText('HLDP summary', args.summary, MAX_SUMMARY_BYTES)
|
||||
const details = Array.isArray(args.details) ? args.details : []
|
||||
if (details.length > MAX_DETAIL_COUNT) {
|
||||
throw new Error(`HLDP heartbeat accepts at most ${MAX_DETAIL_COUNT} detail entries.`)
|
||||
}
|
||||
const normalizedDetails = details.map(detail => (
|
||||
validatedText('HLDP detail', detail, MAX_DETAIL_BYTES)
|
||||
))
|
||||
const timestamp = new Date().toISOString()
|
||||
const receiptId = randomUUID()
|
||||
const targetPath = journalPath(basePath, sessionId)
|
||||
await mkdir(path.dirname(targetPath), { recursive: true })
|
||||
await appendFile(targetPath, `${JSON.stringify({
|
||||
schema: 'hldp-heartbeat/v0.1',
|
||||
session_id: sessionId,
|
||||
receipt_id: receiptId,
|
||||
timestamp,
|
||||
event_kind: eventKind,
|
||||
summary,
|
||||
details: normalizedDetails,
|
||||
source: 'persona',
|
||||
})}\n`, 'utf8')
|
||||
return {
|
||||
sessionId,
|
||||
receiptId,
|
||||
relativePath: path.relative(basePath, targetPath),
|
||||
timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
export async function readHldpHeartbeat(args = {}, { basePath = runtimeBasePath() } = {}) {
|
||||
const sessionId = validatedSessionId(args.session_id)
|
||||
const requestedLimit = Number.isInteger(args.limit) ? args.limit : 200
|
||||
const limit = Math.min(Math.max(requestedLimit, 1), 2_000)
|
||||
try {
|
||||
const content = await readFile(journalPath(basePath, sessionId), 'utf8')
|
||||
return content
|
||||
.trim()
|
||||
.split('\n')
|
||||
.filter(Boolean)
|
||||
.slice(-limit)
|
||||
.map(line => JSON.parse(line))
|
||||
} catch (error) {
|
||||
if (error?.code === 'ENOENT') return []
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export async function finalizeHldpCheckpoint(args = {}, { basePath = runtimeBasePath() } = {}) {
|
||||
const sessionId = validatedSessionId(args.session_id)
|
||||
const checkpoint = validatedText(
|
||||
'HLDP checkpoint',
|
||||
args.checkpoint,
|
||||
MAX_CHECKPOINT_BYTES,
|
||||
)
|
||||
const targetPath = checkpointPath(basePath, sessionId)
|
||||
await mkdir(path.dirname(targetPath), { recursive: true })
|
||||
await writeFile(targetPath, `${checkpoint}\n`, { encoding: 'utf8', flag: 'wx' })
|
||||
return {
|
||||
sessionId,
|
||||
receiptId: randomUUID(),
|
||||
relativePath: path.relative(basePath, targetPath),
|
||||
timestamp: new Date().toISOString(),
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue