@poncho-ai/messaging 0.4.0 → 0.5.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @poncho-ai/messaging@0.4.0 build /Users/cesar/Dev/latitude/poncho-ai/packages/messaging
2
+ > @poncho-ai/messaging@0.5.0 build /Users/cesar/Dev/latitude/poncho-ai/packages/messaging
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 44.99 KB
11
- ESM ⚡️ Build success in 69ms
10
+ ESM dist/index.js 45.94 KB
11
+ ESM ⚡️ Build success in 60ms
12
12
  DTS Build start
13
- DTS ⚡️ Build success in 1830ms
14
- DTS dist/index.d.ts 10.05 KB
13
+ DTS ⚡️ Build success in 2033ms
14
+ DTS dist/index.d.ts 10.13 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @poncho-ai/messaging
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`8ef9316`](https://github.com/cesr/poncho-ai/commit/8ef93165084b4df581e39a1581b1ead64b7b3f42) Thanks [@cesr](https://github.com/cesr)! - Add auto-continuation support for messaging adapters (Telegram, Slack, Resend) on serverless platforms. When `PONCHO_MAX_DURATION` is set, agent runs that hit the soft deadline now automatically resume with "Continue" messages, matching the web UI and client SDK behavior.
8
+
3
9
  ## 0.4.0
4
10
 
5
11
  ### Minor Changes
package/dist/index.d.ts CHANGED
@@ -83,6 +83,9 @@ interface AgentRunner {
83
83
  }): Promise<{
84
84
  response: string;
85
85
  files?: FileAttachment[];
86
+ continuation?: boolean;
87
+ steps?: number;
88
+ maxSteps?: number;
86
89
  }>;
87
90
  }
