@poncho-ai/harness 0.36.3 → 0.37.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/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +12 -0
- package/dist/index.js +60 -14
- package/package.json +1 -1
- package/src/storage/schema.ts +32 -0
- package/src/storage/sql-dialect.ts +30 -12
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @poncho-ai/harness@0.
|
|
2
|
+
> @poncho-ai/harness@0.37.0 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[
|
|
11
|
+
[32mESM[39m [1mdist/index.js [22m[32m389.90 KB[39m
|
|
12
12
|
[32mESM[39m [1mdist/isolate-TCWTUVG4.js [22m[32m47.34 KB[39m
|
|
13
|
-
[32mESM[39m ⚡️ Build success in
|
|
13
|
+
[32mESM[39m ⚡️ Build success in 206ms
|
|
14
14
|
[34mDTS[39m Build start
|
|
15
|
-
[32mDTS[39m ⚡️ Build success in
|
|
15
|
+
[32mDTS[39m ⚡️ Build success in 7213ms
|
|
16
16
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m56.62 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @poncho-ai/harness
|
|
2
2
|
|
|
3
|
+
## 0.37.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`86bc5ac`](https://github.com/cesr/poncho-ai/commit/86bc5ac2a73b80a286228cd9e3b663b50b3d82e7) Thanks [@cesr](https://github.com/cesr)! - perf: promote parentConversationId, pendingApprovals, and channelMeta to dedicated columns so list/summary queries no longer fetch the full data JSONB blob — dramatically reduces database egress
|
|
8
|
+
|
|
9
|
+
## 0.36.4
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`d7eb744`](https://github.com/cesr/poncho-ai/commit/d7eb744fb371727278bda6a349b9e117065549b4) Thanks [@cesr](https://github.com/cesr)! - fix: upsert conflict key matches PK (id only) — fixes ON CONFLICT error on conversation persist
|
|
14
|
+
|
|
3
15
|
## 0.36.3
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -3177,6 +3177,36 @@ var migrations = [
|
|
|
3177
3177
|
]
|
|
3178
3178
|
];
|
|
3179
3179
|
}
|
|
3180
|
+
},
|
|
3181
|
+
{
|
|
3182
|
+
version: 4,
|
|
3183
|
+
name: "promote_summary_fields_to_columns",
|
|
3184
|
+
up: (d) => {
|
|
3185
|
+
const jsonType = d === "sqlite" ? "TEXT" : "JSONB";
|
|
3186
|
+
return [
|
|
3187
|
+
`ALTER TABLE conversations ADD COLUMN parent_conversation_id TEXT`,
|
|
3188
|
+
`ALTER TABLE conversations ADD COLUMN has_pending_approvals INTEGER NOT NULL DEFAULT 0`,
|
|
3189
|
+
`ALTER TABLE conversations ADD COLUMN channel_meta ${jsonType}`,
|
|
3190
|
+
// Backfill from data blob
|
|
3191
|
+
...d === "sqlite" ? [
|
|
3192
|
+
`UPDATE conversations SET
|
|
3193
|
+
parent_conversation_id = json_extract(data, '$.parentConversationId'),
|
|
3194
|
+
has_pending_approvals = CASE
|
|
3195
|
+
WHEN json_array_length(COALESCE(json_extract(data, '$.pendingApprovals'), '[]')) > 0 THEN 1
|
|
3196
|
+
ELSE 0
|
|
3197
|
+
END,
|
|
3198
|
+
channel_meta = json_extract(data, '$.channelMeta')`
|
|
3199
|
+
] : [
|
|
3200
|
+
`UPDATE conversations SET
|
|
3201
|
+
parent_conversation_id = data->>'parentConversationId',
|
|
3202
|
+
has_pending_approvals = CASE
|
|
3203
|
+
WHEN jsonb_array_length(COALESCE(data->'pendingApprovals', '[]'::jsonb)) > 0 THEN 1
|
|
3204
|
+
ELSE 0
|
|
3205
|
+
END,
|
|
3206
|
+
channel_meta = data->'channelMeta'`
|
|
3207
|
+
]
|
|
3208
|
+
];
|
|
3209
|
+
}
|
|
3180
3210
|
}
|
|
3181
3211
|
];
|
|
3182
3212
|
|
|
@@ -3275,7 +3305,8 @@ var SqlStorageEngine = class {
|
|
|
3275
3305
|
const filterTenant = tenantId !== void 0;
|
|
3276
3306
|
const params = [this.agentId];
|
|
3277
3307
|
let sql = `SELECT id, title, updated_at, created_at, owner_id, tenant_id,
|
|
3278
|
-
message_count,
|
|
3308
|
+
message_count, parent_conversation_id,
|
|
3309
|
+
has_pending_approvals, channel_meta
|
|
3279
3310
|
FROM conversations WHERE agent_id = $1`;
|
|
3280
3311
|
if (filterTenant) {
|
|
3281
3312
|
sql += ` AND tenant_id = $2`;
|
|
@@ -3322,8 +3353,9 @@ var SqlStorageEngine = class {
|
|
|
3322
3353
|
const data = JSON.stringify(conv);
|
|
3323
3354
|
await this.executor.run(
|
|
3324
3355
|
rewrite(
|
|
3325
|
-
`INSERT INTO conversations (id, agent_id, tenant_id, owner_id, title, data, message_count, created_at, updated_at
|
|
3326
|
-
|
|
3356
|
+
`INSERT INTO conversations (id, agent_id, tenant_id, owner_id, title, data, message_count, created_at, updated_at,
|
|
3357
|
+
parent_conversation_id, has_pending_approvals, channel_meta)
|
|
3358
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`,
|
|
3327
3359
|
this.dialect
|
|
3328
3360
|
),
|
|
3329
3361
|
[
|
|
@@ -3335,7 +3367,10 @@ var SqlStorageEngine = class {
|
|
|
3335
3367
|
data,
|
|
3336
3368
|
0,
|
|
3337
3369
|
new Date(now2).toISOString(),
|
|
3338
|
-
new Date(now2).toISOString()
|
|
3370
|
+
new Date(now2).toISOString(),
|
|
3371
|
+
null,
|
|
3372
|
+
0,
|
|
3373
|
+
null
|
|
3339
3374
|
]
|
|
3340
3375
|
);
|
|
3341
3376
|
return conv;
|
|
@@ -3358,16 +3393,23 @@ var SqlStorageEngine = class {
|
|
|
3358
3393
|
const tid = normalizeTenant2(conversation.tenantId);
|
|
3359
3394
|
const now2 = new Date(conversation.updatedAt).toISOString();
|
|
3360
3395
|
const created = new Date(conversation.createdAt).toISOString();
|
|
3396
|
+
const parentConvId = conversation.parentConversationId ?? null;
|
|
3397
|
+
const hasPendingApprovals = (conversation.pendingApprovals?.length ?? 0) > 0 ? 1 : 0;
|
|
3398
|
+
const channelMetaJson = conversation.channelMeta ? JSON.stringify(conversation.channelMeta) : null;
|
|
3361
3399
|
await this.executor.run(
|
|
3362
3400
|
rewrite(
|
|
3363
3401
|
`INSERT INTO conversations (id, agent_id, tenant_id, owner_id, title, data, message_count, created_at, updated_at,
|
|
3364
|
-
tool_result_archive, harness_messages, continuation_messages
|
|
3365
|
-
|
|
3366
|
-
$
|
|
3402
|
+
tool_result_archive, harness_messages, continuation_messages,
|
|
3403
|
+
parent_conversation_id, has_pending_approvals, channel_meta)
|
|
3404
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
|
|
3405
|
+
${this.dialect.upsert(["id"])}
|
|
3367
3406
|
data = excluded.data, title = excluded.title, message_count = excluded.message_count,
|
|
3368
3407
|
updated_at = excluded.updated_at, tenant_id = excluded.tenant_id, owner_id = excluded.owner_id,
|
|
3369
3408
|
tool_result_archive = excluded.tool_result_archive, harness_messages = excluded.harness_messages,
|
|
3370
|
-
continuation_messages = excluded.continuation_messages
|
|
3409
|
+
continuation_messages = excluded.continuation_messages,
|
|
3410
|
+
parent_conversation_id = excluded.parent_conversation_id,
|
|
3411
|
+
has_pending_approvals = excluded.has_pending_approvals,
|
|
3412
|
+
channel_meta = excluded.channel_meta`,
|
|
3371
3413
|
this.dialect
|
|
3372
3414
|
),
|
|
3373
3415
|
[
|
|
@@ -3382,7 +3424,10 @@ var SqlStorageEngine = class {
|
|
|
3382
3424
|
now2,
|
|
3383
3425
|
archiveJson,
|
|
3384
3426
|
harnessJson,
|
|
3385
|
-
continuationJson
|
|
3427
|
+
continuationJson,
|
|
3428
|
+
parentConvId,
|
|
3429
|
+
hasPendingApprovals,
|
|
3430
|
+
channelMetaJson
|
|
3386
3431
|
]
|
|
3387
3432
|
);
|
|
3388
3433
|
},
|
|
@@ -3411,7 +3456,8 @@ var SqlStorageEngine = class {
|
|
|
3411
3456
|
const pattern = `%${query}%`;
|
|
3412
3457
|
const params = [this.agentId, pattern, pattern];
|
|
3413
3458
|
let sql = `SELECT id, title, updated_at, created_at, owner_id, tenant_id,
|
|
3414
|
-
message_count,
|
|
3459
|
+
message_count, parent_conversation_id,
|
|
3460
|
+
has_pending_approvals, channel_meta
|
|
3415
3461
|
FROM conversations
|
|
3416
3462
|
WHERE agent_id = $1 AND (title LIKE $2 OR data LIKE $3)`;
|
|
3417
3463
|
if (filterTenant) {
|
|
@@ -3841,8 +3887,8 @@ var SqlStorageEngine = class {
|
|
|
3841
3887
|
return data;
|
|
3842
3888
|
}
|
|
3843
3889
|
rowToSummary(row) {
|
|
3844
|
-
const data = this.parseConversation(row.data);
|
|
3845
3890
|
const tid = row.tenant_id;
|
|
3891
|
+
const rawChannelMeta = row.channel_meta;
|
|
3846
3892
|
return {
|
|
3847
3893
|
conversationId: row.id,
|
|
3848
3894
|
title: row.title,
|
|
@@ -3851,9 +3897,9 @@ var SqlStorageEngine = class {
|
|
|
3851
3897
|
ownerId: row.owner_id,
|
|
3852
3898
|
tenantId: tid === DEFAULT_TENANT2 ? null : tid,
|
|
3853
3899
|
messageCount: row.message_count,
|
|
3854
|
-
hasPendingApprovals:
|
|
3855
|
-
parentConversationId:
|
|
3856
|
-
channelMeta:
|
|
3900
|
+
hasPendingApprovals: !!row.has_pending_approvals,
|
|
3901
|
+
parentConversationId: row.parent_conversation_id || void 0,
|
|
3902
|
+
channelMeta: rawChannelMeta ? typeof rawChannelMeta === "string" ? JSON.parse(rawChannelMeta) : rawChannelMeta : void 0
|
|
3857
3903
|
};
|
|
3858
3904
|
}
|
|
3859
3905
|
rowToReminder(row) {
|
package/package.json
CHANGED
package/src/storage/schema.ts
CHANGED
|
@@ -142,4 +142,36 @@ export const migrations: Migration[] = [
|
|
|
142
142
|
];
|
|
143
143
|
},
|
|
144
144
|
},
|
|
145
|
+
{
|
|
146
|
+
version: 4,
|
|
147
|
+
name: "promote_summary_fields_to_columns",
|
|
148
|
+
up: (d) => {
|
|
149
|
+
const jsonType = d === "sqlite" ? "TEXT" : "JSONB";
|
|
150
|
+
return [
|
|
151
|
+
`ALTER TABLE conversations ADD COLUMN parent_conversation_id TEXT`,
|
|
152
|
+
`ALTER TABLE conversations ADD COLUMN has_pending_approvals INTEGER NOT NULL DEFAULT 0`,
|
|
153
|
+
`ALTER TABLE conversations ADD COLUMN channel_meta ${jsonType}`,
|
|
154
|
+
// Backfill from data blob
|
|
155
|
+
...(d === "sqlite"
|
|
156
|
+
? [
|
|
157
|
+
`UPDATE conversations SET
|
|
158
|
+
parent_conversation_id = json_extract(data, '$.parentConversationId'),
|
|
159
|
+
has_pending_approvals = CASE
|
|
160
|
+
WHEN json_array_length(COALESCE(json_extract(data, '$.pendingApprovals'), '[]')) > 0 THEN 1
|
|
161
|
+
ELSE 0
|
|
162
|
+
END,
|
|
163
|
+
channel_meta = json_extract(data, '$.channelMeta')`,
|
|
164
|
+
]
|
|
165
|
+
: [
|
|
166
|
+
`UPDATE conversations SET
|
|
167
|
+
parent_conversation_id = data->>'parentConversationId',
|
|
168
|
+
has_pending_approvals = CASE
|
|
169
|
+
WHEN jsonb_array_length(COALESCE(data->'pendingApprovals', '[]'::jsonb)) > 0 THEN 1
|
|
170
|
+
ELSE 0
|
|
171
|
+
END,
|
|
172
|
+
channel_meta = data->'channelMeta'`,
|
|
173
|
+
]),
|
|
174
|
+
];
|
|
175
|
+
},
|
|
176
|
+
},
|
|
145
177
|
];
|
|
@@ -189,7 +189,8 @@ export abstract class SqlStorageEngine implements StorageEngine {
|
|
|
189
189
|
const filterTenant = tenantId !== undefined;
|
|
190
190
|
const params: unknown[] = [this.agentId];
|
|
191
191
|
let sql = `SELECT id, title, updated_at, created_at, owner_id, tenant_id,
|
|
192
|
-
message_count,
|
|
192
|
+
message_count, parent_conversation_id,
|
|
193
|
+
has_pending_approvals, channel_meta
|
|
193
194
|
FROM conversations WHERE agent_id = $1`;
|
|
194
195
|
if (filterTenant) {
|
|
195
196
|
sql += ` AND tenant_id = $2`;
|
|
@@ -258,8 +259,9 @@ export abstract class SqlStorageEngine implements StorageEngine {
|
|
|
258
259
|
const data = JSON.stringify(conv);
|
|
259
260
|
await this.executor.run(
|
|
260
261
|
rewrite(
|
|
261
|
-
`INSERT INTO conversations (id, agent_id, tenant_id, owner_id, title, data, message_count, created_at, updated_at
|
|
262
|
-
|
|
262
|
+
`INSERT INTO conversations (id, agent_id, tenant_id, owner_id, title, data, message_count, created_at, updated_at,
|
|
263
|
+
parent_conversation_id, has_pending_approvals, channel_meta)
|
|
264
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`,
|
|
263
265
|
this.dialect,
|
|
264
266
|
),
|
|
265
267
|
[
|
|
@@ -272,6 +274,9 @@ export abstract class SqlStorageEngine implements StorageEngine {
|
|
|
272
274
|
0,
|
|
273
275
|
new Date(now).toISOString(),
|
|
274
276
|
new Date(now).toISOString(),
|
|
277
|
+
null,
|
|
278
|
+
0,
|
|
279
|
+
null,
|
|
275
280
|
],
|
|
276
281
|
);
|
|
277
282
|
return conv;
|
|
@@ -296,16 +301,23 @@ export abstract class SqlStorageEngine implements StorageEngine {
|
|
|
296
301
|
const tid = normalizeTenant(conversation.tenantId);
|
|
297
302
|
const now = new Date(conversation.updatedAt).toISOString();
|
|
298
303
|
const created = new Date(conversation.createdAt).toISOString();
|
|
304
|
+
const parentConvId = conversation.parentConversationId ?? null;
|
|
305
|
+
const hasPendingApprovals = (conversation.pendingApprovals?.length ?? 0) > 0 ? 1 : 0;
|
|
306
|
+
const channelMetaJson = conversation.channelMeta ? JSON.stringify(conversation.channelMeta) : null;
|
|
299
307
|
await this.executor.run(
|
|
300
308
|
rewrite(
|
|
301
309
|
`INSERT INTO conversations (id, agent_id, tenant_id, owner_id, title, data, message_count, created_at, updated_at,
|
|
302
|
-
tool_result_archive, harness_messages, continuation_messages
|
|
303
|
-
|
|
304
|
-
$
|
|
310
|
+
tool_result_archive, harness_messages, continuation_messages,
|
|
311
|
+
parent_conversation_id, has_pending_approvals, channel_meta)
|
|
312
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
|
|
313
|
+
${this.dialect.upsert(["id"])}
|
|
305
314
|
data = excluded.data, title = excluded.title, message_count = excluded.message_count,
|
|
306
315
|
updated_at = excluded.updated_at, tenant_id = excluded.tenant_id, owner_id = excluded.owner_id,
|
|
307
316
|
tool_result_archive = excluded.tool_result_archive, harness_messages = excluded.harness_messages,
|
|
308
|
-
continuation_messages = excluded.continuation_messages
|
|
317
|
+
continuation_messages = excluded.continuation_messages,
|
|
318
|
+
parent_conversation_id = excluded.parent_conversation_id,
|
|
319
|
+
has_pending_approvals = excluded.has_pending_approvals,
|
|
320
|
+
channel_meta = excluded.channel_meta`,
|
|
309
321
|
this.dialect,
|
|
310
322
|
),
|
|
311
323
|
[
|
|
@@ -321,6 +333,9 @@ export abstract class SqlStorageEngine implements StorageEngine {
|
|
|
321
333
|
archiveJson,
|
|
322
334
|
harnessJson,
|
|
323
335
|
continuationJson,
|
|
336
|
+
parentConvId,
|
|
337
|
+
hasPendingApprovals,
|
|
338
|
+
channelMetaJson,
|
|
324
339
|
],
|
|
325
340
|
);
|
|
326
341
|
},
|
|
@@ -359,7 +374,8 @@ export abstract class SqlStorageEngine implements StorageEngine {
|
|
|
359
374
|
// SQLite uses positional ? so we can't reuse $2, need separate params
|
|
360
375
|
const params: unknown[] = [this.agentId, pattern, pattern];
|
|
361
376
|
let sql = `SELECT id, title, updated_at, created_at, owner_id, tenant_id,
|
|
362
|
-
message_count,
|
|
377
|
+
message_count, parent_conversation_id,
|
|
378
|
+
has_pending_approvals, channel_meta
|
|
363
379
|
FROM conversations
|
|
364
380
|
WHERE agent_id = $1 AND (title LIKE $2 OR data LIKE $3)`;
|
|
365
381
|
if (filterTenant) {
|
|
@@ -882,8 +898,8 @@ export abstract class SqlStorageEngine implements StorageEngine {
|
|
|
882
898
|
}
|
|
883
899
|
|
|
884
900
|
private rowToSummary(row: QueryRow): ConversationSummary {
|
|
885
|
-
const data = this.parseConversation(row.data);
|
|
886
901
|
const tid = row.tenant_id as string;
|
|
902
|
+
const rawChannelMeta = row.channel_meta;
|
|
887
903
|
return {
|
|
888
904
|
conversationId: row.id as string,
|
|
889
905
|
title: row.title as string,
|
|
@@ -892,9 +908,11 @@ export abstract class SqlStorageEngine implements StorageEngine {
|
|
|
892
908
|
ownerId: row.owner_id as string,
|
|
893
909
|
tenantId: tid === DEFAULT_TENANT ? null : tid,
|
|
894
910
|
messageCount: row.message_count as number,
|
|
895
|
-
hasPendingApprovals: (
|
|
896
|
-
parentConversationId:
|
|
897
|
-
channelMeta:
|
|
911
|
+
hasPendingApprovals: !!(row.has_pending_approvals),
|
|
912
|
+
parentConversationId: (row.parent_conversation_id as string) || undefined,
|
|
913
|
+
channelMeta: rawChannelMeta
|
|
914
|
+
? (typeof rawChannelMeta === "string" ? JSON.parse(rawChannelMeta) : rawChannelMeta)
|
|
915
|
+
: undefined,
|
|
898
916
|
};
|
|
899
917
|
}
|
|
900
918
|
|