@ai-sdk/harness-opencode 1.0.123 → 1.0.125
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 +21 -0
- package/dist/bridge/host-tool-mcp.mjs +1 -1
- package/dist/bridge/host-tool-mcp.mjs.map +1 -1
- package/dist/bridge/index.mjs +6 -13
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.js +11 -13
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/bridge/create-emit-stream-event.ts +5 -5
- package/src/bridge/index.ts +1 -7
- package/src/bridge/json-schema-to-zod.ts +1 -1
- package/src/bridge/opencode-events.ts +0 -1
- package/src/opencode-harness.ts +13 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @ai-sdk/harness-opencode
|
|
2
2
|
|
|
3
|
+
## 1.0.125
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9c8c0c1: feat (harness): keep harness-generated state out of the sandbox workspace. The framework and every bridge adapter now resolve their generated state — bootstrap recipes and their dependencies (`.harness-bootstrap/…`) and per-session run state (`.agent-runs/…`) — through the new `harnessV1StateDirectory()` helper, which always resolves to a fixed directory (`~/.ai-sdk-harness`) under the sandbox's own HOME, never the sandbox's working directory. This is not configurable: every sandbox provider gets the same layout, so harness infrastructure never lands in a user-owned workspace. This changes the on-disk layout for every provider (a breaking change, acceptable given the experimental nature of this API) — sandboxes bootstrapped under the previous layout re-bootstrap once under the new path.
|
|
8
|
+
- 771e74b: chore: enable dead code lint rules
|
|
9
|
+
- Updated dependencies [fe07867]
|
|
10
|
+
- Updated dependencies [a4b0940]
|
|
11
|
+
- Updated dependencies [9c8c0c1]
|
|
12
|
+
- Updated dependencies [771e74b]
|
|
13
|
+
- Updated dependencies [7115a3f]
|
|
14
|
+
- @ai-sdk/provider-utils@5.0.47
|
|
15
|
+
- @ai-sdk/harness@1.0.123
|
|
16
|
+
|
|
17
|
+
## 1.0.124
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- @ai-sdk/harness@1.0.122
|
|
22
|
+
- @ai-sdk/provider-utils@5.0.46
|
|
23
|
+
|
|
3
24
|
## 1.0.123
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
|
@@ -12,7 +12,7 @@ function jsonSchemaToZodShape(input) {
|
|
|
12
12
|
}
|
|
13
13
|
function toZodShape(schema) {
|
|
14
14
|
if (!schema?.properties) return {};
|
|
15
|
-
const required = new Set(schema.required
|
|
15
|
+
const required = new Set(schema.required);
|
|
16
16
|
const shape = {};
|
|
17
17
|
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
18
18
|
const propType = toZodType(propSchema);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bridge/host-tool-mcp.ts","../../src/bridge/json-schema-to-zod.ts"],"sourcesContent":["#!/usr/bin/env node\n/*\n * These bridge imports are externalized by tsup and resolved inside the\n * sandbox from src/bridge/package.json and its lockfile. Keep this file,\n * tsup.config.ts, and the bridge package dependency list in sync.\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { jsonSchemaToZodShape } from './json-schema-to-zod';\n\ntype ToolSchema = {\n name: string;\n description?: string;\n inputSchema?: unknown;\n};\n\nconst schemas: ToolSchema[] = JSON.parse(process.env.TOOL_SCHEMAS || '[]');\nconst relayUrl = process.env.TOOL_RELAY_URL || '';\n\nif (!schemas.length || !relayUrl) {\n process.stderr.write(\n '[host-tool-mcp] Missing TOOL_SCHEMAS or TOOL_RELAY_URL; exiting\\n',\n );\n process.exit(0);\n}\n\nconst server = new McpServer({ name: 'harness-tools', version: '1.0.0' });\n\nfor (const schema of schemas) {\n const shape = jsonSchemaToZodShape(schema.inputSchema);\n server.tool(\n schema.name,\n schema.description ?? '',\n shape,\n async (input: Record<string, unknown>) => {\n const requestId = crypto.randomUUID();\n try {\n const res = await fetch(relayUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ requestId, toolName: schema.name, input }),\n });\n if (!res.ok) {\n const body = await res.text();\n throw new Error(\n `Tool relay ${schema.name} failed with ${res.status}: ${body.slice(0, 500)}`,\n );\n }\n const data = (await res.json()) as { result?: unknown };\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(data.result ?? null),\n },\n ],\n };\n } catch (err) {\n return {\n content: [{ type: 'text' as const, text: `Error: ${String(err)}` }],\n isError: true,\n };\n }\n },\n );\n}\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n","import { z } from 'zod/v4';\n\ntype JsonLiteral = string | number | boolean | null;\n\ntype JsonSchemaObject = {\n type?: string | string[];\n description?: string;\n properties?: Record<string, JsonSchemaObject>;\n required?: string[];\n items?: JsonSchemaObject;\n enum?: unknown[];\n default?: unknown;\n nullable?: boolean;\n};\n\ntype ZodShape = Record<string, z.ZodTypeAny>;\n\nexport function jsonSchemaToZodShape(input: unknown): ZodShape {\n const schema = isJsonSchemaObject(input) ? input : {};\n return toZodShape(schema);\n}\n\nfunction toZodShape(schema: JsonSchemaObject | undefined): ZodShape {\n if (!schema?.properties) return {};\n const required = new Set(schema.required
|
|
1
|
+
{"version":3,"sources":["../../src/bridge/host-tool-mcp.ts","../../src/bridge/json-schema-to-zod.ts"],"sourcesContent":["#!/usr/bin/env node\n/*\n * These bridge imports are externalized by tsup and resolved inside the\n * sandbox from src/bridge/package.json and its lockfile. Keep this file,\n * tsup.config.ts, and the bridge package dependency list in sync.\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { jsonSchemaToZodShape } from './json-schema-to-zod';\n\ntype ToolSchema = {\n name: string;\n description?: string;\n inputSchema?: unknown;\n};\n\nconst schemas: ToolSchema[] = JSON.parse(process.env.TOOL_SCHEMAS || '[]');\nconst relayUrl = process.env.TOOL_RELAY_URL || '';\n\nif (!schemas.length || !relayUrl) {\n process.stderr.write(\n '[host-tool-mcp] Missing TOOL_SCHEMAS or TOOL_RELAY_URL; exiting\\n',\n );\n process.exit(0);\n}\n\nconst server = new McpServer({ name: 'harness-tools', version: '1.0.0' });\n\nfor (const schema of schemas) {\n const shape = jsonSchemaToZodShape(schema.inputSchema);\n server.tool(\n schema.name,\n schema.description ?? '',\n shape,\n async (input: Record<string, unknown>) => {\n const requestId = crypto.randomUUID();\n try {\n const res = await fetch(relayUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ requestId, toolName: schema.name, input }),\n });\n if (!res.ok) {\n const body = await res.text();\n throw new Error(\n `Tool relay ${schema.name} failed with ${res.status}: ${body.slice(0, 500)}`,\n );\n }\n const data = (await res.json()) as { result?: unknown };\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(data.result ?? null),\n },\n ],\n };\n } catch (err) {\n return {\n content: [{ type: 'text' as const, text: `Error: ${String(err)}` }],\n isError: true,\n };\n }\n },\n );\n}\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n","import { z } from 'zod/v4';\n\ntype JsonLiteral = string | number | boolean | null;\n\ntype JsonSchemaObject = {\n type?: string | string[];\n description?: string;\n properties?: Record<string, JsonSchemaObject>;\n required?: string[];\n items?: JsonSchemaObject;\n enum?: unknown[];\n default?: unknown;\n nullable?: boolean;\n};\n\ntype ZodShape = Record<string, z.ZodTypeAny>;\n\nexport function jsonSchemaToZodShape(input: unknown): ZodShape {\n const schema = isJsonSchemaObject(input) ? input : {};\n return toZodShape(schema);\n}\n\nfunction toZodShape(schema: JsonSchemaObject | undefined): ZodShape {\n if (!schema?.properties) return {};\n const required = new Set(schema.required);\n const shape: ZodShape = {};\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n const propType = toZodType(propSchema);\n shape[key] = required.has(key) ? propType : propType.optional();\n }\n return shape;\n}\n\nfunction toZodType(schema: JsonSchemaObject | undefined): z.ZodTypeAny {\n if (!schema) return z.any();\n\n let zType = zodForEnum(schema) ?? zodForType(schema);\n if (schema.description) zType = zType.describe(schema.description);\n if (schema.nullable) zType = zType.nullable();\n if ('default' in schema) zType = zType.meta({ default: schema.default });\n return zType;\n}\n\nfunction zodForEnum(schema: JsonSchemaObject): z.ZodTypeAny | undefined {\n if (\n !Array.isArray(schema.enum) ||\n schema.enum.length === 0 ||\n !schema.enum.every(isJsonLiteral)\n ) {\n return undefined;\n }\n return z.literal(schema.enum);\n}\n\nfunction zodForType(schema: JsonSchemaObject): z.ZodTypeAny {\n const types = Array.isArray(schema.type)\n ? schema.type.filter((t): t is string => t !== 'null')\n : ([schema.type].filter(Boolean) as string[]);\n\n switch (types[0]) {\n case 'string':\n return z.string();\n case 'number':\n return z.number();\n case 'integer':\n return z.number().int();\n case 'boolean':\n return z.boolean();\n case 'array':\n return z.array(toZodType(schema.items));\n case 'object':\n return z.object(toZodShape(schema));\n case 'null':\n return z.null();\n default:\n return z.any();\n }\n}\n\nfunction isJsonSchemaObject(input: unknown): input is JsonSchemaObject {\n return input != null && typeof input === 'object' && !Array.isArray(input);\n}\n\nfunction isJsonLiteral(value: unknown): value is JsonLiteral {\n return (\n value === null ||\n typeof value === 'string' ||\n typeof value === 'boolean' ||\n (typeof value === 'number' && Number.isFinite(value))\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/bridge/index.mjs
CHANGED
|
@@ -529,7 +529,6 @@ async function runBridge(options) {
|
|
|
529
529
|
const data = await onStop?.() ?? {};
|
|
530
530
|
sendControl(ws, { type: "bridge-stop", data });
|
|
531
531
|
drainThenExit(ws, 1e3, "stop");
|
|
532
|
-
return;
|
|
533
532
|
}
|
|
534
533
|
}
|
|
535
534
|
};
|
|
@@ -729,7 +728,6 @@ function getOpenCodeEventSessionId(event) {
|
|
|
729
728
|
const part = props.part;
|
|
730
729
|
const partObject = asOpenCodeObject(part);
|
|
731
730
|
if (typeof partObject?.sessionID === "string") return partObject.sessionID;
|
|
732
|
-
return void 0;
|
|
733
731
|
}
|
|
734
732
|
function emitMissingFinalDelta({
|
|
735
733
|
id,
|
|
@@ -1405,8 +1403,8 @@ function emitLegacyToolPart({
|
|
|
1405
1403
|
const toolName = toWireToolName2(rawToolName);
|
|
1406
1404
|
if (toolName === "agent") {
|
|
1407
1405
|
const metadata = {
|
|
1408
|
-
...toolPart.metadata
|
|
1409
|
-
...toolPart.state?.metadata
|
|
1406
|
+
...toolPart.metadata,
|
|
1407
|
+
...toolPart.state?.metadata
|
|
1410
1408
|
};
|
|
1411
1409
|
const parentSessionId = stringValue2(metadata.parentSessionId);
|
|
1412
1410
|
const sessionId = stringValue2(metadata.sessionId);
|
|
@@ -1454,9 +1452,9 @@ function emitLegacyToolPart({
|
|
|
1454
1452
|
}
|
|
1455
1453
|
function legacyToolPartInput(part) {
|
|
1456
1454
|
return {
|
|
1457
|
-
...part.metadata
|
|
1458
|
-
...part.state?.metadata
|
|
1459
|
-
...part.state?.input
|
|
1455
|
+
...part.metadata,
|
|
1456
|
+
...part.state?.metadata,
|
|
1457
|
+
...part.state?.input
|
|
1460
1458
|
};
|
|
1461
1459
|
}
|
|
1462
1460
|
function legacyToolPartOutput(part) {
|
|
@@ -1999,7 +1997,7 @@ function buildOpenCodeConfig({
|
|
|
1999
1997
|
}
|
|
2000
1998
|
const provider = buildProviderConfig(start);
|
|
2001
1999
|
if (provider) config.provider = provider;
|
|
2002
|
-
const mcp = { ...start.mcpServers
|
|
2000
|
+
const mcp = { ...start.mcpServers };
|
|
2003
2001
|
if (relayPort && start.tools && start.tools.length > 0) {
|
|
2004
2002
|
mcp["harness-tools"] = {
|
|
2005
2003
|
type: "local",
|
|
@@ -2107,7 +2105,6 @@ function buildProviderConfig(start) {
|
|
|
2107
2105
|
}
|
|
2108
2106
|
};
|
|
2109
2107
|
}
|
|
2110
|
-
return void 0;
|
|
2111
2108
|
}
|
|
2112
2109
|
function parseOpenAIQueryParams() {
|
|
2113
2110
|
if (!procEnv2.OPENAI_QUERY_PARAMS_JSON) return {};
|
|
@@ -2185,7 +2182,6 @@ function readSessionId(data) {
|
|
|
2185
2182
|
const record = data;
|
|
2186
2183
|
if (typeof record.id === "string") return record.id;
|
|
2187
2184
|
if (typeof record.data?.id === "string") return record.data.id;
|
|
2188
|
-
return void 0;
|
|
2189
2185
|
}
|
|
2190
2186
|
function isAsyncIterable(value) {
|
|
2191
2187
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value;
|
|
@@ -2887,7 +2883,6 @@ function getHostToolName(toolName, rawToolName) {
|
|
|
2887
2883
|
if (typeof rawToolName === "string" && rawToolName.startsWith("harness-tools_") && runtime.toolNames.has(rawToolName.slice("harness-tools_".length))) {
|
|
2888
2884
|
return rawToolName.slice("harness-tools_".length);
|
|
2889
2885
|
}
|
|
2890
|
-
return void 0;
|
|
2891
2886
|
}
|
|
2892
2887
|
function authorizeHostToolCall({
|
|
2893
2888
|
callID,
|
|
@@ -2969,7 +2964,6 @@ function latestLegacyAssistantMessage(data) {
|
|
|
2969
2964
|
};
|
|
2970
2965
|
}
|
|
2971
2966
|
}
|
|
2972
|
-
return void 0;
|
|
2973
2967
|
}
|
|
2974
2968
|
function latestV2AssistantMessage(data) {
|
|
2975
2969
|
const messages = data && typeof data === "object" && Array.isArray(data.data) ? data.data : Array.isArray(data) ? data : [];
|
|
@@ -2983,7 +2977,6 @@ function latestV2AssistantMessage(data) {
|
|
|
2983
2977
|
};
|
|
2984
2978
|
}
|
|
2985
2979
|
}
|
|
2986
|
-
return void 0;
|
|
2987
2980
|
}
|
|
2988
2981
|
function emitAssistantContentPart(part, emit) {
|
|
2989
2982
|
if (!part || typeof part !== "object") return;
|