@poncho-ai/harness 0.35.0 → 0.36.1

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.
Files changed (49) hide show
  1. package/.turbo/turbo-build.log +12 -11
  2. package/CHANGELOG.md +25 -0
  3. package/dist/index.d.ts +485 -29
  4. package/dist/index.js +2839 -2114
  5. package/dist/isolate-TCWTUVG4.js +1532 -0
  6. package/package.json +23 -4
  7. package/scripts/migrate-to-engine.mjs +556 -0
  8. package/src/config.ts +106 -1
  9. package/src/harness.ts +226 -91
  10. package/src/index.ts +5 -0
  11. package/src/isolate/bindings.ts +206 -0
  12. package/src/isolate/bundler.ts +179 -0
  13. package/src/isolate/index.ts +10 -0
  14. package/src/isolate/polyfills.ts +796 -0
  15. package/src/isolate/run-code-tool.ts +220 -0
  16. package/src/isolate/runtime.ts +286 -0
  17. package/src/isolate/type-stubs.ts +196 -0
  18. package/src/memory.ts +129 -198
  19. package/src/reminder-store.ts +3 -237
  20. package/src/secrets-store.ts +2 -91
  21. package/src/state.ts +11 -1302
  22. package/src/storage/engine.ts +106 -0
  23. package/src/storage/index.ts +59 -0
  24. package/src/storage/memory-engine.ts +588 -0
  25. package/src/storage/postgres-engine.ts +139 -0
  26. package/src/storage/schema.ts +145 -0
  27. package/src/storage/sql-dialect.ts +963 -0
  28. package/src/storage/sqlite-engine.ts +99 -0
  29. package/src/storage/store-adapters.ts +100 -0
  30. package/src/todo-tools.ts +1 -136
  31. package/src/upload-store.ts +1 -0
  32. package/src/vfs/bash-manager.ts +120 -0
  33. package/src/vfs/bash-tool.ts +59 -0
  34. package/src/vfs/create-bash-fs.ts +32 -0
  35. package/src/vfs/edit-file-tool.ts +72 -0
  36. package/src/vfs/index.ts +5 -0
  37. package/src/vfs/poncho-fs-adapter.ts +267 -0
  38. package/src/vfs/protected-fs.ts +177 -0
  39. package/src/vfs/read-file-tool.ts +103 -0
  40. package/src/vfs/write-file-tool.ts +49 -0
  41. package/test/harness.test.ts +30 -36
  42. package/test/isolate-vfs.test.ts +453 -0
  43. package/test/isolate.test.ts +252 -0
  44. package/test/state.test.ts +4 -27
  45. package/test/storage-engine.test.ts +250 -0
  46. package/test/vfs.test.ts +242 -0
  47. package/.turbo/turbo-lint.log +0 -6
  48. package/.turbo/turbo-test.log +0 -11931
  49. package/src/kv-store.ts +0 -216
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { LanguageModel } from 'ai';
2
2
  import * as _poncho_ai_sdk from '@poncho-ai/sdk';
3
- import { Message, ToolContext, ToolDefinition, RunResult, AgentFailure, RunInput, AgentEvent, JsonSchema } from '@poncho-ai/sdk';
3
+ import { Message, ToolContext, ToolDefinition, JsonSchema, RunResult, AgentFailure, RunInput, AgentEvent } from '@poncho-ai/sdk';
4
4
  export { ToolDefinition, defineTool } from '@poncho-ai/sdk';
5
5
  import { z } from 'zod';
6
+ import { IFileSystem, BufferEncoding, FsStat, FileContent, MkdirOptions, RmOptions, CpOptions, Bash } from 'just-bash';
6
7
 
