blun-king-cli 9.1.471 → 9.1.472

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,4 +1,5 @@
1
1
  const AGENT_TURNS_PATH = '/v1/agent/turns';
2
+ const AGENT_SESSIONS_PATH = '/v1/agent/sessions';
2
3
  const PUBLIC_MODEL_ID = 'king';
3
4
  const PUBLIC_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/u;
4
5
 
@@ -70,9 +71,26 @@ function decodeRequestId(value) {
70
71
  return requirePublicId(decoded, 'request ID');
71
72
  }
72
73
 
74
+ function decodeSessionId(value) {
75
+ let decoded;
76
+ try {
77
+ decoded = decodeURIComponent(value);
78
+ } catch {
79
+ throw adapterError('AGENT_API_INVALID_ID', 'session ID is not valid URL encoding');
80
+ }
81
+ return requirePublicId(decoded, 'session ID');
82
+ }
83
+
73
84
  function routeFor(method, rawPath) {
74
85
  const path = String(rawPath ?? '').split('?', 1)[0];
75
86
  if (method === 'POST' && path === AGENT_TURNS_PATH) return { kind: 'start' };
87
+ if (path.startsWith(`${AGENT_SESSIONS_PATH}/`)) {
88
+ const tail = path.slice(AGENT_SESSIONS_PATH.length + 1);
89
+ if (method === 'DELETE' && !tail.includes('/')) {
90
+ return { kind: 'closeSession', sessionId: decodeSessionId(tail) };
91
+ }
92
+ return { kind: 'unknown' };
93
+ }
76
94
  if (!path.startsWith(`${AGENT_TURNS_PATH}/`)) {
77
95
  if (path.startsWith('/v1/agent/')) return { kind: 'unknown' };
78
96
  return null;
@@ -207,8 +225,19 @@ function createAgentApiHttpAdapter(options = {}) {
207
225
  if (typeof options.resolveSession !== 'function') {
208
226
  throw new TypeError('resolveSession must be a function');
209
227
  }
228
+ if (typeof options.closeSession !== 'function') {
229
+ throw new TypeError('closeSession must be a function');
230
+ }
210
231
  const owners = new Map();
211
232
 
233
+ function hasActiveOwner(principalId, sessionId) {
234
+ const prefix = `${sessionId}\0`;
235
+ for (const [key, scopeOwners] of owners) {
236
+ if (key.startsWith(prefix) && scopeOwners.has(principalId)) return true;
237
+ }
238
+ return false;
239
+ }
240
+
212
241
  function requireOwner(principalId, sessionId, requestId) {
213
242
  const key = scopeKey(sessionId, requestId);
214
243
  const scopeOwners = owners.get(key);
@@ -313,6 +342,31 @@ function createAgentApiHttpAdapter(options = {}) {
313
342
  });
314
343
  }
315
344
 
345
+ async function handleCloseSession(principalId, sessionId) {
346
+ if (hasActiveOwner(principalId, sessionId)) {
347
+ throw adapterError(
348
+ 'AGENT_API_SESSION_BUSY',
349
+ 'Agent session has an active turn.',
350
+ 409,
351
+ );
352
+ }
353
+ const closed = await options.closeSession({ principalId, sessionId });
354
+ if (closed !== true) {
355
+ throw adapterError(
356
+ 'AGENT_API_SESSION_NOT_FOUND',
357
+ 'Agent session was not found.',
358
+ 404,
359
+ );
360
+ }
361
+ return jsonResponse(200, {
362
+ id: `agent-session-${sessionId}`,
363
+ object: 'agent.session.closed',
364
+ model: PUBLIC_MODEL_ID,
365
+ session_id: sessionId,
366
+ closed: true,
367
+ });
368
+ }
369
+
316
370
  async function handleRequest(input) {
317
371
  if (input === null || typeof input !== 'object') return null;
318
372
  const method = String(input.method ?? '').toUpperCase();
@@ -331,6 +385,9 @@ function createAgentApiHttpAdapter(options = {}) {
331
385
  }
332
386
  const principalId = requireTrustedId(input.principalId, 'principalId');
333
387
  if (route.kind === 'start') return await handleStart(input, principalId);
388
+ if (route.kind === 'closeSession') {
389
+ return await handleCloseSession(principalId, route.sessionId);
390
+ }
334
391
  if (route.kind === 'continue') {
335
392
  return await handleContinue(input, principalId, route.requestId);
336
393
  }
@@ -344,6 +401,7 @@ function createAgentApiHttpAdapter(options = {}) {
344
401
  }
345
402
 
346
403
  export {
404
+ AGENT_SESSIONS_PATH,
347
405
  AGENT_TURNS_PATH,
348
406
  AgentApiHttpAdapterError,
349
407
  PUBLIC_MODEL_ID,
@@ -125,6 +125,7 @@ function createAgentApiServiceHost(options = {}) {
125
125
  const adapter = createAgentApiHttpAdapter({
126
126
  controller,
127
127
  resolveSession: sessionRegistry.resolveSession,
128
+ closeSession: sessionRegistry.closeSession,
128
129
  });
129
130
  const privateServer = createAgentApiPrivateHttpServer({
130
131
  adapter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.471",
3
+ "version": "9.1.472",
4
4
  "description": "BLUN CLI - your own AI agent with a Telegram channel. Get it done. With BLUN.",
5
5
  "license": "MIT",
6
6
  "bin": {