@namzu/sdk 4.0.0 → 5.1.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.
Files changed (107) hide show
  1. package/CHANGELOG.md +282 -0
  2. package/README.md +2 -2
  3. package/dist/agents/SupervisorAgent.d.ts.map +1 -1
  4. package/dist/agents/SupervisorAgent.js +6 -0
  5. package/dist/agents/SupervisorAgent.js.map +1 -1
  6. package/dist/agents/__tests__/run-agent.test.d.ts +2 -0
  7. package/dist/agents/__tests__/run-agent.test.d.ts.map +1 -0
  8. package/dist/agents/__tests__/run-agent.test.js +143 -0
  9. package/dist/agents/__tests__/run-agent.test.js.map +1 -0
  10. package/dist/agents/index.d.ts +2 -0
  11. package/dist/agents/index.d.ts.map +1 -1
  12. package/dist/agents/index.js +1 -0
  13. package/dist/agents/index.js.map +1 -1
  14. package/dist/agents/runAgent.d.ts +104 -0
  15. package/dist/agents/runAgent.d.ts.map +1 -0
  16. package/dist/agents/runAgent.js +92 -0
  17. package/dist/agents/runAgent.js.map +1 -0
  18. package/dist/provider/__tests__/thinking-support.test.d.ts +2 -0
  19. package/dist/provider/__tests__/thinking-support.test.d.ts.map +1 -0
  20. package/dist/provider/__tests__/thinking-support.test.js +47 -0
  21. package/dist/provider/__tests__/thinking-support.test.js.map +1 -0
  22. package/dist/provider/__tests__/typed-error-classification.test.d.ts +2 -0
  23. package/dist/provider/__tests__/typed-error-classification.test.d.ts.map +1 -0
  24. package/dist/provider/__tests__/typed-error-classification.test.js +123 -0
  25. package/dist/provider/__tests__/typed-error-classification.test.js.map +1 -0
  26. package/dist/provider/retry.d.ts.map +1 -1
  27. package/dist/provider/retry.js +23 -7
  28. package/dist/provider/retry.js.map +1 -1
  29. package/dist/provider/thinking-support.d.ts +30 -0
  30. package/dist/provider/thinking-support.d.ts.map +1 -0
  31. package/dist/provider/thinking-support.js +32 -0
  32. package/dist/provider/thinking-support.js.map +1 -0
  33. package/dist/public-runtime.d.ts +4 -1
  34. package/dist/public-runtime.d.ts.map +1 -1
  35. package/dist/public-runtime.js +10 -1
  36. package/dist/public-runtime.js.map +1 -1
  37. package/dist/public-tools.d.ts +1 -0
  38. package/dist/public-tools.d.ts.map +1 -1
  39. package/dist/public-tools.js +4 -0
  40. package/dist/public-tools.js.map +1 -1
  41. package/dist/public-types.d.ts +1 -1
  42. package/dist/public-types.d.ts.map +1 -1
  43. package/dist/runtime/query/__tests__/steering-reaches-the-model.test.d.ts +2 -0
  44. package/dist/runtime/query/__tests__/steering-reaches-the-model.test.d.ts.map +1 -0
  45. package/dist/runtime/query/__tests__/steering-reaches-the-model.test.js +94 -0
  46. package/dist/runtime/query/__tests__/steering-reaches-the-model.test.js.map +1 -0
  47. package/dist/runtime/query/__tests__/steering.test.d.ts +2 -0
  48. package/dist/runtime/query/__tests__/steering.test.d.ts.map +1 -0
  49. package/dist/runtime/query/__tests__/steering.test.js +92 -0
  50. package/dist/runtime/query/__tests__/steering.test.js.map +1 -0
  51. package/dist/runtime/query/__tests__/stream-recovery.test.js +5 -0
  52. package/dist/runtime/query/__tests__/stream-recovery.test.js.map +1 -1
  53. package/dist/runtime/query/index.d.ts +10 -0
  54. package/dist/runtime/query/index.d.ts.map +1 -1
  55. package/dist/runtime/query/index.js +1 -0
  56. package/dist/runtime/query/index.js.map +1 -1
  57. package/dist/runtime/query/iteration/phases/context.d.ts +8 -0
  58. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  59. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  60. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  61. package/dist/runtime/query/iteration/phases/tool-review.js +7 -1
  62. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  63. package/dist/runtime/query/steering.d.ts +81 -0
  64. package/dist/runtime/query/steering.d.ts.map +1 -0
  65. package/dist/runtime/query/steering.js +77 -0
  66. package/dist/runtime/query/steering.js.map +1 -0
  67. package/dist/types/agent/manager.d.ts +11 -4
  68. package/dist/types/agent/manager.d.ts.map +1 -1
  69. package/dist/types/agent/supervisor.d.ts +9 -0
  70. package/dist/types/agent/supervisor.d.ts.map +1 -1
  71. package/dist/types/common/index.d.ts +12 -0
  72. package/dist/types/common/index.d.ts.map +1 -1
  73. package/dist/types/common/index.js +7 -0
  74. package/dist/types/common/index.js.map +1 -1
  75. package/dist/types/provider/chat.d.ts +57 -5
  76. package/dist/types/provider/chat.d.ts.map +1 -1
  77. package/dist/types/provider/errors.d.ts +0 -17
  78. package/dist/types/provider/errors.d.ts.map +1 -1
  79. package/dist/types/provider/errors.js +60 -0
  80. package/dist/types/provider/errors.js.map +1 -1
  81. package/dist/types/provider/index.d.ts +1 -1
  82. package/dist/types/provider/index.d.ts.map +1 -1
  83. package/package.json +1 -1
  84. package/src/agents/SupervisorAgent.ts +6 -0
  85. package/src/agents/__tests__/run-agent.test.ts +165 -0
  86. package/src/agents/index.ts +2 -0
  87. package/src/agents/runAgent.ts +179 -0
  88. package/src/provider/__tests__/thinking-support.test.ts +60 -0
  89. package/src/provider/__tests__/typed-error-classification.test.ts +143 -0
  90. package/src/provider/retry.ts +23 -7
  91. package/src/provider/thinking-support.ts +37 -0
  92. package/src/public-runtime.ts +10 -0
  93. package/src/public-tools.ts +4 -0
  94. package/src/public-types.ts +7 -1
  95. package/src/runtime/query/__tests__/steering-reaches-the-model.test.ts +117 -0
  96. package/src/runtime/query/__tests__/steering.test.ts +121 -0
  97. package/src/runtime/query/__tests__/stream-recovery.test.ts +5 -0
  98. package/src/runtime/query/index.ts +12 -0
  99. package/src/runtime/query/iteration/phases/context.ts +9 -0
  100. package/src/runtime/query/iteration/phases/tool-review.ts +7 -1
  101. package/src/runtime/query/steering.ts +135 -0
  102. package/src/types/agent/manager.ts +11 -4
  103. package/src/types/agent/supervisor.ts +10 -0
  104. package/src/types/common/index.ts +20 -0
  105. package/src/types/provider/chat.ts +61 -5
  106. package/src/types/provider/errors.ts +71 -0
  107. package/src/types/provider/index.ts +1 -0
