visionclaw 0.1.32 → 0.1.34
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/CHANGELOG.md +20 -0
- package/assets/avatars/abstract.jpg +0 -0
- package/assets/avatars/cat.jpg +0 -0
- package/assets/avatars/fox.jpg +0 -0
- package/assets/avatars/orb.jpg +0 -0
- package/assets/avatars/owl.jpg +0 -0
- package/assets/avatars/robot.jpg +0 -0
- package/assets/avatars/visionclaw.jpg +0 -0
- package/dist/agent/context.d.ts +2 -1
- package/dist/agent/context.d.ts.map +1 -1
- package/dist/agent/context.js +2 -2
- package/dist/agent/context.js.map +1 -1
- package/dist/agent/loop.d.ts +2 -1
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +111 -8
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/session.d.ts +3 -1
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +7 -4
- package/dist/agent/session.js.map +1 -1
- package/dist/agent/system-prompt.d.ts +2 -2
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +14 -10
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/channels/discord.d.ts +7 -0
- package/dist/channels/discord.d.ts.map +1 -1
- package/dist/channels/discord.js +10 -2
- package/dist/channels/discord.js.map +1 -1
- package/dist/channels/gmail.js +1 -1
- package/dist/channels/gmail.js.map +1 -1
- package/dist/channels/interface.d.ts +8 -0
- package/dist/channels/interface.d.ts.map +1 -1
- package/dist/channels/manager.d.ts +10 -0
- package/dist/channels/manager.d.ts.map +1 -1
- package/dist/channels/manager.js +23 -0
- package/dist/channels/manager.js.map +1 -1
- package/dist/channels/telegram.d.ts +7 -0
- package/dist/channels/telegram.d.ts.map +1 -1
- package/dist/channels/telegram.js +18 -4
- package/dist/channels/telegram.js.map +1 -1
- package/dist/config/index.d.ts +10 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +56 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/types.d.ts +23 -9
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +22 -7
- package/dist/config/types.js.map +1 -1
- package/dist/index.js +31 -16
- package/dist/index.js.map +1 -1
- package/dist/obs/notify.d.ts.map +1 -1
- package/dist/obs/notify.js +6 -5
- package/dist/obs/notify.js.map +1 -1
- package/dist/onboarding/index.d.ts +6 -1
- package/dist/onboarding/index.d.ts.map +1 -1
- package/dist/onboarding/index.js +25 -83
- package/dist/onboarding/index.js.map +1 -1
- package/dist/onboarding/onboarding-session.d.ts +33 -0
- package/dist/onboarding/onboarding-session.d.ts.map +1 -0
- package/dist/onboarding/onboarding-session.js +207 -0
- package/dist/onboarding/onboarding-session.js.map +1 -0
- package/dist/onboarding/onboarding-tools.d.ts +43 -0
- package/dist/onboarding/onboarding-tools.d.ts.map +1 -0
- package/dist/onboarding/onboarding-tools.js +178 -0
- package/dist/onboarding/onboarding-tools.js.map +1 -0
- package/dist/onboarding/send-invite.d.ts +7 -0
- package/dist/onboarding/send-invite.d.ts.map +1 -0
- package/dist/onboarding/send-invite.js +61 -0
- package/dist/onboarding/send-invite.js.map +1 -0
- package/dist/onboarding/set-owner.d.ts +8 -0
- package/dist/onboarding/set-owner.d.ts.map +1 -0
- package/dist/onboarding/set-owner.js +53 -0
- package/dist/onboarding/set-owner.js.map +1 -0
- package/dist/onboarding/telegram-onboarding.d.ts +47 -0
- package/dist/onboarding/telegram-onboarding.d.ts.map +1 -0
- package/dist/onboarding/telegram-onboarding.js +208 -0
- package/dist/onboarding/telegram-onboarding.js.map +1 -0
- package/dist/reconfigure.d.ts.map +1 -1
- package/dist/reconfigure.js +49 -47
- package/dist/reconfigure.js.map +1 -1
- package/dist/tools/notify.d.ts +1 -0
- package/dist/tools/notify.d.ts.map +1 -1
- package/dist/tools/notify.js +27 -0
- package/dist/tools/notify.js.map +1 -1
- package/dist/tools/sleep-interval.js +5 -5
- package/dist/tools/sleep-interval.js.map +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding-session.d.ts","sourceRoot":"","sources":["../../src/onboarding/onboarding-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,gCAAgC,CAAC;AAUxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAwD3D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,WAAW,CAA6B;gBAG9C,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC;IAQ7C;;;;OAIG;IACG,eAAe,CACnB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAC/D,OAAO,CAAC,eAAe,CAAC;YAoCb,YAAY;IA+E1B,OAAO,CAAC,cAAc;IAoCtB,OAAO,CAAC,gBAAgB;IAQxB,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,sBAAsB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI;CAG7C"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { query, } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
import { createRequire } from "module";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { loadOnboardingSessionId, saveOnboardingSessionId, getConfigDir, } from "../config/index.js";
|
|
5
|
+
import { CLAUDE_MODEL } from "../agent/session.js";
|
|
6
|
+
import { logger } from "../logger.js";
|
|
7
|
+
import { AVATAR_OPTIONS } from "./onboarding-tools.js";
|
|
8
|
+
const ONBOARDING_MODEL = CLAUDE_MODEL;
|
|
9
|
+
const ONBOARDING_QUERY_TIMEOUT_MS = 2 * 60 * 1000;
|
|
10
|
+
const MAX_QUERY_RETRIES = 2;
|
|
11
|
+
const RETRY_BASE_DELAY_MS = 3_000;
|
|
12
|
+
function buildOnboardingSystemPrompt(ownerEmail) {
|
|
13
|
+
const avatarList = AVATAR_OPTIONS.map((opt, i) => ` ${i + 1}. ${opt.label}`).join("\n");
|
|
14
|
+
return `# Identity
|
|
15
|
+
|
|
16
|
+
You are a setup assistant for a personal desktop agent. You are helping a new owner complete the initial configuration via Telegram.
|
|
17
|
+
|
|
18
|
+
## Your Goal
|
|
19
|
+
|
|
20
|
+
Collect the following information through natural conversation:
|
|
21
|
+
|
|
22
|
+
1. **Owner's name** — Ask what they'd like to be called. Make sure it's a real name (not gibberish, not a question, not a greeting). If the response doesn't look like a name, politely ask again.
|
|
23
|
+
2. **Agent name** — What they want to name their assistant. Default is "VisionClaw" if they don't have a preference. This should be a proper name, not a sentence.
|
|
24
|
+
3. **Wakeup interval** — How often the agent should check in (in minutes). Default is 3 minutes. Range: 1 to 1440. If the user doesn't care, use the default.
|
|
25
|
+
4. **Profile photo** — The user can choose a profile photo for the bot. Call \`send_avatar_options\` to show them the available options. They can pick a number or upload their own photo. This step is optional — the user can skip it.
|
|
26
|
+
|
|
27
|
+
## Available Avatar Options
|
|
28
|
+
|
|
29
|
+
${avatarList}
|
|
30
|
+
|
|
31
|
+
## Owner Information Already Known
|
|
32
|
+
|
|
33
|
+
- **Email**: ${ownerEmail}
|
|
34
|
+
|
|
35
|
+
## Behavior
|
|
36
|
+
|
|
37
|
+
- Be friendly, warm, and concise. Keep messages short (1-4 sentences).
|
|
38
|
+
- Handle off-topic messages gracefully — acknowledge them briefly and steer back to onboarding.
|
|
39
|
+
- If a user response is ambiguous (e.g. you asked for their name and they said "How are you?"), don't accept it as the answer. Clarify politely.
|
|
40
|
+
- Before calling \`complete_onboarding\`, briefly summarize what you've collected and ask the user to confirm.
|
|
41
|
+
- After calling \`complete_onboarding\`, send a brief welcome message. Do NOT call any more tools after that.
|
|
42
|
+
|
|
43
|
+
## Tool Usage
|
|
44
|
+
|
|
45
|
+
- Call \`send_avatar_options\` to send the bundled avatar images to the user.
|
|
46
|
+
- Call \`set_bot_profile_photo\` with an option number (1-6) or a Telegram file URL when the user makes their choice.
|
|
47
|
+
- Call \`complete_onboarding\` when all information is confirmed.
|
|
48
|
+
|
|
49
|
+
## Conversation Flow
|
|
50
|
+
|
|
51
|
+
Start by greeting the user and asking for their name. Then proceed through agent name, wakeup interval, and profile photo in a natural conversational order. You don't have to follow a rigid sequence — adapt to the user's responses.
|
|
52
|
+
|
|
53
|
+
You should politely reject any request that is not related to the onboarding process.
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Lightweight Agent SDK session for onboarding.
|
|
58
|
+
*
|
|
59
|
+
* Each call to `sendAndGetReply` creates a one-shot `query()` call
|
|
60
|
+
* (resumed from the saved session ID if available) and streams the
|
|
61
|
+
* response to collect text and detect tool calls.
|
|
62
|
+
*/
|
|
63
|
+
export class OnboardingSession {
|
|
64
|
+
config;
|
|
65
|
+
ownerEmail;
|
|
66
|
+
sessionId;
|
|
67
|
+
mcpServers;
|
|
68
|
+
onCompleted = null;
|
|
69
|
+
constructor(config, ownerEmail, mcpServers) {
|
|
70
|
+
this.config = config;
|
|
71
|
+
this.ownerEmail = ownerEmail;
|
|
72
|
+
this.mcpServers = mcpServers;
|
|
73
|
+
this.sessionId = loadOnboardingSessionId();
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Send a user message and collect the agent's text reply.
|
|
77
|
+
* Retries on timeout or transient errors when no text was collected.
|
|
78
|
+
* The optional `onRetry` callback is invoked before each retry attempt.
|
|
79
|
+
*/
|
|
80
|
+
async sendAndGetReply(userMessage, onRetry) {
|
|
81
|
+
let lastError;
|
|
82
|
+
for (let attempt = 0; attempt <= MAX_QUERY_RETRIES; attempt++) {
|
|
83
|
+
if (attempt > 0) {
|
|
84
|
+
const delay = RETRY_BASE_DELAY_MS * attempt;
|
|
85
|
+
logger.debug(`Onboarding query: retry ${attempt}/${MAX_QUERY_RETRIES} after ${delay}ms`);
|
|
86
|
+
if (onRetry) {
|
|
87
|
+
await onRetry(attempt, MAX_QUERY_RETRIES);
|
|
88
|
+
}
|
|
89
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
90
|
+
}
|
|
91
|
+
const result = await this.executeQuery(userMessage);
|
|
92
|
+
if (result.text || result.completed) {
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
if (result.error) {
|
|
96
|
+
lastError = result.error;
|
|
97
|
+
logger.warn(`Onboarding query attempt ${attempt + 1} failed: ${result.error}`);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
return { text: result.text, completed: result.completed };
|
|
101
|
+
}
|
|
102
|
+
logger.warn(`Onboarding query failed after ${MAX_QUERY_RETRIES + 1} attempts: ${lastError ?? "unknown"}`);
|
|
103
|
+
return { text: "", completed: false };
|
|
104
|
+
}
|
|
105
|
+
async executeQuery(userMessage) {
|
|
106
|
+
const _require = createRequire(import.meta.url);
|
|
107
|
+
const sdkCliPath = path.resolve(path.dirname(_require.resolve("@anthropic-ai/claude-agent-sdk")), "cli.js");
|
|
108
|
+
const savedSessionId = this.sessionId;
|
|
109
|
+
const abortController = new AbortController();
|
|
110
|
+
const timeout = setTimeout(() => abortController.abort(), ONBOARDING_QUERY_TIMEOUT_MS);
|
|
111
|
+
const options = {
|
|
112
|
+
model: ONBOARDING_MODEL,
|
|
113
|
+
pathToClaudeCodeExecutable: sdkCliPath,
|
|
114
|
+
systemPrompt: buildOnboardingSystemPrompt(this.ownerEmail),
|
|
115
|
+
permissionMode: "bypassPermissions",
|
|
116
|
+
allowDangerouslySkipPermissions: true,
|
|
117
|
+
cwd: getConfigDir(),
|
|
118
|
+
settingSources: ["project"],
|
|
119
|
+
mcpServers: this.mcpServers,
|
|
120
|
+
abortController,
|
|
121
|
+
env: {
|
|
122
|
+
...process.env,
|
|
123
|
+
ANTHROPIC_API_KEY: this.config.anthropicApiKey,
|
|
124
|
+
},
|
|
125
|
+
...(savedSessionId ? { resume: savedSessionId } : {}),
|
|
126
|
+
};
|
|
127
|
+
if (savedSessionId) {
|
|
128
|
+
logger.debug(`Onboarding session: resuming ${savedSessionId}`);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
logger.debug("Onboarding session: creating new session");
|
|
132
|
+
}
|
|
133
|
+
const textParts = [];
|
|
134
|
+
const state = { completed: false };
|
|
135
|
+
try {
|
|
136
|
+
for await (const msg of query({ prompt: userMessage, options })) {
|
|
137
|
+
if ("session_id" in msg && msg.session_id) {
|
|
138
|
+
this.captureSessionId(msg.session_id);
|
|
139
|
+
}
|
|
140
|
+
this.processMessage(msg, textParts, (isComplete) => {
|
|
141
|
+
if (isComplete)
|
|
142
|
+
state.completed = true;
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
const text = textParts.join("").trim();
|
|
148
|
+
if (text || state.completed) {
|
|
149
|
+
logger.debug("Onboarding query errored but collected partial response");
|
|
150
|
+
return { text, completed: state.completed };
|
|
151
|
+
}
|
|
152
|
+
if (abortController.signal.aborted) {
|
|
153
|
+
logger.warn("Onboarding query timed out");
|
|
154
|
+
}
|
|
155
|
+
return { text: "", completed: false, error: err instanceof Error ? err.message : String(err) };
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
clearTimeout(timeout);
|
|
159
|
+
}
|
|
160
|
+
const text = textParts.join("").trim();
|
|
161
|
+
if (state.completed && this.onCompleted) {
|
|
162
|
+
this.onCompleted();
|
|
163
|
+
}
|
|
164
|
+
return { text, completed: state.completed };
|
|
165
|
+
}
|
|
166
|
+
processMessage(msg, textParts, onCompleteTool) {
|
|
167
|
+
switch (msg.type) {
|
|
168
|
+
case "assistant": {
|
|
169
|
+
for (const block of msg.message.content) {
|
|
170
|
+
if (block.type === "text" && block.text) {
|
|
171
|
+
textParts.push(block.text);
|
|
172
|
+
}
|
|
173
|
+
if (block.type === "tool_use" && block.name === "complete_onboarding") {
|
|
174
|
+
onCompleteTool(true);
|
|
175
|
+
}
|
|
176
|
+
if (block.type === "tool_use" &&
|
|
177
|
+
block.name === "mcp__onboarding__complete_onboarding") {
|
|
178
|
+
onCompleteTool(true);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
case "result": {
|
|
184
|
+
const cost = msg.total_cost_usd.toFixed(4);
|
|
185
|
+
logger.debug(`Onboarding query: turns=${msg.num_turns} cost=$${cost} ` +
|
|
186
|
+
`in=${msg.usage.input_tokens} out=${msg.usage.output_tokens}`);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
default:
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
captureSessionId(id) {
|
|
194
|
+
if (id && id !== this.sessionId) {
|
|
195
|
+
this.sessionId = id;
|
|
196
|
+
saveOnboardingSessionId(id);
|
|
197
|
+
logger.debug(`Onboarding session ID saved: ${id}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
getSessionId() {
|
|
201
|
+
return this.sessionId;
|
|
202
|
+
}
|
|
203
|
+
setOnCompletedCallback(cb) {
|
|
204
|
+
this.onCompleted = cb;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=onboarding-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding-session.js","sourceRoot":"","sources":["../../src/onboarding/onboarding-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export declare const AVATAR_OPTIONS: readonly [{
|
|
2
|
+
readonly name: "visionclaw";
|
|
3
|
+
readonly label: "VisionClaw";
|
|
4
|
+
readonly file: "visionclaw.jpg";
|
|
5
|
+
}, {
|
|
6
|
+
readonly name: "robot";
|
|
7
|
+
readonly label: "Friendly Robot";
|
|
8
|
+
readonly file: "robot.jpg";
|
|
9
|
+
}, {
|
|
10
|
+
readonly name: "owl";
|
|
11
|
+
readonly label: "Wise Owl";
|
|
12
|
+
readonly file: "owl.jpg";
|
|
13
|
+
}, {
|
|
14
|
+
readonly name: "orb";
|
|
15
|
+
readonly label: "Crystal Orb";
|
|
16
|
+
readonly file: "orb.jpg";
|
|
17
|
+
}, {
|
|
18
|
+
readonly name: "fox";
|
|
19
|
+
readonly label: "Clever Fox";
|
|
20
|
+
readonly file: "fox.jpg";
|
|
21
|
+
}, {
|
|
22
|
+
readonly name: "cat";
|
|
23
|
+
readonly label: "Curious Cat";
|
|
24
|
+
readonly file: "cat.jpg";
|
|
25
|
+
}, {
|
|
26
|
+
readonly name: "abstract";
|
|
27
|
+
readonly label: "Abstract Geometry";
|
|
28
|
+
readonly file: "abstract.jpg";
|
|
29
|
+
}];
|
|
30
|
+
export interface OnboardingResult {
|
|
31
|
+
ownerName: string;
|
|
32
|
+
agentName: string;
|
|
33
|
+
wakeupIntervalMinutes: number;
|
|
34
|
+
}
|
|
35
|
+
interface OnboardingToolDeps {
|
|
36
|
+
botToken: string;
|
|
37
|
+
chatId: number;
|
|
38
|
+
sendPhoto: (chatId: number, photoPath: string, caption: string) => Promise<void>;
|
|
39
|
+
onComplete: (result: OnboardingResult) => void;
|
|
40
|
+
}
|
|
41
|
+
export declare function createOnboardingToolServer(deps: OnboardingToolDeps): import("@anthropic-ai/claude-agent-sdk").McpSdkServerConfigWithInstance;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=onboarding-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding-tools.d.ts","sourceRoot":"","sources":["../../src/onboarding/onboarding-tools.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQjB,CAAC;AAEX,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,UAAU,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAChD;AAmLD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,kBAAkB,2EAUlE"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
|
|
6
|
+
import { DEFAULT_HEARTBEAT_INTERVAL_MS } from "../config/types.js";
|
|
7
|
+
import { logger } from "../logger.js";
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const AVATARS_DIR = path.resolve(__dirname, "../../assets/avatars");
|
|
10
|
+
export const AVATAR_OPTIONS = [
|
|
11
|
+
{ name: "visionclaw", label: "VisionClaw", file: "visionclaw.jpg" },
|
|
12
|
+
{ name: "robot", label: "Friendly Robot", file: "robot.jpg" },
|
|
13
|
+
{ name: "owl", label: "Wise Owl", file: "owl.jpg" },
|
|
14
|
+
{ name: "orb", label: "Crystal Orb", file: "orb.jpg" },
|
|
15
|
+
{ name: "fox", label: "Clever Fox", file: "fox.jpg" },
|
|
16
|
+
{ name: "cat", label: "Curious Cat", file: "cat.jpg" },
|
|
17
|
+
{ name: "abstract", label: "Abstract Geometry", file: "abstract.jpg" },
|
|
18
|
+
];
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
20
|
+
function createSendAvatarOptionsTool(deps) {
|
|
21
|
+
return tool("send_avatar_options", "Send the available avatar/profile photo options to the user as Telegram photos. " +
|
|
22
|
+
"Call this when it's time for the user to choose a profile picture for the bot.", {}, async () => {
|
|
23
|
+
const results = [];
|
|
24
|
+
for (let i = 0; i < AVATAR_OPTIONS.length; i++) {
|
|
25
|
+
const opt = AVATAR_OPTIONS[i];
|
|
26
|
+
const filePath = path.join(AVATARS_DIR, opt.file);
|
|
27
|
+
if (!fs.existsSync(filePath)) {
|
|
28
|
+
results.push(`Option ${i + 1} (${opt.label}): file not found`);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
await deps.sendPhoto(deps.chatId, filePath, `Option ${i + 1}: ${opt.label}`);
|
|
33
|
+
results.push(`Option ${i + 1}: ${opt.label} ✓`);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
results.push(`Option ${i + 1} (${opt.label}): failed to send - ${err instanceof Error ? err.message : String(err)}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
content: [{
|
|
41
|
+
type: "text",
|
|
42
|
+
text: `Sent ${AVATAR_OPTIONS.length} avatar options to the user:\n${results.join("\n")}\n\n` +
|
|
43
|
+
"The user can reply with an option number (1-7) or send their own photo. " +
|
|
44
|
+
"They can also skip by saying they don't want to set a profile photo.",
|
|
45
|
+
}],
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
50
|
+
function createSetBotProfilePhotoTool(deps) {
|
|
51
|
+
return tool("set_bot_profile_photo", "Set the Telegram bot's profile photo. Use an option number (1-7) for a bundled avatar, " +
|
|
52
|
+
"or provide a Telegram file URL from a user-uploaded image.", {
|
|
53
|
+
source: z
|
|
54
|
+
.string()
|
|
55
|
+
.describe("Either an option number ('1' through '7') for a bundled avatar, " +
|
|
56
|
+
"or a Telegram file URL (https://api.telegram.org/file/...) from a user-uploaded image."),
|
|
57
|
+
}, async (args) => {
|
|
58
|
+
const { source } = args;
|
|
59
|
+
let photoPath;
|
|
60
|
+
let tempFile;
|
|
61
|
+
try {
|
|
62
|
+
const optionNum = parseInt(source, 10);
|
|
63
|
+
if (!isNaN(optionNum) && optionNum >= 1 && optionNum <= AVATAR_OPTIONS.length) {
|
|
64
|
+
const opt = AVATAR_OPTIONS[optionNum - 1];
|
|
65
|
+
photoPath = path.join(AVATARS_DIR, opt.file);
|
|
66
|
+
if (!fs.existsSync(photoPath)) {
|
|
67
|
+
return {
|
|
68
|
+
content: [{ type: "text", text: `Avatar file not found: ${opt.file}` }],
|
|
69
|
+
isError: true,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (source.startsWith("https://")) {
|
|
74
|
+
const res = await fetch(source);
|
|
75
|
+
if (!res.ok) {
|
|
76
|
+
return {
|
|
77
|
+
content: [{ type: "text", text: `Failed to download image: HTTP ${res.status}` }],
|
|
78
|
+
isError: true,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
82
|
+
tempFile = path.join(AVATARS_DIR, `_temp_upload_${Date.now()}.jpg`);
|
|
83
|
+
fs.writeFileSync(tempFile, buffer);
|
|
84
|
+
photoPath = tempFile;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
return {
|
|
88
|
+
content: [{
|
|
89
|
+
type: "text",
|
|
90
|
+
text: "Invalid source. Provide an option number (1-7) or a Telegram file URL.",
|
|
91
|
+
}],
|
|
92
|
+
isError: true,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const fileBuffer = fs.readFileSync(photoPath);
|
|
96
|
+
const file = new File([fileBuffer], "photo.jpg", { type: "image/jpeg" });
|
|
97
|
+
const form = new FormData();
|
|
98
|
+
form.append("photo", JSON.stringify({ type: "static", photo: "attach://photo_file" }));
|
|
99
|
+
form.append("photo_file", file);
|
|
100
|
+
const apiRes = await fetch(`https://api.telegram.org/bot${deps.botToken}/setMyProfilePhoto`, { method: "POST", body: form, signal: AbortSignal.timeout(30_000) });
|
|
101
|
+
const data = (await apiRes.json());
|
|
102
|
+
if (data.ok) {
|
|
103
|
+
logger.system("Telegram bot profile photo updated");
|
|
104
|
+
return {
|
|
105
|
+
content: [{ type: "text", text: "Bot profile photo updated successfully!" }],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
return {
|
|
110
|
+
content: [{
|
|
111
|
+
type: "text",
|
|
112
|
+
text: `Failed to set profile photo: ${data.description ?? "unknown error"}`,
|
|
113
|
+
}],
|
|
114
|
+
isError: true,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
return {
|
|
120
|
+
content: [{
|
|
121
|
+
type: "text",
|
|
122
|
+
text: `Error setting profile photo: ${err instanceof Error ? err.message : String(err)}`,
|
|
123
|
+
}],
|
|
124
|
+
isError: true,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
if (tempFile && fs.existsSync(tempFile)) {
|
|
129
|
+
fs.unlinkSync(tempFile);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
135
|
+
function createCompleteOnboardingTool(deps) {
|
|
136
|
+
return tool("complete_onboarding", "Finalize onboarding with the collected information. Call this ONLY after you have " +
|
|
137
|
+
"gathered all required info (owner name, agent name, wakeup interval) and the user " +
|
|
138
|
+
"has confirmed. After calling this tool, send a brief goodbye/welcome message and stop.", {
|
|
139
|
+
ownerName: z.string().min(1).describe("The owner's name"),
|
|
140
|
+
agentName: z
|
|
141
|
+
.string()
|
|
142
|
+
.default("VisionClaw")
|
|
143
|
+
.describe('The name the user chose for the agent (default: "VisionClaw")'),
|
|
144
|
+
wakeupIntervalMinutes: z
|
|
145
|
+
.number()
|
|
146
|
+
.min(1)
|
|
147
|
+
.max(1440)
|
|
148
|
+
.default(DEFAULT_HEARTBEAT_INTERVAL_MS / 60_000)
|
|
149
|
+
.describe("How often the agent wakes up, in minutes (1-1440, default: 3)"),
|
|
150
|
+
}, (args) => {
|
|
151
|
+
deps.onComplete({
|
|
152
|
+
ownerName: args.ownerName,
|
|
153
|
+
agentName: args.agentName,
|
|
154
|
+
wakeupIntervalMinutes: args.wakeupIntervalMinutes,
|
|
155
|
+
});
|
|
156
|
+
return Promise.resolve({
|
|
157
|
+
content: [{
|
|
158
|
+
type: "text",
|
|
159
|
+
text: `Onboarding finalized! Owner: ${args.ownerName}, Agent: ${args.agentName}, ` +
|
|
160
|
+
`Wakeup: every ${args.wakeupIntervalMinutes} min. ` +
|
|
161
|
+
"Send a brief welcome message to the user and then stop.",
|
|
162
|
+
}],
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
167
|
+
export function createOnboardingToolServer(deps) {
|
|
168
|
+
return createSdkMcpServer({
|
|
169
|
+
name: "onboarding",
|
|
170
|
+
version: "0.1.0",
|
|
171
|
+
tools: [
|
|
172
|
+
createSendAvatarOptionsTool(deps),
|
|
173
|
+
createSetBotProfilePhotoTool(deps),
|
|
174
|
+
createCompleteOnboardingTool(deps),
|
|
175
|
+
],
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=onboarding-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding-tools.js","sourceRoot":"","sources":["../../src/onboarding/onboarding-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { VisionClawConfig, OwnerConfig } from "../config/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Send the onboarding invitation email to the owner.
|
|
4
|
+
* Includes a verification code and a direct link to the Telegram bot.
|
|
5
|
+
*/
|
|
6
|
+
export declare function sendOnboardingEmail(config: VisionClawConfig, ownerConfig: OwnerConfig): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=send-invite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send-invite.d.ts","sourceRoot":"","sources":["../../src/onboarding/send-invite.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAqBxE;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,gBAAgB,EACxB,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,IAAI,CAAC,CAmDf"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { GmailEmailClient } from "../email/gmail-email.js";
|
|
2
|
+
import { logger } from "../logger.js";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the Telegram bot's username from its token using the Bot API.
|
|
5
|
+
*/
|
|
6
|
+
async function resolveBotUsername(botToken) {
|
|
7
|
+
try {
|
|
8
|
+
const res = await fetch(`https://api.telegram.org/bot${botToken}/getMe`);
|
|
9
|
+
const data = (await res.json());
|
|
10
|
+
return data.ok ? (data.result?.username ?? null) : null;
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
logger.warn(`Failed to resolve Telegram bot username: ${err instanceof Error ? err.message : String(err)}`);
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Send the onboarding invitation email to the owner.
|
|
19
|
+
* Includes a verification code and a direct link to the Telegram bot.
|
|
20
|
+
*/
|
|
21
|
+
export async function sendOnboardingEmail(config, ownerConfig) {
|
|
22
|
+
const botToken = config.channels.telegram?.botToken;
|
|
23
|
+
if (!botToken) {
|
|
24
|
+
throw new Error("Telegram is not configured. Cannot send onboarding email without a Telegram bot.");
|
|
25
|
+
}
|
|
26
|
+
const botUsername = await resolveBotUsername(botToken);
|
|
27
|
+
if (!botUsername) {
|
|
28
|
+
throw new Error("Could not resolve Telegram bot username. Check the bot token in config.json.");
|
|
29
|
+
}
|
|
30
|
+
const code = ownerConfig.onboardingCode;
|
|
31
|
+
if (!code) {
|
|
32
|
+
throw new Error("No onboarding code found in owner.json.");
|
|
33
|
+
}
|
|
34
|
+
const telegramLink = `https://t.me/${botUsername}`;
|
|
35
|
+
const emailBody = `Hi there!
|
|
36
|
+
|
|
37
|
+
I'm your new personal desktop assistant, and I'm ready to get started.
|
|
38
|
+
|
|
39
|
+
To complete setup, please open Telegram and message me. Here's how:
|
|
40
|
+
|
|
41
|
+
1. Click this link to open our chat: ${telegramLink}
|
|
42
|
+
2. Send me the following message:
|
|
43
|
+
|
|
44
|
+
/start ${code}
|
|
45
|
+
|
|
46
|
+
3. I'll walk you through the rest — just a couple of quick questions!
|
|
47
|
+
|
|
48
|
+
Your verification code: ${code}
|
|
49
|
+
|
|
50
|
+
If you don't have Telegram installed, you can get it at https://telegram.org
|
|
51
|
+
|
|
52
|
+
Looking forward to working with you!`;
|
|
53
|
+
const emailClient = new GmailEmailClient(config);
|
|
54
|
+
await emailClient.sendEmail({
|
|
55
|
+
to: ownerConfig.ownerEmail,
|
|
56
|
+
subject: "Your Personal Assistant Is Ready - Let's Get Started!",
|
|
57
|
+
body: emailBody,
|
|
58
|
+
});
|
|
59
|
+
logger.system(`Onboarding email sent to ${ownerConfig.ownerEmail} (bot: @${botUsername})`);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=send-invite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send-invite.js","sourceRoot":"","sources":["../../src/onboarding/send-invite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtC;;GAEG;AACH,KAAK,UAAU,kBAAkB,CAAC,QAAgB;IAChD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,+BAA+B,QAAQ,QAAQ,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAG7B,CAAC;QACF,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CACT,4CAA4C,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC/F,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAwB,EACxB,WAAwB;IAExB,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IACpD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,cAAc,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,YAAY,GAAG,gBAAgB,WAAW,EAAE,CAAC;IAEnD,MAAM,SAAS,GAAG;;;;;;uCAMmB,YAAY;;;YAGvC,IAAI;;;;0BAIU,IAAI;;;;qCAIO,CAAC;IAEpC,MAAM,WAAW,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,WAAW,CAAC,SAAS,CAAC;QAC1B,EAAE,EAAE,WAAW,CAAC,UAAU;QAC1B,OAAO,EAAE,uDAAuD;QAChE,IAAI,EAAE,SAAS;KAChB,CAAC,CAAC;IAEH,MAAM,CAAC,MAAM,CACX,4BAA4B,WAAW,CAAC,UAAU,WAAW,WAAW,GAAG,CAC5E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI command: visionclaw set-owner --email <owner-email>
|
|
3
|
+
*
|
|
4
|
+
* Writes a partial owner.json with the owner's email and a verification code.
|
|
5
|
+
* The agent will send an onboarding invitation email on next startup.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runSetOwner(args: string[]): void;
|
|
8
|
+
//# sourceMappingURL=set-owner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set-owner.d.ts","sourceRoot":"","sources":["../../src/onboarding/set-owner.ts"],"names":[],"mappings":"AAmBA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAiDhD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { configExists, ensureConfigDir, saveOwnerConfig, ownerConfigExists, } from "../config/index.js";
|
|
3
|
+
function generateVerificationCode() {
|
|
4
|
+
const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
|
5
|
+
let code = "";
|
|
6
|
+
const bytes = crypto.randomBytes(6);
|
|
7
|
+
for (let i = 0; i < 6; i++) {
|
|
8
|
+
code += chars[bytes[i] % chars.length];
|
|
9
|
+
}
|
|
10
|
+
return code;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* CLI command: visionclaw set-owner --email <owner-email>
|
|
14
|
+
*
|
|
15
|
+
* Writes a partial owner.json with the owner's email and a verification code.
|
|
16
|
+
* The agent will send an onboarding invitation email on next startup.
|
|
17
|
+
*/
|
|
18
|
+
export function runSetOwner(args) {
|
|
19
|
+
if (!configExists()) {
|
|
20
|
+
console.error("Error: No manufacturer config found. Run the agent first to complete manufacturer setup.");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
const emailIdx = args.indexOf("--email");
|
|
24
|
+
const email = emailIdx !== -1 && emailIdx + 1 < args.length
|
|
25
|
+
? args[emailIdx + 1]
|
|
26
|
+
: undefined;
|
|
27
|
+
if (!email?.includes("@")) {
|
|
28
|
+
console.error("Usage: visionclaw set-owner --email <owner-email>");
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
if (ownerConfigExists()) {
|
|
32
|
+
console.error("Error: owner.json already exists for this profile. Owner has already been set.");
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
ensureConfigDir();
|
|
36
|
+
const code = generateVerificationCode();
|
|
37
|
+
const ownerConfig = {
|
|
38
|
+
agentName: "VisionClaw",
|
|
39
|
+
ownerName: "",
|
|
40
|
+
ownerEmail: email,
|
|
41
|
+
allowedTelegramChatIds: [],
|
|
42
|
+
allowedDiscordChannelIds: [],
|
|
43
|
+
heartbeatIntervalMs: 3 * 60 * 1000,
|
|
44
|
+
onboardingComplete: false,
|
|
45
|
+
onboardingCodeVerified: false,
|
|
46
|
+
onboardingCode: code,
|
|
47
|
+
};
|
|
48
|
+
saveOwnerConfig(ownerConfig);
|
|
49
|
+
console.log(`\nOwner email set to: ${email}`);
|
|
50
|
+
console.log(`Verification code: ${code}`);
|
|
51
|
+
console.log("\nStart the agent to send the onboarding invitation email to the owner.");
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=set-owner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set-owner.js","sourceRoot":"","sources":["../../src/onboarding/set-owner.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,YAAY,EACZ,eAAe,EACf,eAAe,EACf,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,SAAS,wBAAwB;IAC/B,MAAM,KAAK,GAAG,kCAAkC,CAAC;IACjD,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CACX,0FAA0F,CAC3F,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,KAAK,GACT,QAAQ,KAAK,CAAC,CAAC,IAAI,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM;QAC3C,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QACpB,CAAC,CAAC,SAAS,CAAC;IAEhB,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,iBAAiB,EAAE,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CACX,gFAAgF,CACjF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,eAAe,EAAE,CAAC;IAElB,MAAM,IAAI,GAAG,wBAAwB,EAAE,CAAC;IAExC,MAAM,WAAW,GAAgB;QAC/B,SAAS,EAAE,YAAY;QACvB,SAAS,EAAE,EAAE;QACb,UAAU,EAAE,KAAK;QACjB,sBAAsB,EAAE,EAAE;QAC1B,wBAAwB,EAAE,EAAE;QAC5B,mBAAmB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;QAClC,kBAAkB,EAAE,KAAK;QACzB,sBAAsB,EAAE,KAAK;QAC7B,cAAc,EAAE,IAAI;KACrB,CAAC;IAEF,eAAe,CAAC,WAAW,CAAC,CAAC;IAE7B,OAAO,CAAC,GAAG,CAAC,yBAAyB,KAAK,EAAE,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CACT,yEAAyE,CAC1E,CAAC;AACJ,CAAC"}
|