@fonz/tgcc 0.6.18 → 0.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.
Files changed (38) hide show
  1. package/README.md +77 -0
  2. package/dist/bridge.js +41 -11
  3. package/dist/bridge.js.map +1 -1
  4. package/dist/plugin/index.d.ts +41 -0
  5. package/dist/plugin/index.js +161 -0
  6. package/dist/plugin/index.js.map +1 -0
  7. package/dist/plugin/openclaw.plugin.json +55 -0
  8. package/dist/plugin/package.json +6 -0
  9. package/dist/plugin/skills/tgcc-agents/SKILL.md +161 -0
  10. package/dist/plugin/src/client.d.ts +167 -0
  11. package/dist/plugin/src/client.js +523 -0
  12. package/dist/plugin/src/client.js.map +1 -0
  13. package/dist/plugin/src/events.d.ts +44 -0
  14. package/dist/plugin/src/events.js +226 -0
  15. package/dist/plugin/src/events.js.map +1 -0
  16. package/dist/plugin/src/permissions.d.ts +21 -0
  17. package/dist/plugin/src/permissions.js +78 -0
  18. package/dist/plugin/src/permissions.js.map +1 -0
  19. package/dist/plugin/src/tools/tgcc-kill.d.ts +6 -0
  20. package/dist/plugin/src/tools/tgcc-kill.js +52 -0
  21. package/dist/plugin/src/tools/tgcc-kill.js.map +1 -0
  22. package/dist/plugin/src/tools/tgcc-send.d.ts +9 -0
  23. package/dist/plugin/src/tools/tgcc-send.js +61 -0
  24. package/dist/plugin/src/tools/tgcc-send.js.map +1 -0
  25. package/dist/plugin/src/tools/tgcc-spawn.d.ts +9 -0
  26. package/dist/plugin/src/tools/tgcc-spawn.js +79 -0
  27. package/dist/plugin/src/tools/tgcc-spawn.js.map +1 -0
  28. package/dist/plugin/src/tools/tgcc-status.d.ts +9 -0
  29. package/dist/plugin/src/tools/tgcc-status.js +74 -0
  30. package/dist/plugin/src/tools/tgcc-status.js.map +1 -0
  31. package/dist/streaming.d.ts +61 -89
  32. package/dist/streaming.js +672 -677
  33. package/dist/streaming.js.map +1 -1
  34. package/dist/telegram-html-ast.js +3 -0
  35. package/dist/telegram-html-ast.js.map +1 -1
  36. package/package.json +10 -3
  37. package/plugin/openclaw.plugin.json +55 -0
  38. package/plugin/skills/tgcc-agents/SKILL.md +161 -0
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ /**
3
+ * tgcc_status tool — Get status of TGCC agents and sessions.
4
+ *
5
+ * Returns agent states, pending results, pending permissions,
6
+ * and recent observability events.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createTgccStatusTool = createTgccStatusTool;
10
+ const events_js_1 = require("../events.js");
11
+ const TgccStatusParams = {
12
+ type: "object",
13
+ properties: {
14
+ agentId: { type: "string", description: "Filter by specific agent ID" },
15
+ drain: {
16
+ type: "boolean",
17
+ description: "If true, drain pending results (remove after reading). Default: false.",
18
+ },
19
+ eventsSince: {
20
+ type: "number",
21
+ description: "Only return events after this Unix timestamp (ms)",
22
+ },
23
+ },
24
+ };
25
+ const json = (payload) => ({
26
+ content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
27
+ details: payload,
28
+ });
29
+ function createTgccStatusTool(getClient) {
30
+ return {
31
+ name: "tgcc_status",
32
+ label: "TGCC Status",
33
+ description: "Get the status of TGCC agents and sessions. Shows agent states, " +
34
+ "pending results from completed CC sessions, pending permission requests, " +
35
+ "and recent observability events. Use drain=true to consume pending results.",
36
+ parameters: TgccStatusParams,
37
+ async execute(_toolCallId, params) {
38
+ const p = params;
39
+ const client = getClient();
40
+ const connected = client?.isConnected() ?? false;
41
+ // Get cached agent state
42
+ const cache = (0, events_js_1.getAgentCache)();
43
+ // Get pending data
44
+ const results = p.drain ? (0, events_js_1.drainPendingResults)() : (0, events_js_1.getPendingResults)();
45
+ const permissions = (0, events_js_1.getPendingPermissions)();
46
+ const events = (0, events_js_1.getRecentEvents)(p.eventsSince);
47
+ // Filter by agentId if specified
48
+ const filterAgent = (items) => p.agentId ? items.filter((i) => i.agentId === p.agentId) : items;
49
+ // Optionally fetch live status from TGCC
50
+ let liveStatus = null;
51
+ if (connected && client) {
52
+ try {
53
+ liveStatus = await client.getStatus(p.agentId);
54
+ }
55
+ catch {
56
+ // Fall back to cached data
57
+ }
58
+ }
59
+ return json({
60
+ connected,
61
+ agents: p.agentId
62
+ ? cache[p.agentId]
63
+ ? { [p.agentId]: cache[p.agentId] }
64
+ : {}
65
+ : cache,
66
+ liveStatus,
67
+ pendingResults: filterAgent(results),
68
+ pendingPermissions: filterAgent(permissions),
69
+ recentEvents: filterAgent(events),
70
+ });
71
+ },
72
+ };
73
+ }
74
+ //# sourceMappingURL=tgcc-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tgcc-status.js","sourceRoot":"","sources":["../../../../plugin/src/tools/tgcc-status.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAsCH,oDAoDC;AAtFD,4CAMsB;AAEtB,MAAM,gBAAgB,GAAG;IACvB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;QACvE,KAAK,EAAE;YACL,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,wEAAwE;SACtF;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,mDAAmD;SACjE;KACF;CACO,CAAC;AAQX,MAAM,IAAI,GAAG,CAAC,OAAgB,EAAE,EAAE,CAAC,CAAC;IAClC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IAC5E,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,SAAgB,oBAAoB,CAClC,SAA4C;IAE5C,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,aAAa;QACpB,WAAW,EACT,kEAAkE;YAClE,2EAA2E;YAC3E,6EAA6E;QAC/E,UAAU,EAAE,gBAA2C;QACvD,KAAK,CAAC,OAAO,CAAC,WAAmB,EAAE,MAA+B;YAChE,MAAM,CAAC,GAAG,MAAiC,CAAC;YAC5C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,SAAS,GAAG,MAAM,EAAE,WAAW,EAAE,IAAI,KAAK,CAAC;YAEjD,yBAAyB;YACzB,MAAM,KAAK,GAAG,IAAA,yBAAa,GAAE,CAAC;YAE9B,mBAAmB;YACnB,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAA,+BAAmB,GAAE,CAAC,CAAC,CAAC,IAAA,6BAAiB,GAAE,CAAC;YACtE,MAAM,WAAW,GAAG,IAAA,iCAAqB,GAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,IAAA,2BAAe,EAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YAE9C,iCAAiC;YACjC,MAAM,WAAW,GAAG,CAAC,KAAkC,EAAE,EAAE,CACzD,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAEnE,yCAAyC;YACzC,IAAI,UAAU,GAAY,IAAI,CAAC;YAC/B,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;gBACxB,IAAI,CAAC;oBACH,UAAU,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBACjD,CAAC;gBAAC,MAAM,CAAC;oBACP,2BAA2B;gBAC7B,CAAC;YACH,CAAC;YAED,OAAO,IAAI,CAAC;gBACV,SAAS;gBACT,MAAM,EAAE,CAAC,CAAC,OAAO;oBACf,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;wBAChB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE;wBACnC,CAAC,CAAC,EAAE;oBACN,CAAC,CAAC,KAAK;gBACT,UAAU;gBACV,cAAc,EAAE,WAAW,CAAC,OAAO,CAAC;gBACpC,kBAAkB,EAAE,WAAW,CAAC,WAAW,CAAC;gBAC5C,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC;aAClC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -56,91 +56,78 @@ export declare class StreamAccumulator {
56
56
  private splitThreshold;
57
57
  private logger?;
58
58
  private onError?;
59
+ private segments;
59
60
  private tgMessageId;
60
- private buffer;
61
- private thinkingBuffer;
62
- private imageBase64Buffer;
63
- private currentBlockType;
64
- private lastEditTime;
65
- private editTimer;
66
- private thinkingIndicatorShown;
67
- private thinkingMessageId;
68
61
  private messageIds;
69
- private finished;
62
+ sealed: boolean;
70
63
  private sendQueue;
71
64
  private turnUsage;
72
- /** Usage from the most recent message_start event — represents a single API call's context (not cumulative). */
73
65
  private _lastMsgStartCtx;
