-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathutil.ts
More file actions
74 lines (68 loc) · 2.36 KB
/
Copy pathutil.ts
File metadata and controls
74 lines (68 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import os from "node:os"
import { MAX_PENDING } from "./types.ts"
import type { HandlerContext } from "./types.ts"
/**
* Returns the OS-level username, or `undefined` when `os.userInfo()` throws
* (e.g. containerised runs with no matching passwd entry).
*/
export function safeUsername(): string | undefined {
try {
return os.userInfo().username
} catch {
return undefined
}
}
/** Returns a human-readable summary string from an opencode error object. */
export function errorSummary(err: { name: string; data?: unknown } | undefined): string {
if (!err) return "unknown"
if (err.data && typeof err.data === "object" && "message" in err.data) {
return `${err.name}: ${(err.data as { message: string }).message}`
}
return err.name
}
/**
* Inserts a key/value pair into `map`, evicting the oldest entry first when the map
* has reached `MAX_PENDING` capacity to prevent unbounded memory growth.
*/
export function setBoundedMap<K, V>(map: Map<K, V>, key: K, value: V) {
if (map.size >= MAX_PENDING) {
const [firstKey] = map.keys()
if (firstKey !== undefined) map.delete(firstKey)
}
map.set(key, value)
}
/**
* Returns `true` if the metric name (without prefix) is not in the disabled set.
* The `name` should be the suffix after the metric prefix, e.g. `"session.count"`.
*/
export function isMetricEnabled(name: string, ctx: { disabledMetrics: Set<string> }): boolean {
return !ctx.disabledMetrics.has(name)
}
/**
* Returns `true` if the trace type is not in the disabled set.
* Valid names are `"session"`, `"llm"`, and `"tool"`.
*/
export function isTraceEnabled(name: string, ctx: { disabledTraces: Set<string> }): boolean {
return !ctx.disabledTraces.has(name)
}
/**
* Accumulates token and cost totals for a session, and increments the message count.
* Uses `setBoundedMap` to produce a new object rather than mutating in-place.
* No-ops silently if the session was not previously registered via `handleSessionCreated`.
*/
export function accumulateSessionTotals(
sessionID: string,
tokens: number,
cost: number,
ctx: HandlerContext,
) {
const existing = ctx.sessionTotals.get(sessionID)
if (!existing) return
setBoundedMap(ctx.sessionTotals, sessionID, {
startMs: existing.startMs,
tokens: existing.tokens + tokens,
cost: existing.cost + cost,
messages: existing.messages + 1,
agent: existing.agent,
})
}