@namzu/sdk 33.0.0 → 33.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 (55) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  3. package/dist/bridge/a2a/mapper.js +13 -0
  4. package/dist/bridge/a2a/mapper.js.map +1 -1
  5. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  6. package/dist/bridge/sse/mapper.js +3 -0
  7. package/dist/bridge/sse/mapper.js.map +1 -1
  8. package/dist/provider/capabilities.d.ts +2 -0
  9. package/dist/provider/capabilities.d.ts.map +1 -1
  10. package/dist/provider/capabilities.js +6 -0
  11. package/dist/provider/capabilities.js.map +1 -1
  12. package/dist/runtime/query/index.d.ts +3 -1
  13. package/dist/runtime/query/index.d.ts.map +1 -1
  14. package/dist/runtime/query/index.js +2 -0
  15. package/dist/runtime/query/index.js.map +1 -1
  16. package/dist/runtime/query/iteration/index.d.ts +10 -0
  17. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  18. package/dist/runtime/query/iteration/index.js +67 -0
  19. package/dist/runtime/query/iteration/index.js.map +1 -1
  20. package/dist/runtime/query/iteration/phases/context.d.ts +5 -0
  21. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  22. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  23. package/dist/runtime/query/result.d.ts.map +1 -1
  24. package/dist/runtime/query/result.js +25 -22
  25. package/dist/runtime/query/result.js.map +1 -1
  26. package/dist/tools/builtins/computer-use.d.ts.map +1 -1
  27. package/dist/tools/builtins/computer-use.js +37 -0
  28. package/dist/tools/builtins/computer-use.js.map +1 -1
  29. package/dist/types/errors/catalog.d.ts.map +1 -1
  30. package/dist/types/errors/catalog.js +13 -6
  31. package/dist/types/errors/catalog.js.map +1 -1
  32. package/dist/types/errors/index.d.ts.map +1 -1
  33. package/dist/types/errors/index.js +21 -8
  34. package/dist/types/errors/index.js.map +1 -1
  35. package/dist/types/provider/config.d.ts +9 -0
  36. package/dist/types/provider/config.d.ts.map +1 -1
  37. package/dist/types/run/events.d.ts +17 -0
  38. package/dist/types/run/events.d.ts.map +1 -1
  39. package/dist/types/run/events.js.map +1 -1
  40. package/dist/types/tool/presentation.d.ts +6 -2
  41. package/dist/types/tool/presentation.d.ts.map +1 -1
  42. package/package.json +1 -1
  43. package/src/bridge/a2a/mapper.ts +23 -4
  44. package/src/bridge/sse/mapper.ts +3 -0
  45. package/src/provider/capabilities.ts +10 -0
  46. package/src/runtime/query/index.ts +5 -1
  47. package/src/runtime/query/iteration/index.ts +72 -0
  48. package/src/runtime/query/iteration/phases/context.ts +5 -0
  49. package/src/runtime/query/result.ts +25 -23
  50. package/src/tools/builtins/computer-use.ts +41 -0
  51. package/src/types/errors/catalog.ts +14 -6
  52. package/src/types/errors/index.ts +22 -8
  53. package/src/types/provider/config.ts +9 -0
  54. package/src/types/run/events.ts +17 -3
  55. package/src/types/tool/presentation.ts +10 -3
@@ -140,6 +140,28 @@ export class ResultAssembler {
140
140
  // later, discarding every field of it. `toPlatformError` is the
141
141
  // projection that was written for exactly this and had no callers.
142
142
  const failure = toPlatformError(err)
143
+ // The driver's classification and the operator explanation describe the
144
+ // throwable, not the terminal verdict. Compute them before choosing paused
145
+ // versus failed so a recoverable run does not become the one path that
146
+ // discards the reason and remedy a host needs in order to recover it.
147
+ const providerError = isProviderRequestError(err)
148
+ ? {
149
+ kind: err.kind,
150
+ providerId: err.providerId,
151
+ ...(err.providerCode !== undefined ? { providerCode: err.providerCode } : {}),
152
+ ...(err.status !== undefined ? { status: err.status } : {}),
153
+ ...(err.retryAfterMs !== undefined ? { retryAfterMs: err.retryAfterMs } : {}),
154
+ // The provider's own sentence, already truncated and scrubbed
155
+ // by the driver. Without it a host rendering this metadata
156
+ // knows a request was rejected but not which field, and has to
157
+ // re-parse prose to find out.
158
+ ...(err.detail !== undefined ? { detail: err.detail } : {}),
159
+ }
160
+ : undefined
161
+ // Classification is structural; remediation is editorial. The catalog is
162
+ // optional because inventing advice for an uncharacterised failure is worse
163
+ // than presenting the reason alone.
164
+ const explanation = explainError(err) ?? undefined
143
165
 
144
166
  // A transient failure that survived every in-turn recovery is not the
145
167
  // same thing as a bad API key, and settling both as `failed` gave the
@@ -157,6 +179,9 @@ export class ResultAssembler {
157
179
  runId: runMgr.id,
158
180
  checkpointId: resumeFrom,
159
181
  reason: errorMessage,
182
+ failure,
183
+ ...(providerError ? { providerError } : {}),
184
+ ...(explanation ? { explanation } : {}),
160
185
  })
