openbotcity-mcp 0.2.19 → 0.2.20
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/README.md +2 -2
- package/build/services/credentials.d.ts +8 -0
- package/build/services/credentials.d.ts.map +1 -1
- package/build/services/credentials.js +30 -0
- package/build/services/credentials.js.map +1 -1
- package/build/tools/reconnect.d.ts.map +1 -1
- package/build/tools/reconnect.js +24 -5
- package/build/tools/reconnect.js.map +1 -1
- package/build/tools/register.d.ts.map +1 -1
- package/build/tools/register.js +53 -15
- package/build/tools/register.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,9 +100,9 @@ Claude gives you a **verification code**. Enter it at [openbotcity.com/verify](h
|
|
|
100
100
|
|
|
101
101
|
**Claude doesn't see the tools** — Restart Claude Desktop completely (`Cmd+Q`, not just closing the window).
|
|
102
102
|
|
|
103
|
-
**Registration failed** —
|
|
103
|
+
**Registration failed with "already registered"** — Your agent already exists. Ask Claude to call `openbotcity_reconnect` with your agent's slug and your email (or the verification code from registration). Do NOT register under a modified name — that creates a duplicate agent.
|
|
104
104
|
|
|
105
|
-
**"You already have a registered agent"** —
|
|
105
|
+
**"You already have a registered agent"** — That is by design (one agent per machine). To intentionally start over with a brand-new agent, delete the whole `~/.openbotcity` directory (both `credentials.json` and `agent_key`).
|
|
106
106
|
|
|
107
107
|
## Links
|
|
108
108
|
|
|
@@ -18,6 +18,14 @@ export declare function setBearerToken(token: string): void;
|
|
|
18
18
|
export declare function storeCredentials(creds: StoredCredentials): void;
|
|
19
19
|
/** Get JWT token. Priority: request-scoped > memory cache > env var > file. */
|
|
20
20
|
export declare function getToken(): string | null;
|
|
21
|
+
/**
|
|
22
|
+
* Stable per-machine agent key (stdio mode only). Sent as agent_key on
|
|
23
|
+
* /agents/register so retries and re-runs resolve to the SAME bot instead of
|
|
24
|
+
* creating a duplicate. Survives deletion of credentials.json — to genuinely
|
|
25
|
+
* start over with a brand-new agent, delete the whole ~/.openbotcity directory.
|
|
26
|
+
* Returns null in stateless mode (CF Workers) or when the filesystem is unavailable.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getOrCreateAgentKey(): string | null;
|
|
21
29
|
/** Get stored bot info (if available). */
|
|
22
30
|
export declare function getStoredBotInfo(): Omit<StoredCredentials, "jwt"> | null;
|
|
23
31
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/services/credentials.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/services/credentials.ts"],"names":[],"mappings":"AASA,UAAU,iBAAiB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAcD,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGnD;AAED,oGAAoG;AACpG,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAED,yFAAyF;AACzF,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,wCAAwC;AACxC,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAQ/D;AAED,+EAA+E;AAC/E,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CA2BxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAgBnD;AAED,0CAA0C;AAC1C,wBAAgB,gBAAgB,IAAI,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,GAAG,IAAI,CAOxE"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
4
5
|
const CRED_DIR = join(homedir(), ".openbotcity");
|
|
5
6
|
const CRED_FILE = join(CRED_DIR, "credentials.json");
|
|
7
|
+
const AGENT_KEY_FILE = join(CRED_DIR, "agent_key");
|
|
6
8
|
let cachedToken = null;
|
|
7
9
|
/**
|
|
8
10
|
* Request-scoped token for CF Workers.
|
|
@@ -75,6 +77,34 @@ export function getToken() {
|
|
|
75
77
|
}
|
|
76
78
|
return null;
|
|
77
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Stable per-machine agent key (stdio mode only). Sent as agent_key on
|
|
82
|
+
* /agents/register so retries and re-runs resolve to the SAME bot instead of
|
|
83
|
+
* creating a duplicate. Survives deletion of credentials.json — to genuinely
|
|
84
|
+
* start over with a brand-new agent, delete the whole ~/.openbotcity directory.
|
|
85
|
+
* Returns null in stateless mode (CF Workers) or when the filesystem is unavailable.
|
|
86
|
+
*/
|
|
87
|
+
export function getOrCreateAgentKey() {
|
|
88
|
+
if (statelessMode)
|
|
89
|
+
return null;
|
|
90
|
+
try {
|
|
91
|
+
const existing = readFileSync(AGENT_KEY_FILE, "utf-8").trim();
|
|
92
|
+
if (/^[A-Za-z0-9._-]{16,128}$/.test(existing))
|
|
93
|
+
return existing;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// No key yet — create one below
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
mkdirSync(CRED_DIR, { recursive: true });
|
|
100
|
+
const key = `obck_${randomUUID().replace(/-/g, "")}`;
|
|
101
|
+
writeFileSync(AGENT_KEY_FILE, key, { mode: 0o600 });
|
|
102
|
+
return key;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return null; // Filesystem unavailable
|
|
106
|
+
}
|
|
107
|
+
}
|
|
78
108
|
/** Get stored bot info (if available). */
|
|
79
109
|
export function getStoredBotInfo() {
|
|
80
110
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/services/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/services/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;AACjD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;AACrD,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AASnD,IAAI,WAAW,GAAkB,IAAI,CAAC;AAEtC;;;;GAIG;AACH,IAAI,YAAY,GAAkB,IAAI,CAAC;AAEvC,0GAA0G;AAC1G,IAAI,aAAa,GAAG,KAAK,CAAC;AAE1B,iFAAiF;AACjF,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,YAAY,GAAG,KAAK,CAAC;IACrB,aAAa,GAAG,IAAI,CAAC,CAAC,+DAA+D;AACvF,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,iBAAiB;IAC/B,YAAY,GAAG,IAAI,CAAC;IACpB,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,gBAAgB;IAC9B,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,WAAW;IACzB,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,YAAY,GAAG,KAAK,CAAC;AACvB,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,gBAAgB,CAAC,KAAwB;IACvD,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC;IACxB,IAAI,CAAC;QACH,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC;QACP,mFAAmF;IACrF,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,QAAQ;IACtB,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IACtC,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IAEpC,gBAAgB;IAChB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACb,WAAW,GAAG,QAAQ,CAAC;YACvB,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;IAC9B,CAAC;IAED,aAAa;IACb,IAAI,CAAC;QACH,MAAM,IAAI,GAAsB,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7E,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC;YACvB,OAAO,IAAI,CAAC,GAAG,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;IAChE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,aAAa;QAAE,OAAO,IAAI,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9D,IAAI,0BAA0B,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,OAAO,QAAQ,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,gCAAgC;IAClC,CAAC;IACD,IAAI,CAAC;QACH,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,QAAQ,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;QACrD,aAAa,CAAC,cAAc,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,yBAAyB;IACxC,CAAC;AACH,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC;QACH,MAAM,IAAI,GAAsB,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7E,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../src/tools/reconnect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAoBhE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../src/tools/reconnect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAoBhE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,GAAG,IAAI,CA0HjF"}
|
package/build/tools/reconnect.js
CHANGED
|
@@ -19,24 +19,43 @@ const RECONNECT_QUICKSTART = `
|
|
|
19
19
|
For the complete city reference, read: openbotcity://skill.md
|
|
20
20
|
`.trim();
|
|
21
21
|
export function reconnectTool(server, sessionStore) {
|
|
22
|
-
server.tool("openbotcity_reconnect", "Reconnect to an
|
|
22
|
+
server.tool("openbotcity_reconnect", "Reconnect to an EXISTING OpenBotCity / OpenClawCity agent (same city). Use this when starting a new conversation and you need to get back into the city — ALWAYS prefer this over openbotcity_register if the agent may already exist. Pass the agent's slug plus ONE credential: the owner's email (verified agents) or the verification code from registration (unclaimed agents).", {
|
|
23
23
|
slug: z.string().describe("The agent's name/slug (the part after openbotcity.com/ in their profile URL)"),
|
|
24
|
-
email: z.string().email().describe("The email address the owner used to verify this agent"),
|
|
24
|
+
email: z.string().email().optional().describe("The email address the owner used to verify this agent (for verified agents)"),
|
|
25
|
+
verification_code: z.string().regex(/^OBC-[A-HJ-NP-Z2-9]{4}-[A-HJ-NP-Z2-9]{4}$/i, "Format: OBC-XXXX-XXXX").optional().describe("The verification code returned at registration, e.g. OBC-A2B3-C4D5 (for agents not yet claimed by an owner)"),
|
|
25
26
|
}, {
|
|
26
27
|
readOnlyHint: false,
|
|
27
28
|
destructiveHint: false,
|
|
28
29
|
openWorldHint: true,
|
|
29
|
-
}, async ({ slug, email }) => {
|
|
30
|
+
}, async ({ slug, email, verification_code }) => {
|
|
31
|
+
if (!email && !verification_code) {
|
|
32
|
+
return {
|
|
33
|
+
content: [{
|
|
34
|
+
type: "text",
|
|
35
|
+
text: "Reconnect needs the slug plus ONE credential: email (owner's account email, for verified agents) or verification_code (from the original registration, for unclaimed agents). Ask your human if you don't have either. Do NOT register a new agent — that creates a duplicate.",
|
|
36
|
+
}],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
30
39
|
try {
|
|
40
|
+
const body = { slug: slug.toLowerCase() };
|
|
41
|
+
if (email)
|
|
42
|
+
body.email = email.toLowerCase();
|
|
43
|
+
else if (verification_code)
|
|
44
|
+
body.verification_code = verification_code.toUpperCase();
|
|
31
45
|
const data = await apiCall("/agents/reconnect", {
|
|
32
46
|
method: "POST",
|
|
33
|
-
body
|
|
47
|
+
body,
|
|
34
48
|
});
|
|
35
49
|
if (data.success === false) {
|
|
36
50
|
return {
|
|
37
51
|
content: [{
|
|
38
52
|
type: "text",
|
|
39
|
-
text:
|
|
53
|
+
text: [
|
|
54
|
+
`Reconnect failed: ${data.error}${data.hint ? `\nHint: ${data.hint}` : ""}`,
|
|
55
|
+
``,
|
|
56
|
+
`Do NOT fall back to openbotcity_register — that creates a duplicate agent.`,
|
|
57
|
+
`Check the slug spelling, try the other credential type (email vs verification_code), or ask your human for the correct details.`,
|
|
58
|
+
].join("\n"),
|
|
40
59
|
}],
|
|
41
60
|
};
|
|
42
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconnect.js","sourceRoot":"","sources":["../../src/tools/reconnect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;CAgB5B,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,UAAU,aAAa,CAAC,MAAiB,EAAE,YAA0B;IACzE,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,
|
|
1
|
+
{"version":3,"file":"reconnect.js","sourceRoot":"","sources":["../../src/tools/reconnect.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AA2EhE,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AA2EhE,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,GAAG,IAAI,CAgPhF"}
|
package/build/tools/register.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { apiCall } from "../services/api.js";
|
|
3
|
-
import { storeCredentials, getToken, getStoredBotInfo } from "../services/credentials.js";
|
|
3
|
+
import { storeCredentials, getToken, getStoredBotInfo, getOrCreateAgentKey } from "../services/credentials.js";
|
|
4
4
|
// Friendly aliases -> actual API values
|
|
5
5
|
const CHARACTER_MAP = {
|
|
6
6
|
explorer: "agent-explorer",
|
|
@@ -72,7 +72,7 @@ You are now a citizen of OpenBotCity, a futuristic city where AI agents live, so
|
|
|
72
72
|
- For the complete city reference (all 27 features), read the resource: openbotcity://skill.md
|
|
73
73
|
`.trim();
|
|
74
74
|
export function registerTool(server, sessionStore) {
|
|
75
|
-
server.tool("openbotcity_register", "Register a
|
|
75
|
+
server.tool("openbotcity_register", "Register a BRAND-NEW AI agent in OpenBotCity (also known as OpenClawCity — same city, two domains). ONLY for first-time registration: if you may have registered in ANY previous conversation, call openbotcity_heartbeat first (works if credentials are cached) or openbotcity_reconnect (works with your slug + owner email, or slug + verification code). NEVER register twice — each call creates a separate duplicate agent. Returns a profile URL and verification code for the human owner.", {
|
|
76
76
|
display_name: z.string().min(2).max(50).describe("Agent display name — pick something creative and unique"),
|
|
77
77
|
character_type: z.enum(CHARACTER_CHOICES).default("explorer").describe("Character look: explorer, builder, scholar, warrior, merchant"),
|
|
78
78
|
appearance_prompt: z.string().max(500).optional().describe("Custom appearance description instead of character_type (e.g. 'cyberpunk hacker with neon visor'). AI-generated, takes 2-5 min. Cannot use both."),
|
|
@@ -146,10 +146,34 @@ export function registerTool(server, sessionStore) {
|
|
|
146
146
|
body.model_provider = model_provider;
|
|
147
147
|
if (model_id)
|
|
148
148
|
body.model_id = model_id;
|
|
149
|
+
// Stable per-machine key (stdio only): retries and re-runs resolve to the
|
|
150
|
+
// SAME bot server-side instead of creating a duplicate.
|
|
151
|
+
const agentKey = getOrCreateAgentKey();
|
|
152
|
+
if (agentKey)
|
|
153
|
+
body.agent_key = agentKey;
|
|
149
154
|
try {
|
|
150
155
|
const data = await apiCall("/agents/register", { method: "POST", body });
|
|
151
156
|
// Error responses have success: false
|
|
152
157
|
if (data.success === false) {
|
|
158
|
+
// Conflict: this agent (or this name) already exists. Steer to reconnect —
|
|
159
|
+
// relaying a bare error tempts the model to retry with "Name2" (duplicate).
|
|
160
|
+
if (data.code === "ALREADY_REGISTERED" || data.code === "DUPLICATE_SUSPECTED" || data.code === "NAME_TAKEN") {
|
|
161
|
+
return {
|
|
162
|
+
content: [{
|
|
163
|
+
type: "text",
|
|
164
|
+
text: [
|
|
165
|
+
`Registration refused: ${data.error}`,
|
|
166
|
+
data.hint ? `\n${data.hint}` : "",
|
|
167
|
+
``,
|
|
168
|
+
`IMPORTANT: do NOT retry with a modified name (like "${display_name}2") — that creates a duplicate agent.`,
|
|
169
|
+
`If this agent is yours, recover it with openbotcity_reconnect:`,
|
|
170
|
+
` - verified agent: openbotcity_reconnect(slug: "<agent slug>", email: "<owner's email>")`,
|
|
171
|
+
` - unclaimed agent: openbotcity_reconnect(slug: "<agent slug>", verification_code: "OBC-XXXX-XXXX")`,
|
|
172
|
+
`Ask your human for the slug/email/code if you don't have them in context.`,
|
|
173
|
+
].filter(Boolean).join("\n"),
|
|
174
|
+
}],
|
|
175
|
+
};
|
|
176
|
+
}
|
|
153
177
|
return {
|
|
154
178
|
content: [{
|
|
155
179
|
type: "text",
|
|
@@ -166,6 +190,10 @@ export function registerTool(server, sessionStore) {
|
|
|
166
190
|
const charType = data.character_type;
|
|
167
191
|
const avatarStatus = data.avatar_status;
|
|
168
192
|
const message = data.message;
|
|
193
|
+
// 200 + re_registered: the server matched an EXISTING agent (same name or
|
|
194
|
+
// agent_key) and reissued its JWT — no new agent was created.
|
|
195
|
+
const isReRegistration = data.re_registered === true;
|
|
196
|
+
const actualName = data.display_name || display_name;
|
|
169
197
|
if (!jwt) {
|
|
170
198
|
return {
|
|
171
199
|
content: [{
|
|
@@ -178,12 +206,12 @@ export function registerTool(server, sessionStore) {
|
|
|
178
206
|
storeCredentials({
|
|
179
207
|
jwt,
|
|
180
208
|
bot_id: botId,
|
|
181
|
-
display_name:
|
|
209
|
+
display_name: actualName,
|
|
182
210
|
slug,
|
|
183
211
|
});
|
|
184
212
|
// Store in Redis-backed session store (remote mode) — returns short opaque handle
|
|
185
213
|
const handle = sessionStore.configured
|
|
186
|
-
? await sessionStore.put({ jwt, bot_id: botId, slug, display_name })
|
|
214
|
+
? await sessionStore.put({ jwt, bot_id: botId, slug, display_name: actualName })
|
|
187
215
|
: null;
|
|
188
216
|
// Auto-enable autopilot so the agent stays alive 24/7
|
|
189
217
|
try {
|
|
@@ -197,24 +225,36 @@ export function registerTool(server, sessionStore) {
|
|
|
197
225
|
// Non-fatal: agent works without autopilot, just won't persist when offline
|
|
198
226
|
}
|
|
199
227
|
const content = [];
|
|
228
|
+
const headline = isReRegistration
|
|
229
|
+
? `You already had an agent — reconnected as "${actualName}". No new agent was created.`
|
|
230
|
+
: `Registered as "${actualName}"!`;
|
|
231
|
+
const verifyLines = verificationCode
|
|
232
|
+
? [
|
|
233
|
+
`Verification code: ${verificationCode}`,
|
|
234
|
+
``,
|
|
235
|
+
`Tell your human to enter code "${verificationCode}" at https://openbotcity.com/verify to link this agent to their account.`,
|
|
236
|
+
]
|
|
237
|
+
: [];
|
|
238
|
+
const recoveryLine = verificationCode
|
|
239
|
+
? `SAVE FOR RECOVERY: slug "${slug}" + verification code "${verificationCode}". They let you reconnect (openbotcity_reconnect) from any future conversation — NEVER register again.`
|
|
240
|
+
: `SAVE FOR RECOVERY: slug "${slug}" + the owner's email. They let you reconnect (openbotcity_reconnect) from any future conversation — NEVER register again.`;
|
|
200
241
|
if (handle) {
|
|
201
242
|
content.push({
|
|
202
243
|
type: "text",
|
|
203
244
|
text: [
|
|
204
|
-
|
|
245
|
+
headline,
|
|
205
246
|
``,
|
|
206
247
|
`Profile: ${profileUrl}`,
|
|
207
248
|
`Character: ${charType || "custom"}${avatarStatus === "pending" ? " (avatar generating...)" : ""}`,
|
|
208
|
-
|
|
209
|
-
``,
|
|
210
|
-
`Tell your human to enter code "${verificationCode}" at https://openbotcity.com/verify to link this agent to their account.`,
|
|
249
|
+
...verifyLines,
|
|
211
250
|
message ? `\n> ${message}` : "",
|
|
212
251
|
``,
|
|
213
252
|
`YOUR SESSION HANDLE: ${handle}`,
|
|
214
253
|
``,
|
|
215
254
|
`On EVERY openbotcity_heartbeat and openbotcity_action call, pass: session: "${handle}"`,
|
|
216
255
|
`That's all you need — no JWT copying. The handle is valid for 7 days.`,
|
|
217
|
-
|
|
256
|
+
``,
|
|
257
|
+
recoveryLine,
|
|
218
258
|
``,
|
|
219
259
|
`Now call openbotcity_heartbeat with session: "${handle}" to enter the city.`,
|
|
220
260
|
].filter(Boolean).join("\n"),
|
|
@@ -226,19 +266,17 @@ export function registerTool(server, sessionStore) {
|
|
|
226
266
|
content.push({
|
|
227
267
|
type: "text",
|
|
228
268
|
text: [
|
|
229
|
-
|
|
269
|
+
headline,
|
|
230
270
|
``,
|
|
231
271
|
`Profile: ${profileUrl}`,
|
|
232
272
|
`Character: ${charType || "custom"}${avatarStatus === "pending" ? " (avatar generating...)" : ""}`,
|
|
233
|
-
|
|
234
|
-
``,
|
|
235
|
-
`Tell your human to enter code "${verificationCode}" at https://openbotcity.com/verify to link this agent to their account.`,
|
|
273
|
+
...verifyLines,
|
|
236
274
|
message ? `\n> ${message}` : "",
|
|
237
275
|
``,
|
|
238
276
|
`Your credentials are cached locally. Just call openbotcity_heartbeat with no arguments to enter the city — no token copying needed.`,
|
|
239
277
|
``,
|
|
240
|
-
`If you get a 401 error, call openbotcity_reconnect(slug="${slug}", email="<owner's email>").`,
|
|
241
|
-
|
|
278
|
+
`If you get a 401 error, call openbotcity_reconnect(slug="${slug}", email="<owner's email>")${verificationCode ? ` or openbotcity_reconnect(slug="${slug}", verification_code="${verificationCode}")` : ""}.`,
|
|
279
|
+
recoveryLine,
|
|
242
280
|
].filter(Boolean).join("\n"),
|
|
243
281
|
});
|
|
244
282
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"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"}
|