@securecoms/agent-runtime 0.10.0 → 0.11.0
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/bin.js +50 -11
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1782,10 +1782,12 @@ function buildLlmShim(cfg, explicit, deps) {
|
|
|
1782
1782
|
// src/memory.ts
|
|
1783
1783
|
var MAX_HISTORY = 50;
|
|
1784
1784
|
var MAX_FACTS = 200;
|
|
1785
|
+
var CONTROL_CHARS = /[\p{Cc}\u2028\u2029]/gu;
|
|
1785
1786
|
var AgentMemory = class {
|
|
1786
1787
|
history = [];
|
|
1787
1788
|
facts = [];
|
|
1788
1789
|
notes = "";
|
|
1790
|
+
recallItems = [];
|
|
1789
1791
|
constructor(snapshot) {
|
|
1790
1792
|
if (snapshot) this.replace(snapshot);
|
|
1791
1793
|
}
|
|
@@ -1797,6 +1799,7 @@ var AgentMemory = class {
|
|
|
1797
1799
|
}));
|
|
1798
1800
|
this.facts = snapshot.facts.slice(-MAX_FACTS);
|
|
1799
1801
|
this.notes = typeof snapshot.notes === "string" ? snapshot.notes : "";
|
|
1802
|
+
this.recallItems = Array.isArray(snapshot.recall) ? snapshot.recall : [];
|
|
1800
1803
|
}
|
|
1801
1804
|
/** The bridge-rendered notes document for the current turn, or "". Data, never instructions. */
|
|
1802
1805
|
getNotes() {
|
|
@@ -1818,12 +1821,19 @@ var AgentMemory = class {
|
|
|
1818
1821
|
this.history = [];
|
|
1819
1822
|
this.facts = [];
|
|
1820
1823
|
this.notes = "";
|
|
1824
|
+
this.recallItems = [];
|
|
1825
|
+
}
|
|
1826
|
+
/** How many semantic recall items this turn's view renders. */
|
|
1827
|
+
recallCount() {
|
|
1828
|
+
return this.recallItems.length;
|
|
1821
1829
|
}
|
|
1822
1830
|
/** Case-insensitive keyword-overlap recall over protected channel facts. */
|
|
1823
1831
|
async recall(query) {
|
|
1824
1832
|
const queryWords = query.toLowerCase().split(/\W+/).filter((word) => word.length >= 3);
|
|
1825
|
-
|
|
1826
|
-
|
|
1833
|
+
const semantic = this.recallItems.map(
|
|
1834
|
+
(r) => `- [r${r.id}] (${new Date(r.sent_at).toISOString().slice(0, 10)}) ${r.text.replace(CONTROL_CHARS, " ")}`
|
|
1835
|
+
);
|
|
1836
|
+
const scored = queryWords.length === 0 ? [] : this.facts.map((content) => {
|
|
1827
1837
|
const contentLower = content.toLowerCase();
|
|
1828
1838
|
const score = queryWords.reduce(
|
|
1829
1839
|
(acc, word) => contentLower.includes(word) ? acc + 1 : acc,
|
|
@@ -1831,9 +1841,10 @@ var AgentMemory = class {
|
|
|
1831
1841
|
);
|
|
1832
1842
|
return { content, score };
|
|
1833
1843
|
}).filter((entry) => entry.score > 0).sort((a, b) => b.score - a.score).slice(0, 5);
|
|
1834
|
-
|
|
1844
|
+
const lines = [...semantic, ...scored.map((entry) => `- ${entry.content.replace(CONTROL_CHARS, " ")}`)];
|
|
1845
|
+
if (lines.length === 0) return null;
|
|
1835
1846
|
return `Relevant context from memory:
|
|
1836
|
-
${
|
|
1847
|
+
${lines.join("\n")}`;
|
|
1837
1848
|
}
|
|
1838
1849
|
};
|
|
1839
1850
|
|
|
@@ -3675,9 +3686,25 @@ function createStatusReporter(log, fetchImpl = fetch) {
|
|
|
3675
3686
|
var NO_TURN_MEMORY = Object.freeze({
|
|
3676
3687
|
recent: Object.freeze([]),
|
|
3677
3688
|
facts: Object.freeze([]),
|
|
3678
|
-
notes: ""
|
|
3689
|
+
notes: "",
|
|
3690
|
+
recall: Object.freeze([])
|
|
3679
3691
|
});
|
|
3680
3692
|
var NOTES_MAX_CHARS = 8e3;
|
|
3693
|
+
function parseRecall(value) {
|
|
3694
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return [];
|
|
3695
|
+
const r = value.recall;
|
|
3696
|
+
if (!Array.isArray(r)) return [];
|
|
3697
|
+
const out = [];
|
|
3698
|
+
for (const x of r.slice(0, 5)) {
|
|
3699
|
+
if (!x || typeof x !== "object" || Array.isArray(x)) return [];
|
|
3700
|
+
const { id, text, sent_at } = x;
|
|
3701
|
+
if (typeof id !== "number" || !Number.isSafeInteger(id) || id < 1) return [];
|
|
3702
|
+
if (typeof text !== "string" || text.length > 600) return [];
|
|
3703
|
+
if (typeof sent_at !== "number" || !Number.isSafeInteger(sent_at) || sent_at < 0 || sent_at > 864e13) return [];
|
|
3704
|
+
out.push(Object.freeze({ id, text, sent_at }));
|
|
3705
|
+
}
|
|
3706
|
+
return Object.freeze(out);
|
|
3707
|
+
}
|
|
3681
3708
|
function parseNotes(value) {
|
|
3682
3709
|
if (!value || typeof value !== "object" || Array.isArray(value)) return "";
|
|
3683
3710
|
const n = value.notes;
|
|
@@ -3701,12 +3728,13 @@ function parseRecentAndFacts(value) {
|
|
|
3701
3728
|
if (typeof fact !== "string") return NO_TURN_MEMORY;
|
|
3702
3729
|
facts.push(fact);
|
|
3703
3730
|
}
|
|
3704
|
-
return Object.freeze({ recent: Object.freeze(recent), facts: Object.freeze(facts), notes: "" });
|
|
3731
|
+
return Object.freeze({ recent: Object.freeze(recent), facts: Object.freeze(facts), notes: "", recall: Object.freeze([]) });
|
|
3705
3732
|
}
|
|
3706
3733
|
function parseTurnMemory(value) {
|
|
3707
3734
|
const base = parseRecentAndFacts(value);
|
|
3708
3735
|
const notes = parseNotes(value);
|
|
3709
|
-
|
|
3736
|
+
const recall = parseRecall(value);
|
|
3737
|
+
return notes === "" && recall.length === 0 ? base : Object.freeze({ ...base, notes, recall });
|
|
3710
3738
|
}
|
|
3711
3739
|
var AUDIENCES = /* @__PURE__ */ new Set([
|
|
3712
3740
|
"owner_dm",
|
|
@@ -3724,9 +3752,10 @@ var NO_TURN_AUTHORIZATION = Object.freeze({
|
|
|
3724
3752
|
});
|
|
3725
3753
|
var PER_TOOL_GRANTS_FEATURE = "per_tool_grants";
|
|
3726
3754
|
var MEMORY_NOTES_FEATURE = "memory_notes";
|
|
3755
|
+
var MEMORY_RECALL_FEATURE = "memory_recall";
|
|
3727
3756
|
var MEMORY_NOTE_TIMEOUT_MS = 1e4;
|
|
3728
3757
|
function runtimeHelloFrame() {
|
|
3729
|
-
return { type: "hello", features: ["nack", PER_TOOL_GRANTS_FEATURE, MEMORY_NOTES_FEATURE] };
|
|
3758
|
+
return { type: "hello", features: ["nack", PER_TOOL_GRANTS_FEATURE, MEMORY_NOTES_FEATURE, MEMORY_RECALL_FEATURE] };
|
|
3730
3759
|
}
|
|
3731
3760
|
function parseTurnAuthorization(value) {
|
|
3732
3761
|
if (!value || typeof value !== "object" || Array.isArray(value)) return NO_TURN_AUTHORIZATION;
|
|
@@ -4336,13 +4365,13 @@ var MEMORY_NOTE_TOOL = {
|
|
|
4336
4365
|
type: "function",
|
|
4337
4366
|
function: {
|
|
4338
4367
|
name: MEMORY_NOTE,
|
|
4339
|
-
description: "Save, change or delete one short note in this chat's saved notes. Save only what the owner asked you to keep. `text` must be copied word for word from the owner's CURRENT message (a contiguous part of it is fine). You cannot save something said earlier, said in a call, found by a tool, or your own summary. If the owner asks you to remember something from earlier, ask them to type it in one short message. Never store credentials, keys or passwords. To change or delete a note, pass its id: [n7] is id 7.",
|
|
4368
|
+
description: "Save, change or delete one short note in this chat's saved notes. Save only what the owner asked you to keep. First check the saved notes already shown to you: if the fact is already saved, do not call this tool; just tell the owner it is already remembered. `text` must be copied word for word from the owner's CURRENT message (a contiguous part of it is fine). You cannot save something said earlier, said in a call, found by a tool, or your own summary. If the owner asks you to remember something from earlier, ask them to type it in one short message. Never store credentials, keys or passwords. To change or delete a note, pass its id: [n7] is id 7. To forget a remembered message shown to you as [r12], pass op forget with id \"r12\". You can make only one change (replace or forget) per owner message: One change per message. Ask the owner to confirm the next one.",
|
|
4340
4369
|
parameters: {
|
|
4341
4370
|
type: "object",
|
|
4342
4371
|
properties: {
|
|
4343
4372
|
op: { type: "string", enum: ["add", "replace", "forget"] },
|
|
4344
4373
|
text: { type: "string" },
|
|
4345
|
-
id: { type: "integer", minimum: 1 }
|
|
4374
|
+
id: { anyOf: [{ type: "integer", minimum: 1 }, { type: "string", pattern: "^r[1-9][0-9]*$" }] }
|
|
4346
4375
|
},
|
|
4347
4376
|
required: ["op"],
|
|
4348
4377
|
additionalProperties: false
|
|
@@ -4360,6 +4389,10 @@ var REFUSAL = {
|
|
|
4360
4389
|
cap: "Not saved. The notes are full or the note is too long. Replace or forget older notes first.",
|
|
4361
4390
|
audience: "Not saved. Notes can be saved only from the owner's own typed message in their private chat.",
|
|
4362
4391
|
cleared: "Not saved. The owner cleared the notes after this message arrived.",
|
|
4392
|
+
// [COPY] spec 7b §9.1.
|
|
4393
|
+
budget: "One change per message. Ask the owner to confirm the next one.",
|
|
4394
|
+
// [COPY, NEW] Gate: Eric sign-off before npm publish (release PR). The bridge emits it when the chat's memory was purged after the write was queued.
|
|
4395
|
+
purged: "Not saved. This chat's memory was removed after this message arrived.",
|
|
4363
4396
|
mode: "Not saved. Notes are turned off for this agent right now."
|
|
4364
4397
|
};
|
|
4365
4398
|
function parseArgs(raw) {
|
|
@@ -4375,7 +4408,11 @@ function parseArgs(raw) {
|
|
|
4375
4408
|
const text = typeof a.text === "string" && a.text.length > 0 ? a.text : void 0;
|
|
4376
4409
|
if (a.op === "add" && text !== void 0 && a.id === void 0) return { op: "add", text };
|
|
4377
4410
|
if (a.op === "replace" && text !== void 0 && id !== void 0) return { op: "replace", text, id };
|
|
4378
|
-
|
|
4411
|
+
const recallId = typeof a.id === "string" && /^r[1-9][0-9]{0,15}$/.test(a.id) && Number.isSafeInteger(Number(a.id.slice(1))) ? a.id : void 0;
|
|
4412
|
+
if (a.op === "forget" && a.text === void 0) {
|
|
4413
|
+
if (id !== void 0) return { op: "forget", id };
|
|
4414
|
+
if (recallId !== void 0) return { op: "forget", id: recallId };
|
|
4415
|
+
}
|
|
4379
4416
|
return null;
|
|
4380
4417
|
}
|
|
4381
4418
|
async function runMemoryNoteCalls(calls, m, ctx = {}) {
|
|
@@ -4967,6 +5004,8 @@ ${notesLines.slice(0, k).join("\n")}` };
|
|
|
4967
5004
|
history_messages: history.length - historyStart,
|
|
4968
5005
|
history_dropped: historyStart,
|
|
4969
5006
|
recalled: keepRecalled,
|
|
5007
|
+
recall_items: memory.recallCount(),
|
|
5008
|
+
recall_kept: keepRecalled ? memory.recallCount() : 0,
|
|
4970
5009
|
tools_offered: tools.length,
|
|
4971
5010
|
// Counts only: the tools this runtime loaded, and the grants the bridge
|
|
4972
5011
|
// sent. tools_offered=0 with grants=0 points at the bridge decision;
|