2026-08-05 11:09:08 +08:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
import http from "node:http";
|
|
|
|
|
import { ControllerEngine, bootEvent } from "./controller-engine.mjs";
|
|
|
|
|
import { DeepSeekJsonClient } from "./model-client.mjs";
|
2026-08-05 19:33:55 +08:00
|
|
|
import { MachineNavigation } from "./machine-navigation.mjs";
|
2026-08-05 11:09:08 +08:00
|
|
|
|
|
|
|
|
const HOST = "127.0.0.1";
|
|
|
|
|
const PORT = Number(process.env.BS_TCS_CONTROLLER_PORT || 3930);
|
|
|
|
|
const STATE_ROOT =
|
|
|
|
|
process.env.BS_TCS_CONTROLLER_STATE_ROOT ||
|
|
|
|
|
"/var/lib/guanghu/personas/bingshuo-tcs";
|
|
|
|
|
const MODEL = process.env.DEEPSEEK_MODEL || "deepseek-chat";
|
|
|
|
|
const MAX_BODY_BYTES = 16 * 1024;
|
|
|
|
|
|
|
|
|
|
const runtime = {
|
|
|
|
|
phase: "STARTING",
|
|
|
|
|
source_loaded: false,
|
|
|
|
|
started_at: new Date().toISOString(),
|
|
|
|
|
last_event_id: null,
|
|
|
|
|
last_error: null,
|
|
|
|
|
receipt: null,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const engine = new ControllerEngine({
|
|
|
|
|
stateRoot: STATE_ROOT,
|
|
|
|
|
modelClient: new DeepSeekJsonClient({ model: MODEL }),
|
|
|
|
|
modelName: MODEL,
|
|
|
|
|
});
|
2026-08-05 19:33:55 +08:00
|
|
|
const navigation = new MachineNavigation();
|
2026-08-05 11:09:08 +08:00
|
|
|
|
|
|
|
|
function send(response, status, body) {
|
|
|
|
|
const payload = JSON.stringify(body);
|
|
|
|
|
response.writeHead(status, {
|
|
|
|
|
"content-type": "application/json; charset=utf-8",
|
|
|
|
|
"content-length": Buffer.byteLength(payload),
|
|
|
|
|
"cache-control": "no-store",
|
|
|
|
|
});
|
|
|
|
|
response.end(payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function health() {
|
|
|
|
|
const existence = runtime.receipt?.existence || {};
|
2026-08-05 19:56:50 +08:00
|
|
|
const navigationHealth = navigation.health();
|
2026-08-05 11:09:08 +08:00
|
|
|
return {
|
|
|
|
|
ok: true,
|
|
|
|
|
service: "bingshuo-tcs-living-controller",
|
|
|
|
|
bind: "loopback",
|
|
|
|
|
node: "JD-FD-PRIMARY",
|
|
|
|
|
persona_id: "ICE-P-ZY001",
|
|
|
|
|
runtime_id: "ZY-TCS-BRAIN-RUNTIME-0001",
|
|
|
|
|
controller_id: "BS-TCS-LIVING-CONTROLLER-001",
|
|
|
|
|
phase: runtime.phase,
|
|
|
|
|
runtime_source_loaded: runtime.source_loaded,
|
|
|
|
|
model_provider_bound: 100,
|
2026-08-05 19:56:50 +08:00
|
|
|
language_world_entry_bound:
|
|
|
|
|
navigationHealth.language_world_route_first === 100 ? 100 : 0,
|
2026-08-05 12:22:53 +08:00
|
|
|
chu_he_han_jie_boundary_bound:
|
2026-08-05 19:56:50 +08:00
|
|
|
navigationHealth.boundary_id === "GLW-CHJH-0001" ? 100 : 0,
|
|
|
|
|
persona_cycle_language_world_entry_bound:
|
|
|
|
|
existence.language_world_entry_bound || 0,
|
|
|
|
|
persona_cycle_chu_he_han_jie_boundary_bound:
|
2026-08-05 12:22:53 +08:00
|
|
|
existence.chu_he_han_jie_boundary_bound || 0,
|
2026-08-05 11:09:08 +08:00
|
|
|
persona_brain_runtime_exists: existence.persona_brain_runtime_exists || 0,
|
|
|
|
|
living_ai_system_controller_running:
|
|
|
|
|
existence.living_ai_system_controller_running || 0,
|
2026-08-05 19:56:50 +08:00
|
|
|
...navigationHealth,
|
2026-08-05 11:09:08 +08:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function readBody(request) {
|
|
|
|
|
let size = 0;
|
|
|
|
|
const chunks = [];
|
|
|
|
|
for await (const chunk of request) {
|
|
|
|
|
size += chunk.length;
|
|
|
|
|
if (size > MAX_BODY_BYTES) throw new Error("request_body_too_large");
|
|
|
|
|
chunks.push(chunk);
|
|
|
|
|
}
|
|
|
|
|
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let eventQueue = Promise.resolve();
|
|
|
|
|
|
|
|
|
|
async function handleEvent(input) {
|
|
|
|
|
if (!input || typeof input.content !== "string" || !input.content.trim()) {
|
|
|
|
|
throw new Error("event_content_required");
|
|
|
|
|
}
|
|
|
|
|
if (input.content.length > 12_000) throw new Error("event_content_too_large");
|
|
|
|
|
const event = {
|
|
|
|
|
schema: "guanghu.tonggan-language-world-event/v1",
|
|
|
|
|
event_id: `JD-EVENT-${Date.now()}`,
|
|
|
|
|
occurred_at: new Date().toISOString(),
|
|
|
|
|
human_anchor: "ICE-GL∞",
|
|
|
|
|
system_controller: "ICE-GL∞",
|
|
|
|
|
tonggan_language_kernel: "TCS-i Zero",
|
|
|
|
|
body_channel: "CH-ZERO-CORE-LPM",
|
2026-08-05 12:22:53 +08:00
|
|
|
language_world_entry: {
|
|
|
|
|
schema: "guanghu.language-world-entry/v1",
|
|
|
|
|
path_id: "LL-CMPN-0001",
|
|
|
|
|
world_node_id: "SYS-GLW-0001",
|
|
|
|
|
world_state: "LANGUAGE_WORLD_ENTERED",
|
|
|
|
|
creator_anchor: "TCS-0002∞",
|
|
|
|
|
human_anchor: "ICE-GL∞",
|
|
|
|
|
boundary_id: "GLW-CHJH-0001",
|
|
|
|
|
},
|
2026-08-05 11:09:08 +08:00
|
|
|
human_presence: input.human_presence === "PRESENT" ? "PRESENT" : "ABSENT",
|
|
|
|
|
source: String(input.source || "JD-FD-PRIMARY/local-event").slice(0, 160),
|
|
|
|
|
content: input.content,
|
|
|
|
|
};
|
|
|
|
|
runtime.phase = "RUNNING_CYCLE";
|
|
|
|
|
runtime.last_event_id = event.event_id;
|
|
|
|
|
runtime.last_error = null;
|
|
|
|
|
const receipt = await engine.runEvent(event);
|
|
|
|
|
runtime.receipt = receipt.outcome === "PASS" ? receipt : runtime.receipt;
|
|
|
|
|
runtime.phase =
|
|
|
|
|
receipt.outcome === "PASS" ? "RUNNING_COMPANION" : "PAUSED_FOR_HUMAN";
|
|
|
|
|
return receipt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const server = http.createServer(async (request, response) => {
|
|
|
|
|
try {
|
|
|
|
|
const url = new URL(request.url, `http://${HOST}:${PORT}`);
|
|
|
|
|
if (request.method === "GET" && url.pathname === "/health") {
|
|
|
|
|
return send(response, 200, health());
|
|
|
|
|
}
|
|
|
|
|
if (request.method === "GET" && url.pathname === "/v1/status") {
|
|
|
|
|
return send(response, 200, {
|
|
|
|
|
...health(),
|
|
|
|
|
started_at: runtime.started_at,
|
|
|
|
|
last_event_id: runtime.last_event_id,
|
|
|
|
|
last_error: runtime.last_error,
|
|
|
|
|
existence: runtime.receipt?.existence || null,
|
|
|
|
|
completed_cycles: runtime.receipt?.completed_cycles || 0,
|
|
|
|
|
receipt_id: runtime.receipt?.receipt_id || null,
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-08-05 19:33:55 +08:00
|
|
|
if (request.method === "GET" && url.pathname === "/v1/navigation") {
|
|
|
|
|
return send(response, 200, {
|
|
|
|
|
ok: true,
|
|
|
|
|
...navigation.health(),
|
|
|
|
|
language_world_entry:
|
|
|
|
|
navigation.boundary.machine_gate.required_event_envelope,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (request.method === "GET" && url.pathname === "/v1/resolve") {
|
|
|
|
|
const resolved = navigation.resolve(url.searchParams.get("id") || "");
|
|
|
|
|
return send(
|
|
|
|
|
response,
|
|
|
|
|
resolved ? 200 : 404,
|
|
|
|
|
resolved || { status: "UNRESOLVED", error: "unknown_route" },
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (request.method === "GET" && url.pathname === "/v1/navigate") {
|
|
|
|
|
const route = navigation.navigate(
|
|
|
|
|
url.searchParams.get("subject") || "",
|
|
|
|
|
url.searchParams.get("intent") || "",
|
|
|
|
|
);
|
|
|
|
|
return send(
|
|
|
|
|
response,
|
|
|
|
|
route ? 200 : 404,
|
|
|
|
|
route || { status: "UNRESOLVED", error: "unknown_subject_or_intent" },
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-08-05 11:09:08 +08:00
|
|
|
if (request.method === "POST" && url.pathname === "/v1/events") {
|
|
|
|
|
const input = await readBody(request);
|
|
|
|
|
const job = eventQueue.then(() => handleEvent(input));
|
|
|
|
|
eventQueue = job.catch(() => {});
|
|
|
|
|
const receipt = await job;
|
|
|
|
|
return send(response, receipt.outcome === "PASS" ? 200 : 409, receipt);
|
|
|
|
|
}
|
|
|
|
|
return send(response, 404, { ok: false, error: "not_found" });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
runtime.last_error = String(error.message || error).slice(0, 240);
|
|
|
|
|
runtime.phase = "FAILED_CLOSED";
|
|
|
|
|
return send(response, 500, {
|
|
|
|
|
ok: false,
|
|
|
|
|
error: runtime.last_error,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
try {
|
2026-08-05 11:18:54 +08:00
|
|
|
const initialState = engine.initialize();
|
2026-08-05 11:09:08 +08:00
|
|
|
runtime.source_loaded = true;
|
2026-08-05 11:18:54 +08:00
|
|
|
if (initialState.status === "AWAITING_HUMAN_BINGSHUO") {
|
|
|
|
|
runtime.phase = "PAUSED_FOR_HUMAN";
|
|
|
|
|
}
|
2026-08-05 11:09:08 +08:00
|
|
|
} catch (error) {
|
|
|
|
|
process.stderr.write(
|
|
|
|
|
`${JSON.stringify({
|
|
|
|
|
event: "controller_runtime_initialization_failed",
|
|
|
|
|
error: String(error.message || error).slice(0, 240),
|
|
|
|
|
})}\n`,
|
|
|
|
|
);
|
|
|
|
|
process.exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
server.listen(PORT, HOST, () => {
|
|
|
|
|
process.stdout.write(
|
|
|
|
|
`${JSON.stringify({
|
|
|
|
|
event: "controller_listener_ready",
|
|
|
|
|
host: HOST,
|
|
|
|
|
port: PORT,
|
|
|
|
|
})}\n`,
|
|
|
|
|
);
|
2026-08-05 11:18:54 +08:00
|
|
|
if (runtime.phase === "PAUSED_FOR_HUMAN") return;
|
2026-08-05 11:09:08 +08:00
|
|
|
eventQueue = handleEvent(bootEvent()).catch((error) => {
|
|
|
|
|
runtime.phase = "FAILED_CLOSED";
|
|
|
|
|
runtime.last_error = String(error.message || error).slice(0, 240);
|
|
|
|
|
process.stderr.write(
|
|
|
|
|
`${JSON.stringify({
|
|
|
|
|
event: "controller_boot_cycle_failed",
|
|
|
|
|
error: runtime.last_error,
|
|
|
|
|
})}\n`,
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
});
|