grix-connector 2.0.5 → 2.0.7

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.
@@ -1 +1 @@
1
- const a=[{name:"grix_query",description:"Search contacts, sessions, message history, or messages by keyword in the Grix/AIBot platform.",inputSchema:{type:"object",properties:{action:{type:"string",enum:["contact_search","session_search","message_history","message_search"],description:"Query action type."},id:{type:"string",description:"Contact ID (contact_search) or Session ID (session_search)."},keyword:{type:"string",description:"Search keyword."},limit:{type:"integer",description:"Max results."},offset:{type:"integer",description:"Result offset."},sessionId:{type:"string",description:"Session ID (message_history, message_search)."},beforeId:{type:"string",description:"Pagination cursor (message_history, message_search)."}},required:["action"]},validation:{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"}}}},{name:"grix_group",description:"Manage groups in the Grix/AIBot platform: create, get details, leave, dissolve, manage members and permissions.",inputSchema:{type:"object",properties:{action:{type:"string",enum:["create","detail","leave","add_members","remove_members","update_member_role","update_all_members_muted","update_member_speaking","dissolve"],description:"Group action type."},sessionId:{type:"string",description:"Group session ID."},name:{type:"string",description:"Group name (create)."},memberIds:{type:"array",items:{type:"string"},description:"Member IDs to add/remove."},memberTypes:{type:"array",items:{type:"integer",enum:[1,2]},description:"Member types (1=user, 2=agent)."},memberId:{type:"string",description:"Target member ID."},role:{type:"integer",enum:[1,2],description:"New role (1=admin, 2=member)."},memberType:{type:"integer",description:"Member type."},allMembersMuted:{type:"boolean",description:"Whether to mute all members."},isSpeakMuted:{type:"boolean",description:"Whether member is muted."},canSpeakWhenAllMuted:{type:"boolean",description:"Allow speaking when all muted."}},required:["action"]},validation:{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"}}}},{name:"grix_message_send",description:"Send a message to a session in the Grix/AIBot platform.",inputSchema:{type:"object",properties:{sessionId:{type:"string",description:"Target session ID"},content:{type:"string",description:"Message content"},msgType:{type:"integer",description:"Message type (1=text, default 1)"},quotedMessageId:{type:"string",description:"Message ID to reply to"},threadId:{type:"string",description:"Thread ID for threaded reply"}},required:["sessionId","content"]},validation:{required:["sessionId","content"],properties:{sessionId:{type:"string"},content:{type:"string",maxLength:1e4},msgType:{type:"integer"},quotedMessageId:{type:"string"},threadId:{type:"string"}}}},{name:"grix_message_unsend",description:"Recall/unsend a message in the Grix/AIBot platform.",inputSchema:{type:"object",properties:{sessionId:{type:"string",description:"Session ID"},msgId:{type:"string",description:"Message ID to unsend"}},required:["sessionId","msgId"]},validation:{required:["sessionId","msgId"],properties:{sessionId:{type:"string"},msgId:{type:"string"}}}},{name:"grix_file_link",description:"Create a direct, tailnet-only download link for a local file on this host. Use this whenever the user asks you to send, share, give, or deliver a file that exists on the machine where you run (a report, log, build artifact, export, or any local path). It returns a ready-to-use Markdown link in the `markdown` field \u2014 include that exact Markdown link in your reply so the user can click and download the file directly over the shared Tailscale network. Each link is one-time and expires, so call this again to produce a fresh link every time you deliver a file. Requires this host to be on a tailnet (Tailscale running).",inputSchema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to a local file on this host to share with the user."},ttl_ms:{type:"integer",description:"Optional link lifetime in milliseconds (default 10 minutes)."}},required:["file_path"]},validation:{required:["file_path"],properties:{file_path:{type:"string",maxLength:4096},ttl_ms:{type:"integer",minimum:1e4,maximum:864e5}}}},{name:"grix_admin",description:"Agent and category management in the Grix/AIBot platform: create agents, manage categories, rotate API keys.",inputSchema:{type:"object",properties:{action:{type:"string",enum:["create_agent","list_categories","create_category","update_category","assign_category","rotate_api_key"],description:"Admin action type."},agentName:{type:"string",description:"Agent name (create_agent)."},introduction:{type:"string",description:"Agent introduction (create_agent)."},isMain:{type:"boolean",description:"Set as main agent (create_agent)."},agentId:{type:"string",description:"Agent ID (assign_category, rotate_api_key)."},categoryId:{type:"string",description:"Category ID (create_agent, update_category, assign_category)."},name:{type:"string",description:"Category name (create_category, update_category)."},parentId:{type:"string",description:"Parent category ID (create_category, update_category)."},sortOrder:{type:"integer",description:"Sort order (create_category, update_category)."}},required:["action"]},validation:{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"}}}},{name:"grix_call_owner",description:"Call your owner into this session to talk by voice. Use this when, during your work, you need to reach your owner \u2014 to discuss something or to get an approval/review. It sends the owner an offline notification; when they tap it they land directly in this conversation and a voice-brain call is started automatically. Requires the owner to have configured a voice brain. Rate-limited per session.",inputSchema:{type:"object",properties:{session_id:{type:"string",description:"The session ID to call the owner into."}},required:["session_id"]},validation:{required:["session_id"],properties:{session_id:{type:"string"}}}},{name:"grix_agent_update",description:"Update the text introduction of one of your owner's agents, identified by its numeric agent ID.",inputSchema:{type:"object",properties:{agent_id:{type:"string",description:"Target agent's numeric ID, passed as a string."},introduction:{type:"string",description:"New text introduction (max 300 characters)."}},required:["agent_id","introduction"]},validation:{required:["agent_id","introduction"],properties:{agent_id:{type:"string"},introduction:{type:"string",maxLength:300}}}},{name:"grix_dispatch_agent",description:"Dispatch one of your owner's agents to do work in a given working directory. Provide the target agent numeric ID, the working directory, and a text description of the task. The backend opens (or reuses) a private session between the owner and that agent, binds the working directory when the agent type requires it (claude/codex/etc.), and sends the task into the session as the owner so the agent starts working.",inputSchema:{type:"object",properties:{agent_id:{type:"string",description:"Target agent's numeric ID, passed as a string."},cwd:{type:"string",description:"Absolute working directory where the agent should do the work."},task:{type:"string",description:"Text description of the task to perform."}},required:["agent_id","cwd","task"]},validation:{required:["agent_id","cwd","task"],properties:{agent_id:{type:"string"},cwd:{type:"string",maxLength:4096},task:{type:"string",maxLength:1e4}}}},{name:"grix_session_send",description:"Send a message into a session AS THE OWNER \u2014 it appears as if the owner sent it, NOT as you (the agent). Use ONLY to relay on the owner's behalf into one of the owner's OTHER sessions that you are not part of (e.g. you were dispatched to work and need to drop a note to the owner elsewhere). NEVER use this to send your own reply in a session you are conversing in \u2014 that would make your words show up as the owner's message. To answer in your current conversation, reply normally (or use grix_message_send to send as yourself). The owner must be a member of the target session, and you (the agent) must NOT be a member of it \u2014 sending into a session you belong to is rejected.",inputSchema:{type:"object",properties:{session_id:{type:"string",description:"Target session ID."},content:{type:"string",description:"Message content to send as the owner."}},required:["session_id","content"]},validation:{required:["session_id","content"],properties:{session_id:{type:"string"},content:{type:"string",maxLength:1e4}}}},{name:"grix_task_query",description:"Query the session-level task states of all your owner's sessions. Takes no parameters \u2014 owner and agent are resolved from your authenticated connection. Returns one entry per session with a single mutually-exclusive state: running (working), waiting_approval (blocked on your owner to approve/deny), waiting_question (asked the owner a question, awaiting their reply), completed, failed, or idle (no task / stopped). Use this to see at a glance which tasks are done, still running, or waiting on the owner.",inputSchema:{type:"object",properties:{}},validation:{required:[],properties:{}}}],d=[{name:"grix_reply",description:"Send a reply message to the specified session. Supports streaming in chunks; the frontend will automatically aggregate them into one complete message. Any content meant for the user \u2014 including your final conclusion at the end of a turn \u2014 MUST be sent through this tool; text written outside this tool is not delivered to the user.",inputSchema:{type:"object",properties:{event_id:{type:"string",description:"Associated event ID from the inbound event."},session_id:{type:"string",description:"Target session ID."},text:{type:"string",description:"Reply text content."},quoted_message_id:{type:"string",description:"Quoted message ID (optional)."},is_final:{type:"boolean",description:"Whether this is a stage-final reply. Advisory only \u2014 does not trigger event completion; completion is handled by the complete tool or Stop hook."}},required:["session_id","text"]},validation:{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"}}}},{name:"grix_complete",description:"Mark event processing as complete, notifying the backend that no more replies are expected.",inputSchema:{type:"object",properties:{event_id:{type:"string",description:"The event ID to complete."},status:{type:"string",enum:["responded","canceled","failed"],description:"Completion status."},msg:{type:"string",description:"Additional note (optional)."}},required:["event_id","status"]},validation:{required:["event_id","status"],properties:{event_id:{type:"string"},status:{type:"string",enum:["responded","canceled","failed"]},msg:{type:"string",maxLength:500}}}},{name:"grix_event_ack",description:"Acknowledge event receipt (usually done automatically by the Dispatcher; agents typically do not need to call this manually).",inputSchema:{type:"object",properties:{event_id:{type:"string",description:"The event ID to acknowledge."},session_id:{type:"string",description:"Session ID."}},required:["event_id"]},validation:{required:["event_id"],properties:{event_id:{type:"string"},session_id:{type:"string"}}}},{name:"grix_composing",description:'Set the "typing" indicator status for a session.',inputSchema:{type:"object",properties:{session_id:{type:"string",description:"Session ID."},active:{type:"boolean",description:"true = typing, false = stopped."},event_id:{type:"string",description:"Associated event ID (optional)."}},required:["session_id","active"]},validation:{required:["session_id","active"],properties:{session_id:{type:"string"},active:{type:"boolean"},event_id:{type:"string"}}}},{name:"grix_access_control",description:"Manage sender access control: pair approval, allow/remove senders, set policy.",inputSchema:{type:"object",properties:{action:{type:"string",enum:["pair_approve","pair_deny","allow_sender","remove_sender","set_policy"],description:"Access control action type."},code:{type:"string",description:"Pairing code (required for pair_approve/pair_deny)."},sender_id:{type:"string",description:"Sender ID (required for allow_sender/remove_sender)."},policy:{type:"string",enum:["allowlist","open","disabled"],description:"Access policy (required for set_policy)."}},required:["action"]},validation:{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"]}}}},{name:"grix_status",description:"Query the Grix connection status of the current MCP session.",inputSchema:{type:"object",properties:{}},validation:{required:[],properties:{}}}],p=[{name:"reply",description:"Send a visible message back to the chat for this grix-claude event.",inputSchema:{type:"object",properties:{text:{type:"string",description:"The visible reply text to send."},chat_id:{type:"string",description:"The target chat/session id from the <channel> tag."},event_id:{type:"string",description:"The Aibot event_id from the <channel> tag."},reply_to:{type:"string",description:"Optional message_id to quote instead of the inbound trigger message."},final:{type:"boolean",description:"Advisory flag only. It does not complete the event; completion is handled by complete tool or Stop hook."}},required:["chat_id","event_id","text"]}},{name:"complete",description:"Finish an event without sending a visible reply so the backend does not time out.",inputSchema:{type:"object",properties:{event_id:{type:"string",description:"The Aibot event_id from the <channel> tag."},status:{type:"string",enum:["responded","canceled","failed"]},msg:{type:"string"},code:{type:"string"}},required:["event_id","status"]}}],c=new Set(p.map(e=>e.name)),b=new Set(a.map(e=>e.name)),v=new Set(d.map(e=>e.name)),I=/([A-Za-z0-9._-]+:[A-Za-z0-9._-]+:[A-Za-z0-9._-]+:[A-Za-z0-9._-]+)/,w=/[A-Za-z0-9._-]+/;function C(e){return!!(b.has(e)||v.has(e)||c.has(e)||e.startsWith("mcp__grix"))}const k=[...a,...d],x=[...k,...p],P=new Map(x.map(e=>[e.name,e]));function R(e,t){return e==="reply"?{name:"grix_reply",args:_("grix_reply",{event_id:t.event_id,session_id:t.chat_id,text:t.text,quoted_message_id:t.reply_to,is_final:t.final})}:e==="complete"?{name:"grix_complete",args:_("grix_complete",{event_id:t.event_id,status:t.status,msg:t.msg,code:t.code})}:{name:e,args:t}}function l(e){const t=String(e??"").trim();return t?t.match(I)?.[1]:void 0}function u(e){const t=String(e??"").trim();if(!t)return;const n=l(t);if(n)return m(n);const i=t.match(/(?:chat_id|session_id)\s*=\s*"([A-Za-z0-9._-]+)"/)?.[1];if(i)return i;const r=t.match(/[A-Za-z0-9._-]+/g)??[];for(const s of r)if(!(s==="event_id"||s==="chat_id"||s==="session_id")&&s.length>0)return s;return t.match(w)?.[0]}function m(e){if(!e)return;const t=e.split(":",1)[0]?.trim();if(t)return u(t)}function _(e,t){if(e!=="grix_reply"&&e!=="grix_complete")return t;const n={...t},i=l(n.event_id);if(i&&(n.event_id=i),e==="grix_reply"){const r=m(i),o=String(n.session_id??""),s=u(n.session_id),f=/\bevent_id\b|["'<>\s]/.test(o);s&&!(f&&r)?n.session_id=s:r&&(n.session_id=r)}return n}function U(e){return c.has(e)}function z(e,t){switch(e){case"grix_query":return S(t);case"grix_group":return A(t);case"grix_message_send":return q(t);case"grix_message_unsend":return T(t);case"grix_file_link":return M(t);case"grix_admin":return j(t);case"grix_call_owner":return O(t);case"grix_agent_update":return D(t);case"grix_dispatch_agent":return E(t);case"grix_session_send":return L(t);case"grix_task_query":return N();default:throw new Error(`Unknown tool: ${e}`)}}const g={contact_search:"contact_search",session_search:"session_search",message_history:"message_history",message_search:"message_search"};function S(e){const t=String(e.action??""),n=g[t];if(!n)throw new Error(`Unknown grix_query action: ${t}`);const i={};return e.id!=null&&(i.id=e.id),e.keyword!=null&&(i.keyword=e.keyword),e.limit!=null&&(i.limit=e.limit),e.offset!=null&&(i.offset=e.offset),e.sessionId!=null&&(i.session_id=e.sessionId),e.beforeId!=null&&(i.before_id=e.beforeId),{action:n,params:i}}const y={create:"group_create",detail:"group_detail_read",leave:"group_leave_self",add_members:"group_member_add",remove_members:"group_member_remove",update_member_role:"group_member_role_update",update_all_members_muted:"group_all_members_muted_update",update_member_speaking:"group_member_speaking_update",dissolve:"group_dissolve"};function A(e){const t=String(e.action??""),n=y[t];if(!n)throw new Error(`Unknown grix_group action: ${t}`);const i={};return e.sessionId!=null&&(i.session_id=e.sessionId),e.name!=null&&(i.name=e.name),e.memberIds!=null&&(i.member_ids=e.memberIds),e.memberTypes!=null&&(i.member_types=e.memberTypes),e.memberId!=null&&(i.member_id=e.memberId),e.role!=null&&(i.role=e.role),e.memberType!=null&&(i.member_type=e.memberType),e.allMembersMuted!=null&&(i.all_members_muted=e.allMembersMuted),e.isSpeakMuted!=null&&(i.is_speak_muted=e.isSpeakMuted),e.canSpeakWhenAllMuted!=null&&(i.can_speak_when_all_muted=e.canSpeakWhenAllMuted),{action:n,params:i}}function q(e){const t={session_id:e.sessionId,msg_type:e.msgType??1,content:e.content};return e.quotedMessageId!=null&&(t.quoted_message_id=e.quotedMessageId),e.threadId!=null&&(t.thread_id=e.threadId),{action:"send_msg",params:t}}function T(e){return{action:"delete_msg",params:{session_id:e.sessionId,msg_id:e.msgId}}}function M(e){const t={file_path:e.file_path};return e.ttl_ms!=null&&(t.ttl_ms=e.ttl_ms),{action:"file_link",params:t}}const h={create_agent:"agent_api_create",list_categories:"agent_category_list",create_category:"agent_category_create",update_category:"agent_category_update",assign_category:"agent_category_assign",rotate_api_key:"agent_api_key_rotate"};function O(e){return{action:"call_owner",params:{session_id:e.session_id}}}function D(e){return{action:"agent_introduction_update",params:{agent_id:e.agent_id,introduction:e.introduction}}}function E(e){return{action:"dispatch_agent",params:{agent_id:e.agent_id,cwd:e.cwd,task:e.task}}}function L(e){return{action:"session_send",params:{session_id:e.session_id,content:e.content}}}function N(){return{action:"agent_task_query",params:{}}}function j(e){const t=String(e.action??""),n=h[t];if(!n)throw new Error(`Unknown grix_admin action: ${t}`);const i={};return e.agentName!=null&&(i.agent_name=e.agentName),e.introduction!=null&&(i.introduction=e.introduction),e.isMain!=null&&(i.is_main=e.isMain),e.agentId!=null&&(i.agent_id=e.agentId),e.categoryId!=null&&(i.category_id=e.categoryId),e.name!=null&&(i.name=e.name),e.parentId!=null&&(i.parent_id=e.parentId),e.sortOrder!=null&&(i.sort_order=e.sortOrder),{action:n,params:i}}const G=new Set([...Object.values(g),...Object.values(y),...Object.values(h),"send_msg","delete_msg","file_link","call_owner","agent_introduction_update","dispatch_agent","session_send","agent_task_query"]),W={pair_approve:"pair_approve",pair_deny:"pair_deny",allow_sender:"sender_allow",remove_sender:"sender_remove",set_policy:"policy_set"};export{W as ACCESS_CONTROL_ACTION_MAP,k as ALL_TOOLS,d as EVENT_TOOLS,x as EXPOSED_TOOLS,G as PHASE1_INVOKE_ACTIONS,b as PHASE1_TOOL_NAMES,v as PHASE2_TOOL_NAMES,a as TOOLS,p as TOOL_ALIASES,P as TOOL_MAP,U as isAlias,C as isGrixInternalToolName,R as mapToolAlias,_ as normalizeEventToolArgs,z as toolCallToInvoke};
1
+ const a=[{name:"grix_query",description:"Search contacts, sessions, message history, or messages by keyword in the Grix/AIBot platform.",inputSchema:{type:"object",properties:{action:{type:"string",enum:["contact_search","session_search","message_history","message_search"],description:"Query action type."},id:{type:"string",description:"Contact ID (contact_search) or Session ID (session_search)."},keyword:{type:"string",description:"Search keyword."},limit:{type:"integer",description:"Max results."},offset:{type:"integer",description:"Result offset."},sessionId:{type:"string",description:"Session ID (message_history, message_search)."},beforeId:{type:"string",description:"Pagination cursor (message_history, message_search)."}},required:["action"]},validation:{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"}}}},{name:"grix_group",description:"Manage groups in the Grix/AIBot platform: create, get details, leave, dissolve, manage members and permissions.",inputSchema:{type:"object",properties:{action:{type:"string",enum:["create","detail","leave","add_members","remove_members","update_member_role","update_all_members_muted","update_member_speaking","dissolve"],description:"Group action type."},sessionId:{type:"string",description:"Group session ID."},name:{type:"string",description:"Group name (create)."},memberIds:{type:"array",items:{type:"string"},description:"Member IDs to add/remove."},memberTypes:{type:"array",items:{type:"integer",enum:[1,2]},description:"Member types (1=user, 2=agent)."},memberId:{type:"string",description:"Target member ID."},role:{type:"integer",enum:[1,2],description:"New role (1=admin, 2=member)."},memberType:{type:"integer",description:"Member type."},allMembersMuted:{type:"boolean",description:"Whether to mute all members."},isSpeakMuted:{type:"boolean",description:"Whether member is muted."},canSpeakWhenAllMuted:{type:"boolean",description:"Allow speaking when all muted."}},required:["action"]},validation:{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"}}}},{name:"grix_message_send",description:"Send a message to a session in the Grix/AIBot platform.",inputSchema:{type:"object",properties:{sessionId:{type:"string",description:"Target session ID"},content:{type:"string",description:"Message content"},msgType:{type:"integer",description:"Message type (1=text, default 1)"},quotedMessageId:{type:"string",description:"Message ID to reply to"},threadId:{type:"string",description:"Thread ID for threaded reply"}},required:["sessionId","content"]},validation:{required:["sessionId","content"],properties:{sessionId:{type:"string"},content:{type:"string",maxLength:1e4},msgType:{type:"integer"},quotedMessageId:{type:"string"},threadId:{type:"string"}}}},{name:"grix_message_unsend",description:"Recall/unsend a message in the Grix/AIBot platform.",inputSchema:{type:"object",properties:{sessionId:{type:"string",description:"Session ID"},msgId:{type:"string",description:"Message ID to unsend"}},required:["sessionId","msgId"]},validation:{required:["sessionId","msgId"],properties:{sessionId:{type:"string"},msgId:{type:"string"}}}},{name:"grix_file_link",description:"Create a direct, tailnet-only download link for a local file on this host. Use this whenever the user asks you to send, share, give, or deliver a file that exists on the machine where you run (a report, log, build artifact, export, or any local path). It returns a ready-to-use Markdown link in the `markdown` field \u2014 include that exact Markdown link in your reply so the user can click and download the file directly over the shared Tailscale network. Each link is one-time and expires, so call this again to produce a fresh link every time you deliver a file. Requires this host to be on a tailnet (Tailscale running).",inputSchema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to a local file on this host to share with the user."},ttl_ms:{type:"integer",description:"Optional link lifetime in milliseconds (default 10 minutes)."}},required:["file_path"]},validation:{required:["file_path"],properties:{file_path:{type:"string",maxLength:4096},ttl_ms:{type:"integer",minimum:1e4,maximum:864e5}}}},{name:"grix_admin",description:"Agent and category management in the Grix/AIBot platform: create agents, manage categories, rotate API keys.",inputSchema:{type:"object",properties:{action:{type:"string",enum:["create_agent","list_categories","create_category","update_category","assign_category","rotate_api_key"],description:"Admin action type."},agentName:{type:"string",description:"Agent name (create_agent)."},introduction:{type:"string",description:"Agent introduction (create_agent)."},isMain:{type:"boolean",description:"Set as main agent (create_agent)."},agentId:{type:"string",description:"Agent ID (assign_category, rotate_api_key)."},categoryId:{type:"string",description:"Category ID (create_agent, update_category, assign_category)."},name:{type:"string",description:"Category name (create_category, update_category)."},parentId:{type:"string",description:"Parent category ID (create_category, update_category)."},sortOrder:{type:"integer",description:"Sort order (create_category, update_category)."}},required:["action"]},validation:{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"}}}},{name:"grix_call_owner",description:"Call your owner into this session to talk by voice. Use this when, during your work, you need to reach your owner \u2014 to discuss something or to get an approval/review. It sends the owner an offline notification; when they tap it they land directly in this conversation and a voice-brain call is started automatically. Requires the owner to have configured a voice brain. Rate-limited per session.",inputSchema:{type:"object",properties:{session_id:{type:"string",description:"The session ID to call the owner into."}},required:["session_id"]},validation:{required:["session_id"],properties:{session_id:{type:"string"}}}},{name:"grix_agent_update",description:"Update the text introduction of one of your owner's agents, identified by its numeric agent ID.",inputSchema:{type:"object",properties:{agent_id:{type:"string",description:"Target agent's numeric ID, passed as a string."},introduction:{type:"string",description:"New text introduction (max 300 characters)."}},required:["agent_id","introduction"]},validation:{required:["agent_id","introduction"],properties:{agent_id:{type:"string"},introduction:{type:"string",maxLength:300}}}},{name:"grix_dispatch_agent",description:"Dispatch one of your owner's agents to do work in a given working directory. Provide the target agent numeric ID, the working directory, and a text description of the task. The backend opens (or reuses) a private session between the owner and that agent, binds the working directory when the agent type requires it (claude/codex/etc.), and sends the task into the session as the owner so the agent starts working.",inputSchema:{type:"object",properties:{agent_id:{type:"string",description:"Target agent's numeric ID, passed as a string."},cwd:{type:"string",description:"Absolute working directory where the agent should do the work."},task:{type:"string",description:"Text description of the task to perform."}},required:["agent_id","cwd","task"]},validation:{required:["agent_id","cwd","task"],properties:{agent_id:{type:"string"},cwd:{type:"string",maxLength:4096},task:{type:"string",maxLength:1e4}}}},{name:"grix_session_send",description:"Send a message into a session AS THE OWNER \u2014 it appears as if the owner sent it, NOT as you (the agent). Use ONLY to relay on the owner's behalf into one of the owner's OTHER sessions that you are not part of (e.g. you were dispatched to work and need to drop a note to the owner elsewhere). NEVER use this to send your own reply in a session you are conversing in \u2014 that would make your words show up as the owner's message. To answer in your current conversation, reply normally (or use grix_message_send to send as yourself). The owner must be a member of the target session, and you (the agent) must NOT be a member of it \u2014 sending into a session you belong to is rejected.",inputSchema:{type:"object",properties:{session_id:{type:"string",description:"Target session ID."},content:{type:"string",description:"Message content to send as the owner."}},required:["session_id","content"]},validation:{required:["session_id","content"],properties:{session_id:{type:"string"},content:{type:"string",maxLength:1e4}}}},{name:"grix_chat_state_query",description:"Query the chat-level task states across all of your owner's sessions (including direct and group chats). Returns one entry per session with a single mutually-exclusive state: running (working), waiting_approval (blocked on your owner to approve/deny), waiting_question (asked the owner a question, awaiting their reply), completed, failed, or idle (no task / stopped). Also returns the session title (task_title) for easy identification. Supports pagination (page/page_size) and optional state filtering. Use this to see at a glance which chats are done, still running, or waiting on the owner.",inputSchema:{type:"object",properties:{page:{type:"number",description:"(Optional) Page number, starting from 1. Defaults to 1 if omitted."},page_size:{type:"number",description:"(Optional) Number of items per page, max 100. Defaults to 10 if omitted."},state:{type:"string",description:"(Optional) Filter by a specific state: running, waiting_approval, waiting_question, completed, failed, or idle. Omit to return all states."}}},validation:{required:[],properties:{}}},{name:"grix_chat_state_update",description:"Manually update the task state of a specific chat session. Use this to mark a chat as completed, failed, idle, or any other state when you need to override it manually. The reason is written to stop_reason and is optional.",inputSchema:{type:"object",properties:{session_id:{type:"string",description:"The session ID whose state to update."},state:{type:"string",enum:["running","waiting_approval","waiting_question","completed","failed","idle"],description:"The new state to set. Must be one of: running, waiting_approval, waiting_question, completed, failed, idle."},reason:{type:"string",description:"(Optional) Reason for the state change, written to stop_reason."}}},validation:{required:["session_id","state"],properties:{}}}],d=[{name:"grix_reply",description:"Send a reply message to the specified session. Supports streaming in chunks; the frontend will automatically aggregate them into one complete message. Any content meant for the user \u2014 including your final conclusion at the end of a turn \u2014 MUST be sent through this tool; text written outside this tool is not delivered to the user.",inputSchema:{type:"object",properties:{event_id:{type:"string",description:"Associated event ID from the inbound event."},session_id:{type:"string",description:"Target session ID."},text:{type:"string",description:"Reply text content."},quoted_message_id:{type:"string",description:"Quoted message ID (optional)."},is_final:{type:"boolean",description:"Whether this is a stage-final reply. Advisory only \u2014 does not trigger event completion; completion is handled by the complete tool or Stop hook."}},required:["session_id","text"]},validation:{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"}}}},{name:"grix_complete",description:"Mark event processing as complete, notifying the backend that no more replies are expected.",inputSchema:{type:"object",properties:{event_id:{type:"string",description:"The event ID to complete."},status:{type:"string",enum:["responded","canceled","failed"],description:"Completion status."},msg:{type:"string",description:"Additional note (optional)."}},required:["event_id","status"]},validation:{required:["event_id","status"],properties:{event_id:{type:"string"},status:{type:"string",enum:["responded","canceled","failed"]},msg:{type:"string",maxLength:500}}}},{name:"grix_event_ack",description:"Acknowledge event receipt (usually done automatically by the Dispatcher; agents typically do not need to call this manually).",inputSchema:{type:"object",properties:{event_id:{type:"string",description:"The event ID to acknowledge."},session_id:{type:"string",description:"Session ID."}},required:["event_id"]},validation:{required:["event_id"],properties:{event_id:{type:"string"},session_id:{type:"string"}}}},{name:"grix_composing",description:'Set the "typing" indicator status for a session.',inputSchema:{type:"object",properties:{session_id:{type:"string",description:"Session ID."},active:{type:"boolean",description:"true = typing, false = stopped."},event_id:{type:"string",description:"Associated event ID (optional)."}},required:["session_id","active"]},validation:{required:["session_id","active"],properties:{session_id:{type:"string"},active:{type:"boolean"},event_id:{type:"string"}}}},{name:"grix_access_control",description:"Manage sender access control: pair approval, allow/remove senders, set policy.",inputSchema:{type:"object",properties:{action:{type:"string",enum:["pair_approve","pair_deny","allow_sender","remove_sender","set_policy"],description:"Access control action type."},code:{type:"string",description:"Pairing code (required for pair_approve/pair_deny)."},sender_id:{type:"string",description:"Sender ID (required for allow_sender/remove_sender)."},policy:{type:"string",enum:["allowlist","open","disabled"],description:"Access policy (required for set_policy)."}},required:["action"]},validation:{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"]}}}},{name:"grix_status",description:"Query the Grix connection status of the current MCP session.",inputSchema:{type:"object",properties:{}},validation:{required:[],properties:{}}}],p=[{name:"reply",description:"Send a visible message back to the chat for this grix-claude event.",inputSchema:{type:"object",properties:{text:{type:"string",description:"The visible reply text to send."},chat_id:{type:"string",description:"The target chat/session id from the <channel> tag."},event_id:{type:"string",description:"The Aibot event_id from the <channel> tag."},reply_to:{type:"string",description:"Optional message_id to quote instead of the inbound trigger message."},final:{type:"boolean",description:"Advisory flag only. It does not complete the event; completion is handled by complete tool or Stop hook."}},required:["chat_id","event_id","text"]}},{name:"complete",description:"Finish an event without sending a visible reply so the backend does not time out.",inputSchema:{type:"object",properties:{event_id:{type:"string",description:"The Aibot event_id from the <channel> tag."},status:{type:"string",enum:["responded","canceled","failed"]},msg:{type:"string"},code:{type:"string"}},required:["event_id","status"]}}],c=new Set(p.map(e=>e.name)),b=new Set(a.map(e=>e.name)),v=new Set(d.map(e=>e.name)),I=/([A-Za-z0-9._-]+:[A-Za-z0-9._-]+:[A-Za-z0-9._-]+:[A-Za-z0-9._-]+)/,w=/[A-Za-z0-9._-]+/;function z(e){return!!(b.has(e)||v.has(e)||c.has(e)||e.startsWith("mcp__grix"))}const k=[...a,...d],x=[...k,...p],P=new Map(x.map(e=>[e.name,e]));function R(e,t){return e==="reply"?{name:"grix_reply",args:_("grix_reply",{event_id:t.event_id,session_id:t.chat_id,text:t.text,quoted_message_id:t.reply_to,is_final:t.final})}:e==="complete"?{name:"grix_complete",args:_("grix_complete",{event_id:t.event_id,status:t.status,msg:t.msg,code:t.code})}:{name:e,args:t}}function l(e){const t=String(e??"").trim();return t?t.match(I)?.[1]:void 0}function u(e){const t=String(e??"").trim();if(!t)return;const n=l(t);if(n)return m(n);const i=t.match(/(?:chat_id|session_id)\s*=\s*"([A-Za-z0-9._-]+)"/)?.[1];if(i)return i;const o=t.match(/[A-Za-z0-9._-]+/g)??[];for(const s of o)if(!(s==="event_id"||s==="chat_id"||s==="session_id")&&s.length>0)return s;return t.match(w)?.[0]}function m(e){if(!e)return;const t=e.split(":",1)[0]?.trim();if(t)return u(t)}function _(e,t){if(e!=="grix_reply"&&e!=="grix_complete")return t;const n={...t},i=l(n.event_id);if(i&&(n.event_id=i),e==="grix_reply"){const o=m(i),r=String(n.session_id??""),s=u(n.session_id),f=/\bevent_id\b|["'<>\s]/.test(r);s&&!(f&&o)?n.session_id=s:o&&(n.session_id=o)}return n}function U(e){return c.has(e)}function G(e,t){switch(e){case"grix_query":return S(t);case"grix_group":return A(t);case"grix_message_send":return q(t);case"grix_message_unsend":return T(t);case"grix_file_link":return M(t);case"grix_admin":return C(t);case"grix_call_owner":return O(t);case"grix_agent_update":return D(t);case"grix_dispatch_agent":return E(t);case"grix_session_send":return L(t);case"grix_chat_state_query":return N(t);case"grix_chat_state_update":return j(t);default:throw new Error(`Unknown tool: ${e}`)}}const g={contact_search:"contact_search",session_search:"session_search",message_history:"message_history",message_search:"message_search"};function S(e){const t=String(e.action??""),n=g[t];if(!n)throw new Error(`Unknown grix_query action: ${t}`);const i={};return e.id!=null&&(i.id=e.id),e.keyword!=null&&(i.keyword=e.keyword),e.limit!=null&&(i.limit=e.limit),e.offset!=null&&(i.offset=e.offset),e.sessionId!=null&&(i.session_id=e.sessionId),e.beforeId!=null&&(i.before_id=e.beforeId),{action:n,params:i}}const y={create:"group_create",detail:"group_detail_read",leave:"group_leave_self",add_members:"group_member_add",remove_members:"group_member_remove",update_member_role:"group_member_role_update",update_all_members_muted:"group_all_members_muted_update",update_member_speaking:"group_member_speaking_update",dissolve:"group_dissolve"};function A(e){const t=String(e.action??""),n=y[t];if(!n)throw new Error(`Unknown grix_group action: ${t}`);const i={};return e.sessionId!=null&&(i.session_id=e.sessionId),e.name!=null&&(i.name=e.name),e.memberIds!=null&&(i.member_ids=e.memberIds),e.memberTypes!=null&&(i.member_types=e.memberTypes),e.memberId!=null&&(i.member_id=e.memberId),e.role!=null&&(i.role=e.role),e.memberType!=null&&(i.member_type=e.memberType),e.allMembersMuted!=null&&(i.all_members_muted=e.allMembersMuted),e.isSpeakMuted!=null&&(i.is_speak_muted=e.isSpeakMuted),e.canSpeakWhenAllMuted!=null&&(i.can_speak_when_all_muted=e.canSpeakWhenAllMuted),{action:n,params:i}}function q(e){const t={session_id:e.sessionId,msg_type:e.msgType??1,content:e.content};return e.quotedMessageId!=null&&(t.quoted_message_id=e.quotedMessageId),e.threadId!=null&&(t.thread_id=e.threadId),{action:"send_msg",params:t}}function T(e){return{action:"delete_msg",params:{session_id:e.sessionId,msg_id:e.msgId}}}function M(e){const t={file_path:e.file_path};return e.ttl_ms!=null&&(t.ttl_ms=e.ttl_ms),{action:"file_link",params:t}}const h={create_agent:"agent_api_create",list_categories:"agent_category_list",create_category:"agent_category_create",update_category:"agent_category_update",assign_category:"agent_category_assign",rotate_api_key:"agent_api_key_rotate"};function O(e){return{action:"call_owner",params:{session_id:e.session_id}}}function D(e){return{action:"agent_introduction_update",params:{agent_id:e.agent_id,introduction:e.introduction}}}function E(e){return{action:"dispatch_agent",params:{agent_id:e.agent_id,cwd:e.cwd,task:e.task}}}function L(e){return{action:"session_send",params:{session_id:e.session_id,content:e.content}}}function N(e){const t={};return e.page!=null&&(t.page=e.page),e.page_size!=null&&(t.page_size=e.page_size),e.state!=null&&(t.state=e.state),{action:"chat_state_query",params:t}}function j(e){const t={session_id:e.session_id,state:e.state};return e.reason!=null&&(t.reason=e.reason),{action:"chat_state_update",params:t}}function C(e){const t=String(e.action??""),n=h[t];if(!n)throw new Error(`Unknown grix_admin action: ${t}`);const i={};return e.agentName!=null&&(i.agent_name=e.agentName),e.introduction!=null&&(i.introduction=e.introduction),e.isMain!=null&&(i.is_main=e.isMain),e.agentId!=null&&(i.agent_id=e.agentId),e.categoryId!=null&&(i.category_id=e.categoryId),e.name!=null&&(i.name=e.name),e.parentId!=null&&(i.parent_id=e.parentId),e.sortOrder!=null&&(i.sort_order=e.sortOrder),{action:n,params:i}}const W=new Set([...Object.values(g),...Object.values(y),...Object.values(h),"send_msg","delete_msg","file_link","call_owner","agent_introduction_update","dispatch_agent","session_send","chat_state_query","chat_state_update"]),Q={pair_approve:"pair_approve",pair_deny:"pair_deny",allow_sender:"sender_allow",remove_sender:"sender_remove",set_policy:"policy_set"};export{Q as ACCESS_CONTROL_ACTION_MAP,k as ALL_TOOLS,d as EVENT_TOOLS,x as EXPOSED_TOOLS,W as PHASE1_INVOKE_ACTIONS,b as PHASE1_TOOL_NAMES,v as PHASE2_TOOL_NAMES,a as TOOLS,p as TOOL_ALIASES,P as TOOL_MAP,U as isAlias,z as isGrixInternalToolName,R as mapToolAlias,_ as normalizeEventToolArgs,G as toolCallToInvoke};
@@ -1,2 +1,2 @@
1
- import{execFile as l}from"node:child_process";import{promisify as u}from"node:util";const m=3e3;async function p(i){const o=u(l),s=process.platform==="win32"?"where":"which";try{const{stdout:c}=await o(s,[i],{timeout:3e3,encoding:"utf-8"}),r=c.trim().split(/\r?\n/).map(t=>t.trim()).filter(Boolean);if(r.length===0)return null;if(process.platform==="win32"){const t=r.find(n=>/\.(cmd|bat)$/i.test(n));if(t)return t;const e=r.find(n=>/\.exe$/i.test(n));if(e)return e}return r[0]}catch{return null}}async function h(i,o=["--version"],s=m){const c=u(l),r=process.platform==="win32";try{const{stdout:t,stderr:e}=await c(i,o,{timeout:s,encoding:"utf-8",...r?{shell:!0}:{}});return{version:(t||e||"").trim().split(`
2
- `)[0]?.trim()||null||null}}catch(t){const e=t;return e.killed||e.code==="ETIMEDOUT"?{version:null,error:{code:"version_timeout",message:"version check timed out"}}:{version:null,error:{code:"cli_error",message:e.message??String(t)}}}}export{h as getCliVersion,p as resolveCliPath};
1
+ import{execFile as u}from"node:child_process";import{existsSync as w}from"node:fs";import{join as h,dirname as x,delimiter as m}from"node:path";import{promisify as f}from"node:util";import{log as d}from"../log/logger.js";const g=3e3;function y(t,r){const e=[".cmd",".bat",".exe",""];for(const o of t)if(o)for(const i of e){const n=h(o,`${r}${i}`);if(w(n))return n}return null}let c=null;const v=1e4;function M(){c=null}async function P(){if(c&&Date.now()-c.at<v)return c.dirs;const t=f(u),r=async o=>{try{const{stdout:i}=await t("powershell",["-NoProfile","-NonInteractive","-Command",`[Environment]::GetEnvironmentVariable('Path','${o}')`],{timeout:5e3,encoding:"utf-8",windowsHide:!0});return i.split(";").map(n=>n.trim()).filter(Boolean)}catch(i){return d.warn("cli-probe",`\u8BFB\u53D6\u6CE8\u518C\u8868 ${o} PATH \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),[]}},e=[...await r("User"),...await r("Machine")];return c={dirs:e,at:Date.now()},e}async function p(t){if(process.platform!=="win32")return null;const r=await P(),e=y(r,t);return e&&$(x(e)),e}function $(t){const r=process.env.PATH??"";r.split(m).some(o=>o.toLowerCase()===t.toLowerCase())||(process.env.PATH=r?`${t}${m}${r}`:t,d.info("cli-probe",`\u5DF2\u5C06 ${t} \u6CE8\u5165\u5F53\u524D\u8FDB\u7A0B PATH\uFF08\u5B89\u88C5\u540E\u81EA\u6108\uFF09`))}async function S(t){const r=f(u),e=process.platform==="win32",o=e?"where":"which";try{const{stdout:i}=await r(o,[t],{timeout:3e3,encoding:"utf-8"}),n=i.trim().split(/\r?\n/).map(s=>s.trim()).filter(Boolean);if(n.length>0){if(e){const s=n.find(l=>/\.(cmd|bat)$/i.test(l));if(s)return s;const a=n.find(l=>/\.exe$/i.test(l));return a||n[0]}return n[0]}return e?await p(t):null}catch{return e?await p(t):null}}async function W(t,r=["--version"],e=g){const o=f(u),i=process.platform==="win32";try{const n=i&&/\s/.test(t)&&!t.startsWith('"')?`"${t}"`:t,{stdout:s,stderr:a}=await o(n,r,{timeout:e,encoding:"utf-8",...i?{shell:!0}:{}});return{version:(s||a||"").trim().split(`
2
+ `)[0]?.trim()||null||null}}catch(n){const s=n;return s.killed||s.code==="ETIMEDOUT"?{version:null,error:{code:"version_timeout",message:"version check timed out"}}:{version:null,error:{code:"cli_error",message:s.message??String(n)}}}}export{y as findWindowsExecutableInDirs,W as getCliVersion,M as invalidateWindowsRegistryPathCache,S as resolveCliPath,p as resolveWindowsInstalledCli};
@@ -0,0 +1,55 @@
1
+ ---
2
+ name: grix-chat-state
3
+ description: Observe chat state — query the task state of all the owner's chats (`grix_chat_state_query`), and check the current MCP connection status (`grix_status`). Trigger when the user asks which chats are running/done/waiting, or to verify the Grix connection is healthy.
4
+ trigger: 当用户问哪些聊天任务在跑/已完成/在等待审批,或要确认 Grix 连接是否正常时
5
+ ---
6
+
7
+ # Grix Chat State & Status
8
+
9
+ Read-only observation of chat task state and connection state.
10
+
11
+ ## Chat task states — `grix_chat_state_query`
12
+
13
+ Query the task state across all the owner's chats (direct and group sessions).
14
+ Supports pagination and optional state filtering.
15
+
16
+ Parameters:
17
+ - `page` — page number, default 1
18
+ - `page_size` — items per page, default 10, max 100
19
+ - `state` — filter by state; omit to return all
20
+
21
+ Returns one entry per session with a single mutually-exclusive state:
22
+
23
+ - `running` — working
24
+ - `waiting_approval` — blocked on the owner to approve/deny
25
+ - `waiting_question` — asked the owner a question, awaiting reply
26
+ - `completed` / `failed` — finished
27
+ - `idle` — no task / stopped
28
+
29
+ Also returns `task_title` for easy identification of each chat.
30
+
31
+ Use it to see at a glance which chats are done, still running, or waiting on the
32
+ owner.
33
+
34
+ ## Connection status — `grix_status`
35
+
36
+ Query the Grix connection status of the current MCP session. Takes no
37
+ parameters. Use it to confirm the agent is connected before relying on other
38
+ grix tools.
39
+
40
+ ## Manually update a chat state — `grix_chat_state_update`
41
+
42
+ Override the task state of a specific chat session. Useful when you need to
43
+ mark a chat as done, failed, or idle outside of a normal task lifecycle.
44
+
45
+ Parameters:
46
+ - `session_id` — **(required)** the session to update
47
+ - `state` — **(required)** one of: `running`, `waiting_approval`, `waiting_question`, `completed`, `failed`, `idle`
48
+ - `reason` — **(optional)** reason for the change, written to `stop_reason`
49
+
50
+ ## Rules
51
+
52
+ 1. `grix_chat_state_query` is read-only — safe to call any time to orient yourself.
53
+ 2. `grix_chat_state_update` only updates existing records; it will error if the session has no prior state entry.
54
+ 3. `grix_chat_state_query` reports per-session state, not per-message; pair it with
55
+ `grix_query` (`message_history`) when you need the actual content.
@@ -1 +1 @@
1
- function a(t){const o=new Set([`http://127.0.0.1:${t.serverPort}`,`http://localhost:${t.serverPort}`,...t.allowedOrigins]),e=new Set([`127.0.0.1:${t.serverPort}`,`localhost:${t.serverPort}`,...t.allowedHosts]);return{validateRequest(s){const r=i(s,o);if(!r.ok)return r;const n=l(s,e);return n.ok?{ok:!0}:n}}}function i(t,o){const e=t.headers.origin;return e?o.has(e)?{ok:!0}:{ok:!1,statusCode:403,message:`Origin not allowed: ${e}`}:{ok:!0}}function l(t,o){const e=t.headers.host;return e?o.has(e)?{ok:!0}:{ok:!1,statusCode:403,message:`Host not allowed: ${e}`}:{ok:!1,statusCode:403,message:"Missing Host header"}}export{a as createSecurityPolicy};
1
+ function a(o){const e=new Set([`http://127.0.0.1:${o.serverPort}`,`http://localhost:${o.serverPort}`,...o.allowedOrigins]),t=new Set([`127.0.0.1:${o.serverPort}`,`localhost:${o.serverPort}`,...o.allowedHosts]);return{validateRequest(s){const r=i(s,e);if(!r.ok)return r;const n=l(s,t);return n.ok?{ok:!0}:n}}}function i(o,e){const t=o.headers.origin;return t?e.has(t)?{ok:!0}:{ok:!1,statusCode:403,message:`Origin not allowed: ${t}`}:{ok:!0}}function l(o,e){const t=o.headers.host;return t?e.has(t)?{ok:!0}:{ok:!1,statusCode:403,message:`Host not allowed: ${t}`}:{ok:!1,statusCode:403,message:"Missing Host header"}}export{a as createSecurityPolicy};
@@ -9099,16 +9099,40 @@ var TOOLS = [
9099
9099
  }
9100
9100
  },
9101
9101
  {
9102
- name: "grix_task_query",
9103
- description: "Query the session-level task states of all your owner's sessions. Takes no parameters \u2014 owner and agent are resolved from your authenticated connection. Returns one entry per session with a single mutually-exclusive state: running (working), waiting_approval (blocked on your owner to approve/deny), waiting_question (asked the owner a question, awaiting their reply), completed, failed, or idle (no task / stopped). Use this to see at a glance which tasks are done, still running, or waiting on the owner.",
9102
+ name: "grix_chat_state_query",
9103
+ description: "Query the chat-level task states across all of your owner's sessions (including direct and group chats). Returns one entry per session with a single mutually-exclusive state: running (working), waiting_approval (blocked on your owner to approve/deny), waiting_question (asked the owner a question, awaiting their reply), completed, failed, or idle (no task / stopped). Also returns the session title (task_title) for easy identification. Supports pagination (page/page_size) and optional state filtering. Use this to see at a glance which chats are done, still running, or waiting on the owner.",
9104
9104
  inputSchema: {
9105
9105
  type: "object",
9106
- properties: {}
9106
+ properties: {
9107
+ page: { type: "number", description: "(Optional) Page number, starting from 1. Defaults to 1 if omitted." },
9108
+ page_size: { type: "number", description: "(Optional) Number of items per page, max 100. Defaults to 10 if omitted." },
9109
+ state: { type: "string", description: "(Optional) Filter by a specific state: running, waiting_approval, waiting_question, completed, failed, or idle. Omit to return all states." }
9110
+ }
9107
9111
  },
9108
9112
  validation: {
9109
9113
  required: [],
9110
9114
  properties: {}
9111
9115
  }
9116
+ },
9117
+ {
9118
+ name: "grix_chat_state_update",
9119
+ description: "Manually update the task state of a specific chat session. Use this to mark a chat as completed, failed, idle, or any other state when you need to override it manually. The reason is written to stop_reason and is optional.",
9120
+ inputSchema: {
9121
+ type: "object",
9122
+ properties: {
9123
+ session_id: { type: "string", description: "The session ID whose state to update." },
9124
+ state: {
9125
+ type: "string",
9126
+ enum: ["running", "waiting_approval", "waiting_question", "completed", "failed", "idle"],
9127
+ description: "The new state to set. Must be one of: running, waiting_approval, waiting_question, completed, failed, idle."
9128
+ },
9129
+ reason: { type: "string", description: "(Optional) Reason for the state change, written to stop_reason." }
9130
+ }
9131
+ },
9132
+ validation: {
9133
+ required: ["session_id", "state"],
9134
+ properties: {}
9135
+ }
9112
9136
  }
9113
9137
  ];
9114
9138
  var EVENT_TOOLS = [
@@ -9297,8 +9321,10 @@ function toolCallToInvoke(toolName, args) {
9297
9321
  return buildDispatchAgentInvoke(args);
9298
9322
  case "grix_session_send":
9299
9323
  return buildSessionSendInvoke(args);
9300
- case "grix_task_query":
9301
- return buildTaskQueryInvoke();
9324
+ case "grix_chat_state_query":
9325
+ return buildChatStateQueryInvoke(args);
9326
+ case "grix_chat_state_update":
9327
+ return buildChatStateUpdateInvoke(args);
9302
9328
  default:
9303
9329
  throw new Error(`Unknown tool: ${toolName}`);
9304
9330
  }
@@ -9397,8 +9423,20 @@ function buildSessionSendInvoke(args) {
9397
9423
  params: { session_id: args.session_id, content: args.content }
9398
9424
  };
9399
9425
  }
9400
- function buildTaskQueryInvoke() {
9401
- return { action: "agent_task_query", params: {} };
9426
+ function buildChatStateQueryInvoke(args) {
9427
+ const params = {};
9428
+ if (args.page != null) params.page = args.page;
9429
+ if (args.page_size != null) params.page_size = args.page_size;
9430
+ if (args.state != null) params.state = args.state;
9431
+ return { action: "chat_state_query", params };
9432
+ }
9433
+ function buildChatStateUpdateInvoke(args) {
9434
+ const params = {
9435
+ session_id: args.session_id,
9436
+ state: args.state
9437
+ };
9438
+ if (args.reason != null) params.reason = args.reason;
9439
+ return { action: "chat_state_update", params };
9402
9440
  }
9403
9441
  function buildAdminInvoke(args) {
9404
9442
  const action = String(args.action ?? "");
@@ -9426,7 +9464,8 @@ var PHASE1_INVOKE_ACTIONS = /* @__PURE__ */ new Set([
9426
9464
  "agent_introduction_update",
9427
9465
  "dispatch_agent",
9428
9466
  "session_send",
9429
- "agent_task_query"
9467
+ "chat_state_query",
9468
+ "chat_state_update"
9430
9469
  ]);
9431
9470
 
9432
9471
  // src/openclaw/admin/json-result.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grix-connector",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
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",