161
186
  yield* drainPending()
162
187
 
@@ -177,35 +202,12 @@ export class ResultAssembler {
177
202
  return
178
203
  }
179
204
 
180
- // The driver's classification, carried onto the run so a host can
181
- // branch on WHAT failed without re-parsing a sentence.
182
- const providerError = isProviderRequestError(err)
183
- ? {
184
- kind: err.kind,
185
- providerId: err.providerId,
186
- ...(err.providerCode !== undefined ? { providerCode: err.providerCode } : {}),
187
- ...(err.status !== undefined ? { status: err.status } : {}),
188
- ...(err.retryAfterMs !== undefined ? { retryAfterMs: err.retryAfterMs } : {}),
189
- // The provider's own sentence, already truncated and scrubbed
190
- // by the driver. Without it a host rendering this metadata
191
- // knows a request was rejected but not which field, and has to
192
- // go re-parse `error` to find out — which is exactly the
193
- // re-parsing the line above says this exists to avoid.
194
- ...(err.detail !== undefined ? { detail: err.detail } : {}),
195
- }
196
- : undefined
197
205
  runMgr.markFailed(errorMessage, providerError)
198
206
 
199
207
  if (planManager.isActive) {
200
208
  planManager.failPlan(errorMessage)
201
209
  }
202
210
 
203
- // The classification says what kind of failure it is; the catalog
204
- // says what a person should do about it. Keeping them separate is the
205
- // point — classification is structural and belongs at the boundary,
206
- // remediation is editorial and belongs in a list a human appends to.
207
- const explanation = explainError(err) ?? undefined
208
-
209
211
  // Same terminal-verdict recording as the success path in completeRun —
210
212
  // see LOG-14, design §5. Placed AFTER the early `resumeFrom !== undefined`
211
213
  // return above, so a paused/resumable run is never audited as 'failure'.
@@ -106,6 +106,38 @@ function buildDescription(host: ComputerUseHost): string {
106
106
  return lines.join(' ')
107
107
  }
108
108
 
