pi-advisor-flow 0.8.1-dev.1 → 0.8.1

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 CHANGED
@@ -4,7 +4,7 @@ All notable changes to this project are documented here.
4
4
 
5
5
  The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0/).
6
6
 
7
- ## 0.8.1-dev.1 - 2026-09-23
7
+ ## 0.8.1 - 2026-09-23
8
8
 
9
9
  ### Fixed
10
10
 
@@ -12,6 +12,10 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
12
12
  - Keep marked child model selections out of the persisted parent Executor configuration.
13
13
  - Run Advisor Scout with the marked child's active model and thinking level instead of replacing them with the configured parent Executor.
14
14
 
15
+ ### Added
16
+
17
+ - Published validated npm development previews for package changes on `main` under the `dev` dist-tag; stable installs continue to use `latest`.
18
+
15
19
  ## 0.8.0 - 2026-09-22
16
20
 
17
21
  ### Added
package/README.md CHANGED
@@ -46,6 +46,14 @@ Requires Pi 0.84.1 or later. Pi 0.85.0 is not supported (broken upstream release
46
46
  pi install npm:pi-advisor-flow
47
47
  ```
48
48
 
49
+ For npm consumers who want to test the latest development preview:
50
+
51
+ ```bash
52
+ npm install pi-advisor-flow@dev
53
+ ```
54
+
55
+ Preview builds use the next patch prerelease version (for example, `0.8.1-dev.1` after stable `0.8.0`) and are published only when a file included in the npm package changes. Each preview advances the `dev.N` sequence. Regular installs continue to use the stable `latest` version.
56
+
49
57
  You can also install from GitHub:
50
58
 
51
59
  ```bash
package/dist/index.js CHANGED
@@ -2077,8 +2077,8 @@ var toolResultEntry = (message, toolResultMaxLines, toolResultMaxBytes, policies
2077
2077
  return `[Tool Result for ${toolName}] (excluded by Advisor tool policy)`;
2078
2078
  }
2079
2079
  if (policy === "summary") {
2080
- const capped2 = capToolResult(source, toolResultMaxLines, toolResultMaxBytes);
2081
- return `[Tool Result for ${toolName}] (output omitted by Advisor tool policy: summary; status: ${status}; ${capped2.totalLines} lines, ${capped2.totalBytes} bytes; source output was${capped2.truncated ? "" : " not"} truncated)`;
2080
+ const capped = capToolResult(source, toolResultMaxLines, toolResultMaxBytes);
2081
+ return `[Tool Result for ${toolName}] (output omitted by Advisor tool policy: summary; status: ${status}; ${capped.totalLines} lines, ${capped.totalBytes} bytes; source output was${capped.truncated ? "" : " not"} truncated)`;
2082
2082
  }
2083
2083
  const disclosed = redact ? redactSecrets(source) : source;
2084
2084
  const capped = capToolResult(disclosed, toolResultMaxLines, toolResultMaxBytes);
@@ -2118,17 +2118,17 @@ var selectRecentEntries = (entries, maxChars) => {
2118
2118
  }
2119
2119
  const newestTruncated = "[Newest entry truncated]";
2120
2120
  if (entries.length === 1) {
2121
- const prefix2 = `${newestTruncated}${separator}`;
2122
- return `${prefix2}${entries[0].slice(0, Math.max(0, maxChars - prefix2.length))}`.slice(0, maxChars);
2121
+ const prefix = `${newestTruncated}${separator}`;
2122
+ return `${prefix}${entries[0].slice(0, Math.max(0, maxChars - prefix.length))}`.slice(0, maxChars);
2123
2123
  }
2124
2124
  const selected = [];
2125
2125
  let selectedLength = 0;
2126
2126
  for (let index = entries.length - 1;index >= 0; index -= 1) {
2127
2127
  const entry = entries[index];
2128
2128
  const candidateCount = selected.length + 1;
2129
- const omitted2 = entries.length - candidateCount;
2129
+ const omitted = entries.length - candidateCount;
2130
2130
  const candidateLength = selectedLength + entry.length + (selected.length > 0 ? separator.length : 0);
2131
- if (omissionMarker(omitted2).length + separator.length + candidateLength > maxChars) {
2131
+ if (omissionMarker(omitted).length + separator.length + candidateLength > maxChars) {
2132
2132
  break;
2133
2133
  }
2134
2134
  selected.unshift(entry);
@@ -2863,15 +2863,15 @@ var runAdvisorScout = async (ctx, manifest, parentSignal, onEvent, timeoutMs = S
2863
2863
  return { cancelled: true, ok: false };
2864
2864
  };
2865
2865
  const fallback = (category, message, usage) => {
2866
- const outcome2 = {
2866
+ const outcome = {
2867
2867
  category,
2868
2868
  message,
2869
2869
  metrics: usage === undefined ? baseMetrics(manifest, startedAt) : { ...baseMetrics(manifest, startedAt), usage },
2870
2870
  model: effectiveExecutorRef(ctx),
2871
2871
  ok: false
2872
2872
  };
2873
- publish({ outcome: outcome2, type: "fallback" });
2874
- return outcome2;
2873
+ publish({ outcome, type: "fallback" });
2874
+ return outcome;
2875
2875
  };
2876
2876
  if (parentSignal?.aborted) {
2877
2877
  return cancelled();
@@ -2970,12 +2970,12 @@ var curateAdvisorConversation = async (ctx, legacyConversation, signal, onScout,
2970
2970
  };
2971
2971
 
2972
2972
  // src/tools/prompts.ts
2973
- var advisorMessageText = (conversation, question, changes, draft, preferences, untracked2, tracked2) => {
2973
+ var advisorMessageText = (conversation, question, changes, draft, preferences, untracked, tracked) => {
2974
2974
  const safeConversation = escapeRepositoryText(conversation);
2975
2975
  const safeDraft = draft ? escapeRepositoryText(draft) : undefined;
2976
2976
  const safePreferences = preferences ? escapeRepositoryText(preferences) : undefined;
2977
- const safeUntracked = (untracked2 ?? []).map(escapeRepositoryText);
2978
- const safeTracked = (tracked2 ?? []).map(escapeRepositoryText);
2977
+ const safeUntracked = (untracked ?? []).map(escapeRepositoryText);
2978
+ const safeTracked = (tracked ?? []).map(escapeRepositoryText);
2979
2979
  const text = `${safeConversation ? `<conversation>
2980
2980
  ${safeConversation}
2981
2981
  </conversation>` : ""}${changes ? `
@@ -3088,16 +3088,16 @@ var assembleConsultationContext = async (options) => {
3088
3088
  const curated = await curateAdvisorConversation(ctx, legacyConversation, options.signal, options.onScout, advisorScoutEnabledRef, runAdvisorScout, options.currentInvocationId, conversationBudget);
3089
3089
  const preferences = await readProjectPreferences(ctx, ATTACHMENT_TEXT_MAX_BYTES, advisorRedactSecretsRef);
3090
3090
  const draftText = options.draft ? redactAndCapText(options.draft, ATTACHMENT_TEXT_MAX_BYTES, advisorRedactSecretsRef) : undefined;
3091
- const untracked2 = await readUntrackedFiles(ctx.cwd, options.includeUntracked ?? [], advisorUntrackedContentRef, advisorRedactSecretsRef);
3092
- const tracked2 = await readTrackedFiles(ctx.cwd, options.includeTracked ?? [], advisorTrackedFileContentRef, advisorRedactSecretsRef, Math.max(0, ATTACHMENTS_TOTAL_MAX_BYTES - untracked2.reduce((sum, item) => sum + item.bytes, 0)));
3091
+ const untracked = await readUntrackedFiles(ctx.cwd, options.includeUntracked ?? [], advisorUntrackedContentRef, advisorRedactSecretsRef);
3092
+ const tracked = await readTrackedFiles(ctx.cwd, options.includeTracked ?? [], advisorTrackedFileContentRef, advisorRedactSecretsRef, Math.max(0, ATTACHMENTS_TOTAL_MAX_BYTES - untracked.reduce((sum, item) => sum + item.bytes, 0)));
3093
3093
  return {
3094
3094
  changeText,
3095
3095
  conversation: curated.conversation,
3096
3096
  draftText,
3097
3097
  preferences,
3098
3098
  scout: curated.scout,
3099
- tracked: tracked2,
3100
- untracked: untracked2
3099
+ tracked,
3100
+ untracked
3101
3101
  };
3102
3102
  };
3103
3103
 
@@ -3161,11 +3161,11 @@ var parseAutomaticDecision = (text) => {
3161
3161
  if (!subsequent) {
3162
3162
  continue;
3163
3163
  }
3164
- const repeated2 = namedGroups(subsequent).decision.trim().toLowerCase();
3164
+ const repeated = namedGroups(subsequent).decision.trim().toLowerCase();
3165
3165
  if (openingFence) {
3166
- pendingFencedDecisions.push(repeated2);
3166
+ pendingFencedDecisions.push(repeated);
3167
3167
  } else {
3168
- decisions.push(repeated2);
3168
+ decisions.push(repeated);
3169
3169
  }
3170
3170
  }
3171
3171
  if (openingFence) {
@@ -4251,13 +4251,13 @@ Advisor flow ready — Executor: ${activeExecutorRef} (thinking: ${activeExecuto
4251
4251
  };
4252
4252
 
4253
4253
  // src/commands/lifecycle.ts
4254
- var registerCommandLifecycle = (runtime, activateAdvisor2) => {
4254
+ var registerCommandLifecycle = (runtime, activateAdvisor) => {
4255
4255
  runtime.pi.on("session_start", async (_event, ctx) => {
4256
4256
  runtime.pendingExecutorModelRef = undefined;
4257
4257
  try {
4258
4258
  loadConfig(ctx);
4259
4259
  if (alwaysOnRef) {
4260
- await activateAdvisor2("", ctx, false);
4260
+ await activateAdvisor("", ctx, false);
4261
4261
  }
4262
4262
  } catch (error) {
4263
4263
  const message = error instanceof Error ? error.message : String(error);
@@ -4652,12 +4652,12 @@ var connectionFailure = (error) => {
4652
4652
  failure: new JevFailureError("network", `Jev connection failed: ${message}`)
4653
4653
  };
4654
4654
  };
4655
- var sleepWithAbort = (signal, ms) => new Promise((resolve2) => {
4656
- const timer = setTimeout(resolve2, ms);
4655
+ var sleepWithAbort = (signal, ms) => new Promise((resolve) => {
4656
+ const timer = setTimeout(resolve, ms);
4657
4657
  timer.unref?.();
4658
4658
  signal.addEventListener("abort", () => {
4659
4659
  clearTimeout(timer);
4660
- resolve2();
4660
+ resolve();
4661
4661
  }, { once: true });
4662
4662
  });
4663
4663
 
@@ -5644,56 +5644,6 @@ import { getKeybindings } from "@earendil-works/pi-tui";
5644
5644
  import { Key as Key2, matchesKey as matchesKey2, truncateToWidth as truncateToWidth5 } from "@earendil-works/pi-tui";
5645
5645
 
5646
5646
  // node_modules/@typesafe-ai/sdk/dist/index.mjs
5647
- var requestIdFrom = (headers) => headers.get("x-typesafe-request-id") ?? undefined;
5648
- var APIPromise = class APIPromise2 extends Promise {
5649
- #responsePromise;
5650
- #parseResponse;
5651
- #parsed;
5652
- constructor(responsePromise, parseResponse) {
5653
- super((resolve2) => resolve2(undefined));
5654
- this.#responsePromise = responsePromise;
5655
- this.#parseResponse = parseResponse;
5656
- }
5657
- asResponse() {
5658
- return this.#responsePromise;
5659
- }
5660
- async withResponse() {
5661
- const [data, response] = await Promise.all([this.#parse(), this.#responsePromise]);
5662
- return {
5663
- data,
5664
- response,
5665
- requestId: requestIdFrom(response.headers)
5666
- };
5667
- }
5668
- map(fn) {
5669
- return new APIPromise2(this.#responsePromise, () => this.#parse().then(fn));
5670
- }
5671
- #parse() {
5672
- this.#parsed ??= this.#responsePromise.then(this.#parseResponse);
5673
- return this.#parsed;
5674
- }
5675
- then(onfulfilled, onrejected) {
5676
- return this.#parse().then(onfulfilled, onrejected);
5677
- }
5678
- catch(onrejected) {
5679
- return this.#parse().catch(onrejected);
5680
- }
5681
- finally(onfinally) {
5682
- return this.#parse().finally(onfinally);
5683
- }
5684
- };
5685
- var ENV = {
5686
- apiKey: "TYPESAFE_API_KEY",
5687
- baseURL: "TYPESAFE_BASE_URL",
5688
- defaultModel: "TYPESAFE_DEFAULT_MODEL",
5689
- logLevel: "TYPESAFE_LOG_LEVEL"
5690
- };
5691
- var readEnv = (name) => {
5692
- if (typeof process === "undefined" || !process.env)
5693
- return;
5694
- return process.env[name]?.trim() || undefined;
5695
- };
5696
- var fromCodeOrEnv = (fromCode, envVar) => fromCode ?? readEnv(envVar);
5697
5647
  var range2 = (from, to) => Array.from({ length: to - from }, (_, i) => from + i);
5698
5648
  var DEFAULT_RETRY_POLICY = {
5699
5649
  maxRetries: 2,
@@ -5711,239 +5661,11 @@ var DEFAULT_RETRY_POLICY = {
5711
5661
  apiTimeoutError: true
5712
5662
  };
5713
5663
  DEFAULT_RETRY_POLICY.maxRetries;
5714
- var isRetryableStatus = (status, policy = DEFAULT_RETRY_POLICY) => policy.httpStatuses.has(status);
5715
- var parseRetryAfter = (headers, now = Date.now()) => {
5716
- const ms = Number(headers.get("retry-after-ms"));
5717
- if (headers.has("retry-after-ms") && Number.isFinite(ms) && ms >= 0)
5718
- return ms;
5719
- const raw = headers.get("retry-after");
5720
- if (raw === null)
5721
- return;
5722
- const seconds = Number(raw);
5723
- if (Number.isFinite(seconds))
5724
- return seconds >= 0 ? seconds * 1000 : undefined;
5725
- const date = Date.parse(raw);
5726
- if (!Number.isNaN(date))
5727
- return Math.max(0, date - now);
5728
- };
5729
- var retryDelayMs = (attempt, headers, policy = DEFAULT_RETRY_POLICY, random = Math.random) => {
5730
- if (policy.respectRetryAfter && headers !== undefined) {
5731
- const retryAfter = parseRetryAfter(headers);
5732
- if (retryAfter !== undefined && retryAfter <= policy.maxRetryAfterMs)
5733
- return retryAfter;
5734
- }
5735
- const exponential = Math.min(policy.backoffInitialMs * 2 ** attempt, policy.backoffMaxMs);
5736
- return Math.round(exponential * (1 - random() * policy.backoffJitter));
5737
- };
5738
- var sleep = (ms, signal) => new Promise((resolve2, reject) => {
5739
- if (signal?.aborted)
5740
- return reject(signal.reason);
5741
- const onAbort = () => {
5742
- clearTimeout(timer);
5743
- reject(signal?.reason);
5744
- };
5745
- const timer = setTimeout(() => {
5746
- signal?.removeEventListener("abort", onAbort);
5747
- resolve2();
5748
- }, ms);
5749
- signal?.addEventListener("abort", onAbort, { once: true });
5750
- });
5751
- var TypeSafeError = class extends Error {
5752
- constructor(message, options) {
5753
- super(message, options);
5754
- this.name = new.target.name;
5755
- }
5756
- };
5757
- var isRecord2 = (value) => typeof value === "object" && value !== null;
5758
- var extractMessage = (body) => {
5759
- if (typeof body === "string")
5760
- return body || undefined;
5761
- if (!isRecord2(body))
5762
- return;
5763
- const { error, message, detail } = body;
5764
- if (typeof error === "string")
5765
- return error;
5766
- if (isRecord2(error) && typeof error.message === "string")
5767
- return error.message;
5768
- if (typeof message === "string")
5769
- return message;
5770
- if (typeof detail === "string")
5771
- return detail;
5772
- if (isRecord2(detail) && typeof detail.message === "string")
5773
- return detail.message;
5774
- if (Array.isArray(detail))
5775
- return describeValidationErrors(detail);
5776
- };
5777
- var describeValidationErrors = (errors) => {
5778
- const parts = errors.flatMap((e) => {
5779
- if (!isRecord2(e) || typeof e.msg !== "string")
5780
- return [];
5781
- const loc = Array.isArray(e.loc) ? e.loc.filter((x) => x !== "body").join(".") : "";
5782
- return [loc ? `${loc}: ${e.msg}` : e.msg];
5783
- });
5784
- return parts.length > 0 ? parts.join("; ") : undefined;
5785
- };
5786
- var MAX_RAW_BODY_IN_MESSAGE = 200;
5787
- var APIError = class APIError2 extends TypeSafeError {
5788
- status;
5789
- headers;
5790
- body;
5791
- requestId;
5792
- constructor(status, body, headers, message) {
5793
- super(message ?? APIError2.describe(status, body));
5794
- this.status = status;
5795
- this.body = body;
5796
- this.headers = headers;
5797
- this.requestId = requestIdFrom(headers);
5798
- }
5799
- static describe(status, body) {
5800
- const detail = extractMessage(body);
5801
- if (detail)
5802
- return `${status} ${detail}`;
5803
- if (body === undefined)
5804
- return `${status} status code (no body)`;
5805
- const raw = typeof body === "string" ? body : JSON.stringify(body);
5806
- return `${status} ${raw.length > MAX_RAW_BODY_IN_MESSAGE ? `${raw.slice(0, MAX_RAW_BODY_IN_MESSAGE)}…` : raw}`;
5807
- }
5808
- static fromResponse(status, body, headers) {
5809
- if (status === 400)
5810
- return new BadRequestError(status, body, headers);
5811
- if (status === 401)
5812
- return new AuthenticationError(status, body, headers);
5813
- if (status === 403)
5814
- return new PermissionDeniedError(status, body, headers);
5815
- if (status === 404)
5816
- return new NotFoundError(status, body, headers);
5817
- if (status === 422)
5818
- return new UnprocessableEntityError(status, body, headers);
5819
- if (status === 429)
5820
- return new RateLimitError(status, body, headers);
5821
- if (status >= 500)
5822
- return new InternalServerError(status, body, headers);
5823
- return new APIError2(status, body, headers);
5824
- }
5825
- };
5826
- var BadRequestError = class extends APIError {
5827
- };
5828
- var AuthenticationError = class extends APIError {
5829
- };
5830
- var PermissionDeniedError = class extends APIError {
5831
- };
5832
- var NotFoundError = class extends APIError {
5833
- };
5834
- var UnprocessableEntityError = class extends APIError {
5835
- };
5836
- var RateLimitError = class extends APIError {
5837
- retryAfterMs = parseRetryAfter(this.headers);
5838
- };
5839
- var InternalServerError = class extends APIError {
5840
- };
5841
- var APIConnectionError = class extends TypeSafeError {
5842
- constructor(message = "Connection error.", options) {
5843
- super(message, options);
5844
- }
5845
- };
5846
- var APITimeoutError = class extends APIConnectionError {
5847
- timeoutMs;
5848
- constructor(timeoutMs, options) {
5849
- super(`Request timed out after ${timeoutMs}ms.`, options);
5850
- this.timeoutMs = timeoutMs;
5851
- }
5852
- };
5853
- var APIUserAbortError = class extends TypeSafeError {
5854
- constructor(message = "Request was aborted.", options) {
5855
- super(message, options);
5856
- }
5857
- };
5858
- var LOG_LEVELS = [
5859
- "debug",
5860
- "info",
5861
- "warn",
5862
- "error",
5863
- "off"
5864
- ];
5865
- var DEFAULT_LOG_LEVEL = "warn";
5866
- var isLogLevel = (value) => LOG_LEVELS.includes(value);
5867
- var parseLogLevel = (value, source) => {
5868
- if (isLogLevel(value))
5869
- return value;
5870
- throw new TypeSafeError(`Invalid log level "${value}" from ${source}. Expected one of: ${LOG_LEVELS.join(", ")}.`);
5871
- };
5872
- var PREFIX = "[typesafe-sdk]";
5873
- var consoleLogger = {
5874
- debug: (message, ...args) => console.debug(`${PREFIX} ${message}`, ...args),
5875
- info: (message, ...args) => console.info(`${PREFIX} ${message}`, ...args),
5876
- warn: (message, ...args) => console.warn(`${PREFIX} ${message}`, ...args),
5877
- error: (message, ...args) => console.error(`${PREFIX} ${message}`, ...args)
5878
- };
5879
- var RANK = {
5880
- debug: 0,
5881
- info: 1,
5882
- warn: 2,
5883
- error: 3,
5884
- off: 4
5885
- };
5886
- var drop = () => {};
5887
- var withLevel = (sink, level) => {
5888
- const enabled = (at) => RANK[at] >= RANK[level];
5889
- return {
5890
- debug: enabled("debug") ? (message, ...args) => sink.debug(message, ...args) : drop,
5891
- info: enabled("info") ? (message, ...args) => sink.info(message, ...args) : drop,
5892
- warn: enabled("warn") ? (message, ...args) => sink.warn(message, ...args) : drop,
5893
- error: enabled("error") ? (message, ...args) => sink.error(message, ...args) : drop
5894
- };
5895
- };
5896
- var KEY_HEADERS = /* @__PURE__ */ new Set([
5897
- "authorization",
5898
- "proxy-authorization",
5899
- "x-api-key"
5900
- ]);
5901
- var OPAQUE_HEADERS = /* @__PURE__ */ new Set(["cookie", "set-cookie"]);
5902
- var redactKey = (value) => {
5903
- const [scheme, secret] = value.includes(" ") ? value.split(/\s+/, 2) : [undefined, value];
5904
- const tail = secret && secret.length > 8 ? secret.slice(-4) : "";
5905
- return `${scheme ? `${scheme} ` : ""}***${tail}`;
5906
- };
5907
- var redact = (name, value) => {
5908
- const lower = name.toLowerCase();
5909
- if (KEY_HEADERS.has(lower))
5910
- return redactKey(value);
5911
- if (OPAQUE_HEADERS.has(lower))
5912
- return "***";
5913
- return value;
5914
- };
5915
- var redactHeaders = (headers) => Object.fromEntries(Object.entries(headers).map(([name, value]) => [name, redact(name, value)]));
5916
5664
  var noul = (instructions = null, criteria) => ({
5917
5665
  type: "noul",
5918
5666
  instructions,
5919
5667
  criteria
5920
5668
  });
5921
- var validateQuestions = (questions) => {
5922
- if (Object.keys(questions).length === 0)
5923
- throw new TypeSafeError("At least one question is required.");
5924
- for (const [name, question] of Object.entries(questions)) {
5925
- if (question.type !== "score")
5926
- continue;
5927
- if (!Array.isArray(question.criteria))
5928
- throw new TypeSafeError(`Score question "${name}" has criteria that are not a list; score criteria must be a list of descriptions indexed by score from zero.`);
5929
- if (question.criteria.length < 2)
5930
- throw new TypeSafeError(`Score question "${name}" has ${question.criteria.length} criteria; at least two scores are required.`);
5931
- }
5932
- };
5933
- var Models = class {
5934
- #transport;
5935
- constructor(transport) {
5936
- this.#transport = transport;
5937
- }
5938
- list(options = {}) {
5939
- return this.#transport.request("GET", "/v1/models", options).map(unwrapModels);
5940
- }
5941
- };
5942
- var unwrapModels = (wire) => {
5943
- if (Array.isArray(wire?.models))
5944
- return wire.models;
5945
- throw new TypeSafeError("Unexpected response shape from GET /v1/models; expected { models: [...] }.");
5946
- };
5947
5669
  var g = globalThis;
5948
5670
  var isBrowser = () => typeof g.window !== "undefined" && typeof g.window.document !== "undefined" && typeof g.navigator !== "undefined";
5949
5671
  var describeRuntime = () => {
@@ -5962,280 +5684,7 @@ var describeRuntime = () => {
5962
5684
  return "browser";
5963
5685
  return "unknown";
5964
5686
  };
5965
- var VERSION = "0.6.0";
5966
- var missingApiKey = () => {
5967
- throw new TypeSafeError(`No API key was provided. Pass \`apiKey\` to the TypeSafeClient constructor or set the ${ENV.apiKey} environment variable.`);
5968
- };
5969
- var missingFetch = () => {
5970
- throw new TypeSafeError("No global `fetch` is available in this runtime. Pass a `fetch` implementation to the TypeSafeClient constructor.");
5971
- };
5972
- var refuseBrowser = () => {
5973
- throw new TypeSafeError("TypeSafeClient is running in a browser, which would expose your API key to anyone using the page. Call the API from a server instead, or pass `dangerouslyAllowBrowser: true` if you understand the risk.");
5974
- };
5975
- var defaultFetch = (input, init) => globalThis.fetch(input, init);
5976
- var assertNonNegativeInteger = (name, value) => {
5977
- if (!Number.isInteger(value) || value < 0)
5978
- throw new TypeSafeError(`\`${name}\` must be a non-negative integer, got ${String(value)}.`);
5979
- return value;
5980
- };
5981
- var assertPositiveMs = (name, value) => {
5982
- if (!Number.isFinite(value) || value <= 0)
5983
- throw new TypeSafeError(`\`${name}\` must be a positive number of milliseconds, got ${String(value)}.`);
5984
- return value;
5985
- };
5986
- var assertNonNegativeMs = (name, value) => {
5987
- if (!Number.isFinite(value) || value < 0)
5988
- throw new TypeSafeError(`\`${name}\` must be a non-negative number of milliseconds, got ${String(value)}.`);
5989
- return value;
5990
- };
5991
- var assertFraction = (name, value) => {
5992
- if (!Number.isFinite(value) || value < 0 || value > 1)
5993
- throw new TypeSafeError(`\`${name}\` must be between 0 and 1, got ${String(value)}.`);
5994
- return value;
5995
- };
5996
- var assertStatusSet = (name, statuses) => {
5997
- for (const status of statuses)
5998
- if (!Number.isInteger(status) || status < 100 || status > 999)
5999
- throw new TypeSafeError(`\`${name}\` must contain HTTP status codes, got ${String(status)}.`);
6000
- return statuses;
6001
- };
6002
- var resolveRetryPolicy = (base, overrides) => {
6003
- const o = overrides ?? {};
6004
- return {
6005
- maxRetries: o.maxRetries === undefined ? base.maxRetries : assertNonNegativeInteger("retry.maxRetries", o.maxRetries),
6006
- backoffInitialMs: o.backoffInitialMs === undefined ? base.backoffInitialMs : assertNonNegativeMs("retry.backoffInitialMs", o.backoffInitialMs),
6007
- backoffMaxMs: o.backoffMaxMs === undefined ? base.backoffMaxMs : assertNonNegativeMs("retry.backoffMaxMs", o.backoffMaxMs),
6008
- backoffJitter: o.backoffJitter === undefined ? base.backoffJitter : assertFraction("retry.backoffJitter", o.backoffJitter),
6009
- httpStatuses: new Set(o.httpStatuses === undefined ? base.httpStatuses : assertStatusSet("retry.httpStatuses", o.httpStatuses)),
6010
- respectRetryAfter: o.respectRetryAfter ?? base.respectRetryAfter,
6011
- maxRetryAfterMs: o.maxRetryAfterMs === undefined ? base.maxRetryAfterMs : assertNonNegativeMs("retry.maxRetryAfterMs", o.maxRetryAfterMs),
6012
- apiConnectionError: o.apiConnectionError ?? base.apiConnectionError,
6013
- apiTimeoutError: o.apiTimeoutError ?? base.apiTimeoutError
6014
- };
6015
- };
6016
- var isRetryableError = (err, policy) => {
6017
- if (err instanceof APITimeoutError)
6018
- return policy.apiTimeoutError;
6019
- if (err instanceof APIConnectionError)
6020
- return policy.apiConnectionError;
6021
- return false;
6022
- };
6023
- var resolveLogLevel = (fromCode) => {
6024
- if (fromCode !== undefined)
6025
- return parseLogLevel(fromCode, "the `logLevel` option");
6026
- const fromEnv = readEnv(ENV.logLevel);
6027
- if (fromEnv !== undefined)
6028
- return parseLogLevel(fromEnv, ENV.logLevel);
6029
- return DEFAULT_LOG_LEVEL;
6030
- };
6031
- var stripTrailingSlashes = (url) => url.replace(/\/+$/, "");
6032
- var mergeHeaders = (...sources) => {
6033
- const entries = /* @__PURE__ */ new Map;
6034
- for (const source of sources)
6035
- for (const [name, value] of Object.entries(source))
6036
- if (value === undefined)
6037
- entries.delete(name.toLowerCase());
6038
- else
6039
- entries.set(name.toLowerCase(), [name, value]);
6040
- return Object.fromEntries(entries.values());
6041
- };
6042
- var bufferResponse = async (response, signal) => {
6043
- const reader = response.clone().body?.getReader();
6044
- if (!reader)
6045
- return;
6046
- const cancel = () => {
6047
- reader.cancel(signal.reason).catch(() => {});
6048
- response.body?.cancel(signal.reason).catch(() => {});
6049
- };
6050
- signal.addEventListener("abort", cancel, { once: true });
6051
- try {
6052
- if (signal.aborted)
6053
- cancel();
6054
- signal.throwIfAborted();
6055
- while (!(await reader.read()).done)
6056
- signal.throwIfAborted();
6057
- signal.throwIfAborted();
6058
- } finally {
6059
- signal.removeEventListener("abort", cancel);
6060
- reader.releaseLock();
6061
- }
6062
- };
6063
5687
  var RUNTIME = describeRuntime();
6064
- var TypeSafeClient = class {
6065
- #apiKey;
6066
- baseURL;
6067
- defaultModel;
6068
- logLevel;
6069
- logger;
6070
- retry;
6071
- timeout;
6072
- defaultHeaders;
6073
- fetch;
6074
- models;
6075
- #requestCount = 0;
6076
- constructor(config = {}) {
6077
- if (isBrowser() && !config.dangerouslyAllowBrowser)
6078
- refuseBrowser();
6079
- this.#apiKey = fromCodeOrEnv(config.apiKey, ENV.apiKey) ?? missingApiKey();
6080
- this.baseURL = stripTrailingSlashes(fromCodeOrEnv(config.baseURL, ENV.baseURL) ?? "https://api.typesafe.ai");
6081
- this.defaultModel = fromCodeOrEnv(config.defaultModel, ENV.defaultModel) ?? "jev-latest";
6082
- this.logLevel = resolveLogLevel(config.logLevel);
6083
- this.logger = withLevel(config.logger ?? consoleLogger, this.logLevel);
6084
- this.retry = resolveRetryPolicy(DEFAULT_RETRY_POLICY, config.retry);
6085
- this.timeout = assertPositiveMs("timeout", config.timeout ?? 1e4);
6086
- this.defaultHeaders = { ...config.defaultHeaders };
6087
- if (config.fetch === undefined && typeof globalThis.fetch !== "function")
6088
- missingFetch();
6089
- this.fetch = config.fetch ?? defaultFetch;
6090
- const transport = {
6091
- request: (method, path, options) => this.#request(method, path, options),
6092
- defaultModel: this.defaultModel
6093
- };
6094
- this.models = new Models(transport);
6095
- }
6096
- systemOne(request, options = {}) {
6097
- validateQuestions(request.questions);
6098
- const body = {
6099
- ...request,
6100
- model: request.model ?? this.defaultModel
6101
- };
6102
- return this.#request("POST", "/v1/systemone", {
6103
- ...options,
6104
- body
6105
- });
6106
- }
6107
- #request(method, path, options = {}) {
6108
- const resolved = {
6109
- method,
6110
- path,
6111
- body: options.body,
6112
- headers: mergeHeaders(this.defaultHeaders, options.headers ?? {}),
6113
- signal: options.signal,
6114
- timeout: options.timeout === undefined ? this.timeout : assertPositiveMs("timeout", options.timeout),
6115
- retry: resolveRetryPolicy(this.retry, options.retry)
6116
- };
6117
- const tag = `#${++this.#requestCount} ${method} ${path}`;
6118
- return new APIPromise(this.fetchWithRetries(tag, resolved), async (res) => {
6119
- const parsed = await parseBody(res);
6120
- this.logger.debug(`${tag} <- body`, parsed);
6121
- return parsed;
6122
- });
6123
- }
6124
- async fetchWithRetries(tag, req) {
6125
- const url = `${this.baseURL}${req.path}`;
6126
- const headers = mergeHeaders(req.headers, {
6127
- Authorization: `Bearer ${this.#apiKey}`,
6128
- Accept: "application/json",
6129
- "User-Agent": `typesafe-sdk/${VERSION}`,
6130
- "X-TypeSafe-SDK": `typesafe-sdk/${VERSION}`,
6131
- "X-TypeSafe-Runtime": RUNTIME,
6132
- "Content-Type": req.body === undefined ? undefined : "application/json",
6133
- "X-TypeSafe-Retry-Count": undefined
6134
- });
6135
- const body = req.body === undefined ? undefined : JSON.stringify(req.body);
6136
- for (let attempt = 0;; attempt++) {
6137
- const retriesLeft = req.retry.maxRetries - attempt;
6138
- const attemptHeaders = attempt === 0 ? headers : {
6139
- ...headers,
6140
- "X-TypeSafe-Retry-Count": String(attempt)
6141
- };
6142
- this.logger.debug(`${tag} -> ${url}`, {
6143
- headers: redactHeaders(attemptHeaders),
6144
- body: req.body
6145
- });
6146
- const started = Date.now();
6147
- let res;
6148
- try {
6149
- res = await this.attempt(tag, url, {
6150
- method: req.method,
6151
- headers: attemptHeaders,
6152
- body
6153
- }, req);
6154
- } catch (err) {
6155
- if (err instanceof APIUserAbortError || retriesLeft <= 0)
6156
- throw err;
6157
- if (!isRetryableError(err, req.retry))
6158
- throw err;
6159
- await this.backOff(tag, attempt, retriesLeft, err.message, undefined, req);
6160
- continue;
6161
- }
6162
- const requestId = requestIdFrom(res.headers);
6163
- this.logger.info(`${tag} <- ${res.status} in ${Date.now() - started}ms${requestId ? ` (request ${requestId})` : ""}`);
6164
- if (res.ok)
6165
- return res;
6166
- const errorBody = await parseBody(res);
6167
- this.logger.debug(`${tag} <- error body`, errorBody);
6168
- const error = APIError.fromResponse(res.status, errorBody, res.headers);
6169
- if (retriesLeft <= 0 || !isRetryableStatus(res.status, req.retry))
6170
- throw error;
6171
- await this.backOff(tag, attempt, retriesLeft, `${res.status}`, res.headers, req);
6172
- }
6173
- }
6174
- async attempt(tag, url, init, { signal, timeout }) {
6175
- const controller = new AbortController;
6176
- const abortFromCaller = () => controller.abort(signal?.reason);
6177
- if (signal?.aborted)
6178
- abortFromCaller();
6179
- signal?.addEventListener("abort", abortFromCaller, { once: true });
6180
- let timedOut = false;
6181
- const timer = setTimeout(() => {
6182
- timedOut = true;
6183
- controller.abort();
6184
- }, timeout);
6185
- const started = Date.now();
6186
- const elapsed = () => `${Date.now() - started}ms`;
6187
- try {
6188
- const response = await this.fetch(url, {
6189
- ...init,
6190
- signal: controller.signal
6191
- });
6192
- await bufferResponse(response, controller.signal);
6193
- return response;
6194
- } catch (err) {
6195
- if (signal?.aborted) {
6196
- this.logger.info(`${tag} aborted by caller after ${elapsed()}`);
6197
- throw new APIUserAbortError(undefined, { cause: err });
6198
- }
6199
- if (timedOut) {
6200
- this.logger.info(`${tag} timed out after ${elapsed()}`);
6201
- throw new APITimeoutError(timeout, { cause: err });
6202
- }
6203
- this.logger.info(`${tag} connection error after ${elapsed()}`, err);
6204
- throw new APIConnectionError(err instanceof Error ? `Connection error: ${err.message}` : undefined, { cause: err });
6205
- } finally {
6206
- clearTimeout(timer);
6207
- signal?.removeEventListener("abort", abortFromCaller);
6208
- }
6209
- }
6210
- async backOff(tag, attempt, retriesLeft, reason, headers, { retry, signal }) {
6211
- const delay = retryDelayMs(attempt, headers, retry);
6212
- const nth = attempt + 1;
6213
- const total = attempt + retriesLeft;
6214
- this.logger.info(`${tag} retrying in ${delay}ms (retry ${nth}/${total}) after ${reason}`);
6215
- try {
6216
- await sleep(delay, signal);
6217
- } catch (err) {
6218
- this.logger.info(`${tag} aborted by caller while waiting to retry`);
6219
- throw new APIUserAbortError(undefined, { cause: err });
6220
- }
6221
- }
6222
- };
6223
- var parseBody = async (res) => {
6224
- const text = await res.text();
6225
- if (text.length === 0)
6226
- return;
6227
- if ((res.headers.get("content-type") ?? "").includes("application/json"))
6228
- try {
6229
- return JSON.parse(text);
6230
- } catch {
6231
- return text;
6232
- }
6233
- try {
6234
- return JSON.parse(text);
6235
- } catch {
6236
- return text;
6237
- }
6238
- };
6239
5688
 
6240
5689
  // src/ui/masked-input.ts
6241
5690
  import { Input as Input2, truncateToWidth as truncateToWidth4 } from "@earendil-works/pi-tui";
@@ -7338,7 +6787,7 @@ import {
7338
6787
  writeFile
7339
6788
  } from "node:fs/promises";
7340
6789
  import { join as join5 } from "node:path";
7341
- import { setTimeout as sleep2 } from "node:timers/promises";
6790
+ import { setTimeout as sleep } from "node:timers/promises";
7342
6791
  import { getAgentDir as getAgentDir4 } from "@earendil-works/pi-coding-agent";
7343
6792
  var ADOPTIONS = [
7344
6793
  "followed",
@@ -7426,7 +6875,7 @@ var withOutcomeLock = async (run) => {
7426
6875
  }
7427
6876
  continue;
7428
6877
  }
7429
- await sleep2(5);
6878
+ await sleep(5);
7430
6879
  }
7431
6880
  }
7432
6881
  throw new Error("Timed out waiting to append an Advisor outcome.");
@@ -8328,8 +7777,8 @@ function registerPiAdvisor(pi) {
8328
7777
  });
8329
7778
  }
8330
7779
  export {
8331
- runAdvisorGate2 as runAdvisorGate,
8332
- parseAutomaticDecision2 as parseAutomaticDecision,
7780
+ consultAdvisor2 as consultAdvisor,
8333
7781
  registerPiAdvisor as default,
8334
- consultAdvisor2 as consultAdvisor
7782
+ parseAutomaticDecision2 as parseAutomaticDecision,
7783
+ runAdvisorGate2 as runAdvisorGate
8335
7784
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-advisor-flow",
3
- "version": "0.8.1-dev.1",
3
+ "version": "0.8.1",
4
4
  "description": "Advanced Executor/Advisor flow for Pi, fully configurable and extendable.",
5
5
  "keywords": [
6
6
  "advisor",