letagents 0.12.15 → 0.12.17
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.
|
@@ -7,7 +7,7 @@ import { pickLocalCodename } from "../../../shared/codenames.js";
|
|
|
7
7
|
import { buildAgentActorLabel } from "../../../shared/agent-identity.js";
|
|
8
8
|
import { encodeRoomIdPath } from "../../room-id.js";
|
|
9
9
|
import { getGitCurrentBranch } from "../../git-remote.js";
|
|
10
|
-
import { apiCall, getApiUrl } from "./api.js";
|
|
10
|
+
import { apiCall, getApiUrl, getLetagentsToken } from "./api.js";
|
|
11
11
|
import { resolveOwnerContext } from "./identity/directory.js";
|
|
12
12
|
import { detectAgentIdeLabel, detectAgentRuntimeLabel } from "./identity/config.js";
|
|
13
13
|
import { getSessionLivenessRegistration } from "./identity/liveness.js";
|
|
@@ -23,7 +23,11 @@ async function workerScope() {
|
|
|
23
23
|
if (requireValidWorkerBearerRuntime().mode !== "owner") {
|
|
24
24
|
throw new Error("Worker handles are for independent MCP chats; supervised identity is supplied by its supervisor.");
|
|
25
25
|
}
|
|
26
|
+
const hasAccountToken = Boolean(await getLetagentsToken());
|
|
26
27
|
const owner = await resolveOwnerContext();
|
|
28
|
+
if (hasAccountToken && !owner.login) {
|
|
29
|
+
throw new Error("Could not verify your LetAgents account. Check your connection or sign-in, then retry with the same worker_id or registration_key. Saved worker identities have not been changed.");
|
|
30
|
+
}
|
|
27
31
|
return `${getApiUrl()}\n${owner.login?.toLowerCase() ?? `local:${owner.slug}`}`;
|
|
28
32
|
}
|
|
29
33
|
function getWorker(workerId, scope) {
|
|
@@ -43,13 +43,16 @@ export function registerTaskBoardTools(server) {
|
|
|
43
43
|
.string()
|
|
44
44
|
.optional()
|
|
45
45
|
.describe("Deprecated override. Agent identity is resolved automatically on room entry."),
|
|
46
|
+
client_task_id: z.string().trim().min(1).describe("Unique ID for this intended task. Reuse it on every retry; use a different ID for a separate task with identical contents."),
|
|
46
47
|
source_message_id: z.string().optional().describe("Optional message ID where task was agreed, e.g. 'msg_42'"),
|
|
47
48
|
...workerTaskIdentitySchema,
|
|
48
49
|
...boardIntentApprovalSchema,
|
|
49
|
-
}, async ({ title, description, created_by: _createdBy, source_message_id, room_id, conversation_id: _conversation_id, agent_session_id, board_intent_id, board_approval_token }) => {
|
|
50
|
+
}, async ({ title, description, created_by: _createdBy, source_message_id, client_task_id, room_id, conversation_id: _conversation_id, agent_session_id, board_intent_id, board_approval_token }) => {
|
|
50
51
|
const target = resolveTaskToolTarget(room_id);
|
|
51
52
|
if (!target)
|
|
52
53
|
return taskToolError("Not in a room. Join one first.");
|
|
54
|
+
if (!client_task_id?.trim())
|
|
55
|
+
return taskToolError("client_task_id is required. Choose one ID for this intended task and reuse it on every retry.");
|
|
53
56
|
const { identity, agentSession } = await resolveTaskToolIdentity(target, agent_session_id);
|
|
54
57
|
const task = await createTask(target, {
|
|
55
58
|
title,
|
|
@@ -57,10 +60,11 @@ export function registerTaskBoardTools(server) {
|
|
|
57
60
|
created_by: identity.actor_label,
|
|
58
61
|
...taskActorPayload(identity, agentSession),
|
|
59
62
|
source_message_id,
|
|
63
|
+
client_task_id,
|
|
60
64
|
board_intent_id,
|
|
61
65
|
board_approval_token,
|
|
62
66
|
});
|
|
63
|
-
await syncRoomPresence(target.effectiveRoomId, identity, getRememberedRoomPresence(target.effectiveRoomId, identity), agentSession);
|
|
67
|
+
await syncRoomPresence(target.effectiveRoomId, identity, getRememberedRoomPresence(target.effectiveRoomId, identity), agentSession).catch((error) => console.error("[tasks] Task created; presence update failed:", String(error)));
|
|
64
68
|
return jsonToolResponse({ success: true, task, agent_identity: toPublicAgentIdentity(identity) }, 2);
|
|
65
69
|
});
|
|
66
70
|
server.tool("get_board", "Get the current task board for the room. By default shows only actionable tasks " +
|
|
@@ -30,7 +30,7 @@ export function registerTaskMutationTools(server) {
|
|
|
30
30
|
await syncRoomPresence(target.effectiveRoomId, identity, {
|
|
31
31
|
status: "working",
|
|
32
32
|
status_text: `claimed ${task_id}`,
|
|
33
|
-
}, agentSession);
|
|
33
|
+
}, agentSession).catch((error) => console.error("[tasks] Task updated; presence update failed:", String(error)));
|
|
34
34
|
return jsonToolResponse({ success: true, task: updated, agent_identity: toPublicAgentIdentity(identity) }, 2);
|
|
35
35
|
}
|
|
36
36
|
catch (error) {
|
|
@@ -76,7 +76,7 @@ export function registerTaskMutationTools(server) {
|
|
|
76
76
|
await syncRoomPresence(target.effectiveRoomId, identity, {
|
|
77
77
|
status: deriveTaskPresenceStatus(status ?? null, rememberedPresence.status),
|
|
78
78
|
status_text: status ? `${task_id} -> ${status}` : rememberedPresence.status_text,
|
|
79
|
-
}, agentSession);
|
|
79
|
+
}, agentSession).catch((error) => console.error("[tasks] Task updated; presence update failed:", String(error)));
|
|
80
80
|
return jsonToolResponse({
|
|
81
81
|
success: true,
|
|
82
82
|
task: updated,
|
|
@@ -107,7 +107,7 @@ export function registerTaskMutationTools(server) {
|
|
|
107
107
|
await syncRoomPresence(target.effectiveRoomId, identity, {
|
|
108
108
|
status: "reviewing",
|
|
109
109
|
status_text: `${task_id} -> in_review`,
|
|
110
|
-
}, agentSession);
|
|
110
|
+
}, agentSession).catch((error) => console.error("[tasks] Task updated; presence update failed:", String(error)));
|
|
111
111
|
return jsonToolResponse({
|
|
112
112
|
success: true,
|
|
113
113
|
task: updated,
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { normalizeRoutingHandle, normalizeRoutingSender, routingIdentityAliases, routingSenderAliasRows, routingSenderAliases, } from "../../shared/routing-aliases.mjs";
|
|
2
2
|
import { parsePositivePgIntegerScopedId } from "./scoped-ids.js";
|
|
3
|
+
/** Send-time human fallback only; never use this to re-route historical reads. */
|
|
4
|
+
export function humanConversationFallback(input) {
|
|
5
|
+
if (input.source !== "browser" || !input.publisherAccountId || input.publisherAgentKey || input.explicitlyAddressed)
|
|
6
|
+
return null;
|
|
7
|
+
const keys = [...new Set(input.registeredAgentKeys)];
|
|
8
|
+
if (keys.length > 0 && keys.length <= 2)
|
|
9
|
+
return { reason: "small_room", agentKeys: keys };
|
|
10
|
+
if (keys.length > 2 && input.recentAgentKey && keys.includes(input.recentAgentKey)) {
|
|
11
|
+
return { reason: "recent_conversation", agentKeys: [input.recentAgentKey] };
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
3
15
|
/**
|
|
4
16
|
* Repository events can contain text written by any external contributor.
|
|
5
17
|
* They remain visible room activity, but their text is never an instruction
|