neoctl 0.2.30 → 0.2.32
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 +37 -3
- package/dist/agents/agent-activity.d.ts +3 -0
- package/dist/agents/agent-activity.js +33 -6
- package/dist/agents/agent-activity.js.map +1 -1
- package/dist/agents/agent-definition.d.ts +2 -2
- package/dist/agents/agent-definition.js +6 -6
- package/dist/agents/agent-definition.js.map +1 -1
- package/dist/agents/agent-report-tool.d.ts +1 -1
- package/dist/agents/agent-report-tool.js +4 -4
- package/dist/agents/agent-report-tool.js.map +1 -1
- package/dist/agents/agent-tool.d.ts +1 -1
- package/dist/agents/agent-tool.js +97 -18
- package/dist/agents/agent-tool.js.map +1 -1
- package/dist/agents/local-agent-task.d.ts +12 -0
- package/dist/agents/local-agent-task.js +38 -1
- package/dist/agents/local-agent-task.js.map +1 -1
- package/dist/agents/smoke-agents.js +37 -26
- package/dist/agents/smoke-agents.js.map +1 -1
- package/dist/context/compaction.d.ts +20 -4
- package/dist/context/compaction.js +378 -187
- package/dist/context/compaction.js.map +1 -1
- package/dist/context/context-manager.d.ts +7 -1
- package/dist/context/context-manager.js +15 -11
- package/dist/context/context-manager.js.map +1 -1
- package/dist/context/prompts.js +8 -6
- package/dist/context/prompts.js.map +1 -1
- package/dist/context/smoke-context.js +273 -24
- package/dist/context/smoke-context.js.map +1 -1
- package/dist/core/assistant-output-filter.d.ts +1 -0
- package/dist/core/assistant-output-filter.js +54 -2
- package/dist/core/assistant-output-filter.js.map +1 -1
- package/dist/core/context-metrics.d.ts +1 -0
- package/dist/core/context-metrics.js +18 -12
- package/dist/core/context-metrics.js.map +1 -1
- package/dist/core/image-registry.d.ts +16 -3
- package/dist/core/image-registry.js +65 -30
- package/dist/core/image-registry.js.map +1 -1
- package/dist/core/image-storage.d.ts +15 -1
- package/dist/core/image-storage.js +140 -17
- package/dist/core/image-storage.js.map +1 -1
- package/dist/core/message-pipeline.js +18 -4
- package/dist/core/message-pipeline.js.map +1 -1
- package/dist/core/query-engine.d.ts +12 -2
- package/dist/core/query-engine.js +59 -8
- package/dist/core/query-engine.js.map +1 -1
- package/dist/core/query.d.ts +13 -2
- package/dist/core/query.js +144 -27
- package/dist/core/query.js.map +1 -1
- package/dist/core/run-agent.d.ts +13 -2
- package/dist/core/run-agent.js +16 -13
- package/dist/core/run-agent.js.map +1 -1
- package/dist/core/smoke-core-loop.js +121 -3
- package/dist/core/smoke-core-loop.js.map +1 -1
- package/dist/core/smoke-image-integrity.d.ts +1 -0
- package/dist/core/smoke-image-integrity.js +67 -0
- package/dist/core/smoke-image-integrity.js.map +1 -0
- package/dist/core/state.d.ts +1 -1
- package/dist/core/state.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/model/model-metadata.json +4 -4
- package/dist/plugins/plugin-system.d.ts +61 -0
- package/dist/plugins/plugin-system.js +189 -0
- package/dist/plugins/plugin-system.js.map +1 -0
- package/dist/plugins/smoke-plugin-system.d.ts +1 -0
- package/dist/plugins/smoke-plugin-system.js +63 -0
- package/dist/plugins/smoke-plugin-system.js.map +1 -0
- package/dist/repl/index.js +22 -17
- package/dist/repl/index.js.map +1 -1
- package/dist/secrets/secret-redaction.d.ts +5 -0
- package/dist/secrets/secret-redaction.js +43 -0
- package/dist/secrets/secret-redaction.js.map +1 -1
- package/dist/secrets/secret-types.d.ts +4 -0
- package/dist/secrets/secret-types.js.map +1 -1
- package/dist/secrets/smoke-secrets.js +7 -3
- package/dist/secrets/smoke-secrets.js.map +1 -1
- package/dist/session/session-export.d.ts +2 -0
- package/dist/session/session-export.js +10 -0
- package/dist/session/session-export.js.map +1 -1
- package/dist/session/session-store.d.ts +41 -0
- package/dist/session/session-store.js +292 -59
- package/dist/session/session-store.js.map +1 -1
- package/dist/session/smoke-session.js +127 -7
- package/dist/session/smoke-session.js.map +1 -1
- package/dist/skills/smoke-skills.js +5 -5
- package/dist/skills/smoke-skills.js.map +1 -1
- package/dist/tasks/subagent-tools.d.ts +31 -0
- package/dist/tasks/{task-tools.js → subagent-tools.js} +26 -32
- package/dist/tasks/subagent-tools.js.map +1 -0
- package/dist/tools/builtins/edit-tool.js +24 -6
- package/dist/tools/builtins/edit-tool.js.map +1 -1
- package/dist/tools/builtins/exec-process-manager.d.ts +13 -0
- package/dist/tools/builtins/exec-process-manager.js +57 -7
- package/dist/tools/builtins/exec-process-manager.js.map +1 -1
- package/dist/tools/builtins/exec-tool.js +34 -10
- package/dist/tools/builtins/exec-tool.js.map +1 -1
- package/dist/tools/builtins/filesystem-tools.js +2 -4
- package/dist/tools/builtins/filesystem-tools.js.map +1 -1
- package/dist/tools/builtins/grep-tool.js +2 -3
- package/dist/tools/builtins/grep-tool.js.map +1 -1
- package/dist/tools/builtins/image-generation-tool.js +36 -46
- package/dist/tools/builtins/image-generation-tool.js.map +1 -1
- package/dist/tools/builtins/image-loader-tool.js +12 -7
- package/dist/tools/builtins/image-loader-tool.js.map +1 -1
- package/dist/tools/builtins/image-note-tool.js +8 -4
- package/dist/tools/builtins/image-note-tool.js.map +1 -1
- package/dist/tools/builtins/plan-tool.js +1 -1
- package/dist/tools/builtins/plan-tool.js.map +1 -1
- package/dist/tools/builtins/search-tool.js +3 -3
- package/dist/tools/builtins/search-tool.js.map +1 -1
- package/dist/tools/registry.d.ts +8 -1
- package/dist/tools/registry.js +37 -13
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/run-tool-use.js +3 -2
- package/dist/tools/run-tool-use.js.map +1 -1
- package/dist/tools/smoke-exec-process.js +12 -0
- package/dist/tools/smoke-exec-process.js.map +1 -1
- package/dist/tools/smoke-tool-system.js +68 -31
- package/dist/tools/smoke-tool-system.js.map +1 -1
- package/dist/tools/tool-catalog.d.ts +36 -0
- package/dist/tools/tool-catalog.js +64 -0
- package/dist/tools/tool-catalog.js.map +1 -0
- package/dist/tools/tool-orchestration.d.ts +20 -3
- package/dist/tools/tool-orchestration.js +29 -4
- package/dist/tools/tool-orchestration.js.map +1 -1
- package/dist/tools/tool.d.ts +13 -0
- package/dist/tools/tool.js.map +1 -1
- package/dist/types/events.d.ts +28 -1
- package/dist/types/messages.d.ts +13 -5
- package/dist/types/messages.js +4 -0
- package/dist/types/messages.js.map +1 -1
- package/dist/ui/display-message.d.ts +10 -2
- package/dist/ui/display-message.js +18 -9
- package/dist/ui/display-message.js.map +1 -1
- package/dist/web/index.d.ts +198 -9
- package/dist/web/index.js +1208 -146
- package/dist/web/index.js.map +1 -1
- package/dist/web/runtime-context-protocol.d.ts +19 -1
- package/dist/web/runtime-context-protocol.js +19 -3
- package/dist/web/runtime-context-protocol.js.map +1 -1
- package/dist/web/smoke-runtime-context-protocol.js +13 -2
- package/dist/web/smoke-runtime-context-protocol.js.map +1 -1
- package/dist/web/smoke-web-history.d.ts +1 -0
- package/dist/web/smoke-web-history.js +179 -0
- package/dist/web/smoke-web-history.js.map +1 -0
- package/dist/web/smoke-web-terminal-tasks.js +35 -3
- package/dist/web/smoke-web-terminal-tasks.js.map +1 -1
- package/package.json +4 -1
- package/dist/tasks/task-tools.d.ts +0 -31
- package/dist/tasks/task-tools.js.map +0 -1
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
export const NEO_PLUGIN_PROTOCOL = "neo-plugin/v1";
|
|
5
|
+
export const NEO_PLUGIN_MANIFEST = "neo-plugin.json";
|
|
6
|
+
export async function loadNeoPlugins(options) {
|
|
7
|
+
const roots = normalizeRoots(options.directories);
|
|
8
|
+
const plugins = [];
|
|
9
|
+
for (const root of roots)
|
|
10
|
+
plugins.push(...await loadPluginRoot(root, options));
|
|
11
|
+
plugins.sort((left, right) => left.id.localeCompare(right.id));
|
|
12
|
+
assertUnique(plugins.map((plugin) => plugin.id), "duplicate plugin id");
|
|
13
|
+
assertUnique(plugins.flatMap((plugin) => plugin.tools ?? []).map((tool) => tool.name), "duplicate tool name across plugins");
|
|
14
|
+
return plugins;
|
|
15
|
+
}
|
|
16
|
+
export function validateNeoPluginManifest(value, manifestPath = NEO_PLUGIN_MANIFEST) {
|
|
17
|
+
if (!isRecord(value))
|
|
18
|
+
throw new Error(`invalid plugin manifest ${manifestPath}: expected an object`);
|
|
19
|
+
if (value.protocol !== NEO_PLUGIN_PROTOCOL) {
|
|
20
|
+
throw new Error(`invalid plugin manifest ${manifestPath}: protocol must be ${NEO_PLUGIN_PROTOCOL}`);
|
|
21
|
+
}
|
|
22
|
+
const id = requireText(value.id, "id", manifestPath);
|
|
23
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/u.test(id)) {
|
|
24
|
+
throw new Error(`invalid plugin manifest ${manifestPath}: invalid id ${id}`);
|
|
25
|
+
}
|
|
26
|
+
const entry = requireText(value.entry, "entry", manifestPath);
|
|
27
|
+
if (path.isAbsolute(entry))
|
|
28
|
+
throw new Error(`invalid plugin manifest ${manifestPath}: entry must be relative`);
|
|
29
|
+
return {
|
|
30
|
+
protocol: NEO_PLUGIN_PROTOCOL,
|
|
31
|
+
id,
|
|
32
|
+
name: requireText(value.name, "name", manifestPath),
|
|
33
|
+
version: requireText(value.version, "version", manifestPath),
|
|
34
|
+
entry,
|
|
35
|
+
...(typeof value.defaultEnabled === "boolean" ? { defaultEnabled: value.defaultEnabled } : {}),
|
|
36
|
+
...(typeof value.description === "string" && value.description.trim() ? { description: value.description.trim() } : {}),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
async function loadPluginRoot(root, options) {
|
|
40
|
+
let entries;
|
|
41
|
+
try {
|
|
42
|
+
entries = await readdir(root, { withFileTypes: true });
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (isNodeError(error) && error.code === "ENOENT")
|
|
46
|
+
return [];
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
const directories = entries.filter((entry) => entry.isDirectory()).sort((left, right) => left.name.localeCompare(right.name));
|
|
50
|
+
const plugins = [];
|
|
51
|
+
for (const entry of directories) {
|
|
52
|
+
const pluginDir = path.resolve(root, entry.name);
|
|
53
|
+
const manifestPath = path.join(pluginDir, NEO_PLUGIN_MANIFEST);
|
|
54
|
+
let rawManifest;
|
|
55
|
+
try {
|
|
56
|
+
rawManifest = await readFile(manifestPath, "utf8");
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
if (isNodeError(error) && error.code === "ENOENT")
|
|
60
|
+
continue;
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
let parsedManifest;
|
|
64
|
+
try {
|
|
65
|
+
parsedManifest = JSON.parse(rawManifest);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
throw new Error(`invalid plugin manifest ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
69
|
+
}
|
|
70
|
+
const manifest = validateNeoPluginManifest(parsedManifest, manifestPath);
|
|
71
|
+
const entryPath = resolveContainedEntry(pluginDir, manifest.entry, manifestPath);
|
|
72
|
+
const module = await import(pathToFileURL(entryPath).href);
|
|
73
|
+
const factory = module.createPlugin ?? module.default;
|
|
74
|
+
if (typeof factory !== "function") {
|
|
75
|
+
throw new Error(`invalid plugin module ${entryPath}: export createPlugin(context) or a default factory`);
|
|
76
|
+
}
|
|
77
|
+
const context = Object.freeze({
|
|
78
|
+
manifest: Object.freeze({ ...manifest }),
|
|
79
|
+
pluginDir,
|
|
80
|
+
...(options.appDataDir ? { appDataDir: path.resolve(options.appDataDir) } : {}),
|
|
81
|
+
env: Object.freeze({ ...(options.env ?? process.env) }),
|
|
82
|
+
});
|
|
83
|
+
const capabilities = normalizeCapabilities(await factory(context), entryPath);
|
|
84
|
+
plugins.push({
|
|
85
|
+
id: manifest.id,
|
|
86
|
+
name: manifest.name,
|
|
87
|
+
version: manifest.version,
|
|
88
|
+
description: manifest.description,
|
|
89
|
+
defaultEnabled: manifest.defaultEnabled !== false,
|
|
90
|
+
sourceDir: pluginDir,
|
|
91
|
+
manifestPath,
|
|
92
|
+
...capabilities,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return plugins;
|
|
96
|
+
}
|
|
97
|
+
function normalizeCapabilities(value, entryPath) {
|
|
98
|
+
if (!isRecord(value))
|
|
99
|
+
throw new Error(`invalid plugin module ${entryPath}: factory must return an object`);
|
|
100
|
+
const tools = value.tools === undefined ? [] : requireArray(value.tools, "tools", entryPath);
|
|
101
|
+
const promptSections = value.promptSections === undefined ? [] : requireArray(value.promptSections, "promptSections", entryPath);
|
|
102
|
+
for (const [index, tool] of tools.entries())
|
|
103
|
+
validateTool(tool, index, entryPath);
|
|
104
|
+
for (const [index, section] of promptSections.entries())
|
|
105
|
+
validatePromptSection(section, index, entryPath);
|
|
106
|
+
if (value.route !== undefined && typeof value.route !== "function") {
|
|
107
|
+
throw new Error(`invalid plugin module ${entryPath}: route must be a function`);
|
|
108
|
+
}
|
|
109
|
+
if (value.presentToolResult !== undefined && typeof value.presentToolResult !== "function") {
|
|
110
|
+
throw new Error(`invalid plugin module ${entryPath}: presentToolResult must be a function`);
|
|
111
|
+
}
|
|
112
|
+
const normalizedTools = tools;
|
|
113
|
+
const normalizedSections = promptSections;
|
|
114
|
+
assertUnique(normalizedTools.map((tool) => tool.name), `duplicate tool name in plugin module ${entryPath}`);
|
|
115
|
+
return {
|
|
116
|
+
tools: [...normalizedTools],
|
|
117
|
+
promptSections: normalizedSections.map((section) => ({ ...section })),
|
|
118
|
+
...(typeof value.presentToolResult === "function" ? { presentToolResult: value.presentToolResult } : {}),
|
|
119
|
+
...(typeof value.route === "function" ? { route: value.route } : {}),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function validateTool(value, index, entryPath) {
|
|
123
|
+
if (!isRecord(value))
|
|
124
|
+
throw new Error(`invalid plugin module ${entryPath}: tools[${index}] must be an object`);
|
|
125
|
+
if (!requireOptionalText(value.name))
|
|
126
|
+
throw new Error(`invalid plugin module ${entryPath}: tools[${index}].name is required`);
|
|
127
|
+
if (!(typeof value.description === "string" || typeof value.description === "function")) {
|
|
128
|
+
throw new Error(`invalid plugin module ${entryPath}: tools[${index}].description is required`);
|
|
129
|
+
}
|
|
130
|
+
if (!isRecord(value.inputSchema))
|
|
131
|
+
throw new Error(`invalid plugin module ${entryPath}: tools[${index}].inputSchema is required`);
|
|
132
|
+
if (!isRecord(value.metadata))
|
|
133
|
+
throw new Error(`invalid plugin module ${entryPath}: tools[${index}].metadata is required`);
|
|
134
|
+
if (typeof value.execute !== "function" && typeof value.call !== "function") {
|
|
135
|
+
throw new Error(`invalid plugin module ${entryPath}: tools[${index}] must implement execute or call`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function validatePromptSection(value, index, entryPath) {
|
|
139
|
+
if (!isRecord(value) || !requireOptionalText(value.name) || typeof value.content !== "string") {
|
|
140
|
+
throw new Error(`invalid plugin module ${entryPath}: promptSections[${index}] must contain name and content`);
|
|
141
|
+
}
|
|
142
|
+
if (value.cacheStable !== undefined && typeof value.cacheStable !== "boolean") {
|
|
143
|
+
throw new Error(`invalid plugin module ${entryPath}: promptSections[${index}].cacheStable must be boolean`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function resolveContainedEntry(pluginDir, entry, manifestPath) {
|
|
147
|
+
const resolved = path.resolve(pluginDir, entry);
|
|
148
|
+
const relative = path.relative(pluginDir, resolved);
|
|
149
|
+
if (!relative || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
|
|
150
|
+
throw new Error(`invalid plugin manifest ${manifestPath}: entry must resolve inside the plugin directory`);
|
|
151
|
+
}
|
|
152
|
+
return resolved;
|
|
153
|
+
}
|
|
154
|
+
function normalizeRoots(value) {
|
|
155
|
+
const roots = (Array.isArray(value) ? value : [value])
|
|
156
|
+
.map((root) => String(root || "").trim())
|
|
157
|
+
.filter(Boolean)
|
|
158
|
+
.map((root) => path.resolve(root));
|
|
159
|
+
return [...new Set(roots)];
|
|
160
|
+
}
|
|
161
|
+
function requireText(value, field, manifestPath) {
|
|
162
|
+
const text = typeof value === "string" ? value.trim() : "";
|
|
163
|
+
if (!text)
|
|
164
|
+
throw new Error(`invalid plugin manifest ${manifestPath}: ${field} is required`);
|
|
165
|
+
return text;
|
|
166
|
+
}
|
|
167
|
+
function requireArray(value, field, entryPath) {
|
|
168
|
+
if (!Array.isArray(value))
|
|
169
|
+
throw new Error(`invalid plugin module ${entryPath}: ${field} must be an array`);
|
|
170
|
+
return value;
|
|
171
|
+
}
|
|
172
|
+
function requireOptionalText(value) {
|
|
173
|
+
return typeof value === "string" && Boolean(value.trim());
|
|
174
|
+
}
|
|
175
|
+
function assertUnique(values, message) {
|
|
176
|
+
const seen = new Set();
|
|
177
|
+
for (const value of values) {
|
|
178
|
+
if (seen.has(value))
|
|
179
|
+
throw new Error(`${message}: ${value}`);
|
|
180
|
+
seen.add(value);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function isRecord(value) {
|
|
184
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
185
|
+
}
|
|
186
|
+
function isNodeError(error) {
|
|
187
|
+
return error instanceof Error && "code" in error;
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=plugin-system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-system.js","sourceRoot":"","sources":["../../src/plugins/plugin-system.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { loadNeoPlugins, NEO_PLUGIN_PROTOCOL, validateNeoPluginManifest } from "./plugin-system.js";
|
|
6
|
+
async function main() {
|
|
7
|
+
const root = await mkdtemp(path.join(os.tmpdir(), "neo-plugin-smoke-"));
|
|
8
|
+
const dataDir = path.join(root, "data");
|
|
9
|
+
try {
|
|
10
|
+
await createPlugin(root, "beta", false, "beta_tool");
|
|
11
|
+
await createPlugin(root, "alpha", true, "alpha_tool");
|
|
12
|
+
await mkdir(path.join(root, "not-a-plugin"), { recursive: true });
|
|
13
|
+
const plugins = await loadNeoPlugins({
|
|
14
|
+
directories: root,
|
|
15
|
+
appDataDir: dataDir,
|
|
16
|
+
env: { SMOKE_VALUE: "available" },
|
|
17
|
+
});
|
|
18
|
+
assert.deepEqual(plugins.map((plugin) => plugin.id), ["alpha", "beta"]);
|
|
19
|
+
assert.deepEqual(plugins.map((plugin) => plugin.defaultEnabled), [true, false]);
|
|
20
|
+
assert.deepEqual(plugins.flatMap((plugin) => plugin.tools.map((tool) => tool.name)), ["alpha_tool", "beta_tool"]);
|
|
21
|
+
assert.equal(plugins[0]?.promptSections[0]?.content, `available:${path.resolve(dataDir)}`);
|
|
22
|
+
assert.equal(await plugins[0]?.route?.({ method: "GET" }, {}, new URL("http://localhost/alpha"), {}), true);
|
|
23
|
+
assert.throws(() => validateNeoPluginManifest({ protocol: "other", id: "bad", name: "Bad", version: "1", entry: "index.mjs" }), /protocol must be neo-plugin\/v1/);
|
|
24
|
+
const missing = await loadNeoPlugins({ directories: path.join(root, "missing") });
|
|
25
|
+
assert.deepEqual(missing, []);
|
|
26
|
+
console.log(JSON.stringify({ ok: true, protocol: NEO_PLUGIN_PROTOCOL, plugins: plugins.map((plugin) => plugin.id) }, null, 2));
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
await rm(root, { recursive: true, force: true });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function createPlugin(root, id, defaultEnabled, toolName) {
|
|
33
|
+
const pluginDir = path.join(root, id);
|
|
34
|
+
await mkdir(pluginDir, { recursive: true });
|
|
35
|
+
await writeFile(path.join(pluginDir, "neo-plugin.json"), JSON.stringify({
|
|
36
|
+
protocol: NEO_PLUGIN_PROTOCOL,
|
|
37
|
+
id,
|
|
38
|
+
name: id.toUpperCase(),
|
|
39
|
+
version: "1.0.0",
|
|
40
|
+
entry: "index.mjs",
|
|
41
|
+
defaultEnabled,
|
|
42
|
+
}, null, 2));
|
|
43
|
+
await writeFile(path.join(pluginDir, "index.mjs"), `
|
|
44
|
+
export function createPlugin(context) {
|
|
45
|
+
return {
|
|
46
|
+
tools: [{
|
|
47
|
+
name: ${JSON.stringify(toolName)},
|
|
48
|
+
description: "smoke tool",
|
|
49
|
+
inputSchema: { type: "object" },
|
|
50
|
+
metadata: { readOnly: true, concurrent: true, visible: true },
|
|
51
|
+
async execute() { return { ok: true, output: context.manifest.id }; },
|
|
52
|
+
}],
|
|
53
|
+
promptSections: [{ name: "Smoke", content: context.env.SMOKE_VALUE + ":" + context.appDataDir, cacheStable: true }],
|
|
54
|
+
route(request, response, url) { return url.pathname === "/" + context.manifest.id; },
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
`, "utf8");
|
|
58
|
+
}
|
|
59
|
+
main().catch((error) => {
|
|
60
|
+
console.error(error);
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
});
|
|
63
|
+
//# sourceMappingURL=smoke-plugin-system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smoke-plugin-system.js","sourceRoot":"","sources":["../../src/plugins/smoke-plugin-system.ts"],"names":[],"mappings":"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"}
|
package/dist/repl/index.js
CHANGED
|
@@ -28,7 +28,7 @@ import { SecretStore } from "../secrets/secret-store.js";
|
|
|
28
28
|
import { InMemorySecretRedactionRegistry } from "../secrets/secret-redaction.js";
|
|
29
29
|
import { createAgentTool, resumeAgentTask } from "../agents/agent-tool.js";
|
|
30
30
|
import { AgentActivityStore } from "../agents/agent-activity.js";
|
|
31
|
-
import {
|
|
31
|
+
import { createSubagentTools } from "../tasks/subagent-tools.js";
|
|
32
32
|
import { TaskStore } from "../tasks/task-store.js";
|
|
33
33
|
import { cliHelpText, isModelReasoningArgument, isValidReplCommandLine, parseCliReplCommandArgs, parseReplCommand, helpText, replCommandDefinitions } from "./commands.js";
|
|
34
34
|
import { markdownRenderKey, MarkdownText } from "./markdown-renderer.js";
|
|
@@ -295,7 +295,7 @@ async function createRuntime(options = {}) {
|
|
|
295
295
|
};
|
|
296
296
|
return resumeAgentTask(taskId, directive, agentRuntime, taskStore, dummyContext);
|
|
297
297
|
};
|
|
298
|
-
for (const tool of
|
|
298
|
+
for (const tool of createSubagentTools(taskStore, resumeHandler))
|
|
299
299
|
tools.register(tool);
|
|
300
300
|
const taskNotificationSource = createTaskNotificationSource(taskStore);
|
|
301
301
|
const engine = new QueryEngine({
|
|
@@ -894,6 +894,7 @@ function InkRepl({ runtime, initialCommandLine }) {
|
|
|
894
894
|
if (event.type === "state")
|
|
895
895
|
return;
|
|
896
896
|
if (event.type === "context.metrics" ||
|
|
897
|
+
event.type === "context.compacted" ||
|
|
897
898
|
event.type === "usage" ||
|
|
898
899
|
event.type === "tool_call.delta" ||
|
|
899
900
|
event.type === "assistant.delta" ||
|
|
@@ -943,6 +944,7 @@ function InkRepl({ runtime, initialCommandLine }) {
|
|
|
943
944
|
if (event.type === "tool.started") {
|
|
944
945
|
finalizeLiveLine(assistantLineId.current);
|
|
945
946
|
finalizeThinkingLine();
|
|
947
|
+
assistantLineId.current = undefined;
|
|
946
948
|
return;
|
|
947
949
|
}
|
|
948
950
|
if (event.type === "tool.finished")
|
|
@@ -1231,7 +1233,7 @@ function InkRepl({ runtime, initialCommandLine }) {
|
|
|
1231
1233
|
if (runtime.engine !== engine)
|
|
1232
1234
|
continue;
|
|
1233
1235
|
if (suppressReattachedStreamingRef.current.has(engine)) {
|
|
1234
|
-
if (event.type === "message" || event.type === "terminal" || event.type === "error" || event.type === "context.metrics" || event.type === "usage") {
|
|
1236
|
+
if (event.type === "message" || event.type === "terminal" || event.type === "error" || event.type === "context.metrics" || event.type === "context.compacted" || event.type === "usage") {
|
|
1235
1237
|
if (event.type === "message" || event.type === "terminal" || event.type === "error")
|
|
1236
1238
|
suppressReattachedStreamingRef.current.delete(engine);
|
|
1237
1239
|
handleEvent(event);
|
|
@@ -2862,6 +2864,8 @@ function thinkingText(message) {
|
|
|
2862
2864
|
return text.length > 0 ? text : undefined;
|
|
2863
2865
|
}
|
|
2864
2866
|
function reduceStatus(status, event) {
|
|
2867
|
+
if (event.type === "context.compacted")
|
|
2868
|
+
return { ...status, phase: "compacting", detail: `${event.compaction.newWindowMessages} messages in new window`, activityTick: status.activityTick + 1 };
|
|
2865
2869
|
if (event.type === "state") {
|
|
2866
2870
|
return {
|
|
2867
2871
|
...status,
|
|
@@ -3551,8 +3555,9 @@ function formatUsageTotals(totals) {
|
|
|
3551
3555
|
}
|
|
3552
3556
|
function formatManualCompaction(result) {
|
|
3553
3557
|
if (!result.changed)
|
|
3554
|
-
return "No
|
|
3555
|
-
|
|
3558
|
+
return "No conversation context available to compact.";
|
|
3559
|
+
const preservedUsers = result.report?.preservedUserMessages ?? result.messages.filter((message) => message.metadata?.compactPreservedUser === true).length;
|
|
3560
|
+
return `manual context compacted: ${result.messages.length} messages in new window, ${preservedUsers} user message(s) preserved`;
|
|
3556
3561
|
}
|
|
3557
3562
|
function formatPureCompaction(result) {
|
|
3558
3563
|
if (!result.changed)
|
|
@@ -3657,7 +3662,7 @@ function formatToolUse(toolUse) {
|
|
|
3657
3662
|
text: formatPlanToolPayload(toolUse.input),
|
|
3658
3663
|
};
|
|
3659
3664
|
}
|
|
3660
|
-
const description = toolUse.name === "
|
|
3665
|
+
const description = toolUse.name === "terminal_run" ? execDescriptionFromInput(toolUse.input) : undefined;
|
|
3661
3666
|
return {
|
|
3662
3667
|
kind: "tool",
|
|
3663
3668
|
title: toolTitle(toolUse.name),
|
|
@@ -3712,12 +3717,12 @@ function toolTitle(toolName) {
|
|
|
3712
3717
|
skill_validate: "skill validation",
|
|
3713
3718
|
skill_create: "skill create",
|
|
3714
3719
|
skill_update: "skill update",
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3720
|
+
subagent_list: "task list",
|
|
3721
|
+
subagent_get: "task detail",
|
|
3722
|
+
subagent_output: "task output",
|
|
3723
|
+
subagent_stop: "task stop",
|
|
3724
|
+
subagent_resume: "task resume",
|
|
3725
|
+
subagent_message: "task message",
|
|
3721
3726
|
};
|
|
3722
3727
|
return `\u25c6 ${labels[toolName] ?? `tool: ${toolName}`}`;
|
|
3723
3728
|
}
|
|
@@ -3854,19 +3859,19 @@ function formatToolResult(toolName, output, ok) {
|
|
|
3854
3859
|
if (typeof output === "string" && hasAnsi(output)) {
|
|
3855
3860
|
return { text: output, format: "ansi" };
|
|
3856
3861
|
}
|
|
3857
|
-
if (toolName === "
|
|
3862
|
+
if (toolName === "file_list" && isRecord(output)) {
|
|
3858
3863
|
return { text: formatListToolResult(output, ok), format: "ansi" };
|
|
3859
3864
|
}
|
|
3860
|
-
if (toolName === "
|
|
3865
|
+
if (toolName === "file_read" && isRecord(output)) {
|
|
3861
3866
|
return { text: formatReadToolResult(output, ok), format: "ansi" };
|
|
3862
3867
|
}
|
|
3863
|
-
if (toolName === "
|
|
3868
|
+
if (toolName === "file_search" && isRecord(output)) {
|
|
3864
3869
|
return { text: formatGrepToolResult(output, ok), format: "ansi" };
|
|
3865
3870
|
}
|
|
3866
|
-
if (toolName === "
|
|
3871
|
+
if (toolName === "web_search" && isRecord(output)) {
|
|
3867
3872
|
return { text: formatWebSearchToolResult(output, ok), summaryMaxLines: EXPANDED_SUMMARY_MAX_LINES };
|
|
3868
3873
|
}
|
|
3869
|
-
if (toolName === "
|
|
3874
|
+
if (toolName === "image_create" && isRecord(output)) {
|
|
3870
3875
|
return { text: formatImageGenerationToolResult(output, ok), format: "ansi", summaryMaxLines: 8 };
|
|
3871
3876
|
}
|
|
3872
3877
|
if (toolName === "image_note" && isRecord(output)) {
|