@@ -0,0 +1,135 @@
1
+ import type { Message } from '../../types/message/index.js'
2
+
3
+ /**
4
+ * Guidance a host hands to a turn that is already running.
5
+ *
6
+ * The gap this closes is narrow and was documented rather than fixed:
7
+ * `AgentManager` has had `queueMessage` / `drainMessages` for a while, and
8
+ * nothing in the iteration loop ever read them — the type says so in as many
9
+ * words. So a host watching a run go the wrong way had two options, and both
10
+ * are worse than they sound. Cancel and start over throws away every tool
11
+ * result the run had already paid for. Reject through the review gate only
12
+ * works if a tool call happens to be pending approval, and it says "no" when
13
+ * the host wanted to say "yes, but look at this first".
14
+ *
15
+ * **Why the text rides on a tool result rather than arriving as a user
16
+ * message.** A `tool_use` block must be answered by a `tool_result` with the
17
+ * same id — providers reject a user turn wedged between them — so there is no
18
+ * legal place to insert a message mid-batch at all. The slot that already
19
+ * exists is the tool result itself, and this codebase had already worked that
20
+ * out for a neighbouring case: a denied call carries its reason INSIDE the
21
+ * `tool_result`, and `executor.ts` notes that this is also what makes a
22
+ * rejection *steer*, because the model reads it in the slot it already
23
+ * attends to for tool outcomes. Steering is the same delivery with the
24
+ * refusal removed.
25
+ *
26
+ * **What it deliberately is not.** It does not interrupt. The batch in flight
27
+ * finishes, and the guidance lands where the model looks next. A host that
28
+ * wants the current work stopped wants `AbortSignal`, which is a different
29
+ * question with a different answer — and conflating the two is how "please
30
+ * also check the tests" ends up killing a half-written file.
31
+ */
32
+ export interface SteeringChannel {
33
+ /**
34
+ * Queue guidance for the running turn.
35
+ *
36
+ * Repeated calls before the next drain accumulate in order rather than
37
+ * replacing each other: two corrections typed a second apart are two
38
+ * things the model should see, and keeping only the last one silently
39
+ * discards a host's instruction.
40
+ *
41
+ * Empty and whitespace-only text is ignored, so a stray keystroke does
42
+ * not append a blank line to a tool result.
43
+ */
44
+ steer(text: string): void
45
+
46
+ /** Take everything queued, leaving the channel empty. */
47
+ drain(): string | undefined
48
+
49
+ /** True while guidance is queued and undelivered. */
50
+ readonly pending: boolean
51
+ }
52
+
53
+ export class SteeringBinding implements SteeringChannel {
54
+ private queued: string[] = []
55
+
56
+ steer(text: string): void {
57
+ const trimmed = text.trim()
58
+ if (!trimmed) return
59
+ this.queued.push(trimmed)
60
+ }
61
+
62
+ drain(): string | undefined {
63
+ if (this.queued.length === 0) return undefined
64
+ const joined = this.queued.join('\n')
65
+ this.queued = []
66
+ return joined
67
+ }
68
+
69
+ get pending(): boolean {
70
+ return this.queued.length > 0
71
+ }
72
+ }
73
+
74
+ /**
75
+ * The frame the guidance arrives in.
76
+ *
77
+ * Labelled because the model is being handed text from a party other than the
78
+ * tool whose result it is reading, in that tool's slot. Unlabelled, it reads
79
+ * as something the tool said — so a steer saying "stop and ask me first" would
80
+ * look like output from `bash`.
81
+ *
82
+ * This is NOT the untrusted-content envelope. The host operating the run is
83
+ * the one party whose words the agent SHOULD act on; framing them as material
84
+ * to be worked with rather than followed would inverting the very thing the
85
+ * host is trying to do. Different party, different frame, on purpose.
86
+ */
87
+ export function formatSteeringNote(text: string): string {
88
+ return `\n\n[Message from the operator, received while this tool was running]\n${text}`
89
+ }
90
+
91
+ /**
92
+ * Append the guidance to the last tool result in a settled batch.
93
+ *
94
+ * The LAST one, so it is the final thing the model reads before deciding what
95
+ * to do next — appending to the first would bury it under every later result.
96
+ *
97
+ * Returns the messages unchanged when there is nothing queued, and when the
98
+ * batch carries no tool result to attach to. The second case is not a failure
99
+ * to handle: a turn that called no tools has nothing in flight, so guidance
100
+ * belongs to the next turn and stays queued for it.
101
+ */
102
+ export function attachSteering(
103
+ messages: readonly Message[],
104
+ channel: SteeringChannel | undefined,
105
+ ): readonly Message[] {
106
+ if (!channel?.pending) return messages
107
+
108
+ let lastToolIndex = -1
109
+ for (let index = messages.length - 1; index >= 0; index--) {
110
+ if (messages[index]?.role === 'tool') {
111
+ lastToolIndex = index
112
+ break
113
+ }
114
+ }
115
+ if (lastToolIndex === -1) return messages
116
+
117
+ const guidance = channel.drain()
118
+ if (guidance === undefined) return messages
119
+
120
+ const target = messages[lastToolIndex] as Message
121
+ // Only text is extended. A tool that answered with structured content —
122
+ // an image block, say — has a shape the model reads positionally, and
123
+ // appending a string to it would either be dropped or corrupt the block.
124
+ // Such a result keeps its content and the note follows it as its own text
125
+ // part where the shape allows, and otherwise the guidance stays queued
126
+ // for the next turn rather than being forced into a slot it does not fit.
127
+ if (typeof target.content !== 'string') {
128
+ channel.steer(guidance)
129
+ return messages
130
+ }
131
+
132
+ const next = [...messages]
133
+ next[lastToolIndex] = { ...target, content: target.content + formatSteeringNote(guidance) }
134
+ return next
135
+ }
@@ -30,10 +30,17 @@ export interface AgentManagerContract {
30
30
  *
31
31
  * Kept, and documented rather than deleted, because `drainMessages` is
32
32
  * the only way a host can pick these up at all — removing it would take
33
- * away the escape hatch and leave the trap. Two delivery routes that DO
34
- * work today: reject/modify feedback rides inside a tool result, and
35
- * `prepareStep`'s `system` string is appended to the next model call
36
- * from a hook that sees live history.
33
+ * away the escape hatch and leave the trap.
34
+ *
35
+ * **For mid-run guidance, use `SteeringChannel` instead.** That is the
36
+ * delivery handshake this queue was missing: text queued on it is
37
+ * appended to the running batch's last `tool_result`, which is the only
38
+ * slot a provider accepts mid-batch, and the loop drains it. Pass one as
39
+ * `steering` on `drainQuery` params or on `SupervisorAgentConfig`.
40
+ *
41
+ * Two other routes also work: reject/modify feedback rides inside a tool
42
+ * result, and `prepareStep`'s `system` string is appended to the next
43
+ * model call from a hook that sees live history.
37
44
  */
38
45
  continueTask(taskId: TaskId, message: string): Promise<void>
39
46
  /** See {@link continueTask} — queued, not delivered. */
@@ -1,4 +1,5 @@
1
1
  import type { CompactionConfig } from '../../config/runtime.js'
2
+ import type { SteeringChannel } from '../../runtime/query/steering.js'
2
3
  import type { AdvisoryConfig } from '../advisory/index.js'
3
4
  import type { ResumeHandler } from '../hitl/index.js'
4
5
  import type { LLMProvider } from '../provider/index.js'
@@ -63,6 +64,15 @@ export interface SupervisorAgentConfig extends BaseAgentConfig {
63
64
  */
64
65
  resumeHandler?: ResumeHandler
65
66
 
67
+ /**
68
+ * Channel a host uses to hand guidance to the supervisor's running turn.
69
+ *
70
+ * Present here for the same reason `resumeHandler` is: a capability the
71
+ * kernel honours in `drainQuery` and not on the surface hosts actually
72
+ * construct is a capability nobody can reach.
73
+ */
74
+ steering?: SteeringChannel
75
+
66
76
  /**
67
77
  * Optional declarative gate evaluated before tool execution. When
68
78
  * the gate marks all calls in a batch as `allow`, they execute
@@ -10,6 +10,19 @@ export interface TokenUsage {
10
10
  totalTokens: number
11
11
  cachedTokens: number
12
12
  cacheWriteTokens: number
13
+
14
+ /**
15
+ * Output tokens the model spent on internal reasoning.
16
+ *
17
+ * A SUBSET of `completionTokens`, not an addition to it — reasoning is
18
+ * billed as output, so adding these to a total would double-count. Present
19
+ * so a caller can see what share of a turn went to thinking, which is the
20
+ * question budgeting and cost attribution actually ask.
21
+ *
22
+ * Optional because most drivers do not report it. Absent means unknown,
23
+ * not zero.
24
+ */
25
+ reasoningTokens?: number
13
26
  }
14
27
 
15
28
  export function accumulateTokenUsage(current: TokenUsage, addition: TokenUsage): TokenUsage {
@@ -19,6 +32,13 @@ export function accumulateTokenUsage(current: TokenUsage, addition: TokenUsage):
19
32
  totalTokens: current.totalTokens + addition.totalTokens,
20
33
  cachedTokens: current.cachedTokens + addition.cachedTokens,
21
34
  cacheWriteTokens: current.cacheWriteTokens + addition.cacheWriteTokens,
35
+ // Summed only when at least one side reported it. Coercing absent to
36
+ // zero would turn 'this driver does not tell us' into 'it spent none',
37
+ // and a run mixing a reporting driver with a silent one would read as
38
+ // though the silent turns did no thinking.
39
+ ...(current.reasoningTokens !== undefined || addition.reasoningTokens !== undefined
40
+ ? { reasoningTokens: (current.reasoningTokens ?? 0) + (addition.reasoningTokens ?? 0) }
41
+ : {}),
22
42
  }
23
43
  }
