@poncho-ai/sdk 1.0.1 → 1.0.2

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @poncho-ai/sdk@1.0.1 build /home/runner/work/poncho-ai/poncho-ai/packages/sdk
2
+ > @poncho-ai/sdk@1.0.2 build /home/runner/work/poncho-ai/poncho-ai/packages/sdk
3
3
  > tsup src/index.ts --format esm --dts
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -7,8 +7,8 @@
7
7
  CLI tsup v8.5.1
8
8
  CLI Target: es2022
9
9
  ESM Build start
10
- ESM dist/index.js 7.48 KB
11
- ESM ⚡️ Build success in 18ms
10
+ ESM dist/index.js 9.72 KB
11
+ ESM ⚡️ Build success in 17ms
12
12
  DTS Build start
13
- DTS ⚡️ Build success in 1173ms
14
- DTS dist/index.d.ts 14.79 KB
13
+ DTS ⚡️ Build success in 1275ms
14
+ DTS dist/index.d.ts 18.25 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @poncho-ai/sdk
2
2
 
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`e000b96`](https://github.com/cesr/poncho-ai/commit/e000b96837cbbb8d95c868c91a614f458868c444) Thanks [@cesr](https://github.com/cesr)! - Durable approval checkpoints, email conversation improvements, and web UI fixes
8
+ - Simplify approval system to checkpoint-only (remove legacy blocking approvalHandler)
9
+ - Optimize checkpoint storage with delta messages instead of full history
10
+ - Add sidebar sections for conversations awaiting approval with status indicator
11
+ - Fix nested checkpoint missing baseMessageCount in resumeRunFromCheckpoint
12
+ - Improve email conversation titles (sender email + subject)
13
+ - Remove email threading — each incoming email creates its own conversation
14
+ - Fix streaming after approval to preserve existing messages (liveOnly mode)
15
+ - Preserve newlines in user messages in web UI
16
+
3
17
  ## 1.0.1
4
18
 
5
19
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -303,6 +303,9 @@ declare const ONBOARDING_FIELDS: readonly [{
303
303
  }, {
304
304
  readonly value: "slack";
305
305
  readonly label: "Slack";
306
+ }, {
307
+ readonly value: "resend";
308
+ readonly label: "Email (Resend)";
306
309
  }];
307
310
  }, {
308
311
  readonly id: "env.SLACK_BOT_TOKEN";
@@ -335,6 +338,89 @@ declare const ONBOARDING_FIELDS: readonly [{
335
338
  readonly fieldId: "messaging.platform";
336
339
  readonly equals: "slack";
337
340
  };
341
+ }, {
342
+ readonly id: "env.RESEND_API_KEY";
343
+ readonly domain: "messaging";
344
+ readonly target: "env";
345
+ readonly path: "RESEND_API_KEY";
346
+ readonly kind: "string";
347
+ readonly scopes: ["full"];
348
+ readonly label: "Resend API Key";
349
+ readonly prompt: "Resend API Key (from resend.com/api-keys)";
350
+ readonly defaultValue: "";
351
+ readonly placeholder: "re_...";
352
+ readonly secret: true;
353
+ readonly dependsOn: {
354
+ readonly fieldId: "messaging.platform";
355
+ readonly equals: "resend";
356
+ };
357
+ }, {
358
+ readonly id: "env.RESEND_WEBHOOK_SECRET";
359
+ readonly domain: "messaging";
360
+ readonly target: "env";
361
+ readonly path: "RESEND_WEBHOOK_SECRET";
362
+ readonly kind: "string";
363
+ readonly scopes: ["full"];
364
+ readonly label: "Resend Webhook Secret";
365
+ readonly prompt: "Resend Webhook Signing Secret (from webhook details page)";
366
+ readonly defaultValue: "";
367
+ readonly placeholder: "whsec_...";
368
+ readonly secret: true;
369
+ readonly dependsOn: {
370
+ readonly fieldId: "messaging.platform";
371
+ readonly equals: "resend";
372
+ };
373
+ }, {
374
+ readonly id: "env.RESEND_FROM";
375
+ readonly domain: "messaging";
376
+ readonly target: "env";
377
+ readonly path: "RESEND_FROM";
378
+ readonly kind: "string";
379
+ readonly scopes: ["full"];
380
+ readonly label: "From Address";
381
+ readonly prompt: "Email address the agent sends from (e.g. Agent <agent@yourdomain.com>)";
382
+ readonly defaultValue: "";
383
+ readonly placeholder: "Agent <agent@yourdomain.com>";
384
+ readonly dependsOn: {
385
+ readonly fieldId: "messaging.platform";
386
+ readonly equals: "resend";
387
+ };
388
+ }, {
389
+ readonly id: "messaging.resend.mode";
390
+ readonly domain: "messaging";
391
+ readonly target: "agent";
392
+ readonly path: "messaging.resend.mode";
393
+ readonly kind: "select";
394
+ readonly scopes: ["full"];
395
+ readonly label: "Email response mode";
396
+ readonly prompt: "How should the agent respond to emails?";
397
+ readonly defaultValue: "auto-reply";
398
+ readonly options: [{
399
+ readonly value: "auto-reply";
400
+ readonly label: "Auto-reply (agent response sent as email reply)";
401
+ }, {
402
+ readonly value: "tool";
403
+ readonly label: "Tool (agent uses send_email tool for full control)";
404
+ }];
405
+ readonly dependsOn: {
406
+ readonly fieldId: "messaging.platform";
407
+ readonly equals: "resend";
408
+ };
409
+ }, {
410
+ readonly id: "messaging.resend.allowedRecipients";
411
+ readonly domain: "messaging";
412
+ readonly target: "agent";
413
+ readonly path: "messaging.resend.allowedRecipients";
414
+ readonly kind: "string";
415
+ readonly scopes: ["full"];
416
+ readonly label: "Allowed recipients";
417
+ readonly prompt: "Allowed recipient patterns for send_email tool (comma-separated, e.g. *@mycompany.com). Leave empty for no restrictions.";
418
+ readonly defaultValue: "";
419
+ readonly placeholder: "*@mycompany.com, partner@external.com";
420
+ readonly dependsOn: {
421
+ readonly fieldId: "messaging.resend.mode";
422
+ readonly equals: "tool";
423
+ };
338
424
  }];
339
425
  declare const FEATURE_DOMAIN_ORDER: readonly FeatureDomain[];
340
426
  declare const fieldsForScope: (scope: OnboardingScope) => OnboardingField[];
@@ -407,11 +493,13 @@ interface FileInput {
407
493
  filename?: string;
408
494
  }
409
495
  interface RunInput {
410
- task: string;
496
+ task?: string;
411
497
  parameters?: Record<string, unknown>;
412
498
  messages?: Message[];
413
499
  files?: FileInput[];
414
500
  abortSignal?: AbortSignal;
501
+ /** When set, Latitude telemetry groups all turns in this conversation under a single trace. */
502
+ conversationId?: string;
415
503
  }
416
504
  interface TokenUsage {
417
505
  input: number;
@@ -436,6 +524,7 @@ type AgentEvent = {
436
524
  type: "run:started";
437
525
  runId: string;
438
526
  agentId: string;
527
+ contextWindow?: number;
439
528
  } | {
440
529
  type: "run:completed";
441
530
  runId: string;
@@ -489,6 +578,18 @@ type AgentEvent = {
489
578
  type: "tool:approval:denied";
490
579
  approvalId: string;
491
580
  reason?: string;
581
+ } | {
582
+ type: "tool:approval:checkpoint";
583
+ approvalId: string;
584
+ tool: string;
585
+ toolCallId: string;
586
+ input: Record<string, unknown>;
587
+ checkpointMessages: Message[];
588
+ pendingToolCalls: Array<{
589
+ id: string;
590
+ name: string;
591
+ input: Record<string, unknown>;
592
+ }>;
492
593
  };
493
594
 
494
595
  export { type AgentEvent, type AgentFailure, type ContentPart, FEATURE_DOMAIN_ORDER, type FeatureDomain, type FileContentPart, type FileInput, type JsonSchema, type Message, ONBOARDING_FIELDS, type OnboardingField, type OnboardingFieldCondition, type OnboardingFieldKind, type OnboardingFieldTarget, type OnboardingOption, type OnboardingScope, type Role, type RunInput, type RunResult, type TextContentPart, type TokenUsage, type ToolContext, type ToolDefinition, type ToolHandler, defineTool, fieldsForScope, getTextContent };
package/dist/index.js CHANGED
@@ -233,7 +233,8 @@ var ONBOARDING_FIELDS = [
233
233
  defaultValue: "none",
234
234
  options: [
235
235
  { value: "none", label: "None" },
236
- { value: "slack", label: "Slack" }
236
+ { value: "slack", label: "Slack" },
237
+ { value: "resend", label: "Email (Resend)" }
237
238
  ]
238
239
  },
239
240
  {
@@ -262,6 +263,76 @@ var ONBOARDING_FIELDS = [
262
263
  defaultValue: "",
263
264
  secret: true,
264
265
  dependsOn: { fieldId: "messaging.platform", equals: "slack" }
266
+ },
267
+ {
268
+ id: "env.RESEND_API_KEY",
269
+ domain: "messaging",
270
+ target: "env",
271
+ path: "RESEND_API_KEY",
272
+ kind: "string",
273
+ scopes: ["full"],
274
+ label: "Resend API Key",
275
+ prompt: "Resend API Key (from resend.com/api-keys)",
276
+ defaultValue: "",
277
+ placeholder: "re_...",
278
+ secret: true,
279
+ dependsOn: { fieldId: "messaging.platform", equals: "resend" }
280
+ },
281
+ {
282
+ id: "env.RESEND_WEBHOOK_SECRET",
283
+ domain: "messaging",
284
+ target: "env",
285
+ path: "RESEND_WEBHOOK_SECRET",
286
+ kind: "string",
287
+ scopes: ["full"],
288
+ label: "Resend Webhook Secret",
289
+ prompt: "Resend Webhook Signing Secret (from webhook details page)",
290
+ defaultValue: "",
291
+ placeholder: "whsec_...",
292
+ secret: true,
293
+ dependsOn: { fieldId: "messaging.platform", equals: "resend" }
294
+ },
295
+ {
296
+ id: "env.RESEND_FROM",
297
+ domain: "messaging",
298
+ target: "env",
299
+ path: "RESEND_FROM",
300
+ kind: "string",
301
+ scopes: ["full"],
302
+ label: "From Address",
303
+ prompt: "Email address the agent sends from (e.g. Agent <agent@yourdomain.com>)",
304
+ defaultValue: "",
305
+ placeholder: "Agent <agent@yourdomain.com>",
306
+ dependsOn: { fieldId: "messaging.platform", equals: "resend" }
307
+ },
308
+ {
309
+ id: "messaging.resend.mode",
310
+ domain: "messaging",
311
+ target: "agent",
312
+ path: "messaging.resend.mode",
313
+ kind: "select",
314
+ scopes: ["full"],
315
+ label: "Email response mode",
316
+ prompt: "How should the agent respond to emails?",
317
+ defaultValue: "auto-reply",
318
+ options: [
319
+ { value: "auto-reply", label: "Auto-reply (agent response sent as email reply)" },
320
+ { value: "tool", label: "Tool (agent uses send_email tool for full control)" }
321
+ ],
322
+ dependsOn: { fieldId: "messaging.platform", equals: "resend" }
323
+ },
324
+ {
325
+ id: "messaging.resend.allowedRecipients",
326
+ domain: "messaging",
327
+ target: "agent",
328
+ path: "messaging.resend.allowedRecipients",
329
+ kind: "string",
330
+ scopes: ["full"],
331
+ label: "Allowed recipients",
332
+ prompt: "Allowed recipient patterns for send_email tool (comma-separated, e.g. *@mycompany.com). Leave empty for no restrictions.",
333
+ defaultValue: "",
334
+ placeholder: "*@mycompany.com, partner@external.com",
335
+ dependsOn: { fieldId: "messaging.resend.mode", equals: "tool" }
265
336
  }
266
337
  ];
267
338
  var FEATURE_DOMAIN_ORDER = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poncho-ai/sdk",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Core types and utilities for building Poncho skills",
5
5
  "repository": {
6
6
  "type": "git",
@@ -279,6 +279,7 @@ export const ONBOARDING_FIELDS = [
279
279
  options: [
280
280
  { value: "none", label: "None" },
281
281
  { value: "slack", label: "Slack" },
282
+ { value: "resend", label: "Email (Resend)" },
282
283
  ],
283
284
  },
284
285
  {
@@ -308,6 +309,76 @@ export const ONBOARDING_FIELDS = [
308
309
  secret: true,
309
310
  dependsOn: { fieldId: "messaging.platform", equals: "slack" },
310
311
  },
312
+ {
313
+ id: "env.RESEND_API_KEY",
314
+ domain: "messaging",
315
+ target: "env",
316
+ path: "RESEND_API_KEY",
317
+ kind: "string",
318
+ scopes: ["full"],
319
+ label: "Resend API Key",
320
+ prompt: "Resend API Key (from resend.com/api-keys)",
321
+ defaultValue: "",
322
+ placeholder: "re_...",
323
+ secret: true,
324
+ dependsOn: { fieldId: "messaging.platform", equals: "resend" },
325
+ },
326
+ {
327
+ id: "env.RESEND_WEBHOOK_SECRET",
328
+ domain: "messaging",
329
+ target: "env",
330
+ path: "RESEND_WEBHOOK_SECRET",
331
+ kind: "string",
332
+ scopes: ["full"],
333
+ label: "Resend Webhook Secret",
334
+ prompt: "Resend Webhook Signing Secret (from webhook details page)",
335
+ defaultValue: "",
336
+ placeholder: "whsec_...",
337
+ secret: true,
338
+ dependsOn: { fieldId: "messaging.platform", equals: "resend" },
339
+ },
340
+ {
341
+ id: "env.RESEND_FROM",
342
+ domain: "messaging",
343
+ target: "env",
344
+ path: "RESEND_FROM",
345
+ kind: "string",
346
+ scopes: ["full"],
347
+ label: "From Address",
348
+ prompt: "Email address the agent sends from (e.g. Agent <agent@yourdomain.com>)",
349
+ defaultValue: "",
350
+ placeholder: "Agent <agent@yourdomain.com>",
351
+ dependsOn: { fieldId: "messaging.platform", equals: "resend" },
352
+ },
353
+ {
354
+ id: "messaging.resend.mode",
355
+ domain: "messaging",
356
+ target: "agent",
357
+ path: "messaging.resend.mode",
358
+ kind: "select",
359
+ scopes: ["full"],
360
+ label: "Email response mode",
361
+ prompt: "How should the agent respond to emails?",
362
+ defaultValue: "auto-reply",
363
+ options: [
364
+ { value: "auto-reply", label: "Auto-reply (agent response sent as email reply)" },
365
+ { value: "tool", label: "Tool (agent uses send_email tool for full control)" },
366
+ ],
367
+ dependsOn: { fieldId: "messaging.platform", equals: "resend" },
368
+ },
369
+ {
370
+ id: "messaging.resend.allowedRecipients",
371
+ domain: "messaging",
372
+ target: "agent",
373
+ path: "messaging.resend.allowedRecipients",
374
+ kind: "string",
375
+ scopes: ["full"],
376
+ label: "Allowed recipients",
377
+ prompt: "Allowed recipient patterns for send_email tool (comma-separated, e.g. *@mycompany.com). Leave empty for no restrictions.",
378
+ defaultValue: "",
379
+ placeholder: "*@mycompany.com, partner@external.com",
380
+ dependsOn: { fieldId: "messaging.resend.mode", equals: "tool" },
381
+ },
311
382
  ] as const satisfies readonly OnboardingField[];
312
383
 
313
384
  export const FEATURE_DOMAIN_ORDER: readonly FeatureDomain[] = [
package/src/index.ts CHANGED
@@ -93,11 +93,13 @@ export interface FileInput {
93
93
  }
94
94
 
95
95
  export interface RunInput {
96
- task: string;
96
+ task?: string;
97
97
  parameters?: Record<string, unknown>;
98
98
  messages?: Message[];
99
99
  files?: FileInput[];
100
100
  abortSignal?: AbortSignal;
101
+ /** When set, Latitude telemetry groups all turns in this conversation under a single trace. */
102
+ conversationId?: string;
101
103
  }
102
104
 
103
105
  export interface TokenUsage {
@@ -123,7 +125,7 @@ export interface AgentFailure {
123
125
  }
124
126
 
125
127
  export type AgentEvent =
126
- | { type: "run:started"; runId: string; agentId: string }
128
+ | { type: "run:started"; runId: string; agentId: string; contextWindow?: number }
127
129
  | { type: "run:completed"; runId: string; result: RunResult }
128
130
  | { type: "run:cancelled"; runId: string }
129
131
  | { type: "run:error"; runId: string; error: AgentFailure }
@@ -142,4 +144,13 @@ export type AgentEvent =
142
144
  approvalId: string;
143
145
  }
144
146
  | { type: "tool:approval:granted"; approvalId: string }
145
- | { type: "tool:approval:denied"; approvalId: string; reason?: string };
147
+ | { type: "tool:approval:denied"; approvalId: string; reason?: string }
148
+ | {
149
+ type: "tool:approval:checkpoint";
150
+ approvalId: string;
151
+ tool: string;
152
+ toolCallId: string;
153
+ input: Record<string, unknown>;
154
+ checkpointMessages: Message[];
155
+ pendingToolCalls: Array<{ id: string; name: string; input: Record<string, unknown> }>;
156
+ };