@wrongstack/core 0.310.1 → 0.313.1
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/chronicle/index.js +84 -6391
- package/dist/chronicle/project-server.js +84 -4868
- package/dist/chunk-2BUUIMQB.js +225 -0
- package/dist/chunk-2FK4WTFF.js +207 -0
- package/dist/chunk-2FQL4PDC.js +292 -0
- package/dist/chunk-2KKODIQU.js +2256 -0
- package/dist/chunk-2YU4WVBW.js +134 -0
- package/dist/chunk-3E244UDA.js +356 -0
- package/dist/chunk-3XPVB7BA.js +135 -0
- package/dist/chunk-4LJJYBAU.js +388 -0
- package/dist/chunk-4VWO3ZXL.js +342 -0
- package/dist/chunk-4XV6IR37.js +187 -0
- package/dist/chunk-4ZHTKJHM.js +183 -0
- package/dist/chunk-52RTVH4M.js +361 -0
- package/dist/chunk-57GEWK5X.js +26 -0
- package/dist/chunk-5DSMEVA4.js +931 -0
- package/dist/chunk-5RP3QTRL.js +1223 -0
- package/dist/chunk-5S437PRC.js +50 -0
- package/dist/chunk-5XDUGTKN.js +511 -0
- package/dist/chunk-62V2AFVG.js +422 -0
- package/dist/chunk-65RDIOR2.js +2470 -0
- package/dist/chunk-6AKOTGLM.js +597 -0
- package/dist/chunk-7ZHZE5EO.js +28 -0
- package/dist/chunk-A455ATZB.js +140 -0
- package/dist/chunk-AD7ZFZCS.js +46 -0
- package/dist/chunk-AI4LLQ2U.js +856 -0
- package/dist/chunk-ASX6AW36.js +789 -0
- package/dist/chunk-AT4V4XGI.js +3522 -0
- package/dist/chunk-AWNQ6ED6.js +311 -0
- package/dist/chunk-B4AMLZPB.js +9 -0
- package/dist/chunk-BAKVJLEV.js +417 -0
- package/dist/chunk-BJHVULHO.js +55 -0
- package/dist/chunk-CB2HFKTP.js +9 -0
- package/dist/chunk-CE4ZOCOI.js +1640 -0
- package/dist/chunk-CQQL4ZOQ.js +151 -0
- package/dist/chunk-DEIQMBD2.js +65 -0
- package/dist/chunk-E6I5RXVK.js +58 -0
- package/dist/chunk-EFEHDQGY.js +1589 -0
- package/dist/chunk-EODDVJBM.js +82 -0
- package/dist/chunk-EPC3GZD4.js +308 -0
- package/dist/chunk-FAYRX2AD.js +13 -0
- package/dist/chunk-FFSX2QDQ.js +362 -0
- package/dist/chunk-FHAMQS7Q.js +5856 -0
- package/dist/chunk-FIV4IJL7.js +2263 -0
- package/dist/chunk-FNXVT7HF.js +52 -0
- package/dist/chunk-FSWCWSTS.js +395 -0
- package/dist/chunk-FW5LDDMJ.js +16464 -0
- package/dist/chunk-FXQLIX3K.js +211 -0
- package/dist/chunk-G5AAKEEZ.js +228 -0
- package/dist/chunk-G5S3S5ZN.js +38 -0
- package/dist/chunk-GAZEWQEZ.js +231 -0
- package/dist/chunk-GFJOMSHG.js +125 -0
- package/dist/chunk-GFXZTHNI.js +158 -0
- package/dist/chunk-GM54GJBU.js +960 -0
- package/dist/chunk-GPQ3NJPR.js +900 -0
- package/dist/chunk-GTCU6DZ3.js +1 -0
- package/dist/chunk-H5E77KUJ.js +15 -0
- package/dist/chunk-H72H4XDU.js +1023 -0
- package/dist/chunk-HA4ZYA6T.js +178 -0
- package/dist/chunk-I45KAW2N.js +5020 -0
- package/dist/chunk-IQ35HMQL.js +1396 -0
- package/dist/chunk-IYFBFX34.js +86 -0
- package/dist/chunk-JJPMWPB6.js +109 -0
- package/dist/chunk-JTHKOYWU.js +663 -0
- package/dist/chunk-JVGPR3TS.js +365 -0
- package/dist/chunk-JVKB2TBL.js +48 -0
- package/dist/chunk-JX7VBZDK.js +31 -0
- package/dist/chunk-K3G6JBUC.js +5232 -0
- package/dist/chunk-K4YUNKU7.js +589 -0
- package/dist/chunk-KBZGE6LN.js +710 -0
- package/dist/chunk-KDQJCT2J.js +45 -0
- package/dist/chunk-KI4L2DUL.js +560 -0
- package/dist/chunk-KJ2ZTQSL.js +47 -0
- package/dist/chunk-KSJ5UTP7.js +154 -0
- package/dist/chunk-LHOA5DWA.js +28 -0
- package/dist/chunk-LX5QWLBL.js +27 -0
- package/dist/chunk-LZDDLNCZ.js +279 -0
- package/dist/chunk-M2WF6AXG.js +115 -0
- package/dist/chunk-M7BS2K6U.js +1 -0
- package/dist/chunk-NDBIPFNY.js +102 -0
- package/dist/chunk-NEMIWEXC.js +1199 -0
- package/dist/chunk-NFAYHPRH.js +323 -0
- package/dist/chunk-O37BQ65S.js +21 -0
- package/dist/chunk-O74MJHXU.js +187 -0
- package/dist/chunk-OJZEX73F.js +112 -0
- package/dist/chunk-PAAWLLZX.js +74 -0
- package/dist/chunk-PFXFQQRT.js +339 -0
- package/dist/chunk-PFZO3C6H.js +14 -0
- package/dist/chunk-PHH7LD45.js +113 -0
- package/dist/chunk-QRTG4XTI.js +188 -0
- package/dist/chunk-QVOVMXJR.js +1351 -0
- package/dist/chunk-RCQYT2I4.js +757 -0
- package/dist/chunk-RD6DEE36.js +1178 -0
- package/dist/chunk-RJIZEJ42.js +30 -0
- package/dist/chunk-RPOA7IAE.js +150 -0
- package/dist/chunk-SN2DQRL6.js +1172 -0
- package/dist/chunk-SQJVFEBV.js +41 -0
- package/dist/chunk-SQP64RCS.js +5391 -0
- package/dist/chunk-SVT4RNTR.js +49 -0
- package/dist/chunk-SWUFN7XM.js +43 -0
- package/dist/chunk-SXMVYC5H.js +174 -0
- package/dist/chunk-SZ6AYUIZ.js +23 -0
- package/dist/chunk-T3KGZBU5.js +3171 -0
- package/dist/chunk-TBRL2RCC.js +9 -0
- package/dist/chunk-TRT2HRWZ.js +18 -0
- package/dist/chunk-TYW2GI5I.js +1077 -0
- package/dist/chunk-UIWONWVG.js +4959 -0
- package/dist/chunk-VB3H5WWB.js +151 -0
- package/dist/chunk-W4A6QA3D.js +258 -0
- package/dist/chunk-WBPVKEEE.js +227 -0
- package/dist/chunk-WEBMSQP2.js +123 -0
- package/dist/chunk-WOEZV3Q4.js +333 -0
- package/dist/chunk-WQQON3SV.js +473 -0
- package/dist/chunk-WQTOVMGV.js +119 -0
- package/dist/chunk-WZO23AWO.js +2779 -0
- package/dist/chunk-XBDP4QPW.js +7 -0
- package/dist/chunk-XEBHSJLT.js +103 -0
- package/dist/chunk-XQ2ECNK3.js +1 -0
- package/dist/chunk-XQ2XGIBF.js +2086 -0
- package/dist/chunk-Y2GE5TSI.js +355 -0
- package/dist/chunk-YBUJCZ57.js +351 -0
- package/dist/chunk-YNCVSFGF.js +149 -0
- package/dist/chunk-YUPMXOGP.js +282 -0
- package/dist/chunk-YY6APYUM.js +49 -0
- package/dist/chunk-Z2IJUO45.js +691 -0
- package/dist/chunk-ZEHUCJHY.js +129 -0
- package/dist/chunk-ZYU2YOJ6.js +1496 -0
- package/dist/chunk-ZZ4V3WIZ.js +163 -0
- package/dist/coordination/agents/index.js +145 -6260
- package/dist/coordination/index.js +365 -34323
- package/dist/coordination/mailbox-project-server.js +48 -3220
- package/dist/coordination/mailbox-types.d.ts +13 -1
- package/dist/coordination/provider-status-tracker.d.ts +4 -0
- package/dist/coordination/sqlite-mailbox.d.ts +2 -1
- package/dist/core/agent.d.ts +14 -1
- package/dist/core/index.js +267 -12479
- package/dist/core/model-ref.js +5 -23
- package/dist/core/provider-runner.d.ts +36 -1
- package/dist/design/index.js +50 -1087
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/index.js +1599 -21887
- package/dist/execution/prompt-enhancer.js +16 -535
- package/dist/execution/retry-policy.d.ts +31 -1
- package/dist/extension/index.js +7 -311
- package/dist/goal/index.js +33 -3435
- package/dist/hooks/index.js +14 -1138
- package/dist/hq/index.js +112 -5139
- package/dist/hq/protocol.js +21 -668
- package/dist/index.js +1410 -92655
- package/dist/infrastructure/index.js +64 -4811
- package/dist/kernel/events/provider-events.d.ts +15 -0
- package/dist/kernel/events/wrongtrace-events.d.ts +26 -0
- package/dist/kernel/events.d.ts +16 -7
- package/dist/kernel/index.js +14 -992
- package/dist/models/index.js +40 -1117
- package/dist/notifications/index.js +3 -108
- package/dist/observability/index.js +17 -279
- package/dist/plugin/index.js +584 -14835
- package/dist/prompts/index.js +14 -948
- package/dist/registry/index.js +9 -822
- package/dist/registry-R23UBE7H.js +14 -0
- package/dist/replay/index.js +6 -84
- package/dist/review-finding-store-DKAV3AS6.js +21 -0
- package/dist/review-report-store-OWY3EC3N.js +19 -0
- package/dist/security/index.js +114 -2202
- package/dist/session-catalog/index.js +36 -2103
- package/dist/session-catalog/project-server.js +42 -1435
- package/dist/skills/index.js +35 -1578
- package/dist/storage/index.js +182 -15600
- package/dist/tasking/index.js +10 -676
- package/dist/tools/index.js +52 -9589
- package/dist/types/config/autonomy.d.ts +5 -0
- package/dist/types/config/tools.d.ts +2 -2
- package/dist/types/config/ui.d.ts +1 -1
- package/dist/types/errors.d.ts +18 -0
- package/dist/types/index.js +121 -1341
- package/dist/types/provider-runner.d.ts +8 -0
- package/dist/types/session-markers.js +8 -144
- package/dist/utils/error.js +3 -4
- package/dist/utils/expect-defined.js +3 -9
- package/dist/utils/heap-watchdog.js +6 -706
- package/dist/utils/index.js +269 -5685
- package/dist/utils/sage-output-block.js +5 -42
- package/dist/wiring/proxy-rewrite.d.ts +92 -4
- package/dist/wiring/proxy-rewrite.js +20 -61
- package/dist/worktree/index.js +6 -887
- package/package.json +4 -4
package/dist/registry/index.js
CHANGED
|
@@ -1,825 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
this.factories.set(f.type, f);
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Bulk-register multiple provider factories at once.
|
|
14
|
-
*/
|
|
15
|
-
registerAll(factories) {
|
|
16
|
-
for (const f of factories) this.register(f);
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Override an existing factory. Throws if no factory is registered
|
|
20
|
-
* for the given type. Use this to safely replace a provider at runtime
|
|
21
|
-
* (e.g. in tests or when a plugin provides a custom implementation).
|
|
22
|
-
*/
|
|
23
|
-
override(type, f) {
|
|
24
|
-
if (!this.factories.has(type)) {
|
|
25
|
-
throw new Error(`Provider type "${type}" not registered; cannot override`);
|
|
26
|
-
}
|
|
27
|
-
this.factories.set(type, f);
|
|
28
|
-
}
|
|
29
|
-
has(type) {
|
|
30
|
-
return this.factories.has(type);
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Unregister a provider factory by type. Returns true if a factory was
|
|
34
|
-
* removed, false if none was registered for that type.
|
|
35
|
-
*/
|
|
36
|
-
unregister(type) {
|
|
37
|
-
return this.factories.delete(type);
|
|
38
|
-
}
|
|
39
|
-
create(cfg, factoryType = cfg.type) {
|
|
40
|
-
const f = this.factories.get(factoryType);
|
|
41
|
-
if (!f) {
|
|
42
|
-
throw new Error(
|
|
43
|
-
`Provider type "${factoryType}" not registered. Available: ${Array.from(this.factories.keys()).join(", ")}`
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
return f.create(cfg);
|
|
47
|
-
}
|
|
48
|
-
list() {
|
|
49
|
-
return Array.from(this.factories.keys());
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// src/utils/error.ts
|
|
54
|
-
function toErrorMessage(err) {
|
|
55
|
-
return err instanceof Error ? err.message : String(err);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// src/registry/slash-command-registry.ts
|
|
59
|
-
var SlashCommandRegistry = class {
|
|
60
|
-
cmds = /* @__PURE__ */ new Map();
|
|
61
|
-
/**
|
|
62
|
-
* Register a command.
|
|
63
|
-
*
|
|
64
|
-
* Trust tiers, by `owner` and `opts.official`:
|
|
65
|
-
*
|
|
66
|
-
* - **Built-ins** (`owner === 'core'`) and **official plugins**
|
|
67
|
-
* (`opts.official === true`, set by the host only for first-party plugins
|
|
68
|
-
* loaded from the built-in factory list) claim the **bare** command name
|
|
69
|
-
* (`/prompts`). They may override one another — last write wins — so an
|
|
70
|
-
* official plugin can replace a built-in. Official plugins are *also*
|
|
71
|
-
* reachable under their `owner:name` namespace.
|
|
72
|
-
* - **External plugins** (any other `owner`) are isolated under the
|
|
73
|
-
* `owner:name` namespace: invocable only as `/owner:cmd`, never by bare
|
|
74
|
-
* name, and unable to shadow or override a built-in or official command.
|
|
75
|
-
*
|
|
76
|
-
* Officiality is supplied by the host based on the plugin's load source, not
|
|
77
|
-
* self-declared by the plugin — an external plugin cannot name itself into
|
|
78
|
-
* the official tier.
|
|
79
|
-
*/
|
|
80
|
-
register(cmd, owner = "core", opts) {
|
|
81
|
-
const isPlugin = owner !== "core";
|
|
82
|
-
const official = !isPlugin || opts?.official === true;
|
|
83
|
-
if (official) {
|
|
84
|
-
const existing = this.cmds.get(cmd.name);
|
|
85
|
-
if (existing) {
|
|
86
|
-
const existingIsOfficialPlugin = existing.official && existing.owner !== "core";
|
|
87
|
-
if (!isPlugin && existingIsOfficialPlugin) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
if (!isPlugin && existing.owner === "core") return;
|
|
91
|
-
}
|
|
92
|
-
this.cmds.set(cmd.name, { cmd, owner, official });
|
|
93
|
-
for (const a of cmd.aliases ?? []) {
|
|
94
|
-
this.cmds.set(a, { cmd, owner, official });
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
if (isPlugin) {
|
|
98
|
-
this.cmds.set(`${owner}:${cmd.name}`, { cmd, owner, official });
|
|
99
|
-
for (const a of cmd.aliases ?? []) {
|
|
100
|
-
this.cmds.set(`${owner}:${a}`, { cmd, owner, official });
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
unregister(name) {
|
|
105
|
-
const entry = this.cmds.get(name);
|
|
106
|
-
if (!entry) return false;
|
|
107
|
-
for (const [key, e] of this.cmds.entries()) {
|
|
108
|
-
if (e.cmd === entry.cmd) this.cmds.delete(key);
|
|
109
|
-
}
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Bulk-register multiple slash commands at once.
|
|
114
|
-
*/
|
|
115
|
-
registerAll(cmds, owner = "core") {
|
|
116
|
-
for (const cmd of cmds) this.register(cmd, owner);
|
|
117
|
-
}
|
|
118
|
-
get(name) {
|
|
119
|
-
return this.cmds.get(name)?.cmd;
|
|
120
|
-
}
|
|
121
|
-
ownerOf(name) {
|
|
122
|
-
return this.cmds.get(name)?.owner;
|
|
123
|
-
}
|
|
124
|
-
list() {
|
|
125
|
-
const seen = /* @__PURE__ */ new Set();
|
|
126
|
-
const out = [];
|
|
127
|
-
for (const { cmd } of this.cmds.values()) {
|
|
128
|
-
if (!seen.has(cmd)) {
|
|
129
|
-
seen.add(cmd);
|
|
130
|
-
out.push(cmd);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return out;
|
|
134
|
-
}
|
|
135
|
-
listWithOwner() {
|
|
136
|
-
const seen = /* @__PURE__ */ new Set();
|
|
137
|
-
const out = [];
|
|
138
|
-
for (const [fullName, { cmd, owner }] of this.cmds.entries()) {
|
|
139
|
-
if (!seen.has(cmd)) {
|
|
140
|
-
seen.add(cmd);
|
|
141
|
-
out.push({ cmd, owner, fullName });
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return out;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Parse a slash command line. Accepts both:
|
|
148
|
-
* `/cmd args` → builtin command (owner=core)
|
|
149
|
-
* `/pluginName:cmd args` → plugin command
|
|
150
|
-
* The command name is split at the first `:` if the prefix matches a known owner.
|
|
151
|
-
*/
|
|
152
|
-
async dispatch(line, ctx) {
|
|
153
|
-
if (!line.startsWith("/")) return null;
|
|
154
|
-
const trimmed = line.slice(1);
|
|
155
|
-
const spaceIdx = trimmed.indexOf(" ");
|
|
156
|
-
const firstColonIdx = trimmed.indexOf(":");
|
|
157
|
-
let name;
|
|
158
|
-
let args;
|
|
159
|
-
if (firstColonIdx !== -1 && (spaceIdx === -1 || firstColonIdx < spaceIdx)) {
|
|
160
|
-
const prefix = trimmed.slice(0, firstColonIdx);
|
|
161
|
-
name = trimmed.slice(0, spaceIdx === -1 ? void 0 : spaceIdx);
|
|
162
|
-
args = spaceIdx === -1 ? "" : trimmed.slice(spaceIdx + 1);
|
|
163
|
-
const entry2 = this.cmds.get(name);
|
|
164
|
-
if (!entry2 || entry2.owner !== prefix) {
|
|
165
|
-
name = trimmed.slice(0, spaceIdx === -1 ? void 0 : spaceIdx);
|
|
166
|
-
args = spaceIdx === -1 ? "" : trimmed.slice(spaceIdx + 1);
|
|
167
|
-
}
|
|
168
|
-
} else {
|
|
169
|
-
name = trimmed.slice(0, spaceIdx === -1 ? void 0 : spaceIdx);
|
|
170
|
-
args = spaceIdx === -1 ? "" : trimmed.slice(spaceIdx + 1);
|
|
171
|
-
}
|
|
172
|
-
const entry = this.cmds.get(name);
|
|
173
|
-
if (!entry) {
|
|
174
|
-
return { message: `Unknown command "/${name}". Type /help for a list.` };
|
|
175
|
-
}
|
|
176
|
-
try {
|
|
177
|
-
const res = await entry.cmd.run(args, ctx);
|
|
178
|
-
return res ?? {};
|
|
179
|
-
} catch (err) {
|
|
180
|
-
const msg = toErrorMessage(err);
|
|
181
|
-
return { message: `Command "/${name}" failed: ${msg}` };
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
// src/types/errors.ts
|
|
187
|
-
var ERROR_CODES = {
|
|
188
|
-
// Provider
|
|
189
|
-
PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
|
|
190
|
-
PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
|
|
191
|
-
PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
|
|
192
|
-
PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
|
|
193
|
-
PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
|
|
194
|
-
PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
|
|
195
|
-
PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
|
|
196
|
-
// Tool
|
|
197
|
-
TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
|
|
198
|
-
TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
|
|
199
|
-
TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
|
|
200
|
-
TOOL_TIMEOUT: "TOOL_TIMEOUT",
|
|
201
|
-
TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
|
|
202
|
-
// Config
|
|
203
|
-
CONFIG_INVALID: "CONFIG_INVALID",
|
|
204
|
-
CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
|
|
205
|
-
CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
|
|
206
|
-
CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
|
|
207
|
-
// Plugin
|
|
208
|
-
PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
|
|
209
|
-
PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
|
|
210
|
-
PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
|
|
211
|
-
// Agent
|
|
212
|
-
AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
|
|
213
|
-
AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
|
|
214
|
-
AGENT_ABORTED: "AGENT_ABORTED",
|
|
215
|
-
AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
|
|
216
|
-
// Session
|
|
217
|
-
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
218
|
-
SESSION_CORRUPTED: "SESSION_CORRUPTED",
|
|
219
|
-
SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
|
|
220
|
-
// Container / Registry
|
|
221
|
-
CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
|
|
222
|
-
CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
|
|
223
|
-
CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
|
|
224
|
-
REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
|
|
225
|
-
REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
|
|
226
|
-
REGISTRY_INVALID: "REGISTRY_INVALID",
|
|
227
|
-
// File system
|
|
228
|
-
FS_READ_FAILED: "FS_READ_FAILED",
|
|
229
|
-
FS_WRITE_FAILED: "FS_WRITE_FAILED",
|
|
230
|
-
FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
|
|
231
|
-
FS_DELETE_FAILED: "FS_DELETE_FAILED",
|
|
232
|
-
FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
|
|
233
|
-
// SDD (Spec-Driven Development)
|
|
234
|
-
SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
|
|
235
|
-
SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
|
|
236
|
-
SDD_INVALID_STATE: "SDD_INVALID_STATE",
|
|
237
|
-
SDD_NOT_READY: "SDD_NOT_READY",
|
|
238
|
-
// General
|
|
239
|
-
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
240
|
-
PARSE_FAILED: "PARSE_FAILED",
|
|
241
|
-
UNKNOWN: "UNKNOWN"
|
|
242
|
-
};
|
|
243
|
-
var WrongStackError = class extends Error {
|
|
244
|
-
code;
|
|
245
|
-
subsystem;
|
|
246
|
-
severity;
|
|
247
|
-
recoverable;
|
|
248
|
-
context;
|
|
249
|
-
constructor(opts) {
|
|
250
|
-
super(opts.message, { cause: opts.cause });
|
|
251
|
-
this.name = "WrongStackError";
|
|
252
|
-
this.code = opts.code;
|
|
253
|
-
this.subsystem = opts.subsystem;
|
|
254
|
-
this.severity = opts.severity ?? "error";
|
|
255
|
-
this.recoverable = opts.recoverable ?? false;
|
|
256
|
-
this.context = opts.context;
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Render a one-line user-facing description.
|
|
260
|
-
* Subclasses should override for domain-specific formatting.
|
|
261
|
-
*/
|
|
262
|
-
describe() {
|
|
263
|
-
const ctx = this.context ? ` ${formatContext(this.context)}` : "";
|
|
264
|
-
return `${this.code}: ${this.message}${ctx}`;
|
|
265
|
-
}
|
|
266
|
-
};
|
|
267
|
-
function formatContext(ctx) {
|
|
268
|
-
const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
|
|
269
|
-
return parts.length > 0 ? `[${parts.join(" ")}]` : "";
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// src/utils/tool-wire-compact.ts
|
|
273
|
-
var TOOL_DESCRIPTION_MAX_CHARS = 400;
|
|
274
|
-
var SCHEMA_DESCRIPTION_MAX_CHARS = 120;
|
|
275
|
-
var compactCache = /* @__PURE__ */ new WeakMap();
|
|
276
|
-
function compactToolDefinitionForWire(tool, opts = {}) {
|
|
277
|
-
const useDefaultOptions = opts.descriptionMaxChars === void 0 && opts.schemaDescriptionMaxChars === void 0;
|
|
278
|
-
if (useDefaultOptions && typeof tool === "object" && tool !== null) {
|
|
279
|
-
const cached = compactCache.get(tool);
|
|
280
|
-
if (cached) return cached;
|
|
281
|
-
}
|
|
282
|
-
const compact = {
|
|
283
|
-
name: tool.name,
|
|
284
|
-
description: compactDescription(
|
|
285
|
-
tool.description ?? "",
|
|
286
|
-
opts.descriptionMaxChars ?? TOOL_DESCRIPTION_MAX_CHARS
|
|
287
|
-
),
|
|
288
|
-
inputSchema: normalizeTopLevelToolSchema(
|
|
289
|
-
compactSchemaDescriptions(
|
|
290
|
-
tool.inputSchema,
|
|
291
|
-
opts.schemaDescriptionMaxChars ?? SCHEMA_DESCRIPTION_MAX_CHARS
|
|
292
|
-
)
|
|
293
|
-
)
|
|
294
|
-
};
|
|
295
|
-
if (useDefaultOptions && typeof tool === "object" && tool !== null) {
|
|
296
|
-
compactCache.set(tool, compact);
|
|
297
|
-
}
|
|
298
|
-
return compact;
|
|
299
|
-
}
|
|
300
|
-
function normalizeTopLevelToolSchema(schema) {
|
|
301
|
-
const combinators = ["oneOf", "anyOf", "allOf"].map((keyword) => ({ keyword, branches: schema[keyword] })).filter(
|
|
302
|
-
(entry) => Array.isArray(entry.branches)
|
|
303
|
-
);
|
|
304
|
-
if (combinators.length === 0) return schema;
|
|
305
|
-
const out = { ...schema, type: "object" };
|
|
306
|
-
delete out["oneOf"];
|
|
307
|
-
delete out["anyOf"];
|
|
308
|
-
delete out["allOf"];
|
|
309
|
-
const properties = isRecord(schema["properties"]) ? { ...schema["properties"] } : {};
|
|
310
|
-
let required = stringSet(schema["required"]);
|
|
311
|
-
for (const { keyword, branches } of combinators) {
|
|
312
|
-
const objectBranches = branches.filter(isRecord);
|
|
313
|
-
for (const branch of objectBranches) {
|
|
314
|
-
if (isRecord(branch["properties"])) Object.assign(properties, branch["properties"]);
|
|
315
|
-
}
|
|
316
|
-
const branchRequired = objectBranches.map((branch) => stringSet(branch["required"]));
|
|
317
|
-
if (keyword === "allOf") {
|
|
318
|
-
for (const fields of branchRequired) for (const field of fields) required.add(field);
|
|
319
|
-
} else if (branchRequired.length > 0) {
|
|
320
|
-
const common = new Set(
|
|
321
|
-
[...branchRequired[0]].filter(
|
|
322
|
-
(field) => branchRequired.slice(1).every((fields) => fields.has(field))
|
|
323
|
-
)
|
|
324
|
-
);
|
|
325
|
-
required = /* @__PURE__ */ new Set([...required, ...common]);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
out["properties"] = properties;
|
|
329
|
-
if (required.size > 0) out["required"] = [...required];
|
|
330
|
-
else delete out["required"];
|
|
331
|
-
return out;
|
|
332
|
-
}
|
|
333
|
-
function stringSet(value) {
|
|
334
|
-
return new Set(
|
|
335
|
-
Array.isArray(value) ? value.filter((item) => typeof item === "string") : []
|
|
336
|
-
);
|
|
337
|
-
}
|
|
338
|
-
function compactSchemaDescriptions(schema, maxDescriptionChars = SCHEMA_DESCRIPTION_MAX_CHARS) {
|
|
339
|
-
const compact = compactSchemaNode(schema, maxDescriptionChars);
|
|
340
|
-
return isRecord(compact) ? compact : { type: "object", properties: {} };
|
|
341
|
-
}
|
|
342
|
-
function compactSchemaNode(node, maxDescriptionChars) {
|
|
343
|
-
if (Array.isArray(node)) {
|
|
344
|
-
return node.map((item) => compactSchemaNode(item, maxDescriptionChars));
|
|
345
|
-
}
|
|
346
|
-
if (!isRecord(node)) return node;
|
|
347
|
-
const out = {};
|
|
348
|
-
for (const [key, value] of Object.entries(node)) {
|
|
349
|
-
if (key === "description" && typeof value === "string") {
|
|
350
|
-
out[key] = compactDescription(value, maxDescriptionChars);
|
|
351
|
-
} else {
|
|
352
|
-
out[key] = compactSchemaNode(value, maxDescriptionChars);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
return out;
|
|
356
|
-
}
|
|
357
|
-
function compactDescription(text, maxChars) {
|
|
358
|
-
const normalized = text.replace(/\s+/g, " ").trim();
|
|
359
|
-
if (normalized.length <= maxChars) return normalized;
|
|
360
|
-
if (maxChars <= 20) return normalized.slice(0, maxChars);
|
|
361
|
-
const hardLimit = maxChars - 12;
|
|
362
|
-
const boundary = findSemanticBoundary(normalized, hardLimit);
|
|
363
|
-
const head = normalized.slice(0, boundary > 0 ? boundary : hardLimit).trimEnd();
|
|
364
|
-
return `${head} ...`;
|
|
365
|
-
}
|
|
366
|
-
function findSemanticBoundary(text, limit) {
|
|
367
|
-
const punctuation = Math.max(
|
|
368
|
-
text.lastIndexOf(". ", limit),
|
|
369
|
-
text.lastIndexOf("; ", limit),
|
|
370
|
-
text.lastIndexOf(": ", limit)
|
|
371
|
-
);
|
|
372
|
-
if (punctuation >= Math.floor(limit * 0.45)) return punctuation + 1;
|
|
373
|
-
const comma = text.lastIndexOf(", ", limit);
|
|
374
|
-
if (comma >= Math.floor(limit * 0.6)) return comma + 1;
|
|
375
|
-
const space = text.lastIndexOf(" ", limit);
|
|
376
|
-
return space >= Math.floor(limit * 0.6) ? space : limit;
|
|
377
|
-
}
|
|
378
|
-
function isRecord(value) {
|
|
379
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// src/utils/token-estimate.ts
|
|
383
|
-
var RoughTokenEstimate = (text, charsPerToken = 3.5) => Math.max(1, Math.ceil(text.length / charsPerToken));
|
|
384
|
-
function estimateToolDefTokens(tool) {
|
|
385
|
-
const cached = tool._estDefTokens;
|
|
386
|
-
if (typeof cached === "number" && cached > 0) return cached;
|
|
387
|
-
const compact = compactToolDefinitionForWire(tool);
|
|
388
|
-
return RoughTokenEstimate(tool.name) + RoughTokenEstimate(compact.description) + RoughTokenEstimate(JSON.stringify(compact.inputSchema));
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// src/utils/tool-description-mode.ts
|
|
392
|
-
var ORIGINAL_TOOL_DESCRIPTION = /* @__PURE__ */ Symbol.for("wrongstack.tool.originalDescription");
|
|
393
|
-
function normalizeToolDescriptionMode(value) {
|
|
394
|
-
if (typeof value !== "string") return void 0;
|
|
395
|
-
const raw = value.trim().toLowerCase();
|
|
396
|
-
if (raw === "extend" || raw === "extended" || raw === "full") return "extend";
|
|
397
|
-
if (raw === "simple" || raw === "short" || raw === "brief") return "simple";
|
|
398
|
-
return void 0;
|
|
399
|
-
}
|
|
400
|
-
function simplifyToolDescription(text, opts = {}) {
|
|
401
|
-
const maxSentences = Math.max(1, opts.maxSentences ?? 2);
|
|
402
|
-
const maxChars = Math.max(40, opts.maxChars ?? 180);
|
|
403
|
-
const normalized = text.replace(/\r\n?/g, "\n").split("\n").map((line) => line.trim()).filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
|
|
404
|
-
if (normalized.length <= maxChars) return normalized;
|
|
405
|
-
const sentences = normalized.match(/[^.!?]+[.!?]+(?=\s|$)|[^.!?]+$/g) ?? [normalized];
|
|
406
|
-
const selected = [];
|
|
407
|
-
for (const sentence of sentences) {
|
|
408
|
-
selected.push(sentence.trim());
|
|
409
|
-
const candidate = selected.join(" ");
|
|
410
|
-
if (selected.length >= maxSentences || candidate.length >= maxChars) break;
|
|
411
|
-
}
|
|
412
|
-
const summary = selected.join(" ").trim() || normalized;
|
|
413
|
-
if (summary.length <= maxChars) return summary;
|
|
414
|
-
const hardLimit = maxChars - 4;
|
|
415
|
-
const boundary = findWordBoundary(summary, hardLimit);
|
|
416
|
-
return `${summary.slice(0, boundary > 0 ? boundary : hardLimit).trimEnd()} ...`;
|
|
417
|
-
}
|
|
418
|
-
function applyToolDescriptionModeToTool(tool, mode) {
|
|
419
|
-
const existingOriginal = getOriginalDescription(tool);
|
|
420
|
-
if (mode === "extend" && !existingOriginal) return tool;
|
|
421
|
-
const original = existingOriginal ?? {
|
|
422
|
-
description: tool.description,
|
|
423
|
-
usageHint: tool.usageHint
|
|
424
|
-
};
|
|
425
|
-
const next = mode === "simple" ? withDescription(tool, {
|
|
426
|
-
description: simplifyToolDescription(original.description),
|
|
427
|
-
usageHint: original.usageHint === void 0 ? void 0 : simplifyToolDescription(original.usageHint)
|
|
428
|
-
}) : withDescription(tool, original);
|
|
429
|
-
return attachOriginalDescription(next, original);
|
|
430
|
-
}
|
|
431
|
-
function getOriginalDescription(tool) {
|
|
432
|
-
return tool[ORIGINAL_TOOL_DESCRIPTION];
|
|
433
|
-
}
|
|
434
|
-
function attachOriginalDescription(tool, original) {
|
|
435
|
-
Object.defineProperty(tool, ORIGINAL_TOOL_DESCRIPTION, {
|
|
436
|
-
configurable: true,
|
|
437
|
-
enumerable: false,
|
|
438
|
-
value: original,
|
|
439
|
-
writable: true
|
|
440
|
-
});
|
|
441
|
-
return tool;
|
|
442
|
-
}
|
|
443
|
-
function withDescription(tool, next) {
|
|
444
|
-
const copy = {
|
|
445
|
-
...tool,
|
|
446
|
-
description: next.description,
|
|
447
|
-
usageHint: next.usageHint
|
|
448
|
-
};
|
|
449
|
-
if (next.usageHint === void 0) {
|
|
450
|
-
delete copy.usageHint;
|
|
451
|
-
}
|
|
452
|
-
return copy;
|
|
453
|
-
}
|
|
454
|
-
function findWordBoundary(text, limit) {
|
|
455
|
-
const semantic = Math.max(
|
|
456
|
-
text.lastIndexOf(". ", limit),
|
|
457
|
-
text.lastIndexOf("; ", limit),
|
|
458
|
-
text.lastIndexOf(", ", limit)
|
|
459
|
-
);
|
|
460
|
-
if (semantic > 40) return semantic + 1;
|
|
461
|
-
const space = text.lastIndexOf(" ", limit);
|
|
462
|
-
return space > 40 ? space : limit;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// src/registry/tool-registry.ts
|
|
466
|
-
var ToolRegistry = class _ToolRegistry {
|
|
467
|
-
tools = /* @__PURE__ */ new Map();
|
|
468
|
-
descriptionModes = /* @__PURE__ */ new Map();
|
|
469
|
-
/**
|
|
470
|
-
* Set of tool names that are disabled (hidden from list(), get() and all
|
|
471
|
-
* other public accessors). The underlying tool data stays in `_tools` so
|
|
472
|
-
* re-enable is a constant-time operation.
|
|
473
|
-
*/
|
|
474
|
-
_disabled = /* @__PURE__ */ new Set();
|
|
475
|
-
/** Monotonic version bumped on every registry mutation. */
|
|
476
|
-
_version = 0;
|
|
477
|
-
/** Cached `list()` result, frozen after build. Invalidated on _version change. */
|
|
478
|
-
_listSnapshot;
|
|
479
|
-
_listSnapshotVersion = -1;
|
|
480
|
-
/**
|
|
481
|
-
* Optional direct provider surface. `undefined` preserves the legacy
|
|
482
|
-
* behaviour (every enabled catalog tool is direct); when set, `list()` still
|
|
483
|
-
* exposes the complete executable catalog while `listForProvider()` returns
|
|
484
|
-
* only these names. This keeps lazy tools discoverable by tool_search/tool_use.
|
|
485
|
-
*/
|
|
486
|
-
_providerToolNames;
|
|
487
|
-
_providerListSnapshot;
|
|
488
|
-
_providerListSnapshotVersion = -1;
|
|
489
|
-
/** Pre-compute tool definition token estimate once at registration time. */
|
|
490
|
-
_stampDefTokens(tool) {
|
|
491
|
-
if (tool._estDefTokens === void 0) {
|
|
492
|
-
tool._estDefTokens = estimateToolDefTokens(tool);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
/** Apply the description mode transform and stamp token estimates. */
|
|
496
|
-
_prepareForStorage(tool) {
|
|
497
|
-
const mode = this.descriptionModes.get(tool.name) ?? "extend";
|
|
498
|
-
return applyToolDescriptionModeToTool(tool, mode);
|
|
499
|
-
}
|
|
500
|
-
register(tool, owner = "core") {
|
|
501
|
-
if (this.tools.has(tool.name)) {
|
|
502
|
-
throw new WrongStackError({
|
|
503
|
-
message: `Tool "${tool.name}" already registered`,
|
|
504
|
-
code: ERROR_CODES.REGISTRY_DUPLICATE,
|
|
505
|
-
subsystem: "container",
|
|
506
|
-
context: { tool: tool.name }
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
if (!tool.inputSchema || typeof tool.inputSchema !== "object") {
|
|
510
|
-
throw new WrongStackError({
|
|
511
|
-
message: `Tool "${tool.name}" has an invalid or missing inputSchema`,
|
|
512
|
-
code: ERROR_CODES.REGISTRY_INVALID,
|
|
513
|
-
subsystem: "container",
|
|
514
|
-
context: { tool: tool.name }
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
const stored = this._prepareForStorage(tool);
|
|
518
|
-
this._stampDefTokens(stored);
|
|
519
|
-
this.tools.set(tool.name, { tool: stored, owner });
|
|
520
|
-
this._version++;
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* Attempt to register a tool. Returns true if successful, false if a tool
|
|
524
|
-
* with the same name is already registered. Useful in multi-agent or plugin
|
|
525
|
-
* scenarios where duplicate registration may be intentional.
|
|
526
|
-
*/
|
|
527
|
-
tryRegister(tool, owner = "core") {
|
|
528
|
-
if (this.tools.has(tool.name)) return false;
|
|
529
|
-
if (!tool.inputSchema || typeof tool.inputSchema !== "object") {
|
|
530
|
-
return false;
|
|
531
|
-
}
|
|
532
|
-
const stored = this._prepareForStorage(tool);
|
|
533
|
-
this._stampDefTokens(stored);
|
|
534
|
-
this.tools.set(tool.name, { tool: stored, owner });
|
|
535
|
-
this._version++;
|
|
536
|
-
return true;
|
|
537
|
-
}
|
|
538
|
-
/**
|
|
539
|
-
* Bulk-register multiple tools at once. Each tool that conflicts with an
|
|
540
|
-
* existing registration is silently skipped — use `registerAllOrThrow`
|
|
541
|
-
* if you want it to throw on conflicts.
|
|
542
|
-
*/
|
|
543
|
-
registerAll(tools, owner = "core") {
|
|
544
|
-
for (const tool of tools) this.tryRegister(tool, owner);
|
|
545
|
-
}
|
|
546
|
-
/**
|
|
547
|
-
* Bulk-register and throw on the first conflict. Use when you need
|
|
548
|
-
* strict registration (e.g. at boot time).
|
|
549
|
-
*/
|
|
550
|
-
registerAllOrThrow(tools, owner = "core") {
|
|
551
|
-
for (const tool of tools) this.register(tool, owner);
|
|
552
|
-
}
|
|
553
|
-
/**
|
|
554
|
-
* Register a tool as a default. If the tool name is already registered,
|
|
555
|
-
* this is a no-op — the existing registration (from core or another
|
|
556
|
-
* plugin) takes precedence. Use `override` to intentionally replace.
|
|
557
|
-
*/
|
|
558
|
-
registerDefault(tool, owner = "core") {
|
|
559
|
-
if (this.tools.has(tool.name)) return;
|
|
560
|
-
const stored = this._prepareForStorage(tool);
|
|
561
|
-
this._stampDefTokens(stored);
|
|
562
|
-
this.tools.set(tool.name, { tool: stored, owner });
|
|
563
|
-
this._version++;
|
|
564
|
-
}
|
|
565
|
-
unregister(name) {
|
|
566
|
-
const deleted = this.tools.delete(name);
|
|
567
|
-
if (deleted) this._version++;
|
|
568
|
-
return deleted;
|
|
569
|
-
}
|
|
570
|
-
/**
|
|
571
|
-
* Override an existing tool. Throws if the tool is not already registered.
|
|
572
|
-
* Plugins use this to replace built-in tools with custom implementations.
|
|
573
|
-
*/
|
|
574
|
-
override(name, tool, owner = "core") {
|
|
575
|
-
if (!this.tools.has(name)) {
|
|
576
|
-
throw new WrongStackError({
|
|
577
|
-
message: `Tool "${name}" not registered; cannot override`,
|
|
578
|
-
code: ERROR_CODES.REGISTRY_NOT_FOUND,
|
|
579
|
-
subsystem: "container",
|
|
580
|
-
context: { tool: name }
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
const stored = this._prepareForStorage(tool);
|
|
584
|
-
this._stampDefTokens(stored);
|
|
585
|
-
this.tools.set(name, { tool: stored, owner });
|
|
586
|
-
this._version++;
|
|
587
|
-
}
|
|
588
|
-
/**
|
|
589
|
-
* Wrap (decorate) an existing tool. The wrapper receives the current
|
|
590
|
-
* tool and must return a new tool — typically the same tool with a
|
|
591
|
-
* wrapped `execute` or `executeStream`. Throws if the tool is not
|
|
592
|
-
* registered.
|
|
593
|
-
*
|
|
594
|
-
* Multiple wraps stack: each wrapper gets the output of the previous.
|
|
595
|
-
*
|
|
596
|
-
* @example
|
|
597
|
-
* registry.wrap('bash', (t) => ({ ...t, permission: 'confirm' }));
|
|
598
|
-
*/
|
|
599
|
-
wrap(name, wrapper, owner = "core") {
|
|
600
|
-
const entry = this.tools.get(name);
|
|
601
|
-
if (!entry) {
|
|
602
|
-
throw new WrongStackError({
|
|
603
|
-
message: `Tool "${name}" not registered; cannot wrap`,
|
|
604
|
-
code: ERROR_CODES.REGISTRY_NOT_FOUND,
|
|
605
|
-
subsystem: "container",
|
|
606
|
-
context: { tool: name }
|
|
607
|
-
});
|
|
608
|
-
}
|
|
609
|
-
const current = applyToolDescriptionModeToTool(entry.tool, "extend");
|
|
610
|
-
const wrapped = this._prepareForStorage(wrapper(current));
|
|
611
|
-
wrapped._estDefTokens = void 0;
|
|
612
|
-
this._stampDefTokens(wrapped);
|
|
613
|
-
this.tools.set(name, { tool: wrapped, owner: `${entry.owner}+${owner}` });
|
|
614
|
-
this._version++;
|
|
615
|
-
}
|
|
616
|
-
setDescriptionMode(name, mode) {
|
|
617
|
-
const normalized = normalizeToolDescriptionMode(mode);
|
|
618
|
-
if (!normalized) return false;
|
|
619
|
-
const entry = this.tools.get(name);
|
|
620
|
-
if (!entry) return false;
|
|
621
|
-
if (normalized === "extend") {
|
|
622
|
-
this.descriptionModes.delete(name);
|
|
623
|
-
} else {
|
|
624
|
-
this.descriptionModes.set(name, normalized);
|
|
625
|
-
}
|
|
626
|
-
const stored = applyToolDescriptionModeToTool(entry.tool, normalized);
|
|
627
|
-
stored._estDefTokens = void 0;
|
|
628
|
-
this._stampDefTokens(stored);
|
|
629
|
-
this.tools.set(name, { ...entry, tool: stored });
|
|
630
|
-
this._version++;
|
|
631
|
-
return true;
|
|
632
|
-
}
|
|
633
|
-
getDescriptionMode(name) {
|
|
634
|
-
return this.descriptionModes.get(name) ?? "extend";
|
|
635
|
-
}
|
|
636
|
-
applyDescriptionModes(modes = {}) {
|
|
637
|
-
const missing = [];
|
|
638
|
-
let applied = 0;
|
|
639
|
-
for (const [name, rawMode] of Object.entries(modes)) {
|
|
640
|
-
const mode = normalizeToolDescriptionMode(rawMode);
|
|
641
|
-
if (!mode) continue;
|
|
642
|
-
if (this.tools.has(name)) {
|
|
643
|
-
if (this.setDescriptionMode(name, mode)) applied++;
|
|
644
|
-
} else {
|
|
645
|
-
if (mode === "simple") this.descriptionModes.set(name, mode);
|
|
646
|
-
else this.descriptionModes.delete(name);
|
|
647
|
-
missing.push(name);
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
return { applied, missing };
|
|
651
|
-
}
|
|
652
|
-
get(name) {
|
|
653
|
-
if (this._disabled.has(name)) return void 0;
|
|
654
|
-
return this.tools.get(name)?.tool;
|
|
655
|
-
}
|
|
656
|
-
ownerOf(name) {
|
|
657
|
-
return this.tools.get(name)?.owner;
|
|
658
|
-
}
|
|
659
|
-
// ── Disable / enable ────────────────────────────────────────────
|
|
660
|
-
/**
|
|
661
|
-
* Disable a tool by name. The tool is removed from all public accessors
|
|
662
|
-
* (list(), get(), listByCategory(), listWithOwner()) so it does NOT
|
|
663
|
-
* appear in the system prompt or provider request. The underlying
|
|
664
|
-
* registration is preserved in memory — use `enable()` to restore it.
|
|
665
|
-
*
|
|
666
|
-
* @returns `true` if the tool was found and disabled; `false` if the
|
|
667
|
-
* tool is not registered or is already disabled.
|
|
668
|
-
*/
|
|
669
|
-
disable(name) {
|
|
670
|
-
if (!this.tools.has(name) || this._disabled.has(name)) return false;
|
|
671
|
-
this._disabled.add(name);
|
|
672
|
-
this._version++;
|
|
673
|
-
return true;
|
|
674
|
-
}
|
|
675
|
-
/**
|
|
676
|
-
* Re-enable a previously disabled tool. The tool reappears in all
|
|
677
|
-
* public accessors and will be included in the next system prompt /
|
|
678
|
-
* provider request.
|
|
679
|
-
*
|
|
680
|
-
* @returns `true` if the tool was disabled and is now re-enabled;
|
|
681
|
-
* `false` if the tool was not disabled.
|
|
682
|
-
*/
|
|
683
|
-
enable(name) {
|
|
684
|
-
if (!this._disabled.has(name)) return false;
|
|
685
|
-
this._disabled.delete(name);
|
|
686
|
-
this._version++;
|
|
687
|
-
return true;
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
* Re-enable ALL currently disabled tools at once. Returns the number
|
|
691
|
-
* of tools that were re-enabled.
|
|
692
|
-
*/
|
|
693
|
-
enableAll() {
|
|
694
|
-
const count = this._disabled.size;
|
|
695
|
-
if (count === 0) return 0;
|
|
696
|
-
this._disabled.clear();
|
|
697
|
-
this._version++;
|
|
698
|
-
return count;
|
|
699
|
-
}
|
|
700
|
-
/**
|
|
701
|
-
* Check whether a tool is currently disabled.
|
|
702
|
-
*/
|
|
703
|
-
isDisabled(name) {
|
|
704
|
-
return this._disabled.has(name);
|
|
705
|
-
}
|
|
706
|
-
/**
|
|
707
|
-
* Apply a list of tool names to disable. Tools not in the registry
|
|
708
|
-
* are silently ignored so config can reference future tools without
|
|
709
|
-
* error. Returns the number of tools actually disabled.
|
|
710
|
-
*/
|
|
711
|
-
applyDisabled(names) {
|
|
712
|
-
let count = 0;
|
|
713
|
-
for (const name of names) {
|
|
714
|
-
if (this.disable(name)) count++;
|
|
715
|
-
}
|
|
716
|
-
return count;
|
|
717
|
-
}
|
|
718
|
-
/**
|
|
719
|
-
* Return the list of all disabled tool entries (tool + owner). Useful
|
|
720
|
-
* for the /tools slash command to show disabled tools alongside
|
|
721
|
-
* enabled ones.
|
|
722
|
-
*/
|
|
723
|
-
listDisabled() {
|
|
724
|
-
return Array.from(this._disabled).map((name) => {
|
|
725
|
-
const entry = this.tools.get(name);
|
|
726
|
-
return entry ? { tool: entry.tool, owner: entry.owner } : null;
|
|
727
|
-
}).filter((e) => e !== null);
|
|
728
|
-
}
|
|
729
|
-
list() {
|
|
730
|
-
if (this._listSnapshot && this._version === this._listSnapshotVersion) {
|
|
731
|
-
return this._listSnapshot;
|
|
732
|
-
}
|
|
733
|
-
const arr = Array.from(this.tools.entries()).filter(([name]) => !this._disabled.has(name)).map(([, entry]) => entry.tool);
|
|
734
|
-
this._listSnapshot = arr;
|
|
735
|
-
this._listSnapshotVersion = this._version;
|
|
736
|
-
return arr;
|
|
737
|
-
}
|
|
738
|
-
/** Replace the direct provider surface. Pass `undefined` to expose the catalog. */
|
|
739
|
-
setProviderToolNames(names) {
|
|
740
|
-
this._providerToolNames = names ? new Set(names) : void 0;
|
|
741
|
-
this._version++;
|
|
742
|
-
}
|
|
743
|
-
/** Add registered or future tool names to the direct provider surface. */
|
|
744
|
-
exposeToProvider(names) {
|
|
745
|
-
if (!this._providerToolNames) return;
|
|
746
|
-
for (const name of typeof names === "string" ? [names] : names) {
|
|
747
|
-
this._providerToolNames.add(name);
|
|
748
|
-
}
|
|
749
|
-
this._version++;
|
|
750
|
-
}
|
|
751
|
-
/** Tools serialized into provider requests and described by the system prompt. */
|
|
752
|
-
listForProvider() {
|
|
753
|
-
if (!this._providerToolNames) return this.list();
|
|
754
|
-
if (this._providerListSnapshot && this._version === this._providerListSnapshotVersion) {
|
|
755
|
-
return this._providerListSnapshot;
|
|
756
|
-
}
|
|
757
|
-
const arr = Array.from(this.tools.entries()).filter(([name]) => !this._disabled.has(name) && this._providerToolNames?.has(name) === true).map(([, entry]) => entry.tool);
|
|
758
|
-
this._providerListSnapshot = arr;
|
|
759
|
-
this._providerListSnapshotVersion = this._version;
|
|
760
|
-
return arr;
|
|
761
|
-
}
|
|
762
|
-
/**
|
|
763
|
-
* Whether an enabled catalog tool is part of the direct provider surface.
|
|
764
|
-
*
|
|
765
|
-
* This is intentionally different from `get()`/`list()`: a tool can remain
|
|
766
|
-
* executable through a lazy gateway while its schema is omitted from the
|
|
767
|
-
* next provider request. Disabled and unknown tools always return false.
|
|
768
|
-
*/
|
|
769
|
-
isExposedToProvider(name) {
|
|
770
|
-
if (this._disabled.has(name) || !this.tools.has(name)) return false;
|
|
771
|
-
return this._providerToolNames?.has(name) ?? true;
|
|
772
|
-
}
|
|
773
|
-
/**
|
|
774
|
-
* Group tools by their `category` field. Tools without a category
|
|
775
|
-
* are placed under the key `""` (empty string). Returns a Map of
|
|
776
|
-
* category → tools, sorted by registration order within each category.
|
|
777
|
-
*/
|
|
778
|
-
listByCategory() {
|
|
779
|
-
const map = /* @__PURE__ */ new Map();
|
|
780
|
-
for (const [name, { tool }] of this.tools) {
|
|
781
|
-
if (this._disabled.has(name)) continue;
|
|
782
|
-
const cat = tool.category ?? "";
|
|
783
|
-
let group = map.get(cat);
|
|
784
|
-
if (!group) {
|
|
785
|
-
group = [];
|
|
786
|
-
map.set(cat, group);
|
|
787
|
-
}
|
|
788
|
-
group.push(tool);
|
|
789
|
-
}
|
|
790
|
-
return map;
|
|
791
|
-
}
|
|
792
|
-
listWithOwner() {
|
|
793
|
-
return Array.from(this.tools.entries()).filter(([name]) => !this._disabled.has(name)).map(([, entry]) => entry);
|
|
794
|
-
}
|
|
795
|
-
clear() {
|
|
796
|
-
this.tools.clear();
|
|
797
|
-
this.descriptionModes.clear();
|
|
798
|
-
this._disabled.clear();
|
|
799
|
-
this._providerToolNames = void 0;
|
|
800
|
-
this._version++;
|
|
801
|
-
}
|
|
802
|
-
/**
|
|
803
|
-
* Return a new ToolRegistry with the same registered tools and owners.
|
|
804
|
-
* Useful for creating filtered copies in multi-agent scenarios.
|
|
805
|
-
*/
|
|
806
|
-
clone() {
|
|
807
|
-
const copy = new _ToolRegistry();
|
|
808
|
-
copy.descriptionModes.clear();
|
|
809
|
-
for (const [name, mode] of this.descriptionModes) {
|
|
810
|
-
copy.descriptionModes.set(name, mode);
|
|
811
|
-
}
|
|
812
|
-
for (const [name, { tool, owner }] of this.tools) {
|
|
813
|
-
copy.tools.set(name, { tool, owner });
|
|
814
|
-
}
|
|
815
|
-
for (const name of this._disabled) {
|
|
816
|
-
copy._disabled.add(name);
|
|
817
|
-
}
|
|
818
|
-
copy._providerToolNames = this._providerToolNames ? new Set(this._providerToolNames) : void 0;
|
|
819
|
-
copy._version = this._version;
|
|
820
|
-
return copy;
|
|
821
|
-
}
|
|
822
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
ProviderRegistry,
|
|
3
|
+
SlashCommandRegistry,
|
|
4
|
+
ToolRegistry
|
|
5
|
+
} from "../chunk-KI4L2DUL.js";
|
|
6
|
+
import "../chunk-WQTOVMGV.js";
|
|
7
|
+
import "../chunk-FSWCWSTS.js";
|
|
8
|
+
import "../chunk-WOEZV3Q4.js";
|
|
9
|
+
import "../chunk-TBRL2RCC.js";
|
|
823
10
|
export {
|
|
824
11
|
ProviderRegistry,
|
|
825
12
|
SlashCommandRegistry,
|