grix-connector 3.19.0 → 3.19.2
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/dist/adapter/claude/claude-adapter.js +21 -21
- 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/opencode/opencode-adapter.js +3 -3
- package/dist/adapter/pi/pi-adapter.js +3 -3
- package/dist/audit/adapters/codex/codex-audit-adapter.js +1 -1
- package/dist/bridge/bridge.js +2 -2
- package/dist/core/access/allowlist-store.js +1 -1
- package/dist/core/file-ops/list-files.js +1 -1
- package/dist/core/proxy/proxy-manager.js +4 -4
- package/dist/core/proxy/relay-state-sync.js +1 -1
- package/dist/grix.js +1 -1
- package/dist/log.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/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 +1 -1
package/dist/grix.js
CHANGED
|
@@ -38,5 +38,5 @@ Examples:
|
|
|
38
38
|
using Startup folder auto-start instead. For full Task Scheduler integration,
|
|
39
39
|
right-click the terminal and select "Run as administrator".`);const o=H(),c=S["config-dir"]??(S.profile?k.join(o.configDir,S.profile):void 0),h=k.resolve(process.argv[1]||`${o.rootDir}/dist/grix.js`),p=new xe({cliPath:h,nodePath:process.execPath});try{let u;switch(x){case"start":(await p.status({rootDir:o.rootDir})).installed?u=await p.start({rootDir:o.rootDir}):u=await p.install({rootDir:o.rootDir,configDir:c});break;case"stop":u=await p.stop({rootDir:o.rootDir});break;case"restart":(await p.status({rootDir:o.rootDir})).installed?u=await p.restart({rootDir:o.rootDir}):u=await p.install({rootDir:o.rootDir,configDir:c});break;case"status":u=await p.status({rootDir:o.rootDir});break}console.log(JSON.stringify(u,null,2)),process.exit(0)}catch(u){console.error(`${x} failed: ${u instanceof Error?u.message:u}`),process.exit(1)}}else x&&(console.error(`Unknown command: ${x}
|
|
40
40
|
Valid commands: ${ne.join(", ")}`),process.exit(1));const l=H(),Ke=S["config-dir"]??(S.profile?`${l.configDir}/${S.profile}`:void 0),r=new me,F=new Se,ae=Ce(),E=new ke(ae);let K=!1,D;async function se(o){process.stderr.write(o.message+`
|
|
41
|
-
`),s.error("main",o.message.replace(/\n/g," \u2014 "));const c=M(l.daemonLockFile);c?.pid===process.pid&&c.instance_id===D&&await _(l.daemonStatusFile,{state:"failed",pid:process.pid,instance_id:D,updated_at:Date.now(),reason:`port_bind_${o.kind}:${o.label}:${o.port}`}).catch(()=>{}),await G(),T(l.daemonLockFile).catch(()=>{}),C(),process.exit(1)}async function L(o){if(K)return;K=!0,s.info("main",`Received ${o}, shutting down...`),F.markShuttingDown();const c=setTimeout(()=>{s.error("main","Shutdown timed out, forcing exit"),T(l.daemonLockFile).catch(()=>{}),C(),process.exit(2)},1e4);try{await r.stop(),await m()?.stop().catch(()=>{}),await E.stop(),await F.stop(),await G(),await T(l.daemonLockFile),await Ie(l.daemonStatusFile).catch(()=>{}),clearTimeout(c),C(),s.info("main","Shutdown complete"),process.exit(0)}catch(h){s.error("main",`Shutdown error: ${h}`),T(l.daemonLockFile).catch(()=>{}),C(),process.exit(2)}}async function Ve(){if(he(),ye(),we(l.stdoutLogFile,l.stderrLogFile),q(!1),await Ue(),process.platform==="win32"){const e=be(l.rootDir,"win32");await Ee(e,{platform:"win32"})}try{D=(await De(l.daemonLockFile,l.rootDir)).instance_id}catch(e){console.error(e instanceof Error?e.message:e),process.exit(1)}Re(),s.info("main",`grix-connector starting (PID ${process.pid})`),await _(l.daemonStatusFile,{state:"starting",pid:process.pid,instance_id:D,updated_at:Date.now()});const o=parseInt(S["health-port"]??process.env.GRIX_HEALTH_PORT??"19579",10);{const e=await z({label:"health",port:o,envVar:"GRIX_HEALTH_PORT",cliFlag:"health-port",start:n=>F.start(n)});e&&await se(e)}const c=k.join(l.dataDir,"health-port");Y(c,String(o),"utf-8"),process.on("SIGINT",()=>L("SIGINT")),process.on("SIGTERM",()=>L("SIGTERM")),process.on("SIGHUP",()=>{K||(s.info("main","Received SIGHUP, reloading config..."),r.reload().then(e=>s.info("main",`reload done: ${JSON.stringify(e)}`)).catch(e=>s.error("main",`reload failed: ${e instanceof Error?e.message:e}`)))});let h="",p=0,u;process.on("uncaughtException",e=>{const n=e instanceof Error?e.stack??e.message:String(e);n===h?(p++,(p<=3||p%100===0)&&s.error("main",`Uncaught exception (x${p}): ${n}`)):(p>3&&s.error("main",`Previous exception repeated ${p} times total`),h=n,p=1,s.error("main",`Uncaught exception: ${e instanceof Error?e.stack:e}`),u||(u=setTimeout(()=>{p>3&&s.error("main",`Previous exception repeated ${p} times total`),h="",p=0,u=void 0},1e4).unref())),!ie(e)&&(N(e,"uncaughtException"),L("uncaughtException"))}),process.on("unhandledRejection",e=>{s.error("main",`Unhandled rejection: ${e}`),!ie(e)&&(N(e,"unhandledRejection"),L("unhandledRejection"))});const b=$e(l.dataDir);await b.clearRuntimeState();const P=b.getRelayAgents();if(P.length>0)try{await b.startIfAnyRelayAgent(),s.info("main",`mitm proxy started for relay agents: ${P.join(", ")} (per-agent; others stay direct)`)}catch(e){s.error("main",`mitm proxy FAILED to start (relay agents: ${P.join(", ")}): ${e}. These agents will REFUSE to start (they must not silently fall back to your own account). Fix the proxy or turn relay off for them. Other agents are unaffected.`)}else s.info("main",'mitm proxy idle (no agent has Grix relay enabled; enable: PUT /api/proxy/agents/<name>/enabled {"enabled":true})');
|
|
41
|
+
`),s.error("main",o.message.replace(/\n/g," \u2014 "));const c=M(l.daemonLockFile);c?.pid===process.pid&&c.instance_id===D&&await _(l.daemonStatusFile,{state:"failed",pid:process.pid,instance_id:D,updated_at:Date.now(),reason:`port_bind_${o.kind}:${o.label}:${o.port}`}).catch(()=>{}),await G(),T(l.daemonLockFile).catch(()=>{}),C(),process.exit(1)}async function L(o){if(K)return;K=!0,s.info("main",`Received ${o}, shutting down...`),F.markShuttingDown();const c=setTimeout(()=>{s.error("main","Shutdown timed out, forcing exit"),T(l.daemonLockFile).catch(()=>{}),C(),process.exit(2)},1e4);try{await r.stop(),await m()?.stop().catch(()=>{}),await E.stop(),await F.stop(),await G(),await T(l.daemonLockFile),await Ie(l.daemonStatusFile).catch(()=>{}),clearTimeout(c),C(),s.info("main","Shutdown complete"),process.exit(0)}catch(h){s.error("main",`Shutdown error: ${h}`),T(l.daemonLockFile).catch(()=>{}),C(),process.exit(2)}}async function Ve(){if(he(),ye(),we(l.stdoutLogFile,l.stderrLogFile),q(!1),await Ue(),process.platform==="win32"){const e=be(l.rootDir,"win32");await Ee(e,{platform:"win32"})}try{D=(await De(l.daemonLockFile,l.rootDir)).instance_id}catch(e){console.error(e instanceof Error?e.message:e),process.exit(1)}Re(),s.info("main",`grix-connector starting (PID ${process.pid})`),await _(l.daemonStatusFile,{state:"starting",pid:process.pid,instance_id:D,updated_at:Date.now()});const o=parseInt(S["health-port"]??process.env.GRIX_HEALTH_PORT??"19579",10);{const e=await z({label:"health",port:o,envVar:"GRIX_HEALTH_PORT",cliFlag:"health-port",start:n=>F.start(n)});e&&await se(e)}const c=k.join(l.dataDir,"health-port");Y(c,String(o),"utf-8"),process.on("SIGINT",()=>L("SIGINT")),process.on("SIGTERM",()=>L("SIGTERM")),process.on("SIGHUP",()=>{K||(s.info("main","Received SIGHUP, reloading config..."),r.reload().then(e=>s.info("main",`reload done: ${JSON.stringify(e)}`)).catch(e=>s.error("main",`reload failed: ${e instanceof Error?e.message:e}`)))});let h="",p=0,u;process.on("uncaughtException",e=>{const n=e instanceof Error?e.stack??e.message:String(e);n===h?(p++,(p<=3||p%100===0)&&s.error("main",`Uncaught exception (x${p}): ${n}`)):(p>3&&s.error("main",`Previous exception repeated ${p} times total`),h=n,p=1,s.error("main",`Uncaught exception: ${e instanceof Error?e.stack:e}`),u||(u=setTimeout(()=>{p>3&&s.error("main",`Previous exception repeated ${p} times total`),h="",p=0,u=void 0},1e4).unref())),!ie(e)&&(N(e,"uncaughtException"),L("uncaughtException"))}),process.on("unhandledRejection",e=>{s.error("main",`Unhandled rejection: ${e}`),!ie(e)&&(N(e,"unhandledRejection"),L("unhandledRejection"))});const b=$e(l.dataDir);await b.clearRuntimeState();const P=b.getRelayAgents();if(P.length>0)try{await b.startIfAnyRelayAgent(),s.info("main",`mitm proxy started for relay agents: ${P.join(", ")} (per-agent; others stay direct)`)}catch(e){s.error("main",`mitm proxy FAILED to start (relay agents: ${P.join(", ")}): ${e}. These agents will REFUSE to start (they must not silently fall back to your own account). Fix the proxy or turn relay off for them. Other agents are unaffected.`)}else s.info("main",'mitm proxy idle (no agent has Grix relay enabled; enable: PUT /api/proxy/agents/<name>/enabled {"enabled":true})');let I=null;if(m()){const e=async()=>{const t=m();t&&await _e(t,r)&&s.info("main","no agent uses Grix relay anymore; mitm proxy stopped")};r.setRelayEnvSettledHandler(()=>{e().catch(t=>{s.warn("main",`failed to stop idle mitm proxy: ${t}`)})});const n=()=>{const t=m(),a=t.getRelayAgents(),i=t.getDegradedRelayAgents();return{enabled:a.length>0,relayAgents:a,staleRelayAgents:r.getAgentsWithStaleRelayEnv(),degradedRelayAgents:i,runtime:t.getRuntimeInfo(),config:t.getConfigSnapshot()}},d=new Le,R={status:()=>n(),setAgentRelay:async(t,a,i)=>{const f=m(),w={info:y=>s.info("main",y),warn:y=>s.warn("main",y)},A=y=>r.getAgentsStatus().find(v=>v.name===y),g=A(t);if(!a){d.cancel(t);const y=await d.runExclusive(t,async()=>{if(g&&B(g.clientType))return await r.setAgentProvider(t,void 0),{...n(),restarted:!0,busy:!1};const{restarted:v,busy:O}=await Z(f,r,w,{agentName:t,enabled:!1});return{...n(),restarted:v,busy:O}});return r.reportRelayStateLocalChange(t),y}if(!g)throw Object.assign(new Error(`Agent "${t}" not found`),{code:"NOT_FOUND"});if(!B(g.clientType)&&Q(g.clientType).length===0)throw Object.assign(new Error(`client type "${g.clientType??""}" does not support Grix relay`),{code:"UNSUPPORTED_CLIENT_TYPE"});const de=await d.runExclusive(t,async()=>{const y=d.epoch(t),v=A(t);if(!v)throw Object.assign(new Error(`Agent "${t}" not found`),{code:"NOT_FOUND"});const O=B(v.clientType),X=String(v.agentId??"").trim();if(!X)throw new te(`local agent "${t}" has no agent_id registered`,"MISSING_AGENT_ID");const J=d.waitCancelled(t,y);let $;try{$=await Promise.race([r.fetchRelayCredential(t,{model:i}),J.promise.then(()=>{throw new re("relay enable cancelled by a later disable","CANCELLED")})])}finally{J.dispose()}d.assertCurrent(t,y);const{restarted:pe,busy:ge}=await ee(f,r,A,w,{localName:t,agentId:X,virtualKey:$.apiKey,anthropicBaseUrl:$.anthropicBaseUrl,openaiBaseUrl:$.openaiBaseUrl,model:i},(ue,fe)=>r.setAgentProvider(ue,fe));if(d.epoch(t)!==y)throw O?await r.setAgentProvider(t,void 0):await Z(f,r,w,{agentName:t,enabled:!1}),new re("relay enable cancelled by a later disable","CANCELLED");return{...n(),restarted:pe,busy:ge}});return r.reportRelayStateLocalChange(t),de},setAgentRelayCredential:async(t,a)=>{const i=m(),f=r.getAgentsStatus(),{restarted:w,busy:A}=await ee(i,r,g=>f.find(U=>U.name===g),{info:g=>s.info("main",g),warn:g=>s.warn("main",g)},{localName:t,agentId:a.agentId,virtualKey:a.virtualKey,anthropicBaseUrl:a.anthropicBaseUrl,openaiBaseUrl:a.openaiBaseUrl,model:a.model},(g,U)=>r.setAgentProvider(g,U));return r.reportRelayStateLocalChange(t),{...n(),restarted:w,busy:A}},disableAll:async()=>{const t=m();for(const i of r.getAgentsStatus())d.cancel(i.name);await Fe(t,r,{info:i=>s.info("main",i),warn:i=>s.warn("main",i)});const a=await r.clearDirectProviderConfigs();return a.length>0&&s.info("main",`relay disable-all cleared native provider config for: ${a.join(", ")}`),n()},setRoute:async(t,a)=>{const i=a,f=m();return f.setRoute({routeKey:t,targetBaseUrl:i.targetBaseUrl,...i.headers?{headers:i.headers}:{},...i.model?{model:i.model}:{},...i.modelMap?{modelMap:i.modelMap}:{},...i.passthrough?{passthrough:!0}:{},...i.relayOnly?{relayOnly:!0}:{},...i.codexResponsesToChat?{codexResponsesToChat:!0}:{}}),await f.persistConfig(),n()},deleteRoute:async t=>{const a=m();a.deleteRoute(t),await a.persistConfig()},setDefaultRoute:async t=>{const a=m();return a.setDefaultRouteKey(t),await a.persistConfig(),n()},setInterceptHosts:async t=>{const a=m();return a.setInterceptHosts(t),await a.persistConfig(),n()}};I=R,E.setProxyHandler(R),r.setRelayStateApplier({getLocalState:t=>{const a=m();if(a.getRelayAgents().includes(t)){const f=r.getAgentsStatus().find(g=>g.name===t),w=`grix-gateway-${String(f?.clientType??"").trim().toLowerCase()}`;return{enabled:!0,model:a.getConfigSnapshot().routes?.find(g=>g.routeKey===w)?.model?.trim()||void 0}}const i=r.getAgentProvider(t);return i?.api_key?.trim()?{enabled:!0,model:i.model?.trim()||void 0}:{enabled:!1}},applyEnable:async(t,a,i)=>{const f=r.getAgentsStatus().find(A=>A.name===t),w=String(f?.agentId??"").trim();if(!w)throw new te(`local agent "${t}" has no agent_id registered`,"MISSING_AGENT_ID");await R.setAgentRelayCredential(t,{agentId:w,virtualKey:a.apiKey,anthropicBaseUrl:a.anthropicBaseUrl,openaiBaseUrl:a.openaiBaseUrl,model:i??a.model})},applyDisable:async t=>{await R.setAgentRelay(t,!1)}})}if(F.setStatusProvider(()=>r.getAgentsStatus()),await r.start(Ke),P.length>0){const e=r.getAgentsStatus();for(const n of P){const d=e.find(t=>t.name===n);if(!d)continue;const R=Q(d.clientType);R.length!==0&&await b.setAgentRelayEnabled(n,!0,{relayHosts:R}).catch(t=>{s.warn("main",`failed to reconcile relay hosts for "${n}": ${t}`)})}}const V=parseInt(S["admin-port"]??process.env.GRIX_ADMIN_PORT??"19580",10);E.setAgentHandler({list:()=>r.getAgentsStatus(),add:e=>r.addAgent(e),remove:e=>r.removeAgent(e),restart:e=>r.restartAgent(e),reload:()=>r.reload()}),E.setUpgradeHandler({check:()=>r.checkUpgrade(),trigger:()=>r.triggerUpgrade()}),E.setProbeHandler({probeAll:e=>r.probeAll(e),probeOne:(e,n)=>r.probeOne(e,n)}),E.setInstallHandler({listInstallable:()=>r.listInstallable(),installAgent:e=>r.installAgent(e),getInstallProgress:e=>r.getInstallProgress(e)});const W={listAgents:()=>r.getAgentsStatus(),enableManaged:(e,n,d)=>{if(!I)throw new oe(`agent "${e}" needs the MITM proxy for relay, but it is not running`,"PROXY_UNAVAILABLE");return I.setAgentRelayCredential(e,{agentId:n,virtualKey:d.virtualKey,anthropicBaseUrl:d.anthropicBaseUrl,openaiBaseUrl:d.openaiBaseUrl,model:d.model})},disableManaged:e=>{if(!I)throw new oe(`agent "${e}" needs the MITM proxy for relay, but it is not running`,"PROXY_UNAVAILABLE");return I.setAgentRelay(e,!1)},enableHermesProfile:(e,n)=>Oe({agentId:e,baseUrl:n.openaiBaseUrl??"",virtualKey:n.virtualKey,model:n.model??""}),disableHermesProfile:e=>He(e)};E.setRelayCredentialHandler({listHermesProfiles:()=>Be(),enable:async(e,n)=>{const{target:d,result:R}=await Ge(W,e,n);return{target:d,...R}},disable:async e=>{const{target:n,result:d}=await Me(W,e);return{target:n,...d}}});{const e=await z({label:"admin",port:V,envVar:"GRIX_ADMIN_PORT",cliFlag:"admin-port",start:n=>E.start(n)});e&&await se(e)}const le=k.join(l.dataDir,"admin-token"),ce=k.join(l.dataDir,"admin-port");Te(le,ae),Y(ce,String(V),"utf-8"),await _(l.daemonStatusFile,{state:"running",pid:process.pid,instance_id:D,updated_at:Date.now()}),process.send&&process.send("ready"),s.info("main","grix-connector ready")}Ve().catch(async o=>{const c=`Fatal: ${o instanceof Error?o.stack??o.message:String(o)}`;try{process.stderr.write(`${c}
|
|
42
42
|
`)}catch{}q(!1),s.error("main",c),N(o,"startup");const h=M(l.daemonLockFile);h?.pid===process.pid&&h.instance_id===D&&await _(l.daemonStatusFile,{state:"failed",pid:process.pid,instance_id:h.instance_id,updated_at:Date.now(),reason:"startup_error"}).catch(()=>{}),await G(),T(l.daemonLockFile).catch(()=>{}),C(),process.exit(1)});const We=new Set(["ECONNRESET","ECONNREFUSED","ETIMEDOUT","EPIPE","EAI_AGAIN","ENOTFOUND","EHOSTUNREACH","ENETUNREACH","EIO"]);function ie(o){return o instanceof Error&&"code"in o?We.has(o.code):!1}
|
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 t}from"node:path";import{homedir as m}from"node:os";const i=t(m(),".grix"),s={base:i,config:t(i,"config"),log:t(i,"log"),data:t(i,"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=t(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,...n){const e=`${c()} [${o}] ${r}${n.length?" "+n.map(String).join(" "):""}`;console.log(e),a?.write(e+`
|
|
2
|
+
`)},error(o,r,...n){const e=`${c()} [${o}] ERROR ${r}${n.length?" "+n.map(String).join(" "):""}`;console.error(e),a?.write(e+`
|
|
3
3
|
`)}};export{s as GRIX_PATHS,S as ensureGrixDirs,$ as initLogger,u as log};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import*as i from"node:net";const e={bind:"127.0.0.1",port:0,endpoint:"/mcp",sessionTimeoutMs:18e5,invokeTimeoutMs:3e4};function n(o){const u={bind:o?.bind??e.bind,port:o?.port??e.port,endpoint:o?.endpoint??e.endpoint,sessionTimeoutMs:o?.sessionTimeoutMs??e.sessionTimeoutMs,invokeTimeoutMs:o?.invokeTimeoutMs??e.invokeTimeoutMs,allowedOrigins:o?.allowedOrigins,allowedHosts:o?.allowedHosts};return s(u.bind),u.port!==0&&t(u.port),r(u.sessionTimeoutMs),u}function s(o){if(!o||!i.isIPv4(o)&&!i.isIPv6(o))throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: bind \u5730\u5740 "${o}" \u4E0D\u662F\u5408\u6CD5\u7684 IPv4 \u6216 IPv6 \u5730\u5740`)}function t(o){if(!Number.isInteger(o)||o<1||o>65535)throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: port \u503C ${o} \u4E0D\u5728\u5408\u6CD5\u8303\u56F4 1-65535 \u5185\u6216\u4E0D\u662F\u6574\u6570`)}function r(o){if(!Number.isInteger(o)||o<1e3||o>864e5)throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25: session_timeout_ms \u503C ${o} \u4E0D\u5728\u5408\u6CD5\u8303\u56F4 1000-86400000 \u5185`)}export{n as createDefaultGatewayConfig};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const r=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
|
-
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(t,e,r,n){if(!this.registry.hasTool(e))return this.errorResult(`\u672A\u77E5\u5DE5\u5177: ${e}`);const s=a(e,r);if(!s.valid)return this.errorResult(`\u53C2\u6570\u6821\u9A8C\u5931\u8D25: ${s.error}`);if(t.status!=="ready")return this.errorResult(`\u8FDE\u63A5\u4E0D\u53EF\u7528: \u5F53\u524D\u72B6\u6001\u4E3A ${t.status}`);if(p(e))return this.executeEventTool(t,e,r);const o=i(e,r);try{const u=await t.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(t){if(t==null||typeof t!="object")return this.successResult(t??null);const e=t,r=typeof e.code=="number"?e.code:0;if(r===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=${r}]: ${n}`)}successResult(t){return{content:[{type:"text",text:JSON.stringify(t)}],isError:!1}}errorResult(t){return{content:[{type:"text",text:t}],isError:!0}}async executeEventTool(t,e,r){return e==="grix_access_control"?this.executeAccessControl(t,r):d(t,e,r)}async executeAccessControl(t,e){const r=String(e.action??""),n={pair_approve:"pair_approve",pair_deny:"pair_deny",allow_sender:"sender_allow",remove_sender:"sender_remove",set_policy:"policy_set"}[r];if(!n)return this.errorResult(`\u672A\u77E5 access_control action: ${r}`);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 t.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 s,EVENT_TOOLS as t}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=[...s.filter(o=>e.has(o.name)),...t.filter(o=>r.has(o.name))],this.toolMap=new Map(this.tools.map(o=>[o.name,o]))}getTools(){return this.tools}getTool(o){return this.toolMap.get(o)}hasTool(o){return this.toolMap.has(o)}}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(u,t){const e=C[u];if(!e)return{valid:!1,error:`\u672A\u77E5\u5DE5\u5177: ${u}`};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,r]of Object.entries(t)){if(r==null)continue;const n=e.properties[i];if(!n)continue;const s=$(i,r,n);if(s)return{valid:!1,error:s}}return{valid:!0}}function $(u,t,e){switch(e.type){case"string":if(typeof t!="string")return`\u53C2\u6570 ${u} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxLength!==void 0&&t.length>e.maxLength)return`\u53C2\u6570 ${u} \u8D85\u8FC7\u6700\u5927\u957F\u5EA6 ${e.maxLength}\uFF0C\u5B9E\u9645 ${t.length}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${u} \u503C "${t}" \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"integer":if(typeof t!="number"||!Number.isInteger(t))return`\u53C2\u6570 ${u} \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 ${u} \u503C ${t} \u5C0F\u4E8E\u6700\u5C0F\u503C ${e.minimum}`;if(e.maximum!==void 0&&t>e.maximum)return`\u53C2\u6570 ${u} \u503C ${t} \u5927\u4E8E\u6700\u5927\u503C ${e.maximum}`;if(e.enum&&!e.enum.includes(t))return`\u53C2\u6570 ${u} \u503C ${t} \u4E0D\u5728\u5141\u8BB8\u8303\u56F4 [${e.enum.join(", ")}]`;break;case"boolean":if(typeof t!="boolean")return`\u53C2\u6570 ${u} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B boolean\uFF0C\u5B9E\u9645 ${typeof t}`;break;case"array":if(!Array.isArray(t))return`\u53C2\u6570 ${u} \u7C7B\u578B\u9519\u8BEF: \u671F\u671B array\uFF0C\u5B9E\u9645 ${typeof t}`;if(e.maxItems!==void 0&&t.length>e.maxItems)return`\u53C2\u6570 ${u} \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 r=t[i];if(e.items.type==="string"&&typeof r!="string")return`\u53C2\u6570 ${u}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B string\uFF0C\u5B9E\u9645 ${typeof r}`;if(e.items.type==="integer"){if(typeof r!="number"||!Number.isInteger(r))return`\u53C2\u6570 ${u}[${i}] \u7C7B\u578B\u9519\u8BEF: \u671F\u671B integer\uFF0C\u5B9E\u9645 ${typeof r}`;if(e.items.enum&&!e.items.enum.includes(r))return`\u53C2\u6570 ${u}[${i}] \u503C ${r} \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.19.
|
|
3
|
+
"version": "3.19.2",
|
|
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",
|