@opencode-ai/codemode 0.0.0-beta-18414 → 0.0.0-beta-18593

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 CHANGED
@@ -139,8 +139,8 @@ Diagnostic kinds:
139
139
  | `ExecutionFailure` | The program threw or another execution error occurred. |
140
140
  | `Truncated` | Warning only: additional warnings were omitted by `maxOutputBytes`. |
141
141
 
142
- Unknown host failures, defects, and invalid outputs are sanitized. `toolError("safe message")` explicitly exposes a
143
- safe refusal to the model; its optional cause remains private.
142
+ Host failures and defects report their messages and underlying causes. Invalid outputs include the validation or
143
+ copying error. Interruption propagates without becoming an error diagnostic.
144
144
 
145
145
  ## Discovery
146
146
 
@@ -3,9 +3,9 @@ declare const ToolError_base: Schema.Class<ToolError, Schema.TaggedStruct<"ToolE
3
3
  readonly message: Schema.String;
4
4
  readonly cause: Schema.optionalKey<Schema.Defect>;
5
5
  }>, import("effect/Cause").YieldableError>;
6
- /** Safe operational refusal from a standard tool pack, reported as `ToolFailure`. */
6
+ /** Tool failure reported as `ToolFailure`. */
7
7
  export declare class ToolError extends ToolError_base {
8
8
  }
9
- /** Creates a tool refusal whose message is safe to include in an execution diagnostic. */
9
+ /** Creates a tool failure with an optional underlying cause. */
10
10
  export declare const toolError: (message: string, cause?: unknown) => ToolError;
11
11
  export {};
@@ -1,9 +1,9 @@
1
1
  import { Schema } from "effect";
2
- /** Safe operational refusal from a standard tool pack, reported as `ToolFailure`. */
2
+ /** Tool failure reported as `ToolFailure`. */
3
3
  export class ToolError extends Schema.TaggedError()("ToolError", {
4
4
  message: Schema.String,
5
5
  cause: Schema.optionalKey(Schema.Defect()),
6
6
  }) {
7
7
  }
8
- /** Creates a tool refusal whose message is safe to include in an execution diagnostic. */
8
+ /** Creates a tool failure with an optional underlying cause. */
9
9
  export const toolError = (message, cause) => new ToolError({ message, ...(cause === undefined ? {} : { cause }) });
@@ -1,5 +1,5 @@
1
- import { Cause, Effect, Exit, Schema } from "effect";
2
- import { ToolError, toolError } from "./tool-error.js";
1
+ import { Cause, Effect, Exit, Formatter, Schema } from "effect";
2
+ import { toolError } from "./tool-error.js";
3
3
  import { decodeInput as decodeToolInput, decodeOutput as decodeToolOutput, identifierSegment, inputProperties, inputTypeScript, outputTypeScript, } from "./tool-schema.js";
4
4
  import { isTool } from "./tool.js";
5
5
  import { CodeModeDate, CodeModeMap, CodeModePromise, CodeModeRegExp, CodeModeSet, CodeModeURL, CodeModeURLSearchParams, } from "./values.js";
@@ -45,12 +45,6 @@ export class ToolRuntimeError extends Error {
45
45
  this.name = "ToolRuntimeError";
46
46
  }
47
47
  }
48
- const runHost = (effect) => effect.pipe(Effect.catchCause((cause) => {
49
- if (Cause.hasInterruptsOnly(cause))
50
- return Effect.interrupt;
51
- const error = Cause.squash(cause);
52
- return Effect.fail(error instanceof ToolError ? error : toolError("Tool execution failed", error));
53
- }));
54
48
  const blockedMemberNames = new Set(["__proto__", "constructor", "prototype"]);
55
49
  export const isBlockedMember = (name) => blockedMemberNames.has(name);
56
50
  // Checkpoint mode preserves CodeMode values; boundary mode JSON-normalizes them.
@@ -337,14 +331,10 @@ export const make = (tools, maxToolCalls, searchIndex, hooks) => {
337
331
  if (Cause.hasInterruptsOnly(exit.cause))
338
332
  return onEnd({ ...call, durationMs, outcome: "interrupted" });
339
333
  const error = Cause.squash(exit.cause);
340
- const message = error instanceof ToolError || error instanceof ToolRuntimeError ? error.message : "Tool execution failed";
334
+ const message = error instanceof Error ? error.message : Cause.pretty(exit.cause);
341
335
  return onEnd({ ...call, durationMs, outcome: "failure", message });
342
336
  }));
343
337
  };
344
- const decodeOutput = (value, name) => Effect.try({
345
- try: () => copyIn(value, `Result from tool '${name}'`),
346
- catch: () => new ToolRuntimeError("InvalidToolOutput", `Invalid output from tool '${name}'.`),
347
- });
348
338
  const recordCall = (call) => {
349
339
  if (maxToolCalls !== undefined && calls.length >= maxToolCalls) {
350
340
  throw new ToolRuntimeError("ToolCallLimitExceeded", `Execution exceeded its tool-call limit of ${maxToolCalls}.`);
@@ -366,12 +356,17 @@ export const make = (tools, maxToolCalls, searchIndex, hooks) => {
366
356
  return yield* observeEnd(Effect.gen(function* () {
367
357
  if (hooks?.onToolCallStart !== undefined)
368
358
  yield* hooks.onToolCallStart(call);
369
- const raw = yield* runHost(Effect.suspend(() => tool.execute(input)));
370
- const result = yield* Effect.try({
371
- try: () => decodeToolOutput(tool, raw),
372
- catch: () => new ToolRuntimeError("InvalidToolOutput", `Invalid output from tool '${name}'.`),
359
+ const raw = yield* Effect.suspend(() => tool.execute(input)).pipe(Effect.catchCause((cause) => {
360
+ if (Cause.hasInterruptsOnly(cause))
361
+ return Effect.interrupt;
362
+ return Effect.fail(toolError(Cause.prettyErrors(cause)
363
+ .map((error) => (error.cause ? Formatter.format(error) : error.message || error.name))
364
+ .join("\n")));
365
+ }));
366
+ return yield* Effect.try({
367
+ try: () => copyIn(decodeToolOutput(tool, raw), `Result from tool '${name}'`),
368
+ catch: (cause) => new ToolRuntimeError("InvalidToolOutput", `Invalid output from tool '${name}': ${cause}`),
373
369
  });
374
- return yield* decodeOutput(result, name);
375
370
  }), call);
376
371
  });
377
372
  return {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@opencode-ai/codemode",
4
- "version": "0.0.0-beta-18414",
4
+ "version": "0.0.0-beta-18593",
5
5
  "description": "Effect-native confined code execution over schema-described tools",
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "acorn": "8.15.0",
38
- "effect": "4.0.0-rc.111",
38
+ "effect": "4.0.0-rc.112",
39
39
  "typescript": "5.8.2"
40
40
  },
41
41
  "devDependencies": {