74
- private toolMessages;
66
+ private currentBlockType;
67
+ private currentBlockId;
68
+ private currentSegmentIdx;
75
69
  private toolInputBuffers;
76
- private currentToolBlockId;
77
- private consolidatedToolMsgId;
70
+ private imageBase64Buffer;
71
+ private lastEditTime;
72
+ private flushTimer;
73
+ private dirty;
74
+ private turnStartTime;
75
+ private firstSendReady;
76
+ private firstSendTimer;
77
+ private toolHideTimers;
78
78
  constructor(options: StreamAccumulatorOptions);
79
79
  get allMessageIds(): number[];
80
80
  /** Set usage stats for the current turn (called from bridge on result event) */
81
81
  setTurnUsage(usage: TurnUsage): void;
82
+ /** Append a supervisor message segment. Renders in stream order with everything else. */
83
+ addSupervisorMessage(text: string): void;
82
84
  handleEvent(event: StreamInnerEvent): Promise<void>;
83
85
  private onContentBlockStart;
84
86
  private onContentBlockDelta;
85
- /** Send or edit a message. If rawHtml is true, text is already HTML-safe. */
86
- private sendOrEdit;
87
- private _doSendOrEdit;
88
- private sendImage;
89
- /** Send or update the consolidated tool indicator message. */
90
- private sendToolIndicator;
91
- /** Build HTML for the consolidated tool indicator message. */
92
- private buildConsolidatedToolHtml;
93
- /** Resolved tool result stats, keyed by blockId */
94
- private toolResolvedStats;
95
- /** Edit the consolidated tool message with current state of all tools. */
96
- private updateConsolidatedToolMessage;
97
- /** Update a tool indicator message with input preview once the JSON value is complete. */
98
- private toolIndicatorLastSummary;
99
- private updateToolIndicatorWithInput;
100
- /** MCP media tools — on success, delete indicator (the media was sent directly). On failure, keep + react ❌. */
87
+ private onContentBlockStop;
88
+ /** Resolve a tool indicator with success/failure status. Called by bridge on tool_result. */
89
+ resolveToolMessage(blockId: string, isError: boolean, errorMessage?: string, resultContent?: string, toolUseResult?: Record<string, unknown>): void;
90
+ /** Update a sub-agent segment status (called by bridge on task_started/progress/completed). */
91
+ updateSubAgentSegment(blockId: string, status: 'running' | 'dispatched' | 'completed', label?: string): void;
92
+ /** Append a high-signal progress line to a sub-agent segment (called by bridge on task_progress). */
93
+ appendSubAgentProgress(blockId: string, description: string, lastToolName?: string): void;
101
94
  private static MCP_MEDIA_TOOLS;
