@poncho-ai/harness 0.55.0 → 0.57.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 +5 -5
- package/CHANGELOG.md +38 -0
- package/dist/index.d.ts +210 -2
- package/dist/index.js +569 -19
- package/package.json +1 -1
- package/src/index.ts +18 -0
- package/src/orchestrator/entries-dual-write.ts +265 -0
- package/src/orchestrator/index.ts +7 -0
- package/src/orchestrator/orchestrator.ts +179 -13
- package/src/orchestrator/run-conversation-turn.ts +108 -0
- package/src/state.ts +56 -0
- package/src/storage/engine.ts +18 -0
- package/src/storage/entries.ts +13 -0
- package/src/storage/memory-engine.ts +40 -0
- package/src/storage/schema.ts +30 -0
- package/src/storage/sql-dialect.ts +112 -0
- package/src/storage/store-adapters.ts +8 -0
- package/test/entries-dual-write.test.ts +172 -0
- package/test/entries-store.test.ts +165 -0
package/dist/index.js
CHANGED
|
@@ -2789,6 +2789,8 @@ var InMemoryEngine = class {
|
|
|
2789
2789
|
agentId;
|
|
2790
2790
|
// Conversation data
|
|
2791
2791
|
convs = /* @__PURE__ */ new Map();
|
|
2792
|
+
// Append-only conversation entries (Phase 3 substrate)
|
|
2793
|
+
entries = /* @__PURE__ */ new Map();
|
|
2792
2794
|
// Memory data
|
|
2793
2795
|
mem = /* @__PURE__ */ new Map();
|
|
2794
2796
|
// Todos data
|
|
@@ -2918,6 +2920,30 @@ var InMemoryEngine = class {
|
|
|
2918
2920
|
}
|
|
2919
2921
|
results.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
2920
2922
|
return results;
|
|
2923
|
+
},
|
|
2924
|
+
appendEntries: async (conversationId, _agentId, _tenantId, entries) => {
|
|
2925
|
+
const list = this.entries.get(conversationId) ?? [];
|
|
2926
|
+
let nextSeq = list.reduce((max, e) => e.seq > max ? e.seq : max, 0) + 1;
|
|
2927
|
+
const now2 = Date.now();
|
|
2928
|
+
const stored = entries.map(
|
|
2929
|
+
(e) => ({ ...e, seq: nextSeq++, createdAt: now2 })
|
|
2930
|
+
);
|
|
2931
|
+
this.entries.set(conversationId, [...list, ...stored]);
|
|
2932
|
+
return stored;
|
|
2933
|
+
},
|
|
2934
|
+
readEntries: async (conversationId, opts) => {
|
|
2935
|
+
let list = (this.entries.get(conversationId) ?? []).slice().sort((a, b) => a.seq - b.seq);
|
|
2936
|
+
if (opts?.types && opts.types.length > 0) {
|
|
2937
|
+
const allowed = new Set(opts.types);
|
|
2938
|
+
list = list.filter((e) => allowed.has(e.type));
|
|
2939
|
+
}
|
|
2940
|
+
if (typeof opts?.afterSeq === "number") {
|
|
2941
|
+
list = list.filter((e) => e.seq > opts.afterSeq);
|
|
2942
|
+
}
|
|
2943
|
+
if (typeof opts?.limit === "number") {
|
|
2944
|
+
list = list.slice(0, opts.limit);
|
|
2945
|
+
}
|
|
2946
|
+
return list;
|
|
2921
2947
|
}
|
|
2922
2948
|
};
|
|
2923
2949
|
// -----------------------------------------------------------------------
|
|
@@ -3457,6 +3483,36 @@ var migrations = [
|
|
|
3457
3483
|
`ALTER TABLE reminders ALTER COLUMN scheduled_at TYPE BIGINT USING scheduled_at::bigint`
|
|
3458
3484
|
];
|
|
3459
3485
|
}
|
|
3486
|
+
},
|
|
3487
|
+
{
|
|
3488
|
+
version: 8,
|
|
3489
|
+
name: "conversation_entries",
|
|
3490
|
+
// Append-only conversation log (Phase 3 substrate). Additive: no
|
|
3491
|
+
// existing table or behavior changes. `seq` is a per-conversation
|
|
3492
|
+
// monotonic order assigned by the application (NOT an autoincrement
|
|
3493
|
+
// serial), so the same seq space restarts at 1 for every conversation.
|
|
3494
|
+
// The UNIQUE (conversation_id, seq) constraint backstops the
|
|
3495
|
+
// app-assigned ordering against concurrent writers.
|
|
3496
|
+
up: (d) => {
|
|
3497
|
+
const jsonType = d === "sqlite" ? "TEXT" : "JSONB";
|
|
3498
|
+
const tsDefault = d === "sqlite" ? "datetime('now')" : "NOW()";
|
|
3499
|
+
const autoTs = `DEFAULT (${tsDefault})`;
|
|
3500
|
+
return [
|
|
3501
|
+
`CREATE TABLE IF NOT EXISTS conversation_entries (
|
|
3502
|
+
seq INTEGER NOT NULL,
|
|
3503
|
+
id TEXT NOT NULL UNIQUE,
|
|
3504
|
+
agent_id TEXT NOT NULL,
|
|
3505
|
+
tenant_id TEXT NOT NULL DEFAULT '__default__',
|
|
3506
|
+
conversation_id TEXT NOT NULL,
|
|
3507
|
+
type TEXT NOT NULL,
|
|
3508
|
+
payload ${jsonType} NOT NULL,
|
|
3509
|
+
created_at TIMESTAMP ${autoTs},
|
|
3510
|
+
UNIQUE (conversation_id, seq)
|
|
3511
|
+
)`,
|
|
3512
|
+
`CREATE INDEX IF NOT EXISTS idx_conversation_entries_seq
|
|
3513
|
+
ON conversation_entries (conversation_id, seq)`
|
|
3514
|
+
];
|
|
3515
|
+
}
|
|
3460
3516
|
}
|
|
3461
3517
|
];
|
|
3462
3518
|
|
|
@@ -3880,6 +3936,87 @@ var SqlStorageEngine = class {
|
|
|
3880
3936
|
parentConversationId
|
|
3881
3937
|
]);
|
|
3882
3938
|
return rows.map((r) => this.rowToSummary(r));
|
|
3939
|
+
},
|
|
3940
|
+
appendEntries: async (conversationId, agentId, tenantId, entries) => {
|
|
3941
|
+
if (entries.length === 0) return [];
|
|
3942
|
+
const tid = normalizeTenant2(tenantId);
|
|
3943
|
+
const maxAttempts = 3;
|
|
3944
|
+
let lastErr;
|
|
3945
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
3946
|
+
const stored = [];
|
|
3947
|
+
try {
|
|
3948
|
+
await this.executor.transaction(async () => {
|
|
3949
|
+
stored.length = 0;
|
|
3950
|
+
const row = await this.executor.get(
|
|
3951
|
+
rewrite(
|
|
3952
|
+
"SELECT MAX(seq) AS max_seq FROM conversation_entries WHERE conversation_id = $1",
|
|
3953
|
+
this.dialect
|
|
3954
|
+
),
|
|
3955
|
+
[conversationId]
|
|
3956
|
+
);
|
|
3957
|
+
let nextSeq = Number(row?.max_seq ?? 0) + 1;
|
|
3958
|
+
const now2 = Date.now();
|
|
3959
|
+
for (const entry of entries) {
|
|
3960
|
+
const seq = nextSeq++;
|
|
3961
|
+
const createdAt = now2;
|
|
3962
|
+
const payload = JSON.stringify(entry);
|
|
3963
|
+
await this.executor.run(
|
|
3964
|
+
rewrite(
|
|
3965
|
+
`INSERT INTO conversation_entries
|
|
3966
|
+
(seq, id, agent_id, tenant_id, conversation_id, type, payload, created_at)
|
|
3967
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
|
|
3968
|
+
this.dialect
|
|
3969
|
+
),
|
|
3970
|
+
[
|
|
3971
|
+
seq,
|
|
3972
|
+
entry.id,
|
|
3973
|
+
agentId,
|
|
3974
|
+
tid,
|
|
3975
|
+
conversationId,
|
|
3976
|
+
entry.type,
|
|
3977
|
+
payload,
|
|
3978
|
+
new Date(createdAt).toISOString()
|
|
3979
|
+
]
|
|
3980
|
+
);
|
|
3981
|
+
stored.push({ ...entry, seq, createdAt });
|
|
3982
|
+
}
|
|
3983
|
+
});
|
|
3984
|
+
return stored;
|
|
3985
|
+
} catch (err) {
|
|
3986
|
+
lastErr = err;
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
throw lastErr;
|
|
3990
|
+
},
|
|
3991
|
+
readEntries: async (conversationId, opts) => {
|
|
3992
|
+
const params = [conversationId];
|
|
3993
|
+
let sql = "SELECT seq, id, payload, created_at FROM conversation_entries WHERE conversation_id = $1";
|
|
3994
|
+
if (opts?.types && opts.types.length > 0) {
|
|
3995
|
+
const placeholders = opts.types.map(
|
|
3996
|
+
(_t, i) => `$${params.length + 1 + i}`
|
|
3997
|
+
);
|
|
3998
|
+
sql += ` AND type IN (${placeholders.join(", ")})`;
|
|
3999
|
+
params.push(...opts.types);
|
|
4000
|
+
}
|
|
4001
|
+
if (typeof opts?.afterSeq === "number") {
|
|
4002
|
+
sql += ` AND seq > $${params.length + 1}`;
|
|
4003
|
+
params.push(opts.afterSeq);
|
|
4004
|
+
}
|
|
4005
|
+
sql += " ORDER BY seq ASC";
|
|
4006
|
+
if (typeof opts?.limit === "number") {
|
|
4007
|
+
sql += ` LIMIT $${params.length + 1}`;
|
|
4008
|
+
params.push(opts.limit);
|
|
4009
|
+
}
|
|
4010
|
+
const rows = await this.executor.all(rewrite(sql, this.dialect), params);
|
|
4011
|
+
return rows.map((r) => {
|
|
4012
|
+
const parsed = typeof r.payload === "string" ? JSON.parse(r.payload) : r.payload;
|
|
4013
|
+
return {
|
|
4014
|
+
...parsed,
|
|
4015
|
+
id: r.id,
|
|
4016
|
+
seq: Number(r.seq),
|
|
4017
|
+
createdAt: new Date(r.created_at).getTime()
|
|
4018
|
+
};
|
|
4019
|
+
});
|
|
3883
4020
|
}
|
|
3884
4021
|
};
|
|
3885
4022
|
// -----------------------------------------------------------------------
|
|
@@ -4712,7 +4849,9 @@ function createConversationStoreFromEngine(engine) {
|
|
|
4712
4849
|
delete: (conversationId) => engine.conversations.delete(conversationId),
|
|
4713
4850
|
appendSubagentResult: (conversationId, result) => engine.conversations.appendSubagentResult(conversationId, result),
|
|
4714
4851
|
clearCallbackLock: (conversationId) => engine.conversations.clearCallbackLock(conversationId),
|
|
4715
|
-
listThreads: (parentConversationId) => engine.conversations.listThreads(parentConversationId)
|
|
4852
|
+
listThreads: (parentConversationId) => engine.conversations.listThreads(parentConversationId),
|
|
4853
|
+
appendEntries: (conversationId, agentId, tenantId, entries) => engine.conversations.appendEntries(conversationId, agentId, tenantId, entries),
|
|
4854
|
+
readEntries: (conversationId, opts) => engine.conversations.readEntries(conversationId, opts)
|
|
4716
4855
|
};
|
|
4717
4856
|
}
|
|
4718
4857
|
function createMemoryStoreFromEngine(engine, tenantId) {
|
|
@@ -11973,6 +12112,7 @@ var InMemoryStateStore = class {
|
|
|
11973
12112
|
};
|
|
11974
12113
|
var InMemoryConversationStore = class {
|
|
11975
12114
|
conversations = /* @__PURE__ */ new Map();
|
|
12115
|
+
entries = /* @__PURE__ */ new Map();
|
|
11976
12116
|
ttlMs;
|
|
11977
12117
|
constructor(ttlSeconds) {
|
|
11978
12118
|
this.ttlMs = typeof ttlSeconds === "number" ? ttlSeconds * 1e3 : void 0;
|
|
@@ -12102,6 +12242,30 @@ var InMemoryConversationStore = class {
|
|
|
12102
12242
|
channelMeta: c.channelMeta
|
|
12103
12243
|
}));
|
|
12104
12244
|
}
|
|
12245
|
+
async appendEntries(conversationId, _agentId, _tenantId, entries) {
|
|
12246
|
+
const list = this.entries.get(conversationId) ?? [];
|
|
12247
|
+
let nextSeq = list.reduce((max, e) => e.seq > max ? e.seq : max, 0) + 1;
|
|
12248
|
+
const now2 = Date.now();
|
|
12249
|
+
const stored = entries.map(
|
|
12250
|
+
(e) => ({ ...e, seq: nextSeq++, createdAt: now2 })
|
|
12251
|
+
);
|
|
12252
|
+
this.entries.set(conversationId, [...list, ...stored]);
|
|
12253
|
+
return stored;
|
|
12254
|
+
}
|
|
12255
|
+
async readEntries(conversationId, opts) {
|
|
12256
|
+
let list = (this.entries.get(conversationId) ?? []).slice().sort((a, b) => a.seq - b.seq);
|
|
12257
|
+
if (opts?.types && opts.types.length > 0) {
|
|
12258
|
+
const allowed = new Set(opts.types);
|
|
12259
|
+
list = list.filter((e) => allowed.has(e.type));
|
|
12260
|
+
}
|
|
12261
|
+
if (typeof opts?.afterSeq === "number") {
|
|
12262
|
+
list = list.filter((e) => e.seq > opts.afterSeq);
|
|
12263
|
+
}
|
|
12264
|
+
if (typeof opts?.limit === "number") {
|
|
12265
|
+
list = list.slice(0, opts.limit);
|
|
12266
|
+
}
|
|
12267
|
+
return list;
|
|
12268
|
+
}
|
|
12105
12269
|
};
|
|
12106
12270
|
var createStateStore = (config, _options) => {
|
|
12107
12271
|
const ttl = config?.ttl;
|
|
@@ -12112,6 +12276,66 @@ var createConversationStore = (config, _options) => {
|
|
|
12112
12276
|
return new InMemoryConversationStore(ttl);
|
|
12113
12277
|
};
|
|
12114
12278
|
|
|
12279
|
+
// src/storage/entries.ts
|
|
12280
|
+
function buildLlmContext(entries) {
|
|
12281
|
+
let latestCompaction;
|
|
12282
|
+
for (const e of entries) {
|
|
12283
|
+
if (e.type === "compaction" && (!latestCompaction || e.seq > latestCompaction.seq)) {
|
|
12284
|
+
latestCompaction = e;
|
|
12285
|
+
}
|
|
12286
|
+
}
|
|
12287
|
+
const harnessMsgs = entries.filter(
|
|
12288
|
+
(e) => e.type === "harness_message"
|
|
12289
|
+
);
|
|
12290
|
+
if (latestCompaction) {
|
|
12291
|
+
const kept = harnessMsgs.filter((e) => e.seq >= latestCompaction.firstKeptSeq).map((e) => e.message);
|
|
12292
|
+
return [latestCompaction.summaryMessage, ...kept];
|
|
12293
|
+
}
|
|
12294
|
+
return harnessMsgs.map((e) => e.message);
|
|
12295
|
+
}
|
|
12296
|
+
function buildDisplaySnapshot(entries, tailN) {
|
|
12297
|
+
const amendmentsByTarget = /* @__PURE__ */ new Map();
|
|
12298
|
+
for (const e of entries) {
|
|
12299
|
+
if (e.type === "assistant_amendment") {
|
|
12300
|
+
const list = amendmentsByTarget.get(e.targetEntryId) ?? [];
|
|
12301
|
+
list.push(e);
|
|
12302
|
+
amendmentsByTarget.set(e.targetEntryId, list);
|
|
12303
|
+
}
|
|
12304
|
+
}
|
|
12305
|
+
const built = [];
|
|
12306
|
+
for (const e of entries) {
|
|
12307
|
+
if (e.type === "user_message") {
|
|
12308
|
+
if (e.hidden) continue;
|
|
12309
|
+
built.push({ seq: e.seq, message: e.message });
|
|
12310
|
+
} else if (e.type === "assistant_message") {
|
|
12311
|
+
let content = typeof e.message.content === "string" ? e.message.content : "";
|
|
12312
|
+
const amendments = amendmentsByTarget.get(e.id);
|
|
12313
|
+
if (amendments) {
|
|
12314
|
+
for (const a of amendments.sort((x, y) => x.seq - y.seq)) {
|
|
12315
|
+
if (a.appendText) content += a.appendText;
|
|
12316
|
+
}
|
|
12317
|
+
}
|
|
12318
|
+
built.push({ seq: e.seq, message: { ...e.message, content } });
|
|
12319
|
+
}
|
|
12320
|
+
}
|
|
12321
|
+
const total = built.length;
|
|
12322
|
+
const tail = tailN >= total ? built : built.slice(total - tailN);
|
|
12323
|
+
return {
|
|
12324
|
+
messages: tail.map((b) => b.message),
|
|
12325
|
+
totalMessages: total,
|
|
12326
|
+
headSeq: tail.length > 0 ? tail[0].seq : null
|
|
12327
|
+
};
|
|
12328
|
+
}
|
|
12329
|
+
function getPendingSubagentResults(entries) {
|
|
12330
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
12331
|
+
for (const e of entries) {
|
|
12332
|
+
if (e.type === "callback_started") {
|
|
12333
|
+
for (const s of e.consumedSeqs) consumed.add(s);
|
|
12334
|
+
}
|
|
12335
|
+
}
|
|
12336
|
+
return entries.filter((e) => e.type === "subagent_result").filter((e) => !consumed.has(e.seq)).map((e) => e.result);
|
|
12337
|
+
}
|
|
12338
|
+
|
|
12115
12339
|
// src/tenant-token.ts
|
|
12116
12340
|
import { jwtVerify } from "jose";
|
|
12117
12341
|
async function verifyTenantToken(signingKey, token) {
|
|
@@ -12444,9 +12668,143 @@ var CALLBACK_LOCK_STALE_MS = 5 * 60 * 1e3;
|
|
|
12444
12668
|
var STALE_SUBAGENT_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
12445
12669
|
|
|
12446
12670
|
// src/orchestrator/orchestrator.ts
|
|
12671
|
+
import { createLogger as createLogger7, getTextContent as getTextContent4 } from "@poncho-ai/sdk";
|
|
12672
|
+
|
|
12673
|
+
// src/orchestrator/entries-dual-write.ts
|
|
12674
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
12447
12675
|
import { getTextContent as getTextContent3 } from "@poncho-ai/sdk";
|
|
12676
|
+
var entriesParityEnabled = () => process.env.PONCHO_VERIFY_ENTRIES === "1";
|
|
12677
|
+
var appendEntriesSafe = async (store, conversation, entries, log2) => {
|
|
12678
|
+
if (entries.length === 0) return [];
|
|
12679
|
+
try {
|
|
12680
|
+
const withIds = entries.map(
|
|
12681
|
+
(e) => ({ id: randomUUID6(), ...e })
|
|
12682
|
+
);
|
|
12683
|
+
return await store.appendEntries(
|
|
12684
|
+
conversation.conversationId,
|
|
12685
|
+
conversation.ownerId,
|
|
12686
|
+
conversation.tenantId ?? null,
|
|
12687
|
+
withIds
|
|
12688
|
+
);
|
|
12689
|
+
} catch (err) {
|
|
12690
|
+
log2.error(
|
|
12691
|
+
`[entries-dual-write] append failed for ${conversation.conversationId}: ${err instanceof Error ? err.message : String(err)}`
|
|
12692
|
+
);
|
|
12693
|
+
return [];
|
|
12694
|
+
}
|
|
12695
|
+
};
|
|
12696
|
+
var userMessageEntry = (message, turnId, opts) => ({
|
|
12697
|
+
type: "user_message",
|
|
12698
|
+
message,
|
|
12699
|
+
turnId,
|
|
12700
|
+
...opts?.hidden ? { hidden: true } : {}
|
|
12701
|
+
});
|
|
12702
|
+
var assistantMessageEntry = (message, turnId, runId) => ({
|
|
12703
|
+
type: "assistant_message",
|
|
12704
|
+
message,
|
|
12705
|
+
turnId,
|
|
12706
|
+
runId
|
|
12707
|
+
});
|
|
12708
|
+
var harnessMessageEntries = (messages, turnId) => messages.map((message) => ({ type: "harness_message", message, turnId }));
|
|
12709
|
+
var compactionEntry = (summaryMessage, firstKeptSeq, opts) => ({
|
|
12710
|
+
type: "compaction",
|
|
12711
|
+
summaryMessage,
|
|
12712
|
+
firstKeptSeq,
|
|
12713
|
+
...opts?.tokensBefore !== void 0 ? { tokensBefore: opts.tokensBefore } : {},
|
|
12714
|
+
...opts?.tokensAfter !== void 0 ? { tokensAfter: opts.tokensAfter } : {}
|
|
12715
|
+
});
|
|
12716
|
+
var subagentResultEntry = (result) => ({ type: "subagent_result", result });
|
|
12717
|
+
var callbackStartedEntry = (consumedSeqs) => ({
|
|
12718
|
+
type: "callback_started",
|
|
12719
|
+
consumedSeqs
|
|
12720
|
+
});
|
|
12721
|
+
var assistantAmendmentEntry = (targetEntryId, appendText) => ({
|
|
12722
|
+
type: "assistant_amendment",
|
|
12723
|
+
targetEntryId,
|
|
12724
|
+
...appendText ? { appendText } : {}
|
|
12725
|
+
});
|
|
12726
|
+
var newHarnessMessagesThisTurn = (prev, next) => {
|
|
12727
|
+
const prevArr = prev ?? [];
|
|
12728
|
+
const nextArr = next ?? [];
|
|
12729
|
+
if (nextArr.length === 0) return { messages: [], approximate: false };
|
|
12730
|
+
if (prevArr.length === 0) return { messages: nextArr, approximate: false };
|
|
12731
|
+
if (nextArr.length >= prevArr.length) {
|
|
12732
|
+
return { messages: nextArr.slice(prevArr.length), approximate: false };
|
|
12733
|
+
}
|
|
12734
|
+
return { messages: nextArr, approximate: true };
|
|
12735
|
+
};
|
|
12736
|
+
var projectText = (m) => {
|
|
12737
|
+
const role = m.role;
|
|
12738
|
+
const text = getTextContent3(m).replace(/\s+/g, " ").trim();
|
|
12739
|
+
return `${role}:${text}`;
|
|
12740
|
+
};
|
|
12741
|
+
var projectAll = (msgs) => msgs.map(projectText);
|
|
12742
|
+
var countMismatch = (label, a, b) => a === b ? null : `${label} length ${a} (entries) vs ${b} (blob)`;
|
|
12743
|
+
var verifyEntriesParity = async (store, conversationId, blob, log2) => {
|
|
12744
|
+
if (!entriesParityEnabled()) return;
|
|
12745
|
+
try {
|
|
12746
|
+
const entries = await store.readEntries(conversationId);
|
|
12747
|
+
const mismatches = [];
|
|
12748
|
+
if (blob.harnessMessages) {
|
|
12749
|
+
const llm = buildLlmContext(entries);
|
|
12750
|
+
const lenMismatch = countMismatch(
|
|
12751
|
+
"llmContext",
|
|
12752
|
+
llm.length,
|
|
12753
|
+
blob.harnessMessages.length
|
|
12754
|
+
);
|
|
12755
|
+
if (lenMismatch) mismatches.push(lenMismatch);
|
|
12756
|
+
const entriesProj = projectAll(llm);
|
|
12757
|
+
const blobProj = projectAll(blob.harnessMessages);
|
|
12758
|
+
const tail = Math.min(entriesProj.length, blobProj.length, 5);
|
|
12759
|
+
for (let i = 1; i <= tail; i++) {
|
|
12760
|
+
const ep = entriesProj[entriesProj.length - i];
|
|
12761
|
+
const bp = blobProj[blobProj.length - i];
|
|
12762
|
+
if (ep !== bp) {
|
|
12763
|
+
mismatches.push(
|
|
12764
|
+
`llmContext tail[-${i}] differs: entries=${JSON.stringify(ep).slice(0, 120)} blob=${JSON.stringify(bp).slice(0, 120)}`
|
|
12765
|
+
);
|
|
12766
|
+
}
|
|
12767
|
+
}
|
|
12768
|
+
}
|
|
12769
|
+
if (blob.displayMessages) {
|
|
12770
|
+
const snap = buildDisplaySnapshot(entries, Number.MAX_SAFE_INTEGER);
|
|
12771
|
+
const lenMismatch = countMismatch(
|
|
12772
|
+
"display",
|
|
12773
|
+
snap.totalMessages,
|
|
12774
|
+
blob.displayMessages.length
|
|
12775
|
+
);
|
|
12776
|
+
if (lenMismatch) mismatches.push(lenMismatch);
|
|
12777
|
+
const entriesProj = projectAll(snap.messages);
|
|
12778
|
+
const blobProj = projectAll(blob.displayMessages);
|
|
12779
|
+
const tail = Math.min(entriesProj.length, blobProj.length, 5);
|
|
12780
|
+
for (let i = 1; i <= tail; i++) {
|
|
12781
|
+
const ep = entriesProj[entriesProj.length - i];
|
|
12782
|
+
const bp = blobProj[blobProj.length - i];
|
|
12783
|
+
if (ep !== bp) {
|
|
12784
|
+
mismatches.push(
|
|
12785
|
+
`display tail[-${i}] differs: entries=${JSON.stringify(ep).slice(0, 120)} blob=${JSON.stringify(bp).slice(0, 120)}`
|
|
12786
|
+
);
|
|
12787
|
+
}
|
|
12788
|
+
}
|
|
12789
|
+
}
|
|
12790
|
+
if (mismatches.length > 0) {
|
|
12791
|
+
log2.warn(
|
|
12792
|
+
`[entries-parity] ${conversationId} MISMATCH (${mismatches.length}): ${mismatches.join(" | ")}`
|
|
12793
|
+
);
|
|
12794
|
+
} else {
|
|
12795
|
+
log2.info(`[entries-parity] ${conversationId} OK`);
|
|
12796
|
+
}
|
|
12797
|
+
} catch (err) {
|
|
12798
|
+
log2.error(
|
|
12799
|
+
`[entries-parity] ${conversationId} checker threw (ignored): ${err instanceof Error ? err.message : String(err)}`
|
|
12800
|
+
);
|
|
12801
|
+
}
|
|
12802
|
+
};
|
|
12803
|
+
|
|
12804
|
+
// src/orchestrator/orchestrator.ts
|
|
12805
|
+
var dualWriteLog = createLogger7("orchestrator:entries");
|
|
12448
12806
|
var assistantMessageText = (message) => {
|
|
12449
|
-
const raw =
|
|
12807
|
+
const raw = getTextContent4(message).trim();
|
|
12450
12808
|
if (raw.startsWith("{") && raw.includes('"tool_calls"')) {
|
|
12451
12809
|
try {
|
|
12452
12810
|
const parsed = JSON.parse(raw);
|
|
@@ -12755,6 +13113,8 @@ var AgentOrchestrator = class {
|
|
|
12755
13113
|
if (!checkpointedRun) {
|
|
12756
13114
|
const conv = await this.conversationStore.get(conversationId);
|
|
12757
13115
|
if (conv) {
|
|
13116
|
+
let amendmentText;
|
|
13117
|
+
let pushedAssistant;
|
|
12758
13118
|
const hasAssistantContent = draft.assistantResponse.length > 0 || draft.toolTimeline.length > 0 || draft.sections.length > 0;
|
|
12759
13119
|
if (hasAssistantContent) {
|
|
12760
13120
|
const prevMessages = conv.messages;
|
|
@@ -12782,15 +13142,14 @@ var AgentOrchestrator = class {
|
|
|
12782
13142
|
}
|
|
12783
13143
|
}
|
|
12784
13144
|
];
|
|
13145
|
+
amendmentText = draft.assistantResponse;
|
|
12785
13146
|
} else {
|
|
12786
|
-
|
|
12787
|
-
|
|
12788
|
-
|
|
12789
|
-
|
|
12790
|
-
|
|
12791
|
-
|
|
12792
|
-
}
|
|
12793
|
-
];
|
|
13147
|
+
pushedAssistant = {
|
|
13148
|
+
role: "assistant",
|
|
13149
|
+
content: draft.assistantResponse,
|
|
13150
|
+
metadata: buildAssistantMetadata(draft)
|
|
13151
|
+
};
|
|
13152
|
+
conv.messages = [...prevMessages, pushedAssistant];
|
|
12794
13153
|
}
|
|
12795
13154
|
}
|
|
12796
13155
|
applyTurnMetadata(conv, {
|
|
@@ -12800,6 +13159,54 @@ var AgentOrchestrator = class {
|
|
|
12800
13159
|
harnessMessages: execution?.runHarnessMessages
|
|
12801
13160
|
}, { shouldRebuildCanonical: true });
|
|
12802
13161
|
await this.conversationStore.update(conv);
|
|
13162
|
+
if (amendmentText !== void 0 || pushedAssistant) {
|
|
13163
|
+
const finalConv = conv;
|
|
13164
|
+
const amendText = amendmentText;
|
|
13165
|
+
const pushed = pushedAssistant;
|
|
13166
|
+
void (async () => {
|
|
13167
|
+
try {
|
|
13168
|
+
if (pushed) {
|
|
13169
|
+
await appendEntriesSafe(
|
|
13170
|
+
this.conversationStore,
|
|
13171
|
+
finalConv,
|
|
13172
|
+
[assistantMessageEntry(pushed, `resume-${conversationId}`, latestRunId)],
|
|
13173
|
+
dualWriteLog
|
|
13174
|
+
);
|
|
13175
|
+
} else if (amendText !== void 0) {
|
|
13176
|
+
const existing = await this.conversationStore.readEntries(
|
|
13177
|
+
conversationId,
|
|
13178
|
+
{ types: ["assistant_message"] }
|
|
13179
|
+
);
|
|
13180
|
+
const target = existing[existing.length - 1];
|
|
13181
|
+
if (target) {
|
|
13182
|
+
await appendEntriesSafe(
|
|
13183
|
+
this.conversationStore,
|
|
13184
|
+
finalConv,
|
|
13185
|
+
[assistantAmendmentEntry(target.id, amendText)],
|
|
13186
|
+
dualWriteLog
|
|
13187
|
+
);
|
|
13188
|
+
} else {
|
|
13189
|
+
dualWriteLog.warn(
|
|
13190
|
+
`[entries-dual-write] resume amendment for ${conversationId}: no assistant_message entry to target; skipped`
|
|
13191
|
+
);
|
|
13192
|
+
}
|
|
13193
|
+
}
|
|
13194
|
+
await verifyEntriesParity(
|
|
13195
|
+
this.conversationStore,
|
|
13196
|
+
conversationId,
|
|
13197
|
+
{
|
|
13198
|
+
harnessMessages: finalConv._harnessMessages,
|
|
13199
|
+
displayMessages: finalConv.messages
|
|
13200
|
+
},
|
|
13201
|
+
dualWriteLog
|
|
13202
|
+
);
|
|
13203
|
+
} catch (err) {
|
|
13204
|
+
dualWriteLog.error(
|
|
13205
|
+
`[entries-dual-write] resume finalize append failed for ${conversationId}: ${err instanceof Error ? err.message : String(err)}`
|
|
13206
|
+
);
|
|
13207
|
+
}
|
|
13208
|
+
})();
|
|
13209
|
+
}
|
|
12803
13210
|
}
|
|
12804
13211
|
} else {
|
|
12805
13212
|
const conv = await this.conversationStore.get(conversationId);
|
|
@@ -13310,19 +13717,22 @@ var AgentOrchestrator = class {
|
|
|
13310
13717
|
conversation.runStatus = "running";
|
|
13311
13718
|
const callbackCount = (conversation.subagentCallbackCount ?? 0) + 1;
|
|
13312
13719
|
conversation.subagentCallbackCount = callbackCount;
|
|
13720
|
+
const injectedCallbackMessages = [];
|
|
13313
13721
|
for (const pr of pendingResults) {
|
|
13314
13722
|
const responseText = (pr.result?.response ?? "").trim();
|
|
13315
13723
|
const responseLine = responseText || `(subagent produced no final summary after ${pr.result?.steps ?? 0} step(s); its work may be incomplete. Call read_subagent with subagent_id "${pr.subagentId}" and mode "assistant" to retrieve what it did.)`;
|
|
13316
13724
|
const resultBody = pr.result ? `Status: ${pr.result.status}
|
|
13317
13725
|
Response: ${responseLine}
|
|
13318
13726
|
Steps: ${pr.result.steps}, Duration: ${pr.result.duration}ms` : pr.error ? `Error: ${pr.error.message}` : "(no result)";
|
|
13319
|
-
|
|
13727
|
+
const injected = {
|
|
13320
13728
|
role: "user",
|
|
13321
13729
|
content: `[Subagent Result] Subagent "${pr.task}" (${pr.subagentId}) ${pr.status}:
|
|
13322
13730
|
|
|
13323
13731
|
${resultBody}`,
|
|
13324
13732
|
metadata: { _subagentCallback: true, subagentId: pr.subagentId, task: pr.task, timestamp: pr.timestamp }
|
|
13325
|
-
}
|
|
13733
|
+
};
|
|
13734
|
+
injectedCallbackMessages.push(injected);
|
|
13735
|
+
conversation.messages.push(injected);
|
|
13326
13736
|
}
|
|
13327
13737
|
const processedIds = new Set(pendingResults.map((pr) => pr.subagentId));
|
|
13328
13738
|
const freshForPending = await this.conversationStore.get(conversationId);
|
|
@@ -13331,6 +13741,36 @@ ${resultBody}`,
|
|
|
13331
13741
|
conversation._harnessMessages = [...conversation.messages];
|
|
13332
13742
|
conversation.updatedAt = Date.now();
|
|
13333
13743
|
await this.conversationStore.update(conversation);
|
|
13744
|
+
if (pendingResults.length > 0) {
|
|
13745
|
+
const turnId = `callback-${callbackCount}-${conversation.conversationId}`;
|
|
13746
|
+
void (async () => {
|
|
13747
|
+
try {
|
|
13748
|
+
const resultEntries = await this.conversationStore.readEntries(
|
|
13749
|
+
conversation.conversationId,
|
|
13750
|
+
{ types: ["subagent_result"] }
|
|
13751
|
+
);
|
|
13752
|
+
const consumedIds = new Set(pendingResults.map((pr) => pr.subagentId));
|
|
13753
|
+
const consumedSeqs = resultEntries.filter(
|
|
13754
|
+
(e) => e.type === "subagent_result" && consumedIds.has(e.result.subagentId)
|
|
13755
|
+
).map((e) => e.seq);
|
|
13756
|
+
await appendEntriesSafe(
|
|
13757
|
+
this.conversationStore,
|
|
13758
|
+
conversation,
|
|
13759
|
+
[
|
|
13760
|
+
callbackStartedEntry(consumedSeqs),
|
|
13761
|
+
...injectedCallbackMessages.map(
|
|
13762
|
+
(m) => userMessageEntry(m, turnId, { hidden: true })
|
|
13763
|
+
)
|
|
13764
|
+
],
|
|
13765
|
+
dualWriteLog
|
|
13766
|
+
);
|
|
13767
|
+
} catch (err) {
|
|
13768
|
+
dualWriteLog.error(
|
|
13769
|
+
`[entries-dual-write] callback_started append failed for ${conversation.conversationId}: ${err instanceof Error ? err.message : String(err)}`
|
|
13770
|
+
);
|
|
13771
|
+
}
|
|
13772
|
+
})();
|
|
13773
|
+
}
|
|
13334
13774
|
if (callbackCount > MAX_SUBAGENT_CALLBACK_COUNT) {
|
|
13335
13775
|
console.warn(`[poncho][subagent-callback] Circuit breaker: ${callbackCount} callbacks for ${conversationId}, skipping re-run`);
|
|
13336
13776
|
conversation.runningCallbackSince = void 0;
|
|
@@ -13392,12 +13832,14 @@ ${resultBody}`,
|
|
|
13392
13832
|
if (callbackNeedsContinuation || execution.draft.assistantResponse.length > 0 || execution.draft.toolTimeline.length > 0) {
|
|
13393
13833
|
const freshConv = await this.conversationStore.get(conversationId);
|
|
13394
13834
|
if (freshConv) {
|
|
13835
|
+
let callbackAssistantMsg;
|
|
13395
13836
|
if (!callbackNeedsContinuation) {
|
|
13396
|
-
|
|
13837
|
+
callbackAssistantMsg = {
|
|
13397
13838
|
role: "assistant",
|
|
13398
13839
|
content: execution.draft.assistantResponse,
|
|
13399
13840
|
metadata: buildAssistantMetadata(execution.draft)
|
|
13400
|
-
}
|
|
13841
|
+
};
|
|
13842
|
+
freshConv.messages.push(callbackAssistantMsg);
|
|
13401
13843
|
}
|
|
13402
13844
|
applyTurnMetadata(freshConv, {
|
|
13403
13845
|
latestRunId: execution.latestRunId,
|
|
@@ -13410,6 +13852,25 @@ ${resultBody}`,
|
|
|
13410
13852
|
}, { shouldRebuildCanonical: true, clearApprovals: false });
|
|
13411
13853
|
freshConv.runningCallbackSince = void 0;
|
|
13412
13854
|
await this.conversationStore.update(freshConv);
|
|
13855
|
+
if (callbackAssistantMsg) {
|
|
13856
|
+
const finalMsg = callbackAssistantMsg;
|
|
13857
|
+
void appendEntriesSafe(
|
|
13858
|
+
this.conversationStore,
|
|
13859
|
+
freshConv,
|
|
13860
|
+
[assistantMessageEntry(finalMsg, `callback-${conversationId}`, execution.latestRunId)],
|
|
13861
|
+
dualWriteLog
|
|
13862
|
+
).then(
|
|
13863
|
+
() => verifyEntriesParity(
|
|
13864
|
+
this.conversationStore,
|
|
13865
|
+
conversationId,
|
|
13866
|
+
{
|
|
13867
|
+
harnessMessages: freshConv._harnessMessages,
|
|
13868
|
+
displayMessages: freshConv.messages
|
|
13869
|
+
},
|
|
13870
|
+
dualWriteLog
|
|
13871
|
+
)
|
|
13872
|
+
);
|
|
13873
|
+
}
|
|
13413
13874
|
if (freshConv.channelMeta && execution.draft.assistantResponse.length > 0) {
|
|
13414
13875
|
this.hooks?.onMessagingNotify?.(conversationId, execution.draft.assistantResponse);
|
|
13415
13876
|
}
|
|
@@ -13814,6 +14275,22 @@ ${resultBody}`,
|
|
|
13814
14275
|
* old `.catch(() => {})` call sites did. Returns whether the result landed.
|
|
13815
14276
|
*/
|
|
13816
14277
|
async appendSubagentResultReliable(parentConversationId, result) {
|
|
14278
|
+
void (async () => {
|
|
14279
|
+
try {
|
|
14280
|
+
const parent = await this.conversationStore.get(parentConversationId);
|
|
14281
|
+
if (!parent) return;
|
|
14282
|
+
await appendEntriesSafe(
|
|
14283
|
+
this.conversationStore,
|
|
14284
|
+
parent,
|
|
14285
|
+
[subagentResultEntry(result)],
|
|
14286
|
+
dualWriteLog
|
|
14287
|
+
);
|
|
14288
|
+
} catch (err) {
|
|
14289
|
+
dualWriteLog.error(
|
|
14290
|
+
`[entries-dual-write] subagent_result append failed for ${parentConversationId}: ${err instanceof Error ? err.message : String(err)}`
|
|
14291
|
+
);
|
|
14292
|
+
}
|
|
14293
|
+
})();
|
|
13817
14294
|
try {
|
|
13818
14295
|
await this.conversationStore.appendSubagentResult(parentConversationId, result);
|
|
13819
14296
|
return true;
|
|
@@ -13915,9 +14392,9 @@ ${resultBody}`,
|
|
|
13915
14392
|
};
|
|
13916
14393
|
|
|
13917
14394
|
// src/orchestrator/run-conversation-turn.ts
|
|
13918
|
-
import { randomUUID as
|
|
13919
|
-
import { createLogger as
|
|
13920
|
-
var log =
|
|
14395
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
14396
|
+
import { createLogger as createLogger8 } from "@poncho-ai/sdk";
|
|
14397
|
+
var log = createLogger8("orchestrator");
|
|
13921
14398
|
var runConversationTurn = async (opts) => {
|
|
13922
14399
|
const conversation = await opts.conversationStore.getWithArchive(opts.conversationId);
|
|
13923
14400
|
if (!conversation) {
|
|
@@ -13955,9 +14432,9 @@ var runConversationTurn = async (opts) => {
|
|
|
13955
14432
|
const userMessage = {
|
|
13956
14433
|
role: "user",
|
|
13957
14434
|
content: userContent,
|
|
13958
|
-
metadata: { id:
|
|
14435
|
+
metadata: { id: randomUUID7(), timestamp: turnTimestamp }
|
|
13959
14436
|
};
|
|
13960
|
-
const assistantId =
|
|
14437
|
+
const assistantId = randomUUID7();
|
|
13961
14438
|
const draft = createTurnDraftState();
|
|
13962
14439
|
let latestRunId = conversation.runtimeRunId ?? "";
|
|
13963
14440
|
let runCancelled = false;
|
|
@@ -13996,6 +14473,8 @@ var runConversationTurn = async (opts) => {
|
|
|
13996
14473
|
conversation.updatedAt = Date.now();
|
|
13997
14474
|
await opts.conversationStore.update(conversation);
|
|
13998
14475
|
};
|
|
14476
|
+
const preTurnHarnessMessages = conversation._harnessMessages ? [...conversation._harnessMessages] : void 0;
|
|
14477
|
+
const turnId = assistantId;
|
|
13999
14478
|
conversation.messages = [...historyMessages, userMessage];
|
|
14000
14479
|
conversation.subagentCallbackCount = 0;
|
|
14001
14480
|
conversation._continuationCount = void 0;
|
|
@@ -14005,6 +14484,12 @@ var runConversationTurn = async (opts) => {
|
|
|
14005
14484
|
`failed to persist user turn: ${err instanceof Error ? err.message : String(err)}`
|
|
14006
14485
|
);
|
|
14007
14486
|
});
|
|
14487
|
+
void appendEntriesSafe(
|
|
14488
|
+
opts.conversationStore,
|
|
14489
|
+
conversation,
|
|
14490
|
+
[userMessageEntry(userMessage, turnId)],
|
|
14491
|
+
log
|
|
14492
|
+
);
|
|
14008
14493
|
try {
|
|
14009
14494
|
const execution = await executeConversationTurn({
|
|
14010
14495
|
harness: opts.harness,
|
|
@@ -14052,6 +14537,34 @@ var runConversationTurn = async (opts) => {
|
|
|
14052
14537
|
...existingHistory,
|
|
14053
14538
|
...preRunMessages.slice(0, removedCount)
|
|
14054
14539
|
];
|
|
14540
|
+
const summaryMessage = event.compactedMessages[0];
|
|
14541
|
+
const keptCount = Math.max(0, event.compactedMessages.length - 1);
|
|
14542
|
+
if (summaryMessage) {
|
|
14543
|
+
void (async () => {
|
|
14544
|
+
try {
|
|
14545
|
+
const existing = await opts.conversationStore.readEntries(
|
|
14546
|
+
opts.conversationId,
|
|
14547
|
+
{ types: ["harness_message"] }
|
|
14548
|
+
);
|
|
14549
|
+
const harnessSeqs = existing.map((e) => e.seq);
|
|
14550
|
+
const firstKeptSeq = harnessSeqs.length >= keptCount && keptCount > 0 ? harnessSeqs[harnessSeqs.length - keptCount] : (harnessSeqs[harnessSeqs.length - 1] ?? 0) + 1;
|
|
14551
|
+
await appendEntriesSafe(
|
|
14552
|
+
opts.conversationStore,
|
|
14553
|
+
conversation,
|
|
14554
|
+
[
|
|
14555
|
+
compactionEntry(summaryMessage, firstKeptSeq, {
|
|
14556
|
+
tokensBefore: conversation.contextTokens
|
|
14557
|
+
})
|
|
14558
|
+
],
|
|
14559
|
+
log
|
|
14560
|
+
);
|
|
14561
|
+
} catch (err) {
|
|
14562
|
+
log.error(
|
|
14563
|
+
`[entries-dual-write] compaction append failed: ${err instanceof Error ? err.message : String(err)}`
|
|
14564
|
+
);
|
|
14565
|
+
}
|
|
14566
|
+
})();
|
|
14567
|
+
}
|
|
14055
14568
|
}
|
|
14056
14569
|
}
|
|
14057
14570
|
if (event.type === "step:completed") {
|
|
@@ -14185,6 +14698,36 @@ var runConversationTurn = async (opts) => {
|
|
|
14185
14698
|
{ shouldRebuildCanonical }
|
|
14186
14699
|
);
|
|
14187
14700
|
await opts.conversationStore.update(conversation);
|
|
14701
|
+
const finalAssistant = conversation.messages[conversation.messages.length - 1];
|
|
14702
|
+
const { messages: newHarness, approximate } = newHarnessMessagesThisTurn(
|
|
14703
|
+
preTurnHarnessMessages,
|
|
14704
|
+
conversation._harnessMessages
|
|
14705
|
+
);
|
|
14706
|
+
if (approximate) {
|
|
14707
|
+
log.warn(
|
|
14708
|
+
`[entries-dual-write] ${opts.conversationId} harness-message diff approximate (blob array shrank this turn \u2014 likely compaction); appended full context`
|
|
14709
|
+
);
|
|
14710
|
+
}
|
|
14711
|
+
const finalizeEntries = [
|
|
14712
|
+
...harnessMessageEntries(newHarness, turnId),
|
|
14713
|
+
...finalAssistant && finalAssistant.role === "assistant" ? [assistantMessageEntry(finalAssistant, turnId, latestRunId)] : []
|
|
14714
|
+
];
|
|
14715
|
+
void appendEntriesSafe(
|
|
14716
|
+
opts.conversationStore,
|
|
14717
|
+
conversation,
|
|
14718
|
+
finalizeEntries,
|
|
14719
|
+
log
|
|
14720
|
+
).then(
|
|
14721
|
+
() => verifyEntriesParity(
|
|
14722
|
+
opts.conversationStore,
|
|
14723
|
+
opts.conversationId,
|
|
14724
|
+
{
|
|
14725
|
+
harnessMessages: conversation._harnessMessages,
|
|
14726
|
+
displayMessages: conversation.messages
|
|
14727
|
+
},
|
|
14728
|
+
log
|
|
14729
|
+
)
|
|
14730
|
+
);
|
|
14188
14731
|
}
|
|
14189
14732
|
return {
|
|
14190
14733
|
latestRunId,
|
|
@@ -14302,10 +14845,13 @@ export {
|
|
|
14302
14845
|
VFS_SCHEME,
|
|
14303
14846
|
VercelBlobUploadStore,
|
|
14304
14847
|
abnormalEndResponse,
|
|
14848
|
+
appendEntriesSafe,
|
|
14305
14849
|
applyTurnMetadata,
|
|
14306
14850
|
buildAgentDirectoryName,
|
|
14307
14851
|
buildApprovalCheckpoints,
|
|
14308
14852
|
buildAssistantMetadata,
|
|
14853
|
+
buildDisplaySnapshot,
|
|
14854
|
+
buildLlmContext,
|
|
14309
14855
|
buildSkillContextWindow,
|
|
14310
14856
|
buildToolCompletedText,
|
|
14311
14857
|
cloneSections,
|
|
@@ -14342,6 +14888,7 @@ export {
|
|
|
14342
14888
|
deleteOpenAICodexSession,
|
|
14343
14889
|
deriveUploadKey,
|
|
14344
14890
|
ensureAgentIdentity,
|
|
14891
|
+
entriesParityEnabled,
|
|
14345
14892
|
estimateTokens,
|
|
14346
14893
|
estimateTotalTokens,
|
|
14347
14894
|
executeConversationTurn,
|
|
@@ -14353,6 +14900,7 @@ export {
|
|
|
14353
14900
|
getOpenAICodexAccessToken,
|
|
14354
14901
|
getOpenAICodexAuthFilePath,
|
|
14355
14902
|
getOpenAICodexRequiredScopes,
|
|
14903
|
+
getPendingSubagentResults,
|
|
14356
14904
|
getPonchoStoreRoot,
|
|
14357
14905
|
isMessageArray,
|
|
14358
14906
|
jsonSchemaToZod,
|
|
@@ -14366,6 +14914,7 @@ export {
|
|
|
14366
14914
|
loadSkillMetadataFromDirs,
|
|
14367
14915
|
loadVfsSkillMetadata,
|
|
14368
14916
|
mergeSkills,
|
|
14917
|
+
newHarnessMessagesThisTurn,
|
|
14369
14918
|
normalizeApprovalCheckpoint,
|
|
14370
14919
|
normalizeOtlp,
|
|
14371
14920
|
normalizeScriptPolicyPath,
|
|
@@ -14389,6 +14938,7 @@ export {
|
|
|
14389
14938
|
runConversationTurn,
|
|
14390
14939
|
slugifyStorageComponent,
|
|
14391
14940
|
startOpenAICodexDeviceAuth,
|
|
14941
|
+
verifyEntriesParity,
|
|
14392
14942
|
verifyTenantToken,
|
|
14393
14943
|
withToolResultArchiveParam,
|
|
14394
14944
|
writeOpenAICodexSession
|