@ai-sdk/harness-opencode 1.0.11 → 1.0.13
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/CHANGELOG.md +18 -0
- package/dist/bridge/index.mjs +60 -0
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.js +20 -78
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/bridge/index.ts +90 -2
- package/src/opencode-harness.ts +19 -85
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @ai-sdk/harness-opencode
|
|
2
2
|
|
|
3
|
+
## 1.0.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [8c616f0]
|
|
8
|
+
- @ai-sdk/provider-utils@5.0.3
|
|
9
|
+
- @ai-sdk/harness@1.0.13
|
|
10
|
+
|
|
11
|
+
## 1.0.12
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 7859cea: feat(harness): add tool filtering via `activeTools` and `inactiveTools`
|
|
16
|
+
- c857346: feat(harness): add utility functions for certain duplicated layers in harnesses
|
|
17
|
+
- Updated dependencies [7859cea]
|
|
18
|
+
- Updated dependencies [c857346]
|
|
19
|
+
- @ai-sdk/harness@1.0.12
|
|
20
|
+
|
|
3
21
|
## 1.0.11
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/bridge/index.mjs
CHANGED
|
@@ -736,6 +736,19 @@ var OPENCODE_TO_WIRE = {
|
|
|
736
736
|
agent: "agent",
|
|
737
737
|
subtask: "agent"
|
|
738
738
|
};
|
|
739
|
+
var PUBLIC_TO_NATIVE = {
|
|
740
|
+
read: "view",
|
|
741
|
+
write: "write",
|
|
742
|
+
edit: "edit",
|
|
743
|
+
bash: "bash",
|
|
744
|
+
glob: "glob",
|
|
745
|
+
grep: "grep",
|
|
746
|
+
ls: "list",
|
|
747
|
+
webfetch: "webfetch",
|
|
748
|
+
skill: "skill",
|
|
749
|
+
todowrite: "todowrite",
|
|
750
|
+
agent: "agent"
|
|
751
|
+
};
|
|
739
752
|
var TOOL_KIND = {
|
|
740
753
|
read: "readonly",
|
|
741
754
|
glob: "readonly",
|
|
@@ -837,6 +850,18 @@ function buildOpenCodeConfig({
|
|
|
837
850
|
};
|
|
838
851
|
if (start.model) config.model = start.model;
|
|
839
852
|
if (skillsDir) config.skills = { paths: [skillsDir] };
|
|
853
|
+
const inactiveToolNames = resolveInactiveBuiltinToolNames(start);
|
|
854
|
+
const permission = config.permission;
|
|
855
|
+
for (const toolName of inactiveToolNames) {
|
|
856
|
+
const permissionName = toPermissionToolName(
|
|
857
|
+
PUBLIC_TO_NATIVE[toolName] ?? toolName
|
|
858
|
+
);
|
|
859
|
+
if (permissionName === "ls") {
|
|
860
|
+
permission.list = "ask";
|
|
861
|
+
} else {
|
|
862
|
+
permission[permissionName] = "ask";
|
|
863
|
+
}
|
|
864
|
+
}
|
|
840
865
|
const provider = buildProviderConfig(start);
|
|
841
866
|
if (provider) config.provider = provider;
|
|
842
867
|
if (relayPort && start.tools && start.tools.length > 0) {
|
|
@@ -1063,6 +1088,7 @@ async function runPrompt({
|
|
|
1063
1088
|
client,
|
|
1064
1089
|
sessionId,
|
|
1065
1090
|
permissionMode: start.permissionMode,
|
|
1091
|
+
builtinToolFiltering: start.builtinToolFiltering,
|
|
1066
1092
|
turn,
|
|
1067
1093
|
emit: (msg) => {
|
|
1068
1094
|
if (msg.type === "text-delta" || msg.type === "reasoning-delta") {
|
|
@@ -1176,6 +1202,7 @@ async function runCompaction({
|
|
|
1176
1202
|
client,
|
|
1177
1203
|
sessionId,
|
|
1178
1204
|
permissionMode: start.permissionMode,
|
|
1205
|
+
builtinToolFiltering: start.builtinToolFiltering,
|
|
1179
1206
|
turn,
|
|
1180
1207
|
emit: (msg) => {
|
|
1181
1208
|
if (msg.type === "compaction") sawCompaction = true;
|
|
@@ -1237,6 +1264,7 @@ async function consumeEvents({
|
|
|
1237
1264
|
client,
|
|
1238
1265
|
sessionId,
|
|
1239
1266
|
permissionMode,
|
|
1267
|
+
builtinToolFiltering,
|
|
1240
1268
|
turn,
|
|
1241
1269
|
emit,
|
|
1242
1270
|
signal,
|
|
@@ -1255,6 +1283,7 @@ async function consumeEvents({
|
|
|
1255
1283
|
state,
|
|
1256
1284
|
sessionId,
|
|
1257
1285
|
permissionMode,
|
|
1286
|
+
builtinToolFiltering,
|
|
1258
1287
|
client,
|
|
1259
1288
|
turn,
|
|
1260
1289
|
emit
|
|
@@ -1283,6 +1312,7 @@ async function translateAndEmit({
|
|
|
1283
1312
|
state,
|
|
1284
1313
|
sessionId,
|
|
1285
1314
|
permissionMode,
|
|
1315
|
+
builtinToolFiltering,
|
|
1286
1316
|
client,
|
|
1287
1317
|
turn,
|
|
1288
1318
|
emit
|
|
@@ -1520,6 +1550,7 @@ async function translateAndEmit({
|
|
|
1520
1550
|
client,
|
|
1521
1551
|
sessionId,
|
|
1522
1552
|
permissionMode,
|
|
1553
|
+
builtinToolFiltering,
|
|
1523
1554
|
turn,
|
|
1524
1555
|
emit,
|
|
1525
1556
|
event
|
|
@@ -1531,6 +1562,7 @@ async function translateAndEmit({
|
|
|
1531
1562
|
client,
|
|
1532
1563
|
sessionId,
|
|
1533
1564
|
permissionMode,
|
|
1565
|
+
builtinToolFiltering,
|
|
1534
1566
|
turn,
|
|
1535
1567
|
emit,
|
|
1536
1568
|
event
|
|
@@ -1698,6 +1730,7 @@ async function handlePermissionV2({
|
|
|
1698
1730
|
client,
|
|
1699
1731
|
sessionId,
|
|
1700
1732
|
permissionMode,
|
|
1733
|
+
builtinToolFiltering,
|
|
1701
1734
|
turn,
|
|
1702
1735
|
emit,
|
|
1703
1736
|
event
|
|
@@ -1711,6 +1744,7 @@ async function handlePermissionV2({
|
|
|
1711
1744
|
requestID,
|
|
1712
1745
|
toolCallId: typeof props.source === "object" && props.source !== null && "callID" in props.source ? String(props.source.callID) : requestID,
|
|
1713
1746
|
permissionMode,
|
|
1747
|
+
builtinToolFiltering,
|
|
1714
1748
|
turn,
|
|
1715
1749
|
emit
|
|
1716
1750
|
});
|
|
@@ -1725,6 +1759,7 @@ async function handlePermission({
|
|
|
1725
1759
|
client,
|
|
1726
1760
|
sessionId,
|
|
1727
1761
|
permissionMode,
|
|
1762
|
+
builtinToolFiltering,
|
|
1728
1763
|
turn,
|
|
1729
1764
|
emit,
|
|
1730
1765
|
event
|
|
@@ -1738,6 +1773,7 @@ async function handlePermission({
|
|
|
1738
1773
|
requestID,
|
|
1739
1774
|
toolCallId: typeof props.tool === "object" && props.tool !== null && "callID" in props.tool ? String(props.tool.callID) : requestID,
|
|
1740
1775
|
permissionMode,
|
|
1776
|
+
builtinToolFiltering,
|
|
1741
1777
|
turn,
|
|
1742
1778
|
emit
|
|
1743
1779
|
});
|
|
@@ -1755,6 +1791,7 @@ async function selectPermissionReply({
|
|
|
1755
1791
|
requestID,
|
|
1756
1792
|
toolCallId,
|
|
1757
1793
|
permissionMode,
|
|
1794
|
+
builtinToolFiltering,
|
|
1758
1795
|
turn,
|
|
1759
1796
|
emit
|
|
1760
1797
|
}) {
|
|
@@ -1762,6 +1799,18 @@ async function selectPermissionReply({
|
|
|
1762
1799
|
if (resources.some((resource) => isExternalPath(resource))) {
|
|
1763
1800
|
return { reply: "reject", message: "External directory access rejected." };
|
|
1764
1801
|
}
|
|
1802
|
+
if (isBuiltinToolInactive({ toolName, toolFiltering: builtinToolFiltering })) {
|
|
1803
|
+
emit({
|
|
1804
|
+
type: "tool-approval-request",
|
|
1805
|
+
approvalId: requestID,
|
|
1806
|
+
toolCallId
|
|
1807
|
+
});
|
|
1808
|
+
const decision2 = await turn.requestToolApproval(requestID);
|
|
1809
|
+
return decision2.approved ? { reply: "once" } : {
|
|
1810
|
+
reply: "reject",
|
|
1811
|
+
...decision2.reason ? { message: decision2.reason } : {}
|
|
1812
|
+
};
|
|
1813
|
+
}
|
|
1765
1814
|
if (!permissionMode || permissionMode === "allow-all") {
|
|
1766
1815
|
return { reply: "always" };
|
|
1767
1816
|
}
|
|
@@ -1794,6 +1843,17 @@ function toPermissionToolName(action) {
|
|
|
1794
1843
|
if (normalized.includes("read")) return "read";
|
|
1795
1844
|
return toWireToolName(normalized);
|
|
1796
1845
|
}
|
|
1846
|
+
function resolveInactiveBuiltinToolNames(start) {
|
|
1847
|
+
const toolFiltering = start.builtinToolFiltering;
|
|
1848
|
+
if (toolFiltering == null) return [];
|
|
1849
|
+
return toolFiltering.mode === "allow" ? Object.keys(PUBLIC_TO_NATIVE).filter(
|
|
1850
|
+
(name) => !toolFiltering.toolNames.includes(name)
|
|
1851
|
+
) : toolFiltering.toolNames;
|
|
1852
|
+
}
|
|
1853
|
+
function isBuiltinToolInactive(input) {
|
|
1854
|
+
if (input.toolFiltering == null) return false;
|
|
1855
|
+
return input.toolFiltering.mode === "allow" ? !input.toolFiltering.toolNames.includes(input.toolName) : input.toolFiltering.toolNames.includes(input.toolName);
|
|
1856
|
+
}
|
|
1797
1857
|
function isExternalPath(resource) {
|
|
1798
1858
|
if (!path2.isAbsolute(resource)) return false;
|
|
1799
1859
|
const normalized = path2.resolve(resource);
|