assistme 0.8.6 → 0.8.8
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-ZBZWNZVA.js → chunk-T3DBLWUW.js} +26 -2
- package/dist/index.js +1 -1
- package/dist/workers/entry.js +18 -16
- package/package.json +1 -1
- package/src/agent/processor.ts +3 -0
- package/src/agent/skills.ts +31 -2
- package/src/mcp/agent-tools-server.ts +20 -21
|
@@ -2878,6 +2878,8 @@ var SkillManager = class {
|
|
|
2878
2878
|
userId = null;
|
|
2879
2879
|
/** Tracks the in-flight loadFromDb() promise so callers can await it. */
|
|
2880
2880
|
loadPromise = null;
|
|
2881
|
+
/** True once loadFromDb() completes without error (even with 0 skills). */
|
|
2882
|
+
loaded = false;
|
|
2881
2883
|
/** Bounded cache for findRelevant() — keyed by normalized prompt, invalidated on skill changes. */
|
|
2882
2884
|
relevanceCache = new LRUCache(MAX_RELEVANCE_CACHE_ENTRIES);
|
|
2883
2885
|
/** Bounded, TTL-aware cache for marketplace discover results. */
|
|
@@ -2896,11 +2898,31 @@ var SkillManager = class {
|
|
|
2896
2898
|
}
|
|
2897
2899
|
}
|
|
2898
2900
|
/**
|
|
2899
|
-
*
|
|
2900
|
-
*
|
|
2901
|
+
* Guarantee that loadFromDb() has completed at least once.
|
|
2902
|
+
* Awaits any in-flight load; retries once if the initial load failed.
|
|
2903
|
+
* Safe and cheap to call repeatedly — no-ops after the first success.
|
|
2901
2904
|
*/
|
|
2902
2905
|
async ensureLoaded() {
|
|
2903
2906
|
if (this.loadPromise) await this.loadPromise;
|
|
2907
|
+
if (!this.loaded && this.userId) {
|
|
2908
|
+
await this.loadFromDb();
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
/**
|
|
2912
|
+
* Get a skill by name, with a DB search fallback.
|
|
2913
|
+
* Handles: race conditions, failed initial loads, and skills added externally
|
|
2914
|
+
* after the initial load (e.g. created via UI while agent is running).
|
|
2915
|
+
*/
|
|
2916
|
+
async getWithDbFallback(name) {
|
|
2917
|
+
await this.ensureLoaded();
|
|
2918
|
+
const skill = this.skills.get(name);
|
|
2919
|
+
if (skill) return skill;
|
|
2920
|
+
const dbResults = await searchSkillsInDb(name, 5);
|
|
2921
|
+
const match = dbResults?.find((r) => r.name === name);
|
|
2922
|
+
if (!match) return void 0;
|
|
2923
|
+
this.loaded = false;
|
|
2924
|
+
await this.loadFromDb();
|
|
2925
|
+
return this.skills.get(name);
|
|
2904
2926
|
}
|
|
2905
2927
|
async _doLoadFromDb() {
|
|
2906
2928
|
try {
|
|
@@ -2912,6 +2934,7 @@ var SkillManager = class {
|
|
|
2912
2934
|
this.skills.set(row.name, this.rowToSkill(row));
|
|
2913
2935
|
}
|
|
2914
2936
|
this.rebuildIdfCache();
|
|
2937
|
+
this.loaded = true;
|
|
2915
2938
|
if (this.skills.size > 0) {
|
|
2916
2939
|
log.info(`Loaded ${this.skills.size} skill(s) from DB`);
|
|
2917
2940
|
}
|
|
@@ -3711,6 +3734,7 @@ export {
|
|
|
3711
3734
|
executeShell,
|
|
3712
3735
|
MemoryManager,
|
|
3713
3736
|
LRUCache,
|
|
3737
|
+
upsertAgentSkill,
|
|
3714
3738
|
SkillManager,
|
|
3715
3739
|
getLocalStore,
|
|
3716
3740
|
getCredentialStore
|
package/dist/index.js
CHANGED
package/dist/workers/entry.js
CHANGED
|
@@ -18,8 +18,9 @@ import {
|
|
|
18
18
|
getNextRunTime,
|
|
19
19
|
pollActionResponse,
|
|
20
20
|
resetEventSequence,
|
|
21
|
-
setActionRequest
|
|
22
|
-
|
|
21
|
+
setActionRequest,
|
|
22
|
+
upsertAgentSkill
|
|
23
|
+
} from "../chunk-T3DBLWUW.js";
|
|
23
24
|
import {
|
|
24
25
|
EDSGER_PRODUCT_SLUG,
|
|
25
26
|
JobRunner,
|
|
@@ -1779,25 +1780,26 @@ function createAgentToolsServer(deps) {
|
|
|
1779
1780
|
},
|
|
1780
1781
|
async (args) => {
|
|
1781
1782
|
await skillManager.ensureLoaded();
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
const available = skillManager.getAll().map((s) => s.name).join(", ");
|
|
1783
|
+
if (skillManager.update(args.name, args.improved_instructions, args.description)) {
|
|
1784
|
+
log.success(`Self-improvement: improved skill "${args.name}"`);
|
|
1785
1785
|
return {
|
|
1786
1786
|
content: [
|
|
1787
1787
|
{
|
|
1788
1788
|
type: "text",
|
|
1789
|
-
text: `Skill "${args.name}"
|
|
1789
|
+
text: `Skill "${args.name}" improved and version bumped.`
|
|
1790
1790
|
}
|
|
1791
1791
|
]
|
|
1792
1792
|
};
|
|
1793
1793
|
}
|
|
1794
|
-
const
|
|
1795
|
-
args.name,
|
|
1796
|
-
args.
|
|
1797
|
-
args.
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1794
|
+
const result = await upsertAgentSkill({
|
|
1795
|
+
name: args.name,
|
|
1796
|
+
description: args.description || "",
|
|
1797
|
+
content: args.improved_instructions,
|
|
1798
|
+
version: "1.0.1",
|
|
1799
|
+
source: "auto_improved"
|
|
1800
|
+
});
|
|
1801
|
+
if (result) {
|
|
1802
|
+
log.success(`Self-improvement: improved skill "${args.name}" (direct DB)`);
|
|
1801
1803
|
return {
|
|
1802
1804
|
content: [
|
|
1803
1805
|
{
|
|
@@ -1825,8 +1827,7 @@ function createAgentToolsServer(deps) {
|
|
|
1825
1827
|
arguments: z2.string().optional().describe("Arguments to pass to the skill (replaces $ARGUMENTS placeholders)")
|
|
1826
1828
|
},
|
|
1827
1829
|
async (args) => {
|
|
1828
|
-
await skillManager.
|
|
1829
|
-
let skill = skillManager.get(args.name);
|
|
1830
|
+
let skill = await skillManager.getWithDbFallback(args.name);
|
|
1830
1831
|
if (!skill) {
|
|
1831
1832
|
const confirmResult = await confirmMarketplaceSkill(
|
|
1832
1833
|
skillManager,
|
|
@@ -2140,7 +2141,7 @@ Use \`ask_user\` to request these from the user, or create them yourself (e.g. r
|
|
|
2140
2141
|
author_name: z2.string().optional().describe("Your display name as the author")
|
|
2141
2142
|
},
|
|
2142
2143
|
async (args) => {
|
|
2143
|
-
const skill = skillManager.
|
|
2144
|
+
const skill = await skillManager.getWithDbFallback(args.name);
|
|
2144
2145
|
if (!skill) {
|
|
2145
2146
|
return {
|
|
2146
2147
|
content: [
|
|
@@ -3323,6 +3324,7 @@ var TaskProcessor = class {
|
|
|
3323
3324
|
let tokenUsage;
|
|
3324
3325
|
try {
|
|
3325
3326
|
await emitEvent(task.id, "status_change", { status: "running" });
|
|
3327
|
+
await this.skillManager.ensureLoaded();
|
|
3326
3328
|
const systemPrompt = await buildSystemPrompt(task, {
|
|
3327
3329
|
memoryManager: this.memoryManager,
|
|
3328
3330
|
skillManager: this.skillManager,
|
package/package.json
CHANGED
package/src/agent/processor.ts
CHANGED
|
@@ -181,6 +181,9 @@ export class TaskProcessor {
|
|
|
181
181
|
try {
|
|
182
182
|
await emitEvent(task.id, "status_change", { status: "running" });
|
|
183
183
|
|
|
184
|
+
// Guarantee skills are loaded before building prompt or running tools
|
|
185
|
+
await this.skillManager.ensureLoaded();
|
|
186
|
+
|
|
184
187
|
// Build system prompt with memories + skills + history
|
|
185
188
|
const systemPrompt = await buildSystemPrompt(task, {
|
|
186
189
|
memoryManager: this.memoryManager,
|
package/src/agent/skills.ts
CHANGED
|
@@ -65,6 +65,8 @@ export class SkillManager {
|
|
|
65
65
|
|
|
66
66
|
/** Tracks the in-flight loadFromDb() promise so callers can await it. */
|
|
67
67
|
private loadPromise: Promise<void> | null = null;
|
|
68
|
+
/** True once loadFromDb() completes without error (even with 0 skills). */
|
|
69
|
+
private loaded = false;
|
|
68
70
|
|
|
69
71
|
/** Bounded cache for findRelevant() — keyed by normalized prompt, invalidated on skill changes. */
|
|
70
72
|
private relevanceCache = new LRUCache<
|
|
@@ -94,11 +96,37 @@ export class SkillManager {
|
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
+
* Guarantee that loadFromDb() has completed at least once.
|
|
100
|
+
* Awaits any in-flight load; retries once if the initial load failed.
|
|
101
|
+
* Safe and cheap to call repeatedly — no-ops after the first success.
|
|
99
102
|
*/
|
|
100
103
|
async ensureLoaded(): Promise<void> {
|
|
101
104
|
if (this.loadPromise) await this.loadPromise;
|
|
105
|
+
if (!this.loaded && this.userId) {
|
|
106
|
+
await this.loadFromDb();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get a skill by name, with a DB search fallback.
|
|
112
|
+
* Handles: race conditions, failed initial loads, and skills added externally
|
|
113
|
+
* after the initial load (e.g. created via UI while agent is running).
|
|
114
|
+
*/
|
|
115
|
+
async getWithDbFallback(name: string): Promise<Skill | undefined> {
|
|
116
|
+
await this.ensureLoaded();
|
|
117
|
+
|
|
118
|
+
const skill = this.skills.get(name);
|
|
119
|
+
if (skill) return skill;
|
|
120
|
+
|
|
121
|
+
// In-memory miss: check if the skill exists in DB via search
|
|
122
|
+
const dbResults = await searchSkillsInDb(name, 5);
|
|
123
|
+
const match = dbResults?.find((r) => r.name === name);
|
|
124
|
+
if (!match) return undefined;
|
|
125
|
+
|
|
126
|
+
// Found in DB — reload all skills into memory and return
|
|
127
|
+
this.loaded = false; // force reload
|
|
128
|
+
await this.loadFromDb();
|
|
129
|
+
return this.skills.get(name);
|
|
102
130
|
}
|
|
103
131
|
|
|
104
132
|
private async _doLoadFromDb(): Promise<void> {
|
|
@@ -113,6 +141,7 @@ export class SkillManager {
|
|
|
113
141
|
}
|
|
114
142
|
|
|
115
143
|
this.rebuildIdfCache();
|
|
144
|
+
this.loaded = true;
|
|
116
145
|
|
|
117
146
|
if (this.skills.size > 0) {
|
|
118
147
|
log.info(`Loaded ${this.skills.size} skill(s) from DB`);
|
|
@@ -10,6 +10,7 @@ import type { SkillManager } from "../agent/skills.js";
|
|
|
10
10
|
import { substituteArguments, preprocessDynamicContext } from "../agent/skill-utils.js";
|
|
11
11
|
import { validateSkillName } from "../agent/skill-utils.js";
|
|
12
12
|
import { callMcpHandler } from "../db/api-client.js";
|
|
13
|
+
import { upsertAgentSkill } from "../agent/skill-db.js";
|
|
13
14
|
import { JobRunner } from "../agent/job-runner.js";
|
|
14
15
|
import { createScheduledTask, getNextRunTime } from "../agent/scheduler.js";
|
|
15
16
|
import { getCredentialStore, type CredentialType } from "../credentials/index.js";
|
|
@@ -173,32 +174,32 @@ export function createAgentToolsServer(deps: AgentToolsDeps): McpSdkServerConfig
|
|
|
173
174
|
description: z.string().optional().describe("Updated description (optional)"),
|
|
174
175
|
},
|
|
175
176
|
async (args) => {
|
|
176
|
-
//
|
|
177
|
+
// Fast path: skill is in memory → update in-memory + DB
|
|
177
178
|
await skillManager.ensureLoaded();
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (!existing) {
|
|
181
|
-
const available = skillManager
|
|
182
|
-
.getAll()
|
|
183
|
-
.map((s) => s.name)
|
|
184
|
-
.join(", ");
|
|
179
|
+
if (skillManager.update(args.name, args.improved_instructions, args.description)) {
|
|
180
|
+
log.success(`Self-improvement: improved skill "${args.name}"`);
|
|
185
181
|
return {
|
|
186
182
|
content: [
|
|
187
183
|
{
|
|
188
184
|
type: "text",
|
|
189
|
-
text: `Skill "${args.name}"
|
|
185
|
+
text: `Skill "${args.name}" improved and version bumped.`,
|
|
190
186
|
},
|
|
191
187
|
],
|
|
192
188
|
};
|
|
193
189
|
}
|
|
194
190
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
191
|
+
// Fallback: skill not in memory (e.g. loadFromDb failed, race condition,
|
|
192
|
+
// or invoked from detail page where prompt already contains full content).
|
|
193
|
+
// Write directly to agent_skills — the tool params already have everything needed.
|
|
194
|
+
const result = await upsertAgentSkill({
|
|
195
|
+
name: args.name,
|
|
196
|
+
description: args.description || "",
|
|
197
|
+
content: args.improved_instructions,
|
|
198
|
+
version: "1.0.1",
|
|
199
|
+
source: "auto_improved",
|
|
200
|
+
});
|
|
201
|
+
if (result) {
|
|
202
|
+
log.success(`Self-improvement: improved skill "${args.name}" (direct DB)`);
|
|
202
203
|
return {
|
|
203
204
|
content: [
|
|
204
205
|
{
|
|
@@ -231,10 +232,8 @@ export function createAgentToolsServer(deps: AgentToolsDeps): McpSdkServerConfig
|
|
|
231
232
|
.describe("Arguments to pass to the skill (replaces $ARGUMENTS placeholders)"),
|
|
232
233
|
},
|
|
233
234
|
async (args) => {
|
|
234
|
-
//
|
|
235
|
-
await skillManager.
|
|
236
|
-
|
|
237
|
-
let skill = skillManager.get(args.name);
|
|
235
|
+
// Use DB fallback to handle race condition with async loadFromDb
|
|
236
|
+
let skill = await skillManager.getWithDbFallback(args.name);
|
|
238
237
|
|
|
239
238
|
// If not in user's collection, try marketplace — requires user confirmation
|
|
240
239
|
if (!skill) {
|
|
@@ -547,7 +546,7 @@ export function createAgentToolsServer(deps: AgentToolsDeps): McpSdkServerConfig
|
|
|
547
546
|
author_name: z.string().optional().describe("Your display name as the author"),
|
|
548
547
|
},
|
|
549
548
|
async (args) => {
|
|
550
|
-
const skill = skillManager.
|
|
549
|
+
const skill = await skillManager.getWithDbFallback(args.name);
|
|
551
550
|
if (!skill) {
|
|
552
551
|
return {
|
|
553
552
|
content: [
|