shennian 0.2.49 → 0.2.50

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.
@@ -283,7 +283,7 @@ export async function handleChatSend(runtime, req) {
283
283
  return;
284
284
  }
285
285
  rememberProcessedReqId(runtime, req.id);
286
- const { sessionId, text, agentType, workDir, agentSessionId: incomingAgentSid, modelId, clientMessageId, sessionListProjection } = req.params;
286
+ const { sessionId, text, agentType, workDir, agentSessionId: incomingAgentSid, modelId, clientMessageId, sessionListProjection, waitForDispatch } = req.params;
287
287
  mergeProjectedSessions(sessionListProjection);
288
288
  if (!sessionId || !text) {
289
289
  runtime.processedReqIds.delete(req.id);
@@ -354,23 +354,6 @@ export async function handleChatSend(runtime, req) {
354
354
  return;
355
355
  }
356
356
  }
357
- sendSessionUpdateEvent(runtime, {
358
- sessionId,
359
- agentType: requestedAgentType,
360
- workDir: resolvedWorkDir,
361
- agentSessionId: session.agentSessionId ?? incomingAgentSid ?? null,
362
- modelId,
363
- });
364
- session.currentRunId = null;
365
- session.nextEventSeq = 0;
366
- runtime.nativeFusion?.registerManagedSend({
367
- sessionId,
368
- agentType: requestedAgentType,
369
- sourceAgentType: getNativeSourceAgentType(requestedAgentType, modelId),
370
- canonicalMessageId: clientMessageId ?? null,
371
- sourceSessionKey: session.agentSessionId ?? incomingAgentSid ?? null,
372
- text,
373
- });
374
357
  const userEnvelope = {
375
358
  id: clientMessageId ?? `user-${req.id}`,
376
359
  sessionId,
@@ -378,36 +361,39 @@ export async function handleChatSend(runtime, req) {
378
361
  ts: Date.now(),
379
362
  payload: text,
380
363
  };
381
- appendMessage(sessionId, userEnvelope);
382
- sendSessionMessageEvent(runtime, userEnvelope, {
383
- agentType: requestedAgentType,
384
- workDir: resolvedWorkDir,
385
- agentSessionId: session.agentSessionId ?? incomingAgentSid ?? null,
386
- modelId,
387
- });
388
364
  reportLog({
389
365
  level: 'info',
390
366
  sessionId,
391
367
  wsEvent: 'chat.send.start',
392
368
  metadata: { reqId: req.id, agentType: requestedAgentType, modelId },
393
369
  });
394
- runtime.client.sendRes({ type: 'res', id: req.id, ok: true });
395
- reportLog({
396
- level: 'info',
397
- sessionId,
398
- wsEvent: 'chat.send.res',
399
- metadata: { reqId: req.id, ok: true },
400
- });
401
- void session.adapter.send(text, modelId)
402
- .then(() => {
403
- reportLog({
404
- level: 'info',
370
+ const markAccepted = () => {
371
+ sendSessionUpdateEvent(runtime, {
405
372
  sessionId,
406
- wsEvent: 'chat.send.done',
407
- metadata: { reqId: req.id },
373
+ agentType: requestedAgentType,
374
+ workDir: resolvedWorkDir,
375
+ agentSessionId: session.agentSessionId ?? incomingAgentSid ?? null,
376
+ modelId,
408
377
  });
409
- })
410
- .catch(async (err) => {
378
+ session.currentRunId = null;
379
+ session.nextEventSeq = 0;
380
+ runtime.nativeFusion?.registerManagedSend({
381
+ sessionId,
382
+ agentType: requestedAgentType,
383
+ sourceAgentType: getNativeSourceAgentType(requestedAgentType, modelId),
384
+ canonicalMessageId: clientMessageId ?? null,
385
+ sourceSessionKey: session.agentSessionId ?? incomingAgentSid ?? null,
386
+ text,
387
+ });
388
+ appendMessage(sessionId, userEnvelope);
389
+ sendSessionMessageEvent(runtime, userEnvelope, {
390
+ agentType: requestedAgentType,
391
+ workDir: resolvedWorkDir,
392
+ agentSessionId: session.agentSessionId ?? incomingAgentSid ?? null,
393
+ modelId,
394
+ });
395
+ };
396
+ const handleSendFailure = async (err, respondToReq) => {
411
397
  const message = `Agent send failed: ${err instanceof Error ? err.message : String(err)}`;
412
398
  console.error(`[chat.send] send failed reqId=${req.id} sessionId=${sessionId} agentType=${agentType} workDir=${resolvedWorkDir} agentSessionId=${session.agentSessionId ?? incomingAgentSid ?? ''}: ${message}`);
413
399
  runtime.sessions.delete(sessionId);
@@ -426,6 +412,59 @@ export async function handleChatSend(runtime, req) {
426
412
  seq: 0,
427
413
  },
428
414
  });
415
+ if (respondToReq) {
416
+ runtime.processedReqIds.delete(req.id);
417
+ runtime.client.sendRes({
418
+ type: 'res',
419
+ id: req.id,
420
+ ok: false,
421
+ error: message,
422
+ });
423
+ }
424
+ };
425
+ if (waitForDispatch) {
426
+ try {
427
+ await session.adapter.send(text, modelId);
428
+ reportLog({
429
+ level: 'info',
430
+ sessionId,
431
+ wsEvent: 'chat.send.done',
432
+ metadata: { reqId: req.id },
433
+ });
434
+ }
435
+ catch (err) {
436
+ await handleSendFailure(err, true);
437
+ return;
438
+ }
439
+ markAccepted();
440
+ runtime.client.sendRes({ type: 'res', id: req.id, ok: true });
441
+ reportLog({
442
+ level: 'info',
443
+ sessionId,
444
+ wsEvent: 'chat.send.res',
445
+ metadata: { reqId: req.id, ok: true },
446
+ });
447
+ return;
448
+ }
449
+ markAccepted();
450
+ runtime.client.sendRes({ type: 'res', id: req.id, ok: true });
451
+ reportLog({
452
+ level: 'info',
453
+ sessionId,
454
+ wsEvent: 'chat.send.res',
455
+ metadata: { reqId: req.id, ok: true },
456
+ });
457
+ void session.adapter.send(text, modelId)
458
+ .then(() => {
459
+ reportLog({
460
+ level: 'info',
461
+ sessionId,
462
+ wsEvent: 'chat.send.done',
463
+ metadata: { reqId: req.id },
464
+ });
465
+ })
466
+ .catch((err) => {
467
+ void handleSendFailure(err, false);
429
468
  });
430
469
  }
431
470
  export async function handleChatAbort(runtime, req) {
@@ -87,12 +87,14 @@ export class ChatQueueManager {
87
87
  const active = runtime.sessions.get(params.sessionId);
88
88
  const isBusy = Boolean(active?.currentRunId);
89
89
  if (!isBusy && !(readQueue().sessions[params.sessionId]?.length)) {
90
- await this.dispatchQueuedMessage(queueMessageFromParams(params));
91
- runtime.client.sendRes({
92
- type: 'res',
93
- id: req.id,
94
- ok: true,
95
- payload: { queued: false, queue: this.getSnapshot(params.sessionId) },
90
+ await this.opts.dispatchReq({
91
+ ...req,
92
+ method: 'chat.send',
93
+ params: {
94
+ ...params,
95
+ clientMessageId: params.clientMessageId ?? params.queueMessageId,
96
+ waitForDispatch: true,
97
+ },
96
98
  });
97
99
  return;
98
100
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.2.49",
3
+ "version": "0.2.50",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {