@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.
- package/CHANGELOG.md +30 -0
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +13 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +3 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/provider/capabilities.d.ts +2 -0
- package/dist/provider/capabilities.d.ts.map +1 -1
- package/dist/provider/capabilities.js +6 -0
- package/dist/provider/capabilities.js.map +1 -1
- package/dist/runtime/query/index.d.ts +3 -1
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +2 -0
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +10 -0
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +67 -0
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +5 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/result.d.ts.map +1 -1
- package/dist/runtime/query/result.js +25 -22
- package/dist/runtime/query/result.js.map +1 -1
- package/dist/tools/builtins/computer-use.d.ts.map +1 -1
- package/dist/tools/builtins/computer-use.js +37 -0
- package/dist/tools/builtins/computer-use.js.map +1 -1
- package/dist/types/errors/catalog.d.ts.map +1 -1
- package/dist/types/errors/catalog.js +13 -6
- package/dist/types/errors/catalog.js.map +1 -1
- package/dist/types/errors/index.d.ts.map +1 -1
- package/dist/types/errors/index.js +21 -8
- package/dist/types/errors/index.js.map +1 -1
- package/dist/types/provider/config.d.ts +9 -0
- package/dist/types/provider/config.d.ts.map +1 -1
- package/dist/types/run/events.d.ts +17 -0
- package/dist/types/run/events.d.ts.map +1 -1
- package/dist/types/run/events.js.map +1 -1
- package/dist/types/tool/presentation.d.ts +6 -2
- package/dist/types/tool/presentation.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/bridge/a2a/mapper.ts +23 -4
- package/src/bridge/sse/mapper.ts +3 -0
- package/src/provider/capabilities.ts +10 -0
- package/src/runtime/query/index.ts +5 -1
- package/src/runtime/query/iteration/index.ts +72 -0
- package/src/runtime/query/iteration/phases/context.ts +5 -0
- package/src/runtime/query/result.ts +25 -23
- package/src/tools/builtins/computer-use.ts +41 -0
- package/src/types/errors/catalog.ts +14 -6
- package/src/types/errors/index.ts +22 -8
- package/src/types/provider/config.ts +9 -0
- package/src/types/run/events.ts +17 -3
- 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
|
-
|
|
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:
|
|
95
|
+
code: providerFailure.code,
|
|
90
96
|
message,
|
|
91
|
-
name:
|
|
92
|
-
...(
|
|
93
|
-
...(
|
|
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
|
-
|
|
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:
|
|
113
|
+
message: providerFailure.message,
|
|
104
114
|
details: {
|
|
105
|
-
providerCode:
|
|
106
|
-
...(
|
|
107
|
-
|
|
108
|
-
|
|
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:
|
|
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
|
|
package/src/types/run/events.ts
CHANGED
|
@@ -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,
|
|
597
|
-
// attachments against a no-documents driver
|
|
598
|
-
//
|
|
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
|
|
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
|
-
| {
|
|
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
|
|
42
|
+
/** The same shapes, for what a call produced. */
|
|
36
43
|
export type ToolResultView = ToolCallView
|
|
37
44
|
|
|
38
45
|
/**
|