hololake-system-architecture/server-adapters/jd/tcs-agent-driver.mjs

74 lines
4.9 KiB
JavaScript

#!/usr/bin/env node
import { createHash } from 'node:crypto'
import { readFile, rename, writeFile } from 'node:fs/promises'
import { dirname, extname, resolve, sep } from 'node:path'
import { spawnSync } from 'node:child_process'
const [runtime, compiler, source, girOutput, receiptOutput, allowedRoot] = process.argv.slice(2)
if (![runtime, compiler, source, girOutput, receiptOutput, allowedRoot].every(Boolean)) {
throw new Error('usage: tcs-agent-driver <runtime> <compiler.gir.json> <source.tcs> <gir-output> <receipt-output> <allowed-root>')
}
if (extname(source) !== '.tcs') throw new Error('TCS_SOURCE_ONLY')
const root = resolve(allowedRoot)
const inside = (value) => {
const target = resolve(value)
if (target !== root && !target.startsWith(`${root}${sep}`)) throw new Error('TARGET_OUTSIDE_ALLOWED_ROOT')
return target
}
const girPath = inside(girOutput)
const receiptPath = inside(receiptOutput)
const compile = spawnSync(runtime, ['compile-with', compiler, source, girPath], { encoding: 'utf8', timeout: 30000 })
if (compile.status !== 0) throw new Error(`TCS_COMPILE_FAILED:${(compile.stderr || '').trim().slice(0, 240)}`)
const gir = JSON.parse(await readFile(girPath, 'utf8'))
if (resolve(root, gir.exact_target?.exact_path || '') !== receiptPath
|| resolve(root, gir.receipt_plan?.machine_path || '') !== receiptPath) throw new Error('TCS_RECEIPT_TARGET_MISMATCH')
const actions = Object.values(gir.deterministic_action_graph || {})
if (actions.length !== 1 || actions[0].operation !== 'CORE.AGENT_TRANSLATION_CANDIDATE') throw new Error('TCS_AGENT_OPERATION_REQUIRED')
const value = (name) => gir.inputs?.[name]?.value
const exact = {
MODULE_ID: 'ZY-PM-0002', EXECUTION_LIMB: 'ZY-JD-LIMB-001', CONTROLLER: 'ZHUYUAN',
MODEL_ROLE: 'THIRD_GENERATION_STATELESS_REASONING_TOOL', INPUT_POLICY: 'TCS_SOURCE_AND_SELFHOSTED_GIR_ONLY',
OUTPUT_POLICY: 'CANDIDATE_ONLY_NO_SEMANTIC_OR_REALITY_AUTHORITY',
}
for (const [name, expected] of Object.entries(exact)) if (value(name) !== expected) throw new Error(`TCS_CONTRACT_MISMATCH:${name}`)
if (gir.native_self_hosted !== true || gir.compiled_from?.compiler_state !== 'TCS_COMPILER_GIR_EXECUTED') throw new Error('SELFHOSTED_GIR_REQUIRED')
const apiKey = process.env.DEEPSEEK_API_KEY
const base = String(process.env.DEEPSEEK_API_URL || 'https://api.deepseek.com/v1').replace(/\/$/, '')
const endpoint = base.endsWith('/chat/completions') ? base : `${base}/chat/completions`
const model = process.env.DEEPSEEK_MODEL || 'deepseek-chat'
if (!apiKey) throw new Error('DEEPSEEK_API_KEY_MISSING')
const tcsSource = await readFile(source, 'utf8')
const response = await fetch(endpoint, {
method: 'POST', signal: AbortSignal.timeout(90000),
headers: { authorization: `Bearer ${apiKey}`, 'content-type': 'application/json' },
body: JSON.stringify({
model, temperature: 0, response_format: { type: 'json_object' },
messages: [
{ role: 'system', content: 'You are a stateless third-generation reasoning tool. TCS and its self-hosted GIR are the only task semantics. Return one closed JSON object with exactly summary:string, verified_constraints:string[], unknowns:string[], acceptance_candidate:0|100. You have no semantic authority and no reality-action authority.' },
{ role: 'user', content: JSON.stringify({ tcs_source: tcsSource, self_hosted_gir: gir }) },
],
}),
})
if (!response.ok) throw new Error(`MODEL_HTTP_${response.status}`)
const envelope = await response.json()
const raw = envelope?.choices?.[0]?.message?.content
const candidate = JSON.parse(raw)
const keys = Object.keys(candidate).sort().join(',')
if (keys !== 'acceptance_candidate,summary,unknowns,verified_constraints'
|| typeof candidate.summary !== 'string'
|| !Array.isArray(candidate.verified_constraints) || !candidate.verified_constraints.every((item) => typeof item === 'string')
|| !Array.isArray(candidate.unknowns) || !candidate.unknowns.every((item) => typeof item === 'string')
|| ![0, 100].includes(candidate.acceptance_candidate)) throw new Error('MODEL_OUTPUT_INVALID')
const receipt = {
schema: 'tcs.agent-translation-candidate-receipt/v1', state: 'CANDIDATE_TARGET_READBACK_VERIFIED',
module_id: value('MODULE_ID'), execution_limb: value('EXECUTION_LIMB'), controller: value('CONTROLLER'),
model_role: value('MODEL_ROLE'), model_provider: 'DEEPSEEK_REPLACEABLE_TOOL', model,
source_language: 'TCS/0.1', source_sha256: gir.compiled_from.source_sha256,
semantic_authority: false, reality_action_authority: false, ...candidate,
}
const encoded = `${JSON.stringify(receipt, null, 2)}\n`
const pending = `${receiptPath}.pending`
await writeFile(pending, encoded, { mode: 0o600 })
await rename(pending, receiptPath)
if (await readFile(receiptPath, 'utf8') !== encoded) throw new Error('RECEIPT_READBACK_MISMATCH')
process.stdout.write(`${JSON.stringify({ state: receipt.state, module_id: receipt.module_id, acceptance_candidate: receipt.acceptance_candidate, receipt_sha256: createHash('sha256').update(encoded).digest('hex') })}\n`)