@prestyj/agent 5.29.0 → 5.30.0

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/dist/index.d.cts CHANGED
@@ -80,6 +80,11 @@ declare function buildStreamRuleReminder(rules: readonly StreamRule[]): Message;
80
80
  interface StructuredToolResult {
81
81
  content: ToolResultContent;
82
82
  details?: unknown;
83
+ /** End the run after persisting this result, without another model call or
84
+ * draining steering/follow-ups. Use a sequential tool to also prevent later
85
+ * calls in the same batch from running (e.g. a pending plan-review handoff).
86
+ * Host control metadata only: never serialized into provider tool results. */
87
+ endRun?: boolean;
83
88
  }
84
89
  type ToolExecuteResult = string | StructuredToolResult;
85
90
  interface ToolContext {
@@ -359,6 +364,10 @@ interface AgentOptions {
359
364
  defaultHeaders?: StreamOptions["defaultHeaders"];
360
365
  /** OpenAI service tier for latency-sensitive first-party API requests. */
361
366
  serviceTier?: StreamOptions["serviceTier"];
367
+ /** Codex Responses-Lite request shape override (see StreamOptions). */
368
+ responsesLite?: StreamOptions["responsesLite"];
369
+ /** Codex strict tool schema override (see StreamOptions). */
370
+ strictTools?: StreamOptions["strictTools"];
362
371
  /** Whether the target model supports image input. When false, image blocks
363
372
  * in messages/tool_results are downgraded to text placeholders. Default: true. */
364
373
  supportsImages?: boolean;
package/dist/index.d.ts CHANGED
@@ -80,6 +80,11 @@ declare function buildStreamRuleReminder(rules: readonly StreamRule[]): Message;
80
80
  interface StructuredToolResult {
81
81
  content: ToolResultContent;
82
82
  details?: unknown;
83
+ /** End the run after persisting this result, without another model call or
84
+ * draining steering/follow-ups. Use a sequential tool to also prevent later
85
+ * calls in the same batch from running (e.g. a pending plan-review handoff).
86
+ * Host control metadata only: never serialized into provider tool results. */
87
+ endRun?: boolean;
83
88
  }
84
89
  type ToolExecuteResult = string | StructuredToolResult;
85
90
  interface ToolContext {
@@ -359,6 +364,10 @@ interface AgentOptions {
359
364
  defaultHeaders?: StreamOptions["defaultHeaders"];
360
365
  /** OpenAI service tier for latency-sensitive first-party API requests. */
361
366
  serviceTier?: StreamOptions["serviceTier"];
367
+ /** Codex Responses-Lite request shape override (see StreamOptions). */
368
+ responsesLite?: StreamOptions["responsesLite"];
369
+ /** Codex strict tool schema override (see StreamOptions). */
370
+ strictTools?: StreamOptions["strictTools"];
362
371
  /** Whether the target model supports image input. When false, image blocks
363
372
  * in messages/tool_results are downgraded to text placeholders. Default: true. */
364
373
  supportsImages?: boolean;
package/dist/index.js CHANGED
@@ -871,6 +871,8 @@ async function* agentLoop(messages, options) {
871
871
  onContextPrepared: options.onContextPrepared,
872
872
  promptCacheKey: options.promptCacheKey,
873
873
  serviceTier: options.serviceTier,
874
+ responsesLite: options.responsesLite,
875
+ strictTools: options.strictTools,
874
876
  supportsImages: options.supportsImages,
875
877
  supportsVideo: options.supportsVideo,
876
878
  compaction: options.compaction,
@@ -1582,6 +1584,7 @@ async function* agentLoop(messages, options) {
1582
1584
  }
1583
1585
  messages.push({ role: "tool", content: executionResult.toolResults });
1584
1586
  yield { type: "checkpoint", turn };
1587
+ if (executionResult.endRun) break;
1585
1588
  const toolsAborted = executionResult.aborted;
1586
1589
  if (fatalToolArgumentError) {
1587
1590
  if (fatalToolArgumentRecoverable && !toolArgumentAutoContinueUsed) {
@@ -1718,6 +1721,7 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
1718
1721
  let resultContent;
1719
1722
  let details;
1720
1723
  let isError = false;
1724
+ let endRun = false;
1721
1725
  let invalidArgAttempt;
1722
1726
  const tool = options.toolMap.get(toolCall.name);
1723
1727
  if (tool) {
@@ -1776,6 +1780,7 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
1776
1780
  hardSignals.length === 1 ? toolTimeout : AbortSignal.any(hardSignals)
1777
1781
  );
1778
1782
  const normalized = normalizeToolResult(raw);
1783
+ endRun = normalized.endRun === true;
1779
1784
  resultContent = redactValue(normalized.content, toolRedactionOptions());
1780
1785
  details = redactValue(normalized.details, toolRedactionOptions());
1781
1786
  if (options.transformToolResult) {
@@ -1847,11 +1852,12 @@ ${hints}` : "") + "\nRe-issue the call with each field as the correct type.";
1847
1852
  durationMs,
1848
1853
  ...invalidArgAttempt === void 0 ? {} : { invalidArgAttempt }
1849
1854
  });
1850
- return { toolCallId: toolCall.id, content: resultContent, isError };
1855
+ return { toolCallId: toolCall.id, content: resultContent, isError, endRun: endRun && !isError };
1851
1856
  }
1852
1857
  function createPreemptTracker(options, eventStream, state, resultsById, dispatchedIds) {
1853
1858
  const running = /* @__PURE__ */ new Map();
1854
1859
  let graceTimer;
1860
+ let endRun = false;
1855
1861
  const preemptSignal = options.preemptSignal;
1856
1862
  const abandon = () => {
1857
1863
  graceTimer = void 0;
@@ -1875,7 +1881,7 @@ function createPreemptTracker(options, eventStream, state, resultsById, dispatch
1875
1881
  preemptSignal?.addEventListener("abort", onPreempt, { once: true });
1876
1882
  return {
1877
1883
  async run(toolCall) {
1878
- if (options.preemptSignal?.aborted) return;
1884
+ if (endRun || options.preemptSignal?.aborted) return;
1879
1885
  dispatchedIds.add(toolCall.id);
1880
1886
  const interruptible = isInterruptibleTool(options.toolMap.get(toolCall.name), toolCall.name);
1881
1887
  running.set(toolCall.id, { toolCall, interruptible, startedAt: Date.now() });
@@ -1887,15 +1893,15 @@ function createPreemptTracker(options, eventStream, state, resultsById, dispatch
1887
1893
  running.delete(toolCall.id);
1888
1894
  if (resultsById.has(toolCall.id)) return;
1889
1895
  const alreadyMarked = typeof record.content === "string" ? record.content.startsWith(STEER_INTERRUPTED_TEXT) : record.content[0]?.type === "text" && record.content[0].text.startsWith(STEER_INTERRUPTED_TEXT);
1890
- resultsById.set(
1891
- toolCall.id,
1892
- interruptible && preemptSignal?.aborted && !alreadyMarked ? markSteerInterrupted(record) : record
1893
- );
1896
+ const result = interruptible && preemptSignal?.aborted && !alreadyMarked ? markSteerInterrupted(record) : record;
1897
+ resultsById.set(toolCall.id, result);
1898
+ if (result.endRun && !result.isError) endRun = true;
1894
1899
  if (preemptSignal?.aborted && graceTimer === void 0 && running.size === 0) {
1895
1900
  eventStream.close();
1896
1901
  }
1897
1902
  },
1898
1903
  preempted: () => preemptSignal?.aborted === true,
1904
+ endRun: () => endRun,
1899
1905
  dispose: () => {
1900
1906
  if (graceTimer !== void 0) clearTimeout(graceTimer);
1901
1907
  preemptSignal?.removeEventListener("abort", onPreempt);
@@ -1930,7 +1936,7 @@ async function* executeToolCallsMixed(toolCalls, initialToolResults, options) {
1930
1936
  void (async () => {
1931
1937
  try {
1932
1938
  for (const phase of phases) {
1933
- if (options.signal?.aborted || options.preemptSignal?.aborted) break;
1939
+ if (options.signal?.aborted || options.preemptSignal?.aborted || tracker.endRun()) break;
1934
1940
  if (phase.sequential) {
1935
1941
  const signature = JSON.stringify([
1936
1942
  phase.sequential.name,
@@ -1968,7 +1974,12 @@ async function* executeToolCallsMixed(toolCalls, initialToolResults, options) {
1968
1974
  const toolResults = buildToolResults(initialToolResults, toolCalls, resultsById, dispatchedIds);
1969
1975
  capToolResults(toolResults, options.maxToolResultChars);
1970
1976
  capTurnToolResults(toolResults, options.maxTurnToolResultChars);
1971
- return { toolResults, aborted, preempted: !aborted && tracker.preempted() };
1977
+ return {
1978
+ toolResults,
1979
+ aborted,
1980
+ preempted: !aborted && tracker.preempted(),
1981
+ endRun: tracker.endRun()
1982
+ };
1972
1983
  }
1973
1984
  async function* executeToolCallsParallel(toolCalls, initialToolResults, options) {
1974
1985
  const eventStream = new EventStream();
@@ -2002,7 +2013,12 @@ async function* executeToolCallsParallel(toolCalls, initialToolResults, options)
2002
2013
  const toolResults = buildToolResults(initialToolResults, toolCalls, resultsById, dispatchedIds);
2003
2014
  capToolResults(toolResults, options.maxToolResultChars);
2004
2015
  capTurnToolResults(toolResults, options.maxTurnToolResultChars);
2005
- return { toolResults, aborted, preempted: !aborted && tracker.preempted() };
2016
+ return {
2017
+ toolResults,
2018
+ aborted,
2019
+ preempted: !aborted && tracker.preempted(),
2020
+ endRun: tracker.endRun()
2021
+ };
2006
2022
  }
2007
2023
  function cancelledBeforeStartText(name) {
2008
2024
  return `\`${name}\` was cancelled before it started, so it had no effect. Safe to retry.`;