24
44
 
@@ -76,19 +76,75 @@ export interface ChatCompletionParams {
76
76
  * Drivers that do not support it ignore the field.
77
77
  */
78
78
  thinking?: ThinkingConfig
79
+
80
+ /**
81
+ * How much work to put into the response. See {@link ReasoningEffort}.
82
+ *
83
+ * Drivers that do not support it ignore the field.
84
+ */
85
+ effort?: ReasoningEffort
79
86
  }
80
87
 
81
88
  export interface ThinkingConfig {
82
- type: 'enabled' | 'disabled'
83
- /** Token allowance for the thinking pass. */
89
+ /**
90
+ * Which thinking mode to ask for.
91
+ *
92
+ * `'adaptive'` lets the model decide whether and how deeply to think per
93
+ * request; depth is steered by {@link ChatCompletionParams.effort} rather
94
+ * than a token budget. `'enabled'` is the older manual mode, where
95
+ * {@link budgetTokens} fixes the depth and the model thinks on every
96
+ * request.
97
+ *
98
+ * **These are not interchangeable, and a driver must not guess.** Vendors
99
+ * reject the wrong one for a given model outright rather than degrading:
100
+ * newer models refuse `'enabled'`, older ones refuse `'adaptive'`, and
101
+ * some refuse `'disabled'` because they cannot stop thinking at all. A
102
+ * driver that sends a mode the model does not accept produces a failed
103
+ * request, not a worse answer — which is why this is a declared intent
104
+ * that each driver resolves against the model it is about to call.
105
+ */
106
+ type: 'adaptive' | 'enabled' | 'disabled'
107
+
108
+ /**
109
+ * Token allowance for the thinking pass. Manual mode only — the adaptive
110
+ * mode has no budget, and depth is set by `effort`.
111
+ */
84
112
  budgetTokens?: number
113
+
85
114
  /**
86
- * Whether the provider should return full thinking text or a summary.
87
- * Purely a request hint; the runtime stores whatever comes back.
115
+ * Whether the thinking text comes back or only its signature.
116
+ *
117
+ * `'omitted'` returns the blocks with an empty body and a signature, which
118
+ * is enough to replay them on the next turn (see `replayReasoning`) while
119
+ * keeping the text out of the response. `'summarized'` returns a summary
120
+ * of the reasoning.
121
+ *
122
+ * Worth setting explicitly. This defaults to `'omitted'` on newer models,
123
+ * so a caller that wants to show reasoning and does not ask for it gets
124
+ * thinking blocks whose text is empty and no indication why.
125
+ *
126
+ * The values were `'full' | 'summarized'` here, and `'full'` was never a
127
+ * value any vendor accepted — a declared option that could only ever have
128
+ * been rejected, next to a real one that was missing.
88
129
  */
89
- display?: 'full' | 'summarized'
130
+ display?: 'summarized' | 'omitted'
90
131
  }
