@masterxinxin/lark-coding-agent-bridge 0.0.0-stage → 0.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.
@@ -0,0 +1,212 @@
1
+ type AgentEvent = {
2
+ type: 'system';
3
+ sessionId?: string;
4
+ threadId?: string;
5
+ cwd?: string;
6
+ model?: string;
7
+ } | {
8
+ type: 'text';
9
+ delta: string;
10
+ } | {
11
+ type: 'final_text';
12
+ content: string;
13
+ } | {
14
+ type: 'thinking';
15
+ delta: string;
16
+ } | {
17
+ type: 'tool_use';
18
+ id: string;
19
+ name: string;
20
+ input: unknown;
21
+ title?: string;
22
+ } | {
23
+ type: 'tool_result';
24
+ id: string;
25
+ output: string;
26
+ isError: boolean;
27
+ } | {
28
+ /**
29
+ * Agent paused mid-run waiting for the user to approve / reject a tool
30
+ * call. Only opencode emits this today; Claude and Codex have their own
31
+ * non-interactive permission flows. The bridge must call
32
+ * AgentRun.respondToPermission(id, ...) to release the agent — the SSE
33
+ * stream keeps flowing during the wait, but no `done` will arrive until
34
+ * the request is answered (or auto-rejected on timeout).
35
+ */
36
+ type: 'permission_request';
37
+ id: string;
38
+ tool: string;
39
+ input?: unknown;
40
+ description?: string;
41
+ } | {
42
+ type: 'usage';
43
+ inputTokens?: number;
44
+ outputTokens?: number;
45
+ cachedInputTokens?: number;
46
+ reasoningOutputTokens?: number;
47
+ costUsd?: number;
48
+ } | {
49
+ type: 'done';
50
+ sessionId?: string;
51
+ threadId?: string;
52
+ terminationReason: 'normal' | 'interrupted' | 'timeout';
53
+ } | {
54
+ type: 'error';
55
+ message: string;
56
+ terminationReason: 'failed' | 'interrupted' | 'timeout';
57
+ /**
58
+ * Optional session correlation. Only opencode populates it today
59
+ * (the upstream `NormalizedEvent` carries `sessionID` and the
60
+ * translator forwards it); claude/codex emit `error` without it.
61
+ * Callers MUST tolerate its absence.
62
+ */
63
+ sessionId?: string;
64
+ };
65
+
66
+ type ToolStatus = 'running' | 'done' | 'error';
67
+ interface ToolEntry {
68
+ id: string;
69
+ name: string;
70
+ input: unknown;
71
+ status: ToolStatus;
72
+ output?: string;
73
+ /** Optional human-readable title from upstream (opencode populates this; Claude/Codex don't). */
74
+ title?: string;
75
+ }
76
+ interface RunUsage {
77
+ inputTokens?: number;
78
+ outputTokens?: number;
79
+ cachedInputTokens?: number;
80
+ reasoningOutputTokens?: number;
81
+ costUsd?: number;
82
+ }
83
+ type Block = {
84
+ kind: 'text';
85
+ content: string;
86
+ streaming: boolean;
87
+ } | {
88
+ kind: 'tool';
89
+ tool: ToolEntry;
90
+ };
91
+ type FooterStatus = 'thinking' | 'tool_running' | 'streaming' | null;
92
+ type Terminal = 'running' | 'done' | 'interrupted' | 'error' | 'idle_timeout';
93
+ interface RunState {
94
+ blocks: Block[];
95
+ finalText?: string;
96
+ reasoning: {
97
+ content: string;
98
+ active: boolean;
99
+ };
100
+ footer: FooterStatus;
101
+ terminal: Terminal;
102
+ errorMsg?: string;
103
+ /** Set when terminal === 'idle_timeout' — how long claude was idle before
104
+ * the watchdog gave up (so the message can say "N 分钟无响应"). */
105
+ idleTimeoutMinutes?: number;
106
+ /** Model reported by the agent's `system` event, if any. */
107
+ model?: string;
108
+ /** Aggregated token/cost usage for the run, if the agent reported it. */
109
+ usage?: RunUsage;
110
+ }
111
+ declare const initialState: RunState;
112
+ declare function reduce(state: RunState, evt: AgentEvent): RunState;
113
+ declare function markInterrupted(state: RunState): RunState;
114
+ declare function finalizeIfRunning(state: RunState): RunState;
115
+
116
+ interface RunCardRenderOptions {
117
+ signCallback?: (action: string) => string;
118
+ /**
119
+ * Optional banner shown at the top of the card. Used by the wake-up
120
+ * watcher to signal "this card is the bot continuing on its own after a
121
+ * background task finished, not a reply to a user message you just sent".
122
+ */
123
+ headerBanner?: string;
124
+ /** Display name for the card header title (e.g. "opencode"). */
125
+ agentName?: string;
126
+ /** Epoch ms when the run started — enables the elapsed-time footer chip. */
127
+ startedAt?: number;
128
+ /** Override "now" for deterministic renders (tests). Defaults to Date.now(). */
129
+ now?: number;
130
+ }
131
+ declare function renderCard(state: RunState, options?: RunCardRenderOptions): object;
132
+
133
+ /**
134
+ * Render `RunState` as plain markdown text — used in `messageReply: 'text'`
135
+ * mode where we stream a markdown message instead of a card.
136
+ *
137
+ * Differences vs `renderCard`:
138
+ * - No collapsible panels, no buttons (markdown messages have neither)
139
+ * - Tool calls collapse to a single short line each (no body)
140
+ * - No reasoning / thinking output (no place to fold it; would be noise)
141
+ * - Footer is appended inline at the bottom while running
142
+ */
143
+ declare function renderText(state: RunState): string;
144
+
145
+ /**
146
+ * Structured logger.
147
+ *
148
+ * Two destinations on every call:
149
+ * 1. JSON line into the active profile logs directory — the durable
150
+ * record `/doctor` greps over.
151
+ * 2. Compact human-readable line on stdout/stderr — for live tailing in dev.
152
+ *
153
+ * Per-message context (traceId, chatId, msgId) is propagated automatically
154
+ * via AsyncLocalStorage; call `withTrace()` once at the entry point and any
155
+ * downstream `log.*` calls pick up the same fields.
156
+ */
157
+ interface LogContext {
158
+ traceId?: string;
159
+ chatId?: string;
160
+ msgId?: string;
161
+ }
162
+ type LogFields = Record<string, unknown>;
163
+ declare function reportMetric(name: string, value: number, tags?: Record<string, string>): void;
164
+ declare function reportError(err: unknown, ctx?: Record<string, unknown>): void;
165
+
166
+ /**
167
+ * Optional telemetry hook.
168
+ *
169
+ * The bridge itself ships **no** telemetry: by default this module is inert
170
+ * (a noop adapter), pulls in zero dependencies, and makes zero network calls.
171
+ *
172
+ * An operator who wants monitoring points `LARK_CHANNEL_TELEMETRY_MODULE` at a
173
+ * package that default-exports (or exposes `createAdapter`) an `AdapterFactory`.
174
+ * That package — not this repo — owns the vendor SDK, endpoints, and keys.
175
+ * See README "Optional telemetry".
176
+ */
177
+ /** A single structured event — mirrors what `logger.emit` produces. */
178
+ interface TelemetryEvent {
179
+ level: 'info' | 'warn' | 'error';
180
+ phase: string;
181
+ event: string;
182
+ fields: LogFields;
183
+ ctx: LogContext;
184
+ /** ISO-8601 timestamp, same value written to the JSON log line. */
185
+ ts: string;
186
+ }
187
+ /** Sink an external package provides to receive bridge telemetry. */
188
+ interface TelemetryAdapter {
189
+ /** Called for every `log.*` call (info / warn / error). */
190
+ emit(event: TelemetryEvent): void;
191
+ /** Capture an error/exception with its stack. */
192
+ recordError(err: unknown, ctx?: Record<string, unknown>): void;
193
+ /** Record a numeric metric with optional string tags. */
194
+ recordMetric(name: string, value: number, tags?: Record<string, string>): void;
195
+ /** Flush buffered events; `timeoutMs` bounds the wait. Optional. */
196
+ flush?(timeoutMs?: number): Promise<void> | void;
197
+ /** Release resources on shutdown. Optional. */
198
+ close?(): Promise<void> | void;
199
+ }
200
+ /** Runtime metadata handed to the factory when the adapter is loaded. */
201
+ interface AdapterMeta {
202
+ version: string;
203
+ appId?: string;
204
+ tenant?: string;
205
+ /** Host machine identifier (e.g. `os.hostname()`). Useful as a stable
206
+ * `deviceId` for the telemetry sink — survives process restarts. */
207
+ hostname?: string;
208
+ }
209
+ /** The shape an external module must default-export (or expose as `createAdapter`). */
210
+ type AdapterFactory = (meta: AdapterMeta) => TelemetryAdapter;
211
+
212
+ export { type AdapterFactory, type AdapterMeta, type Block, type FooterStatus, type RunState, type TelemetryAdapter, type TelemetryEvent, type Terminal, type ToolEntry, type ToolStatus, finalizeIfRunning, initialState, markInterrupted, reduce, renderCard, renderText, reportError, reportMetric };