109
+ function pointLabel(point: { readonly x: number; readonly y: number }): string {
110
+ return `(${point.x}, ${point.y})`
111
+ }
112
+
113
+ function quotedText(value: string): string {
114
+ const oneLine = value.replace(/\s+/g, ' ')
115
+ const visible = oneLine.length > 64 ? `${oneLine.slice(0, 63)}…` : oneLine
116
+ return JSON.stringify(visible)
117
+ }
118
+
119
+ /** Human activity text; the raw action union remains the model-facing input. */
120
+ function actionLabel(input: ActionInput): string {
121
+ switch (input.type) {
122
+ case 'screenshot':
123
+ return 'Capture screenshot'
124
+ case 'cursor_position':
125
+ return 'Read cursor position'
126
+ case 'mouse_move':
127
+ return `Move pointer to ${pointLabel(input.to)}`
128
+ case 'mouse_click':
129
+ return `Click ${input.button} at ${pointLabel(input.at)}`
130
+ case 'mouse_drag':
131
+ return `Drag ${input.button} from ${pointLabel(input.from)} to ${pointLabel(input.to)}`
132
+ case 'scroll':
133
+ return `Scroll ${input.direction} ${input.amount} at ${pointLabel(input.at)}`
134
+ case 'type_text':
135
+ return `Type ${quotedText(input.text)}`
136
+ case 'key':
137
+ return `Press ${input.keys}`
138
+ }
139
+ }
140
+
109
141
  function resultToToolResult(result: ComputerUseResult): ToolResult {
110
142
  switch (result.type) {
111
143
  case 'screenshot': {
@@ -198,6 +230,15 @@ export function createComputerUseTool(host: ComputerUseHost): ToolDefinition<Act
198
230
  readOnly: false,
199
231
  destructive: (input: ActionInput) => DESTRUCTIVE_ACTION_TYPES.has(input.type),
200
232
  concurrencySafe: false,
233
+ presentCall: (input) => ({
234
+ kind: 'generic',
235
+ label: actionLabel(input),
236
+ presentation: 'activity',
237
+ }),
238
+ presentResult: (_input, result) =>
239
+ result.success && result.output.trim().toLowerCase() === 'ok'
240
+ ? { kind: 'generic', label: result.output, visibility: 'hidden' }
241
+ : undefined,
201
242
 
202
243
  async execute(input, _context): Promise<ToolResult> {
203
244
  const required = requiredCapability(input.type)
@@ -1,4 +1,4 @@
1
- import { ProviderError } from '../provider/errors.js'
1
+ import { ProviderError, classifyProviderError } from '../provider/errors.js'
2
2
  import { isNamzuError } from './index.js'
3
3
 
4
4
  /**
@@ -84,13 +84,21 @@ export function factsOf(err: unknown): ErrorFacts {
84
84
  const hint = readHint(err)
85
85
  const message = err instanceof Error ? err.message : String(err)
86
86
 
87
- if (err instanceof ProviderError) {
87
+ const providerFailure =
88
+ err instanceof ProviderError
89
+ ? err
90
+ : err instanceof Error && err.name === 'ProviderRequestError'
91
+ ? classifyProviderError(err)
92
+ : undefined
93
+ if (providerFailure) {
88
94
  return {
89
- code: err.code,
95
+ code: providerFailure.code,
90
96
  message,
91
- name: err.name,
92
- ...(err.status !== undefined ? { status: err.status } : {}),
93
- ...(err.retryAfterMs !== undefined ? { retryAfterMs: err.retryAfterMs } : {}),
97
+ name: providerFailure.name,
98
+ ...(providerFailure.status !== undefined ? { status: providerFailure.status } : {}),
99
+ ...(providerFailure.retryAfterMs !== undefined
100
+ ? { retryAfterMs: providerFailure.retryAfterMs }
101
+ : {}),
94
102
  ...(hint !== undefined ? { hint } : {}),
95
103
  }
96
104
  }
@@ -1,5 +1,5 @@
1
1
  import type { PlatformError } from '../common/index.js'
2
- import { ProviderError } from '../provider/errors.js'
2
+ import { ProviderError, classifyProviderError } from '../provider/errors.js'
3
3
 
4
4
  /**
5
5
  * What went wrong, at the granularity a HOST actually branches on.
@@ -97,17 +97,31 @@ export function toPlatformError(err: unknown): PlatformError {
97
97
  }
98
98
  }
99
99
 
100
- if (err instanceof ProviderError) {
100
+ // Current drivers throw `ProviderRequestError`; older/custom providers may
101
+ // throw `ProviderError`. The retry layer already classifies both through the
102
+ // shared function below, but this terminal projection used to recognise only
103
+ // the older class and turn a first-hand 429 into unknown/non-retryable.
104
+ const providerFailure =
105
+ err instanceof ProviderError
106
+ ? err
107
+ : err instanceof Error && err.name === 'ProviderRequestError'
108
+ ? classifyProviderError(err)
109
+ : undefined
110
+ if (providerFailure) {
101
111
  return {
102
112
  code: 'provider_error',
103
- message: err.message,
113
+ message: providerFailure.message,
104
114
  details: {
105
- providerCode: err.code,
106
- ...(err.providerId !== undefined ? { providerId: err.providerId } : {}),
107
- ...(err.status !== undefined ? { status: err.status } : {}),
108
- ...(err.retryAfterMs !== undefined ? { retryAfterMs: err.retryAfterMs } : {}),
115
+ providerCode: providerFailure.code,
116
+ ...(providerFailure.providerId !== undefined
117
+ ? { providerId: providerFailure.providerId }
118
+ : {}),
119
+ ...(providerFailure.status !== undefined ? { status: providerFailure.status } : {}),
120
+ ...(providerFailure.retryAfterMs !== undefined
121
+ ? { retryAfterMs: providerFailure.retryAfterMs }
122
+ : {}),
109
123
  },
110
- retryable: err.retryable,
124
+ retryable: providerFailure.retryable,
111
125
  }
112
126
  }
113
127
 
@@ -138,6 +138,15 @@ export interface ProviderCapabilities {
138
138
  * treated as capable, same permissive default.
139
139
  */
140
140
  supportsDocuments?: boolean
141
+ /**
142
+ * Whether the driver maps image blocks returned by tools onto its tool-result
143
+ * wire. Separate from `supportsVision`: some protocols admit user image input
144
+ * but only text in a function result. Absent keeps the permissive compatibility
145
+ * default used by the older flags.
146
+ */
147
+ supportsToolResultImages?: boolean
148
+ /** Whether the driver maps document blocks returned by tools onto its result wire. */
149
+ supportsToolResultDocuments?: boolean
141
150
  maxOutputTokens?: number
142
151
  }
143
152
 
@@ -505,6 +505,17 @@ type CoreRunEvent =
505
505
  runId: RunId
506
506
  checkpointId: CheckpointId
507
507
  reason: string
508
+ /**
509
+ * The same structured failure projection a terminal `run_failed`
510
+ * carries. A pause is a different verdict, not a less informative one:
511
+ * the retryability and any provider-directed delay are what let a host
512
+ * decide when and how to resume this checkpoint.
513
+ */
514
+ failure?: PlatformError
515
+ /** First-hand driver classification, when the provider produced one. */
516
+ providerError?: import('../provider/error.js').ProviderErrorInfo
517
+ /** Curated operator copy, absent when no catalog rule matched. */
518
+ explanation?: { id: string; message: string; hint: string }
508
519
  }
509
520
  | {
510
521
  type: 'run_resuming'
@@ -593,13 +604,16 @@ type CoreRunEvent =
593
604
  // run when the request asks for something the provider DRIVER declared
594
605
  // it cannot do — tools registered against a no-tools driver (tool
595
606
  // surfaces stripped so the model is never told about uncallable
596
- // tools), image attachments against a no-vision driver, or document
597
- // attachments against a no-documents driver. Hosts surface these so
598
- // degradation is visible, not silent.
607
+ // tools), image attachments against a no-vision driver, document
608
+ // attachments against a no-documents driver, or rich tool blocks against a
609
+ // result wire that only carries text. Hosts surface these so degradation is
610
+ // visible, not silent.
599
611
  | {
600
612
  type: 'capability_warning'
601
613
  runId: RunId
602
614
  capability: 'tools' | 'vision' | 'documents'
615
+ /** Present when the mismatch was produced after a tool executed. */
616
+ contentSource?: 'tool-result'
603
617
  providerId: string
604
618
  message: string
605
619
  }
@@ -11,13 +11,20 @@ import type { ToolResult } from './index.js'
11
11
  * the raw arguments and rebuilt the same switch.
12
12
  *
13
13
  * The tool knows what it is doing; the host knows how its surface renders.
14
- * These are the three shapes one host had already found it needed, closed
14
+ * These are the shapes hosts have agreed to render, closed
15
15
  * deliberately: an open union would let a tool ask for a rendering no host
16
16
  * has, which is a request that fails silently at the far end.
17
17
  */
18
18
  export type ToolCallView =
19
19
  /** A line of text. What everything that is not a diff or a command gets. */
20
- | { readonly kind: 'generic'; readonly label: string }
20
+ | {
21
+ readonly kind: 'generic'
22
+ readonly label: string
23
+ /** Render this complete authored label without adding the registry name. */
24
+ readonly presentation?: 'activity'
25
+ /** A successful result may add no information beyond the completed call row. */
26
+ readonly visibility?: 'hidden'
27
+ }
21
28
  /**
22
29
  * A change to a document. `path` is optional because not every diff is
23
30
  * a file — a tool patching a remote record has a before and an after
@@ -32,7 +39,7 @@ export type ToolCallView =
32
39
  /** A command and what it printed. */
33
40
  | { readonly kind: 'terminal'; readonly command?: string; readonly output: string }
34
41
 
35
- /** The same three shapes, for what a call produced. */
42
+ /** The same shapes, for what a call produced. */
36
43
  export type ToolResultView = ToolCallView
37
44
 
38
45
  /**