@hahnfeld/teams-adapter 1.3.5 → 1.4.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,14 +1,17 @@
1
1
  /**
2
2
  * Message composer — manages a single "main message" per session in Teams.
3
3
  *
4
- * The main message has four zones:
5
- * TITLE (persistent, bold) — session name, survives finalize
6
- * HEADER (ephemeral, italic) tool_call, tool_update, thought
7
- * BODY (persistent, streamed) text, attachments
8
- * FOOTER (persistent, italic) usage, session_end
4
+ * Emulates Claude Code's terminal UX using Adaptive Cards:
5
+ * - Title: bold, persistent — session name
6
+ * - Thinking blocks: italic, 💭 prefix, ALWAYS append (never replaced)
7
+ * - Tool progress: 🔄 Running... with elapsed time, persistent as historical record
8
+ * - Tool result: 📄 Result... appears AFTER progress (both coexist)
9
+ * - Streaming text: root-level, appended
10
+ * - Usage: italic footer, persistent
9
11
  *
10
- * All zones are composed into a single markdown string and sent/updated
11
- * as one Teams message via the rate limiter.
12
+ * Tool output during execution is indented as children under the tool block.
13
+ * When a tool completes, a NEW tool-result entry is appended — the progress
14
+ * entry stays as a historical record (matching Claude Code's behavior).
12
15
  */
13
16
  import type { TurnContext } from "@microsoft/agents-hosting";
14
17
  import type { ConversationRateLimiter } from "./rate-limiter.js";
@@ -18,22 +21,22 @@ export interface MessageRef {
18
21
  serviceUrl: string;
19
22
  }
20
23
  export type AcquireBotToken = () => Promise<string | null>;
