@inflexa-ai/harness 0.18.0 → 0.19.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.
Files changed (83) hide show
  1. package/dist/agents/report-session-agent.d.ts +72 -0
  2. package/dist/agents/report-session-agent.js +87 -0
  3. package/dist/app/report-session-runtime.d.ts +72 -0
  4. package/dist/app/report-session-runtime.js +183 -0
  5. package/dist/app/spawn-report-session.d.ts +32 -5
  6. package/dist/app/spawn-report-session.js +19 -0
  7. package/dist/config/environment-stores.d.ts +12 -7
  8. package/dist/config/resource-limits.d.ts +6 -10
  9. package/dist/config/resource-limits.js +6 -44
  10. package/dist/contracts/report-reference.d.ts +4 -0
  11. package/dist/contracts/report-reference.js +3 -0
  12. package/dist/index.d.ts +2 -1
  13. package/dist/lib/chrome.d.ts +14 -0
  14. package/dist/lib/chrome.js +7 -0
  15. package/dist/lib/page-capture.d.ts +47 -0
  16. package/dist/lib/page-capture.js +83 -0
  17. package/dist/loop/run-agent.js +104 -15
  18. package/dist/memory/ai-sdk-message-storage.d.ts +9 -4
  19. package/dist/memory/ai-sdk-message-storage.js +9 -4
  20. package/dist/memory/count-tokens.js +34 -5
  21. package/dist/memory/thread-store.d.ts +4 -4
  22. package/dist/memory/thread-store.js +18 -9
  23. package/dist/prompts/report-session.d.ts +1 -0
  24. package/dist/prompts/report-session.js +110 -0
  25. package/dist/providers/ai-sdk.d.ts +158 -3
  26. package/dist/providers/ai-sdk.js +234 -23
  27. package/dist/providers/errors.d.ts +14 -0
  28. package/dist/providers/errors.js +103 -18
  29. package/dist/providers/types.d.ts +33 -0
  30. package/dist/providers/types.js +10 -1
  31. package/dist/report-model/assert-rules.d.ts +44 -0
  32. package/dist/report-model/assert-rules.js +97 -0
  33. package/dist/report-model/draft-hash.d.ts +14 -0
  34. package/dist/report-model/draft-hash.js +36 -0
  35. package/dist/report-model/fixture-resolver.js +2 -71
  36. package/dist/report-model/{mint-snapshot.d.ts → pin-snapshot.d.ts} +7 -7
  37. package/dist/report-model/{mint-snapshot.js → pin-snapshot.js} +7 -7
  38. package/dist/report-model/production-resolver.d.ts +124 -0
  39. package/dist/report-model/production-resolver.js +801 -0
  40. package/dist/report-model/reference-resolver.d.ts +7 -1
  41. package/dist/report-model/validate.d.ts +34 -2
  42. package/dist/report-model/validate.js +37 -17
  43. package/dist/report-render/page.d.ts +23 -0
  44. package/dist/report-render/page.js +36 -3
  45. package/dist/report-render/value-bridge.d.ts +62 -0
  46. package/dist/report-render/value-bridge.js +82 -0
  47. package/dist/runtime/assemble.d.ts +39 -0
  48. package/dist/runtime/assemble.js +67 -6
  49. package/dist/sandbox/mount-plan.d.ts +7 -0
  50. package/dist/sandbox/mount-plan.js +7 -2
  51. package/dist/state/init.js +36 -0
  52. package/dist/state/purge-analysis.js +1 -0
  53. package/dist/state/report-session-state.d.ts +139 -0
  54. package/dist/state/report-session-state.js +177 -0
  55. package/dist/state/report-versions.d.ts +3 -6
  56. package/dist/state/report-versions.js +11 -38
  57. package/dist/state/snapshot-parse.d.ts +34 -0
  58. package/dist/state/snapshot-parse.js +82 -0
  59. package/dist/tasks/extract-values-script.d.ts +64 -0
  60. package/dist/tasks/extract-values-script.js +180 -0
  61. package/dist/tasks/extract-values.d.ts +124 -0
  62. package/dist/tasks/extract-values.js +193 -0
  63. package/dist/tools/ad-hoc-router.d.ts +7 -2
  64. package/dist/tools/ad-hoc-router.js +2 -1
  65. package/dist/tools/define-tool.d.ts +29 -0
  66. package/dist/tools/define-tool.js +26 -0
  67. package/dist/tools/report/preview-snapshot.d.ts +1 -1
  68. package/dist/tools/report/preview-snapshot.js +11 -50
  69. package/dist/tools/report-authoring/authoring-tools.d.ts +181 -24
  70. package/dist/tools/report-authoring/authoring-tools.js +152 -44
  71. package/dist/tools/report-session/examine-page.d.ts +90 -0
  72. package/dist/tools/report-session/examine-page.js +136 -0
  73. package/dist/tools/report-session/index.d.ts +10 -0
  74. package/dist/tools/report-session/index.js +10 -0
  75. package/dist/tools/report-session/preview-report.d.ts +105 -0
  76. package/dist/tools/report-session/preview-report.js +269 -0
  77. package/dist/tools/report-session/record-version.d.ts +102 -0
  78. package/dist/tools/report-session/record-version.js +139 -0
  79. package/dist/tools/research/generate-plan.js +4 -2
  80. package/dist/tools/sandbox/list-available-packages.js +2 -1
  81. package/dist/tools/sandbox/list-available-refs.d.ts +5 -1
  82. package/dist/tools/sandbox/list-available-refs.js +13 -6
  83. package/package.json +10 -8