102
- /** Resolve a tool indicator with success/failure status. Updates the consolidated message. */
103
- resolveToolMessage(blockId: string, isError: boolean, errorMessage?: string, resultContent?: string, toolUseResult?: Record<string, unknown>): Promise<void>;
104
- /** Edit a specific tool indicator message by block ID (updates the consolidated message). */
105
- editToolMessage(blockId: string, _html: string): Promise<void>;
106
- /** Delete a specific tool from the consolidated indicator. */
107
- deleteToolMessage(blockId: string): Promise<void>;
108
- /** Delete the consolidated tool indicator message. */
109
- deleteAllToolMessages(): Promise<void>;
110
- private throttledEdit;
111
- /** Build the full message text including thinking blockquote prefix and usage footer.
112
- * Returns { text, hasHtmlSuffix } — caller must pass rawHtml=true when hasHtmlSuffix is set
113
- * because the footer contains pre-formatted HTML (<i> tags).
114
- */
115
- private buildFullText;
116
- private doEdit;
95
+ /** Render all segments to one HTML string. */
96
+ renderHtml(): string;
97
+ /** Force any pending timer to fire immediately and await the send queue.
98
+ * Bypasses the first-send gate (like finalize). Useful in tests. */
99
+ flush(): Promise<void>;
100
+ /** Mark dirty and schedule a throttled flush. The single entry point for all renders.
101
+ * Data in dirty flag throttled flush → TG edit. One path, no re-entrant loops. */
102
+ private flushInFlight;
103
+ private requestRender;
104
+ /** Timer callback: consumes dirty flag and chains one _doSendOrEdit onto sendQueue. */
105
+ private flushRender;
106
+ /** Split oversized message — called from within the sendQueue chain, uses _doSendOrEdit directly. */
117
107
  private splitMessage;
