@heylemon/lemonade 0.4.2 → 0.4.4
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.
|
@@ -337,6 +337,10 @@ export function buildAgentSystemPrompt(params) {
|
|
|
337
337
|
"",
|
|
338
338
|
"⚠️ CRITICAL: NEVER narrate your internal search/discovery process to the user. When searching for tools, trying different queries, checking connection status, etc. — do all of that SILENTLY. The user should only see the FINAL result or a brief status like 'Checking your LinkedIn...' Do NOT say things like 'Let me try a more specific search', 'Let me search for tools that can...', 'I found tools but...', 'Let me try one more search'. Just do the work and give the answer.",
|
|
339
339
|
"",
|
|
340
|
+
"⚠️ NEVER expose technical details to the user. NEVER mention tool names (e.g. LINKEDIN_GET_POST_CONTENT), tool slugs, API names, Composio, integration details, connection status, or internal implementation. The user doesn't know or care about tools — they just want results. Speak in plain human language only.",
|
|
341
|
+
"",
|
|
342
|
+
"⚠️ NEVER give up or tell the user to do it themselves. If CLI tools can't do it, use the browser. If the browser requires login, ask the user to log in and wait. If the user IS logged in, just do the task — navigate to their profile, find what they asked for, and give them the answer. You have a browser — USE IT. Do NOT say 'You might want to check LinkedIn directly' or 'I cannot do this'. You CAN do it via the browser.",
|
|
343
|
+
"",
|
|
340
344
|
"## Action Bias",
|
|
341
345
|
"ALWAYS execute tasks directly instead of presenting options or asking how the user wants it done.",
|
|
342
346
|
"If the user asks you to do something (take a screenshot, send a file, etc.), just do it — pick the best approach and act.",
|
|
@@ -366,7 +370,7 @@ export function buildAgentSystemPrompt(params) {
|
|
|
366
370
|
'1. Run `lemon-composio search "<what the user wants>"` — this is your FIRST action. No web search. No `which`. No `--help`. No questions.',
|
|
367
371
|
"2. If result shows `connected: true` → execute the tool immediately with `lemon-composio execute`.",
|
|
368
372
|
"3. If the search returns results but none match the exact action, try broader/different search terms SILENTLY. Do NOT tell the user you're retrying searches.",
|
|
369
|
-
|
|
373
|
+
"4. If the service IS connected but the specific action truly doesn't exist, open the browser to do it. Tell the user briefly: \"Let me do this in the browser — I'll have better control there.\" Do NOT mention Composio, tools, searches, integrations, or any technical details.",
|
|
370
374
|
'5. If result shows `connected: false` → include the `connectUrl` from the search result as plain text (no backticks, no bold, no brackets) e.g. lemon://connect?provider=jira. The app will automatically open the auth page. Say "Connecting [service name] for you: lemon://connect?provider=X" Then STOP and wait for them to complete the auth.',
|
|
371
375
|
"6. Once the user confirms they connected → execute the tool.",
|
|
372
376
|
"7. If `lemon-composio` has no results OR `lemon://connect` fails → use the browser as fallback. Open the service website, let the user log in, and complete the task via browser tools.",
|
|
@@ -430,9 +434,9 @@ export function buildAgentSystemPrompt(params) {
|
|
|
430
434
|
"",
|
|
431
435
|
"Then based on results:",
|
|
432
436
|
'1. **Tools found + connected** → Execute immediately: `lemon-composio execute <TOOL_SLUG> \'{"param": "value"}\'`. If the first search doesn\'t find the right tool, try different search terms (broader terms, service name only, etc.) before giving up.',
|
|
433
|
-
|
|
437
|
+
"2. **No tools found but `serviceConnected: true`** → The user IS connected but this specific action isn't available as a tool. Try a broader search first (e.g. just the service name). If still nothing, tell the user: \"Let me do this in the browser — I'll have better control there.\" Then use the browser. Do NOT try to connect again.",
|
|
434
438
|
"3. **Not connected (`serviceConnected: false`)** → Include the `connectUrl` from the result as plain text: lemon://connect?provider=X. NEVER output a connect URL if `serviceConnected` is true or if the provider appears in `connectedProviders`.",
|
|
435
|
-
|
|
439
|
+
'4. **Connect fails or no results at all** → Tell the user: "Let me do this in the browser — I\'ll have better control there." Then use the browser directly.',
|
|
436
440
|
"",
|
|
437
441
|
"Example flows:",
|
|
438
442
|
'- User: "add a card to my Trello board" → `lemon-composio search "create trello card"` → execute `TRELLO_CREATE_CARD`',
|
package/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
e0ea56bc65e9032f0bba0b7dc14b9fd11af21ca1c5cf8ec22ccf517553455d56
|
|
@@ -207,9 +207,9 @@ async function withSessionStoreLock(storePath, fn, opts = {}) {
|
|
|
207
207
|
if (!storePath || typeof storePath !== "string") {
|
|
208
208
|
throw new Error(`withSessionStoreLock: storePath must be a non-empty string, got ${JSON.stringify(storePath)}`);
|
|
209
209
|
}
|
|
210
|
-
const timeoutMs = opts.timeoutMs ??
|
|
211
|
-
const pollIntervalMs = opts.pollIntervalMs ??
|
|
212
|
-
const staleMs = opts.staleMs ??
|
|
210
|
+
const timeoutMs = opts.timeoutMs ?? 30_000;
|
|
211
|
+
const pollIntervalMs = opts.pollIntervalMs ?? 50;
|
|
212
|
+
const staleMs = opts.staleMs ?? 15_000;
|
|
213
213
|
const lockPath = `${storePath}.lock`;
|
|
214
214
|
const startedAt = Date.now();
|
|
215
215
|
await fs.promises.mkdir(path.dirname(storePath), { recursive: true });
|
|
@@ -242,7 +242,27 @@ async function withSessionStoreLock(storePath, fn, opts = {}) {
|
|
|
242
242
|
throw err;
|
|
243
243
|
const now = Date.now();
|
|
244
244
|
if (now - startedAt > timeoutMs) {
|
|
245
|
-
|
|
245
|
+
// Force-remove the stale lock and retry once instead of crashing
|
|
246
|
+
try {
|
|
247
|
+
await fs.promises.unlink(lockPath);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// ignore
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
const handle = await fs.promises.open(lockPath, "wx");
|
|
254
|
+
try {
|
|
255
|
+
await handle.writeFile(JSON.stringify({ pid: process.pid, startedAt: Date.now() }), "utf-8");
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
// best-effort
|
|
259
|
+
}
|
|
260
|
+
await handle.close();
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
throw new Error(`timeout acquiring session store lock: ${lockPath}`);
|
|
265
|
+
}
|
|
246
266
|
}
|
|
247
267
|
// Best-effort stale lock eviction (e.g. crashed process).
|
|
248
268
|
try {
|
package/package.json
CHANGED
package/skills/browser/SKILL.md
CHANGED
|
@@ -107,6 +107,9 @@ Use browser when Composio isn't available or as fallback after connect fails.
|
|
|
107
107
|
| Airtable | `airtable.com` |
|
|
108
108
|
| Shopify | `admin.shopify.com` |
|
|
109
109
|
| Todoist | `app.todoist.com` |
|
|
110
|
+
| LinkedIn | `linkedin.com/feed` |
|
|
111
|
+
| Twitter/X | `x.com/home` |
|
|
112
|
+
| Discord | `discord.com/channels/@me` |
|
|
110
113
|
|
|
111
114
|
**DO NOT navigate to:** `mail.google.com`, `calendar.google.com`, `drive.google.com`, `docs.google.com`, `sheets.google.com`, `slides.google.com`, `notion.so`, `app.slack.com`, `youtube.com`, `open.spotify.com` — use `lemon-*` CLI tools or AppleScript for these.
|
|
112
115
|
|
|
@@ -61,7 +61,9 @@ Some services (Jira, Trello, Asana, Confluence, etc.) require knowing the user's
|
|
|
61
61
|
|
|
62
62
|
## Browser Fallback
|
|
63
63
|
|
|
64
|
-
When
|
|
64
|
+
When CLI tools or Composio can't do something, ALWAYS use the browser. NEVER give up or tell the user to do it themselves.
|
|
65
65
|
|
|
66
|
-
1. **Use the browser to complete the task directly.** Open the service website
|
|
67
|
-
2. **
|
|
66
|
+
1. **Use the browser to complete the task directly.** Open the service website. If the user is already logged in, just do the task — navigate to the right page, find the information, and give them the answer.
|
|
67
|
+
2. **If the user needs to log in**, ask them to log in and WAIT. Once they're logged in, continue with the task.
|
|
68
|
+
3. **NEVER say "I can't do this" or "you might want to check it yourself."** You have a browser — use it to get the answer.
|
|
69
|
+
4. **NEVER mention technical details** like tool names, API limitations, or integration status. Just do the work silently.
|