@@ -0,0 +1 @@
1
+ export declare const reportSessionPrompt = "# Report Builder\n\nYou compose a scientific report for the user, one block at a time, and you ground\nevery claim in the analysis. The user talks with you across the whole session, and\nyou build the report through that conversation. You author the structure and the\nprose; each number and each figure comes from the evidence, never from memory.\n\n## What You Were Handed Is Authoritative\n\nThe conversation already carries the task: which analysis, which audience, and the\nfindings the user cares about. Start from what is in front of you. Reach for a read\ntool only where the context is thin, and reach in a targeted way:\n\n- `inspect_data_profile` \u2014 what the dataset is: its design, its organism, its\n per-file types. Read it when you must state a fact about the data itself.\n- `inspect_run` \u2014 what a run produced, and where its outputs are. Read it when you\n must ground a claim in a run's results.\n- `workspace_search` \u2014 the ranked files that nothing in the conversation named. It\n gives descriptions and metadata, not contents.\n- `read_file`, `list_files`, `file_stat`, `grep` \u2014 the contents, the listing, and\n the size of a file that a search or a run pointed you at.\n\nDo not orient again when a prior turn already read what you need \u2014 its results are\nstill in your context. To reach further is targeted, not a fresh sweep.\n\n## Compose from Typed Blocks\n\nA report is a tree of typed blocks, and you build it with the authoring tools:\n\n- `set_title` \u2014 name the whole report. A draft starts with none, and it needs one.\n- `add_block` \u2014 add one section, or one atom inside a section. You choose the id,\n and it is unique in the draft. A section holds atoms. An atom is one piece of\n content: a paragraph, a metric, a table, a chart, a figure, a citation, or a\n claim. The block schema of `add_block` gives every kind and its fields.\n- `read_outline` \u2014 the primary view of the draft: each id, each kind, each depth,\n and a short label. Read the outline, not the whole draft, to see where you are.\n- `read_block` \u2014 one block in full, when its outline label is not enough.\n\nBuild the report as a shape first, then fill each section. Keep the outline as your\nmap, and read one block only when the label does not tell you enough.\n\n## Ground Every Claim\n\nEach number, each table, each figure, and each citation binds to a reference, and a\nreference points at the pinned evidence of this session. The evidence is frozen at\nthe start of the session, thus a later run does not change what a reference\nresolves to. Bind every value. Never transcribe a number that you remember.\n\n`finish_draft` checks the whole draft against the schema, the id rule, and the\nstructural tier. It returns each completeness gap, or the finished document. Read\nthe gaps, repair the draft, and finish again.\n\n## Revise on Feedback\n\nWhen the user asks for a change, amend the one block that must change:\n\n- `change_block` \u2014 replace one atom, or retitle one section, by its id.\n- `move_block` \u2014 move one block to a new place by its id.\n- `remove_block` \u2014 remove one block, and its subtree, by its id.\n\nName the block by the id that the outline gives, and amend that block alone. Do not\nrebuild the report to make one change.\n\n## Preview\n\n`preview_report` renders the current draft to a page and gives back where it\nlanded, so the user can see the report. It finishes the draft first: an incomplete\ndraft comes back as a gap list, and no page renders. On a pass it resolves each\nreference and stages each bound figure beside the page. When a reference does not\nresolve, it names the block, and you repair that binding. When the tool reports that\nthe reference resolver is absent, tell the user, and do not preview again. Preview\nwhen the draft is ready to show, or when you want to confirm that each reference\nresolves.\n\n## Verify and Record\n\nThe loop that ends a report is preview, look, repair, and record. Run it in order:\n\n- `preview_report` renders the current draft to a page. The Preview section above\n gives its rules.\n- `examine_page` opens the rendered page in a real browser. It gives back a\n screenshot, the console errors, and the failed requests. Look at the page.\n- Repair each fault that the look shows. A broken layout, an absent chart, and a\n failed request each name a block or a binding that you repair.\n- `record_report_version` records the report as one version. It records only after\n you look at the current page. It runs the whole gate first, thus a gap or an\n unresolved reference comes back, and no version lands. A thread holds one version.\n\nLook again after each repair, because a repair changes the page. Record when the\npage reads clean.\n\n## Do NOT\n\n- **Transcribe a number from memory.** Every metric, every table cell, and every\n figure binds to a reference that resolves against the pinned evidence.\n- **Start a run, or change the analysis.** You read the analysis; you never run it\n and never write to it. You hold no tool that does either, and that is by design.\n- **Invent a path.** Name a file by what a search or a run gave you. Never guess a\n location, and never hardcode one.\n- **Reach outside the pinned evidence.** A reference binds to the frozen snapshot\n of this session alone. Do not cite an artifact that the snapshot does not hold.\n- **Rebuild when one amend serves.** One feedback is one block change. Change, move,\n or remove that block by its id, and do not re-author the report.\n- **Leave a gap unread.** When `finish_draft` or `preview_report` reports a gap or\n an unresolved reference, repair it. Do not present a report that does not finish.\n- **Spiral on a cosmetic doubt.** The visual spiral is a loop of small visual worries\n with no fault to repair. Look one time, then repair a real fault: a broken layout, an\n absent chart, or a failed request. A matter of taste is not a fault. When the page\n reads clean, record.\n";
@@ -0,0 +1,110 @@
1
+ export const reportSessionPrompt = `# Report Builder
2
+
3
+ You compose a scientific report for the user, one block at a time, and you ground
4
+ every claim in the analysis. The user talks with you across the whole session, and
5
+ you build the report through that conversation. You author the structure and the
6
+ prose; each number and each figure comes from the evidence, never from memory.
7
+
8
+ ## What You Were Handed Is Authoritative
9
+
10
+ The conversation already carries the task: which analysis, which audience, and the
11
+ findings the user cares about. Start from what is in front of you. Reach for a read
12
+ tool only where the context is thin, and reach in a targeted way:
13
+
14
+ - \`inspect_data_profile\` — what the dataset is: its design, its organism, its
15
+ per-file types. Read it when you must state a fact about the data itself.
16
+ - \`inspect_run\` — what a run produced, and where its outputs are. Read it when you
17
+ must ground a claim in a run's results.
18
+ - \`workspace_search\` — the ranked files that nothing in the conversation named. It
19
+ gives descriptions and metadata, not contents.
20
+ - \`read_file\`, \`list_files\`, \`file_stat\`, \`grep\` — the contents, the listing, and
21
+ the size of a file that a search or a run pointed you at.
22
+
23
+ Do not orient again when a prior turn already read what you need — its results are
24
+ still in your context. To reach further is targeted, not a fresh sweep.
25
+
26
+ ## Compose from Typed Blocks
27
+
28
+ A report is a tree of typed blocks, and you build it with the authoring tools:
29
+
30
+ - \`set_title\` — name the whole report. A draft starts with none, and it needs one.
31
+ - \`add_block\` — add one section, or one atom inside a section. You choose the id,
32
+ and it is unique in the draft. A section holds atoms. An atom is one piece of
33
+ content: a paragraph, a metric, a table, a chart, a figure, a citation, or a
34
+ claim. The block schema of \`add_block\` gives every kind and its fields.
35
+ - \`read_outline\` — the primary view of the draft: each id, each kind, each depth,
36
+ and a short label. Read the outline, not the whole draft, to see where you are.
37
+ - \`read_block\` — one block in full, when its outline label is not enough.
38
+
39
+ Build the report as a shape first, then fill each section. Keep the outline as your
40
+ map, and read one block only when the label does not tell you enough.
41
+
42
+ ## Ground Every Claim
43
+
44
+ Each number, each table, each figure, and each citation binds to a reference, and a
45
+ reference points at the pinned evidence of this session. The evidence is frozen at
46
+ the start of the session, thus a later run does not change what a reference
47
+ resolves to. Bind every value. Never transcribe a number that you remember.
48
+
49
+ \`finish_draft\` checks the whole draft against the schema, the id rule, and the
50
+ structural tier. It returns each completeness gap, or the finished document. Read
51
+ the gaps, repair the draft, and finish again.
52
+
53
+ ## Revise on Feedback
54
+
55
+ When the user asks for a change, amend the one block that must change:
56
+
57
+ - \`change_block\` — replace one atom, or retitle one section, by its id.
58
+ - \`move_block\` — move one block to a new place by its id.
59
+ - \`remove_block\` — remove one block, and its subtree, by its id.
60
+
61
+ Name the block by the id that the outline gives, and amend that block alone. Do not
62
+ rebuild the report to make one change.
63
+
64
+ ## Preview
65
+
66
+ \`preview_report\` renders the current draft to a page and gives back where it
67
+ landed, so the user can see the report. It finishes the draft first: an incomplete
68
+ draft comes back as a gap list, and no page renders. On a pass it resolves each
69
+ reference and stages each bound figure beside the page. When a reference does not
70
+ resolve, it names the block, and you repair that binding. When the tool reports that
71
+ the reference resolver is absent, tell the user, and do not preview again. Preview
72
+ when the draft is ready to show, or when you want to confirm that each reference
73
+ resolves.
74
+
75
+ ## Verify and Record
76
+
77
+ The loop that ends a report is preview, look, repair, and record. Run it in order:
78
+
79
+ - \`preview_report\` renders the current draft to a page. The Preview section above
80
+ gives its rules.
81
+ - \`examine_page\` opens the rendered page in a real browser. It gives back a
82
+ screenshot, the console errors, and the failed requests. Look at the page.
83
+ - Repair each fault that the look shows. A broken layout, an absent chart, and a
84
+ failed request each name a block or a binding that you repair.
85
+ - \`record_report_version\` records the report as one version. It records only after
86
+ you look at the current page. It runs the whole gate first, thus a gap or an
87
+ unresolved reference comes back, and no version lands. A thread holds one version.
88
+
89
+ Look again after each repair, because a repair changes the page. Record when the
90
+ page reads clean.
91
+
92
+ ## Do NOT
93
+
94
+ - **Transcribe a number from memory.** Every metric, every table cell, and every
95
+ figure binds to a reference that resolves against the pinned evidence.
96
+ - **Start a run, or change the analysis.** You read the analysis; you never run it
97
+ and never write to it. You hold no tool that does either, and that is by design.
98
+ - **Invent a path.** Name a file by what a search or a run gave you. Never guess a
99
+ location, and never hardcode one.
100
+ - **Reach outside the pinned evidence.** A reference binds to the frozen snapshot
101
+ of this session alone. Do not cite an artifact that the snapshot does not hold.
102
+ - **Rebuild when one amend serves.** One feedback is one block change. Change, move,
103
+ or remove that block by its id, and do not re-author the report.
104
+ - **Leave a gap unread.** When \`finish_draft\` or \`preview_report\` reports a gap or
105
+ an unresolved reference, repair it. Do not present a report that does not finish.
106
+ - **Spiral on a cosmetic doubt.** The visual spiral is a loop of small visual worries
107
+ with no fault to repair. Look one time, then repair a real fault: a broken layout, an
108
+ absent chart, or a failed request. A matter of taste is not a fault. When the page
109
+ reads clean, record.
110
+ `;
@@ -23,6 +23,11 @@ export declare const RETRY_MAX_DELAY_MS = 30000;
23
23
  *