118
- /** Emergency split/truncation when buffer exceeds 50KB absolute limit */
119
- private forceSplitOrTruncate;
108
+ private checkFirstSendReady;
109
+ private clearFirstSendTimer;
110
+ /** Force-split when a text segment exceeds 50KB */
111
+ private forceSplitText;
120
112
  finalize(): Promise<void>;
121
- private clearEditTimer;
122
- /** Soft reset: clear buffer/state but keep tgMessageId so next turn edits the same message.
123
- * toolMessages persists across resets — they are independent of the text accumulator. */
113
+ private sendOrEdit;
114
+ private _doSendOrEdit;
115
+ private sendImage;
116
+ /** Soft reset: clear per-API-call transient state. Segments and tgMessageId persist across
117
+ * tool-use loop iterations within the same turn. */
124
118
  softReset(): void;
125
- /** Full reset: also clears tgMessageId (next send creates a new message).
126
- * Chains on the existing sendQueue so any pending finalize() edits complete first.
127
- * Consolidated tool message resets so next turn starts a fresh batch. */
119
+ /** Full reset: clear everything for a new turn. */
128
120
  reset(): void;
121
+ private clearFlushTimer;
129
122
  }
123
+ /** Format a task_progress event into a single HTML-safe progress line.
124
+ * Returns null if the event has no useful display content. */
125
+ export declare function formatProgressLine(description: string, lastToolName?: string): string | null;
130
126
  /** Format usage stats as an HTML italic footer line */
131
127
  export declare function formatUsageFooter(usage: TurnUsage, _model?: string): string;
132
128
  export declare function isSubAgentTool(toolName: string): boolean;
133
- /** Extract a human-readable summary from partial/complete JSON tool input.
134
- * Looks for prompt, task, command, description fields — returns the first found, truncated.
135
- */
136
129
  export declare function extractSubAgentSummary(jsonInput: string, maxLen?: number): string;
137
- /** Priority index for a label source field. Lower = better. */
138
130
  export declare function labelFieldPriority(field: string | null): number;
