tines 0.0.153 → 0.0.155

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.
Files changed (2) hide show
  1. package/dist/index.js +38 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -6935,6 +6935,23 @@ var USAGE_LIMIT_PREFIXES = [
6935
6935
  ];
6936
6936
  var USAGE_LIMIT_PATTERN = /^Fable(?: [^·\n]{1,40})? requires usage credits\./;
6937
6937
  var ANSI = /\x1b\[[0-9;]*m/g;
6938
+ var PROVIDER_ERROR = /(?:\bAPI Error:\s*5\d{2}\b|\bECONNRESET\b|\bconnection reset(?: by peer)?\b|\bsocket hang up\b)/i;
6939
+ function providerErrorDetail(value) {
6940
+ if (typeof value !== "string") return null;
6941
+ const clean = value.replace(ANSI, "").trim();
6942
+ return clean && PROVIDER_ERROR.test(clean) ? clean : null;
6943
+ }
6944
+ function providerErrorFromStreamEvent(event) {
6945
+ if (typeof event !== "object" || event === null) return null;
6946
+ const ev = event;
6947
+ if (ev.type !== "result" || ev.is_error !== true) return null;
6948
+ const detail = providerErrorDetail(ev.result);
6949
+ return detail ? { source: "stream", detail } : null;
6950
+ }
6951
+ function providerErrorFromStderrLine(line) {
6952
+ const detail = providerErrorDetail(line);
6953
+ return detail ? { source: "stderr", detail } : null;
6954
+ }
6938
6955
  function toEpochMs(value) {
6939
6956
  return value < 1e12 ? Math.round(value * 1e3) : Math.round(value);
6940
6957
  }
@@ -7051,10 +7068,14 @@ function parseResetTime(text2, now) {
7051
7068
  var RateLimitDetector = class {
7052
7069
  stream = null;
7053
7070
  stderr = null;
7071
+ providerStream = null;
7072
+ providerStderr = null;
7054
7073
  pending = "";
7055
7074
  noteStreamEvent(event) {
7056
7075
  const signal = rateLimitFromStreamEvent(event);
7057
7076
  if (signal) this.stream = signal;
7077
+ const provider = providerErrorFromStreamEvent(event);
7078
+ if (provider) this.providerStream = provider;
7058
7079
  }
7059
7080
  noteStderr(chunk, now = Date.now()) {
7060
7081
  this.pending += chunk;
@@ -7076,9 +7097,15 @@ var RateLimitDetector = class {
7076
7097
  signal() {
7077
7098
  return this.stream ?? this.stderr;
7078
7099
  }
7100
+ /** A structured provider error when present; stderr as a fallback. */
7101
+ providerError() {
7102
+ return this.providerStream ?? this.providerStderr;
7103
+ }
7079
7104
  line(raw, now) {
7080
7105
  const signal = rateLimitFromStderrLine(raw, now);
7081
7106
  if (signal) this.stderr = signal;
7107
+ const provider = providerErrorFromStderrLine(raw);
7108
+ if (provider) this.providerStderr = provider;
7082
7109
  }
7083
7110
  };
7084
7111
 
@@ -7220,9 +7247,9 @@ var RunTable = class {
7220
7247
  * (shutdown, restart) rather than the work failing: the supervisor then
7221
7248
  * spares the issue a strike. Everything a run can do wrong to itself —
7222
7249
  * a non-zero harness exit, a workspace that would not set up — must not
7223
- * set it. The one exception is `{ judgment: 'rate_limited' }`: a non-zero
7224
- * exit whose cause was the provider refusing on a usage limit is the
7225
- * runner's condition, not the work's.
7250
+ * set it. Exceptions are provider-side failures: usage exhaustion uses
7251
+ * `{ judgment: 'rate_limited' }` with its reset time, while transient 5xx
7252
+ * and transport outages use `interrupted` and the normal short backoff.
7226
7253
  */
7227
7254
  async finishAndCleanup(run, status, error, judgment) {
7228
7255
  if (run.settled) return this.cleanup(run);
@@ -7986,6 +8013,7 @@ async function runDaemon(opts) {
7986
8013
  void table2.finishAndCleanup(run, "completed");
7987
8014
  } else {
7988
8015
  const limited = signal ? null : run.limiter?.signal() ?? null;
8016
+ const providerError = signal ? null : run.limiter?.providerError() ?? null;
7989
8017
  if (limited) {
7990
8018
  log(
7991
8019
  `run ${runId}: harness rate limited (${limited.detail}); reporting without a strike`
@@ -7994,6 +8022,13 @@ async function runDaemon(opts) {
7994
8022
  judgment: "rate_limited",
7995
8023
  ...limited.resumeAt !== null ? { resume_at: limited.resumeAt } : {}
7996
8024
  });
8025
+ } else if (providerError) {
8026
+ log(
8027
+ `run ${runId}: transient provider error (${providerError.detail}); reporting without a strike`
8028
+ );
8029
+ void table2.finishAndCleanup(run, "failed", `provider error: ${providerError.detail}`, {
8030
+ judgment: "interrupted"
8031
+ });
7997
8032
  } else {
7998
8033
  void table2.finishAndCleanup(
7999
8034
  run,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tines",
3
- "version": "0.0.153",
3
+ "version": "0.0.155",
4
4
  "description": "CLI for Tines, an orchestration layer for AI agents",
5
5
  "repository": {
6
6
  "type": "git",