blun-king-cli 9.1.117 → 9.1.119
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/LIESMICH.txt +4 -0
- package/README.md +4 -0
- package/bin/skill-listing-performance-policy.cjs +58 -0
- package/blun.mjs +19 -8
- package/package.json +1 -1
package/LIESMICH.txt
CHANGED
|
@@ -113,6 +113,10 @@ Version 9.1.106 erlaubt Agentenprofilen, Werkzeuge namentlich auszuschließen. K
|
|
|
113
113
|
|
|
114
114
|
Version 9.1.109 hält nur noch die neun Werkzeuge dauerhaft in der Modellanfrage, auf die mehr als 98 Prozent von Fredriks 3.183 gemessenen Werkzeugaufrufen entfielen. Alle übrigen Werkzeuge bleiben über `ToolSearch` auffindbar und nach dem ersten Laden für den Rest der Sitzung verfügbar. Dadurch sinkt die Schemalast bei jedem normalen Modellschritt, ohne ein Werkzeug zu entfernen oder den Schnellweg für Telegram-Antworten und ausstehende Medienergebnisse zu verändern.
|
|
115
115
|
|
|
116
|
+
Ab BLUN King 9.1.118 bleibt der Sitzungszeitstempel im Systemprompt während einer laufenden Sitzung unverändert. Das erneute Einlesen von Verzeichnisübersicht, AGENTS.md-Dateien, Zusatzverzeichnissen und Skillinformationen kann den Prompt weiterhin ändern, wenn sich die jeweiligen Quellen tatsächlich verändert haben. Bleiben diese Quellen gleich, entwertet die Aktualisierung nach einer Verdichtung den Präfix-Cache des Anbieters nicht mehr allein durch einen neuen Zeitstempel. In Fredriks gemessener Sitzung unterschieden sich die beiden letzten Systemprompts mit jeweils 68.631 Zeichen nur in der Zeitangabe, und zwar erst nach einem gemeinsamen Präfix von 27.111 Zeichen. Der geänderte Zeitstempel verhinderte damit die Wiederverwendung der übrigen 41.512 unveränderten Zeichen aus dem Präfix-Cache.
|
|
117
|
+
|
|
118
|
+
Ab BLUN King 9.1.119 enthält der bei jedem Modellschritt erneut gesendete Prompt nur noch eine kleine Auswahl häufig benötigter Skills. Alle übrigen registrierten Skills bleiben verfügbar und lassen sich über das Skill-Werkzeug anhand ihres Namens oder Zwecks suchen; der ausgewählte Skill wird anschließend bei Bedarf geladen. Dadurch sinkt die wiederholt übertragene Promptlast, ohne Skills zu löschen oder die vollständige Ansicht unter `/skills` einzuschränken.
|
|
119
|
+
|
|
116
120
|
Verliert ein delegierter Einzelagent oder ein Mitglied eines Agentenschwarms die Provider-Verbindung, erhält es eine leere Provider-Antwort, bricht sein Stream wegen Leerlaufs ab oder meldet der Server HTTP 408/500/502/503/504, setzt BLUN King denselben Agenten anhand seines dauerhaften Verlaufs fort. Bei Einzelagenten sowie bei Schwarm-Unterbrechungen außerhalb von HTTP 429 wartet die erste Fortsetzung zwei Sekunden und die zweite fünf Sekunden; danach bleibt der ursprüngliche Fehler sichtbar. HTTP 429 behält im Schwarm seine getrennte, längere Überlastungsregel. Authentifizierungs-, Zahlungs- oder Kontingent-, Richtlinien-, Kontext-, Werkzeug- und Codefehler sowie manuelle Abbrüche lösen keine automatische Fortsetzung aus. Jeder Fortsetzungsversuch verwendet die bestehende Agenten-ID, damit bereits abgeschlossene Arbeit nicht wiederholt wird.
|
|
117
121
|
|
|
118
122
|
Rein lesende Sitzungsdiagnose
|
package/README.md
CHANGED
|
@@ -119,6 +119,10 @@ Version 9.1.106 erlaubt Agentenprofilen, Werkzeuge namentlich auszuschließen. K
|
|
|
119
119
|
|
|
120
120
|
Version 9.1.109 hält nur noch die neun Werkzeuge dauerhaft in der Modellanfrage, auf die mehr als 98 Prozent von Fredriks 3.183 gemessenen Werkzeugaufrufen entfielen. Alle übrigen Werkzeuge bleiben über `ToolSearch` auffindbar und nach dem ersten Laden für den Rest der Sitzung verfügbar. Dadurch sinkt die Schemalast bei jedem normalen Modellschritt, ohne ein Werkzeug zu entfernen oder den Schnellweg für Telegram-Antworten und ausstehende Medienergebnisse zu verändern.
|
|
121
121
|
|
|
122
|
+
Ab BLUN King 9.1.118 bleibt der Sitzungszeitstempel im Systemprompt während einer laufenden Sitzung unverändert. Das erneute Einlesen von Verzeichnisübersicht, AGENTS.md-Dateien, Zusatzverzeichnissen und Skillinformationen kann den Prompt weiterhin ändern, wenn sich die jeweiligen Quellen tatsächlich verändert haben. Bleiben diese Quellen gleich, entwertet die Aktualisierung nach einer Verdichtung den Präfix-Cache des Anbieters nicht mehr allein durch einen neuen Zeitstempel. In Fredriks gemessener Sitzung unterschieden sich die beiden letzten Systemprompts mit jeweils 68.631 Zeichen nur in der Zeitangabe, und zwar erst nach einem gemeinsamen Präfix von 27.111 Zeichen. Der geänderte Zeitstempel verhinderte damit die Wiederverwendung der übrigen 41.512 unveränderten Zeichen aus dem Präfix-Cache.
|
|
123
|
+
|
|
124
|
+
Ab BLUN King 9.1.119 enthält der bei jedem Modellschritt erneut gesendete Prompt nur noch eine kleine Auswahl häufig benötigter Skills. Alle übrigen registrierten Skills bleiben verfügbar und lassen sich über das Skill-Werkzeug anhand ihres Namens oder Zwecks suchen; der ausgewählte Skill wird anschließend bei Bedarf geladen. Dadurch sinkt die wiederholt übertragene Promptlast, ohne Skills zu löschen oder die vollständige Ansicht unter `/skills` einzuschränken.
|
|
125
|
+
|
|
122
126
|
Ab BLUN King 9.1.99 werden auch direkt aufeinanderfolgende reine Textergebnisse als Stapel betrachtet. Enthalten sie zusammen mehr als 12.000 Zeichen, obwohl kein einzelnes Ergebnis diese Grenze überschreitet, speichert King so viele der größten geeigneten Ergebnisse wie nötig in privaten Dateien. In der Modellprojektion verbleiben lesbare Verweise. Der unveränderte Sitzungsrohverlauf bleibt vollständig erhalten. Gemischte Medienergebnisse, einzelne Ergebnisse unter 3.000 Zeichen und Stapel bis einschließlich 12.000 Zeichen bleiben unverändert. Beispiel: Bei zwei Suchergebnissen mit 7.000 und 6.000 Zeichen wird das größere Ergebnis privat gespeichert; Anfang, Ende, ausgelassene Zeichenzahl und `output_path` bleiben für den Agenten sichtbar.
|
|
123
127
|
|
|
124
128
|
Ab BLUN King 9.1.100 beendet eine begrenzte Grep-Inhaltssuche ripgrep, sobald der Versatz, die angeforderten Zeilen und eine zusätzliche Vorschauzeile vollständig vorliegen. Die Vorschauzeile belegt, ob eine weitere Seite existiert, ohne vorher bis zu 10 MB einzulesen. Unbegrenzte Suchen, Trefferzählungen und nach Änderungszeit sortierte Dateilisten laufen weiterhin vollständig durch.
|
|
@@ -9,6 +9,8 @@ const FIRST_USE_SKILLS = new Set([
|
|
|
9
9
|
'blun-app-design-system',
|
|
10
10
|
]);
|
|
11
11
|
|
|
12
|
+
const DEFAULT_SEARCH_LIMIT = 12;
|
|
13
|
+
|
|
12
14
|
function compactDescription(value) {
|
|
13
15
|
const normalized = String(value || '').replace(/\s+/g, ' ').trim();
|
|
14
16
|
if (normalized.length <= SKILL_DESCRIPTION_MAX_CHARS) return normalized;
|
|
@@ -26,8 +28,64 @@ function renderCompactSkillListing(skills) {
|
|
|
26
28
|
return (Array.isArray(skills) ? skills : []).map(renderCompactSkillEntry).join('\n');
|
|
27
29
|
}
|
|
28
30
|
|
|
31
|
+
function isResidentSkill(skill) {
|
|
32
|
+
return FIRST_USE_SKILLS.has(String(skill?.name || '').trim().toLowerCase());
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function renderResidentSkillListing(skills) {
|
|
36
|
+
return (Array.isArray(skills) ? skills : [])
|
|
37
|
+
.filter(isResidentSkill)
|
|
38
|
+
.map(renderCompactSkillEntry)
|
|
39
|
+
.join('\n');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function normalizeSearchText(value) {
|
|
43
|
+
return String(value || '')
|
|
44
|
+
.normalize('NFKD')
|
|
45
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
46
|
+
.toLowerCase()
|
|
47
|
+
.replace(/[^a-z0-9]+/g, ' ')
|
|
48
|
+
.trim();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function searchSkills(skills, query, limit = DEFAULT_SEARCH_LIMIT) {
|
|
52
|
+
const normalizedQuery = normalizeSearchText(query);
|
|
53
|
+
const queryTokens = normalizedQuery.split(/\s+/).filter(Boolean);
|
|
54
|
+
if (queryTokens.length === 0 || !Number.isFinite(limit) || limit <= 0) return [];
|
|
55
|
+
|
|
56
|
+
return (Array.isArray(skills) ? skills : [])
|
|
57
|
+
.filter((skill) => skill?.metadata?.disableModelInvocation !== true)
|
|
58
|
+
.map((skill) => {
|
|
59
|
+
const name = normalizeSearchText(skill?.name);
|
|
60
|
+
const description = normalizeSearchText(skill?.description);
|
|
61
|
+
const searchable = `${name} ${description}`.trim();
|
|
62
|
+
if (!queryTokens.every((token) => searchable.includes(token))) return null;
|
|
63
|
+
const score = name === normalizedQuery ? 0 : name.startsWith(normalizedQuery) ? 1 : name.includes(normalizedQuery) ? 2 : 3;
|
|
64
|
+
return { skill, name, score };
|
|
65
|
+
})
|
|
66
|
+
.filter(Boolean)
|
|
67
|
+
.sort((left, right) => left.score - right.score || left.name.localeCompare(right.name))
|
|
68
|
+
.slice(0, Math.floor(limit))
|
|
69
|
+
.map((entry) => entry.skill);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function renderSkillSearchResult(query, skills) {
|
|
73
|
+
const lines = [`No exact skill named "${String(query || '').trim()}" was found. Matching skills:`];
|
|
74
|
+
for (const skill of skills) {
|
|
75
|
+
const description = compactDescription(skill?.description);
|
|
76
|
+
lines.push(description ? `- ${skill.name}: ${description}` : `- ${skill.name}`);
|
|
77
|
+
}
|
|
78
|
+
lines.push('Call the Skill tool again with one exact skill name from this list.');
|
|
79
|
+
return lines.join('\n');
|
|
80
|
+
}
|
|
81
|
+
|
|
29
82
|
module.exports = {
|
|
83
|
+
DEFAULT_SEARCH_LIMIT,
|
|
30
84
|
SKILL_DESCRIPTION_MAX_CHARS,
|
|
85
|
+
isResidentSkill,
|
|
31
86
|
renderCompactSkillEntry,
|
|
32
87
|
renderCompactSkillListing,
|
|
88
|
+
renderResidentSkillListing,
|
|
89
|
+
renderSkillSearchResult,
|
|
90
|
+
searchSkills,
|
|
33
91
|
};
|
package/blun.mjs
CHANGED
|
@@ -235656,13 +235656,13 @@ function truncate$2(value, max) {
|
|
|
235656
235656
|
}
|
|
235657
235657
|
return `${result}…`;
|
|
235658
235658
|
}
|
|
235659
|
-
var LISTING_DESC_MAX, renderCompactSkillEntry, SessionSkillRegistry, SOURCE_GROUPS, graphemeSegmenter$2;
|
|
235659
|
+
var LISTING_DESC_MAX, isResidentSkill, renderCompactSkillEntry, renderSkillSearchResult, searchSkills, SessionSkillRegistry, SOURCE_GROUPS, graphemeSegmenter$2;
|
|
235660
235660
|
var init_registry = __esmMin((() => {
|
|
235661
235661
|
init_parser$1();
|
|
235662
235662
|
init_scanner();
|
|
235663
235663
|
init_types$15();
|
|
235664
235664
|
init_xml_escape();
|
|
235665
|
-
({ renderCompactSkillEntry } = createRequire(import.meta.url)("./bin/skill-listing-performance-policy.cjs"));
|
|
235665
|
+
({ isResidentSkill, renderCompactSkillEntry, renderSkillSearchResult, searchSkills } = createRequire(import.meta.url)("./bin/skill-listing-performance-policy.cjs"));
|
|
235666
235666
|
LISTING_DESC_MAX = 250;
|
|
235667
235667
|
SessionSkillRegistry = class {
|
|
235668
235668
|
byName = /* @__PURE__ */ new Map();
|
|
@@ -235741,10 +235741,13 @@ var init_registry = __esmMin((() => {
|
|
|
235741
235741
|
return rendered.length === 0 ? "No skills" : rendered;
|
|
235742
235742
|
}
|
|
235743
235743
|
getModelSkillListing() {
|
|
235744
|
-
const lines = [
|
|
235745
|
-
|
|
235744
|
+
const lines = [
|
|
235745
|
+
"DISREGARD any earlier skill listings. Frequently used skills are listed below.",
|
|
235746
|
+
"Other registered skills remain available: call the Skill tool with search words to discover their exact names."
|
|
235747
|
+
];
|
|
235748
|
+
const listing = renderGroupedSkills(this.listInvocableSkills().filter((skill) => skill.metadata.isSubSkill !== true && isResidentSkill(skill)), formatModelSkill);
|
|
235746
235749
|
if (listing.length > 0) lines.push(listing);
|
|
235747
|
-
return lines.
|
|
235750
|
+
return lines.join("\n");
|
|
235748
235751
|
}
|
|
235749
235752
|
};
|
|
235750
235753
|
SOURCE_GROUPS = [
|
|
@@ -252921,7 +252924,7 @@ var init_skill_tool = __esmMin((() => {
|
|
|
252921
252924
|
}
|
|
252922
252925
|
};
|
|
252923
252926
|
SkillToolInputSchema = object({
|
|
252924
|
-
skill: string().describe("
|
|
252927
|
+
skill: string().describe("An exact skill name to invoke, or search words to discover matching registered skills when the exact name is unknown."),
|
|
252925
252928
|
args: string().optional().describe("Optional argument string for the skill, written like a command line (e.g. `-m \"fix bug\"`, `123`, a file path). It is split on whitespace (quotes group a token) and expanded into the skill's placeholders ($NAME, $1, $ARGUMENTS); if the skill body has no placeholders, the whole string is still appended as a trailing `ARGUMENTS:` line. Omit it only when there is nothing to pass.")
|
|
252926
252929
|
});
|
|
252927
252930
|
SkillTool = class SkillTool {
|
|
@@ -252959,7 +252962,11 @@ var init_skill_tool = __esmMin((() => {
|
|
|
252959
252962
|
const skills = this.agent.skills;
|
|
252960
252963
|
if (skills === null) return errorResult(`Skill "${args.skill}" not found in the current skill listing.`);
|
|
252961
252964
|
const skill = skills.registry.getSkill(args.skill);
|
|
252962
|
-
if (skill === void 0)
|
|
252965
|
+
if (skill === void 0) {
|
|
252966
|
+
const matches = searchSkills(skills.registry.listInvocableSkills().filter((candidate) => candidate.metadata.isSubSkill !== true), args.skill);
|
|
252967
|
+
if (matches.length === 0) return errorResult(`No registered skill matched "${args.skill}". Try broader search words.`);
|
|
252968
|
+
return { output: renderSkillSearchResult(args.skill, matches) };
|
|
252969
|
+
}
|
|
252963
252970
|
if (skill.metadata.disableModelInvocation === true) return errorResult(`Skill "${args.skill}" can only be triggered by the user (model invocation is disabled).`);
|
|
252964
252971
|
const skillArgs = args.args ?? "";
|
|
252965
252972
|
if (!isInlineSkillType(skill.metadata.type)) return errorResult(`Skill "${skill.name}" is not an inline skill and cannot be invoked by the model in v1.`);
|
|
@@ -264349,6 +264356,7 @@ var init_agent = __esmMin((() => {
|
|
|
264349
264356
|
personalMemoryHostCapabilityEnabled = false;
|
|
264350
264357
|
runtimeSystemPromptAppend = "";
|
|
264351
264358
|
systemPromptContextProvider;
|
|
264359
|
+
systemPromptTimestamp = new Date();
|
|
264352
264360
|
constructor(options) {
|
|
264353
264361
|
this.type = options.type ?? "main";
|
|
264354
264362
|
this._kaos = options.kaos;
|
|
@@ -264545,7 +264553,8 @@ var init_agent = __esmMin((() => {
|
|
|
264545
264553
|
* Re-render the system prompt with freshly gathered runtime context (cwd
|
|
264546
264554
|
* listing, AGENTS.md, additional-dirs info, skill list). Called after
|
|
264547
264555
|
* compaction so the post-compaction turns do not keep a snapshot captured
|
|
264548
|
-
* at session bootstrap.
|
|
264556
|
+
* at session bootstrap. The session timestamp stays stable so an otherwise
|
|
264557
|
+
* unchanged refresh can keep the provider prompt cache warm.
|
|
264549
264558
|
*/
|
|
264550
264559
|
async refreshSystemPrompt() {
|
|
264551
264560
|
if (this.activeProfile === void 0) return;
|
|
@@ -264554,6 +264563,8 @@ var init_agent = __esmMin((() => {
|
|
|
264554
264563
|
}
|
|
264555
264564
|
updateSystemPromptFromProfile(profile, context) {
|
|
264556
264565
|
const systemPrompt = profile.systemPrompt({
|
|
264566
|
+
...context,
|
|
264567
|
+
now: this.systemPromptTimestamp,
|
|
264557
264568
|
osEnv: this.kaos.osEnv,
|
|
264558
264569
|
cwd: this.config.cwd,
|
|
264559
264570
|
skills: this.skills?.registry,
|