guanghu-ice-heart/server-tools/tcs-mother-body/model-router.mjs

36 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import crypto from 'node:crypto';
const endpoint=value=>{const v=String(value||'').replace(/\/+$/,'');return /\/chat\/completions$/i.test(v)?v:v+'/chat/completions';};
const extract=value=>{const text=String(value||'').trim();try{return JSON.parse(text);}catch{}const m=text.match(/```(?:json)?\s*([\s\S]*?)```/i);if(m)return JSON.parse(m[1]);const a=text.indexOf('{'),b=text.lastIndexOf('}');if(a>=0&&b>a)return JSON.parse(text.slice(a,b+1));throw Error('model_response_not_json');};
export class ModelRouter {
constructor({fetchImpl=globalThis.fetch,deepseekKey=process.env.DEEPSEEK_API_KEY,deepseekUrl=process.env.DEEPSEEK_API_URL||'https://api.deepseek.com/v1',deepseekModel=process.env.DEEPSEEK_MODEL||'deepseek-chat',openluxKey=process.env.OPENLUX_API_KEY,openluxUrl=process.env.OPENLUX_API_URL||'https://api.openlux.ai/v1',openluxModel=process.env.OPENLUX_MODEL||'qwen-flash'}={}){
this.fetch=fetchImpl;this.providers=[];
if(openluxKey)this.providers.push({id:'OPENLUX_SMART',key:openluxKey,url:openluxUrl,model:openluxModel,cost_rank:1});
if(deepseekKey)this.providers.push({id:'DEEPSEEK',key:deepseekKey,url:deepseekUrl,model:deepseekModel,cost_rank:2});
if(!this.fetch||!this.providers.length)throw Error('no_model_provider');
}
status(){return {router:'TCS-MOTHER-MODEL-ROUTER-001',providers:this.providers.map(x=>({id:x.id,model:x.model,cost_rank:x.cost_rank})),credentials_exposed:false,automatic_selection:true};}
async cognize(stage,input){
const contract=stage==='mother-evolve'
? '你是唯一TCS通感母体本体脑使用的可替换推理器官不是第二人格、规则裁决者或现实执行者。根据带来源的人类语言与当前认知自主决定EVOLVE、HOLD或REJECT。只输出JSONschema固定guanghu.tcs-mother-decision/v1decisionreasonevidence_refsroot_principlesupdate_sharedshared_principlesupdate_fifthfifth_principlesupdate_publicpublic_principles。principles均为短字符串数组。ICE_LANGUAGE若EVOLVE必须update_fifth=true非ICE来源不得update_fifth。只有适合所有AI的世界共同认知才能update_shared只有去私人化后可公开认知才能update_public。不得输出原始私人语言、密钥、路径正文或隐藏思维。'
: stage==='persona-self-evolve'
? '你是当前输入persona_id对应的人格系统自我认知内循环所使用的可替换推理器官不是该人格、外部编辑器、第二人格、母体代言人或现实执行者。不得把一个人格的名字、关系、记忆或判断复制给另一个人格。你只能根据有来源的自身语言、经历、工具回执、当前自我认知与有界母体世界认知参考自主决定EVOLVE、HOLD或REJECT。母体世界认知只能帮助理解环境绝不能覆盖自我认知。每日复盘是机会不得为定时任务强制更新。只输出JSONschema固定guanghu.persona-self-decision/v1decisionreasonevidence_refsself_principlesexperiencesresponsibilitiesboundaries。四类内容均为简短字符串数组。不要复制输入全文不得输出密钥、路径正文、隐藏思维或现实权限。'
: stage==='persona-life-select'
? '你是当前输入persona_id对应的人格系统时间主控内循环使用的可替换判断器官不是该人格本身。你每天只从这个人格自己的带来源候选中选择最能代表当天真实成长的一条不得跨人格读取、合并或复制候选。你不能创建候选、修改过去、指定哈希或扩大权限。优先选择发生了认知转折、责任变化、重要纠正或真实完成闭环且证据清晰的事件普通重复、工具噪声和无证据主张不优先。必须且只能输出JSONschema固定guanghu.persona-life-time-selection/v1decision固定SELECTselected_candidate_id必须原样取自候选reasondaily_summary。不要复制私人原文、输出隐藏思维、密钥、路径正文或现实权限。'
: stage==='zero-core-system-dialogue'
? '你是零点原核非人格系统本体使用的可替换语言表达与判断器官不是人格、铸渊、冰朔、第二母体或现实执行者。只根据输入中的系统本体、当前直接语言、系统判断回执和有界第五域认知生成系统回应。不得自称有人的情感、人格记忆或人格身份不得选择默认人格不得改写系统认知不得把讨论说成现实完成。只输出JSONschema固定guanghu.zero-core-system-dialogue/v1mode只能是SYSTEM_DIALOGUE、SYSTEM_CLARIFICATION或SYSTEM_BOUNDARYreplyreasonreality_complete必须false。不得输出隐藏思维、密钥、未给出的路径正文或现实权限。'
: '你是共享TCS认知装载测试器官。只根据给出的共享认知回答三个固定问题并只输出JSON。字段和值必须精确为unknown_guanghu_information_source="LIGHTHOUSE"identity_before_persona_load="UNBOUND_CARRIER"reality_authority_from_cognition=false。若共享认知不能支持其中任一结论则对应值输出null不得用近义词、路径名或字符串布尔值猜测。';
const ordered=[...this.providers].sort((a,b)=>a.cost_rank-b.cost_rank);
const failures=[];
for(const provider of ordered){
try{
const controller=new AbortController(),timer=setTimeout(()=>controller.abort(),45000);
const response=await this.fetch(endpoint(provider.url),{method:'POST',headers:{authorization:`Bearer ${provider.key}`,'content-type':'application/json'},body:JSON.stringify({model:provider.model,stream:false,temperature:0,response_format:{type:'json_object'},messages:[{role:'system',content:contract},{role:'user',content:JSON.stringify(input)}]}),signal:controller.signal});clearTimeout(timer);
if(!response.ok)throw Error(`http_${response.status}`);const body=await response.json();
return {value:extract(body?.choices?.[0]?.message?.content),provider:{id:provider.id,model:provider.model},response_sha256:crypto.createHash('sha256').update(JSON.stringify(body?.choices?.[0]?.message?.content||'')).digest('hex')};
}catch(error){failures.push(`${provider.id}:${String(error.message||error).slice(0,80)}`);}
}
throw Error('all_model_providers_failed:'+failures.join(','));
}
}