crewly 1.20.347 → 1.20.349
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/config/roles/orchestrator/prompt.md +1 -1
- package/config/roles/team-leader/prompt.md +1 -1
- package/config/skills/agent/core/publish-app/SKILL.md +10 -0
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +8 -0
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts +15 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +73 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/decision-rights.module.js +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/decision-rights.module.js.map +1 -1
- package/dist/backend/backend/src/services/apps/app-wake-message.d.ts +21 -0
- package/dist/backend/backend/src/services/apps/app-wake-message.d.ts.map +1 -1
- package/dist/backend/backend/src/services/apps/app-wake-message.js +33 -2
- package/dist/backend/backend/src/services/apps/app-wake-message.js.map +1 -1
- package/dist/backend/backend/src/services/apps/app-wake.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/apps/app-wake.service.js +15 -1
- package/dist/backend/backend/src/services/apps/app-wake.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.service.d.ts +165 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.service.js +337 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.service.js.map +1 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.wiring.d.ts +45 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.wiring.js +71 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.wiring.js.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-context.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/trace/trace-context.service.js +11 -0
- package/dist/backend/backend/src/services/trace/trace-context.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/ticket-review.service.d.ts +21 -0
- package/dist/backend/backend/src/services/v3/ticket-review.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/ticket-review.service.js +35 -0
- package/dist/backend/backend/src/services/v3/ticket-review.service.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.js +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/agent-ask-ledger.service.d.ts +165 -0
- package/dist/cli/backend/src/services/messaging/agent-ask-ledger.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/messaging/agent-ask-ledger.service.js +337 -0
- package/dist/cli/backend/src/services/messaging/agent-ask-ledger.service.js.map +1 -0
- package/dist/cli/backend/src/services/trace/trace-context.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/trace/trace-context.service.js +11 -0
- package/dist/cli/backend/src/services/trace/trace-context.service.js.map +1 -1
- package/dist/cli/backend/src/services/v3/ticket-review.service.d.ts +21 -0
- package/dist/cli/backend/src/services/v3/ticket-review.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/v3/ticket-review.service.js +35 -0
- package/dist/cli/backend/src/services/v3/ticket-review.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent ask ledger — the return path of agent-to-agent messages.
|
|
3
|
+
*
|
|
4
|
+
* When one agent hands work to another with a plain message (send-message /
|
|
5
|
+
* `/terminal/:to/write`), nothing brings the answer back: no WorkItem, no
|
|
6
|
+
* completion event. On 2026-10-14 Pia passed the owner's "replicate this X
|
|
7
|
+
* video" to Dex; Dex rendered the films in 24 minutes, wrote "both parts are
|
|
8
|
+
* done" into its own terminal and stopped. Nobody saw it for seven hours.
|
|
9
|
+
*
|
|
10
|
+
* This ledger remembers each agent message once it is delivered. When the
|
|
11
|
+
* receiver ends a turn that worked on it for a while and it neither wrote
|
|
12
|
+
* back to the sender nor posted anywhere, the harness passes the receiver's
|
|
13
|
+
* last words to the sender. The receiver's open asks also hold the owner's
|
|
14
|
+
* ticket open (an agent that handed the work on has not answered yet).
|
|
15
|
+
*
|
|
16
|
+
* Cheap by construction: no model call, one transcript read per forwarded
|
|
17
|
+
* ask. Off switch: `CREWLY_AGENT_ASK_RETURN=off`.
|
|
18
|
+
*
|
|
19
|
+
* @module services/messaging/agent-ask-ledger.service
|
|
20
|
+
*/
|
|
21
|
+
/** Tunables. */
|
|
22
|
+
export declare const AGENT_ASK_CONSTANTS: {
|
|
23
|
+
/** Store file under CREWLY_HOME */
|
|
24
|
+
readonly FILE_NAME: "agent-asks.json";
|
|
25
|
+
/** A turn this long after the delivery counts as having worked on the message (ms) */
|
|
26
|
+
readonly MIN_WORK_MS: number;
|
|
27
|
+
/**
|
|
28
|
+
* A turn that ends sooner than MIN_WORK_MS but at least this long after
|
|
29
|
+
* the delivery read it and let it go (an FYI, an "ok"): the ask is dropped
|
|
30
|
+
* without a word. Sooner than this, the turn that ended is the previous
|
|
31
|
+
* one, not the message's (ms).
|
|
32
|
+
*/
|
|
33
|
+
readonly MIN_READ_MS: 15000;
|
|
34
|
+
/** An ask nobody answered is forgotten after this (ms) */
|
|
35
|
+
readonly TTL_MS: number;
|
|
36
|
+
/** Asks kept in the store */
|
|
37
|
+
readonly MAX_ASKS: 300;
|
|
38
|
+
/** Characters of the asked message quoted back to the sender */
|
|
39
|
+
readonly EXCERPT_CHARS: 200;
|
|
40
|
+
/** Characters of the receiver's last words passed on */
|
|
41
|
+
readonly RESULT_CHARS: 3000;
|
|
42
|
+
/** Env switch: `off` disables the ledger */
|
|
43
|
+
readonly ENV_SWITCH: "CREWLY_AGENT_ASK_RETURN";
|
|
44
|
+
};
|
|
45
|
+
/** One delivered agent-to-agent message. */
|
|
46
|
+
export interface AgentAsk {
|
|
47
|
+
/** Sending agent */
|
|
48
|
+
sender: string;
|
|
49
|
+
/** Receiving agent */
|
|
50
|
+
target: string;
|
|
51
|
+
/** Start of the message */
|
|
52
|
+
excerpt: string;
|
|
53
|
+
/** When it reached the receiver's turn (epoch ms) */
|
|
54
|
+
deliveredAt: number;
|
|
55
|
+
}
|
|
56
|
+
/** Collaborators. */
|
|
57
|
+
export interface AgentAskLedgerDeps {
|
|
58
|
+
/** Store file; omit to keep the ledger in memory only */
|
|
59
|
+
file?: string;
|
|
60
|
+
/** What the receiver last wrote in its own transcript since `sinceMs`, or null */
|
|
61
|
+
readLastWords: (session: string, sinceMs: number) => Promise<string | null>;
|
|
62
|
+
/** Deliver a harness message to an agent */
|
|
63
|
+
deliver: (session: string, text: string) => Promise<unknown>;
|
|
64
|
+
/** Readable name of an agent (default: the member part of its session name) */
|
|
65
|
+
displayName?: (session: string) => string;
|
|
66
|
+
now?: () => number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The member name in a session id: `flopost-dex-7f17ecbc` → `Dex`.
|
|
70
|
+
*
|
|
71
|
+
* @param session - Session name
|
|
72
|
+
* @returns Readable name
|
|
73
|
+
*/
|
|
74
|
+
export declare function memberName(session: string): string;
|
|
75
|
+
/**
|
|
76
|
+
* Text handed to the sender in place of the answer it never got.
|
|
77
|
+
*
|
|
78
|
+
* @param input - Names, the asked excerpt, minutes worked, the last words
|
|
79
|
+
* @returns Message for the sender
|
|
80
|
+
*/
|
|
81
|
+
export declare function renderReturnedAnswer(input: {
|
|
82
|
+
target: string;
|
|
83
|
+
excerpt: string;
|
|
84
|
+
minutes: number;
|
|
85
|
+
lastWords: string | null;
|
|
86
|
+
}): string;
|
|
87
|
+
/**
|
|
88
|
+
* Remembers delivered agent messages and returns unsent answers. See module docs.
|
|
89
|
+
*/
|
|
90
|
+
export declare class AgentAskLedger {
|
|
91
|
+
private readonly deps;
|
|
92
|
+
private asks;
|
|
93
|
+
private posts;
|
|
94
|
+
private readonly logger;
|
|
95
|
+
private readonly now;
|
|
96
|
+
private saving;
|
|
97
|
+
constructor(deps: AgentAskLedgerDeps);
|
|
98
|
+
/**
|
|
99
|
+
* A message from `sender` reached `target`'s turn.
|
|
100
|
+
*
|
|
101
|
+
* @param target - Receiving agent
|
|
102
|
+
* @param sender - Sending agent
|
|
103
|
+
* @param text - What was delivered
|
|
104
|
+
*/
|
|
105
|
+
noteDelivered(target: string, sender: string, text: string): void;
|
|
106
|
+
/**
|
|
107
|
+
* `from` wrote to `to`: every open ask of `to` to `from` is answered.
|
|
108
|
+
*
|
|
109
|
+
* @param from - Writing agent
|
|
110
|
+
* @param to - Agent written to
|
|
111
|
+
*/
|
|
112
|
+
noteAnswered(from: string, to: string): void;
|
|
113
|
+
/**
|
|
114
|
+
* An agent posted in chat (an answer, not an interim note): asks delivered
|
|
115
|
+
* to it before now count as answered where they were asked to be.
|
|
116
|
+
*
|
|
117
|
+
* @param session - Posting agent
|
|
118
|
+
*/
|
|
119
|
+
notePost(session: string): void;
|
|
120
|
+
/**
|
|
121
|
+
* Asks `sender` made that are still unanswered.
|
|
122
|
+
*
|
|
123
|
+
* @param sender - Asking agent
|
|
124
|
+
* @returns Open asks, oldest first
|
|
125
|
+
*/
|
|
126
|
+
openAsksBy(sender: string): AgentAsk[];
|
|
127
|
+
/**
|
|
128
|
+
* `target` finished a turn. An ask it worked on for at least
|
|
129
|
+
* {@link AGENT_ASK_CONSTANTS.MIN_WORK_MS} with no word back is answered
|
|
130
|
+
* for it: its last words go to the sender. One it answered in chat, or
|
|
131
|
+
* read in a short turn, is dropped. Never throws.
|
|
132
|
+
*
|
|
133
|
+
* @param target - Agent whose turn ended
|
|
134
|
+
* @returns Asks returned to their senders
|
|
135
|
+
*/
|
|
136
|
+
onTurnEnded(target: string): Promise<number>;
|
|
137
|
+
private prune;
|
|
138
|
+
private load;
|
|
139
|
+
private save;
|
|
140
|
+
/** Wait for pending writes (tests). */
|
|
141
|
+
flush(): Promise<void>;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The agent's last message in a transcript since a time: the text of the
|
|
145
|
+
* newest assistant entry that has text (Claude Code JSONL or Codex rollout).
|
|
146
|
+
* Subagent (sidechain), meta and API-error entries are not the agent's words.
|
|
147
|
+
*
|
|
148
|
+
* @param text - Whole JSONL lines (a tail of the file is fine)
|
|
149
|
+
* @param kind - Transcript format
|
|
150
|
+
* @param sinceMs - Ignore entries older than this (epoch ms)
|
|
151
|
+
* @returns The text, or null when there is none
|
|
152
|
+
*/
|
|
153
|
+
export declare function lastWordsFromTranscript(text: string, kind: 'claude' | 'codex', sinceMs: number): string | null;
|
|
154
|
+
/** @returns The wired ledger, or null before boot (and when switched off) */
|
|
155
|
+
export declare function getAgentAskLedger(): AgentAskLedger | null;
|
|
156
|
+
/** @param ledger - The ledger to expose (null clears) */
|
|
157
|
+
export declare function setAgentAskLedger(ledger: AgentAskLedger | null): void;
|
|
158
|
+
/**
|
|
159
|
+
* Whether the ledger is switched on.
|
|
160
|
+
*
|
|
161
|
+
* @param env - Environment
|
|
162
|
+
* @returns False when `CREWLY_AGENT_ASK_RETURN=off`
|
|
163
|
+
*/
|
|
164
|
+
export declare function agentAskReturnEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
165
|
+
//# sourceMappingURL=agent-ask-ledger.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-ask-ledger.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/agent-ask-ledger.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent ask ledger — the return path of agent-to-agent messages.
|
|
3
|
+
*
|
|
4
|
+
* When one agent hands work to another with a plain message (send-message /
|
|
5
|
+
* `/terminal/:to/write`), nothing brings the answer back: no WorkItem, no
|
|
6
|
+
* completion event. On 2026-10-14 Pia passed the owner's "replicate this X
|
|
7
|
+
* video" to Dex; Dex rendered the films in 24 minutes, wrote "both parts are
|
|
8
|
+
* done" into its own terminal and stopped. Nobody saw it for seven hours.
|
|
9
|
+
*
|
|
10
|
+
* This ledger remembers each agent message once it is delivered. When the
|
|
11
|
+
* receiver ends a turn that worked on it for a while and it neither wrote
|
|
12
|
+
* back to the sender nor posted anywhere, the harness passes the receiver's
|
|
13
|
+
* last words to the sender. The receiver's open asks also hold the owner's
|
|
14
|
+
* ticket open (an agent that handed the work on has not answered yet).
|
|
15
|
+
*
|
|
16
|
+
* Cheap by construction: no model call, one transcript read per forwarded
|
|
17
|
+
* ask. Off switch: `CREWLY_AGENT_ASK_RETURN=off`.
|
|
18
|
+
*
|
|
19
|
+
* @module services/messaging/agent-ask-ledger.service
|
|
20
|
+
*/
|
|
21
|
+
import * as fsSync from 'fs';
|
|
22
|
+
import * as path from 'path';
|
|
23
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
24
|
+
import { atomicWriteJson } from '../../utils/file-io.utils.js';
|
|
25
|
+
/** Tunables. */
|
|
26
|
+
export const AGENT_ASK_CONSTANTS = {
|
|
27
|
+
/** Store file under CREWLY_HOME */
|
|
28
|
+
FILE_NAME: 'agent-asks.json',
|
|
29
|
+
/** A turn this long after the delivery counts as having worked on the message (ms) */
|
|
30
|
+
MIN_WORK_MS: 2 * 60_000,
|
|
31
|
+
/**
|
|
32
|
+
* A turn that ends sooner than MIN_WORK_MS but at least this long after
|
|
33
|
+
* the delivery read it and let it go (an FYI, an "ok"): the ask is dropped
|
|
34
|
+
* without a word. Sooner than this, the turn that ended is the previous
|
|
35
|
+
* one, not the message's (ms).
|
|
36
|
+
*/
|
|
37
|
+
MIN_READ_MS: 15_000,
|
|
38
|
+
/** An ask nobody answered is forgotten after this (ms) */
|
|
39
|
+
TTL_MS: 12 * 60 * 60_000,
|
|
40
|
+
/** Asks kept in the store */
|
|
41
|
+
MAX_ASKS: 300,
|
|
42
|
+
/** Characters of the asked message quoted back to the sender */
|
|
43
|
+
EXCERPT_CHARS: 200,
|
|
44
|
+
/** Characters of the receiver's last words passed on */
|
|
45
|
+
RESULT_CHARS: 3000,
|
|
46
|
+
/** Env switch: `off` disables the ledger */
|
|
47
|
+
ENV_SWITCH: 'CREWLY_AGENT_ASK_RETURN',
|
|
48
|
+
};
|
|
49
|
+
const C = AGENT_ASK_CONSTANTS;
|
|
50
|
+
/**
|
|
51
|
+
* The member name in a session id: `flopost-dex-7f17ecbc` → `Dex`.
|
|
52
|
+
*
|
|
53
|
+
* @param session - Session name
|
|
54
|
+
* @returns Readable name
|
|
55
|
+
*/
|
|
56
|
+
export function memberName(session) {
|
|
57
|
+
const parts = session.split('-');
|
|
58
|
+
const name = parts.length >= 3 && /^[0-9a-f]{6,}$/.test(parts[parts.length - 1]) ? parts[parts.length - 2] : session;
|
|
59
|
+
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Text handed to the sender in place of the answer it never got.
|
|
63
|
+
*
|
|
64
|
+
* @param input - Names, the asked excerpt, minutes worked, the last words
|
|
65
|
+
* @returns Message for the sender
|
|
66
|
+
*/
|
|
67
|
+
export function renderReturnedAnswer(input) {
|
|
68
|
+
const head = `[ANSWER FROM ${input.target.toUpperCase()}] ${input.target} worked on your message for about ${input.minutes} min and ended without writing back to you or posting anywhere.`;
|
|
69
|
+
const asked = `Your message: "${input.excerpt}"`;
|
|
70
|
+
if (!input.lastWords) {
|
|
71
|
+
return `${head} Crewly could not read what it said. ${asked}\nAsk ${input.target} for the result.`;
|
|
72
|
+
}
|
|
73
|
+
return (`${head} Crewly is passing on its last words. ${asked}\n\n` +
|
|
74
|
+
`--- ${input.target} ---\n${input.lastWords}\n---\n\n` +
|
|
75
|
+
`If this is what you were waiting for, carry it on (for example, post it where the owner asked). No need to answer Crewly.`);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Remembers delivered agent messages and returns unsent answers. See module docs.
|
|
79
|
+
*/
|
|
80
|
+
export class AgentAskLedger {
|
|
81
|
+
deps;
|
|
82
|
+
asks = [];
|
|
83
|
+
posts = new Map();
|
|
84
|
+
logger;
|
|
85
|
+
now;
|
|
86
|
+
saving = Promise.resolve();
|
|
87
|
+
constructor(deps) {
|
|
88
|
+
this.deps = deps;
|
|
89
|
+
this.logger = LoggerService.getInstance().createComponentLogger('AgentAskLedger');
|
|
90
|
+
this.now = deps.now ?? Date.now;
|
|
91
|
+
this.load();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* A message from `sender` reached `target`'s turn.
|
|
95
|
+
*
|
|
96
|
+
* @param target - Receiving agent
|
|
97
|
+
* @param sender - Sending agent
|
|
98
|
+
* @param text - What was delivered
|
|
99
|
+
*/
|
|
100
|
+
noteDelivered(target, sender, text) {
|
|
101
|
+
if (!target || !sender || target === sender)
|
|
102
|
+
return;
|
|
103
|
+
const excerpt = text.replace(/\s+/g, ' ').trim().slice(0, C.EXCERPT_CHARS);
|
|
104
|
+
this.asks.push({ sender, target, excerpt, deliveredAt: this.now() });
|
|
105
|
+
this.prune();
|
|
106
|
+
this.save();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* `from` wrote to `to`: every open ask of `to` to `from` is answered.
|
|
110
|
+
*
|
|
111
|
+
* @param from - Writing agent
|
|
112
|
+
* @param to - Agent written to
|
|
113
|
+
*/
|
|
114
|
+
noteAnswered(from, to) {
|
|
115
|
+
const before = this.asks.length;
|
|
116
|
+
this.asks = this.asks.filter((a) => !(a.target === from && a.sender === to));
|
|
117
|
+
if (this.asks.length !== before)
|
|
118
|
+
this.save();
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* An agent posted in chat (an answer, not an interim note): asks delivered
|
|
122
|
+
* to it before now count as answered where they were asked to be.
|
|
123
|
+
*
|
|
124
|
+
* @param session - Posting agent
|
|
125
|
+
*/
|
|
126
|
+
notePost(session) {
|
|
127
|
+
if (!session)
|
|
128
|
+
return;
|
|
129
|
+
this.posts.set(session, this.now());
|
|
130
|
+
this.save();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Asks `sender` made that are still unanswered.
|
|
134
|
+
*
|
|
135
|
+
* @param sender - Asking agent
|
|
136
|
+
* @returns Open asks, oldest first
|
|
137
|
+
*/
|
|
138
|
+
openAsksBy(sender) {
|
|
139
|
+
this.prune();
|
|
140
|
+
return this.asks.filter((a) => a.sender === sender);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* `target` finished a turn. An ask it worked on for at least
|
|
144
|
+
* {@link AGENT_ASK_CONSTANTS.MIN_WORK_MS} with no word back is answered
|
|
145
|
+
* for it: its last words go to the sender. One it answered in chat, or
|
|
146
|
+
* read in a short turn, is dropped. Never throws.
|
|
147
|
+
*
|
|
148
|
+
* @param target - Agent whose turn ended
|
|
149
|
+
* @returns Asks returned to their senders
|
|
150
|
+
*/
|
|
151
|
+
async onTurnEnded(target) {
|
|
152
|
+
try {
|
|
153
|
+
this.prune();
|
|
154
|
+
const now = this.now();
|
|
155
|
+
const mine = this.asks.filter((a) => a.target === target);
|
|
156
|
+
if (mine.length === 0)
|
|
157
|
+
return 0;
|
|
158
|
+
const posted = this.posts.get(target) ?? 0;
|
|
159
|
+
const age = (a) => now - a.deliveredAt;
|
|
160
|
+
// Answered in chat, or read and let go after a short turn: drop quietly.
|
|
161
|
+
const quiet = mine.filter((a) => posted >= a.deliveredAt || (age(a) >= C.MIN_READ_MS && age(a) < C.MIN_WORK_MS));
|
|
162
|
+
const due = mine.filter((a) => posted < a.deliveredAt && age(a) >= C.MIN_WORK_MS);
|
|
163
|
+
if (quiet.length === 0 && due.length === 0)
|
|
164
|
+
return 0;
|
|
165
|
+
const settled = new Set([...quiet, ...due]);
|
|
166
|
+
this.asks = this.asks.filter((a) => !settled.has(a));
|
|
167
|
+
this.save();
|
|
168
|
+
// One message per sender, from the oldest ask it is waiting on.
|
|
169
|
+
const bySender = new Map();
|
|
170
|
+
for (const a of due)
|
|
171
|
+
if (!bySender.has(a.sender))
|
|
172
|
+
bySender.set(a.sender, a);
|
|
173
|
+
let returned = 0;
|
|
174
|
+
for (const ask of bySender.values()) {
|
|
175
|
+
const lastWords = await this.deps.readLastWords(target, ask.deliveredAt).catch(() => null);
|
|
176
|
+
const text = renderReturnedAnswer({
|
|
177
|
+
target: (this.deps.displayName ?? memberName)(target),
|
|
178
|
+
excerpt: ask.excerpt,
|
|
179
|
+
minutes: Math.max(1, Math.round((now - ask.deliveredAt) / 60_000)),
|
|
180
|
+
lastWords: lastWords ? clipResult(lastWords) : null,
|
|
181
|
+
});
|
|
182
|
+
try {
|
|
183
|
+
await this.deps.deliver(ask.sender, text);
|
|
184
|
+
returned += 1;
|
|
185
|
+
this.logger.info('Returned an unsent answer to its asker', { from: target, to: ask.sender, hadText: !!lastWords });
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
this.logger.warn('Could not return an unsent answer', { from: target, to: ask.sender, error: err instanceof Error ? err.message : String(err) });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return returned;
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
this.logger.debug('Ask settle failed', { target, error: err instanceof Error ? err.message : String(err) });
|
|
195
|
+
return 0;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
prune() {
|
|
199
|
+
const cutoff = this.now() - C.TTL_MS;
|
|
200
|
+
this.asks = this.asks.filter((a) => a.deliveredAt >= cutoff).slice(-C.MAX_ASKS);
|
|
201
|
+
for (const [s, at] of this.posts)
|
|
202
|
+
if (at < cutoff)
|
|
203
|
+
this.posts.delete(s);
|
|
204
|
+
}
|
|
205
|
+
load() {
|
|
206
|
+
if (!this.deps.file)
|
|
207
|
+
return;
|
|
208
|
+
try {
|
|
209
|
+
const raw = JSON.parse(fsSync.readFileSync(this.deps.file, 'utf-8'));
|
|
210
|
+
if (Array.isArray(raw.asks)) {
|
|
211
|
+
this.asks = raw.asks.filter((a) => !!a && typeof a.sender === 'string' && typeof a.target === 'string' && typeof a.excerpt === 'string' && typeof a.deliveredAt === 'number');
|
|
212
|
+
}
|
|
213
|
+
if (raw.posts && typeof raw.posts === 'object') {
|
|
214
|
+
for (const [s, at] of Object.entries(raw.posts))
|
|
215
|
+
if (typeof at === 'number')
|
|
216
|
+
this.posts.set(s, at);
|
|
217
|
+
}
|
|
218
|
+
this.prune();
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
// missing or unreadable: start empty
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
save() {
|
|
225
|
+
const file = this.deps.file;
|
|
226
|
+
if (!file)
|
|
227
|
+
return;
|
|
228
|
+
const data = { asks: this.asks, posts: Object.fromEntries(this.posts) };
|
|
229
|
+
this.saving = this.saving
|
|
230
|
+
.then(async () => {
|
|
231
|
+
fsSync.mkdirSync(path.dirname(file), { recursive: true });
|
|
232
|
+
await atomicWriteJson(file, data);
|
|
233
|
+
})
|
|
234
|
+
.catch((err) => {
|
|
235
|
+
this.logger.debug('Ask ledger not saved', { error: err instanceof Error ? err.message : String(err) });
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
/** Wait for pending writes (tests). */
|
|
239
|
+
async flush() {
|
|
240
|
+
await this.saving;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* The agent's last message in a transcript since a time: the text of the
|
|
245
|
+
* newest assistant entry that has text (Claude Code JSONL or Codex rollout).
|
|
246
|
+
* Subagent (sidechain), meta and API-error entries are not the agent's words.
|
|
247
|
+
*
|
|
248
|
+
* @param text - Whole JSONL lines (a tail of the file is fine)
|
|
249
|
+
* @param kind - Transcript format
|
|
250
|
+
* @param sinceMs - Ignore entries older than this (epoch ms)
|
|
251
|
+
* @returns The text, or null when there is none
|
|
252
|
+
*/
|
|
253
|
+
export function lastWordsFromTranscript(text, kind, sinceMs) {
|
|
254
|
+
let last = null;
|
|
255
|
+
for (const line of text.split('\n')) {
|
|
256
|
+
if (line.length < 20)
|
|
257
|
+
continue;
|
|
258
|
+
if (kind === 'claude' && !(line.includes('"type":"assistant"') && line.includes('"type":"text"')))
|
|
259
|
+
continue;
|
|
260
|
+
if (kind === 'codex' && !line.includes('"agent_message"') && !line.includes('"output_text"'))
|
|
261
|
+
continue;
|
|
262
|
+
let entry;
|
|
263
|
+
try {
|
|
264
|
+
entry = JSON.parse(line);
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
const at = typeof entry.timestamp === 'string' ? Date.parse(entry.timestamp) : NaN;
|
|
270
|
+
if (!Number.isFinite(at) || at < sinceMs)
|
|
271
|
+
continue;
|
|
272
|
+
let found = null;
|
|
273
|
+
if (kind === 'claude') {
|
|
274
|
+
if (entry.type !== 'assistant' || entry.isSidechain === true || entry.isMeta === true || entry.isApiErrorMessage === true)
|
|
275
|
+
continue;
|
|
276
|
+
const content = entry.message?.content;
|
|
277
|
+
if (!Array.isArray(content))
|
|
278
|
+
continue;
|
|
279
|
+
const parts = content
|
|
280
|
+
.filter((b) => !!b && b.type === 'text' && typeof b.text === 'string')
|
|
281
|
+
.map((b) => b.text.trim())
|
|
282
|
+
.filter(Boolean);
|
|
283
|
+
if (parts.length > 0)
|
|
284
|
+
found = parts.join('\n');
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
const p = entry.payload;
|
|
288
|
+
if (!p)
|
|
289
|
+
continue;
|
|
290
|
+
if (entry.type === 'event_msg' && p.type === 'agent_message' && typeof p.message === 'string')
|
|
291
|
+
found = p.message.trim();
|
|
292
|
+
else if (entry.type === 'response_item' && p.type === 'message' && p.role === 'assistant' && Array.isArray(p.content)) {
|
|
293
|
+
const parts = p.content
|
|
294
|
+
.filter((b) => b?.type === 'output_text' && typeof b.text === 'string')
|
|
295
|
+
.map((b) => b.text.trim())
|
|
296
|
+
.filter(Boolean);
|
|
297
|
+
if (parts.length > 0)
|
|
298
|
+
found = parts.join('\n');
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (found)
|
|
302
|
+
last = found;
|
|
303
|
+
}
|
|
304
|
+
return last;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Keep the end of a long text: the conclusion is at the end.
|
|
308
|
+
*
|
|
309
|
+
* @param text - Last words
|
|
310
|
+
* @returns At most {@link AGENT_ASK_CONSTANTS.RESULT_CHARS} characters
|
|
311
|
+
*/
|
|
312
|
+
function clipResult(text) {
|
|
313
|
+
const t = text.trim();
|
|
314
|
+
return t.length <= C.RESULT_CHARS ? t : `…${t.slice(-(C.RESULT_CHARS - 1))}`;
|
|
315
|
+
}
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
// Singleton
|
|
318
|
+
// ---------------------------------------------------------------------------
|
|
319
|
+
let instance = null;
|
|
320
|
+
/** @returns The wired ledger, or null before boot (and when switched off) */
|
|
321
|
+
export function getAgentAskLedger() {
|
|
322
|
+
return instance;
|
|
323
|
+
}
|
|
324
|
+
/** @param ledger - The ledger to expose (null clears) */
|
|
325
|
+
export function setAgentAskLedger(ledger) {
|
|
326
|
+
instance = ledger;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Whether the ledger is switched on.
|
|
330
|
+
*
|
|
331
|
+
* @param env - Environment
|
|
332
|
+
* @returns False when `CREWLY_AGENT_ASK_RETURN=off`
|
|
333
|
+
*/
|
|
334
|
+
export function agentAskReturnEnabled(env = process.env) {
|
|
335
|
+
return (env[C.ENV_SWITCH] ?? '').toLowerCase() !== 'off';
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=agent-ask-ledger.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-ask-ledger.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/agent-ask-ledger.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boot wiring of the agent ask ledger: the store file, the transcript reader
|
|
3
|
+
* and the delivery used to hand an unsent answer to its asker.
|
|
4
|
+
*
|
|
5
|
+
* @module services/messaging/agent-ask-ledger.wiring
|
|
6
|
+
*/
|
|
7
|
+
import { AgentAskLedger } from './agent-ask-ledger.service.js';
|
|
8
|
+
/** Bytes read from the end of a transcript: a long turn's last message is near the end. */
|
|
9
|
+
export declare const LAST_WORDS_TAIL_BYTES: number;
|
|
10
|
+
/** Where a session's transcript is (see the canvas transcript locator). */
|
|
11
|
+
export type AskTranscriptLocator = (session: string) => Promise<{
|
|
12
|
+
kind: 'claude' | 'codex';
|
|
13
|
+
file: string;
|
|
14
|
+
} | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Read the end of a file as whole lines (the first partial line is dropped).
|
|
17
|
+
*
|
|
18
|
+
* @param file - Path
|
|
19
|
+
* @param maxBytes - Bytes from the end
|
|
20
|
+
* @returns Text
|
|
21
|
+
*/
|
|
22
|
+
export declare function readTail(file: string, maxBytes?: number): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* The last words of a session since a time, secrets masked.
|
|
25
|
+
*
|
|
26
|
+
* @param locate - Transcript locator
|
|
27
|
+
* @param session - Agent session
|
|
28
|
+
* @param sinceMs - Oldest entry to read (epoch ms)
|
|
29
|
+
* @returns Text, or null (no transcript, nothing said)
|
|
30
|
+
*/
|
|
31
|
+
export declare function readLastWords(locate: AskTranscriptLocator, session: string, sinceMs: number): Promise<string | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Create and expose the ledger. Returns null when switched off.
|
|
34
|
+
*
|
|
35
|
+
* @param deps.crewlyHome - CREWLY_HOME (store file location)
|
|
36
|
+
* @param deps.sendToAgent - Delivers a harness message to an agent
|
|
37
|
+
* @param deps.locate - Transcript locator
|
|
38
|
+
* @returns The ledger, or null
|
|
39
|
+
*/
|
|
40
|
+
export declare function createAgentAskLedger(deps: {
|
|
41
|
+
crewlyHome: string;
|
|
42
|
+
sendToAgent: (session: string, text: string) => Promise<unknown>;
|
|
43
|
+
locate: AskTranscriptLocator;
|
|
44
|
+
}): AgentAskLedger | null;
|
|
45
|
+
//# sourceMappingURL=agent-ask-ledger.wiring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-ask-ledger.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/agent-ask-ledger.wiring.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAEN,cAAc,EAId,MAAM,+BAA+B,CAAC;AAEvC,2FAA2F;AAC3F,eAAO,MAAM,qBAAqB,QAAkB,CAAC;AAErD,2EAA2E;AAC3E,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAAC;AAEnH;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAA8B,GAAG,OAAO,CAAC,MAAM,CAAC,CAYtG;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAK1H;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,MAAM,EAAE,oBAAoB,CAAC;CAC7B,GAAG,cAAc,GAAG,IAAI,CAYxB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boot wiring of the agent ask ledger: the store file, the transcript reader
|
|
3
|
+
* and the delivery used to hand an unsent answer to its asker.
|
|
4
|
+
*
|
|
5
|
+
* @module services/messaging/agent-ask-ledger.wiring
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs/promises';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { collectSecretEnvValues } from '../../utils/secret-env.js';
|
|
10
|
+
import { redactSecrets } from '../../utils/secret-redactor.js';
|
|
11
|
+
import { AGENT_ASK_CONSTANTS, AgentAskLedger, agentAskReturnEnabled, lastWordsFromTranscript, setAgentAskLedger, } from './agent-ask-ledger.service.js';
|
|
12
|
+
/** Bytes read from the end of a transcript: a long turn's last message is near the end. */
|
|
13
|
+
export const LAST_WORDS_TAIL_BYTES = 2 * 1024 * 1024;
|
|
14
|
+
/**
|
|
15
|
+
* Read the end of a file as whole lines (the first partial line is dropped).
|
|
16
|
+
*
|
|
17
|
+
* @param file - Path
|
|
18
|
+
* @param maxBytes - Bytes from the end
|
|
19
|
+
* @returns Text
|
|
20
|
+
*/
|
|
21
|
+
export async function readTail(file, maxBytes = LAST_WORDS_TAIL_BYTES) {
|
|
22
|
+
const handle = await fs.open(file, 'r');
|
|
23
|
+
try {
|
|
24
|
+
const { size } = await handle.stat();
|
|
25
|
+
const start = Math.max(0, size - maxBytes);
|
|
26
|
+
const buf = Buffer.alloc(size - start);
|
|
27
|
+
await handle.read(buf, 0, buf.length, start);
|
|
28
|
+
const text = buf.toString('utf-8');
|
|
29
|
+
return start > 0 ? text.slice(text.indexOf('\n') + 1) : text;
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
await handle.close();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The last words of a session since a time, secrets masked.
|
|
37
|
+
*
|
|
38
|
+
* @param locate - Transcript locator
|
|
39
|
+
* @param session - Agent session
|
|
40
|
+
* @param sinceMs - Oldest entry to read (epoch ms)
|
|
41
|
+
* @returns Text, or null (no transcript, nothing said)
|
|
42
|
+
*/
|
|
43
|
+
export async function readLastWords(locate, session, sinceMs) {
|
|
44
|
+
const target = await locate(session);
|
|
45
|
+
if (!target)
|
|
46
|
+
return null;
|
|
47
|
+
const words = lastWordsFromTranscript(await readTail(target.file), target.kind, sinceMs);
|
|
48
|
+
return words ? redactSecrets(words, collectSecretEnvValues(process.env)) : null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create and expose the ledger. Returns null when switched off.
|
|
52
|
+
*
|
|
53
|
+
* @param deps.crewlyHome - CREWLY_HOME (store file location)
|
|
54
|
+
* @param deps.sendToAgent - Delivers a harness message to an agent
|
|
55
|
+
* @param deps.locate - Transcript locator
|
|
56
|
+
* @returns The ledger, or null
|
|
57
|
+
*/
|
|
58
|
+
export function createAgentAskLedger(deps) {
|
|
59
|
+
if (!agentAskReturnEnabled()) {
|
|
60
|
+
setAgentAskLedger(null);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const ledger = new AgentAskLedger({
|
|
64
|
+
file: path.join(deps.crewlyHome, AGENT_ASK_CONSTANTS.FILE_NAME),
|
|
65
|
+
readLastWords: (session, sinceMs) => readLastWords(deps.locate, session, sinceMs),
|
|
66
|
+
deliver: deps.sendToAgent,
|
|
67
|
+
});
|
|
68
|
+
setAgentAskLedger(ledger);
|
|
69
|
+
return ledger;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=agent-ask-ledger.wiring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-ask-ledger.wiring.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/agent-ask-ledger.wiring.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EACN,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,iBAAiB,GACjB,MAAM,+BAA+B,CAAC;AAEvC,2FAA2F;AAC3F,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAKrD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,WAAmB,qBAAqB;IACpF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC;QACJ,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QACvC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,CAAC;YAAS,CAAC;QACV,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;AACF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA4B,EAAE,OAAe,EAAE,OAAe;IACjG,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,KAAK,GAAG,uBAAuB,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzF,OAAO,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAIpC;IACA,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC9B,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC;QACjC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,SAAS,CAAC;QAC/D,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC;QACjF,OAAO,EAAE,IAAI,CAAC,WAAW;KACzB,CAAC,CAAC;IACH,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC;AACf,CAAC"}
|