@poncho-ai/harness 0.59.7 → 0.59.9
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/.turbo/turbo-build.log +5 -5
- package/CHANGELOG.md +20 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +15 -2
- package/package.json +1 -1
- package/src/config.ts +5 -0
- package/src/harness.ts +13 -1
- package/src/storage/sql-dialect.ts +13 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @poncho-ai/harness@0.59.
|
|
2
|
+
> @poncho-ai/harness@0.59.9 build /home/runner/work/poncho-ai/poncho-ai/packages/harness
|
|
3
3
|
> node scripts/embed-docs.js && tsup src/index.ts --format esm --dts
|
|
4
4
|
|
|
5
5
|
[embed-docs] Generated poncho-docs.ts with 4 topics
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
[34mCLI[39m tsup v8.5.1
|
|
9
9
|
[34mCLI[39m Target: es2022
|
|
10
10
|
[34mESM[39m Build start
|
|
11
|
+
[32mESM[39m [1mdist/index.js [22m[32m558.75 KB[39m
|
|
11
12
|
[32mESM[39m [1mdist/isolate-F2PPSUL6.js [22m[32m53.82 KB[39m
|
|
12
|
-
[32mESM[39m
|
|
13
|
-
[32mESM[39m ⚡️ Build success in 257ms
|
|
13
|
+
[32mESM[39m ⚡️ Build success in 233ms
|
|
14
14
|
[34mDTS[39m Build start
|
|
15
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
15
|
+
[32mDTS[39m ⚡️ Build success in 7974ms
|
|
16
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m102.06 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @poncho-ai/harness
|
|
2
2
|
|
|
3
|
+
## 0.59.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`eb9600a`](https://github.com/cesr/poncho-ai/commit/eb9600a111cf74968689f8b33835d8b58c64e375) Thanks [@cesr](https://github.com/cesr)! - Root trace spans now carry `session.id` (= conversationId) and `user.id`
|
|
8
|
+
(new `config.telemetry.userId`) alongside the existing
|
|
9
|
+
`gen_ai.conversation.id` — the attributes observability backends
|
|
10
|
+
(Latitude) key session grouping and user filtering on.
|
|
11
|
+
|
|
12
|
+
## 0.59.8
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [`fb07954`](https://github.com/cesr/poncho-ai/commit/fb07954ee7edfa614bdd5ed27474f4d3be7c8f1f) Thanks [@cesr](https://github.com/cesr)! - Fix conversations.rename on Postgres: the JSONB `data` column usually
|
|
17
|
+
holds a JSON-encoded string scalar (update() binds JSON.stringify output),
|
|
18
|
+
so the 0.59.3 in-blob title update threw `cannot set path in scalar` and
|
|
19
|
+
every rename 500'd. The UPDATE now branches on jsonb_typeof(data) and
|
|
20
|
+
preserves each row's encoding (objects via jsonb_set; string scalars
|
|
21
|
+
unwrapped, set, and re-serialized).
|
|
22
|
+
|
|
3
23
|
## 0.59.7
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -756,6 +756,11 @@ interface PonchoConfig extends McpConfig {
|
|
|
756
756
|
url: string;
|
|
757
757
|
headers?: Record<string, string>;
|
|
758
758
|
};
|
|
759
|
+
/** End-user identifier (e.g. an email) stamped as `user.id` on every
|
|
760
|
+
* root trace span — observability backends (Latitude) group and
|
|
761
|
+
* filter traces by it. Per-harness, so a harness-per-user consumer
|
|
762
|
+
* sets it once at construction. */
|
|
763
|
+
userId?: string;
|
|
759
764
|
handler?: (event: unknown) => Promise<void> | void;
|
|
760
765
|
};
|
|
761
766
|
skills?: Record<string, Record<string, unknown>>;
|
|
@@ -1442,6 +1447,8 @@ declare class AgentHarness {
|
|
|
1442
1447
|
private otlpSpanProcessor?;
|
|
1443
1448
|
private otlpTracerProvider?;
|
|
1444
1449
|
private hasOtlpExporter;
|
|
1450
|
+
/** End-user id (config.telemetry.userId) stamped as `user.id` on root spans. */
|
|
1451
|
+
private telemetryUserId?;
|
|
1445
1452
|
private _browserSession?;
|
|
1446
1453
|
private _browserMod?;
|
|
1447
1454
|
private parsedAgent?;
|
package/dist/index.js
CHANGED
|
@@ -3918,7 +3918,10 @@ var SqlStorageEngine = class {
|
|
|
3918
3918
|
},
|
|
3919
3919
|
rename: async (conversationId, title) => {
|
|
3920
3920
|
const normalized = normalizeTitle2(title);
|
|
3921
|
-
const dataExpr = this.dialect.tag === "sqlite" ? `json_set(data, '$.title', $2)` : `
|
|
3921
|
+
const dataExpr = this.dialect.tag === "sqlite" ? `json_set(data, '$.title', $2)` : `CASE WHEN jsonb_typeof(data) = 'object'
|
|
3922
|
+
THEN jsonb_set(data, '{title}', to_jsonb($2::text))
|
|
3923
|
+
ELSE to_jsonb(jsonb_set((data #>> '{}')::jsonb, '{title}', to_jsonb($2::text))::text)
|
|
3924
|
+
END`;
|
|
3922
3925
|
await this.executor.run(
|
|
3923
3926
|
rewrite(
|
|
3924
3927
|
`UPDATE conversations SET title = $1, data = ${dataExpr}, updated_at = $3 WHERE id = $4`,
|
|
@@ -9508,6 +9511,8 @@ var AgentHarness = class _AgentHarness {
|
|
|
9508
9511
|
otlpSpanProcessor;
|
|
9509
9512
|
otlpTracerProvider;
|
|
9510
9513
|
hasOtlpExporter = false;
|
|
9514
|
+
/** End-user id (config.telemetry.userId) stamped as `user.id` on root spans. */
|
|
9515
|
+
telemetryUserId;
|
|
9511
9516
|
_browserSession;
|
|
9512
9517
|
_browserMod;
|
|
9513
9518
|
parsedAgent;
|
|
@@ -10324,6 +10329,7 @@ var AgentHarness = class _AgentHarness {
|
|
|
10324
10329
|
await this.refreshMcpTools("initialize");
|
|
10325
10330
|
const telemetryEnabled = config?.telemetry?.enabled !== false;
|
|
10326
10331
|
const otlpConfig = telemetryEnabled ? normalizeOtlp(config?.telemetry?.otlp) : void 0;
|
|
10332
|
+
this.telemetryUserId = config?.telemetry?.userId;
|
|
10327
10333
|
if (otlpConfig) {
|
|
10328
10334
|
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.WARN);
|
|
10329
10335
|
const exporter = new OTLPTraceExporter({
|
|
@@ -10489,7 +10495,14 @@ var AgentHarness = class _AgentHarness {
|
|
|
10489
10495
|
kind: SpanKind.INTERNAL,
|
|
10490
10496
|
attributes: {
|
|
10491
10497
|
"gen_ai.operation.name": "invoke_agent",
|
|
10492
|
-
|
|
10498
|
+
// `session.id` / `user.id` are the attributes observability
|
|
10499
|
+
// backends (Latitude) key session grouping and user filtering on.
|
|
10500
|
+
// gen_ai.conversation.id is kept for the GenAI semantic convention.
|
|
10501
|
+
...input.conversationId ? {
|
|
10502
|
+
"gen_ai.conversation.id": input.conversationId,
|
|
10503
|
+
"session.id": input.conversationId
|
|
10504
|
+
} : {},
|
|
10505
|
+
...this.telemetryUserId ? { "user.id": this.telemetryUserId } : {},
|
|
10493
10506
|
...input.tenantId ? { "tenant.id": input.tenantId } : {}
|
|
10494
10507
|
}
|
|
10495
10508
|
});
|
package/package.json
CHANGED
package/src/config.ts
CHANGED
|
@@ -231,6 +231,11 @@ export interface PonchoConfig extends McpConfig {
|
|
|
231
231
|
url: string;
|
|
232
232
|
headers?: Record<string, string>;
|
|
233
233
|
};
|
|
234
|
+
/** End-user identifier (e.g. an email) stamped as `user.id` on every
|
|
235
|
+
* root trace span — observability backends (Latitude) group and
|
|
236
|
+
* filter traces by it. Per-harness, so a harness-per-user consumer
|
|
237
|
+
* sets it once at construction. */
|
|
238
|
+
userId?: string;
|
|
234
239
|
handler?: (event: unknown) => Promise<void> | void;
|
|
235
240
|
};
|
|
236
241
|
skills?: Record<string, Record<string, unknown>>;
|
package/src/harness.ts
CHANGED
|
@@ -881,6 +881,8 @@ export class AgentHarness {
|
|
|
881
881
|
private otlpSpanProcessor?: BatchSpanProcessor;
|
|
882
882
|
private otlpTracerProvider?: NodeTracerProvider;
|
|
883
883
|
private hasOtlpExporter = false;
|
|
884
|
+
/** End-user id (config.telemetry.userId) stamped as `user.id` on root spans. */
|
|
885
|
+
private telemetryUserId?: string;
|
|
884
886
|
private _browserSession?: unknown;
|
|
885
887
|
private _browserMod?: {
|
|
886
888
|
createBrowserTools: (getSession: () => unknown, getConversationId?: () => string) => ToolDefinition[];
|
|
@@ -1871,6 +1873,7 @@ export class AgentHarness {
|
|
|
1871
1873
|
|
|
1872
1874
|
const telemetryEnabled = config?.telemetry?.enabled !== false;
|
|
1873
1875
|
const otlpConfig = telemetryEnabled ? normalizeOtlp(config?.telemetry?.otlp) : undefined;
|
|
1876
|
+
this.telemetryUserId = config?.telemetry?.userId;
|
|
1874
1877
|
if (otlpConfig) {
|
|
1875
1878
|
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.WARN);
|
|
1876
1879
|
const exporter = new OTLPTraceExporter({
|
|
@@ -2057,7 +2060,16 @@ export class AgentHarness {
|
|
|
2057
2060
|
kind: SpanKind.INTERNAL,
|
|
2058
2061
|
attributes: {
|
|
2059
2062
|
"gen_ai.operation.name": "invoke_agent",
|
|
2060
|
-
|
|
2063
|
+
// `session.id` / `user.id` are the attributes observability
|
|
2064
|
+
// backends (Latitude) key session grouping and user filtering on.
|
|
2065
|
+
// gen_ai.conversation.id is kept for the GenAI semantic convention.
|
|
2066
|
+
...(input.conversationId
|
|
2067
|
+
? {
|
|
2068
|
+
"gen_ai.conversation.id": input.conversationId,
|
|
2069
|
+
"session.id": input.conversationId,
|
|
2070
|
+
}
|
|
2071
|
+
: {}),
|
|
2072
|
+
...(this.telemetryUserId ? { "user.id": this.telemetryUserId } : {}),
|
|
2061
2073
|
...(input.tenantId ? { "tenant.id": input.tenantId } : {}),
|
|
2062
2074
|
},
|
|
2063
2075
|
});
|
|
@@ -571,9 +571,21 @@ export abstract class SqlStorageEngine implements StorageEngine {
|
|
|
571
571
|
// Distinct placeholders for the two title occurrences: rewrite()
|
|
572
572
|
// converts $N → ? positionally for sqlite, so reusing $1 would
|
|
573
573
|
// desync the param array.
|
|
574
|
+
//
|
|
575
|
+
// Postgres: the JSONB column usually holds a JSON-encoded STRING
|
|
576
|
+
// scalar, not an object — update() binds `JSON.stringify(conv)` and
|
|
577
|
+
// the driver serializes that JS string as a JSON string. A bare
|
|
578
|
+
// jsonb_set on those rows throws `cannot set path in scalar`
|
|
579
|
+
// (observed in prod 2026-06-12: every rename 500'd). Branch on the
|
|
580
|
+
// stored shape and preserve each row's encoding: objects get a plain
|
|
581
|
+
// jsonb_set; string scalars get unwrapped (#>> '{}'), parsed, set,
|
|
582
|
+
// and re-serialized back to a string scalar.
|
|
574
583
|
const dataExpr = this.dialect.tag === "sqlite"
|
|
575
584
|
? `json_set(data, '$.title', $2)`
|
|
576
|
-
: `
|
|
585
|
+
: `CASE WHEN jsonb_typeof(data) = 'object'
|
|
586
|
+
THEN jsonb_set(data, '{title}', to_jsonb($2::text))
|
|
587
|
+
ELSE to_jsonb(jsonb_set((data #>> '{}')::jsonb, '{title}', to_jsonb($2::text))::text)
|
|
588
|
+
END`;
|
|
577
589
|
await this.executor.run(
|
|
578
590
|
rewrite(
|
|
579
591
|
`UPDATE conversations SET title = $1, data = ${dataExpr}, updated_at = $3 WHERE id = $4`,
|