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.
- package/dist/publish-build-manifest.json +8 -8
- package/dist/src/room/room-action-schema.js +1 -1
- package/dist/src/room/room-binding-client.js +1 -1
- package/dist/src/room/tool-schema.d.ts +2 -1
- package/dist/src/room/tool-schema.js +1 -1
- package/dist/src/session/handlers/room-managed.js +1 -1
- package/package.json +1 -1
|
@@ -506,8 +506,8 @@
|
|
|
506
506
|
},
|
|
507
507
|
{
|
|
508
508
|
"file": "src/room/room-action-schema.js",
|
|
509
|
-
"beforeBytes":
|
|
510
|
-
"afterBytes":
|
|
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":
|
|
520
|
-
"afterBytes":
|
|
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":
|
|
540
|
-
"afterBytes":
|
|
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":
|
|
585
|
-
"afterBytes":
|
|
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
|
|
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
|
|
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
|
|
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};
|