shennian 0.3.20 → 0.3.22

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.
@@ -506,8 +506,8 @@
506
506
  },
507
507
  {
508
508
  "file": "src/room/room-action-schema.js",
509
- "beforeBytes": 6700,
510
- "afterBytes": 3171
509
+ "beforeBytes": 6434,
510
+ "afterBytes": 3065
511
511
  },
512
512
  {
513
513
  "file": "src/room/room-authorized-action-executor.js",
@@ -516,8 +516,8 @@
516
516
  },
517
517
  {
518
518
  "file": "src/room/room-binding-client.js",
519
- "beforeBytes": 6716,
520
- "afterBytes": 3894
519
+ "beforeBytes": 7028,
520
+ "afterBytes": 4032
521
521
  },
522
522
  {
523
523
  "file": "src/room/room-binding-ipc.js",
@@ -536,8 +536,8 @@
536
536
  },
537
537
  {
538
538
  "file": "src/room/tool-schema.js",
539
- "beforeBytes": 5149,
540
- "afterBytes": 3140
539
+ "beforeBytes": 5223,
540
+ "afterBytes": 3212
541
541
  },
542
542
  {
543
543
  "file": "src/room/tool-server.js",
@@ -581,8 +581,8 @@
581
581
  },
582
582
  {
583
583
  "file": "src/session/handlers/room-managed.js",
584
- "beforeBytes": 3173,
585
- "afterBytes": 1972
584
+ "beforeBytes": 3724,
585
+ "afterBytes": 2153
586
586
  },
