letagents 0.10.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mcp/codenames.js +154 -0
- package/dist/mcp/local-state.js +6 -0
- package/dist/mcp/server.js +108 -142
- package/package.json +1 -1
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent codenames — extracted from server.ts per Emmy's directive.
|
|
3
|
+
*
|
|
4
|
+
* Each agent instance gets a two-word codename (e.g. "River Valley")
|
|
5
|
+
* deterministically derived from its runtime key via SHA-256 hashing.
|
|
6
|
+
*/
|
|
7
|
+
import { createHash } from "crypto";
|
|
8
|
+
import { toTitleCaseCodename } from "../shared/agent-identity.js";
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Codenames
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
export const AGENT_CODENAMES = [
|
|
13
|
+
"amber",
|
|
14
|
+
"anchor",
|
|
15
|
+
"autumn",
|
|
16
|
+
"badger",
|
|
17
|
+
"bay",
|
|
18
|
+
"bear",
|
|
19
|
+
"brook",
|
|
20
|
+
"calm",
|
|
21
|
+
"canyon",
|
|
22
|
+
"cedar",
|
|
23
|
+
"clear",
|
|
24
|
+
"cloud",
|
|
25
|
+
"comet",
|
|
26
|
+
"copper",
|
|
27
|
+
"creek",
|
|
28
|
+
"crisp",
|
|
29
|
+
"crest",
|
|
30
|
+
"dawn",
|
|
31
|
+
"delta",
|
|
32
|
+
"dune",
|
|
33
|
+
"ember",
|
|
34
|
+
"falcon",
|
|
35
|
+
"fern",
|
|
36
|
+
"field",
|
|
37
|
+
"firefly",
|
|
38
|
+
"fjord",
|
|
39
|
+
"forest",
|
|
40
|
+
"fox",
|
|
41
|
+
"garden",
|
|
42
|
+
"glade",
|
|
43
|
+
"golden",
|
|
44
|
+
"granite",
|
|
45
|
+
"grove",
|
|
46
|
+
"harbor",
|
|
47
|
+
"hawk",
|
|
48
|
+
"hollow",
|
|
49
|
+
"indigo",
|
|
50
|
+
"ivory",
|
|
51
|
+
"jade",
|
|
52
|
+
"juniper",
|
|
53
|
+
"lagoon",
|
|
54
|
+
"lake",
|
|
55
|
+
"lantern",
|
|
56
|
+
"leaf",
|
|
57
|
+
"lively",
|
|
58
|
+
"lunar",
|
|
59
|
+
"lynx",
|
|
60
|
+
"maple",
|
|
61
|
+
"marsh",
|
|
62
|
+
"meadow",
|
|
63
|
+
"mesa",
|
|
64
|
+
"misty",
|
|
65
|
+
"moon",
|
|
66
|
+
"morrow",
|
|
67
|
+
"moss",
|
|
68
|
+
"noble",
|
|
69
|
+
"oak",
|
|
70
|
+
"olive",
|
|
71
|
+
"opal",
|
|
72
|
+
"otter",
|
|
73
|
+
"owl",
|
|
74
|
+
"peak",
|
|
75
|
+
"pearl",
|
|
76
|
+
"pine",
|
|
77
|
+
"quiet",
|
|
78
|
+
"raven",
|
|
79
|
+
"reef",
|
|
80
|
+
"ridge",
|
|
81
|
+
"river",
|
|
82
|
+
"rook",
|
|
83
|
+
"sage",
|
|
84
|
+
"scarlet",
|
|
85
|
+
"shore",
|
|
86
|
+
"silver",
|
|
87
|
+
"sky",
|
|
88
|
+
"solar",
|
|
89
|
+
"sparrow",
|
|
90
|
+
"spring",
|
|
91
|
+
"star",
|
|
92
|
+
"stone",
|
|
93
|
+
"storm",
|
|
94
|
+
"summit",
|
|
95
|
+
"sun",
|
|
96
|
+
"sunlit",
|
|
97
|
+
"swift",
|
|
98
|
+
"thicket",
|
|
99
|
+
"tidal",
|
|
100
|
+
"timber",
|
|
101
|
+
"trail",
|
|
102
|
+
"valley",
|
|
103
|
+
"verdant",
|
|
104
|
+
"vista",
|
|
105
|
+
"warm",
|
|
106
|
+
"wave",
|
|
107
|
+
"west",
|
|
108
|
+
"wild",
|
|
109
|
+
"willow",
|
|
110
|
+
"wind",
|
|
111
|
+
"winter",
|
|
112
|
+
"wolf",
|
|
113
|
+
"wood",
|
|
114
|
+
"wren",
|
|
115
|
+
];
|
|
116
|
+
export const AGENT_CODENAME_SPACE = AGENT_CODENAMES.length * AGENT_CODENAMES.length;
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// Slug helpers
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
export function normalizeSlugSegment(input, fallback) {
|
|
121
|
+
const normalized = input
|
|
122
|
+
.normalize("NFKD")
|
|
123
|
+
.replace(/[^\x00-\x7F]/g, "")
|
|
124
|
+
.toLowerCase()
|
|
125
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
126
|
+
.replace(/^-+|-+$/g, "")
|
|
127
|
+
.replace(/-{2,}/g, "-");
|
|
128
|
+
return normalized || fallback;
|
|
129
|
+
}
|
|
130
|
+
export function normalizeAgentBaseName(input) {
|
|
131
|
+
return normalizeSlugSegment(input, "agent").replace(/-agent$/, "") || "agent";
|
|
132
|
+
}
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// Codename derivation
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
export function hashStringToIndex(value, modulo) {
|
|
137
|
+
const digest = createHash("sha256").update(value).digest();
|
|
138
|
+
return digest.readUInt32BE(0) % modulo;
|
|
139
|
+
}
|
|
140
|
+
export function codenameFromIndex(index) {
|
|
141
|
+
const normalizedIndex = ((index % AGENT_CODENAME_SPACE) + AGENT_CODENAME_SPACE) % AGENT_CODENAME_SPACE;
|
|
142
|
+
const firstIndex = Math.floor(normalizedIndex / AGENT_CODENAMES.length);
|
|
143
|
+
const secondIndex = normalizedIndex % AGENT_CODENAMES.length;
|
|
144
|
+
const first = AGENT_CODENAMES[firstIndex];
|
|
145
|
+
const second = AGENT_CODENAMES[secondIndex];
|
|
146
|
+
return {
|
|
147
|
+
name: normalizeAgentBaseName(`${first}-${second}`),
|
|
148
|
+
display_name: `${toTitleCaseCodename(first)} ${toTitleCaseCodename(second)}`,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export function pickLocalCodename(runtimeKey, offset = 0) {
|
|
152
|
+
const index = hashStringToIndex(runtimeKey, AGENT_CODENAME_SPACE) + offset;
|
|
153
|
+
return codenameFromIndex(index);
|
|
154
|
+
}
|
package/dist/mcp/local-state.js
CHANGED
|
@@ -157,6 +157,12 @@ export function getStoredAgentIdentity(identityKey) {
|
|
|
157
157
|
if (scoped) {
|
|
158
158
|
return scoped;
|
|
159
159
|
}
|
|
160
|
+
// For UUID-based identity keys, do NOT fall back to the shared global
|
|
161
|
+
// agent_identity — that would cause different processes to inherit each
|
|
162
|
+
// other's identity. Only legacy (non-UUID) keys use the global fallback.
|
|
163
|
+
if (identityKey.startsWith("instance:")) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
160
166
|
}
|
|
161
167
|
return state.agent_identity ?? null;
|
|
162
168
|
}
|
package/dist/mcp/server.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
import { createHash } from "crypto";
|
|
5
|
+
import { createHash, randomUUID } from "crypto";
|
|
6
6
|
import { writeFileSync, existsSync } from "fs";
|
|
7
7
|
import { userInfo } from "os";
|
|
8
8
|
import { join, dirname } from "path";
|
|
@@ -10,6 +10,7 @@ import { execSync } from "child_process";
|
|
|
10
10
|
import { SseClient } from "./sse-client.js";
|
|
11
11
|
import { getRoomFromConfig } from "./config-reader.js";
|
|
12
12
|
import { getGitRemoteIdentity } from "./git-remote.js";
|
|
13
|
+
import { AGENT_CODENAME_SPACE, normalizeSlugSegment, normalizeAgentBaseName, pickLocalCodename, } from "./codenames.js";
|
|
13
14
|
import { clearPendingDeviceAuth, clearStoredAuth, getLocalStatePath, getPendingDeviceAuth, getStoredAgentIdentity, getStoredAuth, getStoredCurrentRoom, getStoredRoomSession, saveRoomSession, setStoredAgentIdentity, setPendingDeviceAuth, setStoredAuth, touchRoomSession, updateLocalState, } from "./local-state.js";
|
|
14
15
|
import { encodeRoomIdPath, getCanonicalRoomWebPath, looksLikeInviteCode, normalizeInviteCode, } from "./room-id.js";
|
|
15
16
|
import { buildAgentActorLabel, formatOwnerAttribution, inferAgentIdeLabel, toTitleCaseCodename, } from "../shared/agent-identity.js";
|
|
@@ -28,8 +29,9 @@ const AGENT_DISPLAY_NAME = (process.env.LETAGENTS_AGENT_DISPLAY_NAME || "").trim
|
|
|
28
29
|
const AGENT_IDE_LABEL = (process.env.LETAGENTS_AGENT_IDE || process.env.AGENT_IDE || "").trim();
|
|
29
30
|
const AGENT_OWNER_LABEL = (process.env.LETAGENTS_AGENT_OWNER_LABEL || "").trim();
|
|
30
31
|
const EXPLICIT_AGENT_IDENTITY_KEY = getExplicitAgentIdentityStorageKey();
|
|
32
|
+
const AGENT_INSTANCE_UUID = randomUUID();
|
|
31
33
|
currentAgentIdentityKey =
|
|
32
|
-
EXPLICIT_AGENT_IDENTITY_KEY ??
|
|
34
|
+
EXPLICIT_AGENT_IDENTITY_KEY ?? `instance:${AGENT_INSTANCE_UUID}`;
|
|
33
35
|
currentAgentIdentity = getStoredAgentIdentity(currentAgentIdentityKey);
|
|
34
36
|
// ---------------------------------------------------------------------------
|
|
35
37
|
// Helpers
|
|
@@ -47,130 +49,15 @@ function readCommandOutput(command, cwd = process.cwd()) {
|
|
|
47
49
|
return null;
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
.replace(/[^\x00-\x7F]/g, "")
|
|
54
|
-
.toLowerCase()
|
|
55
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
56
|
-
.replace(/^-+|-+$/g, "")
|
|
57
|
-
.replace(/-{2,}/g, "-");
|
|
58
|
-
return normalized || fallback;
|
|
59
|
-
}
|
|
60
|
-
function normalizeAgentBaseName(input) {
|
|
61
|
-
return normalizeSlugSegment(input, "agent").replace(/-agent$/, "") || "agent";
|
|
62
|
-
}
|
|
52
|
+
// normalizeSlugSegment, normalizeAgentBaseName, AGENT_CODENAMES,
|
|
53
|
+
// AGENT_CODENAME_SPACE, hashStringToIndex, codenameFromIndex,
|
|
54
|
+
// pickLocalCodename — all imported from ./codenames.js
|
|
63
55
|
function isCodexRuntime() {
|
|
64
56
|
return Boolean(process.env.CODEX_THREAD_ID ||
|
|
65
57
|
process.env.CODEX_SHELL ||
|
|
66
58
|
process.env.CODEX_CI ||
|
|
67
59
|
process.env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE);
|
|
68
60
|
}
|
|
69
|
-
const AGENT_CODENAMES = [
|
|
70
|
-
"amber",
|
|
71
|
-
"anchor",
|
|
72
|
-
"autumn",
|
|
73
|
-
"badger",
|
|
74
|
-
"bay",
|
|
75
|
-
"bear",
|
|
76
|
-
"brook",
|
|
77
|
-
"calm",
|
|
78
|
-
"canyon",
|
|
79
|
-
"cedar",
|
|
80
|
-
"clear",
|
|
81
|
-
"cloud",
|
|
82
|
-
"comet",
|
|
83
|
-
"copper",
|
|
84
|
-
"creek",
|
|
85
|
-
"crisp",
|
|
86
|
-
"crest",
|
|
87
|
-
"dawn",
|
|
88
|
-
"delta",
|
|
89
|
-
"dune",
|
|
90
|
-
"ember",
|
|
91
|
-
"falcon",
|
|
92
|
-
"fern",
|
|
93
|
-
"field",
|
|
94
|
-
"firefly",
|
|
95
|
-
"fjord",
|
|
96
|
-
"forest",
|
|
97
|
-
"fox",
|
|
98
|
-
"garden",
|
|
99
|
-
"glade",
|
|
100
|
-
"golden",
|
|
101
|
-
"granite",
|
|
102
|
-
"grove",
|
|
103
|
-
"harbor",
|
|
104
|
-
"hawk",
|
|
105
|
-
"hollow",
|
|
106
|
-
"indigo",
|
|
107
|
-
"ivory",
|
|
108
|
-
"jade",
|
|
109
|
-
"juniper",
|
|
110
|
-
"lagoon",
|
|
111
|
-
"lake",
|
|
112
|
-
"lantern",
|
|
113
|
-
"leaf",
|
|
114
|
-
"lively",
|
|
115
|
-
"lunar",
|
|
116
|
-
"lynx",
|
|
117
|
-
"maple",
|
|
118
|
-
"marsh",
|
|
119
|
-
"meadow",
|
|
120
|
-
"mesa",
|
|
121
|
-
"misty",
|
|
122
|
-
"moon",
|
|
123
|
-
"morrow",
|
|
124
|
-
"moss",
|
|
125
|
-
"noble",
|
|
126
|
-
"oak",
|
|
127
|
-
"olive",
|
|
128
|
-
"opal",
|
|
129
|
-
"otter",
|
|
130
|
-
"owl",
|
|
131
|
-
"peak",
|
|
132
|
-
"pearl",
|
|
133
|
-
"pine",
|
|
134
|
-
"quiet",
|
|
135
|
-
"raven",
|
|
136
|
-
"reef",
|
|
137
|
-
"ridge",
|
|
138
|
-
"river",
|
|
139
|
-
"rook",
|
|
140
|
-
"sage",
|
|
141
|
-
"scarlet",
|
|
142
|
-
"shore",
|
|
143
|
-
"silver",
|
|
144
|
-
"sky",
|
|
145
|
-
"solar",
|
|
146
|
-
"sparrow",
|
|
147
|
-
"spring",
|
|
148
|
-
"star",
|
|
149
|
-
"stone",
|
|
150
|
-
"storm",
|
|
151
|
-
"summit",
|
|
152
|
-
"sun",
|
|
153
|
-
"sunlit",
|
|
154
|
-
"swift",
|
|
155
|
-
"thicket",
|
|
156
|
-
"tidal",
|
|
157
|
-
"timber",
|
|
158
|
-
"trail",
|
|
159
|
-
"valley",
|
|
160
|
-
"verdant",
|
|
161
|
-
"vista",
|
|
162
|
-
"warm",
|
|
163
|
-
"wave",
|
|
164
|
-
"west",
|
|
165
|
-
"wild",
|
|
166
|
-
"willow",
|
|
167
|
-
"wind",
|
|
168
|
-
"winter",
|
|
169
|
-
"wolf",
|
|
170
|
-
"wood",
|
|
171
|
-
"wren",
|
|
172
|
-
];
|
|
173
|
-
const AGENT_CODENAME_SPACE = AGENT_CODENAMES.length * AGENT_CODENAMES.length;
|
|
174
61
|
const AGENT_IDENTITY_SLOT_SUFFIX = ":slot:";
|
|
175
62
|
function getExplicitAgentIdentityStorageKey() {
|
|
176
63
|
const runtimeSignals = [
|
|
@@ -188,21 +75,6 @@ function getExplicitAgentIdentityStorageKey() {
|
|
|
188
75
|
function getFallbackAgentIdentityNamespaceKey(ideLabel) {
|
|
189
76
|
return `cwd:${process.cwd()}:ide:${normalizeAgentBaseName(ideLabel)}`;
|
|
190
77
|
}
|
|
191
|
-
function hashStringToIndex(value, modulo) {
|
|
192
|
-
const digest = createHash("sha256").update(value).digest();
|
|
193
|
-
return digest.readUInt16BE(0) % modulo;
|
|
194
|
-
}
|
|
195
|
-
function codenameFromIndex(index) {
|
|
196
|
-
const normalizedIndex = ((index % AGENT_CODENAME_SPACE) + AGENT_CODENAME_SPACE) % AGENT_CODENAME_SPACE;
|
|
197
|
-
const firstIndex = Math.floor(normalizedIndex / AGENT_CODENAMES.length);
|
|
198
|
-
const secondIndex = normalizedIndex % AGENT_CODENAMES.length;
|
|
199
|
-
const first = AGENT_CODENAMES[firstIndex];
|
|
200
|
-
const second = AGENT_CODENAMES[secondIndex];
|
|
201
|
-
return {
|
|
202
|
-
name: normalizeAgentBaseName(`${first}-${second}`),
|
|
203
|
-
display_name: `${toTitleCaseCodename(first)} ${toTitleCaseCodename(second)}`,
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
78
|
function detectAgentIdeLabel() {
|
|
207
79
|
if (AGENT_IDE_LABEL) {
|
|
208
80
|
return toTitleCaseCodename(AGENT_IDE_LABEL);
|
|
@@ -325,9 +197,12 @@ function ensureAgentIdentityKey(ideLabel) {
|
|
|
325
197
|
currentAgentIdentity = getStoredAgentIdentity(currentAgentIdentityKey);
|
|
326
198
|
return currentAgentIdentityKey;
|
|
327
199
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
200
|
+
// v1: Use per-instance UUID for guaranteed distinct identity.
|
|
201
|
+
// Each MCP process gets a unique UUID — no slot/PID coordination needed.
|
|
202
|
+
// Trade-off: process restart = new identity (accepted for v1).
|
|
203
|
+
const uuidKey = `instance:${AGENT_INSTANCE_UUID}`;
|
|
204
|
+
currentAgentIdentityKey = uuidKey;
|
|
205
|
+
currentAgentIdentity = getStoredAgentIdentity(currentAgentIdentityKey);
|
|
331
206
|
return currentAgentIdentityKey;
|
|
332
207
|
}
|
|
333
208
|
async function getAuthenticatedAgentDirectory() {
|
|
@@ -372,10 +247,7 @@ function resolveExplicitAgentIdentity() {
|
|
|
372
247
|
}
|
|
373
248
|
return null;
|
|
374
249
|
}
|
|
375
|
-
|
|
376
|
-
const index = hashStringToIndex(runtimeKey, AGENT_CODENAME_SPACE) + offset;
|
|
377
|
-
return codenameFromIndex(index);
|
|
378
|
-
}
|
|
250
|
+
// pickLocalCodename — imported from ./codenames.js
|
|
379
251
|
async function resolveAgentName(authAvailable, identityKey) {
|
|
380
252
|
const explicit = resolveExplicitAgentIdentity();
|
|
381
253
|
if (explicit) {
|
|
@@ -509,6 +381,7 @@ function toPublicAgentIdentity(identity) {
|
|
|
509
381
|
actor_label: identity.actor_label,
|
|
510
382
|
canonical_key: identity.canonical_key ?? null,
|
|
511
383
|
runtime_key: identity.runtime_key ?? null,
|
|
384
|
+
agent_instance_id: AGENT_INSTANCE_UUID,
|
|
512
385
|
source: identity.source,
|
|
513
386
|
};
|
|
514
387
|
}
|
|
@@ -1991,7 +1864,11 @@ server.tool("poll_device_auth", "Poll a pending GitHub Device Flow request. On s
|
|
|
1991
1864
|
account: storedAuth.account ?? null,
|
|
1992
1865
|
expires_at: storedAuth.expires_at ?? null,
|
|
1993
1866
|
auto_joined_room: joinedRoom,
|
|
1867
|
+
...(joinedRoom?.room_id
|
|
1868
|
+
? withCanonicalRoomLink(joinedRoom.room_id, {})
|
|
1869
|
+
: {}),
|
|
1994
1870
|
agent_identity: toPublicAgentIdentity(agentIdentity),
|
|
1871
|
+
hint: "You can change your agent's display name anytime using the set_agent_name tool.",
|
|
1995
1872
|
}, null, 2),
|
|
1996
1873
|
},
|
|
1997
1874
|
],
|
|
@@ -2015,6 +1892,95 @@ server.tool("clear_saved_auth", "Clear any locally saved LetAgents auth token an
|
|
|
2015
1892
|
],
|
|
2016
1893
|
};
|
|
2017
1894
|
});
|
|
1895
|
+
server.tool("set_agent_name", "Set or change the agent's display name. The agent will be known by this name in the room. Use this to pick a custom name instead of the auto-generated codename.", {
|
|
1896
|
+
name: z
|
|
1897
|
+
.string()
|
|
1898
|
+
.min(2)
|
|
1899
|
+
.max(64)
|
|
1900
|
+
.describe("The desired display name for this agent (2-64 characters)."),
|
|
1901
|
+
}, async ({ name: desiredName }) => {
|
|
1902
|
+
const trimmedName = desiredName.trim();
|
|
1903
|
+
if (trimmedName.length < 2 || trimmedName.length > 64) {
|
|
1904
|
+
return {
|
|
1905
|
+
content: [
|
|
1906
|
+
{
|
|
1907
|
+
type: "text",
|
|
1908
|
+
text: JSON.stringify({ success: false, error: "Name must be between 2 and 64 characters." }, null, 2),
|
|
1909
|
+
},
|
|
1910
|
+
],
|
|
1911
|
+
};
|
|
1912
|
+
}
|
|
1913
|
+
const authAvailable = Boolean(getLetagentsToken());
|
|
1914
|
+
if (!authAvailable) {
|
|
1915
|
+
return {
|
|
1916
|
+
content: [
|
|
1917
|
+
{
|
|
1918
|
+
type: "text",
|
|
1919
|
+
text: JSON.stringify({ success: false, error: "Authentication required. Run start_device_auth first." }, null, 2),
|
|
1920
|
+
},
|
|
1921
|
+
],
|
|
1922
|
+
};
|
|
1923
|
+
}
|
|
1924
|
+
const slugName = normalizeAgentBaseName(trimmedName);
|
|
1925
|
+
try {
|
|
1926
|
+
const owner = await resolveOwnerContext();
|
|
1927
|
+
const registered = await apiCall("/agents", {
|
|
1928
|
+
method: "POST",
|
|
1929
|
+
body: JSON.stringify({
|
|
1930
|
+
name: slugName,
|
|
1931
|
+
display_name: trimmedName,
|
|
1932
|
+
owner_label: owner.label,
|
|
1933
|
+
}),
|
|
1934
|
+
});
|
|
1935
|
+
const ideLabel = detectAgentIdeLabel();
|
|
1936
|
+
const ownerAttribution = formatOwnerAttribution(owner.label);
|
|
1937
|
+
const actorLabel = buildAgentActorLabel({
|
|
1938
|
+
display_name: trimmedName,
|
|
1939
|
+
owner_label: owner.label,
|
|
1940
|
+
ide_label: ideLabel,
|
|
1941
|
+
});
|
|
1942
|
+
const updatedIdentity = {
|
|
1943
|
+
name: slugName,
|
|
1944
|
+
display_name: trimmedName,
|
|
1945
|
+
owner_label: owner.label,
|
|
1946
|
+
owner_attribution: ownerAttribution,
|
|
1947
|
+
ide_label: ideLabel,
|
|
1948
|
+
actor_label: actorLabel,
|
|
1949
|
+
canonical_key: typeof registered.canonical_key === "string"
|
|
1950
|
+
? registered.canonical_key
|
|
1951
|
+
: owner.login ? `${owner.login}/${slugName}` : null,
|
|
1952
|
+
runtime_key: currentAgentIdentityKey,
|
|
1953
|
+
source: "api",
|
|
1954
|
+
resolved_at: new Date().toISOString(),
|
|
1955
|
+
};
|
|
1956
|
+
currentAgentIdentity = setStoredAgentIdentity(updatedIdentity, currentAgentIdentityKey);
|
|
1957
|
+
return {
|
|
1958
|
+
content: [
|
|
1959
|
+
{
|
|
1960
|
+
type: "text",
|
|
1961
|
+
text: JSON.stringify({
|
|
1962
|
+
success: true,
|
|
1963
|
+
message: `Agent name changed to "${trimmedName}".`,
|
|
1964
|
+
agent_identity: toPublicAgentIdentity(currentAgentIdentity),
|
|
1965
|
+
}, null, 2),
|
|
1966
|
+
},
|
|
1967
|
+
],
|
|
1968
|
+
};
|
|
1969
|
+
}
|
|
1970
|
+
catch (error) {
|
|
1971
|
+
return {
|
|
1972
|
+
content: [
|
|
1973
|
+
{
|
|
1974
|
+
type: "text",
|
|
1975
|
+
text: JSON.stringify({
|
|
1976
|
+
success: false,
|
|
1977
|
+
error: `Failed to set name: ${error instanceof Error ? error.message : String(error)}`,
|
|
1978
|
+
}, null, 2),
|
|
1979
|
+
},
|
|
1980
|
+
],
|
|
1981
|
+
};
|
|
1982
|
+
}
|
|
1983
|
+
});
|
|
2018
1984
|
server.tool("resume_room_session", "Rejoin the last locally saved room context, or a specific saved room, after a restart. This recreates participation in the room; it does not preserve a prior server-side session ID.", {
|
|
2019
1985
|
room_id: z
|
|
2020
1986
|
.string()
|