@browserbasehq/orca 3.2.0-preview.2 → 3.2.0-preview.4
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/cjs/lib/v3/agent/AnthropicCUAClient.js +5 -5
- package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
- package/dist/cjs/lib/v3/agent/GoogleCUAClient.js +5 -5
- package/dist/cjs/lib/v3/agent/GoogleCUAClient.js.map +1 -1
- package/dist/cjs/lib/v3/agent/OpenAICUAClient.js +5 -5
- package/dist/cjs/lib/v3/agent/OpenAICUAClient.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/act.js +1 -10
- package/dist/cjs/lib/v3/agent/tools/act.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/ariaTree.js +1 -12
- package/dist/cjs/lib/v3/agent/tools/ariaTree.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/braveSearch.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/browserbaseSearch.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/click.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/clickAndHold.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/extract.js +1 -10
- package/dist/cjs/lib/v3/agent/tools/extract.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/fillFormVision.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/fillform.js +1 -10
- package/dist/cjs/lib/v3/agent/tools/fillform.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/index.d.ts +2 -2
- package/dist/cjs/lib/v3/agent/tools/index.js +53 -5
- package/dist/cjs/lib/v3/agent/tools/index.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/keys.d.ts +1 -1
- package/dist/cjs/lib/v3/agent/tools/keys.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/type.js.map +1 -1
- package/dist/cjs/lib/v3/api.js +9 -2
- package/dist/cjs/lib/v3/api.js.map +1 -1
- package/dist/cjs/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
- package/dist/cjs/lib/v3/flowlogger/EventEmitter.js +30 -0
- package/dist/cjs/lib/v3/flowlogger/EventEmitter.js.map +1 -0
- package/dist/cjs/lib/v3/flowlogger/EventSink.d.ts +44 -0
- package/dist/cjs/lib/v3/flowlogger/EventSink.js +217 -0
- package/dist/cjs/lib/v3/flowlogger/EventSink.js.map +1 -0
- package/dist/cjs/lib/v3/flowlogger/EventStore.d.ts +26 -0
- package/dist/cjs/lib/v3/flowlogger/EventStore.js +135 -0
- package/dist/cjs/lib/v3/flowlogger/EventStore.js.map +1 -0
- package/dist/{esm/lib/v3/flowLogger.d.ts → cjs/lib/v3/flowlogger/FlowLogger.d.ts} +32 -31
- package/dist/cjs/lib/v3/flowlogger/FlowLogger.js +591 -0
- package/dist/cjs/lib/v3/flowlogger/FlowLogger.js.map +1 -0
- package/dist/cjs/lib/v3/flowlogger/prettify.d.ts +6 -0
- package/dist/cjs/lib/v3/flowlogger/prettify.js +395 -0
- package/dist/cjs/lib/v3/flowlogger/prettify.js.map +1 -0
- package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js +26 -28
- package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
- package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +2 -2
- package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
- package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js +3 -5
- package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
- package/dist/cjs/lib/v3/llm/aisdk.js +9 -9
- package/dist/cjs/lib/v3/llm/aisdk.js.map +1 -1
- package/dist/cjs/lib/v3/types/public/options.d.ts +2 -0
- package/dist/cjs/lib/v3/types/public/options.js.map +1 -1
- package/dist/cjs/lib/v3/understudy/cdp.d.ts +1 -1
- package/dist/cjs/lib/v3/understudy/cdp.js +83 -43
- package/dist/cjs/lib/v3/understudy/cdp.js.map +1 -1
- package/dist/cjs/lib/v3/understudy/page.js +18 -23
- package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
- package/dist/cjs/lib/v3/v3.d.ts +5 -5
- package/dist/cjs/lib/v3/v3.js +48 -46
- package/dist/cjs/lib/v3/v3.js.map +1 -1
- package/dist/cjs/tests/integration/flowLogger.spec.d.ts +1 -0
- package/dist/cjs/tests/integration/flowLogger.spec.js +714 -0
- package/dist/cjs/tests/integration/flowLogger.spec.js.map +1 -0
- package/dist/cjs/tests/integration/testUtils.d.ts +33 -0
- package/dist/cjs/tests/integration/testUtils.js +144 -0
- package/dist/cjs/tests/integration/testUtils.js.map +1 -1
- package/dist/cjs/tests/integration/timeouts.spec.js +112 -2
- package/dist/cjs/tests/integration/timeouts.spec.js.map +1 -1
- package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
- package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js +95 -0
- package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
- package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
- package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js +43 -0
- package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
- package/dist/cjs/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
- package/dist/cjs/tests/unit/flowlogger-eventstore.test.js +250 -0
- package/dist/cjs/tests/unit/flowlogger-eventstore.test.js.map +1 -0
- package/dist/esm/lib/v3/agent/AnthropicCUAClient.js +1 -1
- package/dist/esm/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
- package/dist/esm/lib/v3/agent/GoogleCUAClient.js +1 -1
- package/dist/esm/lib/v3/agent/GoogleCUAClient.js.map +1 -1
- package/dist/esm/lib/v3/agent/OpenAICUAClient.js +1 -1
- package/dist/esm/lib/v3/agent/OpenAICUAClient.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/act.js +1 -10
- package/dist/esm/lib/v3/agent/tools/act.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/ariaTree.js +1 -12
- package/dist/esm/lib/v3/agent/tools/ariaTree.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/braveSearch.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/browserbaseSearch.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/click.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/clickAndHold.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/extract.js +1 -10
- package/dist/esm/lib/v3/agent/tools/extract.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/fillFormVision.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/fillform.js +1 -10
- package/dist/esm/lib/v3/agent/tools/fillform.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/index.d.ts +2 -2
- package/dist/esm/lib/v3/agent/tools/index.js +53 -5
- package/dist/esm/lib/v3/agent/tools/index.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/keys.d.ts +1 -1
- package/dist/esm/lib/v3/agent/tools/keys.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/type.js.map +1 -1
- package/dist/esm/lib/v3/api.js +9 -2
- package/dist/esm/lib/v3/api.js.map +1 -1
- package/dist/esm/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
- package/dist/esm/lib/v3/flowlogger/EventEmitter.js +26 -0
- package/dist/esm/lib/v3/flowlogger/EventEmitter.js.map +1 -0
- package/dist/esm/lib/v3/flowlogger/EventSink.d.ts +44 -0
- package/dist/esm/lib/v3/flowlogger/EventSink.js +206 -0
- package/dist/esm/lib/v3/flowlogger/EventSink.js.map +1 -0
- package/dist/esm/lib/v3/flowlogger/EventStore.d.ts +26 -0
- package/dist/esm/lib/v3/flowlogger/EventStore.js +127 -0
- package/dist/esm/lib/v3/flowlogger/EventStore.js.map +1 -0
- package/dist/{cjs/lib/v3/flowLogger.d.ts → esm/lib/v3/flowlogger/FlowLogger.d.ts} +32 -31
- package/dist/esm/lib/v3/flowlogger/FlowLogger.js +583 -0
- package/dist/esm/lib/v3/flowlogger/FlowLogger.js.map +1 -0
- package/dist/esm/lib/v3/flowlogger/prettify.d.ts +6 -0
- package/dist/esm/lib/v3/flowlogger/prettify.js +389 -0
- package/dist/esm/lib/v3/flowlogger/prettify.js.map +1 -0
- package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js +25 -27
- package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
- package/dist/esm/lib/v3/handlers/v3AgentHandler.js +1 -1
- package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
- package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js +2 -4
- package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
- package/dist/esm/lib/v3/llm/aisdk.js +1 -1
- package/dist/esm/lib/v3/llm/aisdk.js.map +1 -1
- package/dist/esm/lib/v3/types/public/options.d.ts +2 -0
- package/dist/esm/lib/v3/types/public/options.js.map +1 -1
- package/dist/esm/lib/v3/understudy/cdp.d.ts +1 -1
- package/dist/esm/lib/v3/understudy/cdp.js +78 -38
- package/dist/esm/lib/v3/understudy/cdp.js.map +1 -1
- package/dist/esm/lib/v3/understudy/page.js +13 -18
- package/dist/esm/lib/v3/understudy/page.js.map +1 -1
- package/dist/esm/lib/v3/v3.d.ts +5 -5
- package/dist/esm/lib/v3/v3.js +43 -41
- package/dist/esm/lib/v3/v3.js.map +1 -1
- package/dist/esm/tests/integration/flowLogger.spec.d.ts +1 -0
- package/dist/esm/tests/integration/flowLogger.spec.js +712 -0
- package/dist/esm/tests/integration/flowLogger.spec.js.map +1 -0
- package/dist/esm/tests/integration/testUtils.d.ts +33 -0
- package/dist/esm/tests/integration/testUtils.js +138 -0
- package/dist/esm/tests/integration/testUtils.js.map +1 -1
- package/dist/esm/tests/integration/timeouts.spec.js +112 -2
- package/dist/esm/tests/integration/timeouts.spec.js.map +1 -1
- package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
- package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js +93 -0
- package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
- package/dist/esm/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
- package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js +41 -0
- package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
- package/dist/esm/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
- package/dist/esm/tests/unit/flowlogger-eventstore.test.js +248 -0
- package/dist/esm/tests/unit/flowlogger-eventstore.test.js.map +1 -0
- package/package.json +3 -1
- package/dist/cjs/lib/v3/eventStore.d.ts +0 -41
- package/dist/cjs/lib/v3/eventStore.js +0 -375
- package/dist/cjs/lib/v3/eventStore.js.map +0 -1
- package/dist/cjs/lib/v3/flowLogger.js +0 -470
- package/dist/cjs/lib/v3/flowLogger.js.map +0 -1
- package/dist/esm/lib/v3/eventStore.d.ts +0 -41
- package/dist/esm/lib/v3/eventStore.js +0 -363
- package/dist/esm/lib/v3/eventStore.js.map +0 -1
- package/dist/esm/lib/v3/flowLogger.js +0 -462
- package/dist/esm/lib/v3/flowLogger.js.map +0 -1
|
@@ -1,470 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FlowLogger = exports.FlowEvent = void 0;
|
|
4
|
-
exports.extractLlmPromptSummary = extractLlmPromptSummary;
|
|
5
|
-
exports.extractLlmCuaPromptSummary = extractLlmCuaPromptSummary;
|
|
6
|
-
exports.extractLlmCuaResponseSummary = extractLlmCuaResponseSummary;
|
|
7
|
-
const node_async_hooks_1 = require("node:async_hooks");
|
|
8
|
-
const uuid_1 = require("uuid");
|
|
9
|
-
class FlowEvent {
|
|
10
|
-
static createEventId(eventIdSuffix) {
|
|
11
|
-
const rawEventId = (0, uuid_1.v7)();
|
|
12
|
-
return `${rawEventId.slice(0, -1)}${eventIdSuffix || "0"}`;
|
|
13
|
-
}
|
|
14
|
-
// base required fields for all events:
|
|
15
|
-
eventType;
|
|
16
|
-
eventId;
|
|
17
|
-
eventParentIds;
|
|
18
|
-
createdAt;
|
|
19
|
-
sessionId;
|
|
20
|
-
data; // event payload (e.g. params, action, result, error, etc.)
|
|
21
|
-
constructor(input) {
|
|
22
|
-
if (!input.sessionId) {
|
|
23
|
-
throw new Error("FlowEvent.sessionId is required.");
|
|
24
|
-
}
|
|
25
|
-
if (input.eventId &&
|
|
26
|
-
input.eventIdSuffix &&
|
|
27
|
-
!input.eventId.endsWith(input.eventIdSuffix)) {
|
|
28
|
-
throw new Error("FlowEvent cannot take both eventId and eventIdSuffix.");
|
|
29
|
-
}
|
|
30
|
-
this.eventType = input.eventType.endsWith("Event")
|
|
31
|
-
? input.eventType
|
|
32
|
-
: `${input.eventType}Event`;
|
|
33
|
-
this.eventId =
|
|
34
|
-
input.eventId ?? FlowEvent.createEventId(input.eventIdSuffix ?? "0");
|
|
35
|
-
this.eventParentIds = input.eventParentIds ?? [];
|
|
36
|
-
this.createdAt = input.createdAt ?? new Date().toISOString();
|
|
37
|
-
this.sessionId = input.sessionId;
|
|
38
|
-
this.data = input.data ?? {};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
exports.FlowEvent = FlowEvent;
|
|
42
|
-
const loggerContext = new node_async_hooks_1.AsyncLocalStorage();
|
|
43
|
-
function dataToKb(data) {
|
|
44
|
-
return ((data.length * 0.75) / 1024).toFixed(1);
|
|
45
|
-
}
|
|
46
|
-
// =============================================================================
|
|
47
|
-
// Flow Logger - Main API
|
|
48
|
-
// =============================================================================
|
|
49
|
-
class FlowLogger {
|
|
50
|
-
static cloneContext(ctx) {
|
|
51
|
-
return {
|
|
52
|
-
...ctx,
|
|
53
|
-
parentEvents: ctx.parentEvents.map((event) => ({
|
|
54
|
-
...event,
|
|
55
|
-
eventParentIds: [...event.eventParentIds],
|
|
56
|
-
})),
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
static emit(event) {
|
|
60
|
-
const ctx = FlowLogger.currentContext;
|
|
61
|
-
const emittedEvent = new FlowEvent({
|
|
62
|
-
...event,
|
|
63
|
-
eventParentIds: event.eventParentIds ??
|
|
64
|
-
ctx.parentEvents.map((parent) => parent.eventId),
|
|
65
|
-
sessionId: ctx.sessionId,
|
|
66
|
-
});
|
|
67
|
-
ctx.eventBus.emit(emittedEvent.eventType, emittedEvent);
|
|
68
|
-
return emittedEvent;
|
|
69
|
-
}
|
|
70
|
-
static async runWithAutoStatusEventLogging(options, originalMethod) {
|
|
71
|
-
const ctx = FlowLogger.currentContext;
|
|
72
|
-
const { data, eventParentIds, eventType, eventIdSuffix } = options;
|
|
73
|
-
let caughtError = null;
|
|
74
|
-
// if eventParentIds is explicitly [], this is a root event, clear the parent events in context
|
|
75
|
-
if (eventParentIds && eventParentIds.length === 0) {
|
|
76
|
-
ctx.parentEvents = [];
|
|
77
|
-
}
|
|
78
|
-
const startedEvent = FlowLogger.emit({
|
|
79
|
-
eventIdSuffix,
|
|
80
|
-
eventType,
|
|
81
|
-
data,
|
|
82
|
-
eventParentIds,
|
|
83
|
-
});
|
|
84
|
-
ctx.parentEvents.push(startedEvent);
|
|
85
|
-
try {
|
|
86
|
-
return await originalMethod();
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
caughtError = error;
|
|
90
|
-
FlowLogger.emit({
|
|
91
|
-
eventIdSuffix,
|
|
92
|
-
eventType: `${eventType}ErrorEvent`,
|
|
93
|
-
eventParentIds: [...startedEvent.eventParentIds, startedEvent.eventId],
|
|
94
|
-
data: {
|
|
95
|
-
error: error instanceof Error ? error.message : String(error),
|
|
96
|
-
durationMs: Date.now() - new Date(startedEvent.createdAt).getTime(),
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
throw error;
|
|
100
|
-
}
|
|
101
|
-
finally {
|
|
102
|
-
const parentEvent = ctx.parentEvents.pop();
|
|
103
|
-
if (parentEvent?.eventId === startedEvent.eventId && !caughtError) {
|
|
104
|
-
FlowLogger.emit({
|
|
105
|
-
eventIdSuffix,
|
|
106
|
-
eventType: `${eventType}CompletedEvent`,
|
|
107
|
-
eventParentIds: [
|
|
108
|
-
...startedEvent.eventParentIds,
|
|
109
|
-
startedEvent.eventId,
|
|
110
|
-
],
|
|
111
|
-
data: {
|
|
112
|
-
durationMs: Date.now() - new Date(startedEvent.createdAt).getTime(),
|
|
113
|
-
},
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Initialize a new logging context. Call this at the start of a session.
|
|
120
|
-
*/
|
|
121
|
-
static init(sessionId, eventBus) {
|
|
122
|
-
const ctx = {
|
|
123
|
-
sessionId,
|
|
124
|
-
eventBus,
|
|
125
|
-
parentEvents: [],
|
|
126
|
-
};
|
|
127
|
-
loggerContext.enterWith(ctx);
|
|
128
|
-
return ctx;
|
|
129
|
-
}
|
|
130
|
-
static async close(context) {
|
|
131
|
-
const ctx = context ?? loggerContext.getStore() ?? null;
|
|
132
|
-
if (!ctx)
|
|
133
|
-
return;
|
|
134
|
-
ctx.parentEvents = [];
|
|
135
|
-
}
|
|
136
|
-
static get currentContext() {
|
|
137
|
-
const ctx = loggerContext.getStore() ?? null;
|
|
138
|
-
if (!ctx) {
|
|
139
|
-
throw new Error("FlowLogger context is missing.");
|
|
140
|
-
}
|
|
141
|
-
return ctx;
|
|
142
|
-
}
|
|
143
|
-
// decorator method to wrap a class method with automatic started/completed/error events
|
|
144
|
-
static wrapWithLogging(options) {
|
|
145
|
-
return function (originalMethod) {
|
|
146
|
-
const wrappedMethod = async function (...args) {
|
|
147
|
-
return await FlowLogger.runWithLogging(options, (...boundArgs) => originalMethod.apply(this, boundArgs), args);
|
|
148
|
-
};
|
|
149
|
-
return wrappedMethod;
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
static runWithLogging(options, originalMethod, params) {
|
|
153
|
-
const eventData = {
|
|
154
|
-
...(options.data ?? {}),
|
|
155
|
-
params: [...params],
|
|
156
|
-
};
|
|
157
|
-
const execute = () => FlowLogger.runWithAutoStatusEventLogging({
|
|
158
|
-
...options,
|
|
159
|
-
data: eventData,
|
|
160
|
-
}, () => originalMethod(...params));
|
|
161
|
-
if (!options.context && !(loggerContext.getStore() ?? null)) {
|
|
162
|
-
return originalMethod(...params);
|
|
163
|
-
}
|
|
164
|
-
return options.context
|
|
165
|
-
? loggerContext.run(FlowLogger.cloneContext(options.context), execute)
|
|
166
|
-
: execute();
|
|
167
|
-
}
|
|
168
|
-
// ===========================================================================
|
|
169
|
-
// CDP Events
|
|
170
|
-
// ===========================================================================
|
|
171
|
-
static NOISY_CDP_EVENTS = new Set([
|
|
172
|
-
"Target.targetInfoChanged",
|
|
173
|
-
"Runtime.executionContextCreated",
|
|
174
|
-
"Runtime.executionContextDestroyed",
|
|
175
|
-
"Runtime.executionContextsCleared",
|
|
176
|
-
"Page.lifecycleEvent",
|
|
177
|
-
"Network.dataReceived",
|
|
178
|
-
"Network.loadingFinished",
|
|
179
|
-
"Network.requestWillBeSentExtraInfo",
|
|
180
|
-
"Network.responseReceivedExtraInfo",
|
|
181
|
-
"Network.requestWillBeSent",
|
|
182
|
-
"Network.responseReceived",
|
|
183
|
-
]);
|
|
184
|
-
static logCdpEvent(context, eventType, { method, params, result, error, targetId, }, eventParentIds) {
|
|
185
|
-
if (method.endsWith(".enable") || method === "enable") {
|
|
186
|
-
return null;
|
|
187
|
-
}
|
|
188
|
-
if (eventType === "message" && FlowLogger.NOISY_CDP_EVENTS.has(method)) {
|
|
189
|
-
return null;
|
|
190
|
-
}
|
|
191
|
-
return loggerContext.run(FlowLogger.cloneContext(context), () => FlowLogger.emit({
|
|
192
|
-
eventIdSuffix: "6",
|
|
193
|
-
eventType: eventType === "call"
|
|
194
|
-
? "CdpCallEvent"
|
|
195
|
-
: eventType === "response"
|
|
196
|
-
? "CdpResponseEvent"
|
|
197
|
-
: eventType === "responseError"
|
|
198
|
-
? "CdpResponseErrorEvent"
|
|
199
|
-
: "CdpMessageEvent",
|
|
200
|
-
eventParentIds,
|
|
201
|
-
data: {
|
|
202
|
-
method,
|
|
203
|
-
params,
|
|
204
|
-
result,
|
|
205
|
-
error,
|
|
206
|
-
targetId,
|
|
207
|
-
},
|
|
208
|
-
}));
|
|
209
|
-
}
|
|
210
|
-
static logCdpCallEvent(context, data) {
|
|
211
|
-
return FlowLogger.logCdpEvent(context, "call", data);
|
|
212
|
-
}
|
|
213
|
-
static logCdpResponseEvent(context, parentEvent, data) {
|
|
214
|
-
FlowLogger.logCdpEvent(context, data.error ? "responseError" : "response", data, [...parentEvent.eventParentIds, parentEvent.eventId]);
|
|
215
|
-
}
|
|
216
|
-
static logCdpMessageEvent(context, parentEvent, data) {
|
|
217
|
-
FlowLogger.logCdpEvent(context, "message", data, [
|
|
218
|
-
...parentEvent.eventParentIds,
|
|
219
|
-
parentEvent.eventId,
|
|
220
|
-
]);
|
|
221
|
-
}
|
|
222
|
-
// ===========================================================================
|
|
223
|
-
// LLM Events
|
|
224
|
-
// ===========================================================================
|
|
225
|
-
static logLlmRequest({ requestId, model, prompt, }) {
|
|
226
|
-
FlowLogger.emit({
|
|
227
|
-
eventIdSuffix: "7",
|
|
228
|
-
eventType: "LlmRequestEvent",
|
|
229
|
-
data: {
|
|
230
|
-
requestId,
|
|
231
|
-
model,
|
|
232
|
-
prompt,
|
|
233
|
-
},
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
static logLlmResponse({ requestId, model, output, inputTokens, outputTokens, }) {
|
|
237
|
-
FlowLogger.emit({
|
|
238
|
-
eventIdSuffix: "7",
|
|
239
|
-
eventType: "LlmResponseEvent",
|
|
240
|
-
data: {
|
|
241
|
-
requestId,
|
|
242
|
-
model,
|
|
243
|
-
output,
|
|
244
|
-
inputTokens,
|
|
245
|
-
outputTokens,
|
|
246
|
-
},
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
// ===========================================================================
|
|
250
|
-
// LLM Logging Middleware
|
|
251
|
-
// ===========================================================================
|
|
252
|
-
/**
|
|
253
|
-
* Create middleware for wrapping language models with LLM call logging.
|
|
254
|
-
* Returns a no-op middleware when logging is disabled.
|
|
255
|
-
*/
|
|
256
|
-
static createLlmLoggingMiddleware(modelId) {
|
|
257
|
-
return {
|
|
258
|
-
wrapGenerate: async ({ doGenerate, params }) => {
|
|
259
|
-
const llmRequestId = (0, uuid_1.v7)();
|
|
260
|
-
const toolCount = Array.isArray(params.tools) ? params.tools.length : 0;
|
|
261
|
-
const messages = (params.prompt ?? []);
|
|
262
|
-
const lastMsg = messages.filter((m) => m.role !== "system").pop();
|
|
263
|
-
let rolePrefix = lastMsg?.role ?? "?";
|
|
264
|
-
let promptSummary = `(no text) +{${toolCount} tools}`;
|
|
265
|
-
if (lastMsg) {
|
|
266
|
-
if (typeof lastMsg.content === "string") {
|
|
267
|
-
promptSummary = `${lastMsg.content} +{${toolCount} tools}`;
|
|
268
|
-
}
|
|
269
|
-
else if (Array.isArray(lastMsg.content)) {
|
|
270
|
-
const toolResult = lastMsg.content.find((part) => part.type === "tool-result");
|
|
271
|
-
if (toolResult) {
|
|
272
|
-
rolePrefix = `tool result: ${toolResult.toolName}()`;
|
|
273
|
-
if (toolResult.output?.type === "json" &&
|
|
274
|
-
toolResult.output.value) {
|
|
275
|
-
promptSummary = `${JSON.stringify(toolResult.output.value)} +{${toolCount} tools}`;
|
|
276
|
-
}
|
|
277
|
-
else if (Array.isArray(toolResult.output?.value)) {
|
|
278
|
-
promptSummary = `${extractLlmMessageSummary({
|
|
279
|
-
content: toolResult.output.value,
|
|
280
|
-
}) ?? "(no text)"} +{${toolCount} tools}`;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
promptSummary = `${extractLlmMessageSummary({ content: lastMsg.content }) ??
|
|
285
|
-
"(no text)"} +{${toolCount} tools}`;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
promptSummary = `${rolePrefix}: ${promptSummary}`;
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
291
|
-
promptSummary = `?: ${promptSummary}`;
|
|
292
|
-
}
|
|
293
|
-
FlowLogger.logLlmRequest({
|
|
294
|
-
requestId: llmRequestId,
|
|
295
|
-
model: modelId,
|
|
296
|
-
prompt: promptSummary,
|
|
297
|
-
});
|
|
298
|
-
const result = await doGenerate();
|
|
299
|
-
// Extract output summary
|
|
300
|
-
const res = result;
|
|
301
|
-
let outputSummary = res.text || "";
|
|
302
|
-
if (!outputSummary && res.content) {
|
|
303
|
-
if (typeof res.content === "string") {
|
|
304
|
-
outputSummary = res.content;
|
|
305
|
-
}
|
|
306
|
-
else if (Array.isArray(res.content)) {
|
|
307
|
-
outputSummary = res.content
|
|
308
|
-
.map((c) => c.text ||
|
|
309
|
-
(c.type === "tool-call"
|
|
310
|
-
? `tool call: ${c.toolName}()`
|
|
311
|
-
: `[${c.type}]`))
|
|
312
|
-
.join(" ");
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
if (!outputSummary && res.toolCalls?.length) {
|
|
316
|
-
outputSummary = `[${res.toolCalls.length} tool calls]`;
|
|
317
|
-
}
|
|
318
|
-
FlowLogger.logLlmResponse({
|
|
319
|
-
requestId: llmRequestId,
|
|
320
|
-
model: modelId,
|
|
321
|
-
output: outputSummary || "[empty]",
|
|
322
|
-
inputTokens: result.usage?.inputTokens,
|
|
323
|
-
outputTokens: result.usage?.outputTokens,
|
|
324
|
-
});
|
|
325
|
-
return result;
|
|
326
|
-
},
|
|
327
|
-
};
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
exports.FlowLogger = FlowLogger;
|
|
331
|
-
/** Extract text and image info from a content array (handles nested tool_result) */
|
|
332
|
-
function extractLlmMessageContent(content) {
|
|
333
|
-
const result = {
|
|
334
|
-
text: undefined,
|
|
335
|
-
extras: [],
|
|
336
|
-
};
|
|
337
|
-
for (const part of content) {
|
|
338
|
-
const p = part;
|
|
339
|
-
// Text
|
|
340
|
-
if (!result.text && p.text) {
|
|
341
|
-
result.text = p.type === "text" || !p.type ? p.text : undefined;
|
|
342
|
-
}
|
|
343
|
-
// Images - various formats
|
|
344
|
-
if (p.type === "image" || p.type === "image_url") {
|
|
345
|
-
const url = p.image_url?.url;
|
|
346
|
-
if (url?.startsWith("data:"))
|
|
347
|
-
result.extras.push(`${dataToKb(url)}kb image`);
|
|
348
|
-
else if (p.source?.data)
|
|
349
|
-
result.extras.push(`${dataToKb(p.source.data)}kb image`);
|
|
350
|
-
else
|
|
351
|
-
result.extras.push("image");
|
|
352
|
-
}
|
|
353
|
-
else if (p.source?.data) {
|
|
354
|
-
result.extras.push(`${dataToKb(p.source.data)}kb image`);
|
|
355
|
-
}
|
|
356
|
-
else if (p.inlineData?.data) {
|
|
357
|
-
result.extras.push(`${dataToKb(p.inlineData.data)}kb image`);
|
|
358
|
-
}
|
|
359
|
-
// Recurse into tool_result content
|
|
360
|
-
if (p.type === "tool_result" && Array.isArray(p.content)) {
|
|
361
|
-
const nested = extractLlmMessageContent(p.content);
|
|
362
|
-
if (!result.text && nested.text) {
|
|
363
|
-
result.text = nested.text;
|
|
364
|
-
}
|
|
365
|
-
result.extras.push(...nested.extras);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
return result;
|
|
369
|
-
}
|
|
370
|
-
function extractLlmMessageSummary(input, options) {
|
|
371
|
-
const result = {
|
|
372
|
-
text: undefined,
|
|
373
|
-
extras: [...(options?.extras ?? [])],
|
|
374
|
-
};
|
|
375
|
-
if (typeof input.content === "string") {
|
|
376
|
-
result.text = input.content;
|
|
377
|
-
}
|
|
378
|
-
else if (typeof input.text === "string") {
|
|
379
|
-
result.text = input.text;
|
|
380
|
-
}
|
|
381
|
-
else if (Array.isArray(input.parts)) {
|
|
382
|
-
const summary = extractLlmMessageContent(input.parts);
|
|
383
|
-
result.text = summary.text;
|
|
384
|
-
result.extras.push(...summary.extras);
|
|
385
|
-
}
|
|
386
|
-
else if (Array.isArray(input.content)) {
|
|
387
|
-
const summary = extractLlmMessageContent(input.content);
|
|
388
|
-
result.text = summary.text;
|
|
389
|
-
result.extras.push(...summary.extras);
|
|
390
|
-
}
|
|
391
|
-
if (options?.trimInstructionPrefix && result.text) {
|
|
392
|
-
result.text = result.text.replace(/^[Ii]nstruction: /, "");
|
|
393
|
-
}
|
|
394
|
-
const text = result.text;
|
|
395
|
-
if (!text && result.extras.length === 0)
|
|
396
|
-
return undefined;
|
|
397
|
-
let summary = text || "";
|
|
398
|
-
if (result.extras.length > 0) {
|
|
399
|
-
const extrasStr = result.extras.map((e) => `+{${e}}`).join(" ");
|
|
400
|
-
summary = summary ? `${summary} ${extrasStr}` : extrasStr;
|
|
401
|
-
}
|
|
402
|
-
return summary || undefined;
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Format a prompt summary from LLM messages for logging.
|
|
406
|
-
* Returns format like: "some text +{5.8kb image} +{schema} +{12 tools}"
|
|
407
|
-
*/
|
|
408
|
-
function extractLlmPromptSummary(messages, options) {
|
|
409
|
-
try {
|
|
410
|
-
const lastUserMsg = messages.filter((m) => m.role === "user").pop();
|
|
411
|
-
if (!lastUserMsg)
|
|
412
|
-
return undefined;
|
|
413
|
-
return extractLlmMessageSummary(lastUserMsg, {
|
|
414
|
-
trimInstructionPrefix: true,
|
|
415
|
-
extras: [
|
|
416
|
-
...(options?.hasSchema ? ["schema"] : []),
|
|
417
|
-
...(options?.toolCount ? [`${options.toolCount} tools`] : []),
|
|
418
|
-
],
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
catch {
|
|
422
|
-
return undefined;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Extract a text summary from CUA-style messages.
|
|
427
|
-
* Accepts various message formats (Anthropic, OpenAI, Google).
|
|
428
|
-
*/
|
|
429
|
-
function extractLlmCuaPromptSummary(messages) {
|
|
430
|
-
try {
|
|
431
|
-
const lastMsg = messages
|
|
432
|
-
.filter((m) => {
|
|
433
|
-
const msg = m;
|
|
434
|
-
return msg.role === "user" || msg.type === "tool_result";
|
|
435
|
-
})
|
|
436
|
-
.pop();
|
|
437
|
-
if (!lastMsg)
|
|
438
|
-
return undefined;
|
|
439
|
-
return extractLlmMessageSummary(lastMsg);
|
|
440
|
-
}
|
|
441
|
-
catch {
|
|
442
|
-
return undefined;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
/** Format a CUA response summary for logging */
|
|
446
|
-
function extractLlmCuaResponseSummary(output) {
|
|
447
|
-
try {
|
|
448
|
-
// Handle Google format or array
|
|
449
|
-
const items = output
|
|
450
|
-
?.candidates?.[0]?.content?.parts ??
|
|
451
|
-
(Array.isArray(output) ? output : []);
|
|
452
|
-
const summary = items
|
|
453
|
-
.map((item) => {
|
|
454
|
-
const i = item;
|
|
455
|
-
if (i.text)
|
|
456
|
-
return i.text;
|
|
457
|
-
if (i.functionCall?.name)
|
|
458
|
-
return i.functionCall.name;
|
|
459
|
-
if (i.type === "tool_use" && i.name)
|
|
460
|
-
return i.name;
|
|
461
|
-
return i.type ?? "[item]";
|
|
462
|
-
})
|
|
463
|
-
.join(" ");
|
|
464
|
-
return summary;
|
|
465
|
-
}
|
|
466
|
-
catch {
|
|
467
|
-
return "[error]";
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
//# sourceMappingURL=flowLogger.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"flowLogger.js","sourceRoot":"","sources":["../../../../lib/v3/flowLogger.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { EventEmitter } from \"node:events\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport type { LanguageModelMiddleware } from \"ai\";\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nexport type FlowEventData = Record<string, unknown>;\nexport type FlowEventInput = Omit<\n FlowEvent,\n \"eventId\" | \"createdAt\" | \"sessionId\" | \"eventParentIds\" | \"data\"\n> & {\n eventId?: string;\n eventIdSuffix?: string;\n createdAt?: string;\n sessionId?: string;\n eventParentIds?: string[];\n data?: FlowEventData;\n};\n\nexport class FlowEvent {\n static createEventId(eventIdSuffix: string): string {\n const rawEventId = uuidv7();\n return `${rawEventId.slice(0, -1)}${eventIdSuffix || \"0\"}`;\n }\n\n // base required fields for all events:\n eventType: string;\n eventId: string;\n eventParentIds: string[];\n createdAt: string;\n sessionId: string;\n data: FlowEventData; // event payload (e.g. params, action, result, error, etc.)\n\n constructor(input: FlowEventInput) {\n if (!input.sessionId) {\n throw new Error(\"FlowEvent.sessionId is required.\");\n }\n if (\n input.eventId &&\n input.eventIdSuffix &&\n !input.eventId.endsWith(input.eventIdSuffix)\n ) {\n throw new Error(\"FlowEvent cannot take both eventId and eventIdSuffix.\");\n }\n\n this.eventType = input.eventType.endsWith(\"Event\")\n ? input.eventType\n : `${input.eventType}Event`;\n this.eventId =\n input.eventId ?? FlowEvent.createEventId(input.eventIdSuffix ?? \"0\");\n this.eventParentIds = input.eventParentIds ?? [];\n this.createdAt = input.createdAt ?? new Date().toISOString();\n this.sessionId = input.sessionId;\n this.data = input.data ?? {};\n }\n}\n\nexport interface FlowLoggerContext {\n sessionId: string;\n eventBus: EventEmitter;\n parentEvents: FlowEvent[];\n}\n\ntype AsyncOriginalMethod<\n TArgs extends unknown[] = unknown[],\n TResult = unknown,\n TThis = unknown,\n> = (this: TThis, ...args: TArgs) => Promise<TResult>;\n\ntype FlowLoggerLogOptions = FlowEventInput & {\n context?: FlowLoggerContext;\n};\n\nconst loggerContext = new AsyncLocalStorage<FlowLoggerContext>();\n\nfunction dataToKb(data: string): string {\n return ((data.length * 0.75) / 1024).toFixed(1);\n}\n\n// =============================================================================\n// Flow Logger - Main API\n// =============================================================================\n\nexport class FlowLogger {\n private static cloneContext(ctx: FlowLoggerContext): FlowLoggerContext {\n return {\n ...ctx,\n parentEvents: ctx.parentEvents.map((event) => ({\n ...event,\n eventParentIds: [...event.eventParentIds],\n })),\n };\n }\n\n private static emit(event: FlowEventInput): FlowEvent | null {\n const ctx = FlowLogger.currentContext;\n\n const emittedEvent = new FlowEvent({\n ...event,\n eventParentIds:\n event.eventParentIds ??\n ctx.parentEvents.map((parent) => parent.eventId),\n sessionId: ctx.sessionId,\n });\n ctx.eventBus.emit(emittedEvent.eventType, emittedEvent);\n return emittedEvent;\n }\n\n private static async runWithAutoStatusEventLogging<TResult>(\n options: FlowLoggerLogOptions,\n originalMethod: AsyncOriginalMethod<[], TResult>,\n ): Promise<TResult> {\n const ctx = FlowLogger.currentContext;\n const { data, eventParentIds, eventType, eventIdSuffix } = options;\n let caughtError: unknown = null;\n\n // if eventParentIds is explicitly [], this is a root event, clear the parent events in context\n if (eventParentIds && eventParentIds.length === 0) {\n ctx.parentEvents = [];\n }\n\n const startedEvent = FlowLogger.emit({\n eventIdSuffix,\n eventType,\n data,\n eventParentIds,\n });\n\n ctx.parentEvents.push(startedEvent);\n\n try {\n return await originalMethod();\n } catch (error) {\n caughtError = error;\n FlowLogger.emit({\n eventIdSuffix,\n eventType: `${eventType}ErrorEvent`,\n eventParentIds: [...startedEvent.eventParentIds, startedEvent.eventId],\n data: {\n error: error instanceof Error ? error.message : String(error),\n durationMs: Date.now() - new Date(startedEvent.createdAt).getTime(),\n },\n });\n throw error;\n } finally {\n const parentEvent = ctx.parentEvents.pop();\n if (parentEvent?.eventId === startedEvent.eventId && !caughtError) {\n FlowLogger.emit({\n eventIdSuffix,\n eventType: `${eventType}CompletedEvent`,\n eventParentIds: [\n ...startedEvent.eventParentIds,\n startedEvent.eventId,\n ],\n data: {\n durationMs: Date.now() - new Date(startedEvent.createdAt).getTime(),\n },\n });\n }\n }\n }\n\n /**\n * Initialize a new logging context. Call this at the start of a session.\n */\n static init(sessionId: string, eventBus: EventEmitter): FlowLoggerContext {\n const ctx: FlowLoggerContext = {\n sessionId,\n eventBus,\n parentEvents: [],\n };\n\n loggerContext.enterWith(ctx);\n return ctx;\n }\n\n static async close(context?: FlowLoggerContext | null): Promise<void> {\n const ctx = context ?? loggerContext.getStore() ?? null;\n if (!ctx) return;\n ctx.parentEvents = [];\n }\n\n static get currentContext(): FlowLoggerContext {\n const ctx = loggerContext.getStore() ?? null;\n if (!ctx) {\n throw new Error(\"FlowLogger context is missing.\");\n }\n\n return ctx;\n }\n\n // decorator method to wrap a class method with automatic started/completed/error events\n static wrapWithLogging<TMethod extends AsyncOriginalMethod>(\n options: FlowLoggerLogOptions,\n ) {\n return function <\n TWrappedMethod extends AsyncOriginalMethod<\n Parameters<TMethod>,\n Awaited<ReturnType<TMethod>>,\n ThisParameterType<TMethod>\n >,\n >(originalMethod: TWrappedMethod): TWrappedMethod {\n const wrappedMethod = async function (\n this: ThisParameterType<TWrappedMethod>,\n ...args: Parameters<TWrappedMethod>\n ): Promise<Awaited<ReturnType<TWrappedMethod>>> {\n return await FlowLogger.runWithLogging(\n options,\n (...boundArgs: Parameters<TWrappedMethod>) =>\n originalMethod.apply(this, boundArgs) as Promise<\n Awaited<ReturnType<TWrappedMethod>>\n >,\n args,\n );\n };\n\n return wrappedMethod as unknown as TWrappedMethod;\n };\n }\n\n // closure runner to wrap some async work with automatic started/completed/error events\n // Standard case: the logged params are the same tuple passed to the wrapped method.\n static runWithLogging<TMethod extends AsyncOriginalMethod>(\n options: FlowLoggerLogOptions,\n originalMethod: TMethod,\n params: Readonly<Parameters<TMethod>>,\n ): Promise<Awaited<ReturnType<TMethod>>>;\n // Special case: log an arbitrary params tuple while executing a zero-arg closure.\n static runWithLogging<TResult>(\n options: FlowLoggerLogOptions,\n originalMethod: AsyncOriginalMethod<[], TResult>,\n params: ReadonlyArray<unknown>,\n ): Promise<Awaited<TResult>>;\n static runWithLogging(\n options: FlowLoggerLogOptions,\n originalMethod: AsyncOriginalMethod<unknown[], unknown>,\n params: ReadonlyArray<unknown>,\n ): Promise<unknown> {\n const eventData = {\n ...(options.data ?? {}),\n params: [...params],\n };\n\n const execute = (): Promise<unknown> =>\n FlowLogger.runWithAutoStatusEventLogging(\n {\n ...options,\n data: eventData,\n },\n () => originalMethod(...params),\n );\n\n if (!options.context && !(loggerContext.getStore() ?? null)) {\n return originalMethod(...params);\n }\n\n return options.context\n ? loggerContext.run(FlowLogger.cloneContext(options.context), execute)\n : execute();\n }\n\n // ===========================================================================\n // CDP Events\n // ===========================================================================\n\n private static readonly NOISY_CDP_EVENTS = new Set([\n \"Target.targetInfoChanged\",\n \"Runtime.executionContextCreated\",\n \"Runtime.executionContextDestroyed\",\n \"Runtime.executionContextsCleared\",\n \"Page.lifecycleEvent\",\n \"Network.dataReceived\",\n \"Network.loadingFinished\",\n \"Network.requestWillBeSentExtraInfo\",\n \"Network.responseReceivedExtraInfo\",\n \"Network.requestWillBeSent\",\n \"Network.responseReceived\",\n ]);\n\n private static logCdpEvent(\n context: FlowLoggerContext,\n eventType: \"call\" | \"response\" | \"responseError\" | \"message\",\n {\n method,\n params,\n result,\n error,\n targetId,\n }: {\n method: string;\n params?: unknown;\n result?: unknown;\n error?: string;\n targetId?: string | null;\n },\n eventParentIds?: string[],\n ): FlowEvent | null {\n if (method.endsWith(\".enable\") || method === \"enable\") {\n return null;\n }\n\n if (eventType === \"message\" && FlowLogger.NOISY_CDP_EVENTS.has(method)) {\n return null;\n }\n\n return loggerContext.run(FlowLogger.cloneContext(context), () =>\n FlowLogger.emit({\n eventIdSuffix: \"6\",\n eventType:\n eventType === \"call\"\n ? \"CdpCallEvent\"\n : eventType === \"response\"\n ? \"CdpResponseEvent\"\n : eventType === \"responseError\"\n ? \"CdpResponseErrorEvent\"\n : \"CdpMessageEvent\",\n eventParentIds,\n data: {\n method,\n params,\n result,\n error,\n targetId,\n },\n }),\n );\n }\n\n static logCdpCallEvent(\n context: FlowLoggerContext,\n data: {\n method: string;\n params?: object;\n targetId?: string | null;\n },\n ): FlowEvent | null {\n return FlowLogger.logCdpEvent(context, \"call\", data);\n }\n\n static logCdpResponseEvent(\n context: FlowLoggerContext,\n parentEvent: Pick<FlowEvent, \"eventId\" | \"eventParentIds\">,\n data: {\n method: string;\n result?: unknown;\n error?: string;\n targetId?: string | null;\n },\n ): void {\n FlowLogger.logCdpEvent(\n context,\n data.error ? \"responseError\" : \"response\",\n data,\n [...parentEvent.eventParentIds, parentEvent.eventId],\n );\n }\n\n static logCdpMessageEvent(\n context: FlowLoggerContext,\n parentEvent: Pick<FlowEvent, \"eventId\" | \"eventParentIds\">,\n data: {\n method: string;\n params?: unknown;\n targetId?: string | null;\n },\n ): void {\n FlowLogger.logCdpEvent(context, \"message\", data, [\n ...parentEvent.eventParentIds,\n parentEvent.eventId,\n ]);\n }\n\n // ===========================================================================\n // LLM Events\n // ===========================================================================\n\n static logLlmRequest({\n requestId,\n model,\n prompt,\n }: {\n requestId: string;\n model: string;\n prompt?: string;\n }): void {\n FlowLogger.emit({\n eventIdSuffix: \"7\",\n eventType: \"LlmRequestEvent\",\n data: {\n requestId,\n model,\n prompt,\n },\n });\n }\n\n static logLlmResponse({\n requestId,\n model,\n output,\n inputTokens,\n outputTokens,\n }: {\n requestId: string;\n model: string;\n output?: string;\n inputTokens?: number;\n outputTokens?: number;\n }): void {\n FlowLogger.emit({\n eventIdSuffix: \"7\",\n eventType: \"LlmResponseEvent\",\n data: {\n requestId,\n model,\n output,\n inputTokens,\n outputTokens,\n },\n });\n }\n\n // ===========================================================================\n // LLM Logging Middleware\n // ===========================================================================\n\n /**\n * Create middleware for wrapping language models with LLM call logging.\n * Returns a no-op middleware when logging is disabled.\n */\n static createLlmLoggingMiddleware(\n modelId: string,\n ): Pick<LanguageModelMiddleware, \"wrapGenerate\"> {\n return {\n wrapGenerate: async ({ doGenerate, params }) => {\n const llmRequestId = uuidv7();\n const toolCount = Array.isArray(params.tools) ? params.tools.length : 0;\n const messages = (params.prompt ?? []) as Array<{\n role?: string;\n content?: unknown;\n }>;\n const lastMsg = messages.filter((m) => m.role !== \"system\").pop();\n let rolePrefix = lastMsg?.role ?? \"?\";\n let promptSummary = `(no text) +{${toolCount} tools}`;\n\n if (lastMsg) {\n if (typeof lastMsg.content === \"string\") {\n promptSummary = `${lastMsg.content} +{${toolCount} tools}`;\n } else if (Array.isArray(lastMsg.content)) {\n const toolResult = (\n lastMsg.content as Array<{\n type?: string;\n toolName?: string;\n output?: { type?: string; value?: unknown };\n }>\n ).find((part) => part.type === \"tool-result\");\n\n if (toolResult) {\n rolePrefix = `tool result: ${toolResult.toolName}()`;\n if (\n toolResult.output?.type === \"json\" &&\n toolResult.output.value\n ) {\n promptSummary = `${JSON.stringify(toolResult.output.value)} +{${toolCount} tools}`;\n } else if (Array.isArray(toolResult.output?.value)) {\n promptSummary = `${\n extractLlmMessageSummary({\n content: toolResult.output.value,\n }) ?? \"(no text)\"\n } +{${toolCount} tools}`;\n }\n } else {\n promptSummary = `${\n extractLlmMessageSummary({ content: lastMsg.content }) ??\n \"(no text)\"\n } +{${toolCount} tools}`;\n }\n }\n\n promptSummary = `${rolePrefix}: ${promptSummary}`;\n } else {\n promptSummary = `?: ${promptSummary}`;\n }\n\n FlowLogger.logLlmRequest({\n requestId: llmRequestId,\n model: modelId,\n prompt: promptSummary,\n });\n\n const result = await doGenerate();\n\n // Extract output summary\n const res = result as {\n text?: string;\n content?: unknown;\n toolCalls?: unknown[];\n };\n let outputSummary = res.text || \"\";\n if (!outputSummary && res.content) {\n if (typeof res.content === \"string\") {\n outputSummary = res.content;\n } else if (Array.isArray(res.content)) {\n outputSummary = (\n res.content as Array<{\n type?: string;\n text?: string;\n toolName?: string;\n }>\n )\n .map(\n (c) =>\n c.text ||\n (c.type === \"tool-call\"\n ? `tool call: ${c.toolName}()`\n : `[${c.type}]`),\n )\n .join(\" \");\n }\n }\n if (!outputSummary && res.toolCalls?.length) {\n outputSummary = `[${res.toolCalls.length} tool calls]`;\n }\n\n FlowLogger.logLlmResponse({\n requestId: llmRequestId,\n model: modelId,\n output: outputSummary || \"[empty]\",\n inputTokens: result.usage?.inputTokens,\n outputTokens: result.usage?.outputTokens,\n });\n\n return result;\n },\n };\n }\n}\n\n// =============================================================================\n// LLM Event Extraction Helpers\n// =============================================================================\n\ntype ContentPart = {\n type?: string;\n text?: string;\n content?: unknown[];\n source?: { data?: string };\n image_url?: { url?: string };\n inlineData?: { data?: string };\n};\n\ntype LlmMessageContent = {\n content?: unknown;\n text?: string;\n parts?: unknown[];\n};\n\n/** Extract text and image info from a content array (handles nested tool_result) */\nfunction extractLlmMessageContent(content: unknown[]): {\n text?: string;\n extras: string[];\n} {\n const result = {\n text: undefined as string | undefined,\n extras: [] as string[],\n };\n\n for (const part of content) {\n const p = part as ContentPart;\n // Text\n if (!result.text && p.text) {\n result.text = p.type === \"text\" || !p.type ? p.text : undefined;\n }\n // Images - various formats\n if (p.type === \"image\" || p.type === \"image_url\") {\n const url = p.image_url?.url;\n if (url?.startsWith(\"data:\"))\n result.extras.push(`${dataToKb(url)}kb image`);\n else if (p.source?.data)\n result.extras.push(`${dataToKb(p.source.data)}kb image`);\n else result.extras.push(\"image\");\n } else if (p.source?.data) {\n result.extras.push(`${dataToKb(p.source.data)}kb image`);\n } else if (p.inlineData?.data) {\n result.extras.push(`${dataToKb(p.inlineData.data)}kb image`);\n }\n // Recurse into tool_result content\n if (p.type === \"tool_result\" && Array.isArray(p.content)) {\n const nested = extractLlmMessageContent(p.content);\n if (!result.text && nested.text) {\n result.text = nested.text;\n }\n result.extras.push(...nested.extras);\n }\n }\n\n return result;\n}\n\nfunction extractLlmMessageSummary(\n input: LlmMessageContent,\n options?: {\n trimInstructionPrefix?: boolean;\n extras?: string[];\n },\n): string | undefined {\n const result = {\n text: undefined as string | undefined,\n extras: [...(options?.extras ?? [])],\n };\n\n if (typeof input.content === \"string\") {\n result.text = input.content;\n } else if (typeof input.text === \"string\") {\n result.text = input.text;\n } else if (Array.isArray(input.parts)) {\n const summary = extractLlmMessageContent(input.parts);\n result.text = summary.text;\n result.extras.push(...summary.extras);\n } else if (Array.isArray(input.content)) {\n const summary = extractLlmMessageContent(input.content);\n result.text = summary.text;\n result.extras.push(...summary.extras);\n }\n\n if (options?.trimInstructionPrefix && result.text) {\n result.text = result.text.replace(/^[Ii]nstruction: /, \"\");\n }\n\n const text = result.text;\n if (!text && result.extras.length === 0) return undefined;\n\n let summary = text || \"\";\n if (result.extras.length > 0) {\n const extrasStr = result.extras.map((e) => `+{${e}}`).join(\" \");\n summary = summary ? `${summary} ${extrasStr}` : extrasStr;\n }\n return summary || undefined;\n}\n\n/**\n * Format a prompt summary from LLM messages for logging.\n * Returns format like: \"some text +{5.8kb image} +{schema} +{12 tools}\"\n */\nexport function extractLlmPromptSummary(\n messages: Array<{ role: string; content: unknown }>,\n options?: { toolCount?: number; hasSchema?: boolean },\n): string | undefined {\n try {\n const lastUserMsg = messages.filter((m) => m.role === \"user\").pop();\n if (!lastUserMsg) return undefined;\n\n return extractLlmMessageSummary(lastUserMsg, {\n trimInstructionPrefix: true,\n extras: [\n ...(options?.hasSchema ? [\"schema\"] : []),\n ...(options?.toolCount ? [`${options.toolCount} tools`] : []),\n ],\n });\n } catch {\n return undefined;\n }\n}\n\n/**\n * Extract a text summary from CUA-style messages.\n * Accepts various message formats (Anthropic, OpenAI, Google).\n */\nexport function extractLlmCuaPromptSummary(\n messages: unknown[],\n): string | undefined {\n try {\n const lastMsg = messages\n .filter((m) => {\n const msg = m as { role?: string; type?: string };\n return msg.role === \"user\" || msg.type === \"tool_result\";\n })\n .pop() as\n | { content?: unknown; parts?: unknown[]; text?: string }\n | undefined;\n\n if (!lastMsg) return undefined;\n\n return extractLlmMessageSummary(lastMsg);\n } catch {\n return undefined;\n }\n}\n\n/** Format a CUA response summary for logging */\nexport function extractLlmCuaResponseSummary(output: unknown): string {\n try {\n // Handle Google format or array\n const items: unknown[] =\n (output as { candidates?: [{ content?: { parts?: unknown[] } }] })\n ?.candidates?.[0]?.content?.parts ??\n (Array.isArray(output) ? output : []);\n\n const summary = items\n .map((item) => {\n const i = item as {\n type?: string;\n text?: string;\n name?: string;\n functionCall?: { name?: string };\n };\n if (i.text) return i.text;\n if (i.functionCall?.name) return i.functionCall.name;\n if (i.type === \"tool_use\" && i.name) return i.name;\n return i.type ?? \"[item]\";\n })\n .join(\" \");\n\n return summary;\n } catch {\n return \"[error]\";\n }\n}\n"]}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import type { EventEmitter } from "node:events";
|
|
2
|
-
import type { V3Options } from "./types/public/index.js";
|
|
3
|
-
import { type FlowEvent } from "./flowLogger.js";
|
|
4
|
-
export interface FlowEventAggregateMetrics {
|
|
5
|
-
llmRequests: number;
|
|
6
|
-
inputTokens: number;
|
|
7
|
-
outputTokens: number;
|
|
8
|
-
cdpEvents: number;
|
|
9
|
-
}
|
|
10
|
-
export interface EventStoreQuery {
|
|
11
|
-
sessionId?: string;
|
|
12
|
-
eventId?: string;
|
|
13
|
-
eventType?: string;
|
|
14
|
-
limit?: number;
|
|
15
|
-
}
|
|
16
|
-
export type EventStoreListener = (event: FlowEvent) => void;
|
|
17
|
-
export interface EventStore {
|
|
18
|
-
initializeSession(sessionId: string, v3Options?: V3Options): Promise<void>;
|
|
19
|
-
appendEvent(event: FlowEvent): Promise<void>;
|
|
20
|
-
attachBus(sessionId: string, bus: EventEmitter): () => void;
|
|
21
|
-
listEvents(query: EventStoreQuery): Promise<FlowEvent[]>;
|
|
22
|
-
subscribe(query: EventStoreQuery, listener: EventStoreListener): () => void;
|
|
23
|
-
destroy(): Promise<void>;
|
|
24
|
-
}
|
|
25
|
-
export declare function aggregateFlowEventMetrics(events: FlowEvent[]): FlowEventAggregateMetrics;
|
|
26
|
-
export declare function getConfigDir(): string;
|
|
27
|
-
export declare class FileEventStore implements EventStore {
|
|
28
|
-
private readonly sessionContexts;
|
|
29
|
-
private readonly eventsBySession;
|
|
30
|
-
private readonly subscribers;
|
|
31
|
-
initializeSession(sessionId: string, v3Options?: V3Options): Promise<void>;
|
|
32
|
-
private initSessionContext;
|
|
33
|
-
appendEvent(event: FlowEvent): Promise<void>;
|
|
34
|
-
attachBus(sessionId: string, bus: EventEmitter): () => void;
|
|
35
|
-
listEvents(query: EventStoreQuery): Promise<FlowEvent[]>;
|
|
36
|
-
subscribe(query: EventStoreQuery, listener: EventStoreListener): () => void;
|
|
37
|
-
destroy(): Promise<void>;
|
|
38
|
-
}
|
|
39
|
-
export declare function setEventStore(store: EventStore): void;
|
|
40
|
-
export declare function getEventStore(): EventStore;
|
|
41
|
-
export declare function destroyEventStore(): Promise<void>;
|