21
- /**
22
- * A single main message with title/header/body/footer zones.
23
- */
24
24
  export declare class SessionMessage {
25
25
  private context;
26
26
  private conversationId;
27
27
  private sessionId;
28
28
  private rateLimiter;
29
29
  private acquireBotToken;
30
- private title;
31
- private header;
32
- private body;
33
- private footer;
30
+ private entries;
31
+ private titleId;
32
+ private usageId;
33
+ /** The active tool whose children accumulate streaming output */
34
+ private toolActive;
34
35
  private ref;
35
36
  private lastSent;
36
37
  private stallTimer?;
38
+ /** Interval handle for periodic elapsed-time updates on running tools */
39
+ private tickInterval?;
37
40
  constructor(context: TurnContext, conversationId: string, sessionId: string, rateLimiter: ConversationRateLimiter, acquireBotToken: AcquireBotToken);
38
41
  updateContext(context: TurnContext): void;
39
42
  getRef(): MessageRef | null;
@@ -41,40 +44,68 @@ export declare class SessionMessage {
41
44
  getFooter(): string | null;
42
45
  /** Set the persistent session title (bold, survives finalize). */
43
46
  setTitle(text: string): void;
44
- /** Max header length — keeps the message compact; tool diffs can be huge. */
45
- private static readonly MAX_HEADER_LENGTH;
46
- /** Replace the ephemeral header (tool_call, thought, etc.). */
47
- setHeader(text: string): void;
48
- /** Clear the ephemeral header and flush the update. */
49
- clearHeader(): void;
50
- /** Append text to the body (streaming text chunks). */
51
- appendBody(text: string): void;
52
- /** Set the persistent footer (usage, completion). */
53
- setFooter(text: string): void;
54
- /** Append to the existing footer (e.g., adding "Task completed" after usage). */
55
- appendFooter(text: string): void;
56
47
  /**
57
- * Close any unclosed code fences in the body.
58
- * If the body has an odd number of ``` markers, the footer would
59
- * be swallowed into the code block — append a closing fence.
48
+ * Add a tool-progress entry (🔄 Running...). Sets toolActive so subsequent
49
+ * addText() calls route children here. Returns entry id for tracking.
50
+ */
51
+ addToolStart(toolName: string, _params?: string): string;
52
+ /**
53
+ * Add a tool-result entry (📄 Result...). Creates a NEW entry — does NOT
54
+ * replace the tool-progress entry. Both coexist as historical record.
55
+ * Clears toolActive so subsequent addText() goes to root body.
56
+ */
57
+ addToolResult(id: string, result: string): void;
58
+ /** Add text — goes to toolActive children if a tool is running, else root text entry. */
59
+ addText(text: string): void;
60
+ /**
61
+ * Always append a new thought entry (thoughts persist, never replaced).
62
+ * Multiple thinking blocks can coexist — each is a historical record.
63
+ */
64
+ addThought(text: string): void;
65
+ /** Set or replace the usage entry (only one at a time). */
66
+ setUsage(text: string): void;
67
+ /** Add a divider entry. */
68
+ appendDivider(): void;
69
+ private findEntry;
70
+ private removeEntry;
71
+ /**
72
+ * Start a 1-second interval that updates elapsed time on running tool-progress
73
+ * entries. Called when a tool starts, stopped when tool completes or finalize.
60
74
  */
61
- private static closeCodeFences;
62
- /** Compose the four zones into a single markdown string. */
63
- compose(): string;
64
- /** Request a flush through the rate limiter. */
65
- requestFlush(): void;
75
+ private startTickInterval;
76
+ private stopTickInterval;
77
+ private buildCard;
78
+ private requestFlush;
66
79
  private flush;
67
- private updateViaRest;
68
- /** Split: finalize current message at body limit, start fresh. */
69
- private split;
80
+ private updateCardViaRest;
70
81
  private resetStallTimer;
71
- /** Finalize: clear stall timer, clear ephemeral header, do a last flush. */
72
82
  finalize(): Promise<MessageRef | null>;
83
+ /** Legacy compat — strip pattern from root text entries. */
73
84
  stripPattern(pattern: RegExp): Promise<void>;
85
+ /**
86
+ * Check if root text exceeds limit and split into a new message.
87
+ * Called from addText when a message is already sent (this.ref != null).
88
+ */
89
+ private checkSplit;
90
+ /** For split: finalize current message at limit, start fresh. */
91
+ private split;
92
+ /** @deprecated — use addThought instead */
93
+ setHeader(_text: string): void;
94
+ /** @deprecated — use addToolResult instead */
95
+ setHeaderResult(_text: string): void;
96
+ /** @deprecated — use addText instead */
97
+ appendBody(text: string): void;
98
+ /** @deprecated — use setUsage instead */
99
+ setFooter(text: string): void;
100
+ /** @deprecated — use setUsage instead */
101
+ appendFooter(text: string): void;
102
+ /** @deprecated — header zone is gone */
103
+ clearHeader(): void;
104
+ /** @deprecated — thoughts persist, use addThought */
105
+ removeThought(): void;
106
+ /** @deprecated — use addToolStart + addToolResult */
107
+ updateToolResult(_id: string, _result: string): void;
74
108
  }
75
- /**
76
- * Manages SessionMessage instances and plan refs across sessions.
77
- */
78
109
  export declare class SessionMessageManager {
79
110
  private rateLimiter;
80
111
  private acquireBotToken;
@@ -84,9 +115,7 @@ export declare class SessionMessageManager {
84
115
  getOrCreate(sessionId: string, context: TurnContext): SessionMessage;
85
116
  get(sessionId: string): SessionMessage | undefined;
86
117
  has(sessionId: string): boolean;
87
- /** Finalize and remove a session's message and plan ref. */
88
118
  finalize(sessionId: string): Promise<MessageRef | null>;
89
- /** Get or set the plan message ref for a session. */
90
119
  getPlanRef(sessionId: string): MessageRef | undefined;
91
120
  setPlanRef(sessionId: string, ref: MessageRef): void;
92
121
  cleanup(sessionId: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"message-composer.d.ts","sourceRoot":"","sources":["../src/message-composer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"message-composer.d.ts","sourceRoot":"","sources":["../src/message-composer.ts"],"names":[],"mappings":"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"}