@senad-d/observme 0.1.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.
- package/.env.example +57 -0
- package/CHANGELOG.md +52 -0
- package/LICENSE +21 -0
- package/ObservMe-Production-Docs/00-README.md +79 -0
- package/ObservMe-Production-Docs/01-requirements-and-scope.md +207 -0
- package/ObservMe-Production-Docs/02-reference-architecture.md +306 -0
- package/ObservMe-Production-Docs/03-pi-event-and-session-model.md +266 -0
- package/ObservMe-Production-Docs/04-telemetry-semantic-conventions.md +722 -0
- package/ObservMe-Production-Docs/05-otel-pipeline-and-collector.md +355 -0
- package/ObservMe-Production-Docs/06-security-privacy-redaction.md +294 -0
- package/ObservMe-Production-Docs/07-extension-implementation-blueprint.md +447 -0
- package/ObservMe-Production-Docs/08-query-grafana-integration.md +276 -0
- package/ObservMe-Production-Docs/09-dashboards-alerts-slos.md +640 -0
- package/ObservMe-Production-Docs/10-testing-release-operations.md +319 -0
- package/ObservMe-Production-Docs/11-deployment-runbooks.md +203 -0
- package/ObservMe-Production-Docs/12-configuration-reference.md +337 -0
- package/ObservMe-Production-Docs/13-source-notes.md +33 -0
- package/ObservMe-Production-Docs/pi-session-format.md +427 -0
- package/README.md +356 -0
- package/SECURITY.md +45 -0
- package/dashboards/observme-agent-node-graphs.json +250 -0
- package/dashboards/observme-agents.json +1880 -0
- package/dashboards/observme-alerts.yaml +113 -0
- package/dashboards/observme-branches-compactions.json +1042 -0
- package/dashboards/observme-cost.json +1254 -0
- package/dashboards/observme-errors.json +1659 -0
- package/dashboards/observme-export-health.json +1802 -0
- package/dashboards/observme-latency.json +1494 -0
- package/dashboards/observme-llm-conversations.json +730 -0
- package/dashboards/observme-logs-llm.json +644 -0
- package/dashboards/observme-models.json +933 -0
- package/dashboards/observme-overview.json +2129 -0
- package/dashboards/observme-slo-health.json +737 -0
- package/dashboards/observme-slos.yaml +56 -0
- package/dashboards/observme-tools.json +902 -0
- package/dashboards/observme-trace-journey.json +1793 -0
- package/docs/STRUCTURE.md +49 -0
- package/docs/agent-subagent-observability-requirements.md +997 -0
- package/docs/compatibility-matrix.md +39 -0
- package/docs/configuration-tui-design-standard.md +767 -0
- package/docs/configuration.md +38 -0
- package/docs/review-validation.md +115 -0
- package/docs/validation-flow.md +117 -0
- package/examples/collector.yaml +123 -0
- package/examples/observme.yaml +131 -0
- package/img/demo.gif +0 -0
- package/img/icon.svg +47 -0
- package/package.json +103 -0
- package/src/commands/obs-agents-runtime.ts +150 -0
- package/src/commands/obs-agents.ts +491 -0
- package/src/commands/obs-args.ts +63 -0
- package/src/commands/obs-backfill.ts +1334 -0
- package/src/commands/obs-command-support.ts +43 -0
- package/src/commands/obs-cost.ts +228 -0
- package/src/commands/obs-diagnostics.ts +22 -0
- package/src/commands/obs-errors.ts +156 -0
- package/src/commands/obs-health.ts +301 -0
- package/src/commands/obs-link.ts +90 -0
- package/src/commands/obs-logs.ts +194 -0
- package/src/commands/obs-loki-summary.ts +184 -0
- package/src/commands/obs-session.ts +259 -0
- package/src/commands/obs-status.ts +359 -0
- package/src/commands/obs-tools.ts +274 -0
- package/src/commands/obs-trace.ts +411 -0
- package/src/commands/obs.ts +211 -0
- package/src/config/bootstrap-project-config.ts +300 -0
- package/src/config/defaults.ts +143 -0
- package/src/config/load-config.ts +631 -0
- package/src/config/project-paths.ts +61 -0
- package/src/config/schema.ts +405 -0
- package/src/config/validate.ts +456 -0
- package/src/constants.ts +4 -0
- package/src/diagnostics/sanitize.ts +6 -0
- package/src/extension.ts +38 -0
- package/src/otel/logs.ts +160 -0
- package/src/otel/metrics.ts +165 -0
- package/src/otel/otlp-endpoint.ts +10 -0
- package/src/otel/sdk.ts +114 -0
- package/src/otel/shutdown.ts +102 -0
- package/src/otel/traces.ts +166 -0
- package/src/pi/agent-lineage.ts +378 -0
- package/src/pi/agent-tree-tracker.ts +258 -0
- package/src/pi/event-handlers/agent-turn.ts +155 -0
- package/src/pi/event-handlers/lifecycle.ts +642 -0
- package/src/pi/event-handlers/llm.ts +115 -0
- package/src/pi/event-handlers/session-events.ts +159 -0
- package/src/pi/event-handlers/tool-bash.ts +275 -0
- package/src/pi/handler-internals.ts +2154 -0
- package/src/pi/handler-runtime.ts +633 -0
- package/src/pi/handler-types.ts +261 -0
- package/src/pi/handlers.ts +75 -0
- package/src/pi/subagent-spawn.ts +975 -0
- package/src/pi/subagent-types.ts +29 -0
- package/src/privacy/content-capture.ts +104 -0
- package/src/privacy/hash.ts +93 -0
- package/src/privacy/redact.ts +619 -0
- package/src/privacy/secret-patterns.ts +185 -0
- package/src/privacy/truncate.ts +69 -0
- package/src/query/grafana-readiness.ts +164 -0
- package/src/query/grafana-transport.ts +481 -0
- package/src/query/grafana.ts +371 -0
- package/src/query/loki.ts +332 -0
- package/src/query/prometheus.ts +388 -0
- package/src/query/tempo.ts +332 -0
- package/src/safety/sensitive-input.ts +208 -0
- package/src/semconv/attributes.ts +279 -0
- package/src/semconv/metrics.ts +146 -0
- package/src/semconv/spans.ts +19 -0
- package/src/semconv/values.ts +13 -0
- package/src/util/bounded-map.ts +97 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
export type AttributeKey = (typeof ALL_ATTRIBUTE_KEYS)[number];
|
|
2
|
+
|
|
3
|
+
export const RESOURCE_ATTRIBUTES = {
|
|
4
|
+
SERVICE_NAME: "service.name",
|
|
5
|
+
SERVICE_NAMESPACE: "service.namespace",
|
|
6
|
+
SERVICE_VERSION: "service.version",
|
|
7
|
+
SERVICE_INSTANCE_ID: "service.instance.id",
|
|
8
|
+
TELEMETRY_SDK_NAME: "telemetry.sdk.name",
|
|
9
|
+
OBSERVME_VERSION: "observme.version",
|
|
10
|
+
OBSERVME_INSTANCE_ID: "observme.instance.id",
|
|
11
|
+
PI_AGENT_ID: "pi.agent.id",
|
|
12
|
+
PI_AGENT_PARENT_ID: "pi.agent.parent_id",
|
|
13
|
+
PI_AGENT_ROOT_ID: "pi.agent.root_id",
|
|
14
|
+
PI_AGENT_ROLE: "pi.agent.role",
|
|
15
|
+
PI_AGENT_DEPTH: "pi.agent.depth",
|
|
16
|
+
PI_CWD_HASH: "pi.cwd.hash",
|
|
17
|
+
PI_CWD_BASENAME: "pi.cwd.basename",
|
|
18
|
+
DEPLOYMENT_ENVIRONMENT_NAME: "deployment.environment.name",
|
|
19
|
+
OBSERVME_ENVIRONMENT: "observme.environment",
|
|
20
|
+
OBSERVME_TENANT_ID: "observme.tenant.id",
|
|
21
|
+
PI_WORKFLOW_ID: "pi.workflow.id",
|
|
22
|
+
PI_WORKFLOW_ROOT_AGENT_ID: "pi.workflow.root_agent_id",
|
|
23
|
+
PI_USER_HASH: "pi.user.hash",
|
|
24
|
+
PI_PROJECT_NAME: "pi.project.name",
|
|
25
|
+
} as const;
|
|
26
|
+
|
|
27
|
+
export const SESSION_ATTRIBUTES = {
|
|
28
|
+
PI_SESSION_ID: "pi.session.id",
|
|
29
|
+
PI_SESSION_NAME: "pi.session.name",
|
|
30
|
+
PI_SESSION_CWD_HASH: "pi.session.cwd_hash",
|
|
31
|
+
PI_SESSION_PARENT_SESSION_HASH: "pi.session.parent_session_hash",
|
|
32
|
+
PI_SESSION_PERSISTED: "pi.session.persisted",
|
|
33
|
+
PI_SESSION_FILE_HASH: "pi.session.file_hash",
|
|
34
|
+
PI_SESSION_VERSION: "pi.session.version",
|
|
35
|
+
PI_MODEL_PROVIDER_CURRENT: "pi.model.provider.current",
|
|
36
|
+
PI_MODEL_ID_CURRENT: "pi.model.id.current",
|
|
37
|
+
PI_THINKING_LEVEL_CURRENT: "pi.thinking.level.current",
|
|
38
|
+
} as const;
|
|
39
|
+
|
|
40
|
+
export const WORKFLOW_ATTRIBUTES = {
|
|
41
|
+
PI_WORKFLOW_DURATION_MS: "pi.workflow.duration_ms",
|
|
42
|
+
PI_WORKFLOW_STATUS: "pi.workflow.status",
|
|
43
|
+
} as const;
|
|
44
|
+
|
|
45
|
+
export const COMMON_SPAN_ATTRIBUTES = {
|
|
46
|
+
PI_SESSION_ID: "pi.session.id",
|
|
47
|
+
PI_WORKFLOW_ID: "pi.workflow.id",
|
|
48
|
+
PI_WORKFLOW_ROOT_AGENT_ID: "pi.workflow.root_agent_id",
|
|
49
|
+
PI_AGENT_ID: "pi.agent.id",
|
|
50
|
+
PI_AGENT_PARENT_ID: "pi.agent.parent_id",
|
|
51
|
+
PI_AGENT_ROOT_ID: "pi.agent.root_id",
|
|
52
|
+
PI_AGENT_RUN_ID: "pi.agent.run.id",
|
|
53
|
+
PI_ENTRY_ID: "pi.entry.id",
|
|
54
|
+
PI_ENTRY_PARENT_ID: "pi.entry.parent_id",
|
|
55
|
+
PI_ENTRY_TYPE: "pi.entry.type",
|
|
56
|
+
OBSERVME_CAPTURE_PROMPTS: "observme.capture.prompts",
|
|
57
|
+
OBSERVME_CAPTURE_RESPONSES: "observme.capture.responses",
|
|
58
|
+
OBSERVME_CAPTURE_TOOL_ARGUMENTS: "observme.capture.tool_arguments",
|
|
59
|
+
OBSERVME_REDACTION_ENABLED: "observme.redaction.enabled",
|
|
60
|
+
OBSERVME_SEMCONV_VERSION: "observme.semconv.version",
|
|
61
|
+
OBSERVME_REPLAYED: "observme.replayed",
|
|
62
|
+
OBSERVME_EVICTED: "observme.evicted",
|
|
63
|
+
OBSERVME_TRUNCATED: "observme.truncated",
|
|
64
|
+
OBSERVME_ORIGINAL_LENGTH: "observme.original_length",
|
|
65
|
+
} as const;
|
|
66
|
+
|
|
67
|
+
export const AGENT_LINEAGE_ATTRIBUTES = {
|
|
68
|
+
PI_AGENT_CAPABILITY: "pi.agent.capability",
|
|
69
|
+
PI_AGENT_ORPHANED: "pi.agent.orphaned",
|
|
70
|
+
} as const;
|
|
71
|
+
|
|
72
|
+
export const AGENT_RUN_ATTRIBUTES = {
|
|
73
|
+
PI_AGENT_ID: "pi.agent.id",
|
|
74
|
+
PI_AGENT_PARENT_ID: "pi.agent.parent_id",
|
|
75
|
+
PI_AGENT_ROOT_ID: "pi.agent.root_id",
|
|
76
|
+
PI_AGENT_ROLE: "pi.agent.role",
|
|
77
|
+
PI_AGENT_DEPTH: "pi.agent.depth",
|
|
78
|
+
PI_AGENT_RUN_ID: "pi.agent.run.id",
|
|
79
|
+
PI_AGENT_RUN_INDEX: "pi.agent.run.index",
|
|
80
|
+
PI_AGENT_RUN_SOURCE: "pi.agent.run.source",
|
|
81
|
+
PI_AGENT_RUN_PROMPT_HASH: "pi.agent.run.prompt.hash",
|
|
82
|
+
PI_AGENT_RUN_PROMPT_LENGTH: "pi.agent.run.prompt.length",
|
|
83
|
+
GEN_AI_AGENT_ID: "gen_ai.agent.id",
|
|
84
|
+
GEN_AI_AGENT_NAME: "gen_ai.agent.name",
|
|
85
|
+
GEN_AI_AGENT_VERSION: "gen_ai.agent.version",
|
|
86
|
+
} as const;
|
|
87
|
+
|
|
88
|
+
export const AGENT_SPAWN_ATTRIBUTES = {
|
|
89
|
+
PI_AGENT_SPAWN_ID: "pi.agent.spawn.id",
|
|
90
|
+
PI_AGENT_SPAWN_TYPE: "pi.agent.spawn.type",
|
|
91
|
+
PI_AGENT_SPAWN_REASON: "pi.agent.spawn.reason",
|
|
92
|
+
PI_AGENT_SPAWN_OUTCOME: "pi.agent.spawn.outcome",
|
|
93
|
+
PI_AGENT_SPAWN_TOOL_CALL_ID: "pi.agent.spawn.tool_call_id",
|
|
94
|
+
PI_AGENT_SPAWN_COMMAND_HASH: "pi.agent.spawn.command.hash",
|
|
95
|
+
PI_AGENT_CHILD_ID: "pi.agent.child.id",
|
|
96
|
+
PI_AGENT_CHILD_COUNT: "pi.agent.child.count",
|
|
97
|
+
PI_AGENT_CHILDREN_ACTIVE: "pi.agent.children.active",
|
|
98
|
+
PI_AGENT_PARENT_ID: "pi.agent.parent_id",
|
|
99
|
+
PI_AGENT_ROOT_ID: "pi.agent.root_id",
|
|
100
|
+
PI_WORKFLOW_ID: "pi.workflow.id",
|
|
101
|
+
PI_WORKFLOW_ROOT_AGENT_ID: "pi.workflow.root_agent_id",
|
|
102
|
+
PI_AGENT_DEPTH: "pi.agent.depth",
|
|
103
|
+
PI_SESSION_ID: "pi.session.id",
|
|
104
|
+
PI_AGENT_SPAWN_TRACE_CONTEXT_PROPAGATED: "pi.agent.spawn.trace_context_propagated",
|
|
105
|
+
} as const;
|
|
106
|
+
|
|
107
|
+
export const AGENT_WAIT_JOIN_ATTRIBUTES = {
|
|
108
|
+
PI_WORKFLOW_ID: "pi.workflow.id",
|
|
109
|
+
PI_AGENT_ID: "pi.agent.id",
|
|
110
|
+
PI_AGENT_CHILD_ID: "pi.agent.child.id",
|
|
111
|
+
PI_AGENT_SPAWN_ID: "pi.agent.spawn.id",
|
|
112
|
+
PI_AGENT_WAIT_REASON: "pi.agent.wait.reason",
|
|
113
|
+
PI_AGENT_JOIN_STATUS: "pi.agent.join.status",
|
|
114
|
+
PI_AGENT_CHILD_STATUS: "pi.agent.child.status",
|
|
115
|
+
PI_AGENT_FAILURE_PROPAGATED: "pi.agent.failure.propagated",
|
|
116
|
+
PI_AGENT_CHILDREN_ACTIVE: "pi.agent.children.active",
|
|
117
|
+
PI_AGENT_CHILD_COUNT: "pi.agent.child.count",
|
|
118
|
+
} as const;
|
|
119
|
+
|
|
120
|
+
export const TURN_ATTRIBUTES = {
|
|
121
|
+
PI_TURN_ID: "pi.turn.id",
|
|
122
|
+
PI_TURN_INDEX: "pi.turn.index",
|
|
123
|
+
PI_TURN_BRANCH_PATH_HASH: "pi.turn.branch_path_hash",
|
|
124
|
+
PI_TURN_USER_MESSAGE_HASH: "pi.turn.user_message.hash",
|
|
125
|
+
PI_TURN_USER_MESSAGE_LENGTH: "pi.turn.user_message.length",
|
|
126
|
+
PI_TURN_USER_MESSAGE_IMAGE_COUNT: "pi.turn.user_message.image_count",
|
|
127
|
+
PI_MODEL_PROVIDER_CURRENT: "pi.model.provider.current",
|
|
128
|
+
PI_MODEL_ID_CURRENT: "pi.model.id.current",
|
|
129
|
+
} as const;
|
|
130
|
+
|
|
131
|
+
export const LLM_ATTRIBUTES = {
|
|
132
|
+
GEN_AI_OPERATION_NAME: "gen_ai.operation.name",
|
|
133
|
+
GEN_AI_PROVIDER_NAME: "gen_ai.provider.name",
|
|
134
|
+
GEN_AI_REQUEST_MODEL: "gen_ai.request.model",
|
|
135
|
+
GEN_AI_RESPONSE_MODEL: "gen_ai.response.model",
|
|
136
|
+
GEN_AI_RESPONSE_ID: "gen_ai.response.id",
|
|
137
|
+
GEN_AI_RESPONSE_FINISH_REASONS: "gen_ai.response.finish_reasons",
|
|
138
|
+
GEN_AI_REQUEST_TEMPERATURE: "gen_ai.request.temperature",
|
|
139
|
+
GEN_AI_REQUEST_MAX_TOKENS: "gen_ai.request.max_tokens",
|
|
140
|
+
GEN_AI_USAGE_INPUT_TOKENS: "gen_ai.usage.input_tokens",
|
|
141
|
+
GEN_AI_USAGE_OUTPUT_TOKENS: "gen_ai.usage.output_tokens",
|
|
142
|
+
GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS: "gen_ai.usage.cache_read.input_tokens",
|
|
143
|
+
GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS: "gen_ai.usage.cache_creation.input_tokens",
|
|
144
|
+
GEN_AI_USAGE_REASONING_OUTPUT_TOKENS: "gen_ai.usage.reasoning.output_tokens",
|
|
145
|
+
GEN_AI_CONVERSATION_ID: "gen_ai.conversation.id",
|
|
146
|
+
ERROR_TYPE: "error.type",
|
|
147
|
+
PI_LLM_API: "pi.llm.api",
|
|
148
|
+
PI_LLM_REQUEST_THINKING_LEVEL: "pi.llm.request.thinking_level",
|
|
149
|
+
PI_LLM_REQUEST_MESSAGE_COUNT: "pi.llm.request.message_count",
|
|
150
|
+
PI_LLM_REQUEST_TOOL_SCHEMA_COUNT: "pi.llm.request.tool_schema_count",
|
|
151
|
+
PI_LLM_REQUEST_INPUT_CHARS: "pi.llm.request.input_chars",
|
|
152
|
+
PI_LLM_REQUEST_ID: "pi.llm.request.id",
|
|
153
|
+
PI_LLM_STOP_REASON: "pi.llm.stop_reason",
|
|
154
|
+
PI_LLM_ERROR_MESSAGE_HASH: "pi.llm.error_message_hash",
|
|
155
|
+
PI_LLM_USAGE_TOTAL_TOKENS: "pi.llm.usage.total_tokens",
|
|
156
|
+
PI_LLM_USAGE_CACHE_WRITE_1H_TOKENS: "pi.llm.usage.cache_write_1h_tokens",
|
|
157
|
+
PI_LLM_COST_INPUT_USD: "pi.llm.cost.input_usd",
|
|
158
|
+
PI_LLM_COST_OUTPUT_USD: "pi.llm.cost.output_usd",
|
|
159
|
+
PI_LLM_COST_CACHE_READ_USD: "pi.llm.cost.cache_read_usd",
|
|
160
|
+
PI_LLM_COST_CACHE_WRITE_USD: "pi.llm.cost.cache_write_usd",
|
|
161
|
+
PI_LLM_COST_TOTAL_USD: "pi.llm.cost.total_usd",
|
|
162
|
+
PI_LLM_TOOL_CALL_COUNT: "pi.llm.tool_call_count",
|
|
163
|
+
GEN_AI_INPUT_MESSAGES: "gen_ai.input.messages",
|
|
164
|
+
GEN_AI_OUTPUT_MESSAGES: "gen_ai.output.messages",
|
|
165
|
+
PI_LLM_PROMPT_REDACTED: "pi.llm.prompt.redacted",
|
|
166
|
+
PI_LLM_RESPONSE_REDACTED: "pi.llm.response.redacted",
|
|
167
|
+
PI_LLM_THINKING_REDACTED: "pi.llm.thinking.redacted",
|
|
168
|
+
PI_LLM_CONTENT_KIND: "pi.llm.content.kind",
|
|
169
|
+
} as const;
|
|
170
|
+
|
|
171
|
+
export const MESSAGE_ATTRIBUTES = {
|
|
172
|
+
PI_MESSAGE_ROLE: "pi.message.role",
|
|
173
|
+
PI_MESSAGE_CONTENT_LENGTH: "pi.message.content_length",
|
|
174
|
+
} as const;
|
|
175
|
+
|
|
176
|
+
export const TOOL_ATTRIBUTES = {
|
|
177
|
+
PI_TOOL_CALL_ID: "pi.tool.call.id",
|
|
178
|
+
PI_TOOL_NAME: "pi.tool.name",
|
|
179
|
+
PI_TOOL_CATEGORY: "pi.tool.category",
|
|
180
|
+
PI_TOOL_ARGUMENTS_HASH: "pi.tool.arguments.hash",
|
|
181
|
+
PI_TOOL_ARGUMENTS_SIZE: "pi.tool.arguments.size",
|
|
182
|
+
PI_TOOL_RESULT_SIZE: "pi.tool.result.size",
|
|
183
|
+
PI_TOOL_RESULT_HASH: "pi.tool.result.hash",
|
|
184
|
+
PI_TOOL_SUCCESS: "pi.tool.success",
|
|
185
|
+
PI_TOOL_ERROR: "pi.tool.error",
|
|
186
|
+
PI_TOOL_ERROR_CLASS: "pi.tool.error_class",
|
|
187
|
+
GEN_AI_TOOL_CALL_ID: "gen_ai.tool.call.id",
|
|
188
|
+
GEN_AI_TOOL_NAME: "gen_ai.tool.name",
|
|
189
|
+
GEN_AI_TOOL_TYPE: "gen_ai.tool.type",
|
|
190
|
+
PI_TOOL_ARGUMENTS_REDACTED: "pi.tool.arguments.redacted",
|
|
191
|
+
PI_TOOL_RESULT_REDACTED: "pi.tool.result.redacted",
|
|
192
|
+
GEN_AI_TOOL_CALL_ARGUMENTS: "gen_ai.tool.call.arguments",
|
|
193
|
+
GEN_AI_TOOL_CALL_RESULT: "gen_ai.tool.call.result",
|
|
194
|
+
} as const;
|
|
195
|
+
|
|
196
|
+
export const BASH_ATTRIBUTES = {
|
|
197
|
+
PI_BASH_COMMAND_HASH: "pi.bash.command.hash",
|
|
198
|
+
PI_BASH_COMMAND_REDACTED: "pi.bash.command.redacted",
|
|
199
|
+
PI_BASH_EXIT_CODE: "pi.bash.exit_code",
|
|
200
|
+
PI_BASH_CANCELLED: "pi.bash.cancelled",
|
|
201
|
+
PI_BASH_TRUNCATED: "pi.bash.truncated",
|
|
202
|
+
PI_BASH_OUTPUT_SIZE: "pi.bash.output.size",
|
|
203
|
+
PI_BASH_OUTPUT_HASH: "pi.bash.output.hash",
|
|
204
|
+
PI_BASH_OUTPUT_REDACTED: "pi.bash.output.redacted",
|
|
205
|
+
PI_BASH_FULL_OUTPUT_PATH_PRESENT: "pi.bash.full_output_path_present",
|
|
206
|
+
PI_BASH_EXCLUDE_FROM_CONTEXT: "pi.bash.exclude_from_context",
|
|
207
|
+
} as const;
|
|
208
|
+
|
|
209
|
+
export const BRANCH_ATTRIBUTES = {
|
|
210
|
+
PI_BRANCH_FROM_ID: "pi.branch.from_id",
|
|
211
|
+
PI_BRANCH_TO_ID: "pi.branch.to_id",
|
|
212
|
+
PI_BRANCH_COMMON_ANCESTOR_ID: "pi.branch.common_ancestor_id",
|
|
213
|
+
PI_BRANCH_PATH_HASH: "pi.branch.path_hash",
|
|
214
|
+
PI_LEAF_ID: "pi.leaf.id",
|
|
215
|
+
PI_BRANCH_SUMMARY_HASH: "pi.branch.summary.hash",
|
|
216
|
+
PI_BRANCH_SUMMARY_LENGTH: "pi.branch.summary.length",
|
|
217
|
+
PI_BRANCH_FROM_HOOK: "pi.branch.from_hook",
|
|
218
|
+
PI_BRANCH_READ_FILES_COUNT: "pi.branch.read_files_count",
|
|
219
|
+
PI_BRANCH_MODIFIED_FILES_COUNT: "pi.branch.modified_files_count",
|
|
220
|
+
} as const;
|
|
221
|
+
|
|
222
|
+
export const COMPACTION_ATTRIBUTES = {
|
|
223
|
+
PI_COMPACTION_FIRST_KEPT_ENTRY_ID: "pi.compaction.first_kept_entry_id",
|
|
224
|
+
PI_COMPACTION_TOKENS_BEFORE: "pi.compaction.tokens_before",
|
|
225
|
+
PI_COMPACTION_SUMMARY_HASH: "pi.compaction.summary.hash",
|
|
226
|
+
PI_COMPACTION_SUMMARY_LENGTH: "pi.compaction.summary.length",
|
|
227
|
+
PI_COMPACTION_FROM_HOOK: "pi.compaction.from_hook",
|
|
228
|
+
PI_COMPACTION_REASON: "pi.compaction.reason",
|
|
229
|
+
PI_COMPACTION_WILL_RETRY: "pi.compaction.will_retry",
|
|
230
|
+
PI_COMPACTION_READ_FILES_COUNT: "pi.compaction.read_files_count",
|
|
231
|
+
PI_COMPACTION_MODIFIED_FILES_COUNT: "pi.compaction.modified_files_count",
|
|
232
|
+
} as const;
|
|
233
|
+
|
|
234
|
+
export const CONFIG_ATTRIBUTES = {
|
|
235
|
+
OBSERVME_CONFIG_SOURCE: "observme.config.source",
|
|
236
|
+
OBSERVME_CONFIG_REJECTION_ISSUE_CODES: "observme.config.rejection.issue_codes",
|
|
237
|
+
OBSERVME_CONFIG_REJECTION_ISSUE_COUNT: "observme.config.rejection.issue_count",
|
|
238
|
+
} as const;
|
|
239
|
+
|
|
240
|
+
export const LOG_ATTRIBUTES = {
|
|
241
|
+
EVENT_NAME: "event.name",
|
|
242
|
+
EVENT_CATEGORY: "event.category",
|
|
243
|
+
PI_SESSION_ID: "pi.session.id",
|
|
244
|
+
PI_WORKFLOW_ID: "pi.workflow.id",
|
|
245
|
+
PI_WORKFLOW_ROOT_AGENT_ID: "pi.workflow.root_agent_id",
|
|
246
|
+
PI_AGENT_ID: "pi.agent.id",
|
|
247
|
+
PI_AGENT_PARENT_ID: "pi.agent.parent_id",
|
|
248
|
+
PI_AGENT_ROOT_ID: "pi.agent.root_id",
|
|
249
|
+
PI_AGENT_RUN_ID: "pi.agent.run.id",
|
|
250
|
+
PI_TURN_ID: "pi.turn.id",
|
|
251
|
+
TRACE_ID: "trace_id",
|
|
252
|
+
SPAN_ID: "span_id",
|
|
253
|
+
SEVERITY: "severity",
|
|
254
|
+
ERROR_TYPE: "error.type",
|
|
255
|
+
} as const;
|
|
256
|
+
|
|
257
|
+
export const ATTRIBUTE_GROUPS = {
|
|
258
|
+
RESOURCE_ATTRIBUTES,
|
|
259
|
+
SESSION_ATTRIBUTES,
|
|
260
|
+
WORKFLOW_ATTRIBUTES,
|
|
261
|
+
COMMON_SPAN_ATTRIBUTES,
|
|
262
|
+
AGENT_LINEAGE_ATTRIBUTES,
|
|
263
|
+
AGENT_RUN_ATTRIBUTES,
|
|
264
|
+
AGENT_SPAWN_ATTRIBUTES,
|
|
265
|
+
AGENT_WAIT_JOIN_ATTRIBUTES,
|
|
266
|
+
TURN_ATTRIBUTES,
|
|
267
|
+
LLM_ATTRIBUTES,
|
|
268
|
+
MESSAGE_ATTRIBUTES,
|
|
269
|
+
TOOL_ATTRIBUTES,
|
|
270
|
+
BASH_ATTRIBUTES,
|
|
271
|
+
BRANCH_ATTRIBUTES,
|
|
272
|
+
COMPACTION_ATTRIBUTES,
|
|
273
|
+
CONFIG_ATTRIBUTES,
|
|
274
|
+
LOG_ATTRIBUTES,
|
|
275
|
+
} as const;
|
|
276
|
+
|
|
277
|
+
export const ALL_ATTRIBUTE_KEYS = [
|
|
278
|
+
...new Set(Object.values(ATTRIBUTE_GROUPS).flatMap(group => Object.values(group))),
|
|
279
|
+
].sort((left, right) => left.localeCompare(right));
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
export const OBSERVME_COUNTER_METRIC_NAMES = {
|
|
2
|
+
SESSIONS_STARTED_TOTAL: "observme_sessions_started_total",
|
|
3
|
+
SESSIONS_SHUTDOWN_TOTAL: "observme_sessions_shutdown_total",
|
|
4
|
+
WORKFLOWS_STARTED_TOTAL: "observme_workflows_started_total",
|
|
5
|
+
WORKFLOWS_COMPLETED_TOTAL: "observme_workflows_completed_total",
|
|
6
|
+
WORKFLOW_ERRORS_TOTAL: "observme_workflow_errors_total",
|
|
7
|
+
AGENT_RUNS_TOTAL: "observme_agent_runs_total",
|
|
8
|
+
AGENT_RUN_ERRORS_TOTAL: "observme_agent_run_errors_total",
|
|
9
|
+
SUBAGENTS_SPAWNED_TOTAL: "observme_subagents_spawned_total",
|
|
10
|
+
SUBAGENT_SPAWN_FAILURES_TOTAL: "observme_subagent_spawn_failures_total",
|
|
11
|
+
ORPHAN_AGENTS_TOTAL: "observme_orphan_agents_total",
|
|
12
|
+
TRACE_CONTEXT_PROPAGATION_FAILURES_TOTAL: "observme_trace_context_propagation_failures_total",
|
|
13
|
+
CHILD_AGENT_FAILURES_TOTAL: "observme_child_agent_failures_total",
|
|
14
|
+
PARENT_RECOVERED_FROM_CHILD_FAILURE_TOTAL: "observme_parent_recovered_from_child_failure_total",
|
|
15
|
+
TURNS_STARTED_TOTAL: "observme_turns_started_total",
|
|
16
|
+
TURNS_COMPLETED_TOTAL: "observme_turns_completed_total",
|
|
17
|
+
LLM_REQUESTS_TOTAL: "observme_llm_requests_total",
|
|
18
|
+
LLM_ERRORS_TOTAL: "observme_llm_errors_total",
|
|
19
|
+
TOOL_CALLS_TOTAL: "observme_tool_calls_total",
|
|
20
|
+
TOOL_FAILURES_TOTAL: "observme_tool_failures_total",
|
|
21
|
+
BASH_EXECUTIONS_TOTAL: "observme_bash_executions_total",
|
|
22
|
+
BASH_FAILURES_TOTAL: "observme_bash_failures_total",
|
|
23
|
+
MODEL_CHANGES_TOTAL: "observme_model_changes_total",
|
|
24
|
+
THINKING_LEVEL_CHANGES_TOTAL: "observme_thinking_level_changes_total",
|
|
25
|
+
COMPACTIONS_TOTAL: "observme_compactions_total",
|
|
26
|
+
BRANCHES_TOTAL: "observme_branches_total",
|
|
27
|
+
TELEMETRY_DROPPED_TOTAL: "observme_telemetry_dropped_total",
|
|
28
|
+
EXPORT_ERRORS_TOTAL: "observme_export_errors_total",
|
|
29
|
+
REDACTION_FAILURES_TOTAL: "observme_redaction_failures_total",
|
|
30
|
+
EVENTS_OBSERVED_TOTAL: "observme_events_observed_total",
|
|
31
|
+
HANDLER_ERRORS_TOTAL: "observme_handler_errors_total",
|
|
32
|
+
} as const;
|
|
33
|
+
|
|
34
|
+
export const OBSERVME_TOKEN_COST_COUNTER_METRIC_NAMES = {
|
|
35
|
+
LLM_INPUT_TOKENS_TOTAL: "observme_llm_input_tokens_total",
|
|
36
|
+
LLM_OUTPUT_TOKENS_TOTAL: "observme_llm_output_tokens_total",
|
|
37
|
+
LLM_CACHE_READ_TOKENS_TOTAL: "observme_llm_cache_read_tokens_total",
|
|
38
|
+
LLM_CACHE_WRITE_TOKENS_TOTAL: "observme_llm_cache_write_tokens_total",
|
|
39
|
+
LLM_CACHE_WRITE_1H_TOKENS_TOTAL: "observme_llm_cache_write_1h_tokens_total",
|
|
40
|
+
LLM_REASONING_TOKENS_TOTAL: "observme_llm_reasoning_tokens_total",
|
|
41
|
+
LLM_TOTAL_TOKENS_TOTAL: "observme_llm_total_tokens_total",
|
|
42
|
+
LLM_COST_USD_TOTAL: "observme_llm_cost_usd_total",
|
|
43
|
+
} as const;
|
|
44
|
+
|
|
45
|
+
export const OBSERVME_HISTOGRAM_METRIC_NAMES = {
|
|
46
|
+
WORKFLOW_DURATION_MS: "observme_workflow_duration_ms",
|
|
47
|
+
AGENT_RUN_DURATION_MS: "observme_agent_run_duration_ms",
|
|
48
|
+
AGENT_LIFETIME_DURATION_MS: "observme_agent_lifetime_duration_ms",
|
|
49
|
+
SUBAGENT_SPAWN_DURATION_MS: "observme_subagent_spawn_duration_ms",
|
|
50
|
+
AGENT_WAIT_DURATION_MS: "observme_agent_wait_duration_ms",
|
|
51
|
+
AGENT_JOIN_DURATION_MS: "observme_agent_join_duration_ms",
|
|
52
|
+
AGENT_TREE_DEPTH: "observme_agent_tree_depth",
|
|
53
|
+
AGENT_TREE_WIDTH: "observme_agent_tree_width",
|
|
54
|
+
AGENT_FANOUT_COUNT: "observme_agent_fanout_count",
|
|
55
|
+
TURN_DURATION_MS: "observme_turn_duration_ms",
|
|
56
|
+
LLM_REQUEST_DURATION_MS: "observme_llm_request_duration_ms",
|
|
57
|
+
TOOL_DURATION_MS: "observme_tool_duration_ms",
|
|
58
|
+
BASH_DURATION_MS: "observme_bash_duration_ms",
|
|
59
|
+
COMPACTION_TOKENS_BEFORE: "observme_compaction_tokens_before",
|
|
60
|
+
PROMPT_SIZE_CHARS: "observme_prompt_size_chars",
|
|
61
|
+
RESPONSE_SIZE_CHARS: "observme_response_size_chars",
|
|
62
|
+
TOOL_RESULT_SIZE_CHARS: "observme_tool_result_size_chars",
|
|
63
|
+
HANDLER_DURATION_MS: "observme_handler_duration_ms",
|
|
64
|
+
} as const;
|
|
65
|
+
|
|
66
|
+
export const OBSERVME_GAUGE_METRIC_NAMES = {
|
|
67
|
+
ACTIVE_SPANS: "observme_active_spans",
|
|
68
|
+
ACTIVE_AGENTS: "observme_active_agents",
|
|
69
|
+
} as const;
|
|
70
|
+
|
|
71
|
+
export const OFFICIAL_GENAI_METRIC_NAMES = {
|
|
72
|
+
CLIENT_TOKEN_USAGE: "gen_ai.client.token.usage",
|
|
73
|
+
CLIENT_OPERATION_DURATION: "gen_ai.client.operation.duration",
|
|
74
|
+
} as const;
|
|
75
|
+
|
|
76
|
+
export const LOG_EVENT_NAMES = {
|
|
77
|
+
CONFIG_REJECTED: "config.rejected",
|
|
78
|
+
SESSION_STARTED: "session.started",
|
|
79
|
+
SESSION_NAMED: "session.named",
|
|
80
|
+
SESSION_SHUTDOWN: "session.shutdown",
|
|
81
|
+
SESSION_ERROR: "session.error",
|
|
82
|
+
SESSION_DUPLICATE_START: "session.duplicate_start",
|
|
83
|
+
WORKFLOW_STARTED: "workflow.started",
|
|
84
|
+
WORKFLOW_COMPLETED: "workflow.completed",
|
|
85
|
+
WORKFLOW_FAILED: "workflow.failed",
|
|
86
|
+
AGENT_RUN_STARTED: "agent.run.started",
|
|
87
|
+
AGENT_RUN_COMPLETED: "agent.run.completed",
|
|
88
|
+
AGENT_RUN_FAILED: "agent.run.failed",
|
|
89
|
+
AGENT_SPAWN_STARTED: "agent.spawn.started",
|
|
90
|
+
AGENT_SPAWN_COMPLETED: "agent.spawn.completed",
|
|
91
|
+
AGENT_SPAWN_FAILED: "agent.spawn.failed",
|
|
92
|
+
AGENT_WAIT_STARTED: "agent.wait.started",
|
|
93
|
+
AGENT_WAIT_COMPLETED: "agent.wait.completed",
|
|
94
|
+
AGENT_JOIN_STARTED: "agent.join.started",
|
|
95
|
+
AGENT_JOIN_COMPLETED: "agent.join.completed",
|
|
96
|
+
AGENT_ORPHANED: "agent.orphaned",
|
|
97
|
+
TRACE_CONTEXT_PROPAGATION_FAILED: "trace_context.propagation_failed",
|
|
98
|
+
TURN_STARTED: "turn.started",
|
|
99
|
+
TURN_COMPLETED: "turn.completed",
|
|
100
|
+
LLM_REQUEST_STARTED: "llm.request.started",
|
|
101
|
+
LLM_REQUEST_COMPLETED: "llm.request.completed",
|
|
102
|
+
LLM_REQUEST_FAILED: "llm.request.failed",
|
|
103
|
+
LLM_PROMPT_CAPTURED: "llm.prompt.captured",
|
|
104
|
+
LLM_RESPONSE_CAPTURED: "llm.response.captured",
|
|
105
|
+
LLM_THINKING_CAPTURED: "llm.thinking.captured",
|
|
106
|
+
MESSAGE_REPLAYED: "message.replayed",
|
|
107
|
+
TOOL_CALL_STARTED: "tool.call.started",
|
|
108
|
+
TOOL_CALL_COMPLETED: "tool.call.completed",
|
|
109
|
+
TOOL_CALL_FAILED: "tool.call.failed",
|
|
110
|
+
TOOL_ERROR_CAPTURED: "tool.error.captured",
|
|
111
|
+
BASH_COMPLETED: "bash.completed",
|
|
112
|
+
MODEL_CHANGED: "model.changed",
|
|
113
|
+
THINKING_CHANGED: "thinking.changed",
|
|
114
|
+
BRANCH_CREATED: "branch.created",
|
|
115
|
+
COMPACTION_CREATED: "compaction.created",
|
|
116
|
+
REDACTION_FAILED: "redaction.failed",
|
|
117
|
+
EXPORT_FAILED: "export.failed",
|
|
118
|
+
HANDLER_FAILED: "handler.failed",
|
|
119
|
+
TELEMETRY_DROPPED: "telemetry.dropped",
|
|
120
|
+
} as const;
|
|
121
|
+
|
|
122
|
+
export const OBSERVME_METRIC_NAME_GROUPS = {
|
|
123
|
+
COUNTERS: OBSERVME_COUNTER_METRIC_NAMES,
|
|
124
|
+
TOKEN_COST_COUNTERS: OBSERVME_TOKEN_COST_COUNTER_METRIC_NAMES,
|
|
125
|
+
HISTOGRAMS: OBSERVME_HISTOGRAM_METRIC_NAMES,
|
|
126
|
+
GAUGES: OBSERVME_GAUGE_METRIC_NAMES,
|
|
127
|
+
} as const;
|
|
128
|
+
|
|
129
|
+
export const ALL_OBSERVME_METRIC_NAMES = [
|
|
130
|
+
...new Set(Object.values(OBSERVME_METRIC_NAME_GROUPS).flatMap(group => Object.values(group))),
|
|
131
|
+
].sort((left, right) => left.localeCompare(right));
|
|
132
|
+
|
|
133
|
+
export const ALL_OFFICIAL_GENAI_METRIC_NAMES = Object.values(OFFICIAL_GENAI_METRIC_NAMES).sort((left, right) =>
|
|
134
|
+
left.localeCompare(right),
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
export const ALL_METRIC_NAMES = [...ALL_OBSERVME_METRIC_NAMES, ...ALL_OFFICIAL_GENAI_METRIC_NAMES].sort((left, right) =>
|
|
138
|
+
left.localeCompare(right),
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
export const ALL_LOG_EVENT_NAMES = Object.values(LOG_EVENT_NAMES).sort((left, right) => left.localeCompare(right));
|
|
142
|
+
|
|
143
|
+
export type ObservMeMetricName = (typeof ALL_OBSERVME_METRIC_NAMES)[number];
|
|
144
|
+
export type OfficialGenAiMetricName = (typeof ALL_OFFICIAL_GENAI_METRIC_NAMES)[number];
|
|
145
|
+
export type MetricName = (typeof ALL_METRIC_NAMES)[number];
|
|
146
|
+
export type LogEventName = (typeof ALL_LOG_EVENT_NAMES)[number];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const SPAN_NAMES = {
|
|
2
|
+
PI_SESSION: "pi.session",
|
|
3
|
+
PI_AGENT_RUN: "pi.agent.run",
|
|
4
|
+
PI_AGENT_SPAWN: "pi.agent.spawn",
|
|
5
|
+
PI_AGENT_WAIT: "pi.agent.wait",
|
|
6
|
+
PI_AGENT_JOIN: "pi.agent.join",
|
|
7
|
+
PI_TURN: "pi.turn",
|
|
8
|
+
PI_LLM_REQUEST: "pi.llm.request",
|
|
9
|
+
PI_TOOL_CALL: "pi.tool.call",
|
|
10
|
+
PI_BASH_EXECUTION: "pi.bash.execution",
|
|
11
|
+
PI_COMPACTION: "pi.compaction",
|
|
12
|
+
PI_BRANCH: "pi.branch",
|
|
13
|
+
PI_MODEL_CHANGE: "pi.model.change",
|
|
14
|
+
PI_THINKING_CHANGE: "pi.thinking.change",
|
|
15
|
+
} as const;
|
|
16
|
+
|
|
17
|
+
export const ALL_SPAN_NAMES = Object.values(SPAN_NAMES).sort((left, right) => left.localeCompare(right));
|
|
18
|
+
|
|
19
|
+
export type SpanName = (typeof ALL_SPAN_NAMES)[number];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const SUBAGENT_SPAWN_REASON_VALUES = [
|
|
2
|
+
"delegated_task",
|
|
3
|
+
"parallel_search",
|
|
4
|
+
"review",
|
|
5
|
+
"tool_wrapper",
|
|
6
|
+
"unknown",
|
|
7
|
+
] as const;
|
|
8
|
+
|
|
9
|
+
export type SubagentSpawnReason = (typeof SUBAGENT_SPAWN_REASON_VALUES)[number];
|
|
10
|
+
|
|
11
|
+
export const AGENT_WAIT_REASON_VALUES = ["dependency", "rate_limit", "child_running", "unknown"] as const;
|
|
12
|
+
|
|
13
|
+
export type AgentWaitReason = (typeof AGENT_WAIT_REASON_VALUES)[number];
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export interface BoundedMapEviction<K, V> {
|
|
2
|
+
readonly key: K;
|
|
3
|
+
readonly value: V;
|
|
4
|
+
readonly reason: "max_size_exceeded";
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface BoundedMapOptions<K, V> {
|
|
8
|
+
readonly maxSize: number;
|
|
9
|
+
readonly onEvict?: (eviction: BoundedMapEviction<K, V>) => void;
|
|
10
|
+
readonly entries?: Iterable<readonly [K, V]>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class BoundedMap<K, V> implements Iterable<[K, V]> {
|
|
14
|
+
readonly #maxSize: number;
|
|
15
|
+
readonly #entries = new Map<K, V>();
|
|
16
|
+
readonly #onEvict?: (eviction: BoundedMapEviction<K, V>) => void;
|
|
17
|
+
|
|
18
|
+
constructor(options: BoundedMapOptions<K, V>) {
|
|
19
|
+
assertValidMaxSize(options.maxSize);
|
|
20
|
+
this.#maxSize = options.maxSize;
|
|
21
|
+
this.#onEvict = options.onEvict;
|
|
22
|
+
|
|
23
|
+
if (options.entries) this.setMany(options.entries);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get maxSize(): number {
|
|
27
|
+
return this.#maxSize;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get size(): number {
|
|
31
|
+
return this.#entries.size;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get(key: K): V | undefined {
|
|
35
|
+
return this.#entries.get(key);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
has(key: K): boolean {
|
|
39
|
+
return this.#entries.has(key);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
set(key: K, value: V): this {
|
|
43
|
+
this.#entries.set(key, value);
|
|
44
|
+
this.evictOldestEntriesOverLimit();
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
setMany(entries: Iterable<readonly [K, V]>): this {
|
|
49
|
+
for (const [key, value] of entries) this.set(key, value);
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
delete(key: K): boolean {
|
|
54
|
+
return this.#entries.delete(key);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
clear(): void {
|
|
58
|
+
this.#entries.clear();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
keys(): MapIterator<K> {
|
|
62
|
+
return this.#entries.keys();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
values(): MapIterator<V> {
|
|
66
|
+
return this.#entries.values();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
entries(): MapIterator<[K, V]> {
|
|
70
|
+
return this.#entries.entries();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
toMap(): Map<K, V> {
|
|
74
|
+
return new Map(this.#entries);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
[Symbol.iterator](): MapIterator<[K, V]> {
|
|
78
|
+
return this.entries();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private evictOldestEntriesOverLimit(): void {
|
|
82
|
+
while (this.#entries.size > this.#maxSize) this.evictOldestEntry();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private evictOldestEntry(): void {
|
|
86
|
+
const oldestEntry = this.#entries.entries().next().value;
|
|
87
|
+
if (!oldestEntry) return;
|
|
88
|
+
|
|
89
|
+
const [key, value] = oldestEntry;
|
|
90
|
+
this.#entries.delete(key);
|
|
91
|
+
this.#onEvict?.({ key, value, reason: "max_size_exceeded" });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function assertValidMaxSize(maxSize: number): void {
|
|
96
|
+
if (!Number.isInteger(maxSize) || maxSize < 1) throw new Error("BoundedMap maxSize must be a positive integer");
|
|
97
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2023",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"noEmit": true,
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"types": ["node"]
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*.ts"]
|
|
15
|
+
}
|