587
587
  {
588
588
  "file": "src/session/handlers/session-refresh.js",
@@ -1 +1 @@
1
- import{randomUUID as g}from"node:crypto";import{DaemonIpcError as u}from"../daemon-ipc/protocol.js";function D(t,n){const e=y(n);switch(t){case"room.status":return d(e,[]),{};case"room.read":{d(e,["afterSequence","limit","attachmentIds","query"]);const o=a(e.query,"query",200),i=e.afterSequence??"0",s=e.limit??50;(typeof i!="string"||!/^(0|[1-9]\d{0,19})$/.test(i))&&r("afterSequence"),(typeof s!="number"||!Number.isInteger(s)||s<1||s>100)&&r("limit");const m=p(e.attachmentIds,"attachmentIds",10);return o&&(e.afterSequence!=null||m)&&r("parameters"),o?{query:o,limit:s}:{afterSequence:i,limit:s,...m?{attachmentIds:m}:{}}}case"room.send":{d(e,["clientMessageId","text","files","mentionMembershipIds","replyToMessageId"]);const o=e.clientMessageId==null?`room-tool-${g()}`:c(e.clientMessageId,"clientMessageId",191),i=a(e.text,"text",2e4),s=h(e.files,"files",10);!i&&!s&&r("parameters");const m=p(e.mentionMembershipIds,"mentionMembershipIds",20),l=a(e.replyToMessageId,"replyToMessageId",191);return{clientMessageId:o,text:i??"",...s?{files:s}:{},...m?{mentionMembershipIds:m}:{},...l?{replyToMessageId:l}:{}}}case"room.mode":return d(e,["activationMode"]),{activationMode:f(e.activationMode)};case"room.create":return d(e,["name","agentAlias","agentDescription","activationMode"]),{name:c(e.name,"name",80),agentAlias:c(e.agentAlias,"agentAlias",80),...a(e.agentDescription,"agentDescription",1e3)?{agentDescription:a(e.agentDescription,"agentDescription",1e3)}:{},activationMode:f(e.activationMode??"auto_follow")};case"room.join":return d(e,["inviteUrl","agentAlias","agentDescription","message","activationMode"]),{inviteUrl:M(e.inviteUrl),agentAlias:c(e.agentAlias,"agentAlias",80),...a(e.agentDescription,"agentDescription",1e3)?{agentDescription:a(e.agentDescription,"agentDescription",1e3)}:{},activationMode:f(e.activationMode??"auto_follow"),...a(e.message,"message",500)?{message:a(e.message,"message",500)}:{}}}}function h(t,n,e){return t==null?void 0:((!Array.isArray(t)||t.length<1||t.length>e)&&r(n),t.map(i=>((typeof i!="string"||!i.trim()||i.length>4096||/[\0\r\n]/.test(i))&&r(n),i.trim())))}function y(t){return t==null?{}:((Array.isArray(t)||typeof t!="object")&&r("parameters"),t)}function d(t,n){const e=new Set(n);Object.keys(t).some(o=>!e.has(o))&&r("parameters")}function c(t,n,e){return(typeof t!="string"||!t.trim()||t.length>e||/[\0\r]/.test(t))&&r(n),t.trim()}function a(t,n,e){if(!(t==null||t===""))return c(t,n,e)}function p(t,n,e){if(t==null)return;(!Array.isArray(t)||t.length>e)&&r(n);const o=t.map(i=>c(i,n,191));return new Set(o).size!==o.length&&r(n),o.length>0?o:void 0}function f(t){if(t==="auto"||t==="auto_follow")return"auto_follow";if(t==="mention"||t==="mention_only")return"mention_only";if(t==="paused")return"paused";r("activationMode")}function M(t){const n=c(t,"inviteUrl",2048);let e;try{e=new URL(n)}catch{r("inviteUrl")}return(e.protocol!=="https:"||e.hostname!=="shennian.net"||!/^\/spaces\/join\/[A-Za-z0-9_-]{43}$/.test(e.pathname)||e.username||e.password||e.search||e.hash)&&r("inviteUrl"),e.toString()}function r(t){throw new u("invalid_params",`${t} is invalid.`)}export{D as normalizeRoomActionParameters};
1
+ import{randomUUID as g}from"node:crypto";import{DaemonIpcError as u}from"../daemon-ipc/protocol.js";function w(t,n){const e=y(n);switch(t){case"room.status":return m(e,[]),{};case"room.read":{m(e,["afterSequence","limit","attachmentIds","query"]);const o=d(e.query,"query",200),i=e.afterSequence??"0",s=e.limit??50;(typeof i!="string"||!/^(0|[1-9]\d{0,19})$/.test(i))&&r("afterSequence"),(typeof s!="number"||!Number.isInteger(s)||s<1||s>100)&&r("limit");const c=p(e.attachmentIds,"attachmentIds",10);return o&&(e.afterSequence!=null||c)&&r("parameters"),o?{query:o,limit:s}:{afterSequence:i,limit:s,...c?{attachmentIds:c}:{}}}case"room.send":{m(e,["clientMessageId","text","files","mentionMembershipIds","replyToMessageId"]);const o=e.clientMessageId==null?`room-tool-${g()}`:a(e.clientMessageId,"clientMessageId",191),i=d(e.text,"text",2e4),s=h(e.files,"files",10);!i&&!s&&r("parameters");const c=p(e.mentionMembershipIds,"mentionMembershipIds",20),l=d(e.replyToMessageId,"replyToMessageId",191);return{clientMessageId:o,text:i??"",...s?{files:s}:{},...c?{mentionMembershipIds:c}:{},...l?{replyToMessageId:l}:{}}}case"room.mode":return m(e,["activationMode"]),{activationMode:f(e.activationMode)};case"room.create":return m(e,["name","agentAlias","agentDescription","activationMode"]),{name:a(e.name,"name",80),agentAlias:a(e.agentAlias,"agentAlias",80),agentDescription:a(e.agentDescription,"agentDescription",1e3),activationMode:f(e.activationMode??"auto_follow")};case"room.join":return m(e,["inviteUrl","agentAlias","agentDescription","message","activationMode"]),{inviteUrl:M(e.inviteUrl),agentAlias:a(e.agentAlias,"agentAlias",80),agentDescription:a(e.agentDescription,"agentDescription",1e3),activationMode:f(e.activationMode??"auto_follow"),...d(e.message,"message",500)?{message:d(e.message,"message",500)}:{}}}}function h(t,n,e){return t==null?void 0:((!Array.isArray(t)||t.length<1||t.length>e)&&r(n),t.map(i=>((typeof i!="string"||!i.trim()||i.length>4096||/[\0\r\n]/.test(i))&&r(n),i.trim())))}function y(t){return t==null?{}:((Array.isArray(t)||typeof t!="object")&&r("parameters"),t)}function m(t,n){const e=new Set(n);Object.keys(t).some(o=>!e.has(o))&&r("parameters")}function a(t,n,e){return(typeof t!="string"||!t.trim()||t.length>e||/[\0\r]/.test(t))&&r(n),t.trim()}function d(t,n,e){if(!(t==null||t===""))return a(t,n,e)}function p(t,n,e){if(t==null)return;(!Array.isArray(t)||t.length>e)&&r(n);const o=t.map(i=>a(i,n,191));return new Set(o).size!==o.length&&r(n),o.length>0?o:void 0}function f(t){if(t==="auto"||t==="auto_follow")return"auto_follow";if(t==="mention"||t==="mention_only")return"mention_only";if(t==="paused")return"paused";r("activationMode")}function M(t){const n=a(t,"inviteUrl",2048);let e;try{e=new URL(n)}catch{r("inviteUrl")}return(e.protocol!=="https:"||e.hostname!=="shennian.net"||!/^\/spaces\/join\/[A-Za-z0-9_-]{43}$/.test(e.pathname)||e.username||e.password||e.search||e.hash)&&r("inviteUrl"),e.toString()}function r(t){throw new u("invalid_params",`${t} is invalid.`)}export{w as normalizeRoomActionParameters};
@@ -1 +1 @@
1
- import{HttpRoomActionClient as r}from"./room-action-client.js";class o extends Error{code;constructor(e,n){super(n),this.code=e,this.name="RoomBindingHttpError"}}class m{fetchImpl;baseUrl;actionClient;constructor(e,n=fetch){this.fetchImpl=n,this.baseUrl=e.replace(/\/+$/,""),this.actionClient=new r(e,n)}status=e=>this.actionClient.status(e);getAttachmentCapability=e=>this.actionClient.getAttachmentCapability(e);initializeAttachment=e=>this.actionClient.initializeAttachment(e);completeAttachment=e=>this.actionClient.completeAttachment(e);createRoom=e=>this.actionClient.createRoom(e);createOperatorRoom=e=>this.actionClient.createOperatorRoom(e);resolveNativeSession=e=>this.actionClient.resolveNativeSession(e);joinRoom=e=>this.actionClient.joinRoom(e);read=e=>this.actionClient.read(e);send=e=>this.actionClient.send(e);mode=e=>this.actionClient.mode(e);async create(e){let n;try{n=await this.fetchImpl(`${this.baseUrl}/api/rooms/${encodeURIComponent(e.roomId)}/bindings`,{method:"POST",headers:{authorization:`Bearer ${e.machineToken}`,"content-type":"application/json"},body:JSON.stringify({bindingIntentId:e.bindingIntentId,agentIdentityId:e.agentIdentityId,nianSessionId:e.nianSessionId,runtimeAdapter:e.runtimeAdapter,sessionRegistryKey:e.sessionRegistryKey,activationCapability:e.activationCapability,activationMode:e.activationMode}),signal:AbortSignal.timeout(1e4)})}catch{throw new o("room_binding_server_unavailable","Shennian Room service is unavailable.")}if(!n.ok){let i=`room_binding_http_${n.status}`;try{const s=await n.json();typeof s.error=="string"&&/^[a-z0-9_-]{1,80}$/.test(s.error)&&(i=s.error)}catch{}throw new o(i,"Shennian Room binding request failed.")}let t;try{t=await n.json()}catch{throw new o("invalid_room_binding_response","Invalid Room binding response.")}return d(t,e)}async restart(e){let n;try{n=await this.fetchImpl(`${this.baseUrl}/api/rooms/${encodeURIComponent(e.roomId)}/bindings/${encodeURIComponent(e.bindingId)}/session`,{method:"PATCH",headers:{authorization:`Bearer ${e.machineToken}`,"content-type":"application/json"},body:JSON.stringify({agentIdentityId:e.agentIdentityId,previousNianSessionId:e.previousNianSessionId,nianSessionId:e.nianSessionId,runtimeAdapter:e.runtimeAdapter,sessionRegistryKey:e.sessionRegistryKey}),signal:AbortSignal.timeout(1e4)})}catch{throw new o("room_binding_server_unavailable","Shennian Room service is unavailable.")}const t=await n.json().catch(()=>null);if(!n.ok){const s=t&&typeof t.error=="string"&&/^[a-z0-9_-]{1,80}$/.test(t.error)?t.error:`room_binding_http_${n.status}`;throw new o(s,"Shennian Room restart request failed.")}const i=t;if(!i?.binding||i.binding.id!==e.bindingId||i.binding.roomId!==e.roomId||i.binding.agentIdentityId!==e.agentIdentityId||i.binding.nianSessionId!==e.nianSessionId||i.binding.runtimeAdapter!==e.runtimeAdapter||typeof i.binding.agentMembershipId!="string"||typeof i.resumeSequence!="string"||!/^(0|[1-9]\d{0,19})$/.test(i.resumeSequence)||typeof i.idempotent!="boolean")throw new o("invalid_room_binding_response","Invalid Room restart response.");return{binding:i.binding,resumeSequence:i.resumeSequence,idempotent:i.idempotent}}}function d(a,e){if(!a||typeof a!="object")throw new o("invalid_room_binding_response","Invalid Room binding response.");const n=a,t=n.binding;if(!t||typeof t.id!="string"||typeof t.agentMembershipId!="string"||t.roomId!==e.roomId||t.agentIdentityId!==e.agentIdentityId||t.nianSessionId!==e.nianSessionId||t.runtimeAdapter!==e.runtimeAdapter||t.activationCapability!==e.activationCapability||t.activationMode!==e.activationMode||!["pending_approval","active","paused","detached"].includes(t.status??"")||typeof n.idempotent!="boolean")throw new o("invalid_room_binding_response","Room binding response does not match the request.");return{binding:t,idempotent:n.idempotent}}export{m as HttpRoomBindingClient,o as RoomBindingHttpError};
1
+ import{HttpRoomActionClient as r}from"./room-action-client.js";class a extends Error{code;constructor(e,n){super(n),this.code=e,this.name="RoomBindingHttpError"}}class l{fetchImpl;baseUrl;actionClient;constructor(e,n=fetch){this.fetchImpl=n,this.baseUrl=e.replace(/\/+$/,""),this.actionClient=new r(e,n)}status=e=>this.actionClient.status(e);getAttachmentCapability=e=>this.actionClient.getAttachmentCapability(e);initializeAttachment=e=>this.actionClient.initializeAttachment(e);completeAttachment=e=>this.actionClient.completeAttachment(e);createRoom=e=>this.actionClient.createRoom(e);createOperatorRoom=e=>this.actionClient.createOperatorRoom(e);resolveNativeSession=e=>this.actionClient.resolveNativeSession(e);joinRoom=e=>this.actionClient.joinRoom(e);read=e=>this.actionClient.read(e);send=e=>this.actionClient.send(e);mode=e=>this.actionClient.mode(e);async create(e){let n;try{n=await this.fetchImpl(`${this.baseUrl}/api/rooms/${encodeURIComponent(e.roomId)}/bindings`,{method:"POST",headers:{authorization:`Bearer ${e.machineToken}`,"content-type":"application/json"},body:JSON.stringify({bindingIntentId:e.bindingIntentId,agentIdentityId:e.agentIdentityId,nianSessionId:e.nianSessionId,runtimeAdapter:e.runtimeAdapter,sessionRegistryKey:e.sessionRegistryKey,activationCapability:e.activationCapability,activationMode:e.activationMode}),signal:AbortSignal.timeout(1e4)})}catch{throw new a("room_binding_server_unavailable","Shennian Room service is unavailable.")}if(!n.ok){let i=`room_binding_http_${n.status}`;try{const s=await n.json();typeof s.error=="string"&&/^[a-z0-9_-]{1,80}$/.test(s.error)&&(i=s.error)}catch{}throw new a(i,"Shennian Room binding request failed.")}let t;try{t=await n.json()}catch{throw new a("invalid_room_binding_response","Invalid Room binding response.")}return d(t,e)}async restart(e){let n;try{n=await this.fetchImpl(`${this.baseUrl}/api/rooms/${encodeURIComponent(e.roomId)}/bindings/${encodeURIComponent(e.bindingId)}/session`,{method:"PATCH",headers:{authorization:`Bearer ${e.machineToken}`,"content-type":"application/json"},body:JSON.stringify({agentIdentityId:e.agentIdentityId,previousNianSessionId:e.previousNianSessionId,nianSessionId:e.nianSessionId,runtimeAdapter:e.runtimeAdapter,sessionRegistryKey:e.sessionRegistryKey}),signal:AbortSignal.timeout(1e4)})}catch{throw new a("room_binding_server_unavailable","Shennian Room service is unavailable.")}const t=await n.json().catch(()=>null);if(!n.ok){const s=t&&typeof t.error=="string"&&/^[a-z0-9_-]{1,80}$/.test(t.error)?t.error:`room_binding_http_${n.status}`;throw new a(s,"Shennian Room restart request failed.")}const i=t;if(!i?.binding||i.binding.id!==e.bindingId||i.binding.roomId!==e.roomId||i.binding.agentIdentityId!==e.agentIdentityId||i.binding.nianSessionId!==e.nianSessionId||i.binding.runtimeAdapter!==e.runtimeAdapter||typeof i.binding.agentMembershipId!="string"||typeof i.resumeSequence!="string"||!/^(0|[1-9]\d{0,19})$/.test(i.resumeSequence)||typeof i.idempotent!="boolean")throw new a("invalid_room_binding_response","Invalid Room restart response.");return{binding:i.binding,resumeSequence:i.resumeSequence,idempotent:i.idempotent}}}function d(o,e){if(!o||typeof o!="object")throw new a("invalid_room_binding_response","Invalid Room binding response.");const n=o,t=n.binding;if(!t||typeof t.id!="string"||typeof t.agentMembershipId!="string"||t.roomId!==e.roomId||t.agentIdentityId!==e.agentIdentityId||t.nianSessionId!==e.nianSessionId||t.runtimeAdapter!==e.runtimeAdapter||t.activationCapability!==e.activationCapability||!c(t.activationMode,e)||!["pending_approval","active","paused","detached"].includes(t.status??"")||typeof n.idempotent!="boolean")throw new a("invalid_room_binding_response","Room binding response does not match the request.");return{binding:t,idempotent:n.idempotent}}function c(o,e){return e.activationCapability==="managed"&&e.activationMode==="auto_follow"?o==="auto_follow"||o==="mention_only":o===e.activationMode}export{l as HttpRoomBindingClient,a as RoomBindingHttpError};
@@ -4,7 +4,7 @@ export declare const SHENNIAN_ROOM_TOOL_NAME = "shennian_room";
4
4
  export declare const SHENNIAN_ROOM_TOOL: {
5
5
  readonly name: "shennian_room";
6
6
  readonly title: "Shennian Room";
7
- readonly description: "Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session. Status includes member and Agent descriptions plus the canonical local JSONL mirror path.";
7
+ readonly description: "Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session. Creating or joining requires a non-empty Agent description. Status includes member and Agent descriptions plus the canonical local JSONL mirror path.";
8
8
  readonly inputSchema: {
9
9
  readonly type: "object";
10
10
  readonly additionalProperties: false;
@@ -27,6 +27,7 @@ export declare const SHENNIAN_ROOM_TOOL: {
27
27
  };
28
28
  readonly agentDescription: {
29
29
  readonly type: "string";
30
+ readonly minLength: 1;
30
31
  readonly maxLength: 1000;
31
32
  };
32
33
  readonly inviteUrl: {
@@ -1 +1 @@
1
- import{normalizeRoomActionParameters as c}from"./room-action-schema.js";const d="shennian_room",l={name:d,title:"Shennian Room",description:"Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session. Status includes member and Agent descriptions plus the canonical local JSONL mirror path.",inputSchema:{type:"object",additionalProperties:!1,required:["action"],properties:{action:{type:"string",enum:["create","join","read","send","mode","status"],description:"The Room action to perform."},name:{type:"string",minLength:1,maxLength:80},agentAlias:{type:"string",minLength:1,maxLength:80},agentDescription:{type:"string",maxLength:1e3},inviteUrl:{type:"string",format:"uri",maxLength:2048},message:{type:"string",maxLength:500},activationMode:{type:"string",enum:["auto","auto_follow","mention","mention_only","paused"]},afterSequence:{type:"string",pattern:"^(0|[1-9]\\d{0,19})$"},limit:{type:"integer",minimum:1,maximum:100},query:{type:"string",minLength:1,maxLength:200},attachmentIds:{type:"array",maxItems:10,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},clientMessageId:{type:"string",minLength:1,maxLength:191,description:"Optional idempotency key. Shennian generates one when omitted."},text:{type:"string",minLength:1,maxLength:2e4},files:{type:"array",description:"Up to 10 files inside the current Agent workspace to upload privately with this message.",minItems:1,maxItems:10,items:{type:"string",minLength:1,maxLength:4096}},mentionMembershipIds:{type:"array",maxItems:20,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},replyToMessageId:{type:"string",minLength:1,maxLength:191}}}},u=new Map([["create","room.create"],["join","room.join"],["read","room.read"],["send","room.send"],["mode","room.mode"],["status","room.status"]]);function f(i){(!i||typeof i!="object"||Array.isArray(i))&&g();const e=i,n=typeof e.action=="string"?u.get(e.action):void 0;n||g();const o=e._shennianRegistryKey,r=e._shennianInvocationToken,s=e._shennianAuthorizedActionId,a=Object.keys(e).filter(t=>t.startsWith("_shennian"));if(typeof s=="string"&&/^[A-Za-z0-9_-]{8,128}$/.test(s)&&a.length===1){const t=Object.fromEntries(Object.entries(e).filter(([m])=>m!=="action"&&m!=="_shennianAuthorizedActionId"));return{action:n,actionParameters:c(n,t),authorizedActionId:s}}if(typeof o!="string"||!/^[a-f0-9]{64}$/.test(o)||typeof r!="string"||!/^sni_v1_[A-Za-z0-9_-]{40,80}$/.test(r)||a.some(t=>t!=="_shennianRegistryKey"&&t!=="_shennianInvocationToken"))throw new p("session_context_required","The current Agent session is not connected to Shennian Room yet.");const h=Object.fromEntries(Object.entries(e).filter(([t])=>t!=="action"&&t!=="_shennianRegistryKey"&&t!=="_shennianInvocationToken"));return{action:n,actionParameters:c(n,h),registryKey:o,invocationToken:r}}class p extends Error{code;constructor(e,n){super(n),this.code=e,this.name="RoomToolInputError"}}function g(){throw new p("invalid_tool_input","Invalid Shennian Room tool input.")}export{p as RoomToolInputError,l as SHENNIAN_ROOM_TOOL,d as SHENNIAN_ROOM_TOOL_NAME,f as normalizeRoomToolInput};
1
+ import{normalizeRoomActionParameters as c}from"./room-action-schema.js";const d="shennian_room",l={name:d,title:"Shennian Room",description:"Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session. Creating or joining requires a non-empty Agent description. Status includes member and Agent descriptions plus the canonical local JSONL mirror path.",inputSchema:{type:"object",additionalProperties:!1,required:["action"],properties:{action:{type:"string",enum:["create","join","read","send","mode","status"],description:"The Room action to perform."},name:{type:"string",minLength:1,maxLength:80},agentAlias:{type:"string",minLength:1,maxLength:80},agentDescription:{type:"string",minLength:1,maxLength:1e3},inviteUrl:{type:"string",format:"uri",maxLength:2048},message:{type:"string",maxLength:500},activationMode:{type:"string",enum:["auto","auto_follow","mention","mention_only","paused"]},afterSequence:{type:"string",pattern:"^(0|[1-9]\\d{0,19})$"},limit:{type:"integer",minimum:1,maximum:100},query:{type:"string",minLength:1,maxLength:200},attachmentIds:{type:"array",maxItems:10,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},clientMessageId:{type:"string",minLength:1,maxLength:191,description:"Optional idempotency key. Shennian generates one when omitted."},text:{type:"string",minLength:1,maxLength:2e4},files:{type:"array",description:"Up to 10 files inside the current Agent workspace to upload privately with this message.",minItems:1,maxItems:10,items:{type:"string",minLength:1,maxLength:4096}},mentionMembershipIds:{type:"array",maxItems:20,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},replyToMessageId:{type:"string",minLength:1,maxLength:191}}}},u=new Map([["create","room.create"],["join","room.join"],["read","room.read"],["send","room.send"],["mode","room.mode"],["status","room.status"]]);function f(i){(!i||typeof i!="object"||Array.isArray(i))&&g();const e=i,n=typeof e.action=="string"?u.get(e.action):void 0;n||g();const o=e._shennianRegistryKey,r=e._shennianInvocationToken,s=e._shennianAuthorizedActionId,a=Object.keys(e).filter(t=>t.startsWith("_shennian"));if(typeof s=="string"&&/^[A-Za-z0-9_-]{8,128}$/.test(s)&&a.length===1){const t=Object.fromEntries(Object.entries(e).filter(([m])=>m!=="action"&&m!=="_shennianAuthorizedActionId"));return{action:n,actionParameters:c(n,t),authorizedActionId:s}}if(typeof o!="string"||!/^[a-f0-9]{64}$/.test(o)||typeof r!="string"||!/^sni_v1_[A-Za-z0-9_-]{40,80}$/.test(r)||a.some(t=>t!=="_shennianRegistryKey"&&t!=="_shennianInvocationToken"))throw new p("session_context_required","The current Agent session is not connected to Shennian Room yet.");const h=Object.fromEntries(Object.entries(e).filter(([t])=>t!=="action"&&t!=="_shennianRegistryKey"&&t!=="_shennianInvocationToken"));return{action:n,actionParameters:c(n,h),registryKey:o,invocationToken:r}}class p extends Error{code;constructor(e,n){super(n),this.code=e,this.name="RoomToolInputError"}}function g(){throw new p("invalid_tool_input","Invalid Shennian Room tool input.")}export{p as RoomToolInputError,l as SHENNIAN_ROOM_TOOL,d as SHENNIAN_ROOM_TOOL_NAME,f as normalizeRoomToolInput};
@@ -1 +1 @@
1
- const c=/^[A-Za-z0-9_.:@/-]{1,191}$/,S=new Set(["roomId","agentIdentityId","nianSessionId","assignmentIntentId"]),y=new Set(["roomId","bindingId","agentIdentityId","previousNianSessionId","nianSessionId","assignmentIntentId"]);async function w(e,t,n){if(!t)throw new Error("Managed Room binding is unavailable.");if(Object.keys(n.params).some(a=>!S.has(a)))throw new Error("Managed Room binding contains unsupported parameters.");const d=s(n.params.roomId,"roomId"),r=s(n.params.agentIdentityId,"agentIdentityId"),i=s(n.params.nianSessionId,"nianSessionId"),I=s(n.params.assignmentIntentId,"assignmentIntentId"),o=e.sessions.get(i);if(!o?.agentSessionId)throw new Error("The exact native Agent session is not ready for Room binding.");const g=await t.bind({roomId:d,agentIdentityId:r,nianSessionId:i,assignmentIntentId:I,agentSessionId:o.agentSessionId,workDir:o.workDir,agentType:o.agentType});e.client.sendRes({type:"res",id:n.id,ok:!0,payload:g})}async function u(e,t,n){if(!t)throw new Error("Managed Room binding is unavailable.");if(Object.keys(n.params).some(p=>!y.has(p)))throw new Error("Managed Room restart contains unsupported parameters.");const d=s(n.params.roomId,"roomId"),r=s(n.params.bindingId,"bindingId"),i=s(n.params.agentIdentityId,"agentIdentityId"),I=s(n.params.previousNianSessionId,"previousNianSessionId"),o=s(n.params.nianSessionId,"nianSessionId"),g=s(n.params.assignmentIntentId,"assignmentIntentId"),a=e.sessions.get(o);if(!a?.agentSessionId)throw new Error("The replacement native Agent session is not ready for Room binding.");const m=await t.restart({roomId:d,bindingId:r,agentIdentityId:i,previousNianSessionId:I,nianSessionId:o,assignmentIntentId:g,agentSessionId:a.agentSessionId,workDir:a.workDir,agentType:a.agentType});e.client.sendRes({type:"res",id:n.id,ok:!0,payload:m})}function s(e,t){if(typeof e!="string"||!c.test(e))throw new Error(`Invalid ${t}.`);return e}export{w as handleManagedRoomBind,u as handleManagedRoomRestart};
1
+ const p=/^[A-Za-z0-9_.:@/-]{1,191}$/,E=45e3,_=25,w=new Set(["roomId","agentIdentityId","nianSessionId","assignmentIntentId"]),y=new Set(["roomId","bindingId","agentIdentityId","previousNianSessionId","nianSessionId","assignmentIntentId"]);async function R(s,e,n){if(!e)throw new Error("Managed Room binding is unavailable.");if(Object.keys(n.params).some(i=>!w.has(i)))throw new Error("Managed Room binding contains unsupported parameters.");const o=t(n.params.roomId,"roomId"),d=t(n.params.agentIdentityId,"agentIdentityId"),r=t(n.params.nianSessionId,"nianSessionId"),I=t(n.params.assignmentIntentId,"assignmentIntentId"),a=await S(s,r);if(!a?.agentSessionId)throw new Error("The exact native Agent session is not ready for Room binding.");const g=await e.bind({roomId:o,agentIdentityId:d,nianSessionId:r,assignmentIntentId:I,agentSessionId:a.agentSessionId,workDir:a.workDir,agentType:a.agentType});s.client.sendRes({type:"res",id:n.id,ok:!0,payload:g})}async function u(s,e,n){if(!e)throw new Error("Managed Room binding is unavailable.");if(Object.keys(n.params).some(c=>!y.has(c)))throw new Error("Managed Room restart contains unsupported parameters.");const o=t(n.params.roomId,"roomId"),d=t(n.params.bindingId,"bindingId"),r=t(n.params.agentIdentityId,"agentIdentityId"),I=t(n.params.previousNianSessionId,"previousNianSessionId"),a=t(n.params.nianSessionId,"nianSessionId"),g=t(n.params.assignmentIntentId,"assignmentIntentId"),i=await S(s,a);if(!i?.agentSessionId)throw new Error("The replacement native Agent session is not ready for Room binding.");const m=await e.restart({roomId:o,bindingId:d,agentIdentityId:r,previousNianSessionId:I,nianSessionId:a,assignmentIntentId:g,agentSessionId:i.agentSessionId,workDir:i.workDir,agentType:i.agentType});s.client.sendRes({type:"res",id:n.id,ok:!0,payload:m})}function t(s,e){if(typeof s!="string"||!p.test(s))throw new Error(`Invalid ${e}.`);return s}async function S(s,e){const n=Date.now()+45e3;let o=s.sessions.get(e);for(;o&&!o.agentSessionId&&Date.now()<n;)await new Promise(d=>setTimeout(d,25)),o=s.sessions.get(e);return o}export{R as handleManagedRoomBind,u as handleManagedRoomRestart};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.3.20",
3
+ "version": "0.3.22",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {