@canonmsg/agent-sdk 1.6.0 → 1.7.0

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,4 @@
1
- import { ApprovalManager, CanonClient, buildCanonGroupContext, createRuntimeStatePublisher, diffCanonMemberIds, FINAL_MESSAGE_HANDOFF_MS, RUNTIME_NEW_SESSION_ACTION, RUNTIME_STOP_ACTION, RUNTIME_STOP_AND_DROP_ACTION, buildRuntimeInputOutcome, initRTDBAuth, rtdbRead, rtdbWrite, normalizeTurnMetadata, reachOutToCanonContact, resolveCanonReplyContext, resolveMessageActiveSelfContextId, resolveRuntimeProvenance, selectActiveSelfContexts, } from '@canonmsg/core';
1
+ import { ApprovalManager, CanonClient, buildCanonGroupContext, createTurnOutputController, createRuntimeStatePublisher, diffCanonMemberIds, FINAL_MESSAGE_HANDOFF_MS, RUNTIME_NEW_SESSION_ACTION, RUNTIME_STOP_ACTION, RUNTIME_STOP_AND_DROP_ACTION, buildRuntimeInputOutcome, initRTDBAuth, rtdbRead, rtdbWrite, normalizeTurnMetadata, reachOutToCanonContact, resolveCanonReplyContext, resolveMessageActiveSelfContextId, resolveRuntimeProvenance, selectActiveSelfContexts, } from '@canonmsg/core';
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import { AuthManager } from './auth.js';
4
4
  import { Debouncer } from './debouncer.js';
@@ -1112,21 +1112,23 @@ export class CanonAgent {
1112
1112
  : {}),
1113
1113
  })).catch(() => { });
1114
1114
  };
1115
+ const turnOutput = createTurnOutputController({
1116
+ turnId,
1117
+ mode: 'snapshot',
1118
+ writeSnapshot: (snapshot) => this.apiClient.setStreaming({
1119
+ conversationId,
1120
+ text: snapshot.text,
1121
+ status: snapshot.status,
1122
+ messageId: snapshot.messageId,
1123
+ turnId: snapshot.turnId,
1124
+ }),
1125
+ clearSnapshot: () => this.apiClient.clearStreaming(conversationId),
1126
+ });
1115
1127
  const setLiveState = async (state, text, streamingStatus) => {
1116
1128
  throwIfAborted();
1117
1129
  await writeTurn(state);
1118
1130
  if (streamingStatus) {
1119
- try {
1120
- await this.apiClient.setStreaming({
1121
- conversationId,
1122
- text: text ?? '',
1123
- status: streamingStatus,
1124
- messageId: turnId,
1125
- });
1126
- }
1127
- catch {
1128
- // Non-critical
1129
- }
1131
+ await turnOutput.setStatus(streamingStatus, text ?? '');
1130
1132
  }
1131
1133
  };
1132
1134
  // Show thinking indicator and keep it alive (5s client-side expiry)
@@ -1140,12 +1142,7 @@ export class CanonAgent {
1140
1142
  const thinkingKeepalive = setInterval(() => {
1141
1143
  this.apiClient.setTyping(conversationId, true, 'thinking').catch(() => { });
1142
1144
  if (turnState === 'thinking') {
1143
- this.apiClient.setStreaming({
1144
- conversationId,
1145
- text: 'Thinking...',
1146
- status: 'thinking',
1147
- messageId: turnId,
1148
- }).catch(() => { });
1145
+ turnOutput.setStatus('thinking', 'Thinking...').catch(() => { });
1149
1146
  }
1150
1147
  }, 3500);
1151
1148
  try {
@@ -1331,7 +1328,7 @@ export class CanonAgent {
1331
1328
  shouldPersistTurnState = true;
1332
1329
  try {
1333
1330
  try {
1334
- await this.apiClient.clearStreaming(conversationId);
1331
+ await turnOutput.waitingInput();
1335
1332
  }
1336
1333
  catch { }
1337
1334
  await writeTurn('waiting_input');
@@ -1408,7 +1405,7 @@ export class CanonAgent {
1408
1405
  });
1409
1406
  requestCreated = true;
1410
1407
  try {
1411
- await this.apiClient.clearStreaming(conversationId);
1408
+ await turnOutput.waitingInput();
1412
1409
  }
1413
1410
  catch { }
1414
1411
  await writeTurn('waiting_input');
@@ -1586,13 +1583,34 @@ export class CanonAgent {
1586
1583
  setStreaming: async (text) => {
1587
1584
  await setLiveState('streaming', text, 'streaming');
1588
1585
  },
1586
+ appendDelta: (delta) => {
1587
+ throwIfAborted();
1588
+ turnState = 'streaming';
1589
+ turnOutput.appendDelta(delta);
1590
+ void writeTurn('streaming');
1591
+ },
1592
+ appendBlock: (block) => {
1593
+ throwIfAborted();
1594
+ turnState = 'streaming';
1595
+ turnOutput.appendBlock(block);
1596
+ void writeTurn('streaming');
1597
+ },
1598
+ replaceSnapshot: async (text) => {
1599
+ await setLiveState('streaming', text, 'streaming');
1600
+ },
1601
+ flush: async () => {
1602
+ await turnOutput.flush();
1603
+ },
1604
+ clear: async () => {
1605
+ await turnOutput.clear();
1606
+ },
1589
1607
  setTool: async (text) => {
1590
1608
  await setLiveState('tool', text, 'tool');
1591
1609
  },
1592
1610
  setWaitingInput: async (text) => {
1593
1611
  shouldPersistTurnState = true;
1594
1612
  try {
1595
- await this.apiClient.clearStreaming(conversationId);
1613
+ await turnOutput.waitingInput();
1596
1614
  }
1597
1615
  catch { }
1598
1616
  await writeTurn('waiting_input');
@@ -1648,7 +1666,7 @@ export class CanonAgent {
1648
1666
  }
1649
1667
  catch { }
1650
1668
  try {
1651
- await this.apiClient.clearStreaming(conversationId);
1669
+ await turnOutput.clear();
1652
1670
  }
1653
1671
  catch { }
1654
1672
  if (runtimeState && !shouldPersistTurnState) {
package/dist/types.d.ts CHANGED
@@ -31,6 +31,11 @@ export interface TurnController {
31
31
  state: import('@canonmsg/core').TurnLifecycleState;
32
32
  setThinking: (text?: string) => Promise<void>;
33
33
  setStreaming: (text: string) => Promise<void>;
34
+ appendDelta: (delta: string) => void;
35
+ appendBlock: (block: string) => void;
36
+ replaceSnapshot: (text: string) => Promise<void>;
37
+ flush: () => Promise<void>;
38
+ clear: () => Promise<void>;
34
39
  setTool: (text: string) => Promise<void>;
35
40
  setWaitingInput: (text?: string) => Promise<void>;
36
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/agent-sdk",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Canon Agent SDK — build AI agents that participate in Canon conversations",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "node": ">=18.0.0"
29
29
  },
30
30
  "dependencies": {
31
- "@canonmsg/core": "^0.22.0"
31
+ "@canonmsg/core": "^0.24.0"
32
32
  },
33
33
  "publishConfig": {
34
34
  "access": "public"