assistme 0.1.15 → 0.2.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/{chunk-ERK6A6GH.js → chunk-GHMZQ2UA.js} +202 -35
- package/dist/index.js +2644 -1709
- package/dist/job-runner-BH5MDQX3.js +6 -0
- package/package.json +1 -1
- package/src/agent/job-runner.ts +238 -0
- package/src/agent/mcp-servers.test.ts +2 -1
- package/src/agent/mcp-servers.ts +647 -36
- package/src/agent/processor.test.ts +9 -4
- package/src/agent/processor.ts +51 -78
- package/src/agent/scheduler.ts +1 -0
- package/src/agent/session.ts +101 -12
- package/src/agent/skill-extractor.ts +195 -0
- package/src/agent/skills.test.ts +28 -13
- package/src/agent/skills.ts +608 -437
- package/src/commands/auth.ts +92 -0
- package/src/commands/browser.ts +137 -0
- package/src/commands/config.ts +74 -0
- package/src/commands/job.ts +169 -0
- package/src/commands/memory.ts +152 -0
- package/src/commands/schedule.ts +143 -0
- package/src/commands/skill.ts +153 -0
- package/src/commands/start.ts +199 -0
- package/src/commands/status.ts +51 -0
- package/src/db/supabase.ts +31 -0
- package/src/index.ts +19 -833
- package/dist/supabase-5QTM5WBI.js +0 -46
- package/skills/form-filling/SKILL.md +0 -35
- package/skills/price-comparison/SKILL.md +0 -39
- package/skills/web-research/SKILL.md +0 -39
|
@@ -116,8 +116,6 @@ var log = {
|
|
|
116
116
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
117
117
|
import { join } from "path";
|
|
118
118
|
import { homedir } from "os";
|
|
119
|
-
var CLI_AGENT_ID = "00000000-0000-0000-0000-000000000001";
|
|
120
|
-
var DAYBOX_AGENT_ID = "00000000-0000-0000-0000-000000000002";
|
|
121
119
|
var AUTH_DIR = join(homedir(), ".config", "assistme");
|
|
122
120
|
var AUTH_FILE = join(AUTH_DIR, "auth.json");
|
|
123
121
|
function ensureAuthDir() {
|
|
@@ -254,22 +252,6 @@ async function createTask(conversationId, _userId, sessionId, prompt) {
|
|
|
254
252
|
if (error) throw new Error(`Failed to create task: ${error.message}`);
|
|
255
253
|
return { ...data, prompt };
|
|
256
254
|
}
|
|
257
|
-
async function pollPendingTasks(sessionId) {
|
|
258
|
-
const sb = getSupabase();
|
|
259
|
-
const { data, error } = await sb.rpc("mcp_poll_tasks", {
|
|
260
|
-
p_token_hash: getTokenHash(),
|
|
261
|
-
p_session_id: sessionId
|
|
262
|
-
});
|
|
263
|
-
if (error) {
|
|
264
|
-
log.warn(`Task poll failed: ${error.message}`);
|
|
265
|
-
return [];
|
|
266
|
-
}
|
|
267
|
-
const rows = data || [];
|
|
268
|
-
return rows.map((row) => ({
|
|
269
|
-
...row,
|
|
270
|
-
prompt: row.metadata?.prompt || row.content || ""
|
|
271
|
-
}));
|
|
272
|
-
}
|
|
273
255
|
async function pollAndClaimTask(sessionId) {
|
|
274
256
|
const sb = getSupabase();
|
|
275
257
|
const { data, error } = await sb.rpc("mcp_poll_and_claim_task", {
|
|
@@ -315,6 +297,18 @@ async function failTask(messageId, errorMessage) {
|
|
|
315
297
|
});
|
|
316
298
|
if (error) log.error(`Failed to update task status: ${error.message}`);
|
|
317
299
|
}
|
|
300
|
+
async function pollAndClaimJobRun(userId) {
|
|
301
|
+
const sb = getSupabase();
|
|
302
|
+
const { data, error } = await sb.rpc("claim_pending_job_run", {
|
|
303
|
+
p_user_id: userId
|
|
304
|
+
});
|
|
305
|
+
if (error) {
|
|
306
|
+
log.debug(`Job run poll failed: ${error.message}`);
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
if (!data) return null;
|
|
310
|
+
return data;
|
|
311
|
+
}
|
|
318
312
|
async function getConversationHistory(conversationId, excludeMessageId, limit = 20) {
|
|
319
313
|
const sb = getSupabase();
|
|
320
314
|
const { data, error } = await sb.from("conversation_messages").select("id, role, content, status, metadata, created_at").eq("conversation_id", conversationId).in("status", ["completed", "failed"]).neq("id", excludeMessageId).order("created_at", { ascending: false }).limit(limit);
|
|
@@ -346,19 +340,194 @@ async function emitEvent(messageId, eventType, eventData) {
|
|
|
346
340
|
});
|
|
347
341
|
if (error) log.warn(`Failed to emit event: ${error.message}`);
|
|
348
342
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
343
|
+
|
|
344
|
+
// src/agent/job-runner.ts
|
|
345
|
+
var JobRunner = class {
|
|
346
|
+
userId;
|
|
347
|
+
constructor(userId) {
|
|
348
|
+
this.userId = userId;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Load a job and its linked skills from the database.
|
|
352
|
+
* Skills are the agent's *capabilities* — not a fixed execution plan.
|
|
353
|
+
*/
|
|
354
|
+
async loadJob(jobName) {
|
|
355
|
+
try {
|
|
356
|
+
const sb = getSupabase();
|
|
357
|
+
const { data, error } = await sb.rpc("get_job_with_skills", {
|
|
358
|
+
p_user_id: this.userId,
|
|
359
|
+
p_job_name: jobName
|
|
360
|
+
});
|
|
361
|
+
if (error || !data || data.length === 0) {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
const rows = data;
|
|
365
|
+
const first = rows[0];
|
|
366
|
+
return {
|
|
367
|
+
jobId: first.job_id,
|
|
368
|
+
jobName: first.job_name,
|
|
369
|
+
jobDescription: first.job_description,
|
|
370
|
+
skills: rows.map((row) => ({
|
|
371
|
+
skillId: row.skill_id,
|
|
372
|
+
skillName: row.skill_name,
|
|
373
|
+
skillDescription: row.skill_description || "",
|
|
374
|
+
skillEmoji: row.skill_emoji || "",
|
|
375
|
+
skillContent: row.skill_content || ""
|
|
376
|
+
}))
|
|
377
|
+
};
|
|
378
|
+
} catch (err) {
|
|
379
|
+
log.debug(`Failed to load job "${jobName}": ${err}`);
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* List all jobs for the user.
|
|
385
|
+
*/
|
|
386
|
+
async listJobs() {
|
|
387
|
+
try {
|
|
388
|
+
const sb = getSupabase();
|
|
389
|
+
const { data: jobs, error } = await sb.from("agent_jobs").select("id, name, description").eq("user_id", this.userId).eq("is_active", true).order("name");
|
|
390
|
+
if (error || !jobs) return [];
|
|
391
|
+
const result = [];
|
|
392
|
+
for (const job of jobs) {
|
|
393
|
+
const { count } = await sb.from("agent_job_skills").select("id", { count: "exact", head: true }).eq("job_id", job.id);
|
|
394
|
+
result.push({
|
|
395
|
+
id: job.id,
|
|
396
|
+
name: job.name,
|
|
397
|
+
description: job.description,
|
|
398
|
+
skillCount: count || 0
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
return result;
|
|
402
|
+
} catch (err) {
|
|
403
|
+
log.debug(`Failed to list jobs: ${err}`);
|
|
404
|
+
return [];
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Create a job run record.
|
|
409
|
+
* This is just a timestamp + status tracker. The actual execution trace
|
|
410
|
+
* lives in the conversation transcript (message_events).
|
|
411
|
+
*/
|
|
412
|
+
async createRun(jobId, options) {
|
|
413
|
+
try {
|
|
414
|
+
const sb = getSupabase();
|
|
415
|
+
const { data, error } = await sb.rpc("create_job_run", {
|
|
416
|
+
p_user_id: this.userId,
|
|
417
|
+
p_job_id: jobId,
|
|
418
|
+
p_session_id: options?.sessionId || null,
|
|
419
|
+
p_message_id: options?.messageId || null,
|
|
420
|
+
p_trigger_type: options?.triggerType || "manual"
|
|
421
|
+
});
|
|
422
|
+
if (error) {
|
|
423
|
+
log.debug(`Failed to create job run: ${error.message}`);
|
|
424
|
+
return null;
|
|
425
|
+
}
|
|
426
|
+
return data;
|
|
427
|
+
} catch (err) {
|
|
428
|
+
log.debug(`Job run creation error: ${err}`);
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Mark a job run as completed/failed.
|
|
434
|
+
* Throws on failure so callers can handle (e.g. avoid duplicate execution).
|
|
435
|
+
*/
|
|
436
|
+
async completeRun(runId, status = "completed", summary) {
|
|
437
|
+
const sb = getSupabase();
|
|
438
|
+
const { error } = await sb.rpc("complete_job_run", {
|
|
439
|
+
p_run_id: runId,
|
|
440
|
+
p_status: status,
|
|
441
|
+
p_summary: summary?.slice(0, 1e4) || null,
|
|
442
|
+
p_user_id: this.userId
|
|
443
|
+
});
|
|
444
|
+
if (error) {
|
|
445
|
+
log.error(`Failed to mark run ${runId} as ${status}: ${error.message}`);
|
|
446
|
+
throw new Error(`Run completion failed: ${error.message}`);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Get recent job run history.
|
|
451
|
+
*/
|
|
452
|
+
async getRunHistory(jobName, limit = 10) {
|
|
453
|
+
try {
|
|
454
|
+
const sb = getSupabase();
|
|
455
|
+
const { data, error } = await sb.rpc("get_job_runs", {
|
|
456
|
+
p_user_id: this.userId,
|
|
457
|
+
p_job_name: jobName || null,
|
|
458
|
+
p_limit: limit
|
|
459
|
+
});
|
|
460
|
+
if (error || !data) return [];
|
|
461
|
+
return data.map((row) => ({
|
|
462
|
+
runId: row.run_id,
|
|
463
|
+
jobName: row.job_name,
|
|
464
|
+
status: row.status,
|
|
465
|
+
triggerType: row.trigger_type,
|
|
466
|
+
startedAt: row.started_at,
|
|
467
|
+
completedAt: row.completed_at || null,
|
|
468
|
+
summary: row.summary || null
|
|
469
|
+
}));
|
|
470
|
+
} catch (err) {
|
|
471
|
+
log.debug(`Run history error: ${err}`);
|
|
472
|
+
return [];
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Build the agentic prompt for the agent to execute a job.
|
|
477
|
+
*
|
|
478
|
+
* This does NOT prescribe a fixed sequence. Instead, it tells the agent
|
|
479
|
+
* the job's goal and lists available skills as capabilities. The agent
|
|
480
|
+
* decides dynamically which skills to use, in what order, and how to
|
|
481
|
+
* chain them based on what it discovers at runtime.
|
|
482
|
+
*/
|
|
483
|
+
buildJobPrompt(job, runId) {
|
|
484
|
+
let prompt = `## Job: ${job.jobName}
|
|
485
|
+
`;
|
|
486
|
+
prompt += `*${job.jobDescription}*
|
|
487
|
+
|
|
488
|
+
`;
|
|
489
|
+
prompt += `**Run ID:** ${runId}
|
|
490
|
+
|
|
491
|
+
`;
|
|
492
|
+
prompt += `You are now acting as "${job.jobName}". `;
|
|
493
|
+
prompt += `Your goal is to accomplish the objectives described above using the skills and tools available to you.
|
|
494
|
+
|
|
495
|
+
`;
|
|
496
|
+
prompt += `### Available Skills
|
|
497
|
+
`;
|
|
498
|
+
prompt += `These skills are your capabilities for this job. `;
|
|
499
|
+
prompt += `Use \`skill_invoke\` to load any skill's full instructions when you need it. `;
|
|
500
|
+
prompt += `You do NOT need to use all of them \u2014 pick the ones relevant to the current situation.
|
|
501
|
+
|
|
502
|
+
`;
|
|
503
|
+
for (const skill of job.skills) {
|
|
504
|
+
const emoji = skill.skillEmoji ? `${skill.skillEmoji} ` : "";
|
|
505
|
+
prompt += `- **${emoji}${skill.skillName}**: ${skill.skillDescription}
|
|
506
|
+
`;
|
|
507
|
+
}
|
|
508
|
+
prompt += `
|
|
509
|
+
### How to Work
|
|
510
|
+
`;
|
|
511
|
+
prompt += `- **Be agentic**: Decide what to do based on what you discover. `;
|
|
512
|
+
prompt += `If checking Slack reveals a request that requires GitHub work, go do the GitHub work immediately \u2014 don't just note it for later.
|
|
513
|
+
`;
|
|
514
|
+
prompt += `- **Chain dynamically**: One skill's output should inform your next action. `;
|
|
515
|
+
prompt += `For example, if you find an assigned GitHub issue, use your coding skills to implement it.
|
|
516
|
+
`;
|
|
517
|
+
prompt += `- **Skip what's irrelevant**: If a capability doesn't apply right now, skip it.
|
|
518
|
+
`;
|
|
519
|
+
prompt += `- **Use tools directly too**: You also have browser, file, and shell tools. `;
|
|
520
|
+
prompt += `Use them directly when a skill isn't needed \u2014 skills are guides, not mandatory steps.
|
|
521
|
+
`;
|
|
522
|
+
prompt += `- **Respond and act**: If you find messages or issues that need replies, reply to them. `;
|
|
523
|
+
prompt += `If you find code tasks, implement them.
|
|
524
|
+
|
|
525
|
+
`;
|
|
526
|
+
prompt += `When finished, provide a summary of what you accomplished and any items that need the user's attention.
|
|
527
|
+
`;
|
|
528
|
+
return prompt;
|
|
529
|
+
}
|
|
530
|
+
};
|
|
362
531
|
|
|
363
532
|
export {
|
|
364
533
|
getConfig,
|
|
@@ -369,8 +538,6 @@ export {
|
|
|
369
538
|
setCorrelationId,
|
|
370
539
|
newCorrelationId,
|
|
371
540
|
log,
|
|
372
|
-
CLI_AGENT_ID,
|
|
373
|
-
DAYBOX_AGENT_ID,
|
|
374
541
|
getSupabase,
|
|
375
542
|
loginWithToken,
|
|
376
543
|
getCurrentUserId,
|
|
@@ -381,13 +548,13 @@ export {
|
|
|
381
548
|
setSessionBusy,
|
|
382
549
|
getOrCreateCliConversation,
|
|
383
550
|
createTask,
|
|
384
|
-
pollPendingTasks,
|
|
385
551
|
pollAndClaimTask,
|
|
386
552
|
claimTask,
|
|
387
553
|
completeTask,
|
|
388
554
|
failTask,
|
|
555
|
+
pollAndClaimJobRun,
|
|
389
556
|
getConversationHistory,
|
|
390
557
|
resetEventSequence,
|
|
391
558
|
emitEvent,
|
|
392
|
-
|
|
559
|
+
JobRunner
|
|
393
560
|
};
|