melchizedek-agents 0.16.1 → 0.16.2
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/CHANGELOG.md +13 -0
- package/dist/lib/observability/otlpFilter.js +19 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ Consumers of the package read this file; it records changes to the
|
|
|
4
4
|
**published API surface** (the exports map in `package.json`, the bins,
|
|
5
5
|
the starter pack and the templates), not the repo's full history.
|
|
6
6
|
|
|
7
|
+
## 0.16.2 — 2026-10-02
|
|
8
|
+
|
|
9
|
+
- **`OTEL_EXPORT_CONTENT=off` also drops library content attributes.** In
|
|
10
|
+
0.16.1, `off` removed the engine's own conversation attributes but let
|
|
11
|
+
through ADK's: its `call_llm` span carries the full model request and
|
|
12
|
+
response as `gcp.vertex.agent.llm_request` / `_response`. `off` now drops
|
|
13
|
+
any text attribute whose name marks content (request, response, input,
|
|
14
|
+
output, args, prompt, messages, thinking, payload, …) unless the name
|
|
15
|
+
marks metadata (model, name, id, finish reasons); numbers always stay.
|
|
16
|
+
Verified end to end against Jaeger. **If you export OTLP with
|
|
17
|
+
`OTEL_EXPORT_CONTENT=off`, upgrade.** The default `redacted` mode
|
|
18
|
+
already ran the redactor on those attributes.
|
|
19
|
+
|
|
7
20
|
## 0.16.1 — 2026-10-02
|
|
8
21
|
|
|
9
22
|
- **OTLP export is filtered before it leaves** (`OTEL_EXPORT_CONTENT`).
|
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* OTEL_EXPORT_CONTENT=redacted (default) the ledger's redactor runs on
|
|
11
11
|
* every text attribute and event
|
|
12
|
-
* OTEL_EXPORT_CONTENT=off conversation attributes are dropped
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* OTEL_EXPORT_CONTENT=off conversation attributes are dropped (the
|
|
13
|
+
* engine's and any library's, by name) and
|
|
14
|
+
* the user id is hashed; timings, models,
|
|
15
|
+
* token counts, routes, error codes and ids
|
|
16
|
+
* remain
|
|
15
17
|
* OTEL_EXPORT_CONTENT=raw spans are sent as recorded
|
|
16
18
|
*/
|
|
17
19
|
import { createHash } from 'node:crypto';
|
|
@@ -29,6 +31,15 @@ export const CONTENT_ATTRIBUTES = new Set([
|
|
|
29
31
|
]);
|
|
30
32
|
const CONTENT_PREFIXES = ['llm.payload.'];
|
|
31
33
|
const PERSON_ATTRIBUTES = new Set(['user.id']);
|
|
34
|
+
/**
|
|
35
|
+
* Libraries add their own content attributes (ADK puts the whole model request
|
|
36
|
+
* on its call_llm span as `gcp.vertex.agent.llm_request`, and the response and
|
|
37
|
+
* tool calls beside it), and a later version can add more. So `off` also drops
|
|
38
|
+
* any text attribute whose name says it carries content, unless the name says
|
|
39
|
+
* it is metadata (a model, a name, an id, a finish reason).
|
|
40
|
+
*/
|
|
41
|
+
const CONTENT_KEY = /(^|[._])(request|response|input|output|args|arguments|prompt|completion|messages?|content|thinking|payload|data_gathered|bindings|reason|error_message)([._]|$)/i;
|
|
42
|
+
const METADATA_KEY = /([._])(model|name|id|system|description|finish_reasons|type|kind|version|stage)$/i;
|
|
32
43
|
export function otlpContentMode(env = process.env) {
|
|
33
44
|
const raw = (env.OTEL_EXPORT_CONTENT ?? 'redacted').trim().toLowerCase();
|
|
34
45
|
if (raw === 'off' || raw === 'none' || raw === 'false')
|
|
@@ -37,7 +48,10 @@ export function otlpContentMode(env = process.env) {
|
|
|
37
48
|
return 'raw';
|
|
38
49
|
return 'redacted';
|
|
39
50
|
}
|
|
40
|
-
const
|
|
51
|
+
const isText = (v) => typeof v === 'string' || (Array.isArray(v) && v.some((x) => typeof x === 'string'));
|
|
52
|
+
const isContent = (key, value) => CONTENT_ATTRIBUTES.has(key) ||
|
|
53
|
+
CONTENT_PREFIXES.some((p) => key.startsWith(p)) ||
|
|
54
|
+
(isText(value) && CONTENT_KEY.test(key) && !METADATA_KEY.test(key));
|
|
41
55
|
const hashed = (v) => `sha256:${createHash('sha256').update(String(v)).digest('hex').slice(0, 16)}`;
|
|
42
56
|
/** One span's attributes as they may leave under `mode`. */
|
|
43
57
|
export function filterAttributes(attributes, mode, redactor) {
|
|
@@ -46,7 +60,7 @@ export function filterAttributes(attributes, mode, redactor) {
|
|
|
46
60
|
const out = {};
|
|
47
61
|
for (const [key, value] of Object.entries(attributes)) {
|
|
48
62
|
if (mode === 'off') {
|
|
49
|
-
if (isContent(key))
|
|
63
|
+
if (isContent(key, value))
|
|
50
64
|
continue;
|
|
51
65
|
out[key] = PERSON_ATTRIBUTES.has(key) ? hashed(value) : value;
|
|
52
66
|
continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "melchizedek-agents",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.2",
|
|
4
4
|
"description": "A multi-model, multi-agent orchestration framework on Google ADK — YAML-defined syndicates, Supabase session persistence, pgvector long-term memory. Companion repo to the lyceumagents.com curriculum.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|