91
132
 
133
+ /**
134
+ * How much work the model should put into a response.
135
+ *
136
+ * A sibling of {@link ChatCompletionParams.thinking}, not a field inside it,
137
+ * because it is not exclusively a thinking control: it shapes the whole
138
+ * response, and at least one manual-mode model accepts it alongside a token
139
+ * budget, where effort shapes the answer and the budget sets thinking depth.
140
+ * Nesting it under `thinking` would have made that combination unsayable.
141
+ *
142
+ * In adaptive mode it is the primary depth lever — low effort may skip
143
+ * thinking entirely on easy input. In manual mode `budgetTokens` sets depth
144
+ * and effort does not move it.
145
+ */
146
+ export type ReasoningEffort = 'low' | 'medium' | 'high' | 'xhigh' | 'max'
147
+
92
148
  export interface ChatCompletionResponse {
93
149
  id: string
94
150
  model: string
@@ -362,6 +362,62 @@ function codeFromStructure(err: unknown): ProviderErrorCode | undefined {
362
362
  *
363
363
  * Aborts are passed through untouched — see {@link isAbortError}.
364
364
  */
365
+ /**
366
+ * Every `ProviderErrorKind`, mapped to what the runtime acts on.
367
+ *
368
+ * Read structurally rather than with `instanceof`: a driver in one package
369
+ * throws this and the runtime in another reads it, and two copies of the SDK
370
+ * in one process make `instanceof` unreliable — the same reason
371
+ * `isProviderRequestError` exists.
372
+ *
373
+ * `retryable` here is about whether resending the SAME request could succeed.
374
+ * `context_overflow` is correctly false — an identical prompt overflows
375
+ * identically — and it maps to `context_length_exceeded` so the loop can reach
376
+ * for compaction, which is a different remedy than a retry.
377
+ */
378
+ const KIND_TO_CODE: Readonly<Record<string, { code: ProviderErrorCode; retryable: boolean }>> = {
379
+ throttle: { code: 'rate_limit', retryable: true },
380
+ network: { code: 'network', retryable: true },
381
+ server: { code: 'server_error', retryable: true },
382
+ auth: { code: 'auth', retryable: false },
383
+ context_overflow: { code: 'context_length_exceeded', retryable: false },
384
+ bad_request: { code: 'invalid_request', retryable: false },
385
+ }
386
+
387
+ function classifyFromProviderRequestError(
388
+ err: unknown,
389
+ providerId: string | undefined,
390
+ now: number,
391
+ ): ProviderError | undefined {
392
+ if (!(err instanceof Error) || err.name !== 'ProviderRequestError') return undefined
393
+ const candidate = err as Error & {
394
+ kind?: unknown
395
+ providerId?: unknown
396
+ status?: unknown
397
+ retryAfterMs?: unknown
398
+ }
399
+ if (typeof candidate.kind !== 'string') return undefined
400
+ const mapped = KIND_TO_CODE[candidate.kind]
401
+ if (!mapped) return undefined
402
+
403
+ const retryAfterMs =
404
+ typeof candidate.retryAfterMs === 'number' ? candidate.retryAfterMs : readRetryAfterMs(err, now)
405
+
406
+ return new ProviderError({
407
+ code: mapped.code,
408
+ message: err.message,
409
+ retryable: mapped.retryable,
410
+ cause: err,
411
+ ...(typeof candidate.providerId === 'string'
412
+ ? { providerId: candidate.providerId }
413
+ : providerId !== undefined
414
+ ? { providerId }
415
+ : {}),
416
+ ...(typeof candidate.status === 'number' ? { status: candidate.status } : {}),
417
+ ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),
418
+ })
419
+ }
420
+
365
421
  export function classifyProviderError(
366
422
  err: unknown,
367
423
  providerId?: string,
@@ -369,6 +425,21 @@ export function classifyProviderError(
369
425
  ): ProviderError {
370
426
  if (isProviderError(err)) return err
371
427
 
428
+ // A driver that already classified its own failure is read FIRST, and by
429
+ // its `kind` — the field it set on purpose.
430
+ //
431
+ // Without this the classifier fell through to the status heuristics, where
432
+ // a `ProviderRequestError` carrying `kind: 'context_overflow'` and a 400
433
+ // became `invalid_request`, non-retryable. Three of the six kinds landed
434
+ // wrong that way, and the consequences were not cosmetic: the loop's
435
+ // overflow branch tests for `context_length_exceeded`, so compaction relief
436
+ // — the one provider failure this kernel can actually do something about —
437
+ // was unreachable for exactly the drivers that had diagnosed it correctly.
438
+ // A driver that classified its own error came out worse than one that did
439
+ // not, which is the opposite of the incentive the type was created for.
440
+ const fromKind = classifyFromProviderRequestError(err, providerId, now)
441
+ if (fromKind) return fromKind
442
+
372
443
  const message = err instanceof Error ? err.message : String(err)
373
444
  const status = readStatus(err)
374
445
  const errno = readErrnoCode(err)
@@ -4,6 +4,7 @@ export type {
4
4
  CacheControl,
5
5
  ChatCompletionParams,
6
6
  ChatCompletionResponse,
7
+ ReasoningEffort,
7
8
  ThinkingConfig,
8
9
  } from './chat.js'
9
10
  export type { StreamChunk } from './stream.js'