langsmith 0.5.24 → 0.5.26
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.
- package/dist/client.cjs +9 -3
- package/dist/client.js +9 -3
- package/dist/experimental/anthropic/context.cjs +419 -49
- package/dist/experimental/anthropic/context.js +420 -50
- package/dist/experimental/anthropic/index.cjs +78 -10
- package/dist/experimental/anthropic/index.js +80 -12
- package/dist/experimental/anthropic/messages.cjs +53 -0
- package/dist/experimental/anthropic/messages.d.ts +6 -0
- package/dist/experimental/anthropic/messages.js +52 -0
- package/dist/experimental/anthropic/transcripts.cjs +144 -0
- package/dist/experimental/anthropic/transcripts.d.ts +22 -0
- package/dist/experimental/anthropic/transcripts.js +141 -0
- package/dist/experimental/anthropic/types.d.ts +1 -0
- package/dist/experimental/anthropic/usage.cjs +19 -20
- package/dist/experimental/anthropic/usage.d.ts +2 -1
- package/dist/experimental/anthropic/usage.js +18 -20
- package/dist/experimental/opencode/index.cjs +36 -0
- package/dist/experimental/opencode/index.d.ts +3 -0
- package/dist/experimental/opencode/index.js +32 -0
- package/dist/experimental/opencode/tracer.cjs +389 -0
- package/dist/experimental/opencode/tracer.d.ts +30 -0
- package/dist/experimental/opencode/tracer.js +385 -0
- package/dist/experimental/otel/setup.cjs +1 -1
- package/dist/experimental/otel/setup.js +1 -1
- package/dist/experimental/sandbox/sandbox.cjs +6 -2
- package/dist/experimental/sandbox/sandbox.d.ts +5 -1
- package/dist/experimental/sandbox/sandbox.js +6 -2
- package/dist/experimental/sandbox/types.d.ts +3 -1
- package/dist/experimental/vercel/index.cjs +1 -1
- package/dist/experimental/vercel/index.js +1 -1
- package/dist/experimental/vercel/middleware.cjs +2 -1
- package/dist/experimental/vercel/middleware.js +2 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/schemas.d.ts +4 -0
- package/dist/singletons/traceable.cjs +1 -3
- package/dist/singletons/traceable.js +1 -3
- package/dist/traceable.cjs +1 -3
- package/dist/traceable.js +1 -3
- package/dist/utils/_git.cjs +2 -2
- package/dist/utils/_git.js +2 -2
- package/dist/utils/env.cjs +2 -2
- package/dist/utils/env.js +2 -2
- package/dist/utils/error.cjs +2 -2
- package/dist/utils/error.js +2 -2
- package/dist/utils/jestlike/reporter.cjs +1 -1
- package/dist/utils/jestlike/reporter.js +1 -1
- package/dist/utils/jestlike/vendor/chain.cjs +2 -3
- package/dist/utils/jestlike/vendor/chain.js +2 -3
- package/dist/vitest/utils/esm.mjs +4 -4
- package/dist/wrappers/gemini.cjs +1 -1
- package/dist/wrappers/gemini.js +1 -1
- package/dist/wrappers/openai.cjs +2 -6
- package/dist/wrappers/openai.js +2 -6
- package/experimental/opencode.cjs +1 -0
- package/experimental/opencode.d.cts +1 -0
- package/experimental/opencode.d.ts +1 -0
- package/experimental/opencode.js +1 -0
- package/package.json +24 -18
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OpenCodeSessionTracer = void 0;
|
|
4
|
+
// import type { Event, FilePart, Message, Model, Part } from "@opencode-ai/sdk";
|
|
5
|
+
const run_trees_js_1 = require("../../run_trees.cjs");
|
|
6
|
+
const index_js_1 = require("../../index.cjs");
|
|
7
|
+
const dedupeParts = (parts) => {
|
|
8
|
+
const partById = {};
|
|
9
|
+
for (const part of parts) {
|
|
10
|
+
partById[part.id] = { ...partById[part.id], ...part };
|
|
11
|
+
}
|
|
12
|
+
return Object.values(partById);
|
|
13
|
+
};
|
|
14
|
+
const convertToStandardContentBlock = (part) => {
|
|
15
|
+
// Ignore AI SDK specific parts
|
|
16
|
+
if (part.type === "step-start" || part.type === "step-finish") {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
if (part.type === "text") {
|
|
20
|
+
return {
|
|
21
|
+
type: "text",
|
|
22
|
+
text: part.text,
|
|
23
|
+
extras: part.metadata,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (part.type === "reasoning") {
|
|
27
|
+
return {
|
|
28
|
+
type: "thinking",
|
|
29
|
+
thinking: part.text,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (part.type === "file") {
|
|
33
|
+
return {
|
|
34
|
+
type: "file",
|
|
35
|
+
id: part.filename ?? part.id,
|
|
36
|
+
url: part.url,
|
|
37
|
+
mime_type: part.mime,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (part.type === "tool") {
|
|
41
|
+
return {
|
|
42
|
+
type: "tool_use",
|
|
43
|
+
name: part.tool,
|
|
44
|
+
input: part.state.input,
|
|
45
|
+
id: part.callID,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (part.type === "compaction") {
|
|
49
|
+
return {
|
|
50
|
+
type: "compaction",
|
|
51
|
+
data: { auto: part.auto },
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
type: "non_standard",
|
|
56
|
+
value: part,
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
const convertToStandardMessages = (messages) => {
|
|
60
|
+
return messages.flatMap((message) => {
|
|
61
|
+
const parts = dedupeParts(message.parts);
|
|
62
|
+
if (message.info?.role === "assistant") {
|
|
63
|
+
// split out into "model message"
|
|
64
|
+
return [
|
|
65
|
+
{
|
|
66
|
+
role: "assistant",
|
|
67
|
+
content: parts.flatMap(convertToStandardContentBlock),
|
|
68
|
+
},
|
|
69
|
+
...parts.flatMap((part) => {
|
|
70
|
+
if (part.type !== "tool")
|
|
71
|
+
return [];
|
|
72
|
+
if (part.state.status === "completed") {
|
|
73
|
+
return {
|
|
74
|
+
role: "tool",
|
|
75
|
+
content: part.state.output,
|
|
76
|
+
name: part.tool,
|
|
77
|
+
id: part.id,
|
|
78
|
+
tool_call_id: part.callID,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (part.state.status === "error") {
|
|
82
|
+
return {
|
|
83
|
+
role: "tool",
|
|
84
|
+
content: part.state.error,
|
|
85
|
+
name: part.tool,
|
|
86
|
+
id: part.id,
|
|
87
|
+
tool_call_id: part.callID,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return [];
|
|
91
|
+
}),
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
if (message.info?.role === "user") {
|
|
95
|
+
return {
|
|
96
|
+
role: "user",
|
|
97
|
+
content: parts.flatMap(convertToStandardContentBlock),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return [];
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
class OpenCodeSessionTracer {
|
|
104
|
+
constructor(inputConfig) {
|
|
105
|
+
Object.defineProperty(this, "sessions", {
|
|
106
|
+
enumerable: true,
|
|
107
|
+
configurable: true,
|
|
108
|
+
writable: true,
|
|
109
|
+
value: {}
|
|
110
|
+
});
|
|
111
|
+
Object.defineProperty(this, "client", {
|
|
112
|
+
enumerable: true,
|
|
113
|
+
configurable: true,
|
|
114
|
+
writable: true,
|
|
115
|
+
value: void 0
|
|
116
|
+
});
|
|
117
|
+
Object.defineProperty(this, "inputConfig", {
|
|
118
|
+
enumerable: true,
|
|
119
|
+
configurable: true,
|
|
120
|
+
writable: true,
|
|
121
|
+
value: void 0
|
|
122
|
+
});
|
|
123
|
+
this.inputConfig = inputConfig ?? {};
|
|
124
|
+
this.client = inputConfig?.client ?? new index_js_1.Client();
|
|
125
|
+
}
|
|
126
|
+
getSession(sessionID) {
|
|
127
|
+
this.sessions[sessionID] ??= {
|
|
128
|
+
messages: {},
|
|
129
|
+
traces: {},
|
|
130
|
+
history: undefined,
|
|
131
|
+
pendingSystem: undefined,
|
|
132
|
+
postRunQueue: [],
|
|
133
|
+
parentID: undefined,
|
|
134
|
+
};
|
|
135
|
+
return this.sessions[sessionID];
|
|
136
|
+
}
|
|
137
|
+
getMessage(sessionID, messageID) {
|
|
138
|
+
const session = this.getSession(sessionID);
|
|
139
|
+
session.messages[messageID] ??= {
|
|
140
|
+
info: undefined,
|
|
141
|
+
parts: [],
|
|
142
|
+
complete: false,
|
|
143
|
+
system: undefined,
|
|
144
|
+
};
|
|
145
|
+
// Attach pending system to assistant messages
|
|
146
|
+
if (session.pendingSystem != null &&
|
|
147
|
+
session.messages[messageID]?.info?.role === "assistant") {
|
|
148
|
+
session.messages[messageID].system = session.pendingSystem;
|
|
149
|
+
session.pendingSystem = undefined;
|
|
150
|
+
}
|
|
151
|
+
return session.messages[messageID];
|
|
152
|
+
}
|
|
153
|
+
getProviderMetadata(run) {
|
|
154
|
+
const info = run.info;
|
|
155
|
+
if (!info || info.role !== "assistant")
|
|
156
|
+
return {};
|
|
157
|
+
const model = run.system?.model;
|
|
158
|
+
const modelId = model?.id ?? info.modelID;
|
|
159
|
+
const providerId = model?.providerID ?? info.providerID;
|
|
160
|
+
const ls_invocation_params = {
|
|
161
|
+
model: modelId,
|
|
162
|
+
providerID: providerId,
|
|
163
|
+
};
|
|
164
|
+
if (model?.name)
|
|
165
|
+
ls_invocation_params.model_display_name = model.name;
|
|
166
|
+
if (model?.api?.id)
|
|
167
|
+
ls_invocation_params.api_model_id = model.api.id;
|
|
168
|
+
if (model?.api?.url)
|
|
169
|
+
ls_invocation_params.api_url = model.api.url;
|
|
170
|
+
if (model?.api?.npm)
|
|
171
|
+
ls_invocation_params.api_npm_package = model.api.npm;
|
|
172
|
+
const stepFinish = run.parts.find((part) => part.type === "step-finish");
|
|
173
|
+
return {
|
|
174
|
+
ls_model_name: modelId,
|
|
175
|
+
ls_provider: providerId,
|
|
176
|
+
ls_model_type: "chat",
|
|
177
|
+
ls_invocation_params,
|
|
178
|
+
usage_metadata: stepFinish
|
|
179
|
+
? {
|
|
180
|
+
input_tokens: stepFinish.tokens.input,
|
|
181
|
+
output_tokens: stepFinish.tokens.output + stepFinish.tokens.reasoning,
|
|
182
|
+
total_tokens: stepFinish.tokens.input +
|
|
183
|
+
stepFinish.tokens.output +
|
|
184
|
+
stepFinish.tokens.reasoning,
|
|
185
|
+
input_token_details: {
|
|
186
|
+
cache_read: stepFinish.tokens.cache.read,
|
|
187
|
+
cache_creation: stepFinish.tokens.cache.write,
|
|
188
|
+
},
|
|
189
|
+
}
|
|
190
|
+
: undefined,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
async sendTrace(sessionID, runs, options) {
|
|
194
|
+
const session = this.getSession(sessionID);
|
|
195
|
+
const userRunIdx = runs.findIndex(({ info }) => info?.role === "user");
|
|
196
|
+
const userRun = runs.at(userRunIdx);
|
|
197
|
+
const agentRuns = runs.slice(userRunIdx + 1);
|
|
198
|
+
if (userRunIdx === -1 || userRun == null)
|
|
199
|
+
return;
|
|
200
|
+
const parentStartTime = userRun?.info?.time?.created ?? Date.now();
|
|
201
|
+
const parentEndTime = agentRuns
|
|
202
|
+
.flatMap((run) => run.parts)
|
|
203
|
+
.reduce((acc, part) => {
|
|
204
|
+
if (!("time" in part) || part.time == null)
|
|
205
|
+
return acc;
|
|
206
|
+
if (!("end" in part.time) || typeof part.time.end !== "number")
|
|
207
|
+
return acc;
|
|
208
|
+
return Math.max(acc, part.time.end);
|
|
209
|
+
}, parentStartTime);
|
|
210
|
+
if (userRun?.info) {
|
|
211
|
+
session.history ??= [];
|
|
212
|
+
session.history.push({ info: userRun.info, parts: userRun.parts });
|
|
213
|
+
}
|
|
214
|
+
const parentConfig = {
|
|
215
|
+
name: "opencode.session",
|
|
216
|
+
run_type: "chain",
|
|
217
|
+
start_time: parentStartTime,
|
|
218
|
+
end_time: parentEndTime,
|
|
219
|
+
extra: {
|
|
220
|
+
metadata: {
|
|
221
|
+
ls_integration: "opencode-js",
|
|
222
|
+
ls_agent_type: "root",
|
|
223
|
+
thread_id: sessionID,
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
inputs: { messages: convertToStandardMessages([userRun]) },
|
|
227
|
+
outputs: { messages: convertToStandardMessages(agentRuns) },
|
|
228
|
+
...this.inputConfig,
|
|
229
|
+
client: this.client,
|
|
230
|
+
};
|
|
231
|
+
const parent = options?.parentRunTree?.createChild(parentConfig) ??
|
|
232
|
+
new run_trees_js_1.RunTree(parentConfig);
|
|
233
|
+
session.postRunQueue.push(parent.postRun());
|
|
234
|
+
for (const run of agentRuns) {
|
|
235
|
+
const startTime = run.info?.time?.created ?? Date.now();
|
|
236
|
+
const endTime = run.parts.reduce((acc, part) => {
|
|
237
|
+
if (!("time" in part) || part.time == null)
|
|
238
|
+
return acc;
|
|
239
|
+
if (!("end" in part.time) || typeof part.time.end !== "number")
|
|
240
|
+
return acc;
|
|
241
|
+
return Math.max(acc, part.time.end);
|
|
242
|
+
}, startTime);
|
|
243
|
+
const parts = dedupeParts(run.parts);
|
|
244
|
+
// Create child runs for tool parts
|
|
245
|
+
const child = parent.createChild({
|
|
246
|
+
name: "opencode.assistant.turn",
|
|
247
|
+
run_type: "llm",
|
|
248
|
+
start_time: startTime,
|
|
249
|
+
end_time: endTime,
|
|
250
|
+
inputs: {
|
|
251
|
+
messages: [
|
|
252
|
+
...(run.system?.system
|
|
253
|
+
? [{ role: "system", content: run.system.system.join("\n") }]
|
|
254
|
+
: []),
|
|
255
|
+
...convertToStandardMessages(session.history ?? []),
|
|
256
|
+
],
|
|
257
|
+
},
|
|
258
|
+
outputs: { messages: convertToStandardMessages([run]) },
|
|
259
|
+
extra: { metadata: this.getProviderMetadata(run) },
|
|
260
|
+
});
|
|
261
|
+
session.postRunQueue.push(child.postRun());
|
|
262
|
+
for (const toolPart of parts) {
|
|
263
|
+
if (toolPart.type !== "tool")
|
|
264
|
+
continue;
|
|
265
|
+
const state = toolPart.state;
|
|
266
|
+
// Try looking for subgraph
|
|
267
|
+
let toolHandled = false;
|
|
268
|
+
if (state.metadata?.sessionId) {
|
|
269
|
+
const session = this.getSession(state.metadata.sessionId);
|
|
270
|
+
for (const trace of Object.values(session.traces)) {
|
|
271
|
+
if (trace.state !== "subgraph")
|
|
272
|
+
continue;
|
|
273
|
+
await this.sendTrace(state.metadata.sessionId, trace.runs, {
|
|
274
|
+
parentRunTree: child,
|
|
275
|
+
});
|
|
276
|
+
toolHandled = true;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (toolHandled)
|
|
280
|
+
continue;
|
|
281
|
+
const tool = child.createChild({
|
|
282
|
+
name: toolPart.tool,
|
|
283
|
+
run_type: "tool",
|
|
284
|
+
inputs: state.input ?? {},
|
|
285
|
+
outputs: {
|
|
286
|
+
output: state.output,
|
|
287
|
+
attachments: state.attachments?.map(convertToStandardContentBlock) ??
|
|
288
|
+
undefined,
|
|
289
|
+
},
|
|
290
|
+
start_time: state.time?.start ?? startTime,
|
|
291
|
+
end_time: state.time?.end ?? endTime,
|
|
292
|
+
error: state.error,
|
|
293
|
+
extra: { metadata: state.metadata },
|
|
294
|
+
});
|
|
295
|
+
session.postRunQueue.push(tool.postRun());
|
|
296
|
+
}
|
|
297
|
+
if (run.info) {
|
|
298
|
+
session.history ??= [];
|
|
299
|
+
session.history.push({ info: run.info, parts });
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async flush() {
|
|
304
|
+
await Promise.all(Object.values(this.sessions).flatMap((session) => session.postRunQueue));
|
|
305
|
+
await this.client.flush();
|
|
306
|
+
await this.client.awaitPendingTraceBatches();
|
|
307
|
+
}
|
|
308
|
+
async handleSystem(input, output) {
|
|
309
|
+
if (!input.sessionID)
|
|
310
|
+
return;
|
|
311
|
+
const session = this.getSession(input.sessionID);
|
|
312
|
+
session.pendingSystem = { model: input.model, system: output.system };
|
|
313
|
+
}
|
|
314
|
+
async handleSessionLoad(sessionID, history) {
|
|
315
|
+
const session = this.getSession(sessionID);
|
|
316
|
+
if (session.history)
|
|
317
|
+
return;
|
|
318
|
+
session.history = await history(sessionID);
|
|
319
|
+
}
|
|
320
|
+
async handleEvent({ event: { properties, type } }) {
|
|
321
|
+
if (type === "server.instance.disposed") {
|
|
322
|
+
await this.flush();
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const sessionID = "sessionID" in properties && typeof properties.sessionID === "string"
|
|
326
|
+
? properties.sessionID
|
|
327
|
+
: undefined;
|
|
328
|
+
if (!sessionID)
|
|
329
|
+
return;
|
|
330
|
+
const session = this.getSession(sessionID);
|
|
331
|
+
let updatedID;
|
|
332
|
+
if (type === "session.created" || type === "session.updated") {
|
|
333
|
+
session.parentID = properties.info.parentID;
|
|
334
|
+
}
|
|
335
|
+
if (type === "message.updated") {
|
|
336
|
+
const message = this.getMessage(sessionID, properties.info.id);
|
|
337
|
+
message.info = properties.info;
|
|
338
|
+
updatedID = properties.info.id;
|
|
339
|
+
}
|
|
340
|
+
if (type === "message.part.updated") {
|
|
341
|
+
const message = this.getMessage(sessionID, properties.part.messageID);
|
|
342
|
+
message.parts.push(properties.part);
|
|
343
|
+
updatedID = properties.part.messageID;
|
|
344
|
+
}
|
|
345
|
+
if (type === "message.part.removed") {
|
|
346
|
+
const message = this.getMessage(sessionID, properties.messageID);
|
|
347
|
+
message.parts = message.parts.filter((part) => part.id !== properties.partID);
|
|
348
|
+
updatedID = properties.messageID;
|
|
349
|
+
}
|
|
350
|
+
if (type === "message.removed") {
|
|
351
|
+
const session = this.getSession(sessionID);
|
|
352
|
+
delete session.messages[properties.messageID];
|
|
353
|
+
}
|
|
354
|
+
// Message consolidation logic
|
|
355
|
+
const message = updatedID ? session.messages[updatedID] : undefined;
|
|
356
|
+
if (message?.info?.role == null)
|
|
357
|
+
return;
|
|
358
|
+
// Skip if message is already marked as complete
|
|
359
|
+
if (message.complete)
|
|
360
|
+
return;
|
|
361
|
+
message.complete =
|
|
362
|
+
(message.info?.role === "user" && message.parts.length > 0) ||
|
|
363
|
+
(message.info?.role === "assistant" &&
|
|
364
|
+
message.parts.some((part) => part.type === "step-finish"));
|
|
365
|
+
// Now we're complete, add to a trace
|
|
366
|
+
if (message.complete) {
|
|
367
|
+
const traceId = message.info.role === "user" ? message.info.id : message.info.parentID;
|
|
368
|
+
session.traces[traceId] ??= { runs: [], state: false };
|
|
369
|
+
const trace = session.traces[traceId];
|
|
370
|
+
trace.runs.push(message);
|
|
371
|
+
// Skip if trace is already marked as complete
|
|
372
|
+
if (trace.state !== false)
|
|
373
|
+
return;
|
|
374
|
+
trace.state = trace.runs.some((run) => run.parts.some(
|
|
375
|
+
// trace is marked complete when there's a step-finish part with reason "stop"
|
|
376
|
+
(part) => part.type === "step-finish" && part.reason === "stop"));
|
|
377
|
+
if (trace.state) {
|
|
378
|
+
// If trace is part of a subagent call, mark it as a subgraph and submit
|
|
379
|
+
// when parent is being submitted (to preserve correct dotted order)
|
|
380
|
+
if (session.parentID) {
|
|
381
|
+
trace.state = "subgraph";
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
await this.sendTrace(sessionID, trace.runs);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
exports.OpenCodeSessionTracer = OpenCodeSessionTracer;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type RunTreeConfig } from "../../run_trees.js";
|
|
2
|
+
type Event = any;
|
|
3
|
+
type Message = any;
|
|
4
|
+
type Model = any;
|
|
5
|
+
type Part = any;
|
|
6
|
+
export declare class OpenCodeSessionTracer {
|
|
7
|
+
private sessions;
|
|
8
|
+
private client;
|
|
9
|
+
private inputConfig;
|
|
10
|
+
constructor(inputConfig?: Partial<RunTreeConfig>);
|
|
11
|
+
private getSession;
|
|
12
|
+
private getMessage;
|
|
13
|
+
private getProviderMetadata;
|
|
14
|
+
private sendTrace;
|
|
15
|
+
flush(): Promise<void>;
|
|
16
|
+
handleSystem(input: {
|
|
17
|
+
model: Model;
|
|
18
|
+
sessionID?: string | undefined;
|
|
19
|
+
}, output: {
|
|
20
|
+
system: string[];
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
handleSessionLoad(sessionID: string, history: (sessionID: string) => Promise<{
|
|
23
|
+
info: Message;
|
|
24
|
+
parts: Part[];
|
|
25
|
+
}[]>): Promise<void>;
|
|
26
|
+
handleEvent({ event: { properties, type } }: {
|
|
27
|
+
event: Event;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
export {};
|