139
- /**
140
- * Extract a human-readable label for a sub-agent from its JSON tool input.
141
- * Returns { label, field } so callers can track priority and upgrade labels
142
- * when higher-priority fields become available during streaming.
143
- */
144
131
  export declare function extractAgentLabel(jsonInput: string): {
145
132
  label: string;
146
133
  field: string | null;
@@ -155,7 +142,9 @@ export interface SubAgentInfo {
155
142
  labelField: string | null;
156
143
  agentName: string;
157
144
  inputPreview: string;
145
+ startTime: number;
158
146
  dispatchedAt: number | null;
147
+ progressLines: string[];
159
148
  }
160
149
  export interface SubAgentSender {
161
150
  sendMessage(chatId: number | string, text: string, parseMode?: string): Promise<number>;
@@ -166,7 +155,6 @@ export interface SubAgentTrackerOptions {
166
155
  chatId: number | string;
167
156
  sender: SubAgentSender;
168
157
  }
169
- /** A single mailbox message from a CC background sub-agent. */
170
158
  export interface MailboxMessage {
171
159
  from: string;
172
160
  text: string;
@@ -175,14 +163,13 @@ export interface MailboxMessage {
175
163
  color?: string;
176
164
  read: boolean;
177
165
  }
178
- /** Callback invoked when all tracked sub-agents have reported via mailbox. */
179
166
  export type AllAgentsReportedCallback = () => void;
180
167
  export declare class SubAgentTracker {
181
168
  private chatId;
182
169
  private sender;
183
170
  private agents;
184
171
  private blockToAgent;
185
- private consolidatedAgentMsgId;
172
+ private standaloneMsgId;
186
173
  private sendQueue;
187
174
  private teamName;
188
175
  private mailboxPath;
@@ -190,58 +177,43 @@ export declare class SubAgentTracker {
190
177
  private lastMailboxCount;
191
178
  private onAllReported;
192
179
  hasPendingFollowUp: boolean;
180
+ /** When true, stream events update agent metadata but do NOT create TG messages.
181
+ * Set to false after the main turn bubble is sealed to allow standalone status bubble. */
182
+ private inTurn;
193
183
  constructor(options: SubAgentTrackerOptions);
194
184
  get activeAgents(): SubAgentInfo[];
195
- /** Returns true if any sub-agents were tracked in this turn (including completed ones) */
196
185
  get hadSubAgents(): boolean;
197
- /** Returns true if any sub-agents are in dispatched state (spawned but no result yet) */
198
186
  get hasDispatchedAgents(): boolean;
199
- /** Mark all dispatched agents as completed used when CC reports results
200
- * in its main text response rather than via tool_result events.
201
- */
187
+ /** Called after the main bubble is sealed. Creates standalone status bubble for any dispatched agents. */
188
+ startPostTurnTracking(): Promise<void>;
202
189
  markDispatchedAsReportedInMain(): void;
203
190
  handleEvent(event: StreamInnerEvent): Promise<void>;
204
- /** Handle a tool_result event — marks the sub-agent as completed with collapsible result */
205
- /** Set agent metadata from structured tool_use_result */
206
191
  setAgentMetadata(toolUseId: string, meta: {
207
192
  agentName?: string;
208
193
  agentType?: string;
209
194
  color?: string;
210
195
  }): void;
211
- /** Mark an agent as completed externally (e.g. from bridge follow-up) */
212
196
  markCompleted(toolUseId: string, _reason: string): void;
213
197
  handleToolResult(toolUseId: string, result: string): Promise<void>;
214
198
  private onBlockStart;
215
- /** Build and edit the shared sub-agent status message. */
216
- private updateConsolidatedAgentMessage;
217
199
  private onInputDelta;
218
200
  private onBlockStop;
219
- /** Start a periodic timer that edits the message with elapsed time */
220
- /** Set callback invoked when ALL dispatched sub-agents have mailbox results. */
221
201
  setOnAllReported(cb: AllAgentsReportedCallback | null): void;
222
- /** Set the CC team name (extracted from spawn confirmation tool_result). */
223
202
  setTeamName(name: string): void;
224
203
  get currentTeamName(): string | null;
225
204
  get isMailboxWatching(): boolean;
226
- /** Start watching the mailbox file for sub-agent results. */
227
205
  startMailboxWatch(): void;
228
- /** Stop watching the mailbox file. */
229
206
  stopMailboxWatch(): void;
230
- /** Read and parse the mailbox file. Returns [] on any error. */
231
207
  private readMailboxMessages;
232
- /** Process new mailbox messages and update sub-agent TG messages. */
233
208
  private processMailbox;
234
- /** Find a tracked sub-agent whose label matches the mailbox message's `from` field. */
235
209
  private findAgentByFrom;
236
- /** Handle a system task_started event — update the sub-agent status display. */
237
- handleTaskStarted(toolUseId: string, description: string, taskType?: string): void;
238
- /** Handle a system task_progress event — update the sub-agent status with current activity. */
210
+ handleTaskStarted(toolUseId: string, description: string, _taskType?: string): void;
239
211
  handleTaskProgress(toolUseId: string, description: string, lastToolName?: string): void;
240
- /** Handle a system task_completed event. */
241
212
  handleTaskCompleted(toolUseId: string): void;
242
- /** Build and edit the shared sub-agent status message with progress info. */
243
- private updateConsolidatedAgentMessageWithProgress;
244
- /** Find a tracked sub-agent by tool_use_id. */
213
+ /** Build the standalone status bubble HTML. */
214
+ private buildStandaloneHtml;
215
+ /** Edit the standalone status bubble with current state. */
216
+ private updateStandaloneMessage;
245
217
  getAgentByToolUseId(toolUseId: string): SubAgentInfo | undefined;
246
218
  reset(): void;
247
219
  }