crewly 1.20.364 → 1.20.366
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/team-leader/prompt.md +2 -0
- package/config/skills/agent/core/attach-file/SKILL.md +7 -0
- package/config/skills/agent/core/attach-file/execute.sh +8 -3
- package/config/skills/agent/core/complete-task/SKILL.md +4 -2
- package/config/skills/agent/core/complete-task/execute.sh +9 -1
- package/config/skills/agent/core/complete-task/explicit-id.test.sh +13 -2
- package/config/skills/agent/core/create-task/SKILL.md +2 -0
- package/config/skills/agent/core/create-task/execute.sh +27 -1
- package/config/skills/agent/core/create-task/execute.test.sh +67 -0
- package/config/skills/agent/core/handoff-task/execute.sh +12 -5
- package/config/skills/agent/core/handoff-task/explicit-id.test.sh +70 -0
- package/config/skills/agent/core/reply/SKILL.md +10 -2
- package/config/skills/agent/core/reply-channel/SKILL.md +17 -0
- package/config/skills/agent/core/reply-channel/execute.sh +17 -2
- package/config/skills/agent/core/reply-channel/execute.test.sh +15 -2
- package/config/skills/agent/core/send-message/SKILL.md +14 -0
- package/config/skills/agent/core/slack-post/SKILL.md +3 -3
- package/config/skills/orchestrator/delegate-task/SKILL.md +1 -1
- package/config/skills/orchestrator/reply-slack/execute.sh +6 -2
- package/config/skills/orchestrator/send-pdf-to-slack/SKILL.md +2 -1
- package/config/skills/orchestrator/send-pdf-to-slack/execute.sh +10 -2
- package/config/skills/registry.json +6 -6
- package/config/skills/team-leader/delegate-task/SKILL.md +1 -1
- package/config/skills/team-leader/delegate-task/execute.sh +6 -0
- package/dist/backend/backend/src/constants.d.ts +26 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +26 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js +7 -3
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js +2 -0
- package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts +12 -0
- package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.controller.js +56 -7
- package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts +9 -0
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +159 -0
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +89 -2
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.js +58 -4
- package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +36 -2
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +9 -0
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +16 -10
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +19 -11
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/agent-message-envelope.d.ts +106 -0
- package/dist/backend/backend/src/services/messaging/agent-message-envelope.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/agent-message-envelope.js +124 -0
- package/dist/backend/backend/src/services/messaging/agent-message-envelope.js.map +1 -0
- package/dist/backend/backend/src/services/messaging/owner-hook-message.d.ts +62 -13
- package/dist/backend/backend/src/services/messaging/owner-hook-message.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-hook-message.js +196 -22
- package/dist/backend/backend/src/services/messaging/owner-hook-message.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.d.ts +15 -5
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.js +22 -0
- package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.js.map +1 -1
- package/dist/backend/backend/src/services/orc/agent-mention-post-guard.d.ts +69 -0
- package/dist/backend/backend/src/services/orc/agent-mention-post-guard.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orc/agent-mention-post-guard.js +81 -0
- package/dist/backend/backend/src/services/orc/agent-mention-post-guard.js.map +1 -0
- package/dist/backend/backend/src/services/orc/message-route.d.ts +129 -0
- package/dist/backend/backend/src/services/orc/message-route.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orc/message-route.js +197 -0
- package/dist/backend/backend/src/services/orc/message-route.js.map +1 -0
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts +34 -3
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.js +65 -8
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.js.map +1 -1
- package/dist/backend/backend/src/services/orc/owner-completion-report.text.d.ts +15 -2
- package/dist/backend/backend/src/services/orc/owner-completion-report.text.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/owner-completion-report.text.js +21 -6
- package/dist/backend/backend/src/services/orc/owner-completion-report.text.js.map +1 -1
- package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.d.ts +16 -1
- package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.js +19 -3
- package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/orc/reply-destination-resolver.d.ts +76 -4
- package/dist/backend/backend/src/services/orc/reply-destination-resolver.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/reply-destination-resolver.js +343 -45
- package/dist/backend/backend/src/services/orc/reply-destination-resolver.js.map +1 -1
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts +70 -8
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.js +256 -100
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/orc/triggered-by.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/triggered-by.js +9 -0
- package/dist/backend/backend/src/services/orc/triggered-by.js.map +1 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.d.ts +2 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.js +1 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.js.map +1 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.wiring.d.ts +16 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.wiring.js +33 -4
- package/dist/backend/backend/src/services/orc/work-item-destination.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts +1 -0
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/room-responder.d.ts +7 -3
- package/dist/backend/backend/src/services/slack/room-responder.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/room-responder.js +26 -20
- package/dist/backend/backend/src/services/slack/room-responder.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-post.service.d.ts +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-post.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-post.service.js +20 -13
- package/dist/backend/backend/src/services/slack/slack-agent-post.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +17 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +35 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts +20 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.js +58 -3
- package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +31 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +62 -5
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/trace/turn-trigger.d.ts +34 -1
- package/dist/backend/backend/src/services/trace/turn-trigger.d.ts.map +1 -1
- package/dist/backend/backend/src/services/trace/turn-trigger.js +76 -6
- package/dist/backend/backend/src/services/trace/turn-trigger.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +26 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +26 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +16 -10
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +19 -11
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/agent-message-envelope.d.ts +106 -0
- package/dist/cli/backend/src/services/messaging/agent-message-envelope.d.ts.map +1 -0
- package/dist/cli/backend/src/services/messaging/agent-message-envelope.js +124 -0
- package/dist/cli/backend/src/services/messaging/agent-message-envelope.js.map +1 -0
- package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.d.ts +15 -5
- package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.js +22 -0
- package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.js.map +1 -1
- package/dist/cli/backend/src/services/orc/message-route.d.ts +129 -0
- package/dist/cli/backend/src/services/orc/message-route.d.ts.map +1 -0
- package/dist/cli/backend/src/services/orc/message-route.js +197 -0
- package/dist/cli/backend/src/services/orc/message-route.js.map +1 -0
- package/dist/cli/backend/src/services/orc/owner-completion-report.text.d.ts +15 -2
- package/dist/cli/backend/src/services/orc/owner-completion-report.text.d.ts.map +1 -1
- package/dist/cli/backend/src/services/orc/owner-completion-report.text.js +21 -6
- package/dist/cli/backend/src/services/orc/owner-completion-report.text.js.map +1 -1
- package/dist/cli/backend/src/services/orc/work-item-destination.d.ts +2 -1
- package/dist/cli/backend/src/services/orc/work-item-destination.d.ts.map +1 -1
- package/dist/cli/backend/src/services/orc/work-item-destination.js +1 -1
- package/dist/cli/backend/src/services/orc/work-item-destination.js.map +1 -1
- package/dist/cli/backend/src/services/slack/room-responder.d.ts +7 -3
- package/dist/cli/backend/src/services/slack/room-responder.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/room-responder.js +26 -20
- package/dist/cli/backend/src/services/slack/room-responder.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +17 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +35 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.d.ts +20 -1
- package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.js +58 -3
- package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +31 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +62 -5
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/services/trace/turn-trigger.d.ts +34 -1
- package/dist/cli/backend/src/services/trace/turn-trigger.d.ts.map +1 -1
- package/dist/cli/backend/src/services/trace/turn-trigger.js +76 -6
- package/dist/cli/backend/src/services/trace/turn-trigger.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"owner-completion-report.wiring.js","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/owner-completion-report.wiring.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"owner-completion-report.wiring.js","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/owner-completion-report.wiring.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,10 +15,20 @@
|
|
|
15
15
|
* ticket thread binding) or decision card's thread;
|
|
16
16
|
* 3. the referenced work item's origin / destination;
|
|
17
17
|
* 4. validated hints (agent-supplied conversation / thread ids);
|
|
18
|
-
* 5. the
|
|
18
|
+
* 5. the sender of the agent's latest input, when that was another
|
|
19
|
+
* agent's message (crewly#1375) — never the owner's last thread;
|
|
20
|
+
* 6. the reference the harness last prompted the agent about, when newer
|
|
19
21
|
* than its last owner turn;
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
+
* 7. the route of the input the agent is answering (message-route.ts): the
|
|
23
|
+
* owner message it was given last (its turn origin), the route a
|
|
24
|
+
* delegated result carries back, or the work item a dispatch handed
|
|
25
|
+
* over; with no such input, the agent's one live work item.
|
|
26
|
+
*
|
|
27
|
+
* Nothing else. There is no guess (message-routing audit 2026-10-18, R2):
|
|
28
|
+
* not the newest owner turn when the input was something else, not the
|
|
29
|
+
* newest of several work items, not the owner DM, not a channel's top
|
|
30
|
+
* level. When nothing names the destination the reply is refused with the
|
|
31
|
+
* ids that would work.
|
|
22
32
|
*
|
|
23
33
|
* Pure decision logic; collaborators are injected
|
|
24
34
|
* (`reply-destination.wiring.ts` wires the real ones).
|
|
@@ -27,8 +37,10 @@
|
|
|
27
37
|
*/
|
|
28
38
|
import type { WorkItem } from '../../types/v2/work-item.types.js';
|
|
29
39
|
import type { TurnOrigin } from './orc-reply-route.service.js';
|
|
40
|
+
import type { TurnTrigger } from '../trace/turn-trigger.js';
|
|
30
41
|
import { type PromptReference, type ReplyReference } from './agent-prompt-reference.service.js';
|
|
31
42
|
import { type WorkDestination } from './work-item-destination.js';
|
|
43
|
+
import { type MessageRoute } from './message-route.js';
|
|
32
44
|
export type { ReplyReference } from './agent-prompt-reference.service.js';
|
|
33
45
|
/** Agent-supplied ids: hints only. */
|
|
34
46
|
export interface ReplyHints {
|
|
@@ -40,7 +52,7 @@ export interface ReplyHints {
|
|
|
40
52
|
slackChannelId?: string;
|
|
41
53
|
}
|
|
42
54
|
/** Which step decided. */
|
|
43
|
-
export type ReplyDestinationSource = 'message' | 'ticket' | 'decision' | 'work-item' | 'hint' | 'prompt' | 'turn-origin' | 'current-work' | 'owner-dm';
|
|
55
|
+
export type ReplyDestinationSource = 'message' | 'ticket' | 'decision' | 'work-item' | 'hint' | 'prompt' | 'agent-message' | 'turn-origin' | 'current-work' | 'route' | 'owner-dm';
|
|
44
56
|
/** Where the message goes. */
|
|
45
57
|
export type ReplyDestination =
|
|
46
58
|
/** A chat-v2 conversation the agent belongs to (DM / room / huddle), in `thread` (Slack key or chat-v2 root id) */
|
|
@@ -106,6 +118,33 @@ export interface ResolverDecision {
|
|
|
106
118
|
};
|
|
107
119
|
teamId?: string;
|
|
108
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* The agent's latest input, as far as routing cares: the owner, another
|
|
123
|
+
* agent (with its session), a harness dispatch of work, or anything else.
|
|
124
|
+
*/
|
|
125
|
+
export interface LatestInput {
|
|
126
|
+
kind: 'owner' | 'agent' | 'dispatch' | 'result' | 'other';
|
|
127
|
+
/** Sending agent, for `agent` and `result` */
|
|
128
|
+
sender?: string;
|
|
129
|
+
/** When it was delivered (epoch ms) */
|
|
130
|
+
at: number;
|
|
131
|
+
/** Conversation of an owner message */
|
|
132
|
+
conversationId?: string;
|
|
133
|
+
/** Slack thread key of an owner message, when it named one */
|
|
134
|
+
thread?: string;
|
|
135
|
+
/** The work item a dispatch hands over, or a result is about */
|
|
136
|
+
workItemId?: string;
|
|
137
|
+
/** The route an agent message or a result carries (what the chain answers) */
|
|
138
|
+
route?: MessageRoute;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* What the resolver needs to know about an agent's latest input, from its
|
|
142
|
+
* turn trigger.
|
|
143
|
+
*
|
|
144
|
+
* @param trigger - The session's current turn trigger, or null
|
|
145
|
+
* @returns The latest input, or null when unknown
|
|
146
|
+
*/
|
|
147
|
+
export declare function latestInputOf(trigger: TurnTrigger | null): LatestInput | null;
|
|
109
148
|
/** Collaborators. */
|
|
110
149
|
export interface ReplyResolverDeps {
|
|
111
150
|
/** A chat-v2 message by id */
|
|
@@ -156,6 +195,12 @@ export interface ReplyResolverDeps {
|
|
|
156
195
|
* any of them or for the turn origin, so it is not guessed.
|
|
157
196
|
*/
|
|
158
197
|
surfacedOwnerConversations?(session: string): string[];
|
|
198
|
+
/**
|
|
199
|
+
* The agent's latest input (turn-trigger tracker). A bare reply after
|
|
200
|
+
* another agent's message goes back to that agent; an owner turn origin
|
|
201
|
+
* older than a dispatch is not guessed (crewly#1375). Omitted: unknown.
|
|
202
|
+
*/
|
|
203
|
+
latestInput?(session: string): LatestInput | null;
|
|
159
204
|
/** Clock (epoch ms) */
|
|
160
205
|
now(): number;
|
|
161
206
|
}
|
|
@@ -227,4 +272,31 @@ export declare function promptIsCurrent(session: string, prompt: PromptReference
|
|
|
227
272
|
* @returns The destination and the hints that were ignored
|
|
228
273
|
*/
|
|
229
274
|
export declare function resolveReplyDestination(input: ReplyResolveInput, deps: ReplyResolverDeps): Promise<ReplyResolution>;
|
|
275
|
+
/**
|
|
276
|
+
* The owner's turn origin, when the owner message behind it is the latest
|
|
277
|
+
* input that names what the agent answers. Otherwise the origin is just
|
|
278
|
+
* "the agent's last owner thread", which says nothing about this reply.
|
|
279
|
+
*
|
|
280
|
+
* @param origin - The agent's turn origin
|
|
281
|
+
* @param latest - Its latest routed input
|
|
282
|
+
* @returns The origin, or undefined
|
|
283
|
+
*/
|
|
284
|
+
export declare function answeredOwnerOrigin(origin: TurnOrigin | undefined, latest: LatestInput | null): TurnOrigin | undefined;
|
|
285
|
+
/**
|
|
286
|
+
* The agent's live work items (running / accepted), oldest first.
|
|
287
|
+
*
|
|
288
|
+
* @param items - Pool items
|
|
289
|
+
* @param session - Agent
|
|
290
|
+
* @returns Its live items
|
|
291
|
+
*/
|
|
292
|
+
export declare function liveItemsOf(items: readonly WorkItem[], session: string): WorkItem[];
|
|
293
|
+
/**
|
|
294
|
+
* Where a route goes.
|
|
295
|
+
*
|
|
296
|
+
* @param session - Replying agent
|
|
297
|
+
* @param route - The route
|
|
298
|
+
* @param deps - Collaborators
|
|
299
|
+
* @returns The destination (source `route`), or `unresolved`
|
|
300
|
+
*/
|
|
301
|
+
export declare function resolveRoute(session: string, route: MessageRoute, deps: ReplyResolverDeps): Promise<ReplyDestination>;
|
|
230
302
|
//# sourceMappingURL=reply-destination-resolver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reply-destination-resolver.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/reply-destination-resolver.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"reply-destination-resolver.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/reply-destination-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,10 +15,20 @@
|
|
|
15
15
|
* ticket thread binding) or decision card's thread;
|
|
16
16
|
* 3. the referenced work item's origin / destination;
|
|
17
17
|
* 4. validated hints (agent-supplied conversation / thread ids);
|
|
18
|
-
* 5. the
|
|
18
|
+
* 5. the sender of the agent's latest input, when that was another
|
|
19
|
+
* agent's message (crewly#1375) — never the owner's last thread;
|
|
20
|
+
* 6. the reference the harness last prompted the agent about, when newer
|
|
19
21
|
* than its last owner turn;
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
+
* 7. the route of the input the agent is answering (message-route.ts): the
|
|
23
|
+
* owner message it was given last (its turn origin), the route a
|
|
24
|
+
* delegated result carries back, or the work item a dispatch handed
|
|
25
|
+
* over; with no such input, the agent's one live work item.
|
|
26
|
+
*
|
|
27
|
+
* Nothing else. There is no guess (message-routing audit 2026-10-18, R2):
|
|
28
|
+
* not the newest owner turn when the input was something else, not the
|
|
29
|
+
* newest of several work items, not the owner DM, not a channel's top
|
|
30
|
+
* level. When nothing names the destination the reply is refused with the
|
|
31
|
+
* ids that would work.
|
|
22
32
|
*
|
|
23
33
|
* Pure decision logic; collaborators are injected
|
|
24
34
|
* (`reply-destination.wiring.ts` wires the real ones).
|
|
@@ -29,7 +39,34 @@ import { REPLY_ROUTING_CONSTANTS, SLACK_THREAD_KEY_CONSTANTS } from '../../const
|
|
|
29
39
|
import { parseTicketNumber } from '../../types/v2/ticket.types.js';
|
|
30
40
|
import { formatSlackThreadKey, parseSlackThreadKey } from '../slack/slack-thread-key.js';
|
|
31
41
|
import { hasReference } from './agent-prompt-reference.service.js';
|
|
32
|
-
import {
|
|
42
|
+
import { leadReportOf, originOfWorkItem, planWorkDestination } from './work-item-destination.js';
|
|
43
|
+
import { describeRoute, replyCommandFor } from './message-route.js';
|
|
44
|
+
/**
|
|
45
|
+
* What the resolver needs to know about an agent's latest input, from its
|
|
46
|
+
* turn trigger.
|
|
47
|
+
*
|
|
48
|
+
* @param trigger - The session's current turn trigger, or null
|
|
49
|
+
* @returns The latest input, or null when unknown
|
|
50
|
+
*/
|
|
51
|
+
export function latestInputOf(trigger) {
|
|
52
|
+
if (!trigger)
|
|
53
|
+
return null;
|
|
54
|
+
const route = trigger.route ? { route: trigger.route } : {};
|
|
55
|
+
switch (trigger.triggerKind) {
|
|
56
|
+
case 'owner_message':
|
|
57
|
+
return { kind: 'owner', at: trigger.at, ...(trigger.conversationId ? { conversationId: trigger.conversationId } : {}), ...(trigger.thread ? { thread: trigger.thread } : {}) };
|
|
58
|
+
case 'agent_message':
|
|
59
|
+
return trigger.sender ? { kind: 'agent', sender: trigger.sender, at: trigger.at, ...route } : { kind: 'other', at: trigger.at };
|
|
60
|
+
case 'delegated_result':
|
|
61
|
+
return { kind: 'result', at: trigger.at, ...(trigger.sender ? { sender: trigger.sender } : {}), ...(trigger.workItemId ? { workItemId: trigger.workItemId } : {}), ...route };
|
|
62
|
+
// New work the harness handed over; a reminder or a redelivery nag is not.
|
|
63
|
+
case 'dispatch':
|
|
64
|
+
case 'scheduled':
|
|
65
|
+
return { kind: 'dispatch', at: trigger.at, ...(trigger.workItemId ? { workItemId: trigger.workItemId } : {}) };
|
|
66
|
+
default:
|
|
67
|
+
return { kind: 'other', at: trigger.at };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
33
70
|
/**
|
|
34
71
|
* The thread an answer to `msg` belongs in: its Slack thread key when the
|
|
35
72
|
* conversation is mirrored to Slack and the message knows its Slack thread,
|
|
@@ -250,11 +287,18 @@ export async function validateHints(session, hints, origin, deps) {
|
|
|
250
287
|
ignored,
|
|
251
288
|
};
|
|
252
289
|
}
|
|
290
|
+
// Work delegated into this thread (the delegate is not in the room): the
|
|
291
|
+
// thread named by its chat id is the same Slack thread as its key (#1109).
|
|
292
|
+
if (msg && (!conv || msg.channelId === conv)) {
|
|
293
|
+
const delegated = await delegatedSlackThread(session, parseSlackThreadKey(threadOfMessage(msg, deps.slackChannelOfConversation(msg.channelId))), deps);
|
|
294
|
+
if (delegated)
|
|
295
|
+
return { destination: delegated, ignored };
|
|
296
|
+
}
|
|
253
297
|
ignored.push({ hint: `thread ${rawThread}`, why: !msg ? 'no such message' : msg.channelId !== conv && conv ? `that message is not in conversation ${conv}` : 'you are not in its conversation' });
|
|
254
298
|
// A thread that is ANOTHER conversation's message contradicts the
|
|
255
299
|
// conversation: neither is used. An unknown id only loses the thread.
|
|
256
300
|
if (conv && msg) {
|
|
257
|
-
ignored.push({ hint: `conversation ${conv}`, why: 'its thread is in another conversation' });
|
|
301
|
+
ignored.push({ hint: `conversation ${conv}`, why: msg.channelId === conv ? 'you are not in that conversation' : 'its thread is in another conversation' });
|
|
258
302
|
return { destination: null, ignored };
|
|
259
303
|
}
|
|
260
304
|
if (!conv)
|
|
@@ -262,13 +306,82 @@ export async function validateHints(session, hints, origin, deps) {
|
|
|
262
306
|
}
|
|
263
307
|
if (conv) {
|
|
264
308
|
if (await deps.ownsConversation(session, conv)) {
|
|
309
|
+
// The thread comes only from the owner message the agent is answering
|
|
310
|
+
// (`origin` is passed only then), never from its last owner thread in
|
|
311
|
+
// that conversation (message-routing audit 2026-10-18, R2).
|
|
265
312
|
const thread = origin?.conversationId === conv ? origin.slackThreadKey ?? origin.chatThreadId : undefined;
|
|
266
|
-
|
|
313
|
+
if (!thread && needsThread(deps.slackChannelOfConversation(conv))) {
|
|
314
|
+
ignored.push({ hint: `conversation ${conv}`, why: 'it is a Slack channel, no usable thread was named, and the message you are answering is not in it; name the thread with --thread <[SLACK-THREAD:…] key or message id>' });
|
|
315
|
+
return { destination: null, ignored };
|
|
316
|
+
}
|
|
317
|
+
return { destination: { kind: 'conversation', conversationId: conv, ...(thread ? { thread } : {}), source: 'hint', reason: thread ? 'named the conversation of the owner message it answers' : 'named its own conversation' }, ignored };
|
|
267
318
|
}
|
|
319
|
+
// Not in the room, but the current work was delegated into one of its
|
|
320
|
+
// Slack threads: that thread, never the room's top level (2026-10-18:
|
|
321
|
+
// Kai's PDF for Steve's #daily-info thread was posted top level).
|
|
322
|
+
const workThread = await currentWorkThreadIn(session, conv, deps);
|
|
323
|
+
const delegated = await delegatedSlackThread(session, workThread, deps);
|
|
324
|
+
if (delegated)
|
|
325
|
+
return { destination: delegated, ignored };
|
|
268
326
|
ignored.push({ hint: `conversation ${conv}`, why: 'not a conversation you are in' });
|
|
269
327
|
}
|
|
270
328
|
return { destination: null, ignored };
|
|
271
329
|
}
|
|
330
|
+
/**
|
|
331
|
+
* The Slack thread a non-member may post in because its open work was
|
|
332
|
+
* delegated into it (#1109), as a destination.
|
|
333
|
+
*
|
|
334
|
+
* @param session - Agent
|
|
335
|
+
* @param key - The thread, if known
|
|
336
|
+
* @param deps - Collaborators
|
|
337
|
+
* @returns The Slack destination, or null when the thread was not delegated to the agent
|
|
338
|
+
*/
|
|
339
|
+
async function delegatedSlackThread(session, key, deps) {
|
|
340
|
+
if (!key || !deps.delegatedThread)
|
|
341
|
+
return null;
|
|
342
|
+
if (!(await deps.delegatedThread(session, key.slackChannelId, key.threadTs).catch(() => false)))
|
|
343
|
+
return null;
|
|
344
|
+
const keyText = formatSlackThreadKey(key.slackChannelId, key.threadTs);
|
|
345
|
+
const reason = `Slack thread ${keyText} was delegated to you`;
|
|
346
|
+
return { kind: 'work', destination: { kind: 'slack', target: key.slackChannelId, threadTs: key.threadTs, reason }, source: 'hint', reason };
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* The Slack thread of a conversation the agent's open work came from (an
|
|
350
|
+
* owner origin in that conversation with a Slack thread). Only when that is
|
|
351
|
+
* ONE thread: with two pieces of work from different threads of the room,
|
|
352
|
+
* the newest is not a safe guess, and the caller fails loudly instead.
|
|
353
|
+
*
|
|
354
|
+
* @param session - Agent
|
|
355
|
+
* @param conversationId - chat-v2 conversation
|
|
356
|
+
* @param deps - Collaborators
|
|
357
|
+
* @returns The thread, or null when there is none or more than one
|
|
358
|
+
*/
|
|
359
|
+
async function currentWorkThreadIn(session, conversationId, deps) {
|
|
360
|
+
const items = await deps.poolItems().catch(() => []);
|
|
361
|
+
const threads = new Map();
|
|
362
|
+
for (const wi of items) {
|
|
363
|
+
if (wi.target !== session || !OPEN_WORK_STATUSES.has(wi.status))
|
|
364
|
+
continue;
|
|
365
|
+
const origin = originOfWorkItem(wi);
|
|
366
|
+
if (origin?.kind !== 'owner' || origin.conversationId !== conversationId || !origin.slackChannelId || !origin.threadTs)
|
|
367
|
+
continue;
|
|
368
|
+
threads.set(formatSlackThreadKey(origin.slackChannelId, origin.threadTs), { slackChannelId: origin.slackChannelId, threadTs: origin.threadTs });
|
|
369
|
+
}
|
|
370
|
+
return threads.size === 1 ? [...threads.values()][0] : null;
|
|
371
|
+
}
|
|
372
|
+
/** Work an agent still owes an answer for. */
|
|
373
|
+
const OPEN_WORK_STATUSES = new Set(['queued', 'proposed', 'accepted', 'running', 'blocked', 'escalated']);
|
|
374
|
+
/**
|
|
375
|
+
* Whether a post into a conversation must name a thread: a Slack channel
|
|
376
|
+
* (not a DM). A chat-only conversation or a Slack DM takes a post at its
|
|
377
|
+
* top level.
|
|
378
|
+
*
|
|
379
|
+
* @param slackChannelId - The conversation's Slack channel, or null
|
|
380
|
+
* @returns True for a Slack channel
|
|
381
|
+
*/
|
|
382
|
+
function needsThread(slackChannelId) {
|
|
383
|
+
return !!slackChannelId && /^[CG]/.test(slackChannelId);
|
|
384
|
+
}
|
|
272
385
|
/**
|
|
273
386
|
* Whether a prompt reference may steer a bare reply: the agent owes the
|
|
274
387
|
* owner nothing, and the last message delivered to it is that prompt.
|
|
@@ -303,9 +416,13 @@ export async function resolveReplyDestination(input, deps) {
|
|
|
303
416
|
return { destination: d, ignoredHints };
|
|
304
417
|
}
|
|
305
418
|
const origin = deps.turnOrigin(session);
|
|
419
|
+
const latest = deps.latestInput?.(session) ?? null;
|
|
420
|
+
// The owner message the agent is answering: its turn origin, only while
|
|
421
|
+
// that message is the latest input naming what the agent answers.
|
|
422
|
+
const answered = answeredOwnerOrigin(origin, latest);
|
|
306
423
|
// 4. Hints the harness can stand behind.
|
|
307
424
|
if (input.hints && (input.hints.conversationId || input.hints.thread)) {
|
|
308
|
-
const v = await validateHints(session, input.hints,
|
|
425
|
+
const v = await validateHints(session, input.hints, answered, deps);
|
|
309
426
|
ignoredHints.push(...v.ignored);
|
|
310
427
|
if (v.destination)
|
|
311
428
|
return { destination: v.destination, ignoredHints };
|
|
@@ -320,7 +437,13 @@ export async function resolveReplyDestination(input, deps) {
|
|
|
320
437
|
ignoredHints,
|
|
321
438
|
};
|
|
322
439
|
}
|
|
323
|
-
// 5.
|
|
440
|
+
// 5. The latest input was another agent's message: the answer goes back to
|
|
441
|
+
// that agent (agent-to-agent), never into the owner's last thread
|
|
442
|
+
// (crewly#1375: Pia's answer to Atlas landed in the owner's video thread).
|
|
443
|
+
if (latest?.kind === 'agent' && latest.sender && latest.sender !== session) {
|
|
444
|
+
return { destination: await answerToAgent(session, latest, origin, deps), ignoredHints };
|
|
445
|
+
}
|
|
446
|
+
// 6. What the harness last prompted the agent about — only when the agent
|
|
324
447
|
// owes the owner nothing and that prompt is the last thing it was given:
|
|
325
448
|
// a bare answer to a 10:00 owner question must not land in the thread of
|
|
326
449
|
// a 10:02 TKT-150 nudge (and close its promise).
|
|
@@ -329,62 +452,237 @@ export async function resolveReplyDestination(input, deps) {
|
|
|
329
452
|
if (d && d.kind !== 'unresolved')
|
|
330
453
|
return { destination: { ...d, source: 'prompt', reason: `the harness prompted you about it (${d.reason})` }, ignoredHints };
|
|
331
454
|
}
|
|
332
|
-
//
|
|
333
|
-
//
|
|
334
|
-
//
|
|
335
|
-
const
|
|
455
|
+
// 7. The route of the input being answered. An owner message from another
|
|
456
|
+
// conversation shown mid-turn makes even that unsafe: the answer to it
|
|
457
|
+
// landed in the turn origin's thread (Ella, 2026-10-06).
|
|
458
|
+
const routed = await fromLatestInput(input, deps, origin, answered, latest);
|
|
336
459
|
const pending = deps.surfacedOwnerConversations?.(session) ?? [];
|
|
337
|
-
const
|
|
338
|
-
const others = [...new Set(pending.filter((c) => c !==
|
|
339
|
-
if (others.length > 0 &&
|
|
340
|
-
const options = [...(
|
|
460
|
+
const routedConv = routed.kind === 'conversation' ? routed.conversationId : undefined;
|
|
461
|
+
const others = [...new Set(pending.filter((c) => c !== routedConv))];
|
|
462
|
+
if (others.length > 0 && routed.kind !== 'unresolved') {
|
|
463
|
+
const options = [...(routedConv ? [routedConv] : []), ...others];
|
|
341
464
|
return {
|
|
342
465
|
destination: {
|
|
343
466
|
kind: 'unresolved',
|
|
344
467
|
reason: `more than one owner conversation is waiting on you (${options.join(', ')}) — say which one this reply is for`,
|
|
345
|
-
fix: `reply --conversation ${others[0]} "<your message>" (or
|
|
468
|
+
fix: `reply --conversation ${others[0]} --thread <its thread> "<your message>" (or ${answered ? `--conversation ${answered.conversationId}${answered.slackThreadKey ?? answered.chatThreadId ? ` --thread ${answered.slackThreadKey ?? answered.chatThreadId}` : ''}` : '--conversation <id> --thread <thread>'} for the message your turn started with)`,
|
|
346
469
|
},
|
|
347
470
|
ignoredHints,
|
|
348
471
|
};
|
|
349
472
|
}
|
|
350
|
-
return {
|
|
473
|
+
return { destination: routed, ignoredHints };
|
|
351
474
|
}
|
|
352
475
|
/**
|
|
353
|
-
*
|
|
354
|
-
*
|
|
476
|
+
* The owner's turn origin, when the owner message behind it is the latest
|
|
477
|
+
* input that names what the agent answers. Otherwise the origin is just
|
|
478
|
+
* "the agent's last owner thread", which says nothing about this reply.
|
|
479
|
+
*
|
|
480
|
+
* @param origin - The agent's turn origin
|
|
481
|
+
* @param latest - Its latest routed input
|
|
482
|
+
* @returns The origin, or undefined
|
|
355
483
|
*/
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
484
|
+
export function answeredOwnerOrigin(origin, latest) {
|
|
485
|
+
if (!origin || latest?.kind !== 'owner')
|
|
486
|
+
return undefined;
|
|
487
|
+
if (latest.conversationId && latest.conversationId !== origin.conversationId)
|
|
488
|
+
return undefined;
|
|
489
|
+
return origin;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Whether a route is the replying agent's own: an owner conversation it is in,
|
|
493
|
+
* or a work item targeted at it. A message from another agent that carries
|
|
494
|
+
* such a route is about the replier's own request, so a bare reply could be
|
|
495
|
+
* meant for that agent or for the owner.
|
|
496
|
+
*
|
|
497
|
+
* @param session - Replying agent
|
|
498
|
+
* @param route - The route the message carries
|
|
499
|
+
* @param deps - Collaborators
|
|
500
|
+
* @returns True when the route is the replier's
|
|
501
|
+
*/
|
|
502
|
+
async function isOwnRoute(session, route, deps) {
|
|
503
|
+
if (route.kind === 'owner')
|
|
504
|
+
return deps.ownsConversation(session, route.conversationId).catch(() => false);
|
|
505
|
+
const wi = await deps.workItem(route.workItemId).catch(() => null);
|
|
506
|
+
return wi?.target === session;
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Step 5 of {@link resolveReplyDestination}: the answer to another agent's
|
|
510
|
+
* message goes back to that agent — unless the agent also owes the owner an
|
|
511
|
+
* answer, holds work whose answer goes elsewhere, or the message is about the
|
|
512
|
+
* agent's own request (its route): then a bare reply could mean either, and
|
|
513
|
+
* the agent is told to name it.
|
|
514
|
+
*
|
|
515
|
+
* @param session - Replying agent
|
|
516
|
+
* @param latest - The other agent's message (the latest input)
|
|
517
|
+
* @param origin - The replying agent's owner turn origin, if any
|
|
518
|
+
* @param deps - Collaborators
|
|
519
|
+
* @returns The sender as destination, or `unresolved` with both commands
|
|
520
|
+
*/
|
|
521
|
+
async function answerToAgent(session, latest, origin, deps) {
|
|
522
|
+
const sender = latest.sender;
|
|
523
|
+
const toAgent = `send-message --to ${sender} "<your answer>" (to answer ${sender})`;
|
|
524
|
+
const ownRoute = latest.route && (await isOwnRoute(session, latest.route, deps)) ? latest.route : undefined;
|
|
525
|
+
if (ownRoute) {
|
|
526
|
+
return {
|
|
527
|
+
kind: 'unresolved',
|
|
528
|
+
reason: `your latest message is from ${sender} (another agent) about ${describeRoute(ownRoute)}, which you answer — say whether this reply is for ${sender} or for the owner`,
|
|
529
|
+
fix: `${toAgent}, or ${replyCommandFor(ownRoute)} (the consolidated answer for the owner)`,
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
const forOwner = origin
|
|
533
|
+
? `reply --conversation ${origin.conversationId}${origin.slackThreadKey ?? origin.chatThreadId ? ` --thread ${origin.slackThreadKey ?? origin.chatThreadId}` : ''} "<message>"`
|
|
534
|
+
: 'reply --to <message id from the owner\'s message> "<message>"';
|
|
535
|
+
const pendingOwner = deps.owesOwner(session) || (deps.surfacedOwnerConversations?.(session) ?? []).length > 0;
|
|
536
|
+
if (pendingOwner) {
|
|
537
|
+
return {
|
|
538
|
+
kind: 'unresolved',
|
|
539
|
+
reason: `your latest message is from ${sender} (another agent, not the owner), and you also owe the owner an answer — say which one this reply is for`,
|
|
540
|
+
fix: `${toAgent}, or ${forOwner} (to answer the owner)`,
|
|
541
|
+
};
|
|
542
|
+
}
|
|
360
543
|
const items = await deps.poolItems().catch(() => []);
|
|
361
|
-
const workItem
|
|
362
|
-
|
|
544
|
+
for (const workItem of liveItemsOf(items, session)) {
|
|
545
|
+
if (!originOfWorkItem(workItem))
|
|
546
|
+
continue;
|
|
547
|
+
const planned = planWorkDestination({ workItem, now: deps.now() });
|
|
548
|
+
if (!(planned.kind === 'agent' && planned.sessionName === sender)) {
|
|
549
|
+
return {
|
|
550
|
+
kind: 'unresolved',
|
|
551
|
+
reason: `your latest message is from ${sender} (another agent), but you are also on work item ${workItem.id} whose answer goes elsewhere — say which one this reply is for`,
|
|
552
|
+
fix: `${toAgent}, or reply --work-item ${workItem.id} "<message>" (for the work item)`,
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
const reason = `answering ${sender}'s message (another agent, not the owner)`;
|
|
557
|
+
return { kind: 'work', destination: { kind: 'agent', sessionName: sender, reason }, source: 'agent-message', reason };
|
|
558
|
+
}
|
|
559
|
+
/** Statuses in which a work item is live work of its target. */
|
|
560
|
+
const LIVE_STATUSES = new Set(['running', 'accepted']);
|
|
561
|
+
/**
|
|
562
|
+
* The agent's live work items (running / accepted), oldest first.
|
|
563
|
+
*
|
|
564
|
+
* @param items - Pool items
|
|
565
|
+
* @param session - Agent
|
|
566
|
+
* @returns Its live items
|
|
567
|
+
*/
|
|
568
|
+
export function liveItemsOf(items, session) {
|
|
569
|
+
return items
|
|
570
|
+
.filter((w) => w.target === session && LIVE_STATUSES.has(w.status))
|
|
571
|
+
.sort((a, b) => (Date.parse(a.startedAt ?? a.createdAt) || 0) - (Date.parse(b.startedAt ?? b.createdAt) || 0));
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Where a work item's answer goes, refusing the places that are not a
|
|
575
|
+
* destination it names: a work item with no origin, or an owner origin with
|
|
576
|
+
* no place, is not posted at a channel's top level.
|
|
577
|
+
*
|
|
578
|
+
* @param wi - Work item
|
|
579
|
+
* @param session - Replying agent
|
|
580
|
+
* @param deps - Collaborators
|
|
581
|
+
* @returns The destination, or `unresolved`
|
|
582
|
+
*/
|
|
583
|
+
function destinationOfWorkItem(wi, session, deps) {
|
|
584
|
+
const noPlace = {
|
|
585
|
+
kind: 'unresolved',
|
|
586
|
+
reason: `work item ${wi.id} names no conversation or thread to answer in`,
|
|
587
|
+
fix: 'reply --to <owner message id> "<message>", or reply --conversation <id> --thread <thread> "<message>"',
|
|
588
|
+
};
|
|
589
|
+
const origin = originOfWorkItem(wi);
|
|
590
|
+
if (!origin)
|
|
591
|
+
return noPlace;
|
|
592
|
+
const planned = planWorkDestination({ workItem: wi, now: deps.now() });
|
|
363
593
|
if (planned.kind === 'owner-origin') {
|
|
364
594
|
const o = planned.origin;
|
|
365
595
|
const thread = o.slackThreadKey ?? o.chatThreadId;
|
|
366
|
-
|
|
367
|
-
return {
|
|
368
|
-
destination: { kind: 'conversation', conversationId: o.conversationId, ...(thread ? { thread } : {}), source: fromOwner ? 'turn-origin' : 'current-work', reason: planned.reason },
|
|
369
|
-
ignoredHints,
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
const isScheduled = !!workItem && originOfWorkItem(workItem)?.kind === 'trigger';
|
|
373
|
-
// Team work its lead reports in the team channel (crewly#1371) goes there, not to the owner DM.
|
|
374
|
-
const isLeadReported = !!workItem && !!leadReportOf(workItem);
|
|
375
|
-
if (planned.kind !== 'new-top-level' || isScheduled || isLeadReported) {
|
|
376
|
-
return { destination: { kind: 'work', destination: planned, source: 'current-work', reason: planned.reason }, ignoredHints };
|
|
596
|
+
return { kind: 'conversation', conversationId: o.conversationId, ...(thread ? { thread } : {}), source: 'current-work', reason: planned.reason };
|
|
377
597
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
return
|
|
598
|
+
if (planned.kind === 'agent' && planned.sessionName === session)
|
|
599
|
+
return noPlace;
|
|
600
|
+
// A top-level post only for work whose origin says so: a scheduled task, or
|
|
601
|
+
// team work its lead reports in the team channel (crewly#1371).
|
|
602
|
+
if (planned.kind === 'new-top-level' && origin.kind !== 'trigger' && !leadReportOf(wi))
|
|
603
|
+
return noPlace;
|
|
604
|
+
return { kind: 'work', destination: planned, source: 'current-work', reason: planned.reason };
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Where a route goes.
|
|
608
|
+
*
|
|
609
|
+
* @param session - Replying agent
|
|
610
|
+
* @param route - The route
|
|
611
|
+
* @param deps - Collaborators
|
|
612
|
+
* @returns The destination (source `route`), or `unresolved`
|
|
613
|
+
*/
|
|
614
|
+
export async function resolveRoute(session, route, deps) {
|
|
615
|
+
if (route.kind === 'work-item') {
|
|
616
|
+
const wi = await deps.workItem(route.workItemId).catch(() => null);
|
|
617
|
+
if (!wi)
|
|
618
|
+
return { kind: 'unresolved', reason: `there is no work item ${route.workItemId}`, fix: 'reply --to <owner message id> "<message>"' };
|
|
619
|
+
const d = destinationOfWorkItem(wi, session, deps);
|
|
620
|
+
return d.kind === 'unresolved' ? d : { ...d, source: 'route', reason: `the request this answers (${describeRoute(route)}): ${d.reason}` };
|
|
384
621
|
}
|
|
622
|
+
const v = await validateHints(session, { conversationId: route.conversationId, ...(route.thread ? { thread: route.thread } : {}) }, undefined, deps);
|
|
623
|
+
if (v.destination)
|
|
624
|
+
return { ...v.destination, source: 'route', reason: `the request this answers (${describeRoute(route)})` };
|
|
385
625
|
return {
|
|
386
|
-
|
|
387
|
-
|
|
626
|
+
kind: 'unresolved',
|
|
627
|
+
reason: `the request this answers is ${describeRoute(route)}, and you cannot post there (${v.ignored.map((i) => `${i.hint}: ${i.why}`).join('; ') || 'not a conversation you are in'})`,
|
|
628
|
+
fix: 'send the answer to the agent who asked you (send-message --to <agent>), so it answers the owner',
|
|
388
629
|
};
|
|
389
630
|
}
|
|
631
|
+
/**
|
|
632
|
+
* Step 7 of {@link resolveReplyDestination}: the route of the latest input
|
|
633
|
+
* that names what the agent answers. Never a guess: when that input names no
|
|
634
|
+
* place, the agent is told which ids would work.
|
|
635
|
+
*
|
|
636
|
+
* @param input - Agent
|
|
637
|
+
* @param deps - Collaborators
|
|
638
|
+
* @param origin - Its turn origin
|
|
639
|
+
* @param answered - Its turn origin when the owner message behind it is the input answered
|
|
640
|
+
* @param latest - Its latest routed input
|
|
641
|
+
* @returns The destination, or `unresolved`
|
|
642
|
+
*/
|
|
643
|
+
async function fromLatestInput(input, deps, origin, answered, latest) {
|
|
644
|
+
const { session } = input;
|
|
645
|
+
const items = await deps.poolItems().catch(() => []);
|
|
646
|
+
const live = liveItemsOf(items, session);
|
|
647
|
+
const options = [
|
|
648
|
+
...live.map((w) => `reply --work-item ${w.id} "<message>" (${JSON.stringify(w.title.slice(0, 60))})`),
|
|
649
|
+
...(origin ? [`reply --conversation ${origin.conversationId}${origin.slackThreadKey ?? origin.chatThreadId ? ` --thread ${origin.slackThreadKey ?? origin.chatThreadId}` : ''} "<message>" (the owner's last message to you)`] : []),
|
|
650
|
+
];
|
|
651
|
+
const refuse = (reason) => ({
|
|
652
|
+
kind: 'unresolved',
|
|
653
|
+
reason,
|
|
654
|
+
fix: options.length > 0 ? options.join('; or ') : 'reply --to <message id from your prompt> "<message>" (or --work-item <id> / --ticket <id>)',
|
|
655
|
+
});
|
|
656
|
+
if (latest?.kind === 'owner') {
|
|
657
|
+
if (!answered)
|
|
658
|
+
return refuse('Crewly does not know which thread the owner message you are answering is in');
|
|
659
|
+
const thread = answered.slackThreadKey ?? answered.chatThreadId;
|
|
660
|
+
return { kind: 'conversation', conversationId: answered.conversationId, ...(thread ? { thread } : {}), source: 'turn-origin', reason: 'answering the owner message you were given last' };
|
|
661
|
+
}
|
|
662
|
+
if (latest?.kind === 'result') {
|
|
663
|
+
const sender = latest.sender ?? 'your delegate';
|
|
664
|
+
if (!latest.route) {
|
|
665
|
+
return refuse(`your latest message is ${sender}'s result for work you delegated, and nothing names where the answer goes (you delegated it while answering no owner message or work item)`);
|
|
666
|
+
}
|
|
667
|
+
return resolveRoute(session, latest.route, deps);
|
|
668
|
+
}
|
|
669
|
+
if (latest?.kind === 'dispatch' && latest.workItemId) {
|
|
670
|
+
const wi = await deps.workItem(latest.workItemId).catch(() => null);
|
|
671
|
+
if (!wi)
|
|
672
|
+
return refuse(`the work item you were handed (${latest.workItemId}) is not in the pool`);
|
|
673
|
+
// An owner message delivered before the dispatch is still unanswered:
|
|
674
|
+
// a bare reply could be for either (crewly#1375).
|
|
675
|
+
if (origin && origin.receivedAt < latest.at && deps.owesOwner(session)) {
|
|
676
|
+
return refuse(`a dispatch came in after the owner's message in conversation ${origin.conversationId}, and you still owe the owner an answer — say which one this reply is for`);
|
|
677
|
+
}
|
|
678
|
+
return destinationOfWorkItem(wi, session, deps);
|
|
679
|
+
}
|
|
680
|
+
// Nothing names what this reply answers: only the agent's ONE live work
|
|
681
|
+
// item is unambiguous. Several are never resolved to the newest.
|
|
682
|
+
if (live.length === 1)
|
|
683
|
+
return destinationOfWorkItem(live[0], session, deps);
|
|
684
|
+
if (live.length > 1)
|
|
685
|
+
return refuse(`you have ${live.length} live work items and your latest input names none of them — say which one this reply is for`);
|
|
686
|
+
return refuse('nothing you were given names where this reply goes (no owner message, work item or agent message you are answering)');
|
|
687
|
+
}
|
|
390
688
|
//# sourceMappingURL=reply-destination-resolver.js.map
|