mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-13 07:12:00 +01:00
feat(slack): add threaded CEO conversations and live progress
This commit is contained in:
1 parent
91339784ce
commit
fbcae3cd88
39 files changed
+2384
-74
No files matched your search
@@ -0,0 +1,15 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createAcpxChatProgress } from "./chat-progress.js";
|
||||
|
||||
describe("ACPX coarse chat progress", () => {
|
||||
it("emits only a closed tool signal and coalesces token-by-token updates", () => {
|
||||
let time = 0;
|
||||
const project = createAcpxChatProgress(() => time);
|
||||
for (const type of ["text_delta", "status", "error", "done", "private command"]) expect(project(type)).toBeNull();
|
||||
expect(project("tool_call")).toEqual({ eventType: "chat.progress.using_tools", stream: "system", level: "info" });
|
||||
for (let i = 0; i < 100; i++) expect(project("tool_call")).toBeNull();
|
||||
time = 20_000;
|
||||
expect(project("tool_call")).not.toBeNull();
|
||||
expect(createAcpxChatProgress(() => time)("tool_call")).not.toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import type { AdapterRuntimeEvent } from "../types.js";
|
||||
|
||||
/** Only a closed activity label enters the local run-event table. Never accept
|
||||
* a tool title, command, argument, output, or thought delta as display text. */
|
||||
export function createAcpxChatProgress(now: () => number = Date.now) {
|
||||
let lastToolEventAt = -Infinity;
|
||||
return (eventType: string): AdapterRuntimeEvent | null => {
|
||||
if (eventType !== "tool_call" || now() - lastToolEventAt < 20_000) return null;
|
||||
lastToolEventAt = now();
|
||||
return { eventType: "chat.progress.using_tools", stream: "system", level: "info" };
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { cancellableSandboxStartup } from "./startup-cancellation.js";
|
||||
import { createAcpxChatProgress } from "./chat-progress.js";
|
||||
import fs from "node:fs/promises";
|
||||
import fsSync from "node:fs";
|
||||
import os from "node:os";
|
||||
@@ -4835,8 +4836,11 @@ export function createAcpxEngineExecutor(deps: AcpxEngineExecutorOptions = {}) {
|
||||
const stepEventRelay = async (): Promise<AcpRuntimeTurnResult> => {
|
||||
const turn = activeTurn as AcpRuntimeTurn;
|
||||
const toolTitles = new Map<string, string>();
|
||||
const chatProgress = createAcpxChatProgress(now);
|
||||
const drainEvents = (async (): Promise<void> => {
|
||||
for await (const event of turn.events) {
|
||||
const progress = chatProgress(event.type);
|
||||
if (progress) await ctx.onEvent?.(progress);
|
||||
// ACPX currently flattens client-side filesystem/terminal receipts
|
||||
// into status text. They cannot establish complete action outcomes.
|
||||
if (event.type === "status" && /^(fs|terminal)\//.test(event.text)) incompleteToolInventory = true;
|
||||
|
||||
Reference in new issue
Block a user