88
91
  interface AgentBridgeOptions {
package/dist/index.js CHANGED
@@ -33,6 +33,7 @@ var AgentBridge = class {
33
33
  await this.adapter.initialize();
34
34
  }
35
35
  async handleMessage(message) {
36
+ const MAX_CONTINUATIONS = 10;
36
37
  let cleanup;
37
38
  this.adapter.resetRequestState?.();
38
39
  try {
@@ -46,33 +47,53 @@ var AgentBridge = class {
46
47
  const titleParts = [platformTag, senderLabel];
47
48
  if (message.subject) titleParts.push(message.subject);
48
49
  const title = titleParts.join(" ") || `${message.platform} thread`;
49
- const conversation = await this.runner.getOrCreateConversation(
50
- conversationId,
51
- {
52
- platform: message.platform,
53
- ownerId: this.ownerIdOverride ?? message.sender.id,
54
- title
55
- }
56
- );
57
50
  const senderLine = message.sender.name ? `From: ${message.sender.name} <${message.sender.id}>` : `From: ${message.sender.id}`;
58
51
  const subjectLine = message.subject ? `Subject: ${message.subject}` : "";
59
52
  const header = [senderLine, subjectLine].filter(Boolean).join("\n");
60
- const task = `${header}
53
+ let currentTask = `${header}
61
54
 
62
55
  ${message.text}`;
63
- const result = await this.runner.run(conversationId, {
64
- task,
65
- messages: conversation.messages,
66
- files: message.files,
67
- metadata: {
68
- platform: message.platform,
69
- sender: message.sender,
70
- threadId: message.threadRef.platformThreadId
56
+ let currentFiles = message.files;
57
+ let accumulatedResponse = "";
58
+ let accumulatedFiles = [];
59
+ let totalSteps = 0;
60
+ let stepBudget = 0;
61
+ let continuationCount = 0;
62
+ while (true) {
63
+ const conversation = await this.runner.getOrCreateConversation(
64
+ conversationId,
65
+ {
66
+ platform: message.platform,
67
+ ownerId: this.ownerIdOverride ?? message.sender.id,
68
+ title
69
+ }
70
+ );
71
+ const result = await this.runner.run(conversationId, {
72
+ task: currentTask,
73
+ messages: conversation.messages,
74
+ files: currentFiles,
75
+ metadata: {
76
+ platform: message.platform,
77
+ sender: message.sender,
78
+ threadId: message.threadRef.platformThreadId
79
+ }
80
+ });
81
+ accumulatedResponse += result.response;
82
+ if (result.files) accumulatedFiles.push(...result.files);
83
+ totalSteps += result.steps ?? 0;
84
+ if (typeof result.maxSteps === "number") stepBudget = result.maxSteps;
85
+ if (result.continuation && continuationCount < MAX_CONTINUATIONS && (stepBudget <= 0 || totalSteps < stepBudget)) {
86
+ continuationCount++;
87
+ console.log(`[agent-bridge] continuation ${continuationCount}/${MAX_CONTINUATIONS} for ${conversationId}`);
88
+ currentTask = "Continue";
89
+ currentFiles = void 0;
90
+ continue;
71
91
  }
72
- });
92
+ break;
93
+ }
73
94
  if (this.adapter.autoReply) {
74
- await this.adapter.sendReply(message.threadRef, result.response, {
75
- files: result.files
95
+ await this.adapter.sendReply(message.threadRef, accumulatedResponse, {
96
+ files: accumulatedFiles.length > 0 ? accumulatedFiles : void 0
76
97
  });
77
98
  } else if (!this.adapter.hasSentInCurrentRequest) {
78
99
  console.warn("[agent-bridge] tool mode completed without send_email being called; no reply sent");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poncho-ai/messaging",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Messaging platform adapters for Poncho agents (Slack, Telegram, etc.)",
5
5
  "repository": {
6
6
  "type": "git",
package/src/bridge.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import type {
3
3
  AgentBridgeOptions,
4
+ FileAttachment,
4
5
  IncomingMessage,
5
6
  MessagingAdapter,
6
7
  AgentRunner,
@@ -53,6 +54,7 @@ export class AgentBridge {
53
54
  }
54
55
 
55
56
  private async handleMessage(message: IncomingMessage): Promise<void> {
57
+ const MAX_CONTINUATIONS = 10;
56
58
  let cleanup: (() => Promise<void>) | undefined;
57
59
 
58
60
  this.adapter.resetRequestState?.();
@@ -71,36 +73,64 @@ export class AgentBridge {
71
73
  if (message.subject) titleParts.push(message.subject);
72
74
  const title = titleParts.join(" ") || `${message.platform} thread`;
73
75
 
74
- const conversation = await this.runner.getOrCreateConversation(
75
- conversationId,
76
- {
77
- platform: message.platform,
78
- ownerId: this.ownerIdOverride ?? message.sender.id,
79
- title,
80
- },
81
- );
82
-
83
76
  const senderLine = message.sender.name
84
77
  ? `From: ${message.sender.name} <${message.sender.id}>`
85
78
  : `From: ${message.sender.id}`;
86
79
  const subjectLine = message.subject ? `Subject: ${message.subject}` : "";
87
80
  const header = [senderLine, subjectLine].filter(Boolean).join("\n");
88
- const task = `${header}\n\n${message.text}`;
89
-
90
- const result = await this.runner.run(conversationId, {
91
- task,
92
- messages: conversation.messages,
93
- files: message.files,
94
- metadata: {
95
- platform: message.platform,
96
- sender: message.sender,
97
- threadId: message.threadRef.platformThreadId,
98
- },
99
- });
81
+
82
+ let currentTask = `${header}\n\n${message.text}`;
83
+ let currentFiles = message.files;
84
+ let accumulatedResponse = "";
85
+ let accumulatedFiles: FileAttachment[] = [];
86
+ let totalSteps = 0;
87
+ let stepBudget = 0;
88
+ let continuationCount = 0;
89
+
90
+ while (true) {
91
+ const conversation = await this.runner.getOrCreateConversation(
92
+ conversationId,
93
+ {
94
+ platform: message.platform,
95
+ ownerId: this.ownerIdOverride ?? message.sender.id,
96
+ title,
97
+ },
98
+ );
99
+
100
+ const result = await this.runner.run(conversationId, {
101
+ task: currentTask,
102
+ messages: conversation.messages,
103
+ files: currentFiles,
104
+ metadata: {
105
+ platform: message.platform,
106
+ sender: message.sender,
107
+ threadId: message.threadRef.platformThreadId,
108
+ },
109
+ });
110
+
111
+ accumulatedResponse += result.response;
112
+ if (result.files) accumulatedFiles.push(...result.files);
113
+ totalSteps += result.steps ?? 0;
114
+ if (typeof result.maxSteps === "number") stepBudget = result.maxSteps;
115
+
116
+ if (
117
+ result.continuation &&
118
+ continuationCount < MAX_CONTINUATIONS &&
119
+ (stepBudget <= 0 || totalSteps < stepBudget)
120
+ ) {
121
+ continuationCount++;
122
+ console.log(`[agent-bridge] continuation ${continuationCount}/${MAX_CONTINUATIONS} for ${conversationId}`);
123
+ currentTask = "Continue";
124
+ currentFiles = undefined;
125
+ continue;
126
+ }
127
+
128
+ break;
129
+ }
100
130
 
101
131
  if (this.adapter.autoReply) {
102
- await this.adapter.sendReply(message.threadRef, result.response, {
103
- files: result.files,
132
+ await this.adapter.sendReply(message.threadRef, accumulatedResponse, {
133
+ files: accumulatedFiles.length > 0 ? accumulatedFiles : undefined,
104
134
  });
105
135
  } else if (!this.adapter.hasSentInCurrentRequest) {
106
136
  console.warn("[agent-bridge] tool mode completed without send_email being called; no reply sent");
package/src/types.ts CHANGED
@@ -123,6 +123,9 @@ export interface AgentRunner {
123
123
  ): Promise<{
124
124
  response: string;
125
125
  files?: FileAttachment[];
126
+ continuation?: boolean;
127
+ steps?: number;
128
+ maxSteps?: number;
126
129
  }>;
127
130
  }
128
131