@poncho-ai/harness 0.37.2 → 0.39.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 +216 -0
- package/dist/index.d.ts +397 -34
- package/dist/index.js +2228 -130
- package/package.json +2 -2
- package/src/harness.ts +48 -72
- package/src/index.ts +1 -0
- package/src/local-tools.ts +4 -3
- package/src/mcp.ts +9 -6
- package/src/orchestrator/continuation.ts +13 -0
- package/src/orchestrator/history.ts +69 -0
- package/src/orchestrator/index.ts +54 -0
- package/src/orchestrator/orchestrator.ts +1535 -0
- package/src/orchestrator/subagents.ts +27 -0
- package/src/orchestrator/turn.ts +367 -0
- package/src/reminder-store.ts +183 -16
- package/src/reminder-tools.ts +102 -6
- package/src/state.ts +127 -3
- package/src/storage/engine.ts +29 -10
- package/src/storage/memory-engine.ts +74 -10
- package/src/storage/postgres-engine.ts +1 -0
- package/src/storage/schema.ts +21 -0
- package/src/storage/sql-dialect.ts +294 -23
- package/src/storage/sqlite-engine.ts +1 -0
- package/src/storage/store-adapters.ts +17 -11
- package/src/telemetry.ts +10 -7
- package/src/upload-store.ts +7 -4
- package/src/vfs/bash-manager.ts +16 -2
- package/src/vfs/edit-file-tool.ts +9 -8
- package/src/vfs/read-file-tool.ts +14 -15
- package/src/vfs/write-file-tool.ts +6 -5
- package/test/orchestrator.test.ts +176 -0
- package/test/reminder-store.test.ts +193 -4
- package/test/state.test.ts +21 -0
- package/test/storage-engine.test.ts +80 -0
package/dist/index.d.ts
CHANGED
|
@@ -174,6 +174,13 @@ interface Conversation {
|
|
|
174
174
|
contextTokens?: number;
|
|
175
175
|
contextWindow?: number;
|
|
176
176
|
parentConversationId?: string;
|
|
177
|
+
parentMessageId?: string;
|
|
178
|
+
threadMeta?: {
|
|
179
|
+
/** First ~200 chars of the anchor message text, cached for cheap rendering. */
|
|
180
|
+
parentMessageSummary?: string;
|
|
181
|
+
/** Length of the snapshot at fork time. messages[snapshotLength-1] is the anchor. */
|
|
182
|
+
snapshotLength: number;
|
|
183
|
+
};
|
|
177
184
|
subagentMeta?: {
|
|
178
185
|
task: string;
|
|
179
186
|
status: "running" | "completed" | "error" | "stopped";
|
|
@@ -196,16 +203,42 @@ interface Conversation {
|
|
|
196
203
|
createdAt: number;
|
|
197
204
|
updatedAt: number;
|
|
198
205
|
}
|
|
206
|
+
interface ConversationCreateInit {
|
|
207
|
+
parentConversationId?: string;
|
|
208
|
+
parentMessageId?: string;
|
|
209
|
+
threadMeta?: Conversation["threadMeta"];
|
|
210
|
+
subagentMeta?: Conversation["subagentMeta"];
|
|
211
|
+
messages?: Message[];
|
|
212
|
+
channelMeta?: Conversation["channelMeta"];
|
|
213
|
+
}
|
|
199
214
|
interface ConversationStore {
|
|
200
215
|
list(ownerId?: string, tenantId?: string | null): Promise<Conversation[]>;
|
|
201
216
|
listSummaries(ownerId?: string, tenantId?: string | null): Promise<ConversationSummary[]>;
|
|
217
|
+
/**
|
|
218
|
+
* Cheap column-level fetch — returns summary fields only, no data blob.
|
|
219
|
+
* Use this on hot polling paths where the caller just needs to know
|
|
220
|
+
* whether the conversation has changed since last fetch.
|
|
221
|
+
*/
|
|
222
|
+
getStatusSnapshot(conversationId: string): Promise<ConversationStatusSnapshot | undefined>;
|
|
223
|
+
/**
|
|
224
|
+
* Load a conversation WITHOUT the tool_result_archive blob. Default for
|
|
225
|
+
* read paths — archive can grow unboundedly and most callers don't need it.
|
|
226
|
+
*/
|
|
202
227
|
get(conversationId: string): Promise<Conversation | undefined>;
|
|
203
|
-
|
|
228
|
+
/**
|
|
229
|
+
* Load a conversation WITH the tool_result_archive. Use this only on
|
|
230
|
+
* run-entry paths that reseed the harness (via withToolResultArchiveParam
|
|
231
|
+
* or by passing the archive to runCronAgent).
|
|
232
|
+
*/
|
|
233
|
+
getWithArchive(conversationId: string): Promise<Conversation | undefined>;
|
|
234
|
+
create(ownerId?: string, title?: string, tenantId?: string | null, init?: ConversationCreateInit): Promise<Conversation>;
|
|
204
235
|
update(conversation: Conversation): Promise<void>;
|
|
205
236
|
rename(conversationId: string, title: string): Promise<Conversation | undefined>;
|
|
206
237
|
delete(conversationId: string): Promise<boolean>;
|
|
207
238
|
appendSubagentResult(conversationId: string, result: PendingSubagentResult): Promise<void>;
|
|
208
239
|
clearCallbackLock(conversationId: string): Promise<Conversation | undefined>;
|
|
240
|
+
/** List thread conversations anchored under `parentConversationId`. */
|
|
241
|
+
listThreads(parentConversationId: string): Promise<ConversationSummary[]>;
|
|
209
242
|
}
|
|
210
243
|
type StateProviderName = "local" | "memory" | "sqlite" | "postgresql" | "redis" | "upstash" | "dynamodb";
|
|
211
244
|
interface StateConfig {
|
|
@@ -234,12 +267,15 @@ declare class InMemoryConversationStore implements ConversationStore {
|
|
|
234
267
|
list(ownerId?: string, tenantId?: string | null): Promise<Conversation[]>;
|
|
235
268
|
listSummaries(ownerId?: string, tenantId?: string | null): Promise<ConversationSummary[]>;
|
|
236
269
|
get(conversationId: string): Promise<Conversation | undefined>;
|
|
237
|
-
|
|
270
|
+
getWithArchive(conversationId: string): Promise<Conversation | undefined>;
|
|
271
|
+
getStatusSnapshot(conversationId: string): Promise<ConversationStatusSnapshot | undefined>;
|
|
272
|
+
create(ownerId?: string, title?: string, tenantId?: string | null, init?: ConversationCreateInit): Promise<Conversation>;
|
|
238
273
|
update(conversation: Conversation): Promise<void>;
|
|
239
274
|
rename(conversationId: string, title: string): Promise<Conversation | undefined>;
|
|
240
275
|
delete(conversationId: string): Promise<boolean>;
|
|
241
276
|
appendSubagentResult(conversationId: string, result: PendingSubagentResult): Promise<void>;
|
|
242
277
|
clearCallbackLock(conversationId: string): Promise<Conversation | undefined>;
|
|
278
|
+
listThreads(parentConversationId: string): Promise<ConversationSummary[]>;
|
|
243
279
|
}
|
|
244
280
|
type ConversationSummary = {
|
|
245
281
|
conversationId: string;
|
|
@@ -249,6 +285,7 @@ type ConversationSummary = {
|
|
|
249
285
|
ownerId: string;
|
|
250
286
|
tenantId?: string | null;
|
|
251
287
|
parentConversationId?: string;
|
|
288
|
+
parentMessageId?: string;
|
|
252
289
|
messageCount?: number;
|
|
253
290
|
hasPendingApprovals?: boolean;
|
|
254
291
|
channelMeta?: {
|
|
@@ -257,6 +294,22 @@ type ConversationSummary = {
|
|
|
257
294
|
platformThreadId: string;
|
|
258
295
|
};
|
|
259
296
|
};
|
|
297
|
+
/**
|
|
298
|
+
* Lightweight status snapshot — column-level reads only, no data blob.
|
|
299
|
+
* Used by cheap polling endpoints that just need to know "has anything
|
|
300
|
+
* changed?" without paying to deserialize the full conversation.
|
|
301
|
+
*/
|
|
302
|
+
type ConversationStatusSnapshot = {
|
|
303
|
+
conversationId: string;
|
|
304
|
+
updatedAt: number;
|
|
305
|
+
messageCount: number;
|
|
306
|
+
hasPendingApprovals: boolean;
|
|
307
|
+
hasContinuationMessages: boolean;
|
|
308
|
+
parentConversationId: string | null;
|
|
309
|
+
ownerId: string;
|
|
310
|
+
tenantId: string | null;
|
|
311
|
+
runStatus: "running" | "idle" | null;
|
|
312
|
+
};
|
|
260
313
|
declare const createStateStore: (config?: StateConfig, _options?: {
|
|
261
314
|
workingDir?: string;
|
|
262
315
|
agentId?: string;
|
|
@@ -682,6 +735,20 @@ interface TodoStore {
|
|
|
682
735
|
}
|
|
683
736
|
|
|
684
737
|
type ReminderStatus = "pending" | "fired" | "cancelled";
|
|
738
|
+
type RecurrenceType = "daily" | "weekly" | "monthly" | "cron";
|
|
739
|
+
interface Recurrence {
|
|
740
|
+
type: RecurrenceType;
|
|
741
|
+
/** Repeat every N units (e.g. every 2 days). Defaults to 1. */
|
|
742
|
+
interval?: number;
|
|
743
|
+
/** For weekly: which days (0=Sun … 6=Sat). */
|
|
744
|
+
daysOfWeek?: number[];
|
|
745
|
+
/** For type "cron": a 5-field cron expression. */
|
|
746
|
+
expression?: string;
|
|
747
|
+
/** Stop recurring after this epoch-ms timestamp. */
|
|
748
|
+
endsAt?: number;
|
|
749
|
+
/** Stop recurring after this many total firings. */
|
|
750
|
+
maxOccurrences?: number;
|
|
751
|
+
}
|
|
685
752
|
interface Reminder {
|
|
686
753
|
id: string;
|
|
687
754
|
task: string;
|
|
@@ -692,20 +759,35 @@ interface Reminder {
|
|
|
692
759
|
conversationId: string;
|
|
693
760
|
ownerId?: string;
|
|
694
761
|
tenantId?: string | null;
|
|
762
|
+
recurrence?: Recurrence | null;
|
|
763
|
+
occurrenceCount?: number;
|
|
764
|
+
}
|
|
765
|
+
interface ReminderCreateInput {
|
|
766
|
+
task: string;
|
|
767
|
+
scheduledAt: number;
|
|
768
|
+
timezone?: string;
|
|
769
|
+
conversationId: string;
|
|
770
|
+
ownerId?: string;
|
|
771
|
+
tenantId?: string | null;
|
|
772
|
+
recurrence?: Recurrence | null;
|
|
695
773
|
}
|
|
696
774
|
interface ReminderStore {
|
|
697
775
|
list(): Promise<Reminder[]>;
|
|
698
|
-
create(input:
|
|
699
|
-
|
|
700
|
-
scheduledAt
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
ownerId?: string;
|
|
704
|
-
tenantId?: string | null;
|
|
776
|
+
create(input: ReminderCreateInput): Promise<Reminder>;
|
|
777
|
+
update(id: string, fields: {
|
|
778
|
+
scheduledAt?: number;
|
|
779
|
+
occurrenceCount?: number;
|
|
780
|
+
status?: ReminderStatus;
|
|
705
781
|
}): Promise<Reminder>;
|
|
706
782
|
cancel(id: string): Promise<Reminder>;
|
|
707
783
|
delete(id: string): Promise<void>;
|
|
708
784
|
}
|
|
785
|
+
/**
|
|
786
|
+
* Given a reminder's current scheduledAt and its recurrence config, compute the
|
|
787
|
+
* next fire time. Returns null if the recurrence is exhausted (maxOccurrences
|
|
788
|
+
* reached or endsAt passed).
|
|
789
|
+
*/
|
|
790
|
+
declare const computeNextOccurrence: (reminder: Reminder) => number | null;
|
|
709
791
|
declare const createReminderStore: (_agentId: string, _config?: StateConfig, _options?: {
|
|
710
792
|
workingDir?: string;
|
|
711
793
|
}) => ReminderStore;
|
|
@@ -730,14 +812,32 @@ interface StorageEngine {
|
|
|
730
812
|
close(): Promise<void>;
|
|
731
813
|
conversations: {
|
|
732
814
|
list(ownerId?: string, tenantId?: string | null): Promise<ConversationSummary[]>;
|
|
815
|
+
/**
|
|
816
|
+
* Load a conversation WITHOUT the tool_result_archive blob. Use this on
|
|
817
|
+
* read paths (UI loads, existence checks, etc.) — the archive can grow
|
|
818
|
+
* unboundedly as tool calls accumulate, and most callers never touch it.
|
|
819
|
+
*/
|
|
733
820
|
get(conversationId: string): Promise<Conversation | undefined>;
|
|
734
|
-
|
|
821
|
+
/**
|
|
822
|
+
* Load a conversation WITH the tool_result_archive. Only use this when
|
|
823
|
+
* starting/resuming a harness run — the archive needs to be reseeded so
|
|
824
|
+
* the agent can retrieve previously-archived tool results by id.
|
|
825
|
+
*/
|
|
826
|
+
getWithArchive(conversationId: string): Promise<Conversation | undefined>;
|
|
827
|
+
/**
|
|
828
|
+
* Cheap column-level snapshot — no data blob, no heavy columns. For hot
|
|
829
|
+
* polling paths. Returns undefined if the conversation doesn't exist.
|
|
830
|
+
*/
|
|
831
|
+
getStatusSnapshot(conversationId: string): Promise<ConversationStatusSnapshot | undefined>;
|
|
832
|
+
create(ownerId?: string, title?: string, tenantId?: string | null, init?: ConversationCreateInit): Promise<Conversation>;
|
|
735
833
|
update(conversation: Conversation): Promise<void>;
|
|
736
834
|
rename(conversationId: string, title: string): Promise<Conversation | undefined>;
|
|
737
835
|
delete(conversationId: string): Promise<boolean>;
|
|
738
836
|
search(query: string, tenantId?: string | null): Promise<ConversationSummary[]>;
|
|
739
837
|
appendSubagentResult(conversationId: string, result: PendingSubagentResult): Promise<void>;
|
|
740
838
|
clearCallbackLock(conversationId: string): Promise<Conversation | undefined>;
|
|
839
|
+
/** List thread conversations anchored under `parentConversationId`. */
|
|
840
|
+
listThreads(parentConversationId: string): Promise<ConversationSummary[]>;
|
|
741
841
|
};
|
|
742
842
|
memory: {
|
|
743
843
|
get(tenantId?: string | null): Promise<MainMemory>;
|
|
@@ -749,13 +849,11 @@ interface StorageEngine {
|
|
|
749
849
|
};
|
|
750
850
|
reminders: {
|
|
751
851
|
list(tenantId?: string | null): Promise<Reminder[]>;
|
|
752
|
-
create(input:
|
|
753
|
-
|
|
754
|
-
scheduledAt
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
ownerId?: string;
|
|
758
|
-
tenantId?: string | null;
|
|
852
|
+
create(input: ReminderCreateInput): Promise<Reminder>;
|
|
853
|
+
update(id: string, fields: {
|
|
854
|
+
scheduledAt?: number;
|
|
855
|
+
occurrenceCount?: number;
|
|
856
|
+
status?: ReminderStatus;
|
|
759
857
|
}): Promise<Reminder>;
|
|
760
858
|
cancel(id: string): Promise<Reminder>;
|
|
761
859
|
delete(id: string): Promise<void>;
|
|
@@ -1165,13 +1263,16 @@ declare class InMemoryEngine implements StorageEngine {
|
|
|
1165
1263
|
conversations: {
|
|
1166
1264
|
list: (ownerId?: string, tenantId?: string | null) => Promise<ConversationSummary[]>;
|
|
1167
1265
|
get: (conversationId: string) => Promise<Conversation | undefined>;
|
|
1168
|
-
|
|
1266
|
+
getWithArchive: (conversationId: string) => Promise<Conversation | undefined>;
|
|
1267
|
+
getStatusSnapshot: (conversationId: string) => Promise<ConversationStatusSnapshot | undefined>;
|
|
1268
|
+
create: (ownerId?: string, title?: string, tenantId?: string | null, init?: ConversationCreateInit) => Promise<Conversation>;
|
|
1169
1269
|
update: (conversation: Conversation) => Promise<void>;
|
|
1170
1270
|
rename: (conversationId: string, title: string) => Promise<Conversation | undefined>;
|
|
1171
1271
|
delete: (conversationId: string) => Promise<boolean>;
|
|
1172
1272
|
search: (query: string, tenantId?: string | null) => Promise<ConversationSummary[]>;
|
|
1173
1273
|
appendSubagentResult: (conversationId: string, result: PendingSubagentResult) => Promise<void>;
|
|
1174
1274
|
clearCallbackLock: (conversationId: string) => Promise<Conversation | undefined>;
|
|
1275
|
+
listThreads: (parentConversationId: string) => Promise<ConversationSummary[]>;
|
|
1175
1276
|
};
|
|
1176
1277
|
memory: {
|
|
1177
1278
|
get: (tenantId?: string | null) => Promise<MainMemory>;
|
|
@@ -1183,13 +1284,11 @@ declare class InMemoryEngine implements StorageEngine {
|
|
|
1183
1284
|
};
|
|
1184
1285
|
reminders: {
|
|
1185
1286
|
list: (tenantId?: string | null) => Promise<Reminder[]>;
|
|
1186
|
-
create: (input:
|
|
1187
|
-
|
|
1188
|
-
scheduledAt
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
ownerId?: string;
|
|
1192
|
-
tenantId?: string | null;
|
|
1287
|
+
create: (input: ReminderCreateInput) => Promise<Reminder>;
|
|
1288
|
+
update: (id: string, fields: {
|
|
1289
|
+
scheduledAt?: number;
|
|
1290
|
+
occurrenceCount?: number;
|
|
1291
|
+
status?: ReminderStatus;
|
|
1193
1292
|
}) => Promise<Reminder>;
|
|
1194
1293
|
cancel: (id: string) => Promise<Reminder>;
|
|
1195
1294
|
delete: (id: string) => Promise<void>;
|
|
@@ -1249,26 +1348,48 @@ interface QueryExecutor {
|
|
|
1249
1348
|
/** Run multiple statements in a transaction. */
|
|
1250
1349
|
transaction(fn: () => Promise<void>): Promise<void>;
|
|
1251
1350
|
}
|
|
1351
|
+
interface EgressBucket {
|
|
1352
|
+
calls: number;
|
|
1353
|
+
bytes: number;
|
|
1354
|
+
}
|
|
1355
|
+
declare class ConversationEgressMeter {
|
|
1356
|
+
readonly read: Record<string, EgressBucket>;
|
|
1357
|
+
readonly write: Record<string, EgressBucket>;
|
|
1358
|
+
private lastLogAt;
|
|
1359
|
+
private readonly logIntervalMs;
|
|
1360
|
+
private readonly enabled;
|
|
1361
|
+
constructor(logIntervalMs?: number);
|
|
1362
|
+
trackRead(method: string, bytes: number): void;
|
|
1363
|
+
trackWrite(method: string, bytes: number): void;
|
|
1364
|
+
private maybeLog;
|
|
1365
|
+
flush(): void;
|
|
1366
|
+
}
|
|
1252
1367
|
declare abstract class SqlStorageEngine implements StorageEngine {
|
|
1253
1368
|
protected readonly dialect: Dialect;
|
|
1254
1369
|
protected readonly agentId: string;
|
|
1255
1370
|
protected abstract readonly executor: QueryExecutor;
|
|
1371
|
+
protected readonly egressMeter: ConversationEgressMeter;
|
|
1256
1372
|
constructor(dialect: Dialect, agentId: string);
|
|
1257
1373
|
initialize(): Promise<void>;
|
|
1258
1374
|
abstract close(): Promise<void>;
|
|
1375
|
+
/** Flush egress stats before shutdown. Subclasses should call super. */
|
|
1376
|
+
protected flushEgressStats(): void;
|
|
1259
1377
|
/** Hook for subclass-specific setup (e.g. WAL mode). */
|
|
1260
1378
|
protected onBeforeInit(): Promise<void>;
|
|
1261
1379
|
private runMigrations;
|
|
1262
1380
|
conversations: {
|
|
1263
1381
|
list: (ownerId?: string, tenantId?: string | null) => Promise<ConversationSummary[]>;
|
|
1264
1382
|
get: (conversationId: string) => Promise<Conversation | undefined>;
|
|
1265
|
-
|
|
1383
|
+
getStatusSnapshot: (conversationId: string) => Promise<ConversationStatusSnapshot | undefined>;
|
|
1384
|
+
getWithArchive: (conversationId: string) => Promise<Conversation | undefined>;
|
|
1385
|
+
create: (ownerId?: string, title?: string, tenantId?: string | null, init?: ConversationCreateInit) => Promise<Conversation>;
|
|
1266
1386
|
update: (conversation: Conversation) => Promise<void>;
|
|
1267
1387
|
rename: (conversationId: string, title: string) => Promise<Conversation | undefined>;
|
|
1268
1388
|
delete: (conversationId: string) => Promise<boolean>;
|
|
1269
1389
|
search: (query: string, tenantId?: string | null) => Promise<ConversationSummary[]>;
|
|
1270
1390
|
appendSubagentResult: (conversationId: string, result: PendingSubagentResult) => Promise<void>;
|
|
1271
1391
|
clearCallbackLock: (conversationId: string) => Promise<Conversation | undefined>;
|
|
1392
|
+
listThreads: (parentConversationId: string) => Promise<ConversationSummary[]>;
|
|
1272
1393
|
};
|
|
1273
1394
|
memory: {
|
|
1274
1395
|
get: (tenantId?: string | null) => Promise<MainMemory>;
|
|
@@ -1280,13 +1401,11 @@ declare abstract class SqlStorageEngine implements StorageEngine {
|
|
|
1280
1401
|
};
|
|
1281
1402
|
reminders: {
|
|
1282
1403
|
list: (tenantId?: string | null) => Promise<Reminder[]>;
|
|
1283
|
-
create: (input:
|
|
1284
|
-
|
|
1285
|
-
scheduledAt
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
ownerId?: string;
|
|
1289
|
-
tenantId?: string | null;
|
|
1404
|
+
create: (input: ReminderCreateInput) => Promise<Reminder>;
|
|
1405
|
+
update: (id: string, fields: {
|
|
1406
|
+
scheduledAt?: number;
|
|
1407
|
+
occurrenceCount?: number;
|
|
1408
|
+
status?: ReminderStatus;
|
|
1290
1409
|
}) => Promise<Reminder>;
|
|
1291
1410
|
cancel: (id: string) => Promise<Reminder>;
|
|
1292
1411
|
delete: (id: string) => Promise<void>;
|
|
@@ -1419,12 +1538,15 @@ declare class BashEnvironmentManager {
|
|
|
1419
1538
|
private engine;
|
|
1420
1539
|
private limits;
|
|
1421
1540
|
private environments;
|
|
1541
|
+
private filesystems;
|
|
1422
1542
|
private readonly workingDir;
|
|
1423
1543
|
private readonly bashOptions;
|
|
1424
1544
|
constructor(engine: StorageEngine, limits: {
|
|
1425
1545
|
maxFileSize: number;
|
|
1426
1546
|
maxTotalStorage: number;
|
|
1427
1547
|
}, workingDir: string | null, bashConfig?: BashConfig, network?: NetworkConfig);
|
|
1548
|
+
/** Return the combined IFileSystem (VFS + optional /project mount) for a tenant. */
|
|
1549
|
+
getFs(tenantId: string): IFileSystem;
|
|
1428
1550
|
getOrCreate(tenantId: string): Bash;
|
|
1429
1551
|
getAdapter(tenantId: string): PonchoFsAdapter;
|
|
1430
1552
|
/** Refresh the PostgreSQL path cache before a bash.exec() call. */
|
|
@@ -1447,4 +1569,245 @@ declare function verifyTenantToken(signingKey: string, token: string): Promise<T
|
|
|
1447
1569
|
|
|
1448
1570
|
declare const createSubagentTools: (manager: SubagentManager) => ToolDefinition[];
|
|
1449
1571
|
|
|
1450
|
-
|
|
1572
|
+
type HistorySource = "harness" | "continuation" | "messages";
|
|
1573
|
+
type RunRequest = {
|
|
1574
|
+
conversationId: string;
|
|
1575
|
+
messages: Message[];
|
|
1576
|
+
preferContinuation?: boolean;
|
|
1577
|
+
};
|
|
1578
|
+
type RunOutcome = {
|
|
1579
|
+
source: HistorySource;
|
|
1580
|
+
shouldRebuildCanonical: boolean;
|
|
1581
|
+
messages: Message[];
|
|
1582
|
+
};
|
|
1583
|
+
declare const isMessageArray: (value: unknown) => value is Message[];
|
|
1584
|
+
declare const loadCanonicalHistory: (conversation: Conversation) => {
|
|
1585
|
+
messages: Message[];
|
|
1586
|
+
source: HistorySource;
|
|
1587
|
+
};
|
|
1588
|
+
declare const loadRunHistory: (conversation: Conversation, options?: {
|
|
1589
|
+
preferContinuation?: boolean;
|
|
1590
|
+
}) => {
|
|
1591
|
+
messages: Message[];
|
|
1592
|
+
source: HistorySource;
|
|
1593
|
+
shouldRebuildCanonical: boolean;
|
|
1594
|
+
};
|
|
1595
|
+
declare const resolveRunRequest: (conversation: Conversation, request: RunRequest) => RunOutcome;
|
|
1596
|
+
|
|
1597
|
+
type StoredApproval = NonNullable<Conversation["pendingApprovals"]>[number];
|
|
1598
|
+
type PendingToolCall = {
|
|
1599
|
+
id: string;
|
|
1600
|
+
name: string;
|
|
1601
|
+
input: Record<string, unknown>;
|
|
1602
|
+
};
|
|
1603
|
+
type ApprovalEventItem = {
|
|
1604
|
+
approvalId: string;
|
|
1605
|
+
tool: string;
|
|
1606
|
+
toolCallId?: string;
|
|
1607
|
+
input: Record<string, unknown>;
|
|
1608
|
+
};
|
|
1609
|
+
type TurnSection = {
|
|
1610
|
+
type: "text" | "tools";
|
|
1611
|
+
content: string | string[];
|
|
1612
|
+
};
|
|
1613
|
+
type TurnDraftState = {
|
|
1614
|
+
assistantResponse: string;
|
|
1615
|
+
toolTimeline: string[];
|
|
1616
|
+
sections: TurnSection[];
|
|
1617
|
+
currentTools: string[];
|
|
1618
|
+
currentText: string;
|
|
1619
|
+
};
|
|
1620
|
+
type ExecuteTurnResult = {
|
|
1621
|
+
latestRunId: string;
|
|
1622
|
+
runCancelled: boolean;
|
|
1623
|
+
runContinuation: boolean;
|
|
1624
|
+
runContinuationMessages?: Message[];
|
|
1625
|
+
runHarnessMessages?: Message[];
|
|
1626
|
+
runContextTokens: number;
|
|
1627
|
+
runContextWindow: number;
|
|
1628
|
+
runSteps: number;
|
|
1629
|
+
runMaxSteps?: number;
|
|
1630
|
+
draft: TurnDraftState;
|
|
1631
|
+
};
|
|
1632
|
+
type TurnResultMetadata = {
|
|
1633
|
+
latestRunId: string;
|
|
1634
|
+
contextTokens: number;
|
|
1635
|
+
contextWindow: number;
|
|
1636
|
+
continuation?: boolean;
|
|
1637
|
+
continuationMessages?: Message[];
|
|
1638
|
+
harnessMessages?: Message[];
|
|
1639
|
+
toolResultArchive?: Conversation["_toolResultArchive"];
|
|
1640
|
+
};
|
|
1641
|
+
declare const createTurnDraftState: () => TurnDraftState;
|
|
1642
|
+
declare const cloneSections: (sections: TurnSection[]) => TurnSection[];
|
|
1643
|
+
declare const flushTurnDraft: (draft: TurnDraftState) => void;
|
|
1644
|
+
/** Build enriched tool:completed text with input details (bash command, URL, etc.) */
|
|
1645
|
+
declare const buildToolCompletedText: (event: AgentEvent & {
|
|
1646
|
+
type: "tool:completed";
|
|
1647
|
+
}) => string;
|
|
1648
|
+
declare const recordStandardTurnEvent: (draft: TurnDraftState, event: AgentEvent) => void;
|
|
1649
|
+
declare const buildAssistantMetadata: (draft: TurnDraftState, sectionsOverride?: TurnSection[], opts?: {
|
|
1650
|
+
id?: string;
|
|
1651
|
+
timestamp?: number;
|
|
1652
|
+
}) => Message["metadata"] | undefined;
|
|
1653
|
+
declare const executeConversationTurn: ({ harness, runInput, events, initialContextTokens, initialContextWindow, onEvent, }: {
|
|
1654
|
+
harness: AgentHarness;
|
|
1655
|
+
runInput?: Parameters<AgentHarness["runWithTelemetry"]>[0];
|
|
1656
|
+
events?: AsyncIterable<AgentEvent>;
|
|
1657
|
+
initialContextTokens?: number;
|
|
1658
|
+
initialContextWindow?: number;
|
|
1659
|
+
onEvent?: (event: AgentEvent, draft: TurnDraftState) => void | Promise<void>;
|
|
1660
|
+
}) => Promise<ExecuteTurnResult>;
|
|
1661
|
+
declare const normalizeApprovalCheckpoint: (approval: StoredApproval, fallbackMessages: Message[]) => StoredApproval;
|
|
1662
|
+
declare const buildApprovalCheckpoints: ({ approvals, runId, checkpointMessages, baseMessageCount, pendingToolCalls, }: {
|
|
1663
|
+
approvals: ApprovalEventItem[];
|
|
1664
|
+
runId: string;
|
|
1665
|
+
checkpointMessages: Message[];
|
|
1666
|
+
baseMessageCount: number;
|
|
1667
|
+
pendingToolCalls: PendingToolCall[];
|
|
1668
|
+
}) => NonNullable<Conversation["pendingApprovals"]>;
|
|
1669
|
+
declare const applyTurnMetadata: (conv: Conversation, meta: TurnResultMetadata, opts?: {
|
|
1670
|
+
clearContinuation?: boolean;
|
|
1671
|
+
clearApprovals?: boolean;
|
|
1672
|
+
setIdle?: boolean;
|
|
1673
|
+
shouldRebuildCanonical?: boolean;
|
|
1674
|
+
}) => void;
|
|
1675
|
+
|
|
1676
|
+
declare const TOOL_RESULT_ARCHIVE_PARAM = "__toolResultArchive";
|
|
1677
|
+
declare const withToolResultArchiveParam: (parameters: Record<string, unknown> | undefined, conversation: Conversation) => Record<string, unknown>;
|
|
1678
|
+
declare const MAX_CONTINUATION_COUNT = 20;
|
|
1679
|
+
|
|
1680
|
+
type ActiveSubagentRun = {
|
|
1681
|
+
abortController: AbortController;
|
|
1682
|
+
harness: AgentHarness;
|
|
1683
|
+
parentConversationId: string;
|
|
1684
|
+
};
|
|
1685
|
+
type PendingSubagentApproval = {
|
|
1686
|
+
resolve: (decidedApprovals: NonNullable<Conversation["pendingApprovals"]>) => void;
|
|
1687
|
+
childHarness: AgentHarness;
|
|
1688
|
+
checkpoint: NonNullable<Conversation["pendingApprovals"]>[number];
|
|
1689
|
+
childConversationId: string;
|
|
1690
|
+
parentConversationId: string;
|
|
1691
|
+
};
|
|
1692
|
+
/** root -> L1 -> L2 = 3 levels; L2 cannot spawn further */
|
|
1693
|
+
declare const MAX_SUBAGENT_NESTING = 3;
|
|
1694
|
+
declare const MAX_CONCURRENT_SUBAGENTS = 2;
|
|
1695
|
+
declare const MAX_SUBAGENT_CALLBACK_COUNT = 20;
|
|
1696
|
+
declare const CALLBACK_LOCK_STALE_MS: number;
|
|
1697
|
+
declare const STALE_SUBAGENT_THRESHOLD_MS: number;
|
|
1698
|
+
|
|
1699
|
+
type ActiveConversationRun = {
|
|
1700
|
+
ownerId: string;
|
|
1701
|
+
abortController: AbortController;
|
|
1702
|
+
runId: string | null;
|
|
1703
|
+
};
|
|
1704
|
+
type EventSink = (conversationId: string, event: AgentEvent) => void | Promise<void>;
|
|
1705
|
+
interface OrchestratorHooks {
|
|
1706
|
+
/** Called before a continuation run starts. Resets/creates event streams. */
|
|
1707
|
+
onContinuationStart?(conversationId: string): void;
|
|
1708
|
+
/** Called after a continuation run finishes. Cleans up event streams. */
|
|
1709
|
+
onContinuationEnd?(conversationId: string): void;
|
|
1710
|
+
/** Called when an approval checkpoint is stored during resumeRunFromCheckpoint.
|
|
1711
|
+
* Transport layer can use this for platform-specific notifications (e.g. Telegram). */
|
|
1712
|
+
onApprovalCheckpoint?(conversationId: string, approvals: Array<{
|
|
1713
|
+
approvalId: string;
|
|
1714
|
+
tool: string;
|
|
1715
|
+
input: Record<string, unknown>;
|
|
1716
|
+
}>): void;
|
|
1717
|
+
/** Called after resumeRunFromCheckpoint completes. Transport layer can check
|
|
1718
|
+
* for pending subagent callbacks and manage stream lifecycle.
|
|
1719
|
+
* @deprecated Orchestrator handles post-resume subagent work internally in Phase 5+. */
|
|
1720
|
+
onResumeComplete?(conversationId: string, checkpointedRun: boolean): void;
|
|
1721
|
+
/** Create a child AgentHarness for subagent execution. Required for subagent support. */
|
|
1722
|
+
createChildHarness?(): Promise<AgentHarness>;
|
|
1723
|
+
/** Build recall parameters injected into run parameters for conversation context. */
|
|
1724
|
+
buildRecallParams?(opts: {
|
|
1725
|
+
ownerId: string;
|
|
1726
|
+
tenantId?: string | null;
|
|
1727
|
+
excludeConversationId: string;
|
|
1728
|
+
}): Record<string, unknown>;
|
|
1729
|
+
/** Dispatch a background task via serverless self-fetch. If not provided,
|
|
1730
|
+
* the orchestrator calls methods directly (long-lived mode). */
|
|
1731
|
+
dispatchBackground?(type: "subagent-run" | "subagent-callback" | "continuation", conversationId: string): void;
|
|
1732
|
+
/** Called when a conversation's event stream should be closed/finished. */
|
|
1733
|
+
onStreamEnd?(conversationId: string): void;
|
|
1734
|
+
/** Called when processSubagentCallback needs to open/reset the parent's event stream. */
|
|
1735
|
+
onCallbackStreamReset?(conversationId: string): void;
|
|
1736
|
+
/** Notify a messaging platform about a subagent callback result. */
|
|
1737
|
+
onMessagingNotify?(conversationId: string, text: string): void;
|
|
1738
|
+
}
|
|
1739
|
+
/** @deprecated Use OrchestratorHooks instead */
|
|
1740
|
+
type ContinuationHooks = OrchestratorHooks;
|
|
1741
|
+
interface OrchestratorOptions {
|
|
1742
|
+
harness: AgentHarness;
|
|
1743
|
+
conversationStore: ConversationStore;
|
|
1744
|
+
eventSink: EventSink;
|
|
1745
|
+
telemetry?: TelemetryEmitter;
|
|
1746
|
+
hooks?: OrchestratorHooks;
|
|
1747
|
+
/** @deprecated Use hooks instead */
|
|
1748
|
+
continuationHooks?: OrchestratorHooks;
|
|
1749
|
+
/** Agent identity ID for tool context. Falls back to harness frontmatter ID. */
|
|
1750
|
+
agentId?: string;
|
|
1751
|
+
/** Working directory for tool context. */
|
|
1752
|
+
workingDir?: string;
|
|
1753
|
+
}
|
|
1754
|
+
declare class AgentOrchestrator {
|
|
1755
|
+
readonly harness: AgentHarness;
|
|
1756
|
+
readonly conversationStore: ConversationStore;
|
|
1757
|
+
readonly eventSink: EventSink;
|
|
1758
|
+
readonly telemetry?: TelemetryEmitter;
|
|
1759
|
+
/** @internal */
|
|
1760
|
+
hooks?: OrchestratorHooks;
|
|
1761
|
+
private readonly agentId;
|
|
1762
|
+
private readonly workingDir;
|
|
1763
|
+
readonly activeConversationRuns: Map<string, ActiveConversationRun>;
|
|
1764
|
+
readonly runOwners: Map<string, string>;
|
|
1765
|
+
readonly runConversations: Map<string, string>;
|
|
1766
|
+
readonly approvalDecisionTracker: Map<string, Map<string, boolean>>;
|
|
1767
|
+
readonly activeSubagentRuns: Map<string, ActiveSubagentRun>;
|
|
1768
|
+
readonly recentlySpawnedParents: Map<string, number>;
|
|
1769
|
+
readonly pendingSubagentApprovals: Map<string, PendingSubagentApproval>;
|
|
1770
|
+
readonly pendingCallbackNeeded: Set<string>;
|
|
1771
|
+
constructor(options: OrchestratorOptions);
|
|
1772
|
+
setHooks(hooks: OrchestratorHooks): void;
|
|
1773
|
+
/** @deprecated Use setHooks instead */
|
|
1774
|
+
setContinuationHooks(hooks: OrchestratorHooks): void;
|
|
1775
|
+
private get isServerless();
|
|
1776
|
+
runContinuation(conversationId: string, onYield?: (event: AgentEvent) => void | Promise<void>): Promise<void>;
|
|
1777
|
+
runChatContinuation(conversationId: string, conversation: Conversation, continuationMessages: Message[], onYield?: (event: AgentEvent) => void | Promise<void>): Promise<void>;
|
|
1778
|
+
findPendingApproval(approvalId: string, owner: string): Promise<{
|
|
1779
|
+
conversation: Conversation;
|
|
1780
|
+
approval: StoredApproval;
|
|
1781
|
+
} | undefined>;
|
|
1782
|
+
resumeRunFromCheckpoint(conversationId: string, conversation: Conversation, checkpoint: StoredApproval, toolResults: Array<{
|
|
1783
|
+
callId: string;
|
|
1784
|
+
toolName: string;
|
|
1785
|
+
result?: unknown;
|
|
1786
|
+
error?: string;
|
|
1787
|
+
}>): Promise<void>;
|
|
1788
|
+
/** After a resume completes, check for deferred subagent callbacks. */
|
|
1789
|
+
private _handlePostResumeWork;
|
|
1790
|
+
hasRunningSubagentsForParent(parentConversationId: string): boolean;
|
|
1791
|
+
getRunningSubagentCountForParent(parentId: string): number;
|
|
1792
|
+
getSubagentDepth(conversationId: string): Promise<number>;
|
|
1793
|
+
hasPendingSubagentWorkForParent(parentConversationId: string, _owner: string): Promise<boolean>;
|
|
1794
|
+
/**
|
|
1795
|
+
* Submit an approval decision for a pending subagent approval.
|
|
1796
|
+
* Returns whether the approval was found, the child conversation, and whether all approvals are now decided.
|
|
1797
|
+
*/
|
|
1798
|
+
submitSubagentApprovalDecision(approvalId: string, approved: boolean): Promise<{
|
|
1799
|
+
found: boolean;
|
|
1800
|
+
childConversationId?: string;
|
|
1801
|
+
allDecided: boolean;
|
|
1802
|
+
}>;
|
|
1803
|
+
handleSubagentCompletion(subagentId: string): Promise<void>;
|
|
1804
|
+
resumeSubagentFromCheckpoint(subagentId: string): Promise<void>;
|
|
1805
|
+
runSubagent(childConversationId: string, parentConversationId: string, task: string, ownerId: string): Promise<void>;
|
|
1806
|
+
triggerParentCallback(parentConversationId: string): Promise<void>;
|
|
1807
|
+
processSubagentCallback(conversationId: string, skipLockCheck?: boolean): Promise<void>;
|
|
1808
|
+
runSubagentContinuation(conversationId: string, conversation: Conversation, continuationMessages: Message[]): AsyncGenerator<AgentEvent>;
|
|
1809
|
+
createSubagentManager(): SubagentManager;
|
|
1810
|
+
recoverStaleSubagents(): Promise<void>;
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
export { type ActiveConversationRun, type ActiveSubagentRun, type AgentFrontmatter, AgentHarness, type AgentIdentity, type AgentLimitsConfig, type AgentModelConfig, AgentOrchestrator, type ApprovalEventItem, type ArchivedToolResult$1 as ArchivedToolResult, type BashConfig, BashEnvironmentManager, type BashExecutionLimits, type BuiltInToolToggles, CALLBACK_LOCK_STALE_MS, type CompactMessagesOptions, type CompactResult, type CompactionConfig, type ContinuationHooks, type Conversation, type ConversationCreateInit, type ConversationState, type ConversationStatusSnapshot, type ConversationStore, type ConversationSummary, type CronJobConfig, type EventSink, type ExecuteTurnResult, type HarnessOptions, type HarnessRunOutput, type HistorySource, InMemoryConversationStore, InMemoryEngine, InMemoryStateStore, type IsolateBinding, type IsolateConfig, LocalMcpBridge, LocalUploadStore, MAX_CONCURRENT_SUBAGENTS, MAX_CONTINUATION_COUNT, MAX_SUBAGENT_CALLBACK_COUNT, MAX_SUBAGENT_NESTING, type MainMemory, type McpConfig, type MemoryConfig, type MemoryStore, type MessagingChannelConfig, type ModelProviderFactory, type NetworkConfig, OPENAI_CODEX_CLIENT_ID, type OpenAICodexAuthConfig, type OpenAICodexDeviceAuthRequest, type OpenAICodexSession, type OrchestratorHooks, type OrchestratorOptions, type OtlpConfig, type OtlpOption, PONCHO_UPLOAD_SCHEME, type ParsedAgent, type PendingSubagentApproval, type PendingSubagentResult, type PendingToolCall, type PonchoConfig, PonchoFsAdapter, PostgresEngine, type ProviderConfig, type Recurrence, type RecurrenceType, type Reminder, type ReminderCreateInput, type ReminderStatus, type ReminderStore, type RemoteMcpServerConfig, type RunOutcome, type RunRequest, type RuntimeRenderContext, S3UploadStore, STALE_SUBAGENT_THRESHOLD_MS, STORAGE_SCHEMA_VERSION, type SecretsStore, type SkillContextEntry, type SkillMetadata, SqliteEngine, type StateConfig, type StateProviderName, type StateStore, type StorageConfig, type StorageEngine, type StorageFactoryOptions, type StorageProvider, type StoredApproval, type SubagentManager, type SubagentResult, type SubagentSpawnResult, type SubagentSummary, TOOL_RESULT_ARCHIVE_PARAM, type TelemetryConfig, TelemetryEmitter, type TenantTokenPayload, type ToolAccess, type ToolCall, ToolDispatcher, type ToolExecutionResult, type TurnDraftState, type TurnResultMetadata, type TurnSection, type UploadStore, type UploadsConfig, VFS_SCHEME, VercelBlobUploadStore, type VfsDirEntry, type VfsStat, applyTurnMetadata, buildAgentDirectoryName, buildApprovalCheckpoints, buildAssistantMetadata, buildSkillContextWindow, buildToolCompletedText, cloneSections, compactMessages, completeOpenAICodexDeviceAuth, computeNextOccurrence, createBashTool, createConversationStore, createConversationStoreFromEngine, createDefaultTools, createDeleteDirectoryTool, createDeleteTool, createEditTool, createMemoryStore, createMemoryStoreFromEngine, createMemoryTools, createModelProvider, createReminderStore, createReminderStoreFromEngine, createReminderTools, createSearchTools, createSecretsStore, createSkillTools, createStateStore, createStorageEngine, createSubagentTools, createTodoStoreFromEngine, createTurnDraftState, createUploadStore, createWriteTool, deleteOpenAICodexSession, deriveUploadKey, ensureAgentIdentity, estimateTokens, estimateTotalTokens, executeConversationTurn, findSafeSplitPoint, flushTurnDraft, generateAgentId, getAgentStoreDirectory, getModelContextWindow, getOpenAICodexAccessToken, getOpenAICodexAuthFilePath, getOpenAICodexRequiredScopes, getPonchoStoreRoot, isMessageArray, jsonSchemaToZod, loadCanonicalHistory, loadPonchoConfig, loadRunHistory, loadSkillContext, loadSkillInstructions, loadSkillMetadata, normalizeApprovalCheckpoint, normalizeOtlp, normalizeScriptPolicyPath, parseAgentFile, parseAgentMarkdown, ponchoDocsTool, readOpenAICodexSession, readSkillResource, recordStandardTurnEvent, renderAgentPrompt, resolveAgentIdentity, resolveCompactionConfig, resolveEnv, resolveMemoryConfig, resolveRunRequest, resolveSkillDirs, resolveStateConfig, slugifyStorageComponent, startOpenAICodexDeviceAuth, verifyTenantToken, withToolResultArchiveParam, writeOpenAICodexSession };
|