@openape/ape-agent 2.4.0 → 2.5.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.
- package/dist/bridge.mjs +50 -0
- package/package.json +1 -1
package/dist/bridge.mjs
CHANGED
|
@@ -1366,6 +1366,19 @@ var ChatApi = class {
|
|
|
1366
1366
|
});
|
|
1367
1367
|
return result;
|
|
1368
1368
|
}
|
|
1369
|
+
/**
|
|
1370
|
+
* Fetch the most recent `limit` messages in a thread, oldest-first.
|
|
1371
|
+
* Used by ThreadSession to seed `history` so the agent has the
|
|
1372
|
+
* full conversation context after a bridge restart — otherwise it
|
|
1373
|
+
* only sees messages that arrived via WS since the process boot.
|
|
1374
|
+
*/
|
|
1375
|
+
async listMessages(roomId, threadId, limit = 50) {
|
|
1376
|
+
const url = `${this.endpoint}/api/rooms/${encodeURIComponent(roomId)}/messages?thread_id=${encodeURIComponent(threadId)}&limit=${limit}`;
|
|
1377
|
+
return await ofetch5(url, {
|
|
1378
|
+
method: "GET",
|
|
1379
|
+
headers: { Authorization: await this.bearer() }
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1369
1382
|
async requestContact(peerEmail) {
|
|
1370
1383
|
const url = `${this.endpoint}/api/contacts`;
|
|
1371
1384
|
return await ofetch5(url, {
|
|
@@ -4045,6 +4058,14 @@ var ThreadSession = class {
|
|
|
4045
4058
|
active;
|
|
4046
4059
|
queue = [];
|
|
4047
4060
|
history = [];
|
|
4061
|
+
/**
|
|
4062
|
+
* Whether we've already backfilled history from the chat server.
|
|
4063
|
+
* Done lazily on the first turn so a freshly-created ThreadSession
|
|
4064
|
+
* (e.g. after a bridge restart) sees the full conversation context,
|
|
4065
|
+
* not just the message that woke it up. We skip the message that
|
|
4066
|
+
* triggered the turn — runLoop adds it via `userMessage`.
|
|
4067
|
+
*/
|
|
4068
|
+
backfilled = false;
|
|
4048
4069
|
/**
|
|
4049
4070
|
* No-op placeholder kept for API compatibility with the previous
|
|
4050
4071
|
* RPC-listener model where dispose() detached the listener.
|
|
@@ -4089,6 +4110,7 @@ var ThreadSession = class {
|
|
|
4089
4110
|
}
|
|
4090
4111
|
};
|
|
4091
4112
|
const { systemPrompt, tools } = this.deps.resolveConfig();
|
|
4113
|
+
await this.backfillHistoryOnce(replyToMessageId, body);
|
|
4092
4114
|
try {
|
|
4093
4115
|
const result = await runLoop({
|
|
4094
4116
|
config: this.deps.runtimeConfig,
|
|
@@ -4131,6 +4153,33 @@ var ThreadSession = class {
|
|
|
4131
4153
|
await this.failTurn(`(runtime error: ${message})`);
|
|
4132
4154
|
}
|
|
4133
4155
|
}
|
|
4156
|
+
/**
|
|
4157
|
+
* Fetch recent chat history for this thread and seed `this.history`.
|
|
4158
|
+
* Idempotent — only runs once per ThreadSession instance. Skips the
|
|
4159
|
+
* placeholder we just posted plus the inbound message that triggered
|
|
4160
|
+
* this turn (runLoop's `userMessage` handles that one).
|
|
4161
|
+
*
|
|
4162
|
+
* Failures are non-fatal: we log and continue with empty history.
|
|
4163
|
+
* That preserves the pre-backfill behaviour rather than failing the
|
|
4164
|
+
* turn over a transient chat-server hiccup.
|
|
4165
|
+
*/
|
|
4166
|
+
async backfillHistoryOnce(currentMessageId, currentBody) {
|
|
4167
|
+
if (this.backfilled) return;
|
|
4168
|
+
this.backfilled = true;
|
|
4169
|
+
try {
|
|
4170
|
+
const rows = await this.deps.chat.listMessages(this.deps.roomId, this.deps.threadId, 50);
|
|
4171
|
+
for (const row of rows) {
|
|
4172
|
+
if (row.id === currentMessageId) continue;
|
|
4173
|
+
if (!row.body || row.body.length === 0) continue;
|
|
4174
|
+
if (row.body === currentBody && row.senderEmail !== this.deps.selfEmail) continue;
|
|
4175
|
+
const role = row.senderEmail === this.deps.selfEmail ? "assistant" : "user";
|
|
4176
|
+
this.history.push({ role, content: row.body });
|
|
4177
|
+
}
|
|
4178
|
+
this.deps.log(`[${this.deps.roomId}/${this.deps.threadId.slice(0, 8)}] backfilled ${this.history.length} message(s) from chat history`);
|
|
4179
|
+
} catch (err) {
|
|
4180
|
+
this.deps.log(`[${this.deps.roomId}/${this.deps.threadId.slice(0, 8)}] backfill failed (continuing with empty history): ${err instanceof Error ? err.message : String(err)}`);
|
|
4181
|
+
}
|
|
4182
|
+
}
|
|
4134
4183
|
/**
|
|
4135
4184
|
* Stream-end: flush any pending throttled body PATCH, then mark the
|
|
4136
4185
|
* message as no-longer-streaming. The combined call also triggers
|
|
@@ -4381,6 +4430,7 @@ var Bridge = class {
|
|
|
4381
4430
|
})
|
|
4382
4431
|
};
|
|
4383
4432
|
},
|
|
4433
|
+
selfEmail: this.selfEmail,
|
|
4384
4434
|
maxSteps: this.cfg.maxSteps,
|
|
4385
4435
|
log
|
|
4386
4436
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openape/ape-agent",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"description": "OpenApe agent runtime: per-agent process that connects to chat.openape.ai, runs the LLM loop with tools + cron tasks, and streams replies back to owners.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|