@everworker/oneringai 0.1.2 → 0.1.3
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 +55 -24
- package/dist/index.cjs +275 -99
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -38
- package/dist/index.d.ts +88 -38
- package/dist/index.js +275 -99
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -15089,8 +15089,8 @@ var DEFAULT_ALLOWLIST = [
|
|
|
15089
15089
|
"context_list",
|
|
15090
15090
|
// Persistent instructions tools
|
|
15091
15091
|
"instructions_set",
|
|
15092
|
-
"
|
|
15093
|
-
"
|
|
15092
|
+
"instructions_remove",
|
|
15093
|
+
"instructions_list",
|
|
15094
15094
|
"instructions_clear",
|
|
15095
15095
|
// Meta-tools (internal coordination)
|
|
15096
15096
|
"_start_planning",
|
|
@@ -19664,22 +19664,45 @@ function sanitizeAgentId(agentId) {
|
|
|
19664
19664
|
var FilePersistentInstructionsStorage = class {
|
|
19665
19665
|
directory;
|
|
19666
19666
|
filePath;
|
|
19667
|
+
legacyFilePath;
|
|
19667
19668
|
agentId;
|
|
19668
19669
|
constructor(config) {
|
|
19669
19670
|
this.agentId = config.agentId;
|
|
19670
19671
|
const sanitizedId = sanitizeAgentId(config.agentId);
|
|
19671
19672
|
const baseDir = config.baseDirectory ?? getDefaultBaseDirectory();
|
|
19672
|
-
const filename = config.filename ?? "custom_instructions.
|
|
19673
|
+
const filename = config.filename ?? "custom_instructions.json";
|
|
19673
19674
|
this.directory = path3.join(baseDir, sanitizedId);
|
|
19674
19675
|
this.filePath = path3.join(this.directory, filename);
|
|
19676
|
+
this.legacyFilePath = path3.join(this.directory, "custom_instructions.md");
|
|
19675
19677
|
}
|
|
19676
19678
|
/**
|
|
19677
|
-
* Load
|
|
19679
|
+
* Load instruction entries from file.
|
|
19680
|
+
* Falls back to legacy .md file migration if JSON not found.
|
|
19678
19681
|
*/
|
|
19679
19682
|
async load() {
|
|
19680
19683
|
try {
|
|
19681
|
-
const
|
|
19682
|
-
|
|
19684
|
+
const raw = await fs15.promises.readFile(this.filePath, "utf-8");
|
|
19685
|
+
const data = JSON.parse(raw);
|
|
19686
|
+
if (data.version === 2 && Array.isArray(data.entries)) {
|
|
19687
|
+
return data.entries.length > 0 ? data.entries : null;
|
|
19688
|
+
}
|
|
19689
|
+
return null;
|
|
19690
|
+
} catch (error) {
|
|
19691
|
+
if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
|
|
19692
|
+
throw error;
|
|
19693
|
+
}
|
|
19694
|
+
}
|
|
19695
|
+
try {
|
|
19696
|
+
const content = await fs15.promises.readFile(this.legacyFilePath, "utf-8");
|
|
19697
|
+
const trimmed = content.trim();
|
|
19698
|
+
if (!trimmed) return null;
|
|
19699
|
+
const now = Date.now();
|
|
19700
|
+
return [{
|
|
19701
|
+
id: "legacy_instructions",
|
|
19702
|
+
content: trimmed,
|
|
19703
|
+
createdAt: now,
|
|
19704
|
+
updatedAt: now
|
|
19705
|
+
}];
|
|
19683
19706
|
} catch (error) {
|
|
19684
19707
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
19685
19708
|
return null;
|
|
@@ -19688,14 +19711,19 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19688
19711
|
}
|
|
19689
19712
|
}
|
|
19690
19713
|
/**
|
|
19691
|
-
* Save
|
|
19692
|
-
* Creates directory if it doesn't exist
|
|
19714
|
+
* Save instruction entries to file as JSON.
|
|
19715
|
+
* Creates directory if it doesn't exist.
|
|
19716
|
+
* Cleans up legacy .md file if present.
|
|
19693
19717
|
*/
|
|
19694
|
-
async save(
|
|
19718
|
+
async save(entries) {
|
|
19695
19719
|
await this.ensureDirectory();
|
|
19720
|
+
const data = {
|
|
19721
|
+
version: 2,
|
|
19722
|
+
entries
|
|
19723
|
+
};
|
|
19696
19724
|
const tempPath = `${this.filePath}.tmp`;
|
|
19697
19725
|
try {
|
|
19698
|
-
await fs15.promises.writeFile(tempPath,
|
|
19726
|
+
await fs15.promises.writeFile(tempPath, JSON.stringify(data, null, 2), "utf-8");
|
|
19699
19727
|
await fs15.promises.rename(tempPath, this.filePath);
|
|
19700
19728
|
} catch (error) {
|
|
19701
19729
|
try {
|
|
@@ -19704,9 +19732,10 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19704
19732
|
}
|
|
19705
19733
|
throw error;
|
|
19706
19734
|
}
|
|
19735
|
+
await this.removeLegacyFile();
|
|
19707
19736
|
}
|
|
19708
19737
|
/**
|
|
19709
|
-
* Delete instructions file
|
|
19738
|
+
* Delete instructions file (and legacy .md if exists)
|
|
19710
19739
|
*/
|
|
19711
19740
|
async delete() {
|
|
19712
19741
|
try {
|
|
@@ -19716,16 +19745,22 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19716
19745
|
throw error;
|
|
19717
19746
|
}
|
|
19718
19747
|
}
|
|
19748
|
+
await this.removeLegacyFile();
|
|
19719
19749
|
}
|
|
19720
19750
|
/**
|
|
19721
|
-
* Check if instructions file exists
|
|
19751
|
+
* Check if instructions file exists (JSON or legacy .md)
|
|
19722
19752
|
*/
|
|
19723
19753
|
async exists() {
|
|
19724
19754
|
try {
|
|
19725
19755
|
await fs15.promises.access(this.filePath);
|
|
19726
19756
|
return true;
|
|
19727
19757
|
} catch {
|
|
19728
|
-
|
|
19758
|
+
try {
|
|
19759
|
+
await fs15.promises.access(this.legacyFilePath);
|
|
19760
|
+
return true;
|
|
19761
|
+
} catch {
|
|
19762
|
+
return false;
|
|
19763
|
+
}
|
|
19729
19764
|
}
|
|
19730
19765
|
}
|
|
19731
19766
|
/**
|
|
@@ -19752,58 +19787,79 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19752
19787
|
}
|
|
19753
19788
|
}
|
|
19754
19789
|
}
|
|
19790
|
+
/**
|
|
19791
|
+
* Remove legacy .md file if it exists
|
|
19792
|
+
*/
|
|
19793
|
+
async removeLegacyFile() {
|
|
19794
|
+
try {
|
|
19795
|
+
await fs15.promises.unlink(this.legacyFilePath);
|
|
19796
|
+
} catch (error) {
|
|
19797
|
+
if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
|
|
19798
|
+
console.warn(`Failed to remove legacy instructions file: ${this.legacyFilePath}`);
|
|
19799
|
+
}
|
|
19800
|
+
}
|
|
19801
|
+
}
|
|
19755
19802
|
};
|
|
19756
19803
|
|
|
19757
19804
|
// src/core/context-nextgen/plugins/PersistentInstructionsPluginNextGen.ts
|
|
19758
|
-
var
|
|
19805
|
+
var DEFAULT_MAX_TOTAL_LENGTH = 5e4;
|
|
19806
|
+
var DEFAULT_MAX_ENTRIES = 50;
|
|
19807
|
+
var KEY_MAX_LENGTH = 100;
|
|
19808
|
+
var KEY_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
19759
19809
|
var PERSISTENT_INSTRUCTIONS_INSTRUCTIONS = `Persistent Instructions are stored on disk and survive across sessions.
|
|
19810
|
+
Each instruction is a keyed entry that can be independently managed.
|
|
19760
19811
|
|
|
19761
19812
|
**To modify:**
|
|
19762
|
-
- \`instructions_set(content)\`:
|
|
19763
|
-
- \`
|
|
19764
|
-
- \`
|
|
19813
|
+
- \`instructions_set(key, content)\`: Add or update a single instruction by key
|
|
19814
|
+
- \`instructions_remove(key)\`: Remove a single instruction by key
|
|
19815
|
+
- \`instructions_list()\`: List all instructions with keys and content
|
|
19816
|
+
- \`instructions_clear(confirm: true)\`: Remove all instructions (destructive!)
|
|
19765
19817
|
|
|
19766
19818
|
**Use for:** Agent personality, user preferences, learned rules, guidelines.`;
|
|
19767
19819
|
var instructionsSetDefinition = {
|
|
19768
19820
|
type: "function",
|
|
19769
19821
|
function: {
|
|
19770
19822
|
name: "instructions_set",
|
|
19771
|
-
description: `
|
|
19772
|
-
|
|
19823
|
+
description: `Add or update a single persistent instruction by key. Persists across sessions.
|
|
19824
|
+
If the key exists, it will be updated. If not, a new entry is created.`,
|
|
19773
19825
|
parameters: {
|
|
19774
19826
|
type: "object",
|
|
19775
19827
|
properties: {
|
|
19828
|
+
key: {
|
|
19829
|
+
type: "string",
|
|
19830
|
+
description: "Unique key for the instruction (alphanumeric, dash, underscore; max 100 chars)"
|
|
19831
|
+
},
|
|
19776
19832
|
content: {
|
|
19777
19833
|
type: "string",
|
|
19778
|
-
description: "
|
|
19834
|
+
description: "Instruction content (markdown supported)"
|
|
19779
19835
|
}
|
|
19780
19836
|
},
|
|
19781
|
-
required: ["content"]
|
|
19837
|
+
required: ["key", "content"]
|
|
19782
19838
|
}
|
|
19783
19839
|
}
|
|
19784
19840
|
};
|
|
19785
|
-
var
|
|
19841
|
+
var instructionsRemoveDefinition = {
|
|
19786
19842
|
type: "function",
|
|
19787
19843
|
function: {
|
|
19788
|
-
name: "
|
|
19789
|
-
description: "
|
|
19844
|
+
name: "instructions_remove",
|
|
19845
|
+
description: "Remove a single persistent instruction by key.",
|
|
19790
19846
|
parameters: {
|
|
19791
19847
|
type: "object",
|
|
19792
19848
|
properties: {
|
|
19793
|
-
|
|
19849
|
+
key: {
|
|
19794
19850
|
type: "string",
|
|
19795
|
-
description: "
|
|
19851
|
+
description: "Key of the instruction to remove"
|
|
19796
19852
|
}
|
|
19797
19853
|
},
|
|
19798
|
-
required: ["
|
|
19854
|
+
required: ["key"]
|
|
19799
19855
|
}
|
|
19800
19856
|
}
|
|
19801
19857
|
};
|
|
19802
|
-
var
|
|
19858
|
+
var instructionsListDefinition = {
|
|
19803
19859
|
type: "function",
|
|
19804
19860
|
function: {
|
|
19805
|
-
name: "
|
|
19806
|
-
description: "
|
|
19861
|
+
name: "instructions_list",
|
|
19862
|
+
description: "List all persistent instructions with their keys and content.",
|
|
19807
19863
|
parameters: {
|
|
19808
19864
|
type: "object",
|
|
19809
19865
|
properties: {},
|
|
@@ -19815,7 +19871,7 @@ var instructionsClearDefinition = {
|
|
|
19815
19871
|
type: "function",
|
|
19816
19872
|
function: {
|
|
19817
19873
|
name: "instructions_clear",
|
|
19818
|
-
description: "Clear all
|
|
19874
|
+
description: "Clear all persistent instructions (DESTRUCTIVE). Requires confirmation.",
|
|
19819
19875
|
parameters: {
|
|
19820
19876
|
type: "object",
|
|
19821
19877
|
properties: {
|
|
@@ -19828,13 +19884,22 @@ var instructionsClearDefinition = {
|
|
|
19828
19884
|
}
|
|
19829
19885
|
}
|
|
19830
19886
|
};
|
|
19887
|
+
function validateKey(key) {
|
|
19888
|
+
if (typeof key !== "string") return "Key must be a string";
|
|
19889
|
+
const trimmed = key.trim();
|
|
19890
|
+
if (trimmed.length === 0) return "Key cannot be empty";
|
|
19891
|
+
if (trimmed.length > KEY_MAX_LENGTH) return `Key exceeds maximum length (${KEY_MAX_LENGTH} chars)`;
|
|
19892
|
+
if (!KEY_PATTERN.test(trimmed)) return "Key must contain only alphanumeric characters, dashes, and underscores";
|
|
19893
|
+
return null;
|
|
19894
|
+
}
|
|
19831
19895
|
var PersistentInstructionsPluginNextGen = class {
|
|
19832
19896
|
name = "persistent_instructions";
|
|
19833
|
-
|
|
19897
|
+
_entries = /* @__PURE__ */ new Map();
|
|
19834
19898
|
_initialized = false;
|
|
19835
19899
|
_destroyed = false;
|
|
19836
19900
|
storage;
|
|
19837
|
-
|
|
19901
|
+
maxTotalLength;
|
|
19902
|
+
maxEntries;
|
|
19838
19903
|
agentId;
|
|
19839
19904
|
estimator = simpleTokenEstimator;
|
|
19840
19905
|
_tokenCache = null;
|
|
@@ -19844,7 +19909,8 @@ var PersistentInstructionsPluginNextGen = class {
|
|
|
19844
19909
|
throw new Error("PersistentInstructionsPluginNextGen requires agentId");
|
|
19845
19910
|
}
|
|
19846
19911
|
this.agentId = config.agentId;
|
|
19847
|
-
this.
|
|
19912
|
+
this.maxTotalLength = config.maxTotalLength ?? DEFAULT_MAX_TOTAL_LENGTH;
|
|
19913
|
+
this.maxEntries = config.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
19848
19914
|
this.storage = config.storage ?? new FilePersistentInstructionsStorage({
|
|
19849
19915
|
agentId: config.agentId
|
|
19850
19916
|
});
|
|
@@ -19857,14 +19923,16 @@ var PersistentInstructionsPluginNextGen = class {
|
|
|
19857
19923
|
}
|
|
19858
19924
|
async getContent() {
|
|
19859
19925
|
await this.ensureInitialized();
|
|
19860
|
-
if (
|
|
19926
|
+
if (this._entries.size === 0) {
|
|
19927
|
+
this._tokenCache = 0;
|
|
19861
19928
|
return null;
|
|
19862
19929
|
}
|
|
19863
|
-
|
|
19864
|
-
|
|
19930
|
+
const rendered = this.renderContent();
|
|
19931
|
+
this._tokenCache = this.estimator.estimateTokens(rendered);
|
|
19932
|
+
return rendered;
|
|
19865
19933
|
}
|
|
19866
19934
|
getContents() {
|
|
19867
|
-
return this.
|
|
19935
|
+
return new Map(this._entries);
|
|
19868
19936
|
}
|
|
19869
19937
|
getTokenSize() {
|
|
19870
19938
|
return this._tokenCache ?? 0;
|
|
@@ -19884,32 +19952,54 @@ var PersistentInstructionsPluginNextGen = class {
|
|
|
19884
19952
|
getTools() {
|
|
19885
19953
|
return [
|
|
19886
19954
|
this.createInstructionsSetTool(),
|
|
19887
|
-
this.
|
|
19888
|
-
this.
|
|
19955
|
+
this.createInstructionsRemoveTool(),
|
|
19956
|
+
this.createInstructionsListTool(),
|
|
19889
19957
|
this.createInstructionsClearTool()
|
|
19890
19958
|
];
|
|
19891
19959
|
}
|
|
19892
19960
|
destroy() {
|
|
19893
19961
|
if (this._destroyed) return;
|
|
19894
|
-
this.
|
|
19962
|
+
this._entries.clear();
|
|
19895
19963
|
this._destroyed = true;
|
|
19896
19964
|
this._tokenCache = null;
|
|
19897
19965
|
}
|
|
19898
19966
|
getState() {
|
|
19899
19967
|
return {
|
|
19900
|
-
|
|
19901
|
-
agentId: this.agentId
|
|
19968
|
+
entries: Array.from(this._entries.values()),
|
|
19969
|
+
agentId: this.agentId,
|
|
19970
|
+
version: 2
|
|
19902
19971
|
};
|
|
19903
19972
|
}
|
|
19904
19973
|
restoreState(state) {
|
|
19974
|
+
if (!state || typeof state !== "object") return;
|
|
19905
19975
|
const s = state;
|
|
19906
|
-
if (
|
|
19907
|
-
|
|
19908
|
-
|
|
19909
|
-
|
|
19976
|
+
if ("version" in s && s.version === 2 && Array.isArray(s.entries)) {
|
|
19977
|
+
this._entries.clear();
|
|
19978
|
+
for (const entry of s.entries) {
|
|
19979
|
+
this._entries.set(entry.id, entry);
|
|
19980
|
+
}
|
|
19981
|
+
this._initialized = true;
|
|
19982
|
+
this._tokenCache = null;
|
|
19983
|
+
return;
|
|
19984
|
+
}
|
|
19985
|
+
if ("content" in s) {
|
|
19986
|
+
this._entries.clear();
|
|
19987
|
+
const content = s.content;
|
|
19988
|
+
if (content) {
|
|
19989
|
+
const now = Date.now();
|
|
19990
|
+
this._entries.set("legacy_instructions", {
|
|
19991
|
+
id: "legacy_instructions",
|
|
19992
|
+
content,
|
|
19993
|
+
createdAt: now,
|
|
19994
|
+
updatedAt: now
|
|
19995
|
+
});
|
|
19996
|
+
}
|
|
19997
|
+
this._initialized = true;
|
|
19998
|
+
this._tokenCache = null;
|
|
19999
|
+
}
|
|
19910
20000
|
}
|
|
19911
20001
|
// ============================================================================
|
|
19912
|
-
//
|
|
20002
|
+
// Public API
|
|
19913
20003
|
// ============================================================================
|
|
19914
20004
|
/**
|
|
19915
20005
|
* Initialize by loading from storage (called lazily)
|
|
@@ -19917,66 +20007,99 @@ var PersistentInstructionsPluginNextGen = class {
|
|
|
19917
20007
|
async initialize() {
|
|
19918
20008
|
if (this._initialized || this._destroyed) return;
|
|
19919
20009
|
try {
|
|
19920
|
-
|
|
20010
|
+
const entries = await this.storage.load();
|
|
20011
|
+
this._entries.clear();
|
|
20012
|
+
if (entries) {
|
|
20013
|
+
for (const entry of entries) {
|
|
20014
|
+
this._entries.set(entry.id, entry);
|
|
20015
|
+
}
|
|
20016
|
+
}
|
|
19921
20017
|
this._initialized = true;
|
|
19922
20018
|
} catch (error) {
|
|
19923
20019
|
console.warn(`Failed to load persistent instructions for agent '${this.agentId}':`, error);
|
|
19924
|
-
this.
|
|
20020
|
+
this._entries.clear();
|
|
19925
20021
|
this._initialized = true;
|
|
19926
20022
|
}
|
|
19927
20023
|
this._tokenCache = null;
|
|
19928
20024
|
}
|
|
19929
20025
|
/**
|
|
19930
|
-
*
|
|
20026
|
+
* Add or update an instruction entry by key
|
|
19931
20027
|
*/
|
|
19932
|
-
async set(content) {
|
|
20028
|
+
async set(key, content) {
|
|
19933
20029
|
this.assertNotDestroyed();
|
|
19934
|
-
|
|
20030
|
+
await this.ensureInitialized();
|
|
20031
|
+
const keyError = validateKey(key);
|
|
20032
|
+
if (keyError) return false;
|
|
20033
|
+
const trimmedContent = content.trim();
|
|
20034
|
+
if (trimmedContent.length === 0) return false;
|
|
20035
|
+
if (!this._entries.has(key) && this._entries.size >= this.maxEntries) {
|
|
19935
20036
|
return false;
|
|
19936
20037
|
}
|
|
19937
|
-
|
|
19938
|
-
|
|
19939
|
-
|
|
19940
|
-
|
|
19941
|
-
|
|
20038
|
+
const currentTotal = this.calculateTotalContentLength();
|
|
20039
|
+
const existingLength = this._entries.get(key)?.content.length ?? 0;
|
|
20040
|
+
const newTotal = currentTotal - existingLength + trimmedContent.length;
|
|
20041
|
+
if (newTotal > this.maxTotalLength) {
|
|
20042
|
+
return false;
|
|
19942
20043
|
}
|
|
20044
|
+
const now = Date.now();
|
|
20045
|
+
const existing = this._entries.get(key);
|
|
20046
|
+
this._entries.set(key, {
|
|
20047
|
+
id: key,
|
|
20048
|
+
content: trimmedContent,
|
|
20049
|
+
createdAt: existing?.createdAt ?? now,
|
|
20050
|
+
updatedAt: now
|
|
20051
|
+
});
|
|
20052
|
+
await this.persistToStorage();
|
|
19943
20053
|
this._tokenCache = null;
|
|
19944
20054
|
return true;
|
|
19945
20055
|
}
|
|
19946
20056
|
/**
|
|
19947
|
-
*
|
|
20057
|
+
* Remove an instruction entry by key
|
|
19948
20058
|
*/
|
|
19949
|
-
async
|
|
20059
|
+
async remove(key) {
|
|
19950
20060
|
this.assertNotDestroyed();
|
|
19951
20061
|
await this.ensureInitialized();
|
|
19952
|
-
|
|
19953
|
-
|
|
19954
|
-
|
|
19955
|
-
|
|
19956
|
-
|
|
19957
|
-
|
|
19958
|
-
if (newContent.length > this.maxLength) {
|
|
19959
|
-
return false;
|
|
20062
|
+
if (!this._entries.has(key)) return false;
|
|
20063
|
+
this._entries.delete(key);
|
|
20064
|
+
if (this._entries.size === 0) {
|
|
20065
|
+
await this.storage.delete();
|
|
20066
|
+
} else {
|
|
20067
|
+
await this.persistToStorage();
|
|
19960
20068
|
}
|
|
19961
|
-
this._content = newContent;
|
|
19962
|
-
await this.storage.save(this._content);
|
|
19963
20069
|
this._tokenCache = null;
|
|
19964
20070
|
return true;
|
|
19965
20071
|
}
|
|
19966
20072
|
/**
|
|
19967
|
-
* Get
|
|
20073
|
+
* Get one entry by key, or all entries if no key provided
|
|
19968
20074
|
*/
|
|
19969
|
-
async get() {
|
|
20075
|
+
async get(key) {
|
|
19970
20076
|
this.assertNotDestroyed();
|
|
19971
20077
|
await this.ensureInitialized();
|
|
19972
|
-
|
|
20078
|
+
if (key !== void 0) {
|
|
20079
|
+
return this._entries.get(key) ?? null;
|
|
20080
|
+
}
|
|
20081
|
+
if (this._entries.size === 0) return null;
|
|
20082
|
+
return this.getSortedEntries();
|
|
20083
|
+
}
|
|
20084
|
+
/**
|
|
20085
|
+
* List metadata for all entries
|
|
20086
|
+
*/
|
|
20087
|
+
async list() {
|
|
20088
|
+
this.assertNotDestroyed();
|
|
20089
|
+
await this.ensureInitialized();
|
|
20090
|
+
return this.getSortedEntries().map((entry) => ({
|
|
20091
|
+
key: entry.id,
|
|
20092
|
+
contentLength: entry.content.length,
|
|
20093
|
+
createdAt: entry.createdAt,
|
|
20094
|
+
updatedAt: entry.updatedAt
|
|
20095
|
+
}));
|
|
19973
20096
|
}
|
|
19974
20097
|
/**
|
|
19975
|
-
* Clear all
|
|
20098
|
+
* Clear all instruction entries
|
|
19976
20099
|
*/
|
|
19977
20100
|
async clear() {
|
|
19978
20101
|
this.assertNotDestroyed();
|
|
19979
|
-
this.
|
|
20102
|
+
this._entries.clear();
|
|
19980
20103
|
await this.storage.delete();
|
|
19981
20104
|
this._tokenCache = null;
|
|
19982
20105
|
}
|
|
@@ -19999,6 +20122,35 @@ ${trimmedSection}` : trimmedSection;
|
|
|
19999
20122
|
throw new Error("PersistentInstructionsPluginNextGen is destroyed");
|
|
20000
20123
|
}
|
|
20001
20124
|
}
|
|
20125
|
+
/**
|
|
20126
|
+
* Persist current entries to storage
|
|
20127
|
+
*/
|
|
20128
|
+
async persistToStorage() {
|
|
20129
|
+
await this.storage.save(Array.from(this._entries.values()));
|
|
20130
|
+
}
|
|
20131
|
+
/**
|
|
20132
|
+
* Calculate total content length across all entries
|
|
20133
|
+
*/
|
|
20134
|
+
calculateTotalContentLength() {
|
|
20135
|
+
let total = 0;
|
|
20136
|
+
for (const entry of this._entries.values()) {
|
|
20137
|
+
total += entry.content.length;
|
|
20138
|
+
}
|
|
20139
|
+
return total;
|
|
20140
|
+
}
|
|
20141
|
+
/**
|
|
20142
|
+
* Get entries sorted by createdAt (oldest first)
|
|
20143
|
+
*/
|
|
20144
|
+
getSortedEntries() {
|
|
20145
|
+
return Array.from(this._entries.values()).sort((a, b) => a.createdAt - b.createdAt);
|
|
20146
|
+
}
|
|
20147
|
+
/**
|
|
20148
|
+
* Render all entries as markdown for context injection
|
|
20149
|
+
*/
|
|
20150
|
+
renderContent() {
|
|
20151
|
+
return this.getSortedEntries().map((entry) => `### ${entry.id}
|
|
20152
|
+
${entry.content}`).join("\n\n");
|
|
20153
|
+
}
|
|
20002
20154
|
// ============================================================================
|
|
20003
20155
|
// Tool Factories
|
|
20004
20156
|
// ============================================================================
|
|
@@ -20006,60 +20158,84 @@ ${trimmedSection}` : trimmedSection;
|
|
|
20006
20158
|
return {
|
|
20007
20159
|
definition: instructionsSetDefinition,
|
|
20008
20160
|
execute: async (args) => {
|
|
20161
|
+
const key = args.key;
|
|
20009
20162
|
const content = args.content;
|
|
20163
|
+
const keyError = validateKey(key);
|
|
20164
|
+
if (keyError) {
|
|
20165
|
+
return { error: keyError };
|
|
20166
|
+
}
|
|
20010
20167
|
if (!content || content.trim().length === 0) {
|
|
20011
|
-
return { error: "Content cannot be empty. Use
|
|
20168
|
+
return { error: "Content cannot be empty. Use instructions_remove to delete an entry." };
|
|
20012
20169
|
}
|
|
20013
|
-
const
|
|
20170
|
+
const isUpdate = this._entries.has(key.trim());
|
|
20171
|
+
const success = await this.set(key.trim(), content);
|
|
20014
20172
|
if (!success) {
|
|
20015
|
-
|
|
20173
|
+
if (!isUpdate && this._entries.size >= this.maxEntries) {
|
|
20174
|
+
return { error: `Maximum number of entries reached (${this.maxEntries})` };
|
|
20175
|
+
}
|
|
20176
|
+
return { error: `Content would exceed maximum total length (${this.maxTotalLength} chars)` };
|
|
20016
20177
|
}
|
|
20017
20178
|
return {
|
|
20018
20179
|
success: true,
|
|
20019
|
-
message:
|
|
20020
|
-
|
|
20180
|
+
message: isUpdate ? `Instruction '${key.trim()}' updated` : `Instruction '${key.trim()}' added`,
|
|
20181
|
+
key: key.trim(),
|
|
20182
|
+
contentLength: content.trim().length
|
|
20021
20183
|
};
|
|
20022
20184
|
},
|
|
20023
20185
|
permission: { scope: "always", riskLevel: "low" },
|
|
20024
|
-
describeCall: () =>
|
|
20186
|
+
describeCall: (args) => `set instruction '${args.key}'`
|
|
20025
20187
|
};
|
|
20026
20188
|
}
|
|
20027
|
-
|
|
20189
|
+
createInstructionsRemoveTool() {
|
|
20028
20190
|
return {
|
|
20029
|
-
definition:
|
|
20191
|
+
definition: instructionsRemoveDefinition,
|
|
20030
20192
|
execute: async (args) => {
|
|
20031
|
-
const
|
|
20032
|
-
if (!
|
|
20033
|
-
return { error: "
|
|
20193
|
+
const key = args.key;
|
|
20194
|
+
if (!key || typeof key !== "string" || key.trim().length === 0) {
|
|
20195
|
+
return { error: "Key is required" };
|
|
20034
20196
|
}
|
|
20035
|
-
const success = await this.
|
|
20197
|
+
const success = await this.remove(key.trim());
|
|
20036
20198
|
if (!success) {
|
|
20037
|
-
return { error: `
|
|
20199
|
+
return { error: `Instruction '${key.trim()}' not found` };
|
|
20038
20200
|
}
|
|
20039
20201
|
return {
|
|
20040
20202
|
success: true,
|
|
20041
|
-
message:
|
|
20042
|
-
|
|
20203
|
+
message: `Instruction '${key.trim()}' removed`,
|
|
20204
|
+
key: key.trim()
|
|
20043
20205
|
};
|
|
20044
20206
|
},
|
|
20045
20207
|
permission: { scope: "always", riskLevel: "low" },
|
|
20046
|
-
describeCall: () =>
|
|
20208
|
+
describeCall: (args) => `remove instruction '${args.key}'`
|
|
20047
20209
|
};
|
|
20048
20210
|
}
|
|
20049
|
-
|
|
20211
|
+
createInstructionsListTool() {
|
|
20050
20212
|
return {
|
|
20051
|
-
definition:
|
|
20213
|
+
definition: instructionsListDefinition,
|
|
20052
20214
|
execute: async () => {
|
|
20053
|
-
const
|
|
20215
|
+
const entries = await this.list();
|
|
20216
|
+
const all = await this.get();
|
|
20217
|
+
if (entries.length === 0) {
|
|
20218
|
+
return {
|
|
20219
|
+
count: 0,
|
|
20220
|
+
entries: [],
|
|
20221
|
+
message: "(no custom instructions set)"
|
|
20222
|
+
};
|
|
20223
|
+
}
|
|
20224
|
+
const allEntries = all;
|
|
20054
20225
|
return {
|
|
20055
|
-
|
|
20056
|
-
|
|
20057
|
-
|
|
20226
|
+
count: entries.length,
|
|
20227
|
+
entries: allEntries.map((e) => ({
|
|
20228
|
+
key: e.id,
|
|
20229
|
+
content: e.content,
|
|
20230
|
+
contentLength: e.content.length,
|
|
20231
|
+
createdAt: e.createdAt,
|
|
20232
|
+
updatedAt: e.updatedAt
|
|
20233
|
+
})),
|
|
20058
20234
|
agentId: this.agentId
|
|
20059
20235
|
};
|
|
20060
20236
|
},
|
|
20061
20237
|
permission: { scope: "always", riskLevel: "low" },
|
|
20062
|
-
describeCall: () => "
|
|
20238
|
+
describeCall: () => "list instructions"
|
|
20063
20239
|
};
|
|
20064
20240
|
}
|
|
20065
20241
|
createInstructionsClearTool() {
|
|
@@ -20072,7 +20248,7 @@ ${trimmedSection}` : trimmedSection;
|
|
|
20072
20248
|
await this.clear();
|
|
20073
20249
|
return {
|
|
20074
20250
|
success: true,
|
|
20075
|
-
message: "
|
|
20251
|
+
message: "All custom instructions cleared"
|
|
20076
20252
|
};
|
|
20077
20253
|
},
|
|
20078
20254
|
permission: { scope: "once", riskLevel: "medium" },
|