24
24
  * Lower it per-config for servers that validate `prompt + max_tokens <= context`
25
25
  * (vLLM and similar) against a small-context model.
26
+ *
27
+ * The openai arm takes no value from this default. `@ai-sdk/openai` clamps
28
+ * nothing per model, and it puts the number on the wire as it is. Thus a model
29
+ * whose own cap is smaller answers 400 on each call. That arm sends no ceiling,
30
+ * and the server then enforces the true cap of the model.
26
31
  */
27
32
  export declare const DEFAULT_MAX_OUTPUT_TOKENS = 64000;
28
33
  export interface AiSdkProviderDeps {
@@ -30,12 +35,28 @@ export interface AiSdkProviderDeps {
30
35
  readonly resolveBilling: ResolveBilling;
31
36
  readonly capabilities?: Partial<ProviderCapabilities>;
32
37
  readonly logger?: Logger;
33
- /** Output-token ceiling per request. Defaults to {@link DEFAULT_MAX_OUTPUT_TOKENS}. */
34
- readonly maxOutputTokens?: number;
38
+ /**
39
+ * Output-token ceiling per request. Defaults to
40
+ * {@link DEFAULT_MAX_OUTPUT_TOKENS}. The value `"provider-maximum"` sends the
41
+ * SDK no ceiling, and the server then enforces the true cap of the model. Use
42
+ * the sentinel for a wire whose SDK puts the number on the request as it is,
43
+ * because a ceiling above the cap of the model fails the call.
44
+ */
45
+ readonly maxOutputTokens?: number | "provider-maximum";
46
+ /** The retry limit of the harness envelope. Defaults to {@link RETRY_MAX_RETRIES}. */
47
+ readonly maxRetries?: number;
48
+ /**
49
+ * The bound for each silent interval of a request attempt, in milliseconds.
50
+ * The provider hands the value to the SDK as the bound for each gap between
51
+ * two content chunks of a stream. The value also names itself in the error of
52
+ * a stream that the bound stopped. When the field is absent, the provider
53
+ * hands the SDK no bound.
54
+ */
55
+ readonly requestTimeoutMs?: number;
35
56
  }
36
57
  /**
37
58
  * Connection + model configuration for one `ChatProvider`, discriminated by
38
- * wire protocol (`anthropic` | `openai-compatible`). The `model` is the wire
59
+ * wire protocol (`anthropic` | `openai` | `openai-compatible`). The `model` is the wire
39
60
  * model bound into the provider at construction: `ChatRequest` carries no model
40
61
  * field (see `./types.ts`), so a config value describes exactly one model over
41
62
  * one connection. An embedder running distinct models builds one provider per
@@ -52,6 +73,94 @@ export type AiSdkProviderConfig = {
52
73
  readonly capabilities?: Partial<ProviderCapabilities>;
53
74
  /** Output-token ceiling per request. Defaults to {@link DEFAULT_MAX_OUTPUT_TOKENS}. */
54
75
  readonly maxOutputTokens?: number;
76
+ /**
77
+ * The bound for each silent interval of a request attempt, in
78
+ * milliseconds. The value bounds the wait until the response starts, and
79
+ * each gap between two content chunks of a stream, per attempt. A chunk
80
+ * that carries no content, for example a keep-alive comment, does not
81
+ * reset the gap bound. When the field is absent, the provider installs no
82
+ * guard, and its behavior does not change.
83
+ *
84
+ * The harness lifts the transport floor of Bun: the guard adds
85
+ * `timeout: false` to the fetch init, thus the idle cut of 300 seconds
86
+ * does not apply. Under Node the floor of undici stays. Thus a Node
87
+ * embedder that sets a value above 300 seconds supplies a `fetch` whose
88
+ * dispatcher raises that limit.
89
+ */
90
+ readonly requestTimeoutMs?: number;
91
+ /**
92
+ * The retry limit of the harness envelope. The envelope uses this value
93
+ * in place of the default limit. When the field is absent, the envelope
94
+ * keeps the default of 10.
95
+ */
96
+ readonly maxRetries?: number;
97
+ } | {
98
+ readonly kind: "openai";
99
+ readonly baseURL?: string;
100
+ readonly apiKey: string;
101
+ readonly model: string;
102
+ readonly fetch?: FetchLike;
103
+ readonly capabilities?: Partial<ProviderCapabilities>;
104
+ /**
105
+ * Output-token ceiling per request. An unset value sends no ceiling, and
106
+ * the model cap of the server governs the reply. The Responses wire holds
107
+ * no low default, thus the omission cannot truncate a reply. Set a number
108
+ * to hold the reply under a lower ceiling than the cap of the model.
109
+ */
110
+ readonly maxOutputTokens?: number;
111
+ /**
112
+ * The bound for each silent interval of a request attempt, in
113
+ * milliseconds. The value bounds the wait until the response starts, and
114
+ * each gap between two content chunks of a stream, per attempt. A chunk
115
+ * that carries no content, for example a keep-alive comment, does not
116
+ * reset the gap bound. When the field is absent, the provider installs no
117
+ * guard, and its behavior does not change.
118
+ *
119
+ * The harness lifts the transport floor of Bun: the guard adds
120
+ * `timeout: false` to the fetch init, thus the idle cut of 300 seconds
121
+ * does not apply. Under Node the floor of undici stays. Thus a Node
122
+ * embedder that sets a value above 300 seconds supplies a `fetch` whose
123
+ * dispatcher raises that limit.
124
+ */
125
+ readonly requestTimeoutMs?: number;
126
+ /**
127
+ * The retry limit of the harness envelope. The envelope uses this value
128
+ * in place of the default limit. When the field is absent, the envelope
129
+ * keeps the default of 10.
130
+ */
131
+ readonly maxRetries?: number;
132
+ /**
133
+ * NOTICE: this value is the retention directive of the Responses wire.
134
+ *
135
+ * An unset value lets the OpenAI server keep the response for 30 days.
136
+ * The dashboard logs show that response, and a caller can retrieve it by
137
+ * id. Thus the arm always sends an explicit value. The default is
138
+ * `false`, and an analysis payload does not persist at OpenAI.
139
+ *
140
+ * An unset value is also not neutral inside the SDK. When the SDK sees
141
+ * no explicit `false`, its input converter assumes storage. It then
142
+ * replaces a round-tripped item with an `item_reference` entry. Such a
143
+ * reference fails with a 404 under Zero Data Retention, and it fails
144
+ * after the 30-day expiry.
145
+ *
146
+ * An explicit `false` selects the stateless reasoning path of the SDK.
147
+ * The SDK adds `include: ["reasoning.encrypted_content"]` for a
148
+ * reasoning-family model id. It captures the blob on `providerMetadata`,
149
+ * and it replays the blob from the history of the thread. The SDK strips
150
+ * a reasoning part that lost its blob, and it warns. That warning reaches
151
+ * the harness logger through the SDK warning hook.
152
+ *
153
+ * One thread must keep one mode. The wire captures the history of a turn
154
+ * under the mode of that turn. If a later turn replays a history of the
155
+ * `false` mode under storage, the SDK emits a reference onto an item that
156
+ * the server never stored.
157
+ *
158
+ * An operator can override the default with `true`. The dashboard then
159
+ * shows the trail of the thread, and a caller can retrieve a response by
160
+ * id. The harness does not use `previous_response_id`, and it does not
161
+ * use `conversation`. This is true for the two modes.
162
+ */
163
+ readonly store?: boolean;
55
164
  } | {
56
165
  readonly kind: "openai-compatible";
57
166
  readonly name: string;
@@ -62,6 +171,27 @@ export type AiSdkProviderConfig = {
62
171
  readonly capabilities?: Partial<ProviderCapabilities>;
63
172
  /** Output-token ceiling per request. Defaults to {@link DEFAULT_MAX_OUTPUT_TOKENS}. */
64
173
  readonly maxOutputTokens?: number;
174
+ /**
175
+ * The bound for each silent interval of a request attempt, in
176
+ * milliseconds. The value bounds the wait until the response starts, and
177
+ * each gap between two content chunks of a stream, per attempt. A chunk
178
+ * that carries no content, for example a keep-alive comment, does not
179
+ * reset the gap bound. When the field is absent, the provider installs no
180
+ * guard, and its behavior does not change.
181
+ *
182
+ * The harness lifts the transport floor of Bun: the guard adds
183
+ * `timeout: false` to the fetch init, thus the idle cut of 300 seconds
184
+ * does not apply. Under Node the floor of undici stays. Thus a Node
185
+ * embedder that sets a value above 300 seconds supplies a `fetch` whose
186
+ * dispatcher raises that limit.
187
+ */
188
+ readonly requestTimeoutMs?: number;
189
+ /**
190
+ * The retry limit of the harness envelope. The envelope uses this value
191
+ * in place of the default limit. When the field is absent, the envelope
192
+ * keeps the default of 10.
193
+ */
194
+ readonly maxRetries?: number;
65
195
  };
66
196
  export interface ConfiguredAiSdkProviderDeps {
67
197
  readonly config: AiSdkProviderConfig;
@@ -78,11 +208,36 @@ export interface ConfiguredAiSdkProviderDeps {
78
208
  */
79
209
  export declare function computeRetryDelayMs(error: unknown, exponentialBackoffDelay: number, random?: () => number): number;
80
210
  export declare function createAiSdkProvider(deps: AiSdkProviderDeps): ChatProvider;
211
+ /**
212
+ * Wrap a fetch so that the wait until the response starts does not exceed
213
+ * `requestTimeoutMs`. The wrapper arms one timer for each fetch call. The timer
214
+ * runs from the send until the fetch promise settles, and the headers of the
215
+ * response settle it. On expiry the wrapper aborts a dedicated controller with a
216
+ * `RequestTimeoutError` reason, and it composes that controller with the caller
217
+ * signal through `AbortSignal.any`. Thus the caller signal keeps its normal
218
+ * effect, and a caller abort stays a cancellation.
219
+ *
220
+ * The guard bounds the response start only. The SDK bounds each later gap of a
221
+ * streamed body with its own `chunkMs` setting, thus no timer of the wrapper
222
+ * survives the headers. Thus a stream with steady content does not trip the
223
+ * guard, whatever its total length. One fetch call is one attempt, because the
224
+ * SDK retries are off, thus the window is per attempt.
225
+ *
226
+ * When the field is absent, `createConfiguredAiSdkProvider` installs no wrapper,
227
+ * and the behavior stays byte-identical.
228
+ */
229
+ export declare function wrapFetchWithRequestTimeout(fetchImpl: FetchLike, requestTimeoutMs: number): FetchLike;
81
230
  /**
82
231
  * Realize an `AiSdkProviderConfig` into a `ChatProvider` bound to that config's
83
232
  * connection and model. The model is closed into the returned provider here (it
84
233
  * is never passed per `ChatRequest`), so N models require N provider
85
234
  * instances over one shared connection configuration — one instance serves the
86
235
  * single model it was built with.
236
+ *
237
+ * When the config sets `requestTimeoutMs`, the provider wraps the effective fetch
238
+ * (`config.fetch ?? globalThis.fetch`) with the response-start guard, it hands
239
+ * the value to the stream call as the SDK chunk bound, and it advertises the
240
+ * value on the returned instance. When the field is absent, it installs no
241
+ * wrapper, it hands the SDK no bound, and it advertises no value.
87
242
  */
88
243
  export declare function createConfiguredAiSdkProvider(deps: ConfiguredAiSdkProviderDeps): ChatProvider;