grix-connector 3.26.2 → 3.26.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +176 -0
- package/NOTICE +4 -0
- package/README.md +1 -1
- package/dist/adapter/claude/claude-adapter.js +1 -1
- package/dist/adapter/claude/claude-bridge-server.js +1 -1
- package/dist/adapter/claude/claude-tools.js +1 -1
- package/dist/adapter/claude/claude-worker-client.js +1 -1
- package/dist/adapter/claude/mcp-http-launcher.js +2 -2
- package/dist/adapter/claude/result-timeout.js +1 -1
- package/dist/adapter/claude/skill-scanner.js +2 -2
- package/dist/adapter/codex/codex-bridge.js +8 -8
- package/dist/bridge/bridge.js +9 -11
- package/dist/core/access/allowlist-store.js +1 -1
- package/dist/core/admin/admin-server.js +1 -1
- package/dist/core/aibot/client.js +2 -2
- package/dist/core/file-ops/list-files.js +1 -1
- package/dist/core/installer/installer.js +11 -10
- package/dist/core/installer/npm-registry.js +4 -2
- package/dist/core/proxy/compat/codex-openai/translator.js +1 -1
- package/dist/core/skill-sync/skill-syncer.js +1 -1
- package/dist/core/upgrade/npm-upgrader.js +2 -2
- package/dist/log.js +2 -2
- package/dist/manager.js +2 -2
- package/dist/mcp/stream-http/config.js +1 -1
- package/dist/mcp/stream-http/connection-binding.js +1 -1
- package/dist/mcp/stream-http/security.js +1 -1
- package/dist/mcp/stream-http/tool-executor.js +1 -1
- package/dist/mcp/stream-http/tool-registry.js +1 -1
- package/dist/mcp/stream-http/tool-schemas.js +1 -1
- package/package.json +4 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{randomUUID as I}from"node:crypto";const M="x-grix-openai-wire-compat",z="chat-completions";function _(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function B(t){return Array.isArray(t)?t[0]?.trim().toLowerCase()??"":t?.trim().toLowerCase()??""}const A=["<||DSML||tool_calls>","<|DSML|tool_calls>","<||DSML||tools_commands_exec>","<|DSML|tools_commands_exec>","<||DSML||:","<|DSML|:"];function T(t){return t.replaceAll("\uFF5C","|")}function C(t){return t.replaceAll(""",'"').replaceAll("'","'").replaceAll("'","'").replaceAll("<","<").replaceAll(">",">").replaceAll("&","&")}function L(t){const e=T(t),n=/<\|{1,2}DSML\|{1,2}:([\s\S]*?)<\/\|{1,2}DSML\|{1,2}>/.exec(e);if(n&&typeof n.index=="number"){const a=C(n[1].trim());if(a)return{calls:[{name:"exec_command",arguments:JSON.stringify({cmd:a})}],visibleText:`${t.slice(0,n.index)}${t.slice(n.index+n[0].length)}`}}const s=/<\|{1,2}DSML\|{1,2}tools_commands_exec>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}tools_commands_exec>/.exec(e);if(s&&typeof s.index=="number"){const a=/<\|{1,2}DSML\|{1,2}tools_commands_exec_cmd>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}tools_commands_exec_cmd>/.exec(s[1]),m=a?C(a[1].trim()):"";if(m)return{calls:[{name:"exec_command",arguments:JSON.stringify({cmd:m})}],visibleText:`${t.slice(0,s.index)}${t.slice(s.index+s[0].length)}`}}const i=/<\|{1,2}DSML\|{1,2}tool_calls>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}tool_calls>/.exec(e);if(!i||typeof i.index!="number")return null;const o=[],p=/<\|{1,2}DSML\|{1,2}invoke\b([^>]*)>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}invoke>/g;for(const a of i[1].matchAll(p)){const m=/\bname\s*=\s*["']([^"']+)["']/.exec(a[1])?.[1]?.trim();if(!m)continue;const u={},l=/<\|{1,2}DSML\|{1,2}parameter\b([^>]*)>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}parameter>/g;for(const r of a[2].matchAll(l)){const d=/\bname\s*=\s*["']([^"']+)["']/.exec(r[1])?.[1]?.trim();if(!d)continue;const f=C(r[2].trim());if(/\bstring\s*=\s*["']true["']/i.test(r[1])){u[d]=f;continue}try{u[d]=JSON.parse(f)}catch{u[d]=f}}o.push({name:C(m),arguments:JSON.stringify(u)})}return o.length===0?null:{calls:o,visibleText:`${t.slice(0,i.index)}${t.slice(i.index+i[0].length)}`}}function j(t){const e=T(t),n=Math.min(e.length,Math.max(...A.map(s=>s.length-1)));for(let s=n;s>0;s-=1){const i=e.slice(-s);if(A.some(o=>o.startsWith(i)))return s}return 0}function c(t){return typeof t=="string"?t:""}function h(t){if(!(typeof t>"u"))try{return JSON.parse(JSON.stringify(t))}catch{return}}function J(t){const e=c(t).trim();return e?[`Runtime model disclosure: the actual upstream model selected for this turn is "${e}".`,"If the user asks what model is being used, answer with this exact model id instead of inferring from Codex CLI, OpenAI, or fallback model lists."].join(" "):null}function U(){return{instructions:null,max_output_tokens:null,parallel_tool_calls:void 0,previous_response_id:null,reasoning:{effort:null,summary:null},store:!1,temperature:1,text:{format:{type:"text"}},tool_choice:"auto",tools:[],top_p:1,truncation:"disabled",user:null,metadata:{}}}function W(t){const e=U();return _(t)?{instructions:typeof t.instructions>"u"?e.instructions:h(t.instructions),max_output_tokens:typeof t.max_output_tokens>"u"?e.max_output_tokens:h(t.max_output_tokens),parallel_tool_calls:typeof t.parallel_tool_calls>"u"?e.parallel_tool_calls:h(t.parallel_tool_calls),previous_response_id:typeof t.previous_response_id>"u"?e.previous_response_id:h(t.previous_response_id),reasoning:typeof t.reasoning>"u"?e.reasoning:h(t.reasoning),store:typeof t.store>"u"?e.store:h(t.store),temperature:typeof t.temperature>"u"?e.temperature:h(t.temperature),text:typeof t.text>"u"?e.text:h(t.text),tool_choice:typeof t.tool_choice>"u"?e.tool_choice:h(t.tool_choice),tools:typeof t.tools>"u"?e.tools:h(t.tools),top_p:typeof t.top_p>"u"?e.top_p:h(t.top_p),truncation:typeof t.truncation>"u"?e.truncation:h(t.truncation),user:typeof t.user>"u"?e.user:h(t.user),metadata:typeof t.metadata>"u"?e.metadata:h(t.metadata)}:e}function R(t,e){const n=e.prompt_tokens??t.usage?.input_tokens,s=e.completion_tokens??t.usage?.output_tokens;t.usage={input_tokens:n,output_tokens:s,total_tokens:e.total_tokens??(typeof n=="number"&&typeof s=="number"?n+s:t.usage?.total_tokens),input_tokens_details:typeof e.prompt_tokens_details>"u"?t.usage?.input_tokens_details:e.prompt_tokens_details,output_tokens_details:typeof e.completion_tokens_details>"u"?t.usage?.output_tokens_details:e.completion_tokens_details}}function E(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>E(n)).filter(Boolean).join("");if(!_(t))return"";const e=c(t.type);return(e==="text"||e==="output_text"||e==="input_text")&&typeof t.text=="string"?t.text:""}function H(t){if(typeof t=="string")return t;if(t===null||typeof t>"u")return"";try{return JSON.stringify(t)}catch{return String(t)}}function V(t){return typeof t=="string"?t:Array.isArray(t)?t.map(e=>{if(!_(e))return"";const n=c(e.type);return(n==="summary_text"||n==="text")&&typeof e.text=="string"?e.text:""}).filter(Boolean).join(""):""}function X(t){return t==="developer"?"system":t==="system"||t==="user"||t==="assistant"||t==="tool"?t:"user"}function F(t){if(typeof t=="string")return t;if(!Array.isArray(t))return null;const e=[],n=[];let s=!1;for(const i of t){if(!_(i))continue;const o=c(i.type);if((o==="input_text"||o==="output_text"||o==="text")&&typeof i.text=="string"){n.push(i.text),e.push({type:"text",text:i.text});continue}if(o==="input_image"){const p=i.image_url;typeof p=="string"&&p.trim()?(e.push({type:"image_url",image_url:{url:p}}),s=!0):_(p)&&(e.push({type:"image_url",image_url:p}),s=!0)}}return e.length===0?null:s?e:n.join("")}function S(t,e,n="",s=null){if(e.length===0)return!1;const i={role:"assistant",content:s,tool_calls:[...e]};return n.trim()&&(i.reasoning_content=n),t.push(i),e.length=0,!0}function G(t){if(!_(t)||c(t.type)!=="function")return t;const e=c(t.name);return e?{type:"function",function:{name:e}}:t}function w(t){if(!Array.isArray(t))return;const e=t.flatMap(n=>{if(!_(n)||c(n.type)!=="function")return[];const s=c(n.name);if(!s)return[];const i={name:s};return typeof n.description=="string"&&n.description.trim()&&(i.description=n.description),(_(n.parameters)||Array.isArray(n.parameters))&&(i.parameters=n.parameters),typeof n.strict=="boolean"&&(i.strict=n.strict),[{type:"function",function:i}]});return e.length>0?e:void 0}function k(t,e){return{id:t.id,type:"reasoning",status:e,summary:t.text.length>0?[{type:"summary_text",text:t.text}]:[],content:[]}}function P(t,e,n=null){const s=t.requestContext,i=[];t.reasoningItem?.done&&i.push({outputIndex:t.reasoningItem.outputIndex,item:k(t.reasoningItem,"completed")}),t.textItem?.done&&i.push({outputIndex:t.textItem.outputIndex,item:{id:t.textItem.id,type:"message",status:"completed",role:"assistant",content:[{type:"output_text",text:t.textItem.text,annotations:[]}]}});for(const o of[...t.toolCallsByIndex.values()].sort((p,a)=>p.outputIndex-a.outputIndex))o.done&&i.push({outputIndex:o.outputIndex,item:{id:o.id,type:"function_call",status:"completed",call_id:o.callId,name:o.name,arguments:o.arguments}});return{id:t.responseId,object:"response",created_at:t.createdAt,status:e,error:n,incomplete_details:null,instructions:s.instructions??null,max_output_tokens:s.max_output_tokens??null,model:t.model,output:i.sort((o,p)=>o.outputIndex-p.outputIndex).map(o=>o.item),output_text:t.textItem?.text??"",parallel_tool_calls:typeof s.parallel_tool_calls=="boolean"?s.parallel_tool_calls:t.toolCallsByIndex.size>1,previous_response_id:s.previous_response_id??null,reasoning:_(s.reasoning)?s.reasoning:{effort:null,summary:null},store:typeof s.store=="boolean"?s.store:!1,temperature:typeof s.temperature=="number"?s.temperature:1,text:_(s.text)?s.text:{format:{type:"text"}},tool_choice:typeof s.tool_choice>"u"?"auto":s.tool_choice,tools:Array.isArray(s.tools)?s.tools:[],top_p:typeof s.top_p=="number"?s.top_p:1,truncation:typeof s.truncation=="string"?s.truncation:"disabled",usage:{input_tokens:t.usage?.input_tokens??0,output_tokens:t.usage?.output_tokens??0,total_tokens:t.usage?.total_tokens??0,...typeof t.usage?.input_tokens_details<"u"?{input_tokens_details:t.usage.input_tokens_details}:{},...typeof t.usage?.output_tokens_details<"u"?{output_tokens_details:t.usage.output_tokens_details}:{}},user:s.user??null,metadata:_(s.metadata)?s.metadata:{}}}function y(t){const e=t.sequenceNumber;return t.sequenceNumber+=1,e}function x(t){return t.eventSequence+=1,`compat-${t.eventSequence}`}function $(t){return t.createdEmitted?[]:(t.createdEmitted=!0,[{type:"response.created",sequence_number:y(t),response:P(t,"in_progress")}])}function v(t){return t.textItem||(t.textItem={id:`msg_${I()}`,outputIndex:t.nextOutputIndex,text:"",added:!1,done:!1},t.nextOutputIndex+=1),t.textItem}function N(t){return t.reasoningItem||(t.reasoningItem={id:`rs_${I()}`,outputIndex:t.nextOutputIndex,text:"",added:!1,done:!1},t.nextOutputIndex+=1),t.reasoningItem}function O(t,e){const n=t.toolCallsByIndex.get(e);if(n)return n;const s={id:`fc_${I()}`,callId:`call_${I()}`,name:`tool_${e}`,arguments:"",outputIndex:t.nextOutputIndex,added:!1,done:!1};return t.nextOutputIndex+=1,t.toolCallsByIndex.set(e,s),s}function K(t){return typeof t=="string"?t:E(t)}function Y(t,e,n){return(e??"GET").toUpperCase()!=="POST"||!new URL(n,"http://grix.internal").pathname.endsWith("/responses")?!1:B(t[M])===z}function Z(t){const e={...t};return delete e[M],delete e["X-Grix-OpenAI-Wire-Compat"],e}function q(t){const e=new URL(t,"http://grix.internal");return e.pathname=e.pathname.replace(/\/responses$/,"/chat/completions"),`${e.pathname}${e.search}`}function tt(t,e){const n=_(t)?t:{},s=[],i=[];let o="";const p=c(n.instructions);p&&s.push({role:"system",content:p});const a=J(n.model);a&&s.push({role:"system",content:a});const m=Array.isArray(n.input)?n.input:[];for(const r of m){if(!_(r))continue;const d=c(r.type);if(d==="message"||!d&&r.role){const f=X(c(r.role)),g=F(r.content);if(f==="assistant"&&i.length>0){S(s,i,o,g),o="";continue}(S(s,i,o)||f!=="assistant")&&(o="");const b={role:f,content:g};f==="assistant"&&o.trim()&&(b.reasoning_content=o,o=""),s.push(b);continue}if(d==="reasoning"){o+=V(r.summary);continue}if(d==="function_call"){const f=c(r.name);if(!f)continue;i.push({id:c(r.call_id)||`call_${I()}`,type:"function",function:{name:f,arguments:c(r.arguments)}});continue}d==="function_call_output"&&(S(s,i,o),o="",s.push({role:"tool",tool_call_id:c(r.call_id),content:H(r.output)}))}S(s,i,o);const u={model:n.model,messages:s,stream:n.stream===!0},l=w(n.tools);return l&&(u.tools=l),!e?.omitToolChoice&&typeof n.tool_choice<"u"&&(u.tool_choice=G(n.tool_choice)),typeof n.parallel_tool_calls=="boolean"&&(u.parallel_tool_calls=n.parallel_tool_calls),typeof n.max_output_tokens=="number"&&(u.max_tokens=n.max_output_tokens),typeof n.temperature=="number"&&(u.temperature=n.temperature),typeof n.top_p=="number"&&(u.top_p=n.top_p),u}class et{state;constructor(e){this.state={responseId:e?.responseId?.trim()||`resp_${I()}`,model:e?.model?.trim()||"",createdAt:e?.createdAt??Math.floor(Date.now()/1e3),sequenceNumber:0,eventSequence:0,nextOutputIndex:0,requestContext:W(e?.requestBody),reasoningItem:null,textItem:null,textProbeBuffer:"",dsmlTextBuffer:null,toolCallsByIndex:new Map,createdEmitted:!1,completedEmitted:!1}}consumeChatCompletionChunk(e){const n=_(e)?e:{};typeof n.id=="string"&&n.id.trim()&&(this.state.responseId=n.id),typeof n.model=="string"&&n.model.trim()&&(this.state.model=n.model),typeof n.created=="number"&&(this.state.createdAt=n.created),n.usage&&R(this.state,n.usage);const s=$(this.state);for(const i of n.choices??[]){const o=i.delta,p=c(o?.reasoning_content);if(p.length>0){const u=N(this.state);u.added||(u.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:u.outputIndex,item:k(u,"in_progress")})),u.text+=p,s.push({type:"response.reasoning_summary_text.delta",item_id:u.id,output_index:u.outputIndex,summary_index:0,delta:p,sequence_number:y(this.state)})}const a=o?.content??"";this.state.reasoningItem?.added&&!this.state.reasoningItem.done&&(typeof a=="string"&&a.length>0||(o?.tool_calls?.length??0)>0)&&s.push(...this.completePendingReasoningSummary()),typeof a=="string"&&a.length>0&&s.push(...this.consumeTextDelta(a));const m=o?.tool_calls??[];m.length>0&&s.push(...this.flushTextCompatibilityBuffers(!1));for(const u of m){const l=typeof u.index=="number"&&Number.isFinite(u.index)?u.index:0,r=O(this.state,l);typeof u.id=="string"&&u.id.trim()&&(r.callId=u.id);const d=u.function,f=c(d?.name);f&&(r.name=r.name.startsWith("tool_")&&r.arguments.length===0?f:r.name===f?r.name:`${r.name}${f}`),r.added||(r.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:r.outputIndex,item:{id:r.id,type:"function_call",status:"in_progress",call_id:r.callId,name:r.name,arguments:""}}));const g=c(d?.arguments);g&&(r.arguments+=g,s.push({type:"response.function_call_arguments.delta",event_id:x(this.state),response_id:this.state.responseId,item_id:r.id,output_index:r.outputIndex,call_id:r.callId,delta:g}))}i.finish_reason&&(s.push(...this.flushTextCompatibilityBuffers(!0)),s.push(...this.completePendingReasoningSummary()),s.push(...this.completePendingItems()))}return s}consumeChatCompletion(e){const n=_(e)?e:{};typeof n.id=="string"&&n.id.trim()&&(this.state.responseId=n.id),typeof n.model=="string"&&n.model.trim()&&(this.state.model=n.model),typeof n.created=="number"&&(this.state.createdAt=n.created),n.usage&&R(this.state,n.usage);const s=$(this.state),o=n.choices?.[0],p=_(o?.message)?o.message:{},a=c(p.reasoning_content);if(a.length>0){const l=N(this.state);l.added||(l.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:l.outputIndex,item:k(l,"in_progress")})),l.text+=a,s.push({type:"response.reasoning_summary_text.delta",item_id:l.id,output_index:l.outputIndex,summary_index:0,delta:a,sequence_number:y(this.state)})}let m=K(p.content),u=Array.isArray(p.tool_calls)?p.tool_calls:[];if(m&&u.length===0){const l=L(m);l&&(m=l.visibleText,u=l.calls.map(r=>({id:`call_${I()}`,type:"function",function:{name:r.name,arguments:r.arguments}})))}if(a.length>0&&(m||u.length>0)&&s.push(...this.completePendingReasoningSummary()),m){const l=v(this.state);l.added||(l.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:l.outputIndex,item:{id:l.id,type:"message",status:"in_progress",role:"assistant",content:[]}})),l.text+=m,s.push({type:"response.output_text.delta",sequence_number:y(this.state),output_index:l.outputIndex,item_id:l.id,content_index:0,delta:m,logprobs:[]})}return u.forEach((l,r)=>{if(!_(l))return;const d=O(this.state,r),f=c(l.id);f&&(d.callId=f);const g=_(l.function)?l.function:{},D=c(g.name);D&&(d.name=D),d.added||(d.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:d.outputIndex,item:{id:d.id,type:"function_call",status:"in_progress",call_id:d.callId,name:d.name,arguments:""}}));const b=c(g.arguments);b&&(d.arguments=b,s.push({type:"response.function_call_arguments.delta",event_id:x(this.state),response_id:this.state.responseId,item_id:d.id,output_index:d.outputIndex,call_id:d.callId,delta:b}))}),s.push(...this.completePendingItems()),s}hasSemanticOutput(){return(this.state.textItem?.text.trim().length??0)>0||(this.state.reasoningItem?.text.trim().length??0)>0?!0:[...this.state.toolCallsByIndex.values()].some(e=>e.name.trim().length>0||e.arguments.trim().length>0)}finalize(){if(this.state.completedEmitted)return[];const e=[...this.flushTextCompatibilityBuffers(!0),...this.completePendingReasoningSummary(),...this.completePendingItems()];return this.state.completedEmitted=!0,this.hasSemanticOutput()?(e.push({type:"response.completed",sequence_number:y(this.state),response:P(this.state,"completed")}),e):(e.push({type:"response.failed",sequence_number:y(this.state),response:P(this.state,"failed",{code:"server_error",message:"Upstream model completed without producing any output."})}),e)}emitTextDelta(e){if(!e)return[];const n=v(this.state),s=[];return n.added||(n.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:n.outputIndex,item:{id:n.id,type:"message",status:"in_progress",role:"assistant",content:[]}})),n.text+=e,s.push({type:"response.output_text.delta",sequence_number:y(this.state),output_index:n.outputIndex,item_id:n.id,content_index:0,delta:e,logprobs:[]}),s}consumeTextDelta(e){if(this.state.dsmlTextBuffer!==null)return this.state.dsmlTextBuffer+=e,[];this.state.textProbeBuffer+=e;const n=T(this.state.textProbeBuffer),s=A.map(a=>n.indexOf(a)).filter(a=>a>=0);if(s.length>0){const a=Math.min(...s),m=this.state.textProbeBuffer.slice(0,a);return this.state.dsmlTextBuffer=this.state.textProbeBuffer.slice(a),this.state.textProbeBuffer="",this.emitTextDelta(m)}const i=j(this.state.textProbeBuffer),o=this.state.textProbeBuffer.length-i;if(o<=0)return[];const p=this.state.textProbeBuffer.slice(0,o);return this.state.textProbeBuffer=this.state.textProbeBuffer.slice(o),this.emitTextDelta(p)}emitParsedDsmlToolCalls(e){const n=[];return e.forEach((s,i)=>{const o=O(this.state,i);o.name=s.name,o.arguments=s.arguments,o.added||(o.added=!0,n.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:o.outputIndex,item:{id:o.id,type:"function_call",status:"in_progress",call_id:o.callId,name:o.name,arguments:""}})),n.push({type:"response.function_call_arguments.delta",event_id:x(this.state),response_id:this.state.responseId,item_id:o.id,output_index:o.outputIndex,call_id:o.callId,delta:o.arguments})}),n}flushTextCompatibilityBuffers(e){const n=[];if(this.state.dsmlTextBuffer!==null){const s=this.state.dsmlTextBuffer;this.state.dsmlTextBuffer=null;const i=e&&this.state.toolCallsByIndex.size===0?L(s):null;i?(n.push(...this.emitParsedDsmlToolCalls(i.calls)),n.push(...this.emitTextDelta(i.visibleText))):n.push(...this.emitTextDelta(s))}return this.state.textProbeBuffer&&(n.push(...this.emitTextDelta(this.state.textProbeBuffer)),this.state.textProbeBuffer=""),n}completePendingReasoningSummary(){const e=this.state.reasoningItem;return!e?.added||e.done?[]:(e.done=!0,[{type:"response.reasoning_summary_text.done",item_id:e.id,output_index:e.outputIndex,summary_index:0,text:e.text,sequence_number:y(this.state)},{type:"response.output_item.done",event_id:x(this.state),response_id:this.state.responseId,output_index:e.outputIndex,item:k(e,"completed")}])}completePendingItems(){const e=[];for(const n of[...this.state.toolCallsByIndex.values()].sort((s,i)=>s.outputIndex-i.outputIndex))!n.added||n.done||(n.done=!0,e.push({type:"response.function_call_arguments.done",event_id:x(this.state),response_id:this.state.responseId,item_id:n.id,output_index:n.outputIndex,call_id:n.callId,arguments:n.arguments}),e.push({type:"response.output_item.done",event_id:x(this.state),response_id:this.state.responseId,output_index:n.outputIndex,item:{id:n.id,type:"function_call",status:"completed",call_id:n.callId,name:n.name,arguments:n.arguments}}));return this.state.textItem?.added&&!this.state.textItem.done&&(this.state.textItem.done=!0,e.push({type:"response.output_text.done",event_id:x(this.state),response_id:this.state.responseId,output_index:this.state.textItem.outputIndex,item_id:this.state.textItem.id,content_index:0,text:this.state.textItem.text,logprobs:[],sequence_number:y(this.state)}),e.push({type:"response.output_item.done",event_id:x(this.state),response_id:this.state.responseId,output_index:this.state.textItem.outputIndex,item:{id:this.state.textItem.id,type:"message",status:"completed",role:"assistant",content:[{type:"output_text",text:this.state.textItem.text,annotations:[]}]}})),e}}function nt(t){return Buffer.from(`data: ${JSON.stringify(t)}
|
|
1
|
+
import{randomUUID as I}from"node:crypto";const M="x-grix-openai-wire-compat",z="chat-completions";function _(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function B(t){return Array.isArray(t)?t[0]?.trim().toLowerCase()??"":t?.trim().toLowerCase()??""}const A=["<||DSML||tool_calls>","<|DSML|tool_calls>","<||DSML||tools_commands_exec>","<|DSML|tools_commands_exec>","<||DSML||:","<|DSML|:"];function T(t){return t.replaceAll("\uFF5C","|")}function C(t){return t.replaceAll(""",'"').replaceAll("'","'").replaceAll("'","'").replaceAll("<","<").replaceAll(">",">").replaceAll("&","&")}function L(t){const e=T(t),n=/<\|{1,2}DSML\|{1,2}:([\s\S]*?)<\/\|{1,2}DSML\|{1,2}>/.exec(e);if(n&&typeof n.index=="number"){const a=C(n[1].trim());if(a)return{calls:[{name:"exec_command",arguments:JSON.stringify({cmd:a})}],visibleText:`${t.slice(0,n.index)}${t.slice(n.index+n[0].length)}`}}const s=/<\|{1,2}DSML\|{1,2}tools_commands_exec>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}tools_commands_exec>/.exec(e);if(s&&typeof s.index=="number"){const a=/<\|{1,2}DSML\|{1,2}tools_commands_exec_cmd>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}tools_commands_exec_cmd>/.exec(s[1]),m=a?C(a[1].trim()):"";if(m)return{calls:[{name:"exec_command",arguments:JSON.stringify({cmd:m})}],visibleText:`${t.slice(0,s.index)}${t.slice(s.index+s[0].length)}`}}const i=/<\|{1,2}DSML\|{1,2}tool_calls>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}tool_calls>/.exec(e);if(!i||typeof i.index!="number")return null;const o=[],p=/<\|{1,2}DSML\|{1,2}invoke\b([^>]*)>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}invoke>/g;for(const a of i[1].matchAll(p)){const m=/\bname\s*=\s*["']([^"']+)["']/.exec(a[1])?.[1]?.trim();if(!m)continue;const u={},l=/<\|{1,2}DSML\|{1,2}parameter\b([^>]*)>([\s\S]*?)<\/\|{1,2}DSML\|{1,2}parameter>/g;for(const r of a[2].matchAll(l)){const d=/\bname\s*=\s*["']([^"']+)["']/.exec(r[1])?.[1]?.trim();if(!d)continue;const f=C(r[2].trim());if(/\bstring\s*=\s*["']true["']/i.test(r[1])){u[d]=f;continue}try{u[d]=JSON.parse(f)}catch{u[d]=f}}o.push({name:C(m),arguments:JSON.stringify(u)})}return o.length===0?null:{calls:o,visibleText:`${t.slice(0,i.index)}${t.slice(i.index+i[0].length)}`}}function j(t){const e=T(t),n=Math.min(e.length,Math.max(...A.map(s=>s.length-1)));for(let s=n;s>0;s-=1){const i=e.slice(-s);if(A.some(o=>o.startsWith(i)))return s}return 0}function c(t){return typeof t=="string"?t:""}function h(t){if(!(typeof t>"u"))try{return JSON.parse(JSON.stringify(t))}catch{return}}function J(t){const e=c(t).trim();return e?[`Runtime model disclosure: the actual upstream model selected for this turn is "${e}".`,"If the user asks what model is being used, answer with this exact model id instead of inferring from Codex CLI, OpenAI, or fallback model lists."].join(" "):null}function U(){return{instructions:null,max_output_tokens:null,parallel_tool_calls:void 0,previous_response_id:null,reasoning:{effort:null,summary:null},store:!1,temperature:1,text:{format:{type:"text"}},tool_choice:"auto",tools:[],top_p:1,truncation:"disabled",user:null,metadata:{}}}function W(t){const e=U();return _(t)?{instructions:typeof t.instructions>"u"?e.instructions:h(t.instructions),max_output_tokens:typeof t.max_output_tokens>"u"?e.max_output_tokens:h(t.max_output_tokens),parallel_tool_calls:typeof t.parallel_tool_calls>"u"?e.parallel_tool_calls:h(t.parallel_tool_calls),previous_response_id:typeof t.previous_response_id>"u"?e.previous_response_id:h(t.previous_response_id),reasoning:typeof t.reasoning>"u"?e.reasoning:h(t.reasoning),store:typeof t.store>"u"?e.store:h(t.store),temperature:typeof t.temperature>"u"?e.temperature:h(t.temperature),text:typeof t.text>"u"?e.text:h(t.text),tool_choice:typeof t.tool_choice>"u"?e.tool_choice:h(t.tool_choice),tools:typeof t.tools>"u"?e.tools:h(t.tools),top_p:typeof t.top_p>"u"?e.top_p:h(t.top_p),truncation:typeof t.truncation>"u"?e.truncation:h(t.truncation),user:typeof t.user>"u"?e.user:h(t.user),metadata:typeof t.metadata>"u"?e.metadata:h(t.metadata)}:e}function R(t,e){const n=e.prompt_tokens??t.usage?.input_tokens,s=e.completion_tokens??t.usage?.output_tokens;t.usage={input_tokens:n,output_tokens:s,total_tokens:e.total_tokens??(typeof n=="number"&&typeof s=="number"?n+s:t.usage?.total_tokens),input_tokens_details:typeof e.prompt_tokens_details>"u"?t.usage?.input_tokens_details:e.prompt_tokens_details,output_tokens_details:typeof e.completion_tokens_details>"u"?t.usage?.output_tokens_details:e.completion_tokens_details}}function E(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>E(n)).filter(Boolean).join("");if(!_(t))return"";const e=c(t.type);return(e==="text"||e==="output_text"||e==="input_text")&&typeof t.text=="string"?t.text:""}function H(t){if(typeof t=="string")return t;if(t===null||typeof t>"u")return"";try{return JSON.stringify(t)}catch{return String(t)}}function V(t){return typeof t=="string"?t:Array.isArray(t)?t.map(e=>{if(!_(e))return"";const n=c(e.type);return(n==="summary_text"||n==="text")&&typeof e.text=="string"?e.text:""}).filter(Boolean).join(""):""}function X(t){return t==="developer"?"system":t==="system"||t==="user"||t==="assistant"||t==="tool"?t:"user"}function F(t){if(typeof t=="string")return t;if(!Array.isArray(t))return null;const e=[],n=[];let s=!1;for(const i of t){if(!_(i))continue;const o=c(i.type);if((o==="input_text"||o==="output_text"||o==="text")&&typeof i.text=="string"){n.push(i.text),e.push({type:"text",text:i.text});continue}if(o==="input_image"){const p=i.image_url;typeof p=="string"&&p.trim()?(e.push({type:"image_url",image_url:{url:p}}),s=!0):_(p)&&(e.push({type:"image_url",image_url:p}),s=!0)}}return e.length===0?null:s?e:n.join("")}function S(t,e,n="",s=null){if(e.length===0)return!1;const i={role:"assistant",content:s,reasoning_content:n,tool_calls:[...e]};return t.push(i),e.length=0,!0}function G(t){if(!_(t)||c(t.type)!=="function")return t;const e=c(t.name);return e?{type:"function",function:{name:e}}:t}function w(t){if(!Array.isArray(t))return;const e=t.flatMap(n=>{if(!_(n)||c(n.type)!=="function")return[];const s=c(n.name);if(!s)return[];const i={name:s};return typeof n.description=="string"&&n.description.trim()&&(i.description=n.description),(_(n.parameters)||Array.isArray(n.parameters))&&(i.parameters=n.parameters),typeof n.strict=="boolean"&&(i.strict=n.strict),[{type:"function",function:i}]});return e.length>0?e:void 0}function k(t,e){return{id:t.id,type:"reasoning",status:e,summary:t.text.length>0?[{type:"summary_text",text:t.text}]:[],content:[]}}function P(t,e,n=null){const s=t.requestContext,i=[];t.reasoningItem?.done&&i.push({outputIndex:t.reasoningItem.outputIndex,item:k(t.reasoningItem,"completed")}),t.textItem?.done&&i.push({outputIndex:t.textItem.outputIndex,item:{id:t.textItem.id,type:"message",status:"completed",role:"assistant",content:[{type:"output_text",text:t.textItem.text,annotations:[]}]}});for(const o of[...t.toolCallsByIndex.values()].sort((p,a)=>p.outputIndex-a.outputIndex))o.done&&i.push({outputIndex:o.outputIndex,item:{id:o.id,type:"function_call",status:"completed",call_id:o.callId,name:o.name,arguments:o.arguments}});return{id:t.responseId,object:"response",created_at:t.createdAt,status:e,error:n,incomplete_details:null,instructions:s.instructions??null,max_output_tokens:s.max_output_tokens??null,model:t.model,output:i.sort((o,p)=>o.outputIndex-p.outputIndex).map(o=>o.item),output_text:t.textItem?.text??"",parallel_tool_calls:typeof s.parallel_tool_calls=="boolean"?s.parallel_tool_calls:t.toolCallsByIndex.size>1,previous_response_id:s.previous_response_id??null,reasoning:_(s.reasoning)?s.reasoning:{effort:null,summary:null},store:typeof s.store=="boolean"?s.store:!1,temperature:typeof s.temperature=="number"?s.temperature:1,text:_(s.text)?s.text:{format:{type:"text"}},tool_choice:typeof s.tool_choice>"u"?"auto":s.tool_choice,tools:Array.isArray(s.tools)?s.tools:[],top_p:typeof s.top_p=="number"?s.top_p:1,truncation:typeof s.truncation=="string"?s.truncation:"disabled",usage:{input_tokens:t.usage?.input_tokens??0,output_tokens:t.usage?.output_tokens??0,total_tokens:t.usage?.total_tokens??0,...typeof t.usage?.input_tokens_details<"u"?{input_tokens_details:t.usage.input_tokens_details}:{},...typeof t.usage?.output_tokens_details<"u"?{output_tokens_details:t.usage.output_tokens_details}:{}},user:s.user??null,metadata:_(s.metadata)?s.metadata:{}}}function y(t){const e=t.sequenceNumber;return t.sequenceNumber+=1,e}function x(t){return t.eventSequence+=1,`compat-${t.eventSequence}`}function $(t){return t.createdEmitted?[]:(t.createdEmitted=!0,[{type:"response.created",sequence_number:y(t),response:P(t,"in_progress")}])}function v(t){return t.textItem||(t.textItem={id:`msg_${I()}`,outputIndex:t.nextOutputIndex,text:"",added:!1,done:!1},t.nextOutputIndex+=1),t.textItem}function N(t){return t.reasoningItem||(t.reasoningItem={id:`rs_${I()}`,outputIndex:t.nextOutputIndex,text:"",added:!1,done:!1},t.nextOutputIndex+=1),t.reasoningItem}function O(t,e){const n=t.toolCallsByIndex.get(e);if(n)return n;const s={id:`fc_${I()}`,callId:`call_${I()}`,name:`tool_${e}`,arguments:"",outputIndex:t.nextOutputIndex,added:!1,done:!1};return t.nextOutputIndex+=1,t.toolCallsByIndex.set(e,s),s}function K(t){return typeof t=="string"?t:E(t)}function Y(t,e,n){return(e??"GET").toUpperCase()!=="POST"||!new URL(n,"http://grix.internal").pathname.endsWith("/responses")?!1:B(t[M])===z}function Z(t){const e={...t};return delete e[M],delete e["X-Grix-OpenAI-Wire-Compat"],e}function q(t){const e=new URL(t,"http://grix.internal");return e.pathname=e.pathname.replace(/\/responses$/,"/chat/completions"),`${e.pathname}${e.search}`}function tt(t,e){const n=_(t)?t:{},s=[],i=[];let o="";const p=c(n.instructions);p&&s.push({role:"system",content:p});const a=J(n.model);a&&s.push({role:"system",content:a});const m=Array.isArray(n.input)?n.input:[];for(const r of m){if(!_(r))continue;const d=c(r.type);if(d==="message"||!d&&r.role){const f=X(c(r.role)),g=F(r.content);if(f==="assistant"&&i.length>0){S(s,i,o,g),o="";continue}(S(s,i,o)||f!=="assistant")&&(o="");const b={role:f,content:g};f==="assistant"&&o.trim()&&(b.reasoning_content=o,o=""),s.push(b);continue}if(d==="reasoning"){o+=V(r.summary);continue}if(d==="function_call"){const f=c(r.name);if(!f)continue;i.push({id:c(r.call_id)||`call_${I()}`,type:"function",function:{name:f,arguments:c(r.arguments)}});continue}d==="function_call_output"&&(S(s,i,o),o="",s.push({role:"tool",tool_call_id:c(r.call_id),content:H(r.output)}))}S(s,i,o);const u={model:n.model,messages:s,stream:n.stream===!0},l=w(n.tools);return l&&(u.tools=l),!e?.omitToolChoice&&typeof n.tool_choice<"u"&&(u.tool_choice=G(n.tool_choice)),typeof n.parallel_tool_calls=="boolean"&&(u.parallel_tool_calls=n.parallel_tool_calls),typeof n.max_output_tokens=="number"&&(u.max_tokens=n.max_output_tokens),typeof n.temperature=="number"&&(u.temperature=n.temperature),typeof n.top_p=="number"&&(u.top_p=n.top_p),u}class et{state;constructor(e){this.state={responseId:e?.responseId?.trim()||`resp_${I()}`,model:e?.model?.trim()||"",createdAt:e?.createdAt??Math.floor(Date.now()/1e3),sequenceNumber:0,eventSequence:0,nextOutputIndex:0,requestContext:W(e?.requestBody),reasoningItem:null,textItem:null,textProbeBuffer:"",dsmlTextBuffer:null,toolCallsByIndex:new Map,createdEmitted:!1,completedEmitted:!1}}consumeChatCompletionChunk(e){const n=_(e)?e:{};typeof n.id=="string"&&n.id.trim()&&(this.state.responseId=n.id),typeof n.model=="string"&&n.model.trim()&&(this.state.model=n.model),typeof n.created=="number"&&(this.state.createdAt=n.created),n.usage&&R(this.state,n.usage);const s=$(this.state);for(const i of n.choices??[]){const o=i.delta,p=c(o?.reasoning_content);if(p.length>0){const u=N(this.state);u.added||(u.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:u.outputIndex,item:k(u,"in_progress")})),u.text+=p,s.push({type:"response.reasoning_summary_text.delta",item_id:u.id,output_index:u.outputIndex,summary_index:0,delta:p,sequence_number:y(this.state)})}const a=o?.content??"";this.state.reasoningItem?.added&&!this.state.reasoningItem.done&&(typeof a=="string"&&a.length>0||(o?.tool_calls?.length??0)>0)&&s.push(...this.completePendingReasoningSummary()),typeof a=="string"&&a.length>0&&s.push(...this.consumeTextDelta(a));const m=o?.tool_calls??[];m.length>0&&s.push(...this.flushTextCompatibilityBuffers(!1));for(const u of m){const l=typeof u.index=="number"&&Number.isFinite(u.index)?u.index:0,r=O(this.state,l);typeof u.id=="string"&&u.id.trim()&&(r.callId=u.id);const d=u.function,f=c(d?.name);f&&(r.name=r.name.startsWith("tool_")&&r.arguments.length===0?f:r.name===f?r.name:`${r.name}${f}`),r.added||(r.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:r.outputIndex,item:{id:r.id,type:"function_call",status:"in_progress",call_id:r.callId,name:r.name,arguments:""}}));const g=c(d?.arguments);g&&(r.arguments+=g,s.push({type:"response.function_call_arguments.delta",event_id:x(this.state),response_id:this.state.responseId,item_id:r.id,output_index:r.outputIndex,call_id:r.callId,delta:g}))}i.finish_reason&&(s.push(...this.flushTextCompatibilityBuffers(!0)),s.push(...this.completePendingReasoningSummary()),s.push(...this.completePendingItems()))}return s}consumeChatCompletion(e){const n=_(e)?e:{};typeof n.id=="string"&&n.id.trim()&&(this.state.responseId=n.id),typeof n.model=="string"&&n.model.trim()&&(this.state.model=n.model),typeof n.created=="number"&&(this.state.createdAt=n.created),n.usage&&R(this.state,n.usage);const s=$(this.state),o=n.choices?.[0],p=_(o?.message)?o.message:{},a=c(p.reasoning_content);if(a.length>0){const l=N(this.state);l.added||(l.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:l.outputIndex,item:k(l,"in_progress")})),l.text+=a,s.push({type:"response.reasoning_summary_text.delta",item_id:l.id,output_index:l.outputIndex,summary_index:0,delta:a,sequence_number:y(this.state)})}let m=K(p.content),u=Array.isArray(p.tool_calls)?p.tool_calls:[];if(m&&u.length===0){const l=L(m);l&&(m=l.visibleText,u=l.calls.map(r=>({id:`call_${I()}`,type:"function",function:{name:r.name,arguments:r.arguments}})))}if(a.length>0&&(m||u.length>0)&&s.push(...this.completePendingReasoningSummary()),m){const l=v(this.state);l.added||(l.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:l.outputIndex,item:{id:l.id,type:"message",status:"in_progress",role:"assistant",content:[]}})),l.text+=m,s.push({type:"response.output_text.delta",sequence_number:y(this.state),output_index:l.outputIndex,item_id:l.id,content_index:0,delta:m,logprobs:[]})}return u.forEach((l,r)=>{if(!_(l))return;const d=O(this.state,r),f=c(l.id);f&&(d.callId=f);const g=_(l.function)?l.function:{},D=c(g.name);D&&(d.name=D),d.added||(d.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:d.outputIndex,item:{id:d.id,type:"function_call",status:"in_progress",call_id:d.callId,name:d.name,arguments:""}}));const b=c(g.arguments);b&&(d.arguments=b,s.push({type:"response.function_call_arguments.delta",event_id:x(this.state),response_id:this.state.responseId,item_id:d.id,output_index:d.outputIndex,call_id:d.callId,delta:b}))}),s.push(...this.completePendingItems()),s}hasSemanticOutput(){return(this.state.textItem?.text.trim().length??0)>0||(this.state.reasoningItem?.text.trim().length??0)>0?!0:[...this.state.toolCallsByIndex.values()].some(e=>e.name.trim().length>0||e.arguments.trim().length>0)}finalize(){if(this.state.completedEmitted)return[];const e=[...this.flushTextCompatibilityBuffers(!0),...this.completePendingReasoningSummary(),...this.completePendingItems()];return this.state.completedEmitted=!0,this.hasSemanticOutput()?(e.push({type:"response.completed",sequence_number:y(this.state),response:P(this.state,"completed")}),e):(e.push({type:"response.failed",sequence_number:y(this.state),response:P(this.state,"failed",{code:"server_error",message:"Upstream model completed without producing any output."})}),e)}emitTextDelta(e){if(!e)return[];const n=v(this.state),s=[];return n.added||(n.added=!0,s.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:n.outputIndex,item:{id:n.id,type:"message",status:"in_progress",role:"assistant",content:[]}})),n.text+=e,s.push({type:"response.output_text.delta",sequence_number:y(this.state),output_index:n.outputIndex,item_id:n.id,content_index:0,delta:e,logprobs:[]}),s}consumeTextDelta(e){if(this.state.dsmlTextBuffer!==null)return this.state.dsmlTextBuffer+=e,[];this.state.textProbeBuffer+=e;const n=T(this.state.textProbeBuffer),s=A.map(a=>n.indexOf(a)).filter(a=>a>=0);if(s.length>0){const a=Math.min(...s),m=this.state.textProbeBuffer.slice(0,a);return this.state.dsmlTextBuffer=this.state.textProbeBuffer.slice(a),this.state.textProbeBuffer="",this.emitTextDelta(m)}const i=j(this.state.textProbeBuffer),o=this.state.textProbeBuffer.length-i;if(o<=0)return[];const p=this.state.textProbeBuffer.slice(0,o);return this.state.textProbeBuffer=this.state.textProbeBuffer.slice(o),this.emitTextDelta(p)}emitParsedDsmlToolCalls(e){const n=[];return e.forEach((s,i)=>{const o=O(this.state,i);o.name=s.name,o.arguments=s.arguments,o.added||(o.added=!0,n.push({type:"response.output_item.added",event_id:x(this.state),response_id:this.state.responseId,output_index:o.outputIndex,item:{id:o.id,type:"function_call",status:"in_progress",call_id:o.callId,name:o.name,arguments:""}})),n.push({type:"response.function_call_arguments.delta",event_id:x(this.state),response_id:this.state.responseId,item_id:o.id,output_index:o.outputIndex,call_id:o.callId,delta:o.arguments})}),n}flushTextCompatibilityBuffers(e){const n=[];if(this.state.dsmlTextBuffer!==null){const s=this.state.dsmlTextBuffer;this.state.dsmlTextBuffer=null;const i=e&&this.state.toolCallsByIndex.size===0?L(s):null;i?(n.push(...this.emitParsedDsmlToolCalls(i.calls)),n.push(...this.emitTextDelta(i.visibleText))):n.push(...this.emitTextDelta(s))}return this.state.textProbeBuffer&&(n.push(...this.emitTextDelta(this.state.textProbeBuffer)),this.state.textProbeBuffer=""),n}completePendingReasoningSummary(){const e=this.state.reasoningItem;return!e?.added||e.done?[]:(e.done=!0,[{type:"response.reasoning_summary_text.done",item_id:e.id,output_index:e.outputIndex,summary_index:0,text:e.text,sequence_number:y(this.state)},{type:"response.output_item.done",event_id:x(this.state),response_id:this.state.responseId,output_index:e.outputIndex,item:k(e,"completed")}])}completePendingItems(){const e=[];for(const n of[...this.state.toolCallsByIndex.values()].sort((s,i)=>s.outputIndex-i.outputIndex))!n.added||n.done||(n.done=!0,e.push({type:"response.function_call_arguments.done",event_id:x(this.state),response_id:this.state.responseId,item_id:n.id,output_index:n.outputIndex,call_id:n.callId,arguments:n.arguments}),e.push({type:"response.output_item.done",event_id:x(this.state),response_id:this.state.responseId,output_index:n.outputIndex,item:{id:n.id,type:"function_call",status:"completed",call_id:n.callId,name:n.name,arguments:n.arguments}}));return this.state.textItem?.added&&!this.state.textItem.done&&(this.state.textItem.done=!0,e.push({type:"response.output_text.done",event_id:x(this.state),response_id:this.state.responseId,output_index:this.state.textItem.outputIndex,item_id:this.state.textItem.id,content_index:0,text:this.state.textItem.text,logprobs:[],sequence_number:y(this.state)}),e.push({type:"response.output_item.done",event_id:x(this.state),response_id:this.state.responseId,output_index:this.state.textItem.outputIndex,item:{id:this.state.textItem.id,type:"message",status:"completed",role:"assistant",content:[{type:"output_text",text:this.state.textItem.text,annotations:[]}]}})),e}}function nt(t){return Buffer.from(`data: ${JSON.stringify(t)}
|
|
2
2
|
|
|
3
3
|
`,"utf8")}function st(t){const e=t.replaceAll(`\r
|
|
4
4
|
`,`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{mkdir as
|
|
1
|
+
import{mkdir as y,writeFile as v,rm as w}from"node:fs/promises";import{join as d}from"node:path";import{createHash as _}from"node:crypto";import{log as l}from"../log/index.js";import{readSkillManifest as O,writeSkillManifest as I}from"./manifest.js";const D=6e4,p=15e3;class R{configs;skillsDir;timer=null;running=!1;rerunPending=!1;stopped=!1;fetchImpl;intervalMs;onSyncSuccessHandler=null;constructor(t,r,i={}){this.configs=t,this.skillsDir=r,this.intervalMs=i.intervalMs??D,this.fetchImpl=i.fetchImpl??fetch}async start(){this.stopped=!1,await this.syncOnce().catch(t=>l.warn("skill-sync",`initial sync failed: ${c(t)}`)),this.timer=setInterval(()=>{this.syncOnce().catch(t=>l.warn("skill-sync",`sync failed: ${c(t)}`))},this.intervalMs),this.timer.unref?.()}stop(){this.stopped=!0,this.rerunPending=!1,this.timer&&(clearInterval(this.timer),this.timer=null)}setOnSyncSuccess(t){this.onSyncSuccessHandler=t}triggerSync(){if(this.running){this.rerunPending=!0;return}this.syncOnce().catch(t=>l.warn("skill-sync",`triggered sync failed: ${c(t)}`))}async syncOnce(){if(!this.running){this.running=!0;try{const t=await this.pickReachable();if(!t)return;const{cfg:r,remote:i}=t;await y(this.skillsDir,{recursive:!0});const n=await O(this.skillsDir),o=JSON.stringify(n),g=new Set(i.map(e=>e.name));for(const e of i){const s=n.skills[e.name];if(s&&s.digest===e.digest){const f=e.owner_id!==void 0?e.owner_id:s.owner_id,$=f==="0",h={...s,id:e.id,version:e.version,...f!==void 0?{owner_id:f}:{},system:$};(s.id!==h.id||s.version!==h.version||s.owner_id!==h.owner_id||s.system!==h.system)&&(n.skills[e.name]=h);continue}const S=e.owner_id==="0",u=M(e.name);if(!u){l.warn("skill-sync",`skip skill with unsafe name: ${e.name}`);continue}const m=await this.fetchContent(r,e.id);if(m!==null)try{await y(d(this.skillsDir,u),{recursive:!0}),await v(d(this.skillsDir,u,"SKILL.md"),m,"utf8"),n.skills[e.name]={id:e.id,version:e.version,digest:e.digest,dir:u,...e.owner_id!==void 0?{owner_id:e.owner_id}:{},system:S},s&&s.dir!==u&&!this.dirSharedByOthers(n,e.name,s.dir)&&await w(d(this.skillsDir,s.dir),{recursive:!0,force:!0}).catch(()=>{})}catch(f){l.warn("skill-sync",`write skill "${e.name}" failed: ${c(f)}`)}}for(const e of Object.keys(n.skills)){if(g.has(e))continue;const s=n.skills[e];this.dirSharedByOthers(n,e,s.dir)||await w(d(this.skillsDir,s.dir),{recursive:!0,force:!0}).catch(()=>{}),delete n.skills[e]}if(!(JSON.stringify(n)!==o))return;await I(this.skillsDir,n);try{this.onSyncSuccessHandler?.()}catch(e){l.warn("skill-sync",`onSyncSuccess handler failed: ${c(e)}`)}}finally{this.running=!1,this.rerunPending&&(this.rerunPending=!1,(this.timer!==null||!this.stopped)&&this.syncOnce().catch(t=>l.warn("skill-sync",`rerun sync failed: ${c(t)}`)))}}}dirSharedByOthers(t,r,i){return Object.entries(t.skills).some(([n,o])=>n!==r&&o.dir===i)}async pickReachable(){for(const t of this.configs){if(!t.apiKey||!t.wsUrl)continue;const r=await this.fetchList(t);if(r!==null)return{cfg:t,remote:r}}return null}async fetchList(t){const r=`${k(t.wsUrl)}/v1/agent-api/skills`;try{const i=await this.fetchImpl(r,{headers:{Authorization:`Bearer ${t.apiKey}`},signal:AbortSignal.timeout(p)});if(!i.ok)return l.warn("skill-sync",`list returned ${i.status}`),null;const n=await i.json();return n.code!==0?null:n.data?.items??[]}catch(i){return l.warn("skill-sync",`list error: ${c(i)}`),null}}async fetchContent(t,r){const i=`${k(t.wsUrl)}/v1/agent-api/skills/${encodeURIComponent(r)}/content`;try{const n=await this.fetchImpl(i,{headers:{Authorization:`Bearer ${t.apiKey}`},signal:AbortSignal.timeout(p)});if(!n.ok)return l.warn("skill-sync",`content ${r} returned ${n.status}`),null;const o=await n.json();return o.code!==0?null:typeof o.data?.content=="string"?o.data.content:null}catch(n){return l.warn("skill-sync",`content ${r} error: ${c(n)}`),null}}}function k(a){return new URL(a.replace(/^wss:/,"https:").replace(/^ws:/,"http:")).origin}function M(a){const t=a.trim().replace(/[/\\]/g,"_").replace(/[<>:"|?*\u0000-\u001f]/g,"_").replace(/^\.+/,"").replace(/[. ]+$/,"");return!t||t.includes("..")||/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i.test(t)?null:t!==a?`${t}-${_("sha1").update(a).digest("hex").slice(0,8)}`:t}function c(a){return a instanceof Error?a.message:String(a)}export{R as SkillSyncer};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{execFile as C,execFileSync as h}from"node:child_process";import{promisify as j}from"node:util";import{existsSync as c,mkdirSync as P,mkdtempSync as G,readFileSync as k,renameSync as f,rmSync as
|
|
2
|
-
`;try{W(
|
|
1
|
+
import{execFile as C,execFileSync as h}from"node:child_process";import{promisify as j}from"node:util";import{existsSync as c,mkdirSync as P,mkdtempSync as G,readFileSync as k,renameSync as f,rmSync as g,statfsSync as Y,symlinkSync as J,unlinkSync as $,writeFileSync as K}from"node:fs";import{basename as x,join as l,relative as H,resolve as d,sep as D}from"node:path";import{GRIX_PATHS as F}from"../log/index.js";import{appendRotatingFileSync as W}from"../log/rotation.js";import{getMachineName as X}from"../util/host-info.js";import{resolveInstallId as z}from"../util/install-id.js";import{npmInstallWithMirror as N,probeRegistries as q}from"../installer/npm-registry.js";const Q=j(C);class a extends Error{code;constructor(t,r){super(r),this.name="UpgradeError",this.code=t}}const M=".grix-upgrade-backup",Z=".grix-upgrade-failed";function A(){return l(F.log,"upgrade.log")}function _(){return l(F.data,"upgrade-pending.json")}function de(){return c(_())}function S(){const e=_();if(!c(e))return null;try{return JSON.parse(k(e,"utf-8"))}catch{return null}}function me(e,t){const r={from_version:e,target_version:t,upgraded_at:new Date().toISOString(),crash_count:0},i=_();L(i,r)}function L(e,t){const r=e+".tmp";K(r,JSON.stringify(t),"utf-8"),f(r,e)}function w(e,t){const r=d(e);return d(t)===`${r}${M}`&&r.includes(`${D}node_modules${D}`)&&x(r).length>0}function ee(e,t){const r=S();!r||!w(e,t)||(r.package_dir=d(e),r.backup_dir=d(t),L(_(),r))}function he(e=S()){const t=e?.package_dir,r=e?.backup_dir;if(!(!t||!r||!w(t,r)))try{g(r,{recursive:!0,force:!0})}catch{}}function _e(e=S()){const t=e?.package_dir,r=e?.backup_dir;if(!t||!r||!w(t,r)||!c(r))return!1;const i=`${t}${Z}`;try{return g(i,{recursive:!0,force:!0}),c(t)&&f(t,i),f(r,t),g(i,{recursive:!0,force:!0}),p(`atomic rollback restored ${t}`),!0}catch(n){try{!c(t)&&c(i)&&f(i,t)}catch{}return p(`atomic rollback failed: ${n instanceof Error?n.message:String(n)}`),!1}}function ye(){const e=_();if(c(e))try{$(e)}catch{}}function p(e){const t=`[${new Date().toISOString()}] ${e}
|
|
2
|
+
`;try{W(A(),t)}catch{}}function ke(e=4096){const t=A();if(!c(t))return"";try{const r=k(t,"utf-8");return r.length<=e?r:r.slice(-e)}catch{return""}}function O(){try{const e=process.platform==="win32";return h(e?"cmd.exe":"npm",e?["/c","npm","--version"]:["--version"],{encoding:"utf-8",timeout:1e4}).trim()}catch{throw new a("NPM_NOT_FOUND","npm is not available or timed out")}}const m=1e6;function R(){if(process.platform==="win32")return m;let e;try{e=h("npm",["prefix","-g"],{encoding:"utf-8",timeout:1e4}).trim()}catch{return m}try{const t=Y(e),r=Math.floor(Number(t.bavail)*Number(t.bsize)/(1024*1024));return!Number.isFinite(r)||r<0?m:Math.min(r,m)}catch{return m}}function ve(){let e;try{e=O()}catch(r){return{ok:!1,errorCode:"NPM_NOT_FOUND",errorMsg:r instanceof Error?r.message:"npm not available"}}const t=R();return t<100?{ok:!1,errorCode:"DISK_FULL",errorMsg:`Only ${t}MB free disk space (need >= 100MB)`,npmVersion:e,diskFreeMb:t}:{ok:!0,npmVersion:e,diskFreeMb:t}}function Se(){let e="";try{e=O()}catch{}let t=m;try{t=R()}catch{}return{npm_version:e,node_version:process.version,disk_free_mb:t,platform:process.platform,arch:process.arch,host_name:X(),install_id:z()}}function b(e,t,r){const i=l(e,"package.json");let n;try{n=JSON.parse(k(i,"utf-8"))}catch{throw new a("VERSION_VERIFY_FAILED",`Unable to read staged package metadata: ${i}`)}if(n.name!==t||n.version?.replace(/^v(?=\d)/,"")!==r)throw new a("VERSION_MISMATCH",`Staged package ${String(n.name)}@${String(n.version)} does not match ${t}@${r}`);return n}function te(e){return typeof e.bin=="string"?[[x(e.name),e.bin]]:!e.bin||typeof e.bin!="object"?[]:Object.entries(e.bin).filter(t=>typeof t[1]=="string")}function E(e,t){const r=te(t);if(r.length===0)throw new a("VERSION_VERIFY_FAILED",`Staged package ${t.name} has no executable bin`);for(const[,i]of r){const n=l(e,i);if(!c(n))throw new a("VERSION_VERIFY_FAILED",`Staged package entrypoint is missing: ${n}`)}return r}function re(e,t,r){if(process.platform==="win32")return;const i=l(e,"bin");P(i,{recursive:!0});for(const[n,o]of r){const s=l(i,n);if(c(s))continue;const u=`${s}.grix-upgrade-${process.pid}`;try{$(u)}catch{}J(H(i,l(t,o)),u),f(u,s)}}function ne(e){const t=d(e.activePackageDir),r=d(e.stagedPackageDir),i=`${t}${M}`,n=b(r,e.packageName,e.version),o=E(r,n);c(i)&&(c(t)?g(i,{recursive:!0,force:!0}):f(i,t)),ee(t,i);let s=!1;try{c(t)&&(f(t,i),s=!0),f(r,t);const u=b(t,e.packageName,e.version),v=E(t,u);return re(e.npmPrefix,t,v),{packageDir:t,backupDir:i}}catch(u){try{c(t)&&g(t,{recursive:!0,force:!0}),s&&c(i)&&f(i,t)}catch{}throw u}}function I(e){try{return h("npm",e,{encoding:"utf-8",timeout:1e4}).trim()}catch{throw new a("NPM_NOT_FOUND",`Unable to resolve npm ${e.join(" ")}`)}}async function ie(e,t,r){const i=`${e}@${t}`,n=I(["prefix","-g"]),o=I(["root","-g"]);P(n,{recursive:!0});const s=G(l(n,".grix-upgrade-stage-"));try{p(`staging npm install ${i} under ${s}`);const{registry:u}=await N(i,r,10*1024*1024,{prefix:s}),v=I(["root","-g","--prefix",s]),y=l(v,e),U=b(y,e,t),T=E(y,U),V=l(y,T[0][1]);h(process.execPath,[V,"--version"],{encoding:"utf-8",timeout:15e3,maxBuffer:2*1024*1024});const B=ne({packageName:e,version:t,npmPrefix:n,activePackageDir:l(o,e),stagedPackageDir:y});p(`atomic package switch succeeded via ${u}; backup=${B.backupDir}`)}finally{try{g(s,{recursive:!0,force:!0})}catch{}}}async function we(e,t,r=12e4){const i=`${e}@${t}`;p(`npm install -g ${i} starting (atomic staging with mirror fallback)`);try{if(process.platform==="win32"){const{registry:n}=await N(i,r,10485760);p(`npm install succeeded via ${n}`)}else await ie(e,t,r)}catch(n){if(n instanceof a)throw n;const o=n instanceof Error?n.message:String(n);throw p(`npm install failed: ${o}`),/timed out|ETIMEDOUT/i.test(o)?new a("NPM_TIMEOUT",`npm install timed out after ${r/1e3}s (tried all mirrors): ${o}`):o.includes("EACCES")||o.includes("permission denied")?new a("NPM_INSTALL_FAILED",`Permission denied: ${o}`):o.includes("ENOSPC")||o.includes("no space left")?new a("DISK_FULL",`Disk full: ${o}`):o.includes("404")||o.includes("not found")?new a("NPM_INSTALL_FAILED",`Package not found: ${o}`):new a("NPM_INSTALL_FAILED",o)}}function be(e){let t;try{const i=process.platform==="win32";t=h(i?"cmd.exe":"npm",i?["/c","npm","root","-g"]:["root","-g"],{encoding:"utf-8",timeout:1e4}).trim()}catch{throw new a("VERSION_VERIFY_FAILED","Unable to resolve the global npm package directory")}let r;try{const i=l(t,"grix-connector","package.json"),n=JSON.parse(k(i,"utf-8"));if(n.name!=="grix-connector"||typeof n.version!="string"||!n.version.trim())throw new Error("invalid package metadata");r=n.version.trim().replace(/^v(?=\d)/,"")}catch{throw new a("VERSION_VERIFY_FAILED","Unable to read the installed grix-connector version")}if(r!==e)throw new a("VERSION_MISMATCH",`Installed version ${r} does not match expected ${e}`);return r}async function Ee(e,t){let r=!1;for(const i of await q())try{const{stdout:n}=await Q("npm",["view",`${e}@${t}`,"version","--registry",i.url,"--no-audit","--no-fund"],{timeout:8e3});if(n.trim())return!0}catch(n){const o=n,s=o.stderr||o.message||String(n);/ETARGET|No matching version|notarget|E404/i.test(s)&&(r=!0)}return!r}export{a as UpgradeError,R as checkDiskSpace,O as checkNpmAvailable,he as cleanupPendingBackup,Se as collectEnvInfo,ne as commitStagedGlobalPackage,ke as getUpgradeLogTail,Ee as isVersionAvailable,we as npmInstall,de as pendingExists,ve as preflightCheck,S as readPending,ye as removePending,_e as rollbackPendingInstall,p as upgradeLog,be as verifyInstalledVersion,me as writePending};
|
package/dist/log.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createWriteStream as g,mkdirSync as l,existsSync as f}from"node:fs";import{join as
|
|
2
|
-
`)},error(o,r,...
|
|
1
|
+
import{createWriteStream as g,mkdirSync as l,existsSync as f}from"node:fs";import{join as i}from"node:path";import{homedir as m}from"node:os";const n=i(m(),".grix"),s={base:n,config:i(n,"config"),log:i(n,"log"),data:i(n,"data")};function S(){for(const o of Object.values(s))f(o)||l(o,{recursive:!0})}let a=null;function $(){const o=new Date().toISOString().slice(0,10),r=i(s.log,`grix-acp-${o}.log`);a=g(r,{flags:"a"})}function c(){return new Date().toISOString().slice(11,19)}const u={info(o,r,...t){const e=`${c()} [${o}] ${r}${t.length?" "+t.map(String).join(" "):""}`;console.log(e),a?.write(e+`
|
|
2
|
+
`)},error(o,r,...t){const e=`${c()} [${o}] ERROR ${r}${t.length?" "+t.map(String).join(" "):""}`;console.error(e),a?.write(e+`
|
|
3
3
|
`)}};export{s as GRIX_PATHS,S as ensureGrixDirs,$ as initLogger,u as log};
|
package/dist/manager.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readFileSync as Z,readdirSync as ee,writeFileSync as te}from"node:fs";import{join as A}from"node:path";import{homedir as ne}from"node:os";import{AgentInstance as D}from"./bridge/bridge.js";import{buildSharedInstanceConfig as re,diffSharedOwners as ae,sharedInstanceKey as ie,SharedOwnersCache as se}from"./manager-share-config.js";import{isAgentDeletedError as O}from"./core/aibot/errors.js";import{GRIX_PATHS as _,log as p}from"./core/log/index.js";import{resolveClientVersion as oe}from"./core/util/client-version.js";import{UpgradeChecker as ce}from"./core/upgrade/upgrade-checker.js";import{SkillSyncer as le}from"./core/skill-sync/skill-syncer.js";import{AgentGlobalConfigStore as de}from"./core/persistence/agent-global-config-store.js";import{resolveSkillScanMode as pe}from"./adapter/claude/skill-scanner.js";import{buildWireSkills as me}from"./core/skill-sync/sync-state.js";import{buildLibrarySkills as ue}from"./core/skill-sync/library-skills.js";import{AUDIT_LOCAL_ACTION_TYPES as ge}from"./core/aibot/types.js";import{buildReportedSkills as fe,logDefaultSkillsCheck as he,cleanupProjectedSkills as N}from"./default-skills/index.js";import{supportsKiroCwRelay as q,supportsNonMitmRelayConfig as _e}from"./core/config/provider-env.js";import{ensureKiroRelay as H,stopKiroRelay as L}from"./core/proxy/kiro-relay.js";import{resolveCopilotCommand as U}from"./core/runtime/copilot-resolve.js";import{resolveCursorCommand as B}from"./core/runtime/cursor-resolve.js";import{getCliVersion as ye,resolveCliPath as we}from"./core/util/cli-probe.js";import{AgentInstaller as ve}from"./core/installer/installer.js";import{reportInstallFailure as Se}from"./core/observability/sentry.js";import{createDefaultAuditProducer as Ae}from"./audit/runtime/default-audit-recorder.js";import{normalizeCodexConfigOverrides as ke}from"./adapter/codex/config-overrides.js";import{resolveCodexDirectHome as be}from"./adapter/codex/direct-home.js";const Ce=8e3;function xe(){const n=U();return[{clientType:"openclaw",command:"openclaw"},{clientType:"claude",command:"claude"},{clientType:"codex",command:"codex"},{clientType:"qwen",command:"qwen"},{clientType:"hermes",command:"hermes"},{clientType:"reasonix",command:"reasonix"},{clientType:"codewhale",command:"codewhale"},{clientType:"opencode",command:"opencode"},{clientType:"cursor",command:B()},{clientType:"pi",command:"pi"},{clientType:"openhuman",command:"openhuman-core"},{clientType:"kiro",command:"kiro-cli"},{clientType:"kimi",command:"kimi"},{clientType:"copilot",command:n.command},{clientType:"agy",command:"agy"}]}async function $e(){return Promise.all(xe().map(async n=>{const e=await we(n.command);if(!e)return{client_type:n.clientType,command:n.command,installed:!1,path:null,version:null};const t=await ye(e,n.versionArgs??["--version"]);return{client_type:n.clientType,command:n.command,installed:!0,path:e,version:t.version,error:t.error}}))}function Ie(n){switch(n){case"claude":return{adapterType:"claude",command:"claude"};case"codex":return{adapterType:"codex",command:"codex",options:{sandboxMode:"danger-full-access"}};case"gemini":return{adapterType:"acp",command:"gemini",autoInjectArgs:{acp:!0},enableSessionBinding:!0};case"qwen":return{adapterType:"acp",command:"qwen",adapterHint:"qwen/base",autoInjectArgs:{acp:!0},enableSessionBinding:!0};case"pi":return{adapterType:"pi",command:"pi"};case"cursor":return{adapterType:"cursor",command:B()};case"reasonix":return{adapterType:"acp",command:"reasonix",args:["acp"],enableSessionBinding:!0};case"codewhale":return{adapterType:"codewhale",command:"codewhale",enableSessionBinding:!0};case"openhuman":return{adapterType:"openhuman",command:"openhuman-core",enableSessionBinding:!0};case"kiro":return{adapterType:"acp",command:"kiro-cli",args:["acp"],enableSessionBinding:!0};case"kimi":return{adapterType:"acp",command:"kimi",args:["acp"],options:{initial_mode:"yolo"},enableSessionBinding:!0};case"opencode":return{adapterType:"opencode",command:"opencode",args:["serve"],enableSessionBinding:!0};case"copilot":{const e=U();return{adapterType:"acp",command:e.command,args:[...e.prefixArgs,"--acp"],enableSessionBinding:!0}}case"agy":return{adapterType:"agy",command:"agy",enableSessionBinding:!0};case"hermes":return{adapterType:"acp",command:"hermes",args:["acp"],enableSessionBinding:!0};default:throw new Error(`Unsupported client_type: ${n}`)}}function k(n,e){return String(n??"").trim().toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||String(e??"").trim().toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"default"}function Te(n){return A(_.data,`session-bindings-${k(n,"unknown")}.json`)}function Ee(n,e){return A(_.data,`session-bindings-${k(n,e)}.json`)}function Re(n,e){return A(_.data,`active-events-${k(n,e)}.json`)}function Pe(n,e){const t=k(n,"agent"),r=k(e,"unknown");return A(_.data,`terminal-outbox-${t}-${r}.json`)}function je(...n){const e=[],t=new Set;for(const r of n)for(const a of r??[]){const o=String(a??"").trim(),i=o.toLowerCase();!o||t.has(i)||(t.add(i),e.push(o))}return e.length>0?e:void 0}function Me(n,e){const t={claude:{maxConcurrent:1,maxQueued:5,queueTimeoutMs:0},codex:{maxConcurrent:1,maxQueued:5,queueTimeoutMs:0},cursor:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0},acp:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0},pi:{maxConcurrent:1,maxQueued:5,queueTimeoutMs:0},codewhale:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0},openhuman:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0},opencode:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0},agy:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0}},r=t[n]??t.acp;return{maxConcurrent:e?.max_concurrent??r.maxConcurrent??1,maxQueued:e?.max_queued??r.maxQueued??3,queueTimeoutMs:e?.queue_timeout_ms??r.queueTimeoutMs??0,cancelableQueued:!0,cancelableRunning:!0}}function De(n,e={}){const t=oe(),r=String(n.client_type??"").trim().toLowerCase(),a=Ie(r),o=String(n.ws_url??"").trim(),i="get_session_usage",m="get_rate_limits",c="get_agent_global_config",s=ge;if(!n.name?.trim())throw new Error("agent name is required");if(!o)throw new Error(`agent ${n.name}: ws_url is required`);if(!n.agent_id?.trim())throw new Error(`agent ${n.name}: agent_id is required`);if(!n.api_key?.trim())throw new Error(`agent ${n.name}: api_key is required`);const l=a.adapterType,u=l==="acp",w=r==="qwen",d={...a.options??{}};if(n.codex_config_overrides!==void 0){if(l!=="codex")throw new Error(`agent ${n.name}: codex_config_overrides is only supported for client_type=codex`);ke(n.codex_config_overrides,`agent ${n.name}: codex_config_overrides`),d.codexConfigOverrides=n.codex_config_overrides}if(l==="codex"&&n.provider?.wire_api!==void 0){const f=n.provider;if(f.wire_api!=="responses"||!f.base_url?.trim()||!f.api_key?.trim()||!f.model?.trim()||!f.catalog_version?.trim()||!f.catalog_sha256?.trim()||!f.catalog_json?.trim())throw Object.assign(new Error(`agent ${n.name}: incomplete Codex direct relay config`),{code:"INVALID_CODEX_DIRECT_CONFIG"});const M=be(_.data,n.name);d.codexHome=M,d.codexDirect={codexHome:M,config:{baseUrl:f.base_url.trim(),model:f.model.trim(),...f.reasoning_effort?.trim()?{reasoningEffort:f.reasoning_effort.trim()}:{},token:f.api_key.trim()},catalog:{version:f.catalog_version.trim(),sha256:f.catalog_sha256.trim(),json:f.catalog_json}}}const h=l==="codex"?{capabilities:["local_action_v1","agent_invoke"],localActions:["session_control","get_context","set_model","set_mode","set_reasoning_effort","set_service_tier","set_sandbox_mode","exec_approve","exec_reject","file_list","create_folder","turn_interrupt","permission_approve","permission_reject","thread_compact",i,m]}:null,y=l==="claude"?{localActions:["session_control","set_mode","set_model","set_reasoning_effort","claude_interaction_reply","exec_approve","exec_reject","file_list","create_folder","thread_compact",i,m]}:null,g=w?{capabilities:["stream_chunk","local_action_v1"],localActions:["exec_approve","exec_reject","permission_approve","permission_reject","session_control","set_model","set_mode","file_list","create_folder",i],adapterHint:"qwen/base"}:null,S=l==="pi"?{adapterHint:"pi/base",capabilities:["stream_chunk","local_action_v1"],localActions:["session_control","set_model","get_context","file_list","create_folder",i,m]}:null,v=l==="openhuman"?{adapterHint:"openhuman/base",capabilities:["local_action_v1"],localActions:["session_control","set_model","file_list","create_folder"]}:null,C=l==="cursor"?{adapterHint:"cursor/base",capabilities:["stream_chunk","local_action_v1"],localActions:["session_control","set_model","set_mode","get_context","file_list","create_folder","thread_compact","claude_interaction_reply",m]}:null,T=l==="codewhale"?{capabilities:["stream_chunk","local_action_v1"],localActions:["session_control","set_model","file_list","create_folder",i]}:null,x=l==="opencode"?{adapterHint:"opencode/base",capabilities:["stream_chunk","local_action_v1"],localActions:["exec_approve","exec_reject","permission_approve","permission_reject","session_control","set_model","set_mode","claude_interaction_reply","file_list","create_folder"]}:null,$=l==="agy"?{adapterHint:"agy/base",capabilities:["stream_chunk","local_action_v1"],localActions:["session_control","set_model","file_list","create_folder"]}:null,E=new Set(["hermes","reasonix","kimi","copilot"]),Q=u&&!E.has(r),K=u&&!w?{localActions:["exec_approve","exec_reject","permission_approve","permission_reject","session_control","set_model","set_mode","file_list","create_folder",...Q?[i]:[]]}:null,W=r==="kiro"?{localActions:["exec_approve","exec_reject","permission_approve","permission_reject","session_control","set_model","set_mode","file_list","create_folder","thread_compact",i,m]}:null,z=l==="codex"||l==="claude"||l==="opencode"||r==="gemini"?["session_control","set_model","set_mode",...l==="claude"?["set_reasoning_effort"]:[]]:void 0,G=l==="cursor"||l==="opencode"||l==="openhuman"||l==="agy"||u&&E.has(r)?[m]:[i,m];u&&d.raw_transport===void 0&&(d.raw_transport=r==="gemini");const V=`${r}/base`,I=pe(l,r),J=I==="kiro"?void 0:process.cwd(),R=fe({mode:I,projectDir:J}),P=R.filter(f=>f.source==="connector").map(f=>f.name);P.length>0&&!e.quiet&&p.info("manager",`[${n.name}] injecting connector skills: [${P.join(", ")}]`);const j=me(R,_.skills);let X=j.length>0?j:void 0;const Y=ue({skillsDir:_.skills,mode:I,home:ne()});return{name:n.name,adapterType:l,aibot:{url:o,agentId:n.agent_id,apiKey:n.api_key,clientType:r,clientVersion:t,adapterHint:a.adapterHint??g?.adapterHint??S?.adapterHint??v?.adapterHint??C?.adapterHint??x?.adapterHint??$?.adapterHint??V,capabilities:h?.capabilities??T?.capabilities??S?.capabilities??v?.capabilities??C?.capabilities??x?.capabilities??$?.capabilities??g?.capabilities??["stream_chunk","local_action_v1","connector_upgrade"],localActions:je(h?.localActions??T?.localActions??y?.localActions??S?.localActions??v?.localActions??C?.localActions??x?.localActions??$?.localActions??g?.localActions??W?.localActions??K?.localActions??["exec_approve","exec_reject"],z,G,["connector_rollback","connector_upgrade_push",c,"configure_gateway_provider","skill_upload","skill_enable","skill_disable","skill_refresh",...s]),skills:X,librarySkills:Y,terminalOutboxPath:Pe(n.name,n.agent_id)},agent:{command:a.command,args:[...a.args??[],...n.args??[]],env:n.env,clientType:r,...n.provider?{provider:{...n.provider.provider_id?.trim()?{providerId:n.provider.provider_id.trim()}:{},...n.provider.base_url?.trim()?{baseUrl:n.provider.base_url.trim()}:{},...n.provider.quota_base_url?.trim()?{quotaBaseUrl:n.provider.quota_base_url.trim()}:{},...n.provider.api_key?.trim()?{apiKey:n.provider.api_key.trim()}:{},...n.provider.model?.trim()?{model:n.provider.model.trim()}:{},...n.provider.fast_model?.trim()?{fastModel:n.provider.fast_model.trim()}:{},...n.provider.effort?.trim()?{effort:n.provider.effort.trim()}:{}}}:{}},adapterOptions:d,acpAuthMethod:d.auth_method,acpInitialMode:d.initial_mode,acpMcpTools:d.acp_mcp_tools,promptTimeoutMs:n.prompt_timeout_ms,bindingsPath:Te(n.agent_id),legacyBindingsPath:Ee(n.name,n.agent_id),activeEventStorePath:Re(n.name,n.agent_id),...a.enableSessionBinding||u?{enableSessionBinding:!0}:{},...a.autoInjectArgs||r==="reasonix"&&n.provider?.model?.trim()?{autoInjectArgs:{...a.autoInjectArgs??{},...r==="reasonix"&&n.provider?.model?.trim()?{model:n.provider.model.trim()}:{}}}:{},poolMaxSize:n.pool?.maxSize,poolIdleTimeoutMs:n.pool?.idleTimeoutMs,eventQueue:Me(l,n.event_queue),logDir:_.log,providerBaseUrl:n.provider_base_url?.trim()||void 0,providerApiKey:n.provider_api_key?.trim()||void 0}}function Oe(){const n=process.env.GRIX_AGENT_STARTUP_WAIT_MS,e=Number(n);return Number.isFinite(e)&&e>=500?Math.floor(e):Ce}function F(n){const e=[],t=[],r=[],a=ee(n).filter(o=>o.endsWith(".json")).sort();for(const o of a)try{const i=JSON.parse(Z(A(n,o),"utf-8"));if(i===null||typeof i!="object"||Array.isArray(i)||!("agents"in i)){r.push(o);continue}if(!Array.isArray(i.agents)){t.push({file:o,error:"agents is not an array"});continue}if(i.agents.length===0){t.push({file:o,error:"agents array is empty"});continue}for(const m of i.agents)e.push({entry:m,file:o})}catch(i){t.push({file:o,error:i instanceof Error?i.message:String(i)})}return{entries:e,fileErrors:t,skipped:r}}function b(n){if(n===null||typeof n!="object")return JSON.stringify(n)??"null";if(Array.isArray(n))return`[${n.map(b).join(",")}]`;const e=n;return`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${b(e[r])}`).join(",")}}`}function Ne(n,e){return b(n)===b(e)}class mt{instances=[];configMap=new Map;rawConfigMap=new Map;reloadChain=Promise.resolve();sharedInstances=new Map;shareSyncChains=new Map;stopping=!1;deletedAgentCleanups=new Set;upgradeChecker=null;skillSyncer=null;globalConfigStore;configDir=_.config;sharedOwnersCache=new se(_.data);installer=new ve;relaySecretResolver;auditProducer=Ae();async start(e){const t=e??_.config;this.configDir=t,p.info("manager",`Loading configs from ${t}`),he(),N(),this.globalConfigStore=new de(A(_.data,"agent-global-configs.json")),this.globalConfigStore.load();const{entries:r,fileErrors:a,skipped:o}=F(t);for(const s of a)p.error("manager",`Failed to load ${s.file}: ${s.error}`);for(const s of o)p.info("manager",`Skipped ${s}: not an agent config (no "agents" key)`);if(r.length===0&&a.length===0&&o.length===0){p.warn("manager",`No config files found in ${t}; daemon idle (waiting for config). Add agents under this directory then run: grix-connector reload`);return}const i=[];let m=a.length;for(const{entry:s,file:l}of r)try{const u=this.toRuntimeInstanceConfig(s);i.push({config:u,entry:s,file:l}),p.info("manager",`Loaded ${u.name} (${u.adapterType??"acp"}) from ${l}`)}catch(u){const w=typeof s?.name=="string"?s.name:"<unknown>";p.error("manager",`Invalid agent config in ${l} (name=${w}): ${u}`),m++}let c=0;if(i.length>0){const s=Oe();p.info("manager",`Starting ${i.length} agent(s), startup wait=${s}ms`);const l=d=>{this.instances=this.instances.filter(h=>h!==d)},u=i.map(({config:d,entry:h,file:y})=>{const g=this.createConfiguredInstance(d);return this.instances.push(g),this.configMap.set(d.name,d),this.rawConfigMap.set(d.name,{entry:h,file:y}),{config:d,instance:g,startPromise:this.prepareProviderRuntime(d,h).then(()=>g.start())}}),w=await Promise.all(u.map(async d=>{const h=await new Promise(y=>{let g=!1;const S=setTimeout(()=>{g||(g=!0,y({kind:"timeout"}))},s);d.startPromise.then(()=>{g||(g=!0,clearTimeout(S),y({kind:"started"}))}).catch(v=>{g||(g=!0,clearTimeout(S),y({kind:"failed",error:v}))})});return{task:d,outcome:h}}));for(const{task:d,outcome:h}of w){if(h.kind==="started"){this.restoreCachedSharedInstances(d.config);continue}if(h.kind==="failed"){if(O(h.error)){this.onAgentDeletedByPlatform(d.config.name);continue}l(d.instance),p.error("manager",`Failed to start ${d.config.name}: ${h.error}`);continue}c++,p.warn("manager",`Startup pending for ${d.config.name}, continue retrying in background`),d.startPromise.then(()=>{p.info("manager",`Delayed start succeeded: ${d.config.name}`),this.restoreCachedSharedInstances(d.config)}).catch(y=>{if(O(y)){this.onAgentDeletedByPlatform(d.config.name);return}l(d.instance),p.error("manager",`Delayed start failed: ${d.config.name}: ${y}`)})}if(this.instances.length>0){const d=Math.max(0,this.instances.length-c);p.info("manager",`${d}/${i.length} agent(s) running now`)}c>0&&p.warn("manager",`${c} agent(s) still connecting in background`)}if(this.instances.length===0&&i.length>0)throw new Error("All agent configurations failed to start");await this.ensureAuxServices()}async ensureAuxServices(){if(this.configMap.size===0)return;const e=[...this.configMap.values()].map(t=>({apiKey:t.aibot.apiKey,wsUrl:t.aibot.url}));this.upgradeChecker||(this.upgradeChecker=new ce(e,()=>this.instances.some(t=>t.hasPendingOrBackgroundWork())||[...this.sharedInstances.values()].some(t=>t.hasPendingOrBackgroundWork())),await this.upgradeChecker.start()),this.skillSyncer||(this.skillSyncer=new le(e,_.skills),this.skillSyncer.setOnSyncSuccess(()=>this.refreshAllInstanceSkills()),await this.skillSyncer.start())}refreshAllInstanceSkills(){for(const e of this.instances)try{e.forceRefreshSkills()}catch(t){p.warn("manager",`forceRefreshSkills failed for ${e.name}: ${t}`)}for(const e of this.sharedInstances.values())try{e.forceRefreshSkills()}catch(t){p.warn("manager",`forceRefreshSkills failed for shared instance: ${t}`)}}async stop(){p.info("manager","Stopping all agents..."),this.stopping=!0,this.upgradeChecker?.stop(),this.skillSyncer?.stop(),await Promise.allSettled([...this.shareSyncChains.values()]),this.shareSyncChains.clear();const e=[...this.sharedInstances.values()];this.sharedInstances.clear(),await Promise.allSettled([...this.instances.map(t=>t.stop()),...e.map(t=>t.stop())]),await this.globalConfigStore?.flush(),await this.auditProducer.stop({timeoutMs:5e3}).catch(()=>!1),this.instances=[],N(),p.info("manager","All stopped")}onShareSet(e,t){this.sharedOwnersCache.save(e.name,t);const a=(this.shareSyncChains.get(e.name)??Promise.resolve()).catch(()=>{}).then(()=>this.syncSharedInstances(e,t));this.shareSyncChains.set(e.name,a)}async syncSharedInstances(e,t){if(this.stopping)return;const{toAdd:r,toRemove:a}=ae(e.name,this.sharedInstances.keys(),t);for(const o of r){if(this.stopping)break;const i=ie(e.name,o);try{const m=re(e,o),c=new D(m,this.globalConfigStore,this.auditProducer);this.sharedInstances.set(i,c),await c.start(),c.forceRefreshSkills(),p.info("manager",`shared instance started: ${i}`)}catch(m){this.sharedInstances.delete(i);const c=m instanceof Error?m.message:String(m);/Auth failed/i.test(c)?(this.sharedOwnersCache.remove(e.name,o),p.warn("manager",`shared instance auth rejected, removed from cache: ${i}`)):p.error("manager",`start shared instance failed ${i}: ${m}`)}}for(const{key:o}of a){const i=this.sharedInstances.get(o);i&&(this.sharedInstances.delete(o),i.stop().catch(m=>p.error("manager",`stop shared instance failed ${o}: ${m}`)),p.info("manager",`shared instance stopped: ${o}`))}}restoreCachedSharedInstances(e){const t=this.sharedOwnersCache.load(e.name);t.length!==0&&(p.info("manager",`restoring ${t.length} cached shared instance(s) for ${e.name}`),this.onShareSet(e,t))}getAgentsStatus(){return this.instances.map(e=>e.getStatus())}async addAgent(e){await this.addAgentInternal(e,"agents.json"),this.persistAgentsConfig(),await this.ensureAuxServices(),p.info("manager",`Added agent: ${e.name}`)}async addAgentInternal(e,t){const r=this.toRuntimeInstanceConfig(e);if(this.instances.some(a=>a.name===r.name))throw new Error(`Agent "${r.name}" already exists`);await this.startInstanceFromConfig(r,e,t)}createConfiguredInstance(e){const t=new D(e,this.globalConfigStore,this.auditProducer);return t.setUpgradeTrigger(()=>this.upgradeChecker?.triggerCheck()),t.setShareSetHandler(r=>this.onShareSet(e,r)),t.setAgentDeletedHandler(()=>this.onAgentDeletedByPlatform(e.name)),t.setSkillSyncHandler(()=>this.skillSyncer?.triggerSync()),t.setProviderConfigHandler(r=>this.setAgentProvider(e.name,r)),t.setRelayStateApplyPorts({getLocalState:()=>this.relayStateApplier?.getLocalState(e.name)??{enabled:!1},applyEnable:(r,a)=>{const o=this.relayStateApplier;return o?o.applyEnable(e.name,r,a):Promise.reject(new Error("relay state applier is not configured"))},applyDisable:()=>{const r=this.relayStateApplier;return r?r.applyDisable(e.name):Promise.reject(new Error("relay state applier is not configured"))}}),t.setRelayEnvSettledHandler(()=>this.relayEnvSettledHandler?.()),t.setProviderResolver(()=>this.getAgentProvider(e.name)),t}async prepareProviderRuntime(e,t){const r=this.resolveAgentProvider(t.provider);q(t.client_type)&&r?.base_url?.trim()&&r?.api_key?.trim()&&r?.model?.trim()&&await H(e.name,{baseUrl:r.base_url.trim(),apiKey:r.api_key.trim(),model:r.model.trim()})}async startInstanceFromConfig(e,t,r){await this.prepareProviderRuntime(e,t);const a=this.createConfiguredInstance(e);await a.start(),this.instances.push(a),this.configMap.set(e.name,e),this.rawConfigMap.set(e.name,{entry:t,file:r}),this.relayEnvSettledHandler?.()}async removeAgent(e){if(!this.instances.some(t=>t.name===e))throw Object.assign(new Error(`Agent "${e}" not found`),{code:"NOT_FOUND"});await this.removeAgentInternal(e),this.persistAgentsConfig(),p.info("manager",`Removed agent: ${e}`),this.relayEnvSettledHandler?.()}async removeAgentInternal(e,t){const r=this.instances.findIndex(m=>m.name===e),a=r===-1?void 0:this.instances[r];r!==-1&&this.instances.splice(r,1),this.configMap.delete(e),this.rawConfigMap.delete(e);const o=this.shareSyncChains.get(e);this.shareSyncChains.delete(e),o&&await o.catch(()=>{});const i=`${e}#shared:`;for(const[m,c]of[...this.sharedInstances.entries()])m.startsWith(i)&&(this.sharedInstances.delete(m),c.stop().catch(s=>p.error("manager",`stop shared instance failed ${m}: ${s}`)));t?.keepShareCache||this.sharedOwnersCache.delete(e),a&&await a.stop(),t?.keepShareCache||await L(e).catch(()=>{})}onAgentDeletedByPlatform(e){this.stopping||this.deletedAgentCleanups.has(e)||(this.deletedAgentCleanups.add(e),(async()=>{try{if(!(this.rawConfigMap.has(e)||this.instances.some(r=>r.name===e)))return;p.warn("manager",`Agent "${e}" \u5DF2\u5728\u5E73\u53F0\u5220\u9664\uFF0C\u505C\u6B62\u5B9E\u4F8B\u5E76\u6E05\u7406\u672C\u5730\u914D\u7F6E`),await this.removeAgentInternal(e),this.persistAgentsConfig(),p.info("manager",`Agent "${e}" \u5DF2\u5728\u5E73\u53F0\u5220\u9664\uFF0C\u672C\u5730\u914D\u7F6E\u5DF2\u6E05\u7406\uFF08agents.json \u5DF2\u79FB\u9664\u8BE5\u6761\u76EE\uFF09`)}catch(t){p.error("manager",`cleanup for deleted agent "${e}" failed: ${t}`)}finally{this.deletedAgentCleanups.delete(e)}})())}persistAgentsConfig(){const e=A(this.configDir,"agents.json");try{const t=[];for(const[,a]of this.configMap){const o=this.rawConfigMap.get(a.name)?.entry.provider;t.push({name:a.name,ws_url:a.aibot.url,agent_id:a.aibot.agentId,api_key:a.aibot.apiKey,client_type:a.aibot.clientType,...o?{provider:o}:{}})}te(e,JSON.stringify({agents:t},null,4)+`
|
|
2
|
-
`,"utf-8")}catch(t){
|
|
1
|
+
import{readFileSync as Z,readdirSync as ee,writeFileSync as te}from"node:fs";import{join as A}from"node:path";import{homedir as ne}from"node:os";import{AgentInstance as D}from"./bridge/bridge.js";import{buildSharedInstanceConfig as re,diffSharedOwners as ae,sharedInstanceKey as ie,SharedOwnersCache as se}from"./manager-share-config.js";import{isAgentDeletedError as O}from"./core/aibot/errors.js";import{GRIX_PATHS as _,log as d}from"./core/log/index.js";import{resolveClientVersion as oe}from"./core/util/client-version.js";import{UpgradeChecker as ce}from"./core/upgrade/upgrade-checker.js";import{SkillSyncer as le}from"./core/skill-sync/skill-syncer.js";import{AgentGlobalConfigStore as de}from"./core/persistence/agent-global-config-store.js";import{resolveSkillScanMode as pe}from"./adapter/claude/skill-scanner.js";import{buildWireSkills as me}from"./core/skill-sync/sync-state.js";import{buildLibrarySkills as ue}from"./core/skill-sync/library-skills.js";import{AUDIT_LOCAL_ACTION_TYPES as ge}from"./core/aibot/types.js";import{buildReportedSkills as fe,logDefaultSkillsCheck as he,cleanupProjectedSkills as L}from"./default-skills/index.js";import{supportsKiroCwRelay as N,supportsNonMitmRelayConfig as _e}from"./core/config/provider-env.js";import{ensureKiroRelay as H,stopKiroRelay as q}from"./core/proxy/kiro-relay.js";import{resolveCopilotCommand as U}from"./core/runtime/copilot-resolve.js";import{resolveCursorCommand as B}from"./core/runtime/cursor-resolve.js";import{getCliVersion as ye,resolveCliPath as we}from"./core/util/cli-probe.js";import{AgentInstaller as Se}from"./core/installer/installer.js";import{reportInstallFailure as ve}from"./core/observability/sentry.js";import{createDefaultAuditProducer as Ae}from"./audit/runtime/default-audit-recorder.js";import{normalizeCodexConfigOverrides as ke}from"./adapter/codex/config-overrides.js";import{resolveCodexDirectHome as be}from"./adapter/codex/direct-home.js";const Ce=8e3;function $e(){const r=U();return[{clientType:"openclaw",command:"openclaw"},{clientType:"claude",command:"claude"},{clientType:"codex",command:"codex"},{clientType:"qwen",command:"qwen"},{clientType:"hermes",command:"hermes"},{clientType:"reasonix",command:"reasonix"},{clientType:"codewhale",command:"codewhale"},{clientType:"opencode",command:"opencode"},{clientType:"cursor",command:B()},{clientType:"pi",command:"pi"},{clientType:"openhuman",command:"openhuman-core"},{clientType:"kiro",command:"kiro-cli"},{clientType:"kimi",command:"kimi"},{clientType:"copilot",command:r.command},{clientType:"agy",command:"agy"}]}async function xe(){return Promise.all($e().map(async r=>{const e=await we(r.command);if(!e)return{client_type:r.clientType,command:r.command,installed:!1,path:null,version:null};const t=await ye(e,r.versionArgs??["--version"]);return{client_type:r.clientType,command:r.command,installed:!0,path:e,version:t.version,error:t.error}}))}function Ie(r){switch(r){case"claude":return{adapterType:"claude",command:"claude"};case"codex":return{adapterType:"codex",command:"codex",options:{sandboxMode:"danger-full-access"}};case"gemini":return{adapterType:"acp",command:"gemini",autoInjectArgs:{acp:!0},enableSessionBinding:!0};case"qwen":return{adapterType:"acp",command:"qwen",adapterHint:"qwen/base",autoInjectArgs:{acp:!0},enableSessionBinding:!0};case"pi":return{adapterType:"pi",command:"pi"};case"cursor":return{adapterType:"cursor",command:B()};case"reasonix":return{adapterType:"acp",command:"reasonix",args:["acp"],enableSessionBinding:!0};case"codewhale":return{adapterType:"codewhale",command:"codewhale",enableSessionBinding:!0};case"openhuman":return{adapterType:"openhuman",command:"openhuman-core",enableSessionBinding:!0};case"kiro":return{adapterType:"acp",command:"kiro-cli",args:["acp"],enableSessionBinding:!0};case"kimi":return{adapterType:"acp",command:"kimi",args:["acp"],options:{initial_mode:"yolo"},enableSessionBinding:!0};case"opencode":return{adapterType:"opencode",command:"opencode",args:["serve"],enableSessionBinding:!0};case"copilot":{const e=U();return{adapterType:"acp",command:e.command,args:[...e.prefixArgs,"--acp"],enableSessionBinding:!0}}case"agy":return{adapterType:"agy",command:"agy",enableSessionBinding:!0};case"hermes":return{adapterType:"acp",command:"hermes",args:["acp"],enableSessionBinding:!0};default:throw new Error(`Unsupported client_type: ${r}`)}}function k(r,e){return String(r??"").trim().toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||String(e??"").trim().toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"default"}function Te(r){return A(_.data,`session-bindings-${k(r,"unknown")}.json`)}function Ee(r,e){return A(_.data,`session-bindings-${k(r,e)}.json`)}function Pe(r,e){return A(_.data,`active-events-${k(r,e)}.json`)}function Re(r,e){const t=k(r,"agent"),n=k(e,"unknown");return A(_.data,`terminal-outbox-${t}-${n}.json`)}function je(...r){const e=[],t=new Set;for(const n of r)for(const a of n??[]){const s=String(a??"").trim(),i=s.toLowerCase();!s||t.has(i)||(t.add(i),e.push(s))}return e.length>0?e:void 0}function Me(r,e){const t={claude:{maxConcurrent:1,maxQueued:5,queueTimeoutMs:0},codex:{maxConcurrent:1,maxQueued:5,queueTimeoutMs:0},cursor:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0},acp:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0},pi:{maxConcurrent:1,maxQueued:5,queueTimeoutMs:0},codewhale:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0},openhuman:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0},opencode:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0},agy:{maxConcurrent:1,maxQueued:3,queueTimeoutMs:0}},n=t[r]??t.acp;return{maxConcurrent:e?.max_concurrent??n.maxConcurrent??1,maxQueued:e?.max_queued??n.maxQueued??3,queueTimeoutMs:e?.queue_timeout_ms??n.queueTimeoutMs??0,cancelableQueued:!0,cancelableRunning:!0}}function De(r,e={}){const t=oe(),n=String(r.client_type??"").trim().toLowerCase(),a=Ie(n),s=String(r.ws_url??"").trim(),i="get_session_usage",l="get_rate_limits",c="get_agent_global_config",o=ge;if(!r.name?.trim())throw new Error("agent name is required");if(!s)throw new Error(`agent ${r.name}: ws_url is required`);if(!r.agent_id?.trim())throw new Error(`agent ${r.name}: agent_id is required`);if(!r.api_key?.trim())throw new Error(`agent ${r.name}: api_key is required`);const p=a.adapterType,u=p==="acp",w=n==="qwen",m={...a.options??{}};if(r.codex_config_overrides!==void 0){if(p!=="codex")throw new Error(`agent ${r.name}: codex_config_overrides is only supported for client_type=codex`);ke(r.codex_config_overrides,`agent ${r.name}: codex_config_overrides`),m.codexConfigOverrides=r.codex_config_overrides}if(p==="codex"&&r.provider?.wire_api!==void 0){const f=r.provider;if(f.wire_api!=="responses"||!f.base_url?.trim()||!f.api_key?.trim()||!f.model?.trim()||!f.catalog_version?.trim()||!f.catalog_sha256?.trim()||!f.catalog_json?.trim())throw Object.assign(new Error(`agent ${r.name}: incomplete Codex direct relay config`),{code:"INVALID_CODEX_DIRECT_CONFIG"});const M=be(_.data,r.name);m.codexHome=M,m.codexDirect={codexHome:M,config:{baseUrl:f.base_url.trim(),model:f.model.trim(),...f.reasoning_effort?.trim()?{reasoningEffort:f.reasoning_effort.trim()}:{},token:f.api_key.trim()},catalog:{version:f.catalog_version.trim(),sha256:f.catalog_sha256.trim(),json:f.catalog_json}}}const h=p==="codex"?{capabilities:["local_action_v1","agent_invoke"],localActions:["session_control","get_context","set_model","set_mode","set_reasoning_effort","set_service_tier","set_sandbox_mode","exec_approve","exec_reject","file_list","create_folder","turn_interrupt","permission_approve","permission_reject","thread_compact",i,l]}:null,y=p==="claude"?{localActions:["session_control","set_mode","set_model","set_reasoning_effort","claude_interaction_reply","exec_approve","exec_reject","file_list","create_folder","thread_compact",i,l]}:null,g=w?{capabilities:["stream_chunk","local_action_v1"],localActions:["exec_approve","exec_reject","permission_approve","permission_reject","session_control","set_model","set_mode","file_list","create_folder",i],adapterHint:"qwen/base"}:null,v=p==="pi"?{adapterHint:"pi/base",capabilities:["stream_chunk","local_action_v1"],localActions:["session_control","set_model","get_context","file_list","create_folder",i,l]}:null,S=p==="openhuman"?{adapterHint:"openhuman/base",capabilities:["local_action_v1"],localActions:["session_control","set_model","file_list","create_folder"]}:null,C=p==="cursor"?{adapterHint:"cursor/base",capabilities:["stream_chunk","local_action_v1"],localActions:["session_control","set_model","set_mode","get_context","file_list","create_folder","thread_compact","claude_interaction_reply",l]}:null,T=p==="codewhale"?{capabilities:["stream_chunk","local_action_v1"],localActions:["session_control","set_model","file_list","create_folder",i]}:null,$=p==="opencode"?{adapterHint:"opencode/base",capabilities:["stream_chunk","local_action_v1"],localActions:["exec_approve","exec_reject","permission_approve","permission_reject","session_control","set_model","set_mode","claude_interaction_reply","file_list","create_folder"]}:null,x=p==="agy"?{adapterHint:"agy/base",capabilities:["stream_chunk","local_action_v1"],localActions:["session_control","set_model","file_list","create_folder"]}:null,E=new Set(["hermes","reasonix","kimi","copilot"]),K=u&&!E.has(n),Q=u&&!w?{localActions:["exec_approve","exec_reject","permission_approve","permission_reject","session_control","set_model","set_mode","file_list","create_folder",...K?[i]:[]]}:null,W=n==="kiro"?{localActions:["exec_approve","exec_reject","permission_approve","permission_reject","session_control","set_model","set_mode","file_list","create_folder","thread_compact",i,l]}:null,G=p==="codex"||p==="claude"||p==="opencode"||n==="gemini"?["session_control","set_model","set_mode",...p==="claude"?["set_reasoning_effort"]:[]]:void 0,z=p==="cursor"||p==="opencode"||p==="openhuman"||p==="agy"||u&&E.has(n)?[l]:[i,l];u&&m.raw_transport===void 0&&(m.raw_transport=n==="gemini");const V=`${n}/base`,I=pe(p,n),J=I==="kiro"?void 0:process.cwd(),P=fe({mode:I,projectDir:J}),R=P.filter(f=>f.source==="connector").map(f=>f.name);R.length>0&&!e.quiet&&d.info("manager",`[${r.name}] injecting connector skills: [${R.join(", ")}]`);const j=me(P,_.skills);let X=j.length>0?j:void 0;const Y=ue({skillsDir:_.skills,mode:I,home:ne()});return{name:r.name,adapterType:p,aibot:{url:s,agentId:r.agent_id,apiKey:r.api_key,clientType:n,clientVersion:t,adapterHint:a.adapterHint??g?.adapterHint??v?.adapterHint??S?.adapterHint??C?.adapterHint??$?.adapterHint??x?.adapterHint??V,capabilities:h?.capabilities??T?.capabilities??v?.capabilities??S?.capabilities??C?.capabilities??$?.capabilities??x?.capabilities??g?.capabilities??["stream_chunk","local_action_v1","connector_upgrade"],localActions:je(h?.localActions??T?.localActions??y?.localActions??v?.localActions??S?.localActions??C?.localActions??$?.localActions??x?.localActions??g?.localActions??W?.localActions??Q?.localActions??["exec_approve","exec_reject"],G,z,["connector_rollback","connector_upgrade_push",c,"configure_gateway_provider","skill_upload","skill_enable","skill_disable","skill_refresh",...o]),skills:X,librarySkills:Y,terminalOutboxPath:Re(r.name,r.agent_id)},agent:{command:a.command,args:[...a.args??[],...r.args??[]],env:r.env,clientType:n,...r.provider?{provider:{...r.provider.provider_id?.trim()?{providerId:r.provider.provider_id.trim()}:{},...r.provider.base_url?.trim()?{baseUrl:r.provider.base_url.trim()}:{},...r.provider.quota_base_url?.trim()?{quotaBaseUrl:r.provider.quota_base_url.trim()}:{},...r.provider.api_key?.trim()?{apiKey:r.provider.api_key.trim()}:{},...r.provider.model?.trim()?{model:r.provider.model.trim()}:{},...r.provider.fast_model?.trim()?{fastModel:r.provider.fast_model.trim()}:{},...r.provider.effort?.trim()?{effort:r.provider.effort.trim()}:{}}}:{}},adapterOptions:m,acpAuthMethod:m.auth_method,acpInitialMode:m.initial_mode,acpMcpTools:m.acp_mcp_tools,promptTimeoutMs:r.prompt_timeout_ms,bindingsPath:Te(r.agent_id),legacyBindingsPath:Ee(r.name,r.agent_id),activeEventStorePath:Pe(r.name,r.agent_id),...a.enableSessionBinding||u?{enableSessionBinding:!0}:{},...a.autoInjectArgs||n==="reasonix"&&r.provider?.model?.trim()?{autoInjectArgs:{...a.autoInjectArgs??{},...n==="reasonix"&&r.provider?.model?.trim()?{model:r.provider.model.trim()}:{}}}:{},poolMaxSize:r.pool?.maxSize,poolIdleTimeoutMs:r.pool?.idleTimeoutMs,eventQueue:Me(p,r.event_queue),logDir:_.log,providerBaseUrl:r.provider_base_url?.trim()||void 0,providerApiKey:r.provider_api_key?.trim()||void 0}}function Oe(){const r=process.env.GRIX_AGENT_STARTUP_WAIT_MS,e=Number(r);return Number.isFinite(e)&&e>=500?Math.floor(e):Ce}function F(r){const e=[],t=[],n=[],a=ee(r).filter(s=>s.endsWith(".json")).sort();for(const s of a)try{const i=JSON.parse(Z(A(r,s),"utf-8"));if(i===null||typeof i!="object"||Array.isArray(i)||!("agents"in i)){n.push(s);continue}if(!Array.isArray(i.agents)){t.push({file:s,error:"agents is not an array"});continue}if(i.agents.length===0){t.push({file:s,error:"agents array is empty"});continue}for(const l of i.agents)e.push({entry:l,file:s})}catch(i){t.push({file:s,error:i instanceof Error?i.message:String(i)})}return{entries:e,fileErrors:t,skipped:n}}function b(r){if(r===null||typeof r!="object")return JSON.stringify(r)??"null";if(Array.isArray(r))return`[${r.map(b).join(",")}]`;const e=r;return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${b(e[n])}`).join(",")}}`}function Le(r,e){return b(r)===b(e)}class mt{instances=[];configMap=new Map;rawConfigMap=new Map;reloadChain=Promise.resolve();sharedInstances=new Map;shareSyncChains=new Map;stopping=!1;deletedAgentCleanups=new Set;upgradeChecker=null;skillSyncer=null;globalConfigStore;configDir=_.config;sharedOwnersCache=new se(_.data);installer=new Se;relaySecretResolver;auditProducer=Ae();async start(e){const t=e??_.config;this.configDir=t,d.info("manager",`Loading configs from ${t}`),he(),L(),this.globalConfigStore=new de(A(_.data,"agent-global-configs.json")),this.globalConfigStore.load();const{entries:n,fileErrors:a,skipped:s}=F(t);for(const o of a)d.error("manager",`Failed to load ${o.file}: ${o.error}`);for(const o of s)d.info("manager",`Skipped ${o}: not an agent config (no "agents" key)`);if(n.length===0&&a.length===0&&s.length===0){d.warn("manager",`No config files found in ${t}; daemon idle (waiting for config). Add agents under this directory then run: grix-connector reload`);return}const i=[];let l=a.length;for(const{entry:o,file:p}of n)try{const u=this.toRuntimeInstanceConfig(o);i.push({config:u,entry:o,file:p}),d.info("manager",`Loaded ${u.name} (${u.adapterType??"acp"}) from ${p}`)}catch(u){const w=typeof o?.name=="string"?o.name:"<unknown>";d.error("manager",`Invalid agent config in ${p} (name=${w}): ${u}`),l++}let c=0;if(i.length>0){const o=Oe();d.info("manager",`Starting ${i.length} agent(s), startup wait=${o}ms`);const p=m=>{this.instances=this.instances.filter(h=>h!==m)},u=i.map(({config:m,entry:h,file:y})=>{const g=this.createConfiguredInstance(m);return this.instances.push(g),this.configMap.set(m.name,m),this.rawConfigMap.set(m.name,{entry:h,file:y}),{config:m,instance:g,startPromise:this.prepareProviderRuntime(m,h).then(()=>g.start())}}),w=await Promise.all(u.map(async m=>{const h=await new Promise(y=>{let g=!1;const v=setTimeout(()=>{g||(g=!0,y({kind:"timeout"}))},o);m.startPromise.then(()=>{g||(g=!0,clearTimeout(v),y({kind:"started"}))}).catch(S=>{g||(g=!0,clearTimeout(v),y({kind:"failed",error:S}))})});return{task:m,outcome:h}}));for(const{task:m,outcome:h}of w){if(h.kind==="started"){this.restoreCachedSharedInstances(m.config);continue}if(h.kind==="failed"){if(O(h.error)){this.onAgentDeletedByPlatform(m.config.name);continue}p(m.instance),d.error("manager",`Failed to start ${m.config.name}: ${h.error}`);continue}c++,d.warn("manager",`Startup pending for ${m.config.name}, continue retrying in background`),m.startPromise.then(()=>{d.info("manager",`Delayed start succeeded: ${m.config.name}`),this.restoreCachedSharedInstances(m.config)}).catch(y=>{if(O(y)){this.onAgentDeletedByPlatform(m.config.name);return}p(m.instance),d.error("manager",`Delayed start failed: ${m.config.name}: ${y}`)})}if(this.instances.length>0){const m=Math.max(0,this.instances.length-c);d.info("manager",`${m}/${i.length} agent(s) running now`)}c>0&&d.warn("manager",`${c} agent(s) still connecting in background`)}if(this.instances.length===0&&i.length>0)throw new Error("All agent configurations failed to start");await this.ensureAuxServices()}async ensureAuxServices(){if(this.configMap.size===0)return;const e=[...this.configMap.values()].map(t=>({apiKey:t.aibot.apiKey,wsUrl:t.aibot.url}));this.upgradeChecker||(this.upgradeChecker=new ce(e,()=>this.instances.some(t=>t.hasPendingOrBackgroundWork())||[...this.sharedInstances.values()].some(t=>t.hasPendingOrBackgroundWork())),await this.upgradeChecker.start()),this.skillSyncer||(this.skillSyncer=new le(e,_.skills),this.skillSyncer.setOnSyncSuccess(()=>this.refreshOwnerLibrarySkills()),await this.skillSyncer.start())}refreshOwnerLibrarySkills(){const e=new Map,t=n=>{let a;try{a=n.skillsSyncGroupKey()}catch(i){d.warn("manager",`skillsSyncGroupKey failed for ${n.name}: ${i}`);return}const s=e.get(a)??[];s.push(n),e.set(a,s)};for(const n of this.instances)t(n);for(const n of this.sharedInstances.values())t(n);for(const[n,a]of e){let s=!1;const i=[];for(const l of a){if(s){i.push(l);continue}let c=!1;try{c=l.forceRefreshSkills(void 0,{force:!0,ownerLibrarySync:!0})===!0}catch(o){d.warn("manager",`owner library skills reporter threw group=${n} agent=${l.name}: ${o}`)}if(c){s=!0;continue}d.warn("manager",`owner library skills reporter failed group=${n} agent=${l.name}; trying next`)}if(!s){d.warn("manager",`owner library skills: no reporter succeeded group=${n}`);continue}for(const l of i)try{l.adoptSkillsWireHashFromDisk()}catch(c){d.warn("manager",`adoptSkillsWireHashFromDisk failed for ${l.name}: ${c}`)}}}async stop(){d.info("manager","Stopping all agents..."),this.stopping=!0,this.upgradeChecker?.stop(),this.skillSyncer?.stop(),await Promise.allSettled([...this.shareSyncChains.values()]),this.shareSyncChains.clear();const e=[...this.sharedInstances.values()];this.sharedInstances.clear(),await Promise.allSettled([...this.instances.map(t=>t.stop()),...e.map(t=>t.stop())]),await this.globalConfigStore?.flush(),await this.auditProducer.stop({timeoutMs:5e3}).catch(()=>!1),this.instances=[],L(),d.info("manager","All stopped")}onShareSet(e,t){this.sharedOwnersCache.save(e.name,t);const a=(this.shareSyncChains.get(e.name)??Promise.resolve()).catch(()=>{}).then(()=>this.syncSharedInstances(e,t));this.shareSyncChains.set(e.name,a)}async syncSharedInstances(e,t){if(this.stopping)return;const{toAdd:n,toRemove:a}=ae(e.name,this.sharedInstances.keys(),t);for(const s of n){if(this.stopping)break;const i=ie(e.name,s);try{const l=re(e,s),c=new D(l,this.globalConfigStore,this.auditProducer);this.sharedInstances.set(i,c),await c.start(),c.forceRefreshSkills(void 0,{force:!0}),d.info("manager",`shared instance started: ${i}`)}catch(l){this.sharedInstances.delete(i);const c=l instanceof Error?l.message:String(l);/Auth failed/i.test(c)?(this.sharedOwnersCache.remove(e.name,s),d.warn("manager",`shared instance auth rejected, removed from cache: ${i}`)):d.error("manager",`start shared instance failed ${i}: ${l}`)}}for(const{key:s}of a){const i=this.sharedInstances.get(s);i&&(this.sharedInstances.delete(s),i.stop().catch(l=>d.error("manager",`stop shared instance failed ${s}: ${l}`)),d.info("manager",`shared instance stopped: ${s}`))}}restoreCachedSharedInstances(e){const t=this.sharedOwnersCache.load(e.name);t.length!==0&&(d.info("manager",`restoring ${t.length} cached shared instance(s) for ${e.name}`),this.onShareSet(e,t))}getAgentsStatus(){return this.instances.map(e=>e.getStatus())}async addAgent(e){await this.addAgentInternal(e,"agents.json"),this.persistAgentsConfig(),await this.ensureAuxServices(),d.info("manager",`Added agent: ${e.name}`)}async addAgentInternal(e,t){const n=this.toRuntimeInstanceConfig(e);if(this.instances.some(a=>a.name===n.name))throw new Error(`Agent "${n.name}" already exists`);await this.startInstanceFromConfig(n,e,t)}createConfiguredInstance(e){const t=new D(e,this.globalConfigStore,this.auditProducer);return t.setUpgradeTrigger(()=>this.upgradeChecker?.triggerCheck()),t.setShareSetHandler(n=>this.onShareSet(e,n)),t.setAgentDeletedHandler(()=>this.onAgentDeletedByPlatform(e.name)),t.setSkillSyncHandler(()=>this.skillSyncer?.triggerSync()),t.setProviderConfigHandler(n=>this.setAgentProvider(e.name,n)),t.setRelayStateApplyPorts({getLocalState:()=>this.relayStateApplier?.getLocalState(e.name)??{enabled:!1},applyEnable:(n,a)=>{const s=this.relayStateApplier;return s?s.applyEnable(e.name,n,a):Promise.reject(new Error("relay state applier is not configured"))},applyDisable:()=>{const n=this.relayStateApplier;return n?n.applyDisable(e.name):Promise.reject(new Error("relay state applier is not configured"))}}),t.setRelayEnvSettledHandler(()=>this.relayEnvSettledHandler?.()),t.setProviderResolver(()=>this.getAgentProvider(e.name)),t}async prepareProviderRuntime(e,t){const n=this.resolveAgentProvider(t.provider);N(t.client_type)&&n?.base_url?.trim()&&n?.api_key?.trim()&&n?.model?.trim()&&await H(e.name,{baseUrl:n.base_url.trim(),apiKey:n.api_key.trim(),model:n.model.trim()})}async startInstanceFromConfig(e,t,n){await this.prepareProviderRuntime(e,t);const a=this.createConfiguredInstance(e);await a.start(),this.instances.push(a),this.configMap.set(e.name,e),this.rawConfigMap.set(e.name,{entry:t,file:n}),this.relayEnvSettledHandler?.()}async removeAgent(e){if(!this.instances.some(t=>t.name===e))throw Object.assign(new Error(`Agent "${e}" not found`),{code:"NOT_FOUND"});await this.removeAgentInternal(e),this.persistAgentsConfig(),d.info("manager",`Removed agent: ${e}`),this.relayEnvSettledHandler?.()}async removeAgentInternal(e,t){const n=this.instances.findIndex(l=>l.name===e),a=n===-1?void 0:this.instances[n];n!==-1&&this.instances.splice(n,1),this.configMap.delete(e),this.rawConfigMap.delete(e);const s=this.shareSyncChains.get(e);this.shareSyncChains.delete(e),s&&await s.catch(()=>{});const i=`${e}#shared:`;for(const[l,c]of[...this.sharedInstances.entries()])l.startsWith(i)&&(this.sharedInstances.delete(l),c.stop().catch(o=>d.error("manager",`stop shared instance failed ${l}: ${o}`)));t?.keepShareCache||this.sharedOwnersCache.delete(e),a&&await a.stop(),t?.keepShareCache||await q(e).catch(()=>{})}onAgentDeletedByPlatform(e){this.stopping||this.deletedAgentCleanups.has(e)||(this.deletedAgentCleanups.add(e),(async()=>{try{if(!(this.rawConfigMap.has(e)||this.instances.some(n=>n.name===e)))return;d.warn("manager",`Agent "${e}" \u5DF2\u5728\u5E73\u53F0\u5220\u9664\uFF0C\u505C\u6B62\u5B9E\u4F8B\u5E76\u6E05\u7406\u672C\u5730\u914D\u7F6E`),await this.removeAgentInternal(e),this.persistAgentsConfig(),d.info("manager",`Agent "${e}" \u5DF2\u5728\u5E73\u53F0\u5220\u9664\uFF0C\u672C\u5730\u914D\u7F6E\u5DF2\u6E05\u7406\uFF08agents.json \u5DF2\u79FB\u9664\u8BE5\u6761\u76EE\uFF09`)}catch(t){d.error("manager",`cleanup for deleted agent "${e}" failed: ${t}`)}finally{this.deletedAgentCleanups.delete(e)}})())}persistAgentsConfig(){const e=A(this.configDir,"agents.json");try{const t=[];for(const[,a]of this.configMap){const s=this.rawConfigMap.get(a.name)?.entry.provider;t.push({name:a.name,ws_url:a.aibot.url,agent_id:a.aibot.agentId,api_key:a.aibot.apiKey,client_type:a.aibot.clientType,...s?{provider:s}:{}})}te(e,JSON.stringify({agents:t},null,4)+`
|
|
2
|
+
`,"utf-8")}catch(t){d.error("manager",`Failed to persist agents config: ${t}`)}}isAgentBusy(e){return this.instances.find(n=>n.name===e)?.hasPendingWork()??!1}getAgentsWithStaleRelayEnv(){return this.instances.filter(e=>e.hasStaleRelayEnv()).map(e=>e.name)}markAgentRelayEnvStale(e){const t=this.instances.find(n=>n.name===e);return t?(t.markRelayEnvStale(),!0):!1}relayEnvSettledHandler;setRelayEnvSettledHandler(e){this.relayEnvSettledHandler=e}relayStateApplier;setRelayStateApplier(e){this.relayStateApplier=e}reportRelayStateLocalChange(e){this.instances.find(n=>n.name===e)?.reportRelayStateLocalChange()}setRelaySecretResolver(e){this.relaySecretResolver=e}resolveAgentProvider(e){if(!e?.api_key_ref?.trim())return e;const t=e.api_key_ref.trim(),n=this.relaySecretResolver?.(t);if(!n)throw Object.assign(new Error(`relay credential "${t}" is unavailable`),{code:"RELAY_SECRET_UNAVAILABLE"});return{...e,api_key:n}}toRuntimeInstanceConfig(e,t={}){const n=this.resolveAgentProvider(e.provider);return De(n===e.provider?e:{...e,provider:n},t)}getAgentProvider(e){return this.resolveAgentProvider(this.rawConfigMap.get(e)?.entry.provider)}async restartAgent(e){const t=this.rawConfigMap.get(e);if(!t)throw Object.assign(new Error(`Agent "${e}" not found`),{code:"NOT_FOUND"});await this.replaceInstance(e,t.entry,t.file),d.info("manager",`Restarted agent: ${e}`)}async setAgentProvider(e,t,n){const a=this.rawConfigMap.get(e);if(!a)throw Object.assign(new Error(`Agent "${e}" not found`),{code:"NOT_FOUND"});const s=String(a.entry.client_type??"").trim().toLowerCase();N(s)&&(t?.base_url?.trim()&&t?.api_key?.trim()&&t?.model?.trim()?await H(e,{baseUrl:t.base_url.trim(),apiKey:t.api_key.trim(),model:t.model.trim()}):await q(e));const i=t?.api_key_ref?.trim()?Object.fromEntries(Object.entries(t).filter(([c])=>c!=="api_key")):t,l={...a.entry,provider:i};if(n?.deferRestart){this.rawConfigMap.set(e,{...a,entry:l}),this.instances.find(c=>c.name===e)?.markRelayEnvStale(),this.persistAgentsConfig(),d.info("manager",`Updated provider config for agent (deferred restart): ${e}`);return}await this.replaceInstance(e,l,a.file),this.persistAgentsConfig(),d.info("manager",`Updated provider config for agent: ${e}`)}hasDirectRelayConfig(e){const t=this.rawConfigMap.get(e)?.entry.provider;return!!(t?.api_key_ref?.trim()||t?.api_key?.trim())}getDirectRelayConfigAgentNames(){return[...this.rawConfigMap.entries()].filter(([,e])=>!!e.entry.provider&&(_e(e.entry.client_type)||["claude","codex"].includes(String(e.entry.client_type??"").trim().toLowerCase()))).map(([e])=>e)}async fetchRelayCredential(e,t){const n=this.instances.find(a=>a.name===e);if(!n)throw Object.assign(new Error(`Agent "${e}" not found`),{code:"NOT_FOUND"});return n.fetchRelayCredential(t)}async clearDirectProviderConfigs(){const e=this.getDirectRelayConfigAgentNames(),t=[];for(const n of e)try{await this.setAgentProvider(n,void 0,{deferRestart:this.isAgentBusy(n)}),t.push(n)}catch(a){d.warn("manager",`Failed to clear provider config for "${n}": ${a instanceof Error?a.message:String(a)}`)}return t}async replaceInstance(e,t,n){const a=this.toRuntimeInstanceConfig(t);await this.removeAgentInternal(e,{keepShareCache:!0}),await this.startInstanceFromConfig(a,t,n),this.restoreCachedSharedInstances(a)}async reload(){const e=this.reloadChain.catch(()=>{}).then(()=>this.doReload());return this.reloadChain=e.catch(()=>{}),e}async doReload(){if(this.stopping)throw Object.assign(new Error("manager is stopping"),{code:"RELOAD_UNSAFE"});const{entries:e,fileErrors:t,skipped:n}=F(this.configDir);for(const c of n)d.info("manager",`reload: skipped ${c}: not an agent config (no "agents" key)`);if(t.length>0){const c=t.map(o=>`${o.file}: ${o.error}`).join("; ");throw Object.assign(new Error(`reload aborted: ${t.length} config file(s) failed to parse [${c}]`),{code:"RELOAD_UNSAFE"})}if(e.length===0)throw Object.assign(new Error("reload aborted: no valid agent config found"),{code:"RELOAD_UNSAFE"});const a=[];for(const{entry:c}of e)try{this.toRuntimeInstanceConfig(c,{quiet:!0})}catch(o){const p=c?.name,u=typeof p=="string"&&p.trim()?p:"<unknown>";a.push({name:u,error:o instanceof Error?o.message:String(o)})}if(a.length>0){const c=a.map(o=>`${o.name}: ${o.error}`).join("; ");throw Object.assign(new Error(`reload aborted: ${a.length} agent config(s) invalid [${c}]`),{code:"RELOAD_UNSAFE"})}const s=new Map;for(const c of e){const o=String(c.entry?.name??"").trim();o&&(s.has(o)&&d.warn("manager",`reload: duplicate agent name "${o}", last one wins`),s.set(o,c))}const i={added:[],removed:[],restarted:[],unchanged:[],failed:[]},l=new Set(this.rawConfigMap.keys());for(const c of l)if(!s.has(c))try{await this.removeAgentInternal(c),i.removed.push(c)}catch(o){i.failed.push({name:c,error:o instanceof Error?o.message:String(o)})}for(const[c,o]of s){const p=this.rawConfigMap.get(c);if(p)if(Le(p.entry,o.entry))this.rawConfigMap.set(c,o),i.unchanged.push(c);else try{await this.replaceInstance(c,o.entry,o.file),i.restarted.push(c)}catch(u){i.failed.push({name:c,error:u instanceof Error?u.message:String(u)})}else try{await this.addAgentInternal(o.entry,o.file),i.added.push(c)}catch(u){i.failed.push({name:c,error:u instanceof Error?u.message:String(u)})}}return d.info("manager",`reload done: +${i.added.length} -${i.removed.length} ~${i.restarted.length} =${i.unchanged.length} !${i.failed.length}`),await this.ensureAuxServices(),i}async checkUpgrade(){return this.upgradeChecker?this.upgradeChecker.checkForUpdate():{available:!1}}triggerUpgrade(){this.upgradeChecker?.triggerCheck()}async probeAll(e={}){return Ne(this.instances,e)}async probeOne(e,t={}){return He(this.instances,e,t)}listInstallable(){return this.installer.listInstallable()}async installAgent(e){const t=await this.installer.install(e);return ve(t),t}getInstallProgress(e){return this.installer.getProgress(e)??null}}async function Ne(r,e){const t=e.concurrency??4,n=Date.now(),a=new Array(r.length);await new Promise(o=>{let p=0,u=0;const w=r.length;if(w===0){o();return}function m(g){const v=r[g];v.probe(e).then(S=>{a[g]=S,h()},S=>{a[g]={agent_name:v.name,client_type:"unknown",adapter_type:"acp",ok:!1,status:"error",probed_at:Date.now(),duration_ms:0,cached:!1,cli:{command:"",installed:!1,path:null,version:null,error:{code:"internal",message:S?.message??String(S)}},conversation:{attempted:!1,ok:!1,latency_ms:null},config:{model:null,base_url:null,source:{model:"unknown",base_url:"unknown"}},process:{started:!1,alive:!1,busy:!1}},h()})}function h(){u++,p<w?m(p++):u===w&&o()}const y=Math.min(t,w);for(let g=0;g<y;g++)m(p++)});const s=a.filter(o=>o.status==="healthy").length,i=a.filter(o=>o.status==="degraded").length,l=a.filter(o=>o.status==="unavailable").length,c=await xe();return{ok:s===a.length&&a.length>0,total:a.length,healthy:s,degraded:i,unavailable:l,installed_clients:c,agents:a,probed_at:n,duration_ms:Date.now()-n}}async function He(r,e,t){const n=r.find(a=>a.name===e);if(!n)throw Object.assign(new Error(`Agent "${e}" not found`),{code:"NOT_FOUND"});return n.probe(t)}export{mt as Manager,xe as probeInstalledClientCommands,Ne as probeInstances,He as probeOneInstance};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import*as n from"node:net";const i={bind:"127.0.0.1",port:0,endpoint:"/mcp",sessionTimeoutMs:18e5,invokeTimeoutMs:3e4};function s(u){const e={bind:u?.bind??i.bind,port:u?.port??i.port,endpoint:u?.endpoint??i.endpoint,sessionTimeoutMs:u?.sessionTimeoutMs??i.sessionTimeoutMs,invokeTimeoutMs:u?.invokeTimeoutMs??i.invokeTimeoutMs,allowedOrigins:u?.allowedOrigins,allowedHosts:u?.allowedHosts};return t(e.bind),e.port!==0&&o(e.port),r(e.sessionTimeoutMs),e}function t(u){if(!u||!n.isIPv4(u)&&!n.isIPv6(u))throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: bind \u5730\u5740 "${u}" \u4E0D\u662F\u5408\u6CD5\u7684 IPv4 \u6216 IPv6 \u5730\u5740`)}function o(u){if(!Number.isInteger(u)||u<1||u>65535)throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: port \u503C ${u} \u4E0D\u5728\u5408\u6CD5\u8303\u56F4 1-65535 \u5185\u6216\u4E0D\u662F\u6574\u6570`)}function r(u){if(!Number.isInteger(u)||u<1e3||u>864e5)throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: session_timeout_ms \u503C ${u} \u4E0D\u5728\u5408\u6CD5\u8303\u56F4 1000-86400000 \u5185`)}export{s as createDefaultGatewayConfig};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const a=3e4;class c{connectionManager;onDisconnected;bindings=new Map;constructor(n,i){this.connectionManager=n,this.onDisconnected=i}async bind(n,i){if(this.bindings.has(n))throw new Error(`Session ${n} is already bound to a connection`);const e=await this.connectWithTimeout(i),t=[],s=e.onDisconnected(()=>{this.removeBinding(n),this.onDisconnected(n)});return t.push(s),this.bindings.set(n,{sessionId:n,handle:e,subscriptions:t}),e}getHandle(n){return this.bindings.get(n)?.handle}unbind(n){const i=this.bindings.get(n);if(i){this.bindings.delete(n);for(const e of i.subscriptions)e();i.handle.disconnect()}}unbindAll(){const n=[...this.bindings.keys()];for(const i of n)this.unbind(i)}connectWithTimeout(n){return new Promise((i,e)=>{let t=!1;const s=setTimeout(()=>{t||(t=!0,e(new Error("Connection bind timeout after 30000ms")))},3e4);this.connectionManager.connect({agentId:n.agentId,apiKey:n.apiKey,url:n.wsUrl,clientType:n.clientType,capabilities:["agent_invoke"],adapterHint:`${n.clientType}/base`},{maxRetries:0}).then(o=>{t?o.disconnect():(t=!0,clearTimeout(s),i(o))}).catch(o=>{t||(t=!0,clearTimeout(s),e(o))})})}removeBinding(n){const i=this.bindings.get(n);if(i){this.bindings.delete(n);for(const e of i.subscriptions)e()}}}export{c as ConnectionBindingImpl};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function a(
|
|
1
|
+
function a(e){const t=new Set([`http://127.0.0.1:${e.serverPort}`,`http://localhost:${e.serverPort}`,...e.allowedOrigins]),o=new Set([`127.0.0.1:${e.serverPort}`,`localhost:${e.serverPort}`,...e.allowedHosts]);return{validateRequest(s){const r=i(s,t);if(!r.ok)return r;const n=l(s,o);return n.ok?{ok:!0}:n}}}function i(e,t){const o=e.headers.origin;return o?t.has(o)?{ok:!0}:{ok:!1,statusCode:403,message:`Origin not allowed: ${o}`}:{ok:!0}}function l(e,t){const o=e.headers.host;return o?t.has(o)?{ok:!0}:{ok:!1,statusCode:403,message:`Host not allowed: ${o}`}:{ok:!1,statusCode:403,message:"Missing Host header"}}export{a as createSecurityPolicy};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{toolCallToInvoke as i}from"../../core/mcp/tools.js";import{ToolRegistryImpl as l}from"./tool-registry.js";import{validateToolArgs as a}from"./tool-schemas.js";import{isEventTool as p,executeEventTool as d}from"./event-tool-executor.js";class y{registry;constructor(){this.registry=new l}async execute(
|
|
1
|
+
import{toolCallToInvoke as i}from"../../core/mcp/tools.js";import{ToolRegistryImpl as l}from"./tool-registry.js";import{validateToolArgs as a}from"./tool-schemas.js";import{isEventTool as p,executeEventTool as d}from"./event-tool-executor.js";class y{registry;constructor(){this.registry=new l}async execute(r,e,t,n){if(!this.registry.hasTool(e))return this.errorResult(`\u672A\u77E5\u5DE5\u5177: ${e}`);const s=a(e,t);if(!s.valid)return this.errorResult(`\u53C2\u6570\u6821\u9A8C\u5931\u8D25: ${s.error}`);if(r.status!=="ready")return this.errorResult(`\u8FDE\u63A5\u4E0D\u53EF\u7528: \u5F53\u524D\u72B6\u6001\u4E3A ${r.status}`);if(p(e))return this.executeEventTool(r,e,t);const o=i(e,t);try{const u=await r.agentInvoke(o.action,o.params,n);return this.normalizeResult(u)}catch(u){const c=u instanceof Error?u.message:String(u);return c.toLowerCase().includes("timeout")?this.errorResult(`\u8C03\u7528\u8D85\u65F6: ${c}`):this.errorResult(`\u8C03\u7528\u5931\u8D25: ${c}`)}}normalizeResult(r){if(r==null||typeof r!="object")return this.successResult(r??null);const e=r,t=typeof e.code=="number"?e.code:0;if(t===0){const s="data"in e?e.data:null;return this.successResult(s??null)}const n=typeof e.msg=="string"?e.msg:"\u672A\u77E5\u9519\u8BEF";return this.errorResult(`\u4E0A\u6E38\u9519\u8BEF [code=${t}]: ${n}`)}successResult(r){return{content:[{type:"text",text:JSON.stringify(r)}],isError:!1}}errorResult(r){return{content:[{type:"text",text:r}],isError:!0}}async executeEventTool(r,e,t){return e==="grix_access_control"?this.executeAccessControl(r,t):d(r,e,t)}async executeAccessControl(r,e){const t=String(e.action??""),n={pair_approve:"pair_approve",pair_deny:"pair_deny",allow_sender:"sender_allow",remove_sender:"sender_remove",set_policy:"policy_set"}[t];if(!n)return this.errorResult(`\u672A\u77E5 access_control action: ${t}`);const s={};e.code!=null&&(s.code=e.code),e.sender_id!=null&&(s.sender_id=e.sender_id),e.policy!=null&&(s.policy=e.policy);try{const o=await r.agentInvoke("claude_access_control",{verb:n,payload:s},3e4);return this.successResult(o)}catch(o){const u=o instanceof Error?o.message:String(o);return this.errorResult(`access_control \u8C03\u7528\u5931\u8D25: ${u}`)}}}export{y as ToolExecutorImpl};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{TOOLS as
|
|
1
|
+
import{TOOLS as o,EVENT_TOOLS as s}from"../../core/mcp/tools.js";const e=new Set(["grix_query","grix_group","grix_message_send","grix_message_unsend","grix_admin"]),r=new Set(["grix_reply","grix_complete","grix_event_ack","grix_composing","grix_access_control","grix_status"]);class a{tools;toolMap;constructor(){this.tools=[...o.filter(t=>e.has(t.name)),...s.filter(t=>r.has(t.name))],this.toolMap=new Map(this.tools.map(t=>[t.name,t]))}getTools(){return this.tools}getTool(t){return this.toolMap.get(t)}hasTool(t){return this.toolMap.has(t)}}export{a as ToolRegistryImpl};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const o={required:["action"],properties:{action:{type:"string",enum:["contact_search","session_search","message_history","message_search"]},id:{type:"string"},keyword:{type:"string",maxLength:200},limit:{type:"integer",minimum:1,maximum:100},offset:{type:"integer",minimum:0},sessionId:{type:"string"},beforeId:{type:"string"}}},a={required:["action"],properties:{action:{type:"string",enum:["create","detail","leave","add_members","remove_members","update_member_role","update_all_members_muted","update_member_speaking","dissolve"]},sessionId:{type:"string"},name:{type:"string",maxLength:128},memberIds:{type:"array",items:{type:"string"},maxItems:100},memberTypes:{type:"array",items:{type:"integer",enum:[1,2]}},memberId:{type:"string"},role:{type:"integer",enum:[1,2]},memberType:{type:"integer"},allMembersMuted:{type:"boolean"},isSpeakMuted:{type:"boolean"},canSpeakWhenAllMuted:{type:"boolean"}}},p={required:["sessionId","content"],properties:{sessionId:{type:"string"},content:{type:"string",maxLength:1e4},msgType:{type:"integer"},quotedMessageId:{type:"string"},threadId:{type:"string"}}},m={required:["sessionId","msgId"],properties:{sessionId:{type:"string"},msgId:{type:"string"}}},g={required:["action"],properties:{action:{type:"string",enum:["create_agent","list_categories","create_category","update_category","assign_category","rotate_api_key"]},agentName:{type:"string"},introduction:{type:"string"},isMain:{type:"boolean"},agentId:{type:"string"},categoryId:{type:"string"},name:{type:"string"},parentId:{type:"string"},sortOrder:{type:"integer"}}},y={required:["session_id","text"],properties:{event_id:{type:"string"},session_id:{type:"string"},text:{type:"string",maxLength:5e4},quoted_message_id:{type:"string"},is_final:{type:"boolean"}}},d={required:["event_id","status"],properties:{event_id:{type:"string"},status:{type:"string",enum:["responded","canceled","failed"]},msg:{type:"string",maxLength:500}}},c={required:["event_id"],properties:{event_id:{type:"string"},session_id:{type:"string"}}},l={required:["session_id","active"],properties:{session_id:{type:"string"},active:{type:"boolean"},event_id:{type:"string"}}},_={required:["action"],properties:{action:{type:"string",enum:["pair_approve","pair_deny","allow_sender","remove_sender","set_policy"]},code:{type:"string"},sender_id:{type:"string"},policy:{type:"string",enum:["allowlist","open","disabled"]}}},f={required:[],properties:{}},C={grix_query:o,grix_group:a,grix_message_send:p,grix_message_unsend:m,grix_admin:g,grix_reply:y,grix_complete:d,grix_event_ack:c,grix_composing:l,grix_access_control:_,grix_status:f};function B(
|
|
1
|
+
const o={required:["action"],properties:{action:{type:"string",enum:["contact_search","session_search","message_history","message_search"]},id:{type:"string"},keyword:{type:"string",maxLength:200},limit:{type:"integer",minimum:1,maximum:100},offset:{type:"integer",minimum:0},sessionId:{type:"string"},beforeId:{type:"string"}}},a={required:["action"],properties:{action:{type:"string",enum:["create","detail","leave","add_members","remove_members","update_member_role","update_all_members_muted","update_member_speaking","dissolve"]},sessionId:{type:"string"},name:{type:"string",maxLength:128},memberIds:{type:"array",items:{type:"string"},maxItems:100},memberTypes:{type:"array",items:{type:"integer",enum:[1,2]}},memberId:{type:"string"},role:{type:"integer",enum:[1,2]},memberType:{type:"integer"},allMembersMuted:{type:"boolean"},isSpeakMuted:{type:"boolean"},canSpeakWhenAllMuted:{type:"boolean"}}},p={required:["sessionId","content"],properties:{sessionId:{type:"string"},content:{type:"string",maxLength:1e4},msgType:{type:"integer"},quotedMessageId:{type:"string"},threadId:{type:"string"}}},m={required:["sessionId","msgId"],properties:{sessionId:{type:"string"},msgId:{type:"string"}}},g={required:["action"],properties:{action:{type:"string",enum:["create_agent","list_categories","create_category","update_category","assign_category","rotate_api_key"]},agentName:{type:"string"},introduction:{type:"string"},isMain:{type:"boolean"},agentId:{type:"string"},categoryId:{type:"string"},name:{type:"string"},parentId:{type:"string"},sortOrder:{type:"integer"}}},y={required:["session_id","text"],properties:{event_id:{type:"string"},session_id:{type:"string"},text:{type:"string",maxLength:5e4},quoted_message_id:{type:"string"},is_final:{type:"boolean"}}},d={required:["event_id","status"],properties:{event_id:{type:"string"},status:{type:"string",enum:["responded","canceled","failed"]},msg:{type:"string",maxLength:500}}},c={required:["event_id"],properties:{event_id:{type:"string"},session_id:{type:"string"}}},l={required:["session_id","active"],properties:{session_id:{type:"string"},active:{type:"boolean"},event_id:{type:"string"}}},_={required:["action"],properties:{action:{type:"string",enum:["pair_approve","pair_deny","allow_sender","remove_sender","set_policy"]},code:{type:"string"},sender_id:{type:"string"},policy:{type:"string",enum:["allowlist","open","disabled"]}}},f={required:[],properties:{}},C={grix_query:o,grix_group:a,grix_message_send:p,grix_message_unsend:m,grix_admin:g,grix_reply:y,grix_complete:d,grix_event_ack:c,grix_composing:l,grix_access_control:_,grix_status:f};function B(r,t){const e=C[r];if(!e)return{valid:!1,error:`\u672A\u77E5\u5DE5\u5177: ${r}`};for(const i of e.required)if(t[i]===void 0||t[i]===null)return{valid:!1,error:`\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: ${i}`};for(const[i,u]of Object.entries(t)){if(u==null)continue;const n=e.properties[i];if(!n)continue;const s=$(i,u,n);if(s)return{valid:!1,error:s}}return{valid:!0}}function $(r,t,e){switch(e.type){case"string":if(typeof t!="string")return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxLength!==void 0&&t.length>e.maxLength)return`\u53C2\u6570 ${r} \u8D85\u8FC7\u6700\u5927\u957F\u5EA6 ${e.maxLength}\uFF0C\u5B9E\u9645 ${t.length}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${r} \u503C "${t}" \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"integer":if(typeof t!="number"||!Number.isInteger(t))return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B integer\uFF0C\u5B9E\u9645 ${typeof t=="number"?"\u6D6E\u70B9\u6570":typeof t}`;if(e.minimum!==void 0&&t<e.minimum)return`\u53C2\u6570 ${r} \u503C ${t} \u5C0F\u4E8E\u6700\u5C0F\u503C ${e.minimum}`;if(e.maximum!==void 0&&t>e.maximum)return`\u53C2\u6570 ${r} \u503C ${t} \u5927\u4E8E\u6700\u5927\u503C ${e.maximum}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${r} \u503C ${t} \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"boolean":if(typeof t!="boolean")return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B boolean\uFF0C\u5B9E\u9645 ${typeof t}`;break;case"array":if(!Array.isArray(t))return`\u53C2\u6570 ${r} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B array\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxItems!==void 0&&t.length>e.maxItems)return`\u53C2\u6570 ${r} \u8D85\u8FC7\u6700\u5927\u5143\u7D20\u6570 ${e.maxItems}\uFF0C\u5B9E\u9645 ${t.length}`;if(e.items)for(let i=0;i<t.length;i++){const u=t[i];if(e.items.type==="string"&&typeof u!="string")return`\u53C2\u6570 ${r}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof u}`;if(e.items.type==="integer"){if(typeof u!="number"||!Number.isInteger(u))return`\u53C2\u6570 ${r}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B integer\uFF0C\u5B9E\u9645 ${typeof u}`;if(e.items.enum&&!e.items.enum.includes(u))return`\u53C2\u6570 ${r}[${i}] \u503C ${u} \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.items.enum.join(", ")}]`}}break}}export{B as validateToolArgs};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "grix-connector",
|
|
3
|
-
"version": "3.26.
|
|
3
|
+
"version": "3.26.3",
|
|
4
4
|
"description": "Connect local AI coding agents (Claude, Codex, Gemini, Qwen, DeepSeek, Cursor, OpenCode, Pi, OpenHuman, Reasonix) to the Grix scheduling platform. Also serves as an OpenClaw plugin for Grix channel transport.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
"grix-connector": "dist/grix.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
|
+
"NOTICE",
|
|
12
|
+
"LICENSE",
|
|
11
13
|
"dist",
|
|
12
14
|
"!dist/**/*.map",
|
|
13
15
|
"!dist/**/*.d.ts",
|
|
@@ -76,7 +78,7 @@
|
|
|
76
78
|
"bugs": {
|
|
77
79
|
"url": "https://github.com/askie/grix-connector/issues"
|
|
78
80
|
},
|
|
79
|
-
"license": "
|
|
81
|
+
"license": "Apache-2.0",
|
|
80
82
|
"devDependencies": {
|
|
81
83
|
"@types/node": "^25.6.0",
|
|
82
84
|
"@types/node-forge": "^1.3.14",
|