@codeworksh/harness 0.0.1-dev.20260824191503 → 0.0.1-dev.20260825093030

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/effect.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-B4iAMlE-.mjs";
2
- import { c as harness_exports, r as session_exports, s as sandbox_exports, u as tool_exports } from "./session-DZZfASHn.mjs";
2
+ import { c as harness_exports, h as run_exports, r as session_exports, s as sandbox_exports, u as tool_exports } from "./session-B8PG8cMg.mjs";
3
3
  //#region src/effect/tools.ts
4
4
  var tools_exports = /* @__PURE__ */ __exportAll({
5
5
  Tools: () => tools_exports,
@@ -7,6 +7,6 @@ var tools_exports = /* @__PURE__ */ __exportAll({
7
7
  });
8
8
  const bash = "bash";
9
9
  //#endregion
10
- export { harness_exports as Harness, sandbox_exports as Sandbox, session_exports as Session, tool_exports as Tool, tools_exports as Tools };
10
+ export { harness_exports as Harness, run_exports as Runner, sandbox_exports as Sandbox, session_exports as Session, tool_exports as Tool, tools_exports as Tools };
11
11
 
12
12
  //# sourceMappingURL=effect.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeworksh/harness",
3
- "version": "0.0.1-dev.20260824191503",
3
+ "version": "0.0.1-dev.20260825093030",
4
4
  "description": "AI agent harness — agent loop, tools, and code execution sandbox.",
5
5
  "keywords": [
6
6
  "agent",
@@ -51,7 +51,7 @@
51
51
  "node": ">=24.14.1"
52
52
  },
53
53
  "dependencies": {
54
- "@codeworksh/aikit": "0.7.1",
54
+ "@codeworksh/aikit": "0.7.2",
55
55
  "@daytona/sdk": "^0.187.0",
56
56
  "@effect/platform-node": "4.0.0-beta.107",
57
57
  "@effect/sql-sqlite-node": "4.0.0-beta.107",
@@ -14,6 +14,7 @@ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
14
14
  import { MemoryProvider, RealFSProvider, SqliteProvider, create } from "@platformatic/vfs";
15
15
  import { Bash } from "just-bash";
16
16
  import { createHash } from "crypto";
17
+ import * as AikitFailure from "@codeworksh/aikit/failure";
17
18
  import { randomBytes } from "node:crypto";
18
19
  //#region src/schema.ts
19
20
  const aikitValidators = /* @__PURE__ */ new WeakMap();
@@ -2574,7 +2575,7 @@ const sanitizeError = (cause, redact = makeRedactor()) => {
2574
2575
  ...code === void 0 ? {} : { code: redact(code) }
2575
2576
  };
2576
2577
  };
2577
- const providerError = (input) => {
2578
+ const providerError$1 = (input) => {
2578
2579
  const error = new SandboxProviderError({
2579
2580
  driver: input.driver,
2580
2581
  operation: input.operation,
@@ -2890,7 +2891,7 @@ const encodeMetadataJson = Schema.encodeEffect(MetadataJson);
2890
2891
  const encodePersistedErrorJson = Schema.encodeEffect(PersistedErrorJson);
2891
2892
  /** Schema-aware runtime check; `instanceof` does not survive schema decoding. */
2892
2893
  const isSandboxProviderError = Schema.is(SandboxProviderError);
2893
- const parseJson = (driver, operation, value) => decodeUnknownJson(value).pipe(Effect.mapError((cause) => providerError({
2894
+ const parseJson = (driver, operation, value) => decodeUnknownJson(value).pipe(Effect.mapError((cause) => providerError$1({
2894
2895
  driver,
2895
2896
  operation,
2896
2897
  cause
@@ -2982,18 +2983,18 @@ const make$16 = Effect.fn("Sandbox.Controller.make")(function* (options = {}) {
2982
2983
  const runtime = Effect.fn("Sandbox.Controller.runtime")(function* (row, operation) {
2983
2984
  const driverName = Name.make(row.driver);
2984
2985
  const driver = yield* registry.get(driverName);
2985
- if (driver.kind !== row.kind) return yield* providerError({
2986
+ if (driver.kind !== row.kind) return yield* providerError$1({
2986
2987
  driver: driverName,
2987
2988
  operation,
2988
2989
  cause: /* @__PURE__ */ new Error(`registered kind ${driver.kind} conflicts with persisted kind ${row.kind}`)
2989
2990
  });
2990
- if (Option.isNone(row.runtimeConfig)) return yield* providerError({
2991
+ if (Option.isNone(row.runtimeConfig)) return yield* providerError$1({
2991
2992
  driver: driverName,
2992
2993
  operation,
2993
2994
  cause: /* @__PURE__ */ new Error(`sandbox runtime config is missing: ${row.id}`)
2994
2995
  });
2995
2996
  const decoded = yield* parseJson(driverName, operation, row.runtimeConfig.value);
2996
- const runtimeConfig = yield* registry.decodeRuntimeConfig(driverName, decoded).pipe(Effect.mapError((cause) => providerError({
2997
+ const runtimeConfig = yield* registry.decodeRuntimeConfig(driverName, decoded).pipe(Effect.mapError((cause) => providerError$1({
2997
2998
  driver: driverName,
2998
2999
  operation,
2999
3000
  cause
@@ -3110,7 +3111,7 @@ const make$16 = Effect.fn("Sandbox.Controller.make")(function* (options = {}) {
3110
3111
  }).pipe(Effect.catch((error) => persistProviderFailure(id, "faulted", error)));
3111
3112
  return yield* Effect.gen(function* () {
3112
3113
  const encoded = yield* registry.encodeRuntimeConfig(driver.name, provisioned.runtimeConfig);
3113
- const runtimeConfig = yield* encodeUnknownJson$1(encoded).pipe(Effect.mapError((cause) => providerError({
3114
+ const runtimeConfig = yield* encodeUnknownJson$1(encoded).pipe(Effect.mapError((cause) => providerError$1({
3114
3115
  driver: driver.name,
3115
3116
  operation: "create",
3116
3117
  cause
@@ -3158,7 +3159,7 @@ const make$16 = Effect.fn("Sandbox.Controller.make")(function* (options = {}) {
3158
3159
  overrides: input.runtimeConfig
3159
3160
  });
3160
3161
  const encoded = yield* registry.encodeRuntimeConfig(driver.name, runtimeConfig);
3161
- const persisted = yield* encodeUnknownJson$1(encoded).pipe(Effect.mapError((cause) => providerError({
3162
+ const persisted = yield* encodeUnknownJson$1(encoded).pipe(Effect.mapError((cause) => providerError$1({
3162
3163
  driver: driver.name,
3163
3164
  operation: "register",
3164
3165
  cause
@@ -3750,7 +3751,7 @@ const make$13 = () => {
3750
3751
  const resources = /* @__PURE__ */ new Map();
3751
3752
  const find = (operation, input) => {
3752
3753
  const vfs = resources.get(input.id);
3753
- return vfs === void 0 ? Effect.fail(providerError({
3754
+ return vfs === void 0 ? Effect.fail(providerError$1({
3754
3755
  driver: name,
3755
3756
  operation,
3756
3757
  cause: /* @__PURE__ */ new Error(`memory namespace is unavailable in this process: ${input.id}`),
@@ -3769,7 +3770,7 @@ const make$13 = () => {
3769
3770
  },
3770
3771
  createConfigCodec: CreateConfig$3,
3771
3772
  runtimeConfigCodec: RuntimeConfig$3,
3772
- create: ({ instanceId, config }) => make$15({ cwd: config.initializeCwd ?? config.defaultCwd }).pipe(Effect.mapError((cause) => providerError({
3773
+ create: ({ instanceId, config }) => make$15({ cwd: config.initializeCwd ?? config.defaultCwd }).pipe(Effect.mapError((cause) => providerError$1({
3773
3774
  driver: name,
3774
3775
  operation: "create",
3775
3776
  cause
@@ -3781,7 +3782,7 @@ const make$13 = () => {
3781
3782
  runtimeConfig: { defaultCwd: config.defaultCwd }
3782
3783
  };
3783
3784
  })),
3784
- runtimeConfigFor: ({ providerResourceId }) => Effect.fail(providerError({
3785
+ runtimeConfigFor: ({ providerResourceId }) => Effect.fail(providerError$1({
3785
3786
  driver: name,
3786
3787
  operation: "runtimeConfigFor",
3787
3788
  cause: /* @__PURE__ */ new Error(`memory resources cannot be reattached: ${providerResourceId}`),
@@ -3801,7 +3802,7 @@ const make$13 = () => {
3801
3802
  providerStatus: "retained"
3802
3803
  }),
3803
3804
  destroy: (input) => Effect.suspend(() => {
3804
- return resources.delete(input.id) || Option.isSome(input.providerResourceId) ? Effect.void : Effect.fail(providerError({
3805
+ return resources.delete(input.id) || Option.isSome(input.providerResourceId) ? Effect.void : Effect.fail(providerError$1({
3805
3806
  driver: name,
3806
3807
  operation: "destroy",
3807
3808
  cause: /* @__PURE__ */ new Error(`memory namespace is unavailable: ${input.id}`),
@@ -3860,7 +3861,7 @@ const make$11 = () => {
3860
3861
  const runtimeLocation = (input) => input.runtimeConfig.location ?? Option.getOrUndefined(input.providerResourceId);
3861
3862
  const persistentTransport = (location) => {
3862
3863
  const backend = layer$12({ location });
3863
- return transportLayer(Layer.effectContext(Layer.build(backend).pipe(Effect.mapError((cause) => providerError({
3864
+ return transportLayer(Layer.effectContext(Layer.build(backend).pipe(Effect.mapError((cause) => providerError$1({
3864
3865
  driver: name,
3865
3866
  operation: "attach",
3866
3867
  cause
@@ -3868,7 +3869,7 @@ const make$11 = () => {
3868
3869
  };
3869
3870
  const memoryResource = (operation, id) => {
3870
3871
  const resource = memory.get(id);
3871
- return resource === void 0 ? Effect.fail(providerError({
3872
+ return resource === void 0 ? Effect.fail(providerError$1({
3872
3873
  driver: name,
3873
3874
  operation,
3874
3875
  cause: /* @__PURE__ */ new Error(`in-memory sqlite namespace is unavailable in this process: ${id}`),
@@ -3889,7 +3890,7 @@ const make$11 = () => {
3889
3890
  runtimeConfigCodec: RuntimeConfig$2,
3890
3891
  create: ({ instanceId, config }) => {
3891
3892
  const location = config.location === void 0 ? void 0 : posix.resolve(config.location);
3892
- return make$12(location, { cwd: config.initializeCwd ?? config.defaultCwd }).pipe(Effect.mapError((cause) => providerError({
3893
+ return make$12(location, { cwd: config.initializeCwd ?? config.defaultCwd }).pipe(Effect.mapError((cause) => providerError$1({
3893
3894
  driver: name,
3894
3895
  operation: "create",
3895
3896
  cause
@@ -3908,7 +3909,7 @@ const make$11 = () => {
3908
3909
  }));
3909
3910
  },
3910
3911
  runtimeConfigFor: ({ providerResourceId, overrides }) => {
3911
- if (!posix.isAbsolute(providerResourceId)) return Effect.fail(providerError({
3912
+ if (!posix.isAbsolute(providerResourceId)) return Effect.fail(providerError$1({
3912
3913
  driver: name,
3913
3914
  operation: "runtimeConfigFor",
3914
3915
  cause: /* @__PURE__ */ new Error(`sqldb resource path must be absolute: ${providerResourceId}`)
@@ -3923,7 +3924,7 @@ const make$11 = () => {
3923
3924
  attach: (input) => {
3924
3925
  if (input.runtimeConfig.inMemory) return Layer.unwrap(Effect.map(memoryResource("attach", input.id), (resource) => transport$2(resource.vfs)));
3925
3926
  const location = runtimeLocation(input);
3926
- return location === void 0 ? Layer.unwrap(Effect.fail(providerError({
3927
+ return location === void 0 ? Layer.unwrap(Effect.fail(providerError$1({
3927
3928
  driver: name,
3928
3929
  operation: "attach",
3929
3930
  cause: /* @__PURE__ */ new Error(`sqldb runtime location is missing: ${input.id}`)
@@ -3935,12 +3936,12 @@ const make$11 = () => {
3935
3936
  providerStatus: "online"
3936
3937
  });
3937
3938
  const location = runtimeLocation(input);
3938
- if (location === void 0) return Effect.fail(providerError({
3939
+ if (location === void 0) return Effect.fail(providerError$1({
3939
3940
  driver: name,
3940
3941
  operation: "inspect",
3941
3942
  cause: /* @__PURE__ */ new Error(`sqldb runtime location is missing: ${input.id}`)
3942
3943
  }));
3943
- return fileSystem.access(location).pipe(Effect.mapError((cause) => providerError({
3944
+ return fileSystem.access(location).pipe(Effect.mapError((cause) => providerError$1({
3944
3945
  driver: name,
3945
3946
  operation: "inspect",
3946
3947
  cause,
@@ -3972,11 +3973,11 @@ const make$11 = () => {
3972
3973
  return Effect.void;
3973
3974
  }
3974
3975
  const location = runtimeLocation(input);
3975
- return location === void 0 ? Effect.fail(providerError({
3976
+ return location === void 0 ? Effect.fail(providerError$1({
3976
3977
  driver: name,
3977
3978
  operation: "destroy",
3978
3979
  cause: /* @__PURE__ */ new Error(`sqldb runtime location is missing: ${input.id}`)
3979
- })) : fileSystem.remove(location, { force: true }).pipe(Effect.mapError((cause) => providerError({
3980
+ })) : fileSystem.remove(location, { force: true }).pipe(Effect.mapError((cause) => providerError$1({
3980
3981
  driver: name,
3981
3982
  operation: "destroy",
3982
3983
  cause
@@ -4194,7 +4195,7 @@ const make$9 = (client = {}) => {
4194
4195
  sdk = loaded;
4195
4196
  return run(loaded);
4196
4197
  }),
4197
- catch: (cause) => providerError({
4198
+ catch: (cause) => providerError$1({
4198
4199
  driver: name$1,
4199
4200
  operation,
4200
4201
  cause,
@@ -4474,7 +4475,7 @@ const make$8 = (client = {}) => {
4474
4475
  const redact = makeRedactor([client.token ?? ""]);
4475
4476
  const attempt = (operation, run) => Effect.tryPromise({
4476
4477
  try: run,
4477
- catch: (cause) => providerError({
4478
+ catch: (cause) => providerError$1({
4478
4479
  driver: name,
4479
4480
  operation,
4480
4481
  cause,
@@ -5052,29 +5053,125 @@ const layer$8 = (ref = {}) => Layer.effect(Service$5, Effect.gen(function* () {
5052
5053
  }));
5053
5054
  //#endregion
5054
5055
  //#region src/runner/run.ts
5056
+ var run_exports = /* @__PURE__ */ __exportAll({
5057
+ LLMStreamError: () => LLMStreamError,
5058
+ ModelCatalogError: () => ModelCatalogError,
5059
+ ModelNotFoundError: () => ModelNotFoundError,
5060
+ ProviderAuthenticationError: () => ProviderAuthenticationError,
5061
+ ProviderAuthorizationError: () => ProviderAuthorizationError,
5062
+ ProviderConfigurationError: () => ProviderConfigurationError,
5063
+ ProviderContentPolicyError: () => ProviderContentPolicyError,
5064
+ ProviderError: () => ProviderError,
5065
+ ProviderFailureReason: () => ProviderFailureReason,
5066
+ ProviderInvalidRequestError: () => ProviderInvalidRequestError,
5067
+ ProviderInvalidResponseError: () => ProviderInvalidResponseError,
5068
+ ProviderModelUnavailableError: () => ProviderModelUnavailableError,
5069
+ ProviderQuotaError: () => ProviderQuotaError,
5070
+ ProviderRateLimitError: () => ProviderRateLimitError,
5071
+ ProviderTimeoutError: () => ProviderTimeoutError,
5072
+ ProviderTransportError: () => ProviderTransportError,
5073
+ ProviderUnavailableError: () => ProviderUnavailableError,
5074
+ ProviderUnknownError: () => ProviderUnknownError,
5075
+ Runner: () => run_exports,
5076
+ SandboxDirectoryNotFoundError: () => SandboxDirectoryNotFoundError,
5077
+ Service: () => Service$4
5078
+ });
5055
5079
  var SandboxDirectoryNotFoundError = class extends Schema.TaggedError()("Runner.SandboxDirectoryNotFoundError", {
5056
5080
  sessionId: Schema.String,
5057
5081
  sandboxInstanceId: ID$2,
5058
5082
  directory: Schema.String
5083
+ }) {
5084
+ get message() {
5085
+ return `sandbox directory not found: ${this.directory}`;
5086
+ }
5087
+ };
5088
+ const ProviderFailureFields = {
5089
+ message: Schema.String,
5090
+ isRetryable: Schema.Boolean,
5091
+ status: optional(Schema.Finite),
5092
+ code: optional(Schema.String),
5093
+ requestId: optional(Schema.String),
5094
+ retryAfter: optional(Schema.Duration)
5095
+ };
5096
+ var ProviderAuthenticationError = class extends Schema.TaggedError()("Runner.ProviderAuthenticationError", {
5097
+ authentication: Schema.Literals([
5098
+ "missing",
5099
+ "invalid",
5100
+ "expired"
5101
+ ]),
5102
+ ...ProviderFailureFields
5059
5103
  }) {};
5104
+ var ProviderConfigurationError = class extends Schema.TaggedError()("Runner.ProviderConfigurationError", ProviderFailureFields) {};
5105
+ var ProviderAuthorizationError = class extends Schema.TaggedError()("Runner.ProviderAuthorizationError", ProviderFailureFields) {};
5106
+ var ProviderModelUnavailableError = class extends Schema.TaggedError()("Runner.ProviderModelUnavailableError", ProviderFailureFields) {};
5107
+ var ProviderRateLimitError = class extends Schema.TaggedError()("Runner.ProviderRateLimitError", ProviderFailureFields) {};
5108
+ var ProviderQuotaError = class extends Schema.TaggedError()("Runner.ProviderQuotaError", ProviderFailureFields) {};
5109
+ var ProviderInvalidRequestError = class extends Schema.TaggedError()("Runner.ProviderInvalidRequestError", ProviderFailureFields) {};
5110
+ var ProviderContentPolicyError = class extends Schema.TaggedError()("Runner.ProviderContentPolicyError", ProviderFailureFields) {};
5111
+ var ProviderTimeoutError = class extends Schema.TaggedError()("Runner.ProviderTimeoutError", ProviderFailureFields) {};
5112
+ var ProviderTransportError = class extends Schema.TaggedError()("Runner.ProviderTransportError", ProviderFailureFields) {};
5113
+ var ProviderUnavailableError = class extends Schema.TaggedError()("Runner.ProviderUnavailableError", ProviderFailureFields) {};
5114
+ var ProviderInvalidResponseError = class extends Schema.TaggedError()("Runner.ProviderInvalidResponseError", ProviderFailureFields) {};
5115
+ var ProviderUnknownError = class extends Schema.TaggedError()("Runner.ProviderUnknownError", ProviderFailureFields) {};
5116
+ const ProviderFailureReason = Schema.Union([
5117
+ ProviderAuthenticationError,
5118
+ ProviderConfigurationError,
5119
+ ProviderAuthorizationError,
5120
+ ProviderModelUnavailableError,
5121
+ ProviderRateLimitError,
5122
+ ProviderQuotaError,
5123
+ ProviderInvalidRequestError,
5124
+ ProviderContentPolicyError,
5125
+ ProviderTimeoutError,
5126
+ ProviderTransportError,
5127
+ ProviderUnavailableError,
5128
+ ProviderInvalidResponseError,
5129
+ ProviderUnknownError
5130
+ ]);
5131
+ /** Stable provider boundary for SDK and RPC consumers; inspect `reason._tag` for the category. */
5132
+ var ProviderError = class extends Schema.TaggedError()("Runner.ProviderError", {
5133
+ provider: Schema.String,
5134
+ model: Schema.String,
5135
+ reason: ProviderFailureReason
5136
+ }) {
5137
+ cause = this.reason;
5138
+ get message() {
5139
+ return `${this.provider}/${this.model}: ${this.reason.message}`;
5140
+ }
5141
+ get isRetryable() {
5142
+ return this.reason.isRetryable;
5143
+ }
5144
+ };
5145
+ var ModelCatalogError = class extends Schema.TaggedError()("Runner.ModelCatalogError", {
5146
+ path: Schema.String,
5147
+ reason: Schema.Literals([
5148
+ "missing",
5149
+ "unreadable",
5150
+ "empty",
5151
+ "invalid"
5152
+ ]),
5153
+ detail: Schema.String
5154
+ }) {
5155
+ get message() {
5156
+ return this.detail;
5157
+ }
5158
+ };
5060
5159
  var ModelNotFoundError = class extends Schema.TaggedError()("Runner.ModelNotFoundError", {
5061
5160
  provider: Schema.String,
5062
5161
  model: Schema.String
5063
- }) {};
5064
- var ProviderTurnError = class extends Schema.TaggedError()("Runner.ProviderTurnError", {
5065
- provider: Schema.String,
5066
- model: Schema.String,
5067
- cause: Schema.Defect()
5068
- }) {};
5162
+ }) {
5163
+ get message() {
5164
+ return `model "${this.model}" is not present for provider "${this.provider}" in the model catalog`;
5165
+ }
5166
+ };
5069
5167
  var LLMStreamError = class extends Schema.TaggedError()("Runner.LLMStreamError", {
5070
5168
  sessionId: Schema.String,
5071
5169
  reason: Schema.String
5072
- }) {};
5073
- var TurnError = class extends Schema.TaggedError()("Runner.TurnError", {
5074
- sessionId: Schema.String,
5075
- messageId: optional(ID$1),
5076
- cause: TurnAbortCause
5077
- }) {};
5170
+ }) {
5171
+ get message() {
5172
+ return `invalid provider event stream: ${this.reason}`;
5173
+ }
5174
+ };
5078
5175
  var Service$4 = class extends Context.Service()("@codeworksh/harness/runner/run/Service") {};
5079
5176
  //#endregion
5080
5177
  //#region src/runner/execution.ts
@@ -5486,7 +5583,7 @@ const layer$6 = Layer.effect(Service$3, Effect.gen(function* () {
5486
5583
  sessionId,
5487
5584
  force
5488
5585
  }).pipe(Effect.provideContext(Context.merge(locationContext, mountContext)));
5489
- }).pipe(Effect.scoped, Effect.tapCause((cause) => Cause.hasInterruptsOnly(cause) ? Effect.void : Effect.logError("failed to drain session", cause).pipe(Effect.annotateLogs({ sessionId }))));
5586
+ }).pipe(Effect.scoped, Effect.tapCause((cause) => Cause.hasDies(cause) ? Effect.logError("runner defect", cause).pipe(Effect.annotateLogs({ sessionId })) : Effect.void));
5490
5587
  }) });
5491
5588
  return Service$3.of({
5492
5589
  active: coordinator.active,
@@ -5654,15 +5751,72 @@ const runtimeOptions = (input, signal) => ({
5654
5751
  sessionId: input.sessionId,
5655
5752
  signal
5656
5753
  });
5754
+ const reasonFields = (failure) => ({
5755
+ message: failure.message,
5756
+ isRetryable: failure.retryable,
5757
+ ...failure.status === void 0 ? {} : { status: failure.status },
5758
+ ...failure.code === void 0 ? {} : { code: failure.code },
5759
+ ...failure.requestId === void 0 ? {} : { requestId: failure.requestId },
5760
+ ...failure.retryAfterMs === void 0 ? {} : { retryAfter: Duration.millis(failure.retryAfterMs) }
5761
+ });
5762
+ /** Lift Aikit's JSON-safe failure data into the Effect-native Runner error channel. */
5763
+ const providerError = (input, failure) => {
5764
+ const fields = reasonFields(failure);
5765
+ const reason = (() => {
5766
+ switch (failure._tag) {
5767
+ case "Authentication": return new ProviderAuthenticationError({
5768
+ authentication: failure.reason,
5769
+ ...fields
5770
+ });
5771
+ case "Configuration": return new ProviderConfigurationError(fields);
5772
+ case "Authorization": return new ProviderAuthorizationError(fields);
5773
+ case "ModelUnavailable": return new ProviderModelUnavailableError(fields);
5774
+ case "RateLimit": return new ProviderRateLimitError(fields);
5775
+ case "Quota": return new ProviderQuotaError(fields);
5776
+ case "InvalidRequest": return new ProviderInvalidRequestError(fields);
5777
+ case "ContentPolicy": return new ProviderContentPolicyError(fields);
5778
+ case "Timeout": return new ProviderTimeoutError(fields);
5779
+ case "Transport": return new ProviderTransportError(fields);
5780
+ case "Unavailable": return new ProviderUnavailableError(fields);
5781
+ case "InvalidResponse": return new ProviderInvalidResponseError(fields);
5782
+ case "Unknown": return new ProviderUnknownError(fields);
5783
+ }
5784
+ })();
5785
+ return new ProviderError({
5786
+ provider: input.provider,
5787
+ model: input.model,
5788
+ reason
5789
+ });
5790
+ };
5791
+ const providerErrorFromUnknown = (input, cause) => providerError(input, AikitFailure.normalize(cause));
5792
+ const modelCatalogFailure = (cause) => {
5793
+ if (typeof cause !== "object" || cause === null || !("name" in cause) || cause.name !== "ModelCatalogLoadError") return;
5794
+ if (!("data" in cause) || typeof cause.data !== "object" || cause.data === null) return void 0;
5795
+ const data = cause.data;
5796
+ if (!("path" in data) || typeof data.path !== "string" || !("message" in data) || typeof data.message !== "string" || !("reason" in data) || data.reason !== "missing" && data.reason !== "unreadable" && data.reason !== "empty" && data.reason !== "invalid") return;
5797
+ return {
5798
+ path: data.path,
5799
+ reason: data.reason,
5800
+ message: data.message
5801
+ };
5802
+ };
5803
+ /** Read structured terminal data while remaining compatible with older Aikit messages. */
5804
+ const messageFailure = (message) => {
5805
+ const candidate = message.failure;
5806
+ return AikitFailure.isFailure(candidate) ? candidate : AikitFailure.fromMessage(message.errorMessage ?? "The provider turn failed.");
5807
+ };
5657
5808
  /** Resolve the configured model and start aikit's provider stream. */
5658
5809
  const open = Effect.fn("LLM.open")(function* (input, signal) {
5659
5810
  const model = yield* Effect.tryPromise({
5660
5811
  try: () => llm(input.provider, input.model),
5661
- catch: (cause) => new ProviderTurnError({
5662
- provider: input.provider,
5663
- model: input.model,
5664
- cause
5665
- })
5812
+ catch: (cause) => {
5813
+ const catalog = modelCatalogFailure(cause);
5814
+ return catalog === void 0 ? providerErrorFromUnknown(input, cause) : new ModelCatalogError({
5815
+ path: catalog.path,
5816
+ reason: catalog.reason,
5817
+ detail: catalog.message
5818
+ });
5819
+ }
5666
5820
  });
5667
5821
  if (model === void 0) return yield* new ModelNotFoundError({
5668
5822
  provider: input.provider,
@@ -5670,11 +5824,7 @@ const open = Effect.fn("LLM.open")(function* (input, signal) {
5670
5824
  });
5671
5825
  return yield* Effect.try({
5672
5826
  try: () => stream(model, input.context, runtimeOptions(input, signal)),
5673
- catch: (cause) => new ProviderTurnError({
5674
- provider: input.provider,
5675
- model: input.model,
5676
- cause
5677
- })
5827
+ catch: (cause) => providerErrorFromUnknown(input, cause)
5678
5828
  });
5679
5829
  });
5680
5830
  /**
@@ -5689,11 +5839,7 @@ const make$4 = (openStream) => {
5689
5839
  const abort = Scope.close(signalScope, Exit.void);
5690
5840
  return yield* Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
5691
5841
  const iterable = yield* restore(openStream(input, signal)).pipe(Effect.onInterrupt(() => abort));
5692
- const consumer = yield* Stream.fromAsyncIterable(iterable, (cause) => new ProviderTurnError({
5693
- provider: input.provider,
5694
- model: input.model,
5695
- cause
5696
- })).pipe(Stream.runForEach(input.publisher.publish), Effect.andThen(input.publisher.terminal), Effect.interruptible).pipe(Effect.forkScoped({ startImmediately: true }));
5842
+ const consumer = yield* Stream.fromAsyncIterable(iterable, (cause) => providerErrorFromUnknown(input, cause)).pipe(Stream.runForEach(input.publisher.publish), Effect.andThen(input.publisher.terminal), Effect.interruptible).pipe(Effect.forkScoped({ startImmediately: true }));
5697
5843
  const awaited = yield* restore(Fiber.await(consumer)).pipe(Effect.onInterrupt(() => abort), Effect.exit);
5698
5844
  if (Exit.isFailure(awaited)) {
5699
5845
  const drained = yield* Fiber.await(consumer);
@@ -6653,7 +6799,10 @@ const layer$4 = (options = {}) => {
6653
6799
  //#region src/runner/loop.ts
6654
6800
  const errorMessage = (cause) => {
6655
6801
  const squashed = Cause.squash(cause);
6656
- return squashed instanceof Error ? squashed.message : String(squashed);
6802
+ if (squashed instanceof Error && squashed.message.trim().length > 0) return squashed.message;
6803
+ if (typeof squashed === "string" && squashed.trim().length > 0) return squashed;
6804
+ if (typeof squashed === "object" && squashed !== null && "_tag" in squashed) return String(squashed._tag);
6805
+ return "the turn failed for an unknown reason";
6657
6806
  };
6658
6807
  const terminalResult = (text) => ({
6659
6808
  content: [{
@@ -6836,15 +6985,11 @@ const layer$3 = (options = {}) => Layer.effect(Service$4, Effect.gen(function* (
6836
6985
  publisher
6837
6986
  });
6838
6987
  if (terminal.outcome === "failed") {
6839
- const cause = terminal.reason === "aborted" ? { _tag: "interrupted" } : {
6840
- _tag: "error",
6841
- message: terminal.message.errorMessage ?? "provider turn failed"
6842
- };
6843
- return yield* new TurnError({
6844
- sessionId,
6845
- ...publisher.startedMessageId === void 0 ? {} : { messageId: publisher.startedMessageId },
6846
- cause
6847
- });
6988
+ if (terminal.reason === "aborted") return yield* Effect.interrupt;
6989
+ return yield* providerError({
6990
+ provider: snapshot.provider,
6991
+ model: snapshot.model
6992
+ }, messageFailure(terminal.message));
6848
6993
  }
6849
6994
  const interrupted = yield* settleTools(snapshot, terminal.message, terminal.reason, () => {
6850
6995
  committed = true;
@@ -6856,32 +7001,26 @@ const layer$3 = (options = {}) => Layer.effect(Service$4, Effect.gen(function* (
6856
7001
  };
6857
7002
  }).pipe(Effect.catchCause((cause) => {
6858
7003
  if (committed) return Effect.failCause(cause);
6859
- const failure = Cause.findErrorOption(cause);
6860
- if (Option.isSome(failure) && failure.value._tag === "Runner.TurnError") return Effect.fail(failure.value);
6861
7004
  const turnCause = Cause.hasInterruptsOnly(cause) ? { _tag: "interrupted" } : {
6862
7005
  _tag: "error",
6863
7006
  message: errorMessage(cause)
6864
7007
  };
6865
- return Effect.fail(new TurnError({
6866
- sessionId,
6867
- ...publisher?.startedMessageId === void 0 ? {} : { messageId: publisher.startedMessageId },
6868
- cause: turnCause
6869
- }));
7008
+ const record = Effect.gen(function* () {
7009
+ if (publisher?.startedMessageId !== void 0) {
7010
+ const stored = yield* sessions.entry(publisher.startedMessageId);
7011
+ if (Option.isSome(stored) && stored.value.entry.state === "draft") yield* publishFailure(stored.value, turnCause);
7012
+ }
7013
+ yield* events.publish(TurnAborted, {
7014
+ timestamp: yield* DateTime.now,
7015
+ sessionId,
7016
+ cause: turnCause
7017
+ });
7018
+ });
7019
+ return Effect.uninterruptible(record).pipe(Effect.andThen(Effect.failCause(cause)));
6870
7020
  }));
6871
7021
  });
6872
7022
  const runTurn = Effect.fn("Loop.runTurn")(function* (promotion, snapshot) {
6873
- return yield* runTurnAttempt(promotion, snapshot).pipe(Effect.catchTag("Runner.TurnError", (error) => Effect.gen(function* () {
6874
- if (error.messageId !== void 0) {
6875
- const stored = yield* sessions.entry(error.messageId);
6876
- if (Option.isSome(stored) && stored.value.entry.state === "draft") yield* publishFailure(stored.value, error.cause);
6877
- }
6878
- yield* events.publish(TurnAborted, {
6879
- timestamp: yield* DateTime.now,
6880
- sessionId: snapshot.sessionId,
6881
- cause: error.cause
6882
- });
6883
- return yield* error;
6884
- })));
7023
+ return yield* runTurnAttempt(promotion, snapshot);
6885
7024
  });
6886
7025
  const run$1 = Effect.fn("Loop.run")(function* (input) {
6887
7026
  yield* healDanglingDraft(input.sessionId);
@@ -7274,6 +7413,6 @@ const attach = Effect.fn("Session.attach")(function* (input) {
7274
7413
  return found.value;
7275
7414
  });
7276
7415
  //#endregion
7277
- export { create$2 as a, harness_exports as c, LLMEnded as d, LLMTextDelta as f, Drivers as i, layer as l, ID$4 as m, create$1 as n, register as o, TurnEnded as p, session_exports as r, sandbox_exports as s, attach as t, tool_exports as u };
7416
+ export { LLMEnded as _, create$2 as a, ID$4 as b, harness_exports as c, LLMStreamError as d, ModelCatalogError as f, SandboxProviderError as g, run_exports as h, Drivers as i, layer as l, ProviderError as m, create$1 as n, register as o, ModelNotFoundError as p, session_exports as r, sandbox_exports as s, attach as t, tool_exports as u, LLMTextDelta as v, TurnEnded as y };
7278
7417
 
7279
- //# sourceMappingURL=session-DZZfASHn.mjs.map
7418
+ //# sourceMappingURL=session-B8PG8cMg.mjs.map