blun-king-cli 9.1.527 → 9.1.550
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 +13 -834
- package/README.md +41 -799
- package/bin/agent-resume-snapshot.cjs +31 -0
- package/bin/assistant-message-offload-policy.cjs +23 -2
- package/bin/codebase-search-runtime.cjs +23 -0
- package/bin/context-performance-policy.cjs +2 -5
- package/bin/context-pressure-policy.cjs +20 -0
- package/bin/cron-run-output.cjs +45 -0
- package/bin/cron-run-store.cjs +145 -0
- package/bin/durable-task-resume-policy.cjs +130 -0
- package/bin/durable-task-resume-runtime.cjs +117 -0
- package/bin/durable-task-resume-store.cjs +88 -0
- package/bin/editable-tool-approval-policy.cjs +540 -0
- package/bin/editable-tool-approval-runtime.cjs +99 -0
- package/bin/empty-response-retry-policy.cjs +29 -0
- package/bin/history-offload-pressure-policy.cjs +33 -0
- package/bin/html-to-research-markdown.cjs +146 -0
- package/bin/programmatic-context-isolation.cjs +25 -0
- package/bin/programmatic-tool-runtime.mjs +627 -0
- package/bin/read-continuation-policy.cjs +36 -5
- package/bin/scoped-cron-run-policy.cjs +358 -0
- package/bin/skill-activation-performance-policy.cjs +9 -0
- package/bin/startup-preferences.cjs +3 -3
- package/bin/structured-agent-swarm-output.cjs +325 -0
- package/bin/structured-subagent-output.cjs +252 -0
- package/bin/subagent-context-fork-policy.cjs +155 -0
- package/bin/subagent-skill-policy.cjs +204 -0
- package/bin/telegram-approval-relay.cjs +2 -1
- package/bin/telegram-direct-focus-policy.cjs +25 -1
- package/bin/todo-list-turn-policy.cjs +111 -1
- package/bin/tool-result-offload-policy.cjs +43 -1
- package/bin/turn-thinking-policy.cjs +6 -15
- package/bin/turn-tool-performance-policy.cjs +5 -4
- package/bin/update-notice.js +14 -18
- package/bin/user-message-offload-policy.cjs +12 -1
- package/blun.mjs +1406 -265
- package/codebase-index/README.md +82 -0
- package/codebase-index/codebase_index.py +469 -0
- package/package.json +24 -38
- package/telegram-plugin/bin/telegram-typing-keepalive.cjs +89 -0
- package/telegram-plugin/dist/bridge.mjs +8 -1
- package/CHANGELOG.md +0 -260
- package/agent-spine-plugin/CHANGELOG.md +0 -406
- package/agent-spine-plugin/CONTRIBUTING.md +0 -52
- package/agent-spine-plugin/README.md +0 -344
- package/agent-spine-plugin/SECURITY.md +0 -47
- package/agent-spine-plugin/docs/acceptance.md +0 -61
- package/agent-spine-plugin/docs/architecture.md +0 -183
- package/agent-spine-plugin/docs/attention.md +0 -121
- package/agent-spine-plugin/docs/automatic-continuity.md +0 -79
- package/agent-spine-plugin/docs/channel-runtime.md +0 -92
- package/agent-spine-plugin/docs/coordination.md +0 -138
- package/agent-spine-plugin/docs/feed-transport.md +0 -99
- package/agent-spine-plugin/docs/gateway-runtime.md +0 -116
- package/agent-spine-plugin/docs/harness-reference.md +0 -45
- package/agent-spine-plugin/docs/host-integration.md +0 -129
- package/agent-spine-plugin/docs/https-transport.md +0 -116
- package/agent-spine-plugin/docs/learning.md +0 -133
- package/agent-spine-plugin/docs/object-transport.md +0 -93
- package/agent-spine-plugin/docs/peer-transport.md +0 -88
- package/agent-spine-plugin/docs/preflight-recall.md +0 -69
- package/agent-spine-plugin/docs/preservation-contract.md +0 -53
- package/agent-spine-plugin/docs/quality-gates.md +0 -50
- package/agent-spine-plugin/docs/relationships.md +0 -73
- package/agent-spine-plugin/docs/releasing.md +0 -83
- package/agent-spine-plugin/docs/roadmap.md +0 -307
- package/agent-spine-plugin/docs/selfstarter.md +0 -88
- package/agent-spine-plugin/docs/session-briefing.md +0 -74
- package/agent-spine-plugin/docs/shared-memory.md +0 -259
- package/agent-spine-plugin/docs/source-roots.md +0 -86
- package/agent-spine-plugin/docs/sqlite-transport.md +0 -76
- package/agent-spine-plugin/scripts/check-hosts.js +0 -195
- package/agent-spine-plugin/scripts/check-install.js +0 -569
- package/agent-spine-plugin/scripts/check-syntax.js +0 -29
- package/agent-spine-plugin/scripts/github-actions.js +0 -11
- package/agent-spine-plugin/scripts/release-check.js +0 -128
- package/agent-spine-plugin/scripts/run-acceptance.js +0 -19
- package/agent-spine-plugin/scripts/run-checks.js +0 -46
- package/agent-spine-plugin/scripts/run-tests-hermetic.js +0 -73
- package/agent-spine-plugin/spine-example/1-identity.md +0 -12
- package/agent-spine-plugin/spine-example/2-voice.md +0 -6
- package/agent-spine-plugin/spine-example/3-conduct.md +0 -8
- package/agent-spine-plugin/spine-example/4-history.md +0 -4
- package/bin/package-regression-policy.cjs +0 -77
- package/release-planned-removals.json +0 -15
- package/scripts/check-active-profile-plugin-startup.js +0 -36
- package/scripts/check-approval-observability-regression.js +0 -111
- package/scripts/check-approval-queue-shortcuts-regression.js +0 -65
- package/scripts/check-bundled-agent-spine-regression.js +0 -48
- package/scripts/check-copy-command-regression.js +0 -74
- package/scripts/check-historical-tool-result-preview-regression.js +0 -77
- package/scripts/check-mcp-startup-wait-budget.js +0 -48
- package/scripts/check-package-regression.js +0 -38
- package/scripts/check-plugin-startup-regression.js +0 -53
- package/scripts/check-queue-controls-regression.js +0 -189
- package/scripts/check-release-metadata.js +0 -103
- package/scripts/check-reload-agent-spine-regression.js +0 -76
- package/scripts/check-resume-replay-regression.js +0 -100
- package/scripts/check-session-cancel-regression.js +0 -43
- package/scripts/check-session-picker-resume-metrics-regression.js +0 -97
- package/scripts/check-session-start-hook-context-regression.js +0 -228
- package/scripts/check-shell-terminal-isolation-regression.js +0 -81
- package/scripts/check-slash-escape-regression.js +0 -89
- package/scripts/check-telegram-bridge-watchdog.js +0 -60
- package/scripts/check-telegram-loop-exactly-once-regression.js +0 -71
- package/scripts/check-todo-loop-regression.js +0 -78
- package/scripts/check-todo-recovery-catalog-regression.js +0 -50
- /package/{scripts → bin}/fix-node-pty-perms.js +0 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
canonicalEditedToolInputJson,
|
|
5
|
+
validateEditedToolInputObject,
|
|
6
|
+
} = require('./editable-tool-approval-policy.cjs');
|
|
7
|
+
|
|
8
|
+
class EditableToolReprepareError extends Error {
|
|
9
|
+
constructor(code, message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = 'EditableToolReprepareError';
|
|
12
|
+
this.code = code;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function fail(code, message) {
|
|
17
|
+
throw new EditableToolReprepareError(code, message);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function buildEditedToolCallPlan({
|
|
21
|
+
step,
|
|
22
|
+
call,
|
|
23
|
+
editedArgs,
|
|
24
|
+
editCount,
|
|
25
|
+
preflightToolCall,
|
|
26
|
+
} = {}) {
|
|
27
|
+
if (editCount !== 0) {
|
|
28
|
+
fail('EDITED_REPREPARE_ALREADY_EDITED', 'A tool call may be edited at most once.');
|
|
29
|
+
}
|
|
30
|
+
if (call?.kind !== 'runnable' || call.toolCall === null || typeof call.toolCall !== 'object' || typeof call.toolCall.id !== 'string' || typeof call.toolCall.name !== 'string') {
|
|
31
|
+
fail('EDITED_REPREPARE_CALL_INVALID', 'Only a runnable tool call can be re-prepared.');
|
|
32
|
+
}
|
|
33
|
+
if (!Array.isArray(step?.toolCalls) || typeof preflightToolCall !== 'function') {
|
|
34
|
+
fail('EDITED_REPREPARE_CONTEXT_INVALID', 'Edited re-preparation requires the active ordered tool-call list and preflight function.');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const matchingIndexes = [];
|
|
38
|
+
for (let index = 0; index < step.toolCalls.length; index += 1) {
|
|
39
|
+
if (step.toolCalls[index]?.id === call.toolCall.id) matchingIndexes.push(index);
|
|
40
|
+
}
|
|
41
|
+
if (matchingIndexes.length === 0) {
|
|
42
|
+
fail('EDITED_REPREPARE_IDENTITY_MISSING', 'The edited tool call is absent from the active ordered call list.');
|
|
43
|
+
}
|
|
44
|
+
if (matchingIndexes.length !== 1) {
|
|
45
|
+
fail('EDITED_REPREPARE_IDENTITY_AMBIGUOUS', 'The edited tool-call ID is not unique in the active call list.');
|
|
46
|
+
}
|
|
47
|
+
const position = matchingIndexes[0];
|
|
48
|
+
if (step.toolCalls[position] !== call.toolCall || call.toolName !== call.toolCall.name) {
|
|
49
|
+
fail('EDITED_REPREPARE_IDENTITY_CHANGED', 'The active tool-call identity changed before re-preparation.');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const safeEditedArgs = validateEditedToolInputObject(editedArgs);
|
|
53
|
+
const patchedToolCall = Object.freeze({
|
|
54
|
+
...call.toolCall,
|
|
55
|
+
id: call.toolCall.id,
|
|
56
|
+
name: call.toolCall.name,
|
|
57
|
+
arguments: canonicalEditedToolInputJson(safeEditedArgs),
|
|
58
|
+
});
|
|
59
|
+
const patchedToolCalls = step.toolCalls.slice();
|
|
60
|
+
patchedToolCalls[position] = patchedToolCall;
|
|
61
|
+
const editedStep = {
|
|
62
|
+
...step,
|
|
63
|
+
toolCalls: Object.freeze(patchedToolCalls),
|
|
64
|
+
};
|
|
65
|
+
const repreflight = preflightToolCall(editedStep, patchedToolCall);
|
|
66
|
+
if (repreflight === null || typeof repreflight !== 'object') {
|
|
67
|
+
fail('EDITED_REPREPARE_PREFLIGHT_INVALID', 'Edited tool preflight returned no result.');
|
|
68
|
+
}
|
|
69
|
+
if (repreflight.toolCall?.id !== call.toolCall.id || repreflight.toolCall?.name !== call.toolCall.name || repreflight.toolName !== call.toolName) {
|
|
70
|
+
fail('EDITED_REPREPARE_IDENTITY_CHANGED', 'Edited preflight changed the immutable tool identity.');
|
|
71
|
+
}
|
|
72
|
+
if (repreflight.kind === 'rejected') {
|
|
73
|
+
return Object.freeze({
|
|
74
|
+
kind: 'rejected',
|
|
75
|
+
step: editedStep,
|
|
76
|
+
call: repreflight,
|
|
77
|
+
editCount: 1,
|
|
78
|
+
output: repreflight.output,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (repreflight.kind !== 'runnable') {
|
|
82
|
+
fail('EDITED_REPREPARE_PREFLIGHT_INVALID', 'Edited preflight returned an unsupported call state.');
|
|
83
|
+
}
|
|
84
|
+
if (repreflight.tool !== call.tool) {
|
|
85
|
+
fail('EDITED_REPREPARE_REGISTRY_CHANGED', 'The authoritative tool registry entry changed during edited approval.');
|
|
86
|
+
}
|
|
87
|
+
return Object.freeze({
|
|
88
|
+
kind: 'runnable',
|
|
89
|
+
step: editedStep,
|
|
90
|
+
call: repreflight,
|
|
91
|
+
editCount: 1,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = Object.freeze({
|
|
96
|
+
EditableToolReprepareError,
|
|
97
|
+
buildEditedToolCallPlan,
|
|
98
|
+
});
|
|
99
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const EMPTY_LENGTH_EFFORT_DOWNGRADE = Object.freeze({
|
|
4
|
+
max: 'high',
|
|
5
|
+
xhigh: 'high',
|
|
6
|
+
high: 'low',
|
|
7
|
+
medium: 'low',
|
|
8
|
+
low: 'off',
|
|
9
|
+
minimal: 'off',
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
function nextThinkingEffortForExhaustedEmpty(input = {}) {
|
|
13
|
+
const budget = Number(input.maxCompletionTokens);
|
|
14
|
+
const completion = Number(input.completionTokens);
|
|
15
|
+
if (
|
|
16
|
+
input.emptyResponseKind !== 'length'
|
|
17
|
+
|| !Number.isFinite(budget)
|
|
18
|
+
|| budget <= 0
|
|
19
|
+
|| !Number.isFinite(completion)
|
|
20
|
+
|| completion < budget
|
|
21
|
+
) return undefined;
|
|
22
|
+
|
|
23
|
+
return EMPTY_LENGTH_EFFORT_DOWNGRADE[String(input.thinkingEffort || '').toLowerCase()];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = {
|
|
27
|
+
EMPTY_LENGTH_EFFORT_DOWNGRADE,
|
|
28
|
+
nextThinkingEffortForExhaustedEmpty,
|
|
29
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const HISTORY_OFFLOAD_MIN_MESSAGES = 64;
|
|
4
|
+
const HISTORY_OFFLOAD_MIN_CHARS = 1_000_000;
|
|
5
|
+
|
|
6
|
+
function messageTextChars(message) {
|
|
7
|
+
if (!Array.isArray(message?.content)) return 0;
|
|
8
|
+
return message.content.reduce((total, part) => (
|
|
9
|
+
total + (part?.type === 'text' && typeof part.text === 'string' ? part.text.length : 0)
|
|
10
|
+
), 0);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function historyTextChars(messages) {
|
|
14
|
+
if (!Array.isArray(messages)) return 0;
|
|
15
|
+
return messages.reduce((total, message) => total + messageTextChars(message), 0);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function hasHistoricalOffloadPressure(options = {}) {
|
|
19
|
+
const historyLength = Number(options.historyLength);
|
|
20
|
+
const historyChars = Number(options.historyChars);
|
|
21
|
+
return Number.isSafeInteger(historyLength)
|
|
22
|
+
&& Number.isSafeInteger(historyChars)
|
|
23
|
+
&& historyLength >= HISTORY_OFFLOAD_MIN_MESSAGES
|
|
24
|
+
&& historyChars >= HISTORY_OFFLOAD_MIN_CHARS;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = {
|
|
28
|
+
HISTORY_OFFLOAD_MIN_CHARS,
|
|
29
|
+
HISTORY_OFFLOAD_MIN_MESSAGES,
|
|
30
|
+
hasHistoricalOffloadPressure,
|
|
31
|
+
historyTextChars,
|
|
32
|
+
messageTextChars,
|
|
33
|
+
};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { Readability } = require('@mozilla/readability');
|
|
4
|
+
const { parseHTML } = require('linkedom');
|
|
5
|
+
const TurndownService = require('turndown');
|
|
6
|
+
const { tables } = require('turndown-plugin-gfm');
|
|
7
|
+
|
|
8
|
+
const MAX_LINK_LENGTH = 2_048;
|
|
9
|
+
const JUNK_SELECTORS = Object.freeze([
|
|
10
|
+
'script',
|
|
11
|
+
'style',
|
|
12
|
+
'noscript',
|
|
13
|
+
'nav',
|
|
14
|
+
'footer',
|
|
15
|
+
'header',
|
|
16
|
+
'aside',
|
|
17
|
+
'iframe',
|
|
18
|
+
'svg',
|
|
19
|
+
'form',
|
|
20
|
+
'button',
|
|
21
|
+
'input',
|
|
22
|
+
'[role="navigation"]',
|
|
23
|
+
'[role="banner"]',
|
|
24
|
+
'[role="contentinfo"]',
|
|
25
|
+
'[aria-hidden="true"]',
|
|
26
|
+
'[hidden]',
|
|
27
|
+
]);
|
|
28
|
+
|
|
29
|
+
function canonicalBaseUrl(value) {
|
|
30
|
+
const parsed = new URL(value);
|
|
31
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
32
|
+
throw new Error('HTML-to-Markdown base URL must use http or https.');
|
|
33
|
+
}
|
|
34
|
+
return parsed.toString();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function safeResolvedLink(raw, baseUrl) {
|
|
38
|
+
if (typeof raw !== 'string' || raw.trim().length === 0) return null;
|
|
39
|
+
let resolved;
|
|
40
|
+
try {
|
|
41
|
+
resolved = new URL(raw, baseUrl);
|
|
42
|
+
} catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (resolved.protocol !== 'http:' && resolved.protocol !== 'https:') return null;
|
|
46
|
+
const value = resolved.toString();
|
|
47
|
+
return value.length <= MAX_LINK_LENGTH ? value : null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function removeAll(root, selector) {
|
|
51
|
+
for (const element of root.querySelectorAll(selector)) element.remove();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function sanitizeTree(root, baseUrl) {
|
|
55
|
+
for (const selector of JUNK_SELECTORS) removeAll(root, selector);
|
|
56
|
+
|
|
57
|
+
for (const element of root.querySelectorAll('[style]')) {
|
|
58
|
+
const style = element.getAttribute('style') ?? '';
|
|
59
|
+
if (/display\s*:\s*none|visibility\s*:\s*hidden/iu.test(style)) element.remove();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (const selector of [
|
|
63
|
+
'sup.reference',
|
|
64
|
+
'sup.noprint',
|
|
65
|
+
'.reflist',
|
|
66
|
+
'.references',
|
|
67
|
+
'.refbegin',
|
|
68
|
+
'.catlinks',
|
|
69
|
+
'.mw-authority-control',
|
|
70
|
+
]) removeAll(root, selector);
|
|
71
|
+
|
|
72
|
+
for (const anchor of root.querySelectorAll('a[href]')) {
|
|
73
|
+
const safe = safeResolvedLink(anchor.getAttribute('href'), baseUrl);
|
|
74
|
+
if (safe === null) anchor.removeAttribute('href');
|
|
75
|
+
else anchor.setAttribute('href', safe);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
for (const image of root.querySelectorAll('img')) {
|
|
79
|
+
const alt = (image.getAttribute('alt') ?? '').trim();
|
|
80
|
+
if (alt.length > 0) image.replaceWith(image.ownerDocument.createTextNode(alt));
|
|
81
|
+
else image.remove();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function createMarkdownService() {
|
|
86
|
+
const service = new TurndownService({
|
|
87
|
+
headingStyle: 'atx',
|
|
88
|
+
codeBlockStyle: 'fenced',
|
|
89
|
+
bulletListMarker: '-',
|
|
90
|
+
});
|
|
91
|
+
service.use(tables);
|
|
92
|
+
service.remove(['script', 'style', 'noscript', 'iframe', 'svg']);
|
|
93
|
+
return service;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function withTitle(title, markdown) {
|
|
97
|
+
const cleanTitle = title.trim();
|
|
98
|
+
if (cleanTitle.length === 0) return markdown;
|
|
99
|
+
const titleHeading = `# ${cleanTitle}`;
|
|
100
|
+
if (markdown === titleHeading || markdown.startsWith(`${titleHeading}\n`)) return markdown;
|
|
101
|
+
return `${titleHeading}\n\n${markdown}`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function renderRoot(root, title, safeBaseUrl) {
|
|
105
|
+
sanitizeTree(root, safeBaseUrl);
|
|
106
|
+
const fallback = (root.textContent ?? '').replace(/\s+/gu, ' ').trim();
|
|
107
|
+
let markdown = createMarkdownService().turndown(root.innerHTML).trim();
|
|
108
|
+
if (markdown.length === 0) markdown = fallback;
|
|
109
|
+
markdown = markdown.replace(/\n{4,}/gu, '\n\n\n').trim();
|
|
110
|
+
return withTitle(title, markdown);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function htmlToResearchMarkdown(html, baseUrl) {
|
|
114
|
+
if (typeof html !== 'string' || html.trim().length === 0) return '';
|
|
115
|
+
const safeBaseUrl = canonicalBaseUrl(baseUrl);
|
|
116
|
+
const primary = parseHTML(html);
|
|
117
|
+
try {
|
|
118
|
+
const article = new Readability(primary.document, { charThreshold: 0 }).parse();
|
|
119
|
+
if (article !== null && (article.content ?? '').trim().length > 0) {
|
|
120
|
+
const extracted = parseHTML(article.content);
|
|
121
|
+
const extractedRoot = extracted.document.querySelector('body');
|
|
122
|
+
if (extractedRoot !== null) {
|
|
123
|
+
const markdown = renderRoot(extractedRoot, article.title ?? '', safeBaseUrl);
|
|
124
|
+
if (markdown.length > 0) return markdown;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
} catch {
|
|
128
|
+
// Keep the existing fail-open container fallback.
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const { document } = parseHTML(html);
|
|
132
|
+
const title = (document.querySelector('title')?.textContent ?? '').trim();
|
|
133
|
+
const root = document.querySelector('article')
|
|
134
|
+
?? document.querySelector('main')
|
|
135
|
+
?? document.querySelector('[role="main"]')
|
|
136
|
+
?? document.querySelector('body');
|
|
137
|
+
return root === null ? '' : renderRoot(root, title, safeBaseUrl);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = Object.freeze({
|
|
141
|
+
JUNK_SELECTORS,
|
|
142
|
+
MAX_LINK_LENGTH,
|
|
143
|
+
canonicalBaseUrl,
|
|
144
|
+
htmlToResearchMarkdown,
|
|
145
|
+
safeResolvedLink,
|
|
146
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const PROGRAMMATIC_WIRE_ONLY = 'programmatic_nested';
|
|
4
|
+
|
|
5
|
+
function isNestedToolEvent(event) {
|
|
6
|
+
return event?.type === 'tool.call' || event?.type === 'tool.result';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function markProgrammaticNestedEvent(event) {
|
|
10
|
+
if (!isNestedToolEvent(event)) return event;
|
|
11
|
+
return {
|
|
12
|
+
...event,
|
|
13
|
+
contextVisibility: PROGRAMMATIC_WIRE_ONLY,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function isWireOnlyProgrammaticEvent(event) {
|
|
18
|
+
return isNestedToolEvent(event) && event.contextVisibility === PROGRAMMATIC_WIRE_ONLY;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
PROGRAMMATIC_WIRE_ONLY,
|
|
23
|
+
isWireOnlyProgrammaticEvent,
|
|
24
|
+
markProgrammaticNestedEvent,
|
|
25
|
+
};
|