7
8
  interface AgentModelConfig {
8
9
  provider: string;
@@ -188,30 +189,14 @@ interface Conversation {
188
189
  subagentCallbackCount?: number;
189
190
  runningCallbackSince?: number;
190
191
  lastActivityAt?: number;
191
- /** Harness-internal message chain preserved across continuation runs.
192
- * Cleared when a run completes without continuation. */
193
192
  _continuationMessages?: Message[];
194
- /** Number of continuation pickups for the current multi-step run.
195
- * Reset when a run completes without continuation. Used to enforce
196
- * a maximum continuation count across all entry points. */
197
193
  _continuationCount?: number;
198
- /** Full structured message chain from the last harness run, including
199
- * tool-call and tool-result messages the model needs for context.
200
- * Unlike `_continuationMessages`, this is always set after a run
201
- * and does NOT signal that a continuation is pending. */
202
194
  _harnessMessages?: Message[];
203
- /** Archived full-fidelity tool results keyed by toolResultId. */
204
195
  _toolResultArchive?: Record<string, ArchivedToolResult$1>;
205
196
  createdAt: number;
206
197
  updatedAt: number;
207
198
  }
208
199
  interface ConversationStore {
209
- /**
210
- * List conversations. tenantId semantics:
211
- * undefined = no filter (builder/admin sees everything)
212
- * null = legacy single-user only
213
- * string = tenant-scoped
214
- */
215
200
  list(ownerId?: string, tenantId?: string | null): Promise<Conversation[]>;
216
201
  listSummaries(ownerId?: string, tenantId?: string | null): Promise<ConversationSummary[]>;
217
202
  get(conversationId: string): Promise<Conversation | undefined>;
@@ -220,14 +205,9 @@ interface ConversationStore {
220
205
  rename(conversationId: string, title: string): Promise<Conversation | undefined>;
221
206
  delete(conversationId: string): Promise<boolean>;
222
207
  appendSubagentResult(conversationId: string, result: PendingSubagentResult): Promise<void>;
223
- /**
224
- * Atomically clear `runningCallbackSince` without clobbering other fields.
225
- * Returns the conversation as it exists after the clear (with current
226
- * `pendingSubagentResults`).
227
- */
228
208
  clearCallbackLock(conversationId: string): Promise<Conversation | undefined>;
229
209
  }
230
- type StateProviderName = "local" | "memory" | "redis" | "upstash" | "dynamodb";
210
+ type StateProviderName = "local" | "memory" | "sqlite" | "postgresql" | "redis" | "upstash" | "dynamodb";
231
211
  interface StateConfig {
232
212
  provider?: StateProviderName;
233
213
  ttl?: number;
@@ -277,11 +257,11 @@ type ConversationSummary = {
277
257
  platformThreadId: string;
278
258
  };
279
259
  };
280
- declare const createStateStore: (config?: StateConfig, options?: {
260
+ declare const createStateStore: (config?: StateConfig, _options?: {
281
261
  workingDir?: string;
282
262
  agentId?: string;
283
263
  }) => StateStore;
284
- declare const createConversationStore: (config?: StateConfig, options?: {
264
+ declare const createConversationStore: (config?: StateConfig, _options?: {
285
265
  workingDir?: string;
286
266
  agentId?: string;
287
267
  }) => ConversationStore;
@@ -376,7 +356,7 @@ declare class LocalMcpBridge {
376
356
  }
377
357
 
378
358
  interface StorageConfig {
379
- provider?: "local" | "memory" | "redis" | "upstash" | "dynamodb";
359
+ provider?: "local" | "memory" | "sqlite" | "postgresql" | "redis" | "upstash" | "dynamodb";
380
360
  urlEnv?: string;
381
361
  tokenEnv?: string;
382
362
  table?: string;
@@ -389,6 +369,10 @@ interface StorageConfig {
389
369
  enabled?: boolean;
390
370
  maxRecallConversations?: number;
391
371
  };
372
+ limits?: {
373
+ maxFileSize?: number;
374
+ maxTotalStorage?: number;
375
+ };
392
376
  }
393
377
  interface UploadsConfig {
394
378
  provider?: "local" | "vercel-blob" | "s3";
@@ -428,6 +412,99 @@ interface MessagingChannelConfig {
428
412
  maxSendsPerRun?: number;
429
413
  allowedUserIds?: number[];
430
414
  }
415
+ interface IsolateBinding {
416
+ description: string;
417
+ inputSchema: JsonSchema;
418
+ handler: (input: Record<string, unknown>) => Promise<unknown> | unknown;
419
+ }
420
+ /**
421
+ * Network access configuration for the bash sandbox (curl, wget).
422
+ * Network access is disabled by default — you must explicitly allow URLs.
423
+ */
424
+ interface NetworkConfig {
425
+ /**
426
+ * List of allowed URL prefixes. Each entry must be a full origin (scheme + host),
427
+ * optionally followed by a path prefix.
428
+ *
429
+ * Examples:
430
+ * - `"https://api.example.com"` — allows all paths on this origin
431
+ * - `"https://api.example.com/v1/"` — allows only paths starting with /v1/
432
+ *
433
+ * Entries can be plain strings or objects with header transforms for credentials brokering:
434
+ * ```
435
+ * { url: "https://api.example.com", transform: [{ headers: { "Authorization": "Bearer ..." } }] }
436
+ * ```
437
+ */
438
+ allowedUrls?: (string | {
439
+ url: string;
440
+ transform?: {
441
+ headers: Record<string, string>;
442
+ }[];
443
+ })[];
444
+ /** Allowed HTTP methods. Defaults to `["GET", "HEAD"]`. */
445
+ allowedMethods?: ("GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS")[];
446
+ /** Bypass the allow-list and permit all URLs and methods. Only use in trusted environments. */
447
+ dangerouslyAllowAll?: boolean;
448
+ /** Maximum number of redirects to follow. Default: 20. */
449
+ maxRedirects?: number;
450
+ /** Request timeout in milliseconds. Default: 30000. */
451
+ timeoutMs?: number;
452
+ /** Maximum response body size in bytes. Default: 10MB. */
453
+ maxResponseSize?: number;
454
+ /** Reject URLs resolving to private/loopback IPs (SSRF protection). Default: false. */
455
+ denyPrivateRanges?: boolean;
456
+ }
457
+ interface BashExecutionLimits {
458
+ /** Maximum function call/recursion depth. Default: 100. */
459
+ maxCallDepth?: number;
460
+ /** Maximum number of commands to execute. Default: 10000. */
461
+ maxCommandCount?: number;
462
+ /** Maximum loop iterations for while/for/until. Default: 10000. */
463
+ maxLoopIterations?: number;
464
+ /** Maximum total output size (stdout + stderr) in bytes. Default: 10MB. */
465
+ maxOutputSize?: number;
466
+ /** Maximum string length in bytes. Default: 10MB. */
467
+ maxStringLength?: number;
468
+ /** Maximum array elements. Default: 100000. */
469
+ maxArrayElements?: number;
470
+ }
471
+ interface BashConfig {
472
+ /**
473
+ * Whitelist of allowed commands. When set, only these commands are available.
474
+ * Omit to allow all built-in commands.
475
+ *
476
+ * @example ["cat", "grep", "jq", "echo", "ls", "head", "tail", "wc", "sort"]
477
+ */
478
+ commands?: string[];
479
+ /** Execution limits to prevent runaway scripts. */
480
+ executionLimits?: BashExecutionLimits;
481
+ /** Enable python3/python commands in the sandbox. Default: false. */
482
+ python?: boolean;
483
+ /** Enable js-exec/node commands via QuickJS in the sandbox. Default: false. */
484
+ javascript?: boolean;
485
+ /** Environment variables injected into every bash session. */
486
+ env?: Record<string, string>;
487
+ }
488
+ interface IsolateConfig {
489
+ /** V8 isolate memory limit in MB. Default: 128 */
490
+ memoryLimit?: number;
491
+ /** Execution timeout in ms. Default: 10000 */
492
+ timeLimit?: number;
493
+ /** Max combined stdout+stderr in bytes. Default: 65536 */
494
+ outputLimit?: number;
495
+ /** Max code input size in bytes. Default: 102400 (100KB) */
496
+ codeLimit?: number;
497
+ /** npm packages to bundle and make available via require() */
498
+ libraries?: string[];
499
+ /** External API access */
500
+ apis?: {
501
+ fetch?: {
502
+ allowedDomains: string[];
503
+ };
504
+ };
505
+ /** Builder-defined custom bindings injected into the isolate */
506
+ bindings?: Record<string, IsolateBinding>;
507
+ }
431
508
  interface PonchoConfig extends McpConfig {
432
509
  harness?: string;
433
510
  messaging?: MessagingChannelConfig[];
@@ -502,6 +579,15 @@ interface PonchoConfig extends McpConfig {
502
579
  tenantSecrets?: Record<string, string>;
503
580
  /** Set to `false` to disable the built-in web UI (headless / API-only mode). */
504
581
  webUi?: false;
582
+ /** Enable sandboxed V8 isolate code execution. */
583
+ isolate?: IsolateConfig;
584
+ /**
585
+ * Network access for sandboxed tools (bash curl/wget, isolate fetch).
586
+ * Disabled by default — you must explicitly allow URLs.
587
+ */
588
+ network?: NetworkConfig;
589
+ /** Bash sandbox configuration. */
590
+ bash?: BashConfig;
505
591
  /** Enable browser automation tools. Set `true` for defaults, or provide config. */
506
592
  browser?: boolean | {
507
593
  viewport?: {
@@ -539,6 +625,7 @@ declare const createDeleteDirectoryTool: (workingDir: string) => ToolDefinition;
539
625
  declare const ponchoDocsTool: ToolDefinition;
540
626
 
541
627
  declare const PONCHO_UPLOAD_SCHEME = "poncho-upload://";
628
+ declare const VFS_SCHEME = "vfs://";
542
629
  interface UploadStore {
543
630
  put(key: string, data: Buffer, mediaType: string): Promise<string>;
544
631
  get(urlOrKey: string): Promise<Buffer>;
@@ -589,6 +676,10 @@ interface TodoItem {
589
676
  createdAt: number;
590
677
  updatedAt: number;
591
678
  }
679
+ interface TodoStore {
680
+ get(conversationId: string): Promise<TodoItem[]>;
681
+ set(conversationId: string, todos: TodoItem[]): Promise<void>;
682
+ }
592
683
 
593
684
  type ReminderStatus = "pending" | "fired" | "cancelled";
594
685
  interface Reminder {
@@ -615,17 +706,90 @@ interface ReminderStore {
615
706
  cancel(id: string): Promise<Reminder>;
616
707
  delete(id: string): Promise<void>;
617
708
  }
618
- declare const createReminderStore: (agentId: string, config?: StateConfig, options?: {
709
+ declare const createReminderStore: (_agentId: string, _config?: StateConfig, _options?: {
619
710
  workingDir?: string;
620
711
  }) => ReminderStore;
621
712
 
713
+ interface VfsStat {
714
+ type: "file" | "directory" | "symlink";
715
+ size: number;
716
+ mode: number;
717
+ mimeType?: string;
718
+ symlinkTarget?: string;
719
+ createdAt: number;
720
+ updatedAt: number;
721
+ }
722
+ interface VfsDirEntry {
723
+ name: string;
724
+ type: "file" | "directory" | "symlink";
725
+ }
726
+ interface StorageEngine {
727
+ /** Run migrations and prepare the storage backend. */
728
+ initialize(): Promise<void>;
729
+ /** Gracefully release resources. */
730
+ close(): Promise<void>;
731
+ conversations: {
732
+ list(ownerId?: string, tenantId?: string | null): Promise<ConversationSummary[]>;
733
+ get(conversationId: string): Promise<Conversation | undefined>;
734
+ create(ownerId?: string, title?: string, tenantId?: string | null): Promise<Conversation>;
735
+ update(conversation: Conversation): Promise<void>;
736
+ rename(conversationId: string, title: string): Promise<Conversation | undefined>;
737
+ delete(conversationId: string): Promise<boolean>;
738
+ search(query: string, tenantId?: string | null): Promise<ConversationSummary[]>;
739
+ appendSubagentResult(conversationId: string, result: PendingSubagentResult): Promise<void>;
740
+ clearCallbackLock(conversationId: string): Promise<Conversation | undefined>;
741
+ };
742
+ memory: {
743
+ get(tenantId?: string | null): Promise<MainMemory>;
744
+ update(content: string, tenantId?: string | null): Promise<MainMemory>;
745
+ };
746
+ todos: {
747
+ get(conversationId: string): Promise<TodoItem[]>;
748
+ set(conversationId: string, todos: TodoItem[]): Promise<void>;
749
+ };
750
+ reminders: {
751
+ list(tenantId?: string | null): Promise<Reminder[]>;
752
+ create(input: {
753
+ task: string;
754
+ scheduledAt: number;
755
+ timezone?: string;
756
+ conversationId: string;
757
+ ownerId?: string;
758
+ tenantId?: string | null;
759
+ }): Promise<Reminder>;
760
+ cancel(id: string): Promise<Reminder>;
761
+ delete(id: string): Promise<void>;
762
+ };
763
+ vfs: {
764
+ readFile(tenantId: string, path: string): Promise<Uint8Array>;
765
+ writeFile(tenantId: string, path: string, content: Uint8Array, mimeType?: string): Promise<void>;
766
+ appendFile(tenantId: string, path: string, content: Uint8Array): Promise<void>;
767
+ deleteFile(tenantId: string, path: string): Promise<void>;
768
+ deleteDir(tenantId: string, path: string, recursive?: boolean): Promise<void>;
769
+ stat(tenantId: string, path: string): Promise<VfsStat | undefined>;
770
+ readdir(tenantId: string, path: string): Promise<VfsDirEntry[]>;
771
+ mkdir(tenantId: string, path: string, recursive?: boolean): Promise<void>;
772
+ rename(tenantId: string, oldPath: string, newPath: string): Promise<void>;
773
+ chmod(tenantId: string, path: string, mode: number): Promise<void>;
774
+ utimes(tenantId: string, path: string, mtime: Date): Promise<void>;
775
+ symlink(tenantId: string, target: string, linkPath: string): Promise<void>;
776
+ readlink(tenantId: string, path: string): Promise<string>;
777
+ lstat(tenantId: string, path: string): Promise<VfsStat | undefined>;
778
+ listAllPaths(tenantId: string): string[];
779
+ getUsage(tenantId: string): Promise<{
780
+ fileCount: number;
781
+ totalBytes: number;
782
+ }>;
783
+ };
784
+ }
785
+
622
786
  interface SecretsStore {
623
787
  get(tenantId: string): Promise<Record<string, string>>;
624
788
  set(tenantId: string, key: string, value: string): Promise<void>;
625
789
  delete(tenantId: string, key: string): Promise<void>;
626
790
  list(tenantId: string): Promise<string[]>;
627
791
  }
628
- declare const createSecretsStore: (agentId: string, signingKey: string, config?: StateConfig, options?: {
792
+ declare const createSecretsStore: (_agentId: string, signingKey: string, _config?: StateConfig, options?: {
629
793
  workingDir?: string;
630
794
  }) => SecretsStore;
631
795
  /**
@@ -791,6 +955,10 @@ declare class AgentHarness {
791
955
  private mcpBridge?;
792
956
  private subagentManager?;
793
957
  private readonly archivedToolResultsByConversation;
958
+ /** Unified storage engine (replaces individual KV-backed stores). */
959
+ storageEngine?: StorageEngine;
960
+ /** Bash environment manager (creates per-tenant bash instances). */
961
+ private bashManager?;
794
962
  private resolveToolAccess;
795
963
  private isToolEnabled;
796
964
  private registerIfMissing;
@@ -804,6 +972,7 @@ declare class AgentHarness {
804
972
  setSubagentManager(manager: SubagentManager): void;
805
973
  private registerConfiguredBuiltInTools;
806
974
  private createGetToolResultByIdTool;
975
+ private createVfsAccess;
807
976
  private shouldEnableWriteTool;
808
977
  constructor(options?: HarnessOptions);
809
978
  get frontmatter(): AgentFrontmatter | undefined;
@@ -864,6 +1033,10 @@ declare class AgentHarness {
864
1033
  get browserSession(): unknown;
865
1034
  shutdown(): Promise<void>;
866
1035
  listTools(): ToolDefinition[];
1036
+ listSkills(): Array<{
1037
+ name: string;
1038
+ description: string;
1039
+ }>;
867
1040
  /**
868
1041
  * Wraps the run() generator with an OTel root span (invoke_agent) so all
869
1042
  * child spans (LLM calls via AI SDK, tool execution) group under one trace.
@@ -979,6 +1152,289 @@ declare class TelemetryEmitter {
979
1152
  private sendOtlp;
980
1153
  }
981
1154
 
1155
+ declare class InMemoryEngine implements StorageEngine {
1156
+ private readonly agentId;
1157
+ private convs;
1158
+ private mem;
1159
+ private todoData;
1160
+ private reminderData;
1161
+ private vfsData;
1162
+ constructor(agentId: string);
1163
+ initialize(): Promise<void>;
1164
+ close(): Promise<void>;
1165
+ conversations: {
1166
+ list: (ownerId?: string, tenantId?: string | null) => Promise<ConversationSummary[]>;
1167
+ get: (conversationId: string) => Promise<Conversation | undefined>;
1168
+ create: (ownerId?: string, title?: string, tenantId?: string | null) => Promise<Conversation>;
1169
+ update: (conversation: Conversation) => Promise<void>;
1170
+ rename: (conversationId: string, title: string) => Promise<Conversation | undefined>;
1171
+ delete: (conversationId: string) => Promise<boolean>;
1172
+ search: (query: string, tenantId?: string | null) => Promise<ConversationSummary[]>;
1173
+ appendSubagentResult: (conversationId: string, result: PendingSubagentResult) => Promise<void>;
1174
+ clearCallbackLock: (conversationId: string) => Promise<Conversation | undefined>;
1175
+ };
1176
+ memory: {
1177
+ get: (tenantId?: string | null) => Promise<MainMemory>;
1178
+ update: (content: string, tenantId?: string | null) => Promise<MainMemory>;
1179
+ };
1180
+ todos: {
1181
+ get: (conversationId: string) => Promise<TodoItem[]>;
1182
+ set: (conversationId: string, todos: TodoItem[]) => Promise<void>;
1183
+ };
1184
+ reminders: {
1185
+ list: (tenantId?: string | null) => Promise<Reminder[]>;
1186
+ create: (input: {
1187
+ task: string;
1188
+ scheduledAt: number;
1189
+ timezone?: string;
1190
+ conversationId: string;
1191
+ ownerId?: string;
1192
+ tenantId?: string | null;
1193
+ }) => Promise<Reminder>;
1194
+ cancel: (id: string) => Promise<Reminder>;
1195
+ delete: (id: string) => Promise<void>;
1196
+ };
1197
+ vfs: {
1198
+ readFile: (tenantId: string, path: string) => Promise<Uint8Array>;
1199
+ writeFile: (tenantId: string, path: string, content: Uint8Array, mimeType?: string) => Promise<void>;
1200
+ appendFile: (tenantId: string, path: string, content: Uint8Array) => Promise<void>;
1201
+ deleteFile: (tenantId: string, path: string) => Promise<void>;
1202
+ deleteDir: (tenantId: string, path: string, recursive?: boolean) => Promise<void>;
1203
+ stat: (tenantId: string, path: string) => Promise<VfsStat | undefined>;
1204
+ readdir: (tenantId: string, path: string) => Promise<VfsDirEntry[]>;
1205
+ mkdir: (tenantId: string, path: string, recursive?: boolean) => Promise<void>;
1206
+ rename: (tenantId: string, oldPath: string, newPath: string) => Promise<void>;
1207
+ chmod: (tenantId: string, path: string, mode: number) => Promise<void>;
1208
+ utimes: (tenantId: string, path: string, mtime: Date) => Promise<void>;
1209
+ symlink: (tenantId: string, target: string, linkPath: string) => Promise<void>;
1210
+ readlink: (tenantId: string, path: string) => Promise<string>;
1211
+ lstat: (tenantId: string, path: string) => Promise<VfsStat | undefined>;
1212
+ listAllPaths: (tenantId: string) => string[];
1213
+ getUsage: (tenantId: string) => Promise<{
1214
+ fileCount: number;
1215
+ totalBytes: number;
1216
+ }>;
1217
+ };
1218
+ private toSummary;
1219
+ private ensureParentDirs;
1220
+ private mkdirSingle;
1221
+ private resolveSymlink;
1222
+ }
1223
+
1224
+ /** Tag used by migrations to branch on backend. */
1225
+ type DialectTag = "sqlite" | "postgresql";
1226
+
1227
+ interface Dialect {
1228
+ tag: DialectTag;
1229
+ /** Return a positional parameter placeholder. 1-indexed. */
1230
+ param(index: number): string;
1231
+ /** BLOB type name */
1232
+ blob: string;
1233
+ /** JSON type name */
1234
+ json: string;
1235
+ /** Current-timestamp expression */
1236
+ now(): string;
1237
+ /** UPSERT conflict clause for a given PK column list */
1238
+ upsert(pkCols: string[]): string;
1239
+ }
1240
+ interface QueryRow {
1241
+ [key: string]: unknown;
1242
+ }
1243
+ interface QueryExecutor {
1244
+ run(sql: string, params?: unknown[]): Promise<void>;
1245
+ get<T extends QueryRow = QueryRow>(sql: string, params?: unknown[]): Promise<T | undefined>;
1246
+ all<T extends QueryRow = QueryRow>(sql: string, params?: unknown[]): Promise<T[]>;
1247
+ /** Execute raw SQL (for migrations). */
1248
+ exec(sql: string): Promise<void>;
1249
+ /** Run multiple statements in a transaction. */
1250
+ transaction(fn: () => Promise<void>): Promise<void>;
1251
+ }
1252
+ declare abstract class SqlStorageEngine implements StorageEngine {
1253
+ protected readonly dialect: Dialect;
1254
+ protected readonly agentId: string;
1255
+ protected abstract readonly executor: QueryExecutor;
1256
+ constructor(dialect: Dialect, agentId: string);
1257
+ initialize(): Promise<void>;
1258
+ abstract close(): Promise<void>;
1259
+ /** Hook for subclass-specific setup (e.g. WAL mode). */
1260
+ protected onBeforeInit(): Promise<void>;
1261
+ private runMigrations;
1262
+ conversations: {
1263
+ list: (ownerId?: string, tenantId?: string | null) => Promise<ConversationSummary[]>;
1264
+ get: (conversationId: string) => Promise<Conversation | undefined>;
1265
+ create: (ownerId?: string, title?: string, tenantId?: string | null) => Promise<Conversation>;
1266
+ update: (conversation: Conversation) => Promise<void>;
1267
+ rename: (conversationId: string, title: string) => Promise<Conversation | undefined>;
1268
+ delete: (conversationId: string) => Promise<boolean>;
1269
+ search: (query: string, tenantId?: string | null) => Promise<ConversationSummary[]>;
1270
+ appendSubagentResult: (conversationId: string, result: PendingSubagentResult) => Promise<void>;
1271
+ clearCallbackLock: (conversationId: string) => Promise<Conversation | undefined>;
1272
+ };
1273
+ memory: {
1274
+ get: (tenantId?: string | null) => Promise<MainMemory>;
1275
+ update: (content: string, tenantId?: string | null) => Promise<MainMemory>;
1276
+ };
1277
+ todos: {
1278
+ get: (conversationId: string) => Promise<TodoItem[]>;
1279
+ set: (conversationId: string, todos: TodoItem[]) => Promise<void>;
1280
+ };
1281
+ reminders: {
1282
+ list: (tenantId?: string | null) => Promise<Reminder[]>;
1283
+ create: (input: {
1284
+ task: string;
1285
+ scheduledAt: number;
1286
+ timezone?: string;
1287
+ conversationId: string;
1288
+ ownerId?: string;
1289
+ tenantId?: string | null;
1290
+ }) => Promise<Reminder>;
1291
+ cancel: (id: string) => Promise<Reminder>;
1292
+ delete: (id: string) => Promise<void>;
1293
+ };
1294
+ vfs: {
1295
+ readFile: (tenantId: string, path: string) => Promise<Uint8Array>;
1296
+ writeFile: (tenantId: string, path: string, content: Uint8Array, mimeType?: string) => Promise<void>;
1297
+ appendFile: (tenantId: string, path: string, content: Uint8Array) => Promise<void>;
1298
+ deleteFile: (tenantId: string, path: string) => Promise<void>;
1299
+ deleteDir: (tenantId: string, path: string, recursive?: boolean) => Promise<void>;
1300
+ stat: (tenantId: string, path: string) => Promise<VfsStat | undefined>;
1301
+ readdir: (tenantId: string, path: string) => Promise<VfsDirEntry[]>;
1302
+ mkdir: (tenantId: string, path: string, recursive?: boolean) => Promise<void>;
1303
+ rename: (tenantId: string, oldPath: string, newPath: string) => Promise<void>;
1304
+ chmod: (tenantId: string, path: string, mode: number) => Promise<void>;
1305
+ utimes: (tenantId: string, path: string, mtime: Date) => Promise<void>;
1306
+ symlink: (tenantId: string, target: string, linkPath: string) => Promise<void>;
1307
+ readlink: (tenantId: string, path: string) => Promise<string>;
1308
+ lstat: (tenantId: string, path: string) => Promise<VfsStat | undefined>;
1309
+ listAllPaths: (_tenantId: string) => string[];
1310
+ getUsage: (tenantId: string) => Promise<{
1311
+ fileCount: number;
1312
+ totalBytes: number;
1313
+ }>;
1314
+ };
1315
+ private parseConversation;
1316
+ private rowToSummary;
1317
+ private rowToReminder;
1318
+ protected toUint8Array(value: unknown): Uint8Array;
1319
+ private ensureParentDirs;
1320
+ private mkdirSingle;
1321
+ private resolveSymlink;
1322
+ }
1323
+
1324
+ declare class SqliteEngine extends SqlStorageEngine {
1325
+ private db;
1326
+ private readonly dbPath;
1327
+ protected readonly executor: QueryExecutor;
1328
+ constructor(options: {
1329
+ workingDir: string;
1330
+ agentId: string;
1331
+ dbPath?: string;
1332
+ });
1333
+ protected onBeforeInit(): Promise<void>;
1334
+ initialize(): Promise<void>;
1335
+ close(): Promise<void>;
1336
+ }
1337
+
1338
+ declare class PostgresEngine extends SqlStorageEngine {
1339
+ private sql;
1340
+ private readonly urlEnv;
1341
+ protected readonly executor: QueryExecutor;
1342
+ /** In-memory path cache per tenant for sync getAllPaths(). */
1343
+ private pathCache;
1344
+ constructor(options: {
1345
+ agentId: string;
1346
+ urlEnv?: string;
1347
+ });
1348
+ protected onBeforeInit(): Promise<void>;
1349
+ initialize(): Promise<void>;
1350
+ close(): Promise<void>;
1351
+ /** Refresh the path cache for a tenant (call before bash.exec()). */
1352
+ refreshPathCache(tenantId: string): Promise<void>;
1353
+ private patchVfs;
1354
+ private query;
1355
+ private addToPathCache;
1356
+ private removeFromPathCache;
1357
+ }
1358
+
1359
+ type StorageProvider = "memory" | "sqlite" | "postgresql" | "local";
1360
+ interface StorageFactoryOptions {
1361
+ provider?: StorageProvider;
1362
+ workingDir: string;
1363
+ agentId: string;
1364
+ /** Env var name for the PostgreSQL connection URL (default: DATABASE_URL). */
1365
+ urlEnv?: string;
1366
+ /** Override the SQLite database file path. */
1367
+ dbPath?: string;
1368
+ }
1369
+ declare function createStorageEngine(options: StorageFactoryOptions): StorageEngine;
1370
+
1371
+ declare function createConversationStoreFromEngine(engine: StorageEngine): ConversationStore;
1372
+ declare function createMemoryStoreFromEngine(engine: StorageEngine, tenantId?: string | null): MemoryStore;
1373
+ declare function createTodoStoreFromEngine(engine: StorageEngine): TodoStore;
1374
+ declare function createReminderStoreFromEngine(engine: StorageEngine): ReminderStore;
1375
+
1376
+ declare class PonchoFsAdapter implements IFileSystem {
1377
+ private engine;
1378
+ private tenantId;
1379
+ private limits;
1380
+ constructor(engine: StorageEngine, tenantId: string, limits: {
1381
+ maxFileSize: number;
1382
+ maxTotalStorage: number;
1383
+ });
1384
+ readFile(path: string, _options?: {
1385
+ encoding?: BufferEncoding | null;
1386
+ } | BufferEncoding): Promise<string>;
1387
+ readFileBuffer(path: string): Promise<Uint8Array>;
1388
+ exists(path: string): Promise<boolean>;
1389
+ stat(path: string): Promise<FsStat>;
1390
+ readdir(path: string): Promise<string[]>;
1391
+ readdirWithFileTypes(path: string): Promise<Array<{
1392
+ name: string;
1393
+ isFile: boolean;
1394
+ isDirectory: boolean;
1395
+ isSymbolicLink: boolean;
1396
+ }>>;
1397
+ writeFile(path: string, content: FileContent, _options?: {
1398
+ encoding?: BufferEncoding;
1399
+ } | BufferEncoding): Promise<void>;
1400
+ appendFile(path: string, content: FileContent, _options?: {
1401
+ encoding?: BufferEncoding;
1402
+ } | BufferEncoding): Promise<void>;
1403
+ mkdir(path: string, options?: MkdirOptions): Promise<void>;
1404
+ rm(path: string, options?: RmOptions): Promise<void>;
1405
+ cp(src: string, dest: string, options?: CpOptions): Promise<void>;
1406
+ mv(src: string, dest: string): Promise<void>;
1407
+ resolvePath(base: string, path: string): string;
1408
+ realpath(path: string): Promise<string>;
1409
+ getAllPaths(): string[];
1410
+ chmod(path: string, mode: number): Promise<void>;
1411
+ utimes(path: string, _atime: Date, mtime: Date): Promise<void>;
1412
+ symlink(target: string, linkPath: string): Promise<void>;
1413
+ link(existingPath: string, newPath: string): Promise<void>;
1414
+ readlink(path: string): Promise<string>;
1415
+ lstat(path: string): Promise<FsStat>;
1416
+ }
1417
+
1418
+ declare class BashEnvironmentManager {
1419
+ private engine;
1420
+ private limits;
1421
+ private environments;
1422
+ private readonly workingDir;
1423
+ private readonly bashOptions;
1424
+ constructor(engine: StorageEngine, limits: {
1425
+ maxFileSize: number;
1426
+ maxTotalStorage: number;
1427
+ }, workingDir: string | null, bashConfig?: BashConfig, network?: NetworkConfig);
1428
+ getOrCreate(tenantId: string): Bash;
1429
+ getAdapter(tenantId: string): PonchoFsAdapter;
1430
+ /** Refresh the PostgreSQL path cache before a bash.exec() call. */
1431
+ refreshPathCache(tenantId: string): Promise<void>;
1432
+ destroy(tenantId: string): void;
1433
+ destroyAll(): void;
1434
+ }
1435
+
1436
+ declare const createBashTool: (bashManager: BashEnvironmentManager) => ToolDefinition;
1437
+
982
1438
  interface TenantTokenPayload {
983
1439
  tenantId: string;
984
1440
  metadata?: Record<string, unknown>;
@@ -991,4 +1447,4 @@ declare function verifyTenantToken(signingKey: string, token: string): Promise<T
991
1447
 
992
1448
  declare const createSubagentTools: (manager: SubagentManager) => ToolDefinition[];
993
1449
 
994
- export { type AgentFrontmatter, AgentHarness, type AgentIdentity, type AgentLimitsConfig, type AgentModelConfig, type ArchivedToolResult$1 as ArchivedToolResult, type BuiltInToolToggles, type CompactMessagesOptions, type CompactResult, type CompactionConfig, type Conversation, type ConversationState, type ConversationStore, type ConversationSummary, type CronJobConfig, type HarnessOptions, type HarnessRunOutput, InMemoryConversationStore, InMemoryStateStore, LocalMcpBridge, LocalUploadStore, type MainMemory, type McpConfig, type MemoryConfig, type MemoryStore, type MessagingChannelConfig, type ModelProviderFactory, OPENAI_CODEX_CLIENT_ID, type OpenAICodexAuthConfig, type OpenAICodexDeviceAuthRequest, type OpenAICodexSession, type OtlpConfig, type OtlpOption, PONCHO_UPLOAD_SCHEME, type ParsedAgent, type PendingSubagentResult, type PonchoConfig, type ProviderConfig, type Reminder, type ReminderStatus, type ReminderStore, type RemoteMcpServerConfig, type RuntimeRenderContext, S3UploadStore, STORAGE_SCHEMA_VERSION, type SecretsStore, type SkillContextEntry, type SkillMetadata, type StateConfig, type StateProviderName, type StateStore, type StorageConfig, type SubagentManager, type SubagentResult, type SubagentSpawnResult, type SubagentSummary, type TelemetryConfig, TelemetryEmitter, type TenantTokenPayload, type ToolAccess, type ToolCall, ToolDispatcher, type ToolExecutionResult, type UploadStore, type UploadsConfig, VercelBlobUploadStore, buildAgentDirectoryName, buildSkillContextWindow, compactMessages, completeOpenAICodexDeviceAuth, createConversationStore, createDefaultTools, createDeleteDirectoryTool, createDeleteTool, createEditTool, createMemoryStore, createMemoryTools, createModelProvider, createReminderStore, createReminderTools, createSearchTools, createSecretsStore, createSkillTools, createStateStore, createSubagentTools, createUploadStore, createWriteTool, deleteOpenAICodexSession, deriveUploadKey, ensureAgentIdentity, estimateTokens, estimateTotalTokens, findSafeSplitPoint, generateAgentId, getAgentStoreDirectory, getModelContextWindow, getOpenAICodexAccessToken, getOpenAICodexAuthFilePath, getOpenAICodexRequiredScopes, getPonchoStoreRoot, jsonSchemaToZod, loadPonchoConfig, loadSkillContext, loadSkillInstructions, loadSkillMetadata, normalizeOtlp, normalizeScriptPolicyPath, parseAgentFile, parseAgentMarkdown, ponchoDocsTool, readOpenAICodexSession, readSkillResource, renderAgentPrompt, resolveAgentIdentity, resolveCompactionConfig, resolveEnv, resolveMemoryConfig, resolveSkillDirs, resolveStateConfig, slugifyStorageComponent, startOpenAICodexDeviceAuth, verifyTenantToken, writeOpenAICodexSession };
1450
+ export { type AgentFrontmatter, AgentHarness, type AgentIdentity, type AgentLimitsConfig, type AgentModelConfig, type ArchivedToolResult$1 as ArchivedToolResult, type BashConfig, BashEnvironmentManager, type BashExecutionLimits, type BuiltInToolToggles, type CompactMessagesOptions, type CompactResult, type CompactionConfig, type Conversation, type ConversationState, type ConversationStore, type ConversationSummary, type CronJobConfig, type HarnessOptions, type HarnessRunOutput, InMemoryConversationStore, InMemoryEngine, InMemoryStateStore, type IsolateBinding, type IsolateConfig, LocalMcpBridge, LocalUploadStore, 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 OtlpConfig, type OtlpOption, PONCHO_UPLOAD_SCHEME, type ParsedAgent, type PendingSubagentResult, type PonchoConfig, PonchoFsAdapter, PostgresEngine, type ProviderConfig, type Reminder, type ReminderStatus, type ReminderStore, type RemoteMcpServerConfig, type RuntimeRenderContext, S3UploadStore, 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 SubagentManager, type SubagentResult, type SubagentSpawnResult, type SubagentSummary, type TelemetryConfig, TelemetryEmitter, type TenantTokenPayload, type ToolAccess, type ToolCall, ToolDispatcher, type ToolExecutionResult, type UploadStore, type UploadsConfig, VFS_SCHEME, VercelBlobUploadStore, type VfsDirEntry, type VfsStat, buildAgentDirectoryName, buildSkillContextWindow, compactMessages, completeOpenAICodexDeviceAuth, createBashTool, createConversationStore, createConversationStoreFromEngine, createDefaultTools, createDeleteDirectoryTool, createDeleteTool, createEditTool, createMemoryStore, createMemoryStoreFromEngine, createMemoryTools, createModelProvider, createReminderStore, createReminderStoreFromEngine, createReminderTools, createSearchTools, createSecretsStore, createSkillTools, createStateStore, createStorageEngine, createSubagentTools, createTodoStoreFromEngine, createUploadStore, createWriteTool, deleteOpenAICodexSession, deriveUploadKey, ensureAgentIdentity, estimateTokens, estimateTotalTokens, findSafeSplitPoint, generateAgentId, getAgentStoreDirectory, getModelContextWindow, getOpenAICodexAccessToken, getOpenAICodexAuthFilePath, getOpenAICodexRequiredScopes, getPonchoStoreRoot, jsonSchemaToZod, loadPonchoConfig, loadSkillContext, loadSkillInstructions, loadSkillMetadata, normalizeOtlp, normalizeScriptPolicyPath, parseAgentFile, parseAgentMarkdown, ponchoDocsTool, readOpenAICodexSession, readSkillResource, renderAgentPrompt, resolveAgentIdentity, resolveCompactionConfig, resolveEnv, resolveMemoryConfig, resolveSkillDirs, resolveStateConfig, slugifyStorageComponent, startOpenAICodexDeviceAuth, verifyTenantToken, writeOpenAICodexSession };