@namzu/sdk 62.3.0 → 62.5.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 +29 -0
- package/dist/agents/QueryAgent.d.ts.map +1 -1
- package/dist/agents/QueryAgent.js +3 -0
- package/dist/agents/QueryAgent.js.map +1 -1
- package/dist/agents/runAgent.d.ts +3 -1
- package/dist/agents/runAgent.d.ts.map +1 -1
- package/dist/agents/runAgent.js +1 -0
- package/dist/agents/runAgent.js.map +1 -1
- package/dist/authorization/top-level-entries.d.ts +38 -0
- package/dist/authorization/top-level-entries.d.ts.map +1 -0
- package/dist/authorization/top-level-entries.js +200 -0
- package/dist/authorization/top-level-entries.js.map +1 -0
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +5 -3
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/peers/envelope.d.ts.map +1 -1
- package/dist/peers/envelope.js +3 -1
- package/dist/peers/envelope.js.map +1 -1
- package/dist/peers/protocol.d.ts +9 -0
- package/dist/peers/protocol.d.ts.map +1 -1
- package/dist/peers/protocol.js +3 -1
- package/dist/peers/protocol.js.map +1 -1
- package/dist/peers/record.d.ts +2 -0
- package/dist/peers/record.d.ts.map +1 -1
- package/dist/pricing/catalogue.generated.d.ts.map +1 -1
- package/dist/pricing/catalogue.generated.js +5 -0
- package/dist/pricing/catalogue.generated.js.map +1 -1
- package/dist/provider/fallback.d.ts.map +1 -1
- package/dist/provider/fallback.js +23 -1
- package/dist/provider/fallback.js.map +1 -1
- package/dist/public-runtime.d.ts +1 -1
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +1 -1
- package/dist/public-runtime.js.map +1 -1
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +2 -1
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.d.ts +21 -0
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +4 -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 +59 -6
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +4 -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/iteration/phases/tool-review.js +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/iteration/step-shaping.d.ts.map +1 -1
- package/dist/runtime/query/iteration/step-shaping.js +3 -0
- package/dist/runtime/query/iteration/step-shaping.js.map +1 -1
- package/dist/runtime/query/path-escalation.d.ts +10 -1
- package/dist/runtime/query/path-escalation.d.ts.map +1 -1
- package/dist/runtime/query/path-escalation.js +24 -2
- package/dist/runtime/query/path-escalation.js.map +1 -1
- package/dist/runtime/query/prepare-turn.d.ts.map +1 -1
- package/dist/runtime/query/prepare-turn.js +5 -2
- package/dist/runtime/query/prepare-turn.js.map +1 -1
- package/dist/runtime/query/request-rich-content.d.ts +7 -1
- package/dist/runtime/query/request-rich-content.d.ts.map +1 -1
- package/dist/runtime/query/request-rich-content.js +8 -2
- package/dist/runtime/query/request-rich-content.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts +1 -1
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +1 -1
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/turn/index.d.ts +1 -1
- package/dist/turn/index.d.ts.map +1 -1
- package/dist/turn/index.js +1 -1
- package/dist/turn/index.js.map +1 -1
- package/dist/turn/memory-recall.d.ts +13 -0
- package/dist/turn/memory-recall.d.ts.map +1 -1
- package/dist/turn/memory-recall.js +38 -1
- package/dist/turn/memory-recall.js.map +1 -1
- package/dist/types/agent/base.d.ts +2 -0
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/agent/query.d.ts +4 -0
- package/dist/types/agent/query.d.ts.map +1 -1
- package/dist/types/common/index.d.ts +7 -0
- package/dist/types/common/index.d.ts.map +1 -1
- package/dist/types/common/index.js +3 -0
- package/dist/types/common/index.js.map +1 -1
- package/dist/types/hitl/index.d.ts +3 -1
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/provider/chat.d.ts +10 -0
- package/dist/types/provider/chat.d.ts.map +1 -1
- package/dist/types/provider/config.d.ts +8 -0
- package/dist/types/provider/config.d.ts.map +1 -1
- package/dist/types/provider/index.d.ts +1 -1
- package/dist/types/provider/index.d.ts.map +1 -1
- package/dist/types/session/config.d.ts +10 -0
- package/dist/types/session/config.d.ts.map +1 -1
- package/dist/types/session/events.d.ts +8 -1
- package/dist/types/session/events.d.ts.map +1 -1
- package/dist/types/session/events.js.map +1 -1
- package/dist/types/session/prepare-step.d.ts +7 -0
- package/dist/types/session/prepare-step.d.ts.map +1 -1
- package/dist/utils/cost.d.ts +7 -0
- package/dist/utils/cost.d.ts.map +1 -1
- package/dist/utils/cost.js +15 -0
- package/dist/utils/cost.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/QueryAgent.ts +3 -0
- package/src/agents/runAgent.ts +9 -1
- package/src/authorization/top-level-entries.ts +203 -0
- package/src/bridge/a2a/mapper.ts +5 -3
- package/src/peers/envelope.ts +4 -1
- package/src/peers/protocol.ts +3 -1
- package/src/pricing/catalogue.generated.ts +5 -0
- package/src/pricing/rates.source.json +15 -5
- package/src/provider/fallback.ts +33 -1
- package/src/public-runtime.ts +1 -1
- package/src/runtime/query/executor.ts +6 -1
- package/src/runtime/query/index.ts +27 -0
- package/src/runtime/query/iteration/index.ts +70 -5
- package/src/runtime/query/iteration/phases/context.ts +4 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +1 -1
- package/src/runtime/query/iteration/step-shaping.ts +3 -0
- package/src/runtime/query/path-escalation.ts +33 -1
- package/src/runtime/query/prepare-turn.ts +6 -2
- package/src/runtime/query/request-rich-content.ts +11 -2
- package/src/runtime/query/review-policy.ts +1 -1
- package/src/turn/index.ts +1 -1
- package/src/turn/memory-recall.ts +40 -0
- package/src/types/agent/base.ts +2 -0
- package/src/types/agent/query.ts +4 -0
- package/src/types/common/index.ts +11 -0
- package/src/types/hitl/index.ts +3 -1
- package/src/types/provider/chat.ts +12 -0
- package/src/types/provider/config.ts +8 -0
- package/src/types/provider/index.ts +1 -0
- package/src/types/session/config.ts +11 -0
- package/src/types/session/events.ts +8 -1
- package/src/types/session/prepare-step.ts +7 -0
- package/src/utils/cost.ts +23 -0
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
* - does it write a protected path (a git hook, a shell rc file, editor or
|
|
8
8
|
* tool configuration, the project's `.namzu` directory)?
|
|
9
9
|
* - does its shell line remove something catastrophic?
|
|
10
|
+
* - does its call create or delete a top-level entry of the home folder or the
|
|
11
|
+
* filesystem root (see `authorization/top-level-entries.ts`)? It is reported
|
|
12
|
+
* as a protected path: the same question, asked the same way.
|
|
10
13
|
* - does its shell line reach a path outside the turn's roots, through a
|
|
11
14
|
* command whose operands are paths or through a redirection?
|
|
12
15
|
*
|
|
@@ -22,6 +25,10 @@ import { isProtectedPath } from '../../authorization/protected-paths.js'
|
|
|
22
25
|
import { dangerousRemoval } from '../../authorization/removal.js'
|
|
23
26
|
import type { ShellDialect } from '../../authorization/shell-lexer.js'
|
|
24
27
|
import { readShellLine, shellPathAccess } from '../../authorization/shell-paths.js'
|
|
28
|
+
import {
|
|
29
|
+
topLevelEntriesOfMovers,
|
|
30
|
+
topLevelEntryChange,
|
|
31
|
+
} from '../../authorization/top-level-entries.js'
|
|
25
32
|
import { canonicalize, pathOutsideRoots } from '../../tools/paths.js'
|
|
26
33
|
|
|
27
34
|
/** What the escalation records carry. */
|
|
@@ -38,6 +45,12 @@ export interface PathEscalationContext {
|
|
|
38
45
|
readonly cwd?: string
|
|
39
46
|
/** Whether to report paths outside the roots (`outsideRootAccess: 'review'`, no sandbox). */
|
|
40
47
|
readonly reviewOutside: boolean
|
|
48
|
+
/**
|
|
49
|
+
* Whether to report a top-level entry of the home folder or the filesystem
|
|
50
|
+
* root the line would create or delete. Like `reviewOutside`, off in a sandbox,
|
|
51
|
+
* where the paths are the guest's.
|
|
52
|
+
*/
|
|
53
|
+
readonly topLevel?: boolean
|
|
41
54
|
}
|
|
42
55
|
|
|
43
56
|
/**
|
|
@@ -137,11 +150,13 @@ function beforeGlob(path: string): string {
|
|
|
137
150
|
export async function declaredWriteEscalation(
|
|
138
151
|
roots: readonly string[],
|
|
139
152
|
value: string,
|
|
153
|
+
topLevel = false,
|
|
140
154
|
): Promise<string | undefined> {
|
|
141
155
|
const [first] = roots
|
|
142
156
|
if (first === undefined || value === '') return undefined
|
|
143
157
|
const absolute = resolve(resolve(first), value)
|
|
144
|
-
|
|
158
|
+
if (await isProtectedWrite(value, absolute, roots)) return absolute
|
|
159
|
+
return topLevel ? topLevelEntryChange(absolute, 'write', homedir()) : undefined
|
|
145
160
|
}
|
|
146
161
|
|
|
147
162
|
/** What a shell line reaches. */
|
|
@@ -190,6 +205,15 @@ export async function shellEscalations(
|
|
|
190
205
|
for (const candidate of absolutes) {
|
|
191
206
|
if (await isProtectedWrite(spelled, candidate, context.roots))
|
|
192
207
|
protectedPaths.add(candidate)
|
|
208
|
+
else if (
|
|
209
|
+
context.topLevel === true &&
|
|
210
|
+
'path' in settled &&
|
|
211
|
+
(!use.unresolved || /^\$(?:\{HOME\}|HOME)\//.test(spelled)) &&
|
|
212
|
+
use.via !== 'mv'
|
|
213
|
+
) {
|
|
214
|
+
const entry = topLevelEntryChange(candidate, use.via, home)
|
|
215
|
+
if (entry !== undefined) protectedPaths.add(entry)
|
|
216
|
+
}
|
|
193
217
|
}
|
|
194
218
|
}
|
|
195
219
|
if (!context.reviewOutside) continue
|
|
@@ -224,6 +248,14 @@ export async function shellEscalations(
|
|
|
224
248
|
}
|
|
225
249
|
}
|
|
226
250
|
}
|
|
251
|
+
if (context.topLevel === true) {
|
|
252
|
+
for (const entry of topLevelEntriesOfMovers(reading, {
|
|
253
|
+
home,
|
|
254
|
+
cwd,
|
|
255
|
+
changesDirectory: access.changesDirectory,
|
|
256
|
+
}))
|
|
257
|
+
protectedPaths.add(entry)
|
|
258
|
+
}
|
|
227
259
|
const removalAt = (directory: string | undefined) =>
|
|
228
260
|
directory === undefined
|
|
229
261
|
? undefined
|
|
@@ -332,8 +332,13 @@ export async function prepareTurn(params: QueryParams): Promise<PreparedTurn> {
|
|
|
332
332
|
const promptCache = params.promptCache
|
|
333
333
|
const taskScheduler = params.taskScheduler
|
|
334
334
|
const streamIdleTimeoutMs = resolveStreamIdleTimeoutMs(params.turnConfig.streamIdleTimeoutMs)
|
|
335
|
-
|
|
335
|
+
// Validated here, at the door, but only the caller's own override is kept on
|
|
336
|
+
// the turn: the provider's declaration is read where it is used (see
|
|
337
|
+
// `IterationOrchestrator.richContentBudget`), so it follows the provider
|
|
338
|
+
// that serves the turn rather than being pinned by the first one.
|
|
339
|
+
resolveMaxRequestRichContentBytes(
|
|
336
340
|
params.turnConfig.maxRequestRichContentBytes,
|
|
341
|
+
params.provider.capabilities?.maxRequestRichContentBytes,
|
|
337
342
|
)
|
|
338
343
|
const sandboxTeardownTimeoutMs = resolveSandboxTeardownTimeoutMs(params.sandboxTeardownTimeoutMs)
|
|
339
344
|
// Persist the EFFECTIVE value, not only an override. A turn replayed after a
|
|
@@ -343,7 +348,6 @@ export async function prepareTurn(params: QueryParams): Promise<PreparedTurn> {
|
|
|
343
348
|
const turnConfig: TurnConfig = {
|
|
344
349
|
...params.turnConfig,
|
|
345
350
|
streamIdleTimeoutMs,
|
|
346
|
-
maxRequestRichContentBytes,
|
|
347
351
|
}
|
|
348
352
|
|
|
349
353
|
// The turn's one correlated logger, built before anything below needs
|
|
@@ -12,8 +12,17 @@ export const DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES = 24 * 1024 * 1024
|
|
|
12
12
|
|
|
13
13
|
const MAX_REQUEST_RICH_CONTENT_BYTES = Number.MAX_SAFE_INTEGER
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The budget for one turn: the caller's `turnConfig.maxRequestRichContentBytes`
|
|
17
|
+
* when set, else the one the provider declares for its own wire limit
|
|
18
|
+
* (`ProviderCapabilities.maxRequestRichContentBytes`), else the kernel default.
|
|
19
|
+
* The override always wins, so a host can tighten or loosen what a driver declares.
|
|
20
|
+
*/
|
|
21
|
+
export function resolveMaxRequestRichContentBytes(
|
|
22
|
+
value: number | undefined,
|
|
23
|
+
providerDeclared?: number,
|
|
24
|
+
): number {
|
|
25
|
+
const resolved = value ?? providerDeclared ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES
|
|
17
26
|
if (
|
|
18
27
|
!Number.isSafeInteger(resolved) ||
|
|
19
28
|
resolved < 0 ||
|
|
@@ -293,7 +293,7 @@ export const UNKNOWN_PROGRAM_UNATTENDED_REFUSAL =
|
|
|
293
293
|
* existed (a mode, a rule, "approve all") is not an answer about it.
|
|
294
294
|
*/
|
|
295
295
|
export const PROTECTED_PATH_UNATTENDED_REFUSAL =
|
|
296
|
-
"Refused: this call writes a protected path (a git hook or config, a shell startup file, editor or tool configuration, or the project's .namzu directory), which needs a person to approve it each time, and nobody can be asked in this session. This call did not run; the other calls in the batch are not affected.
|
|
296
|
+
"Refused: this call writes a protected path (a git hook or config, a shell startup file, editor or tool configuration, or the project's .namzu directory) or creates or deletes a top-level entry directly in the home folder or the filesystem root, which needs a person to approve it each time, and nobody can be asked in this session. This call did not run; the other calls in the batch are not affected. Work inside a project folder instead (create it first, or use an existing one), or tell the user what change you need so they can make it."
|
|
297
297
|
|
|
298
298
|
/**
|
|
299
299
|
* What the model is told when a batch removes something catastrophic (the
|
package/src/turn/index.ts
CHANGED
|
@@ -23,7 +23,7 @@ export type { LimitCheckerState, LimitCheckResult } from './LimitChecker.js'
|
|
|
23
23
|
|
|
24
24
|
export { SESSION_MEMORY_TAG, createMemoryPromoter } from './memory-promoter.js'
|
|
25
25
|
export type { MemoryPromoterOptions, SessionMemoryCategory } from './memory-promoter.js'
|
|
26
|
-
export { createMemoryRecallStep } from './memory-recall.js'
|
|
26
|
+
export { createMemoryRecallStep, recalledMemoryIds } from './memory-recall.js'
|
|
27
27
|
export type {
|
|
28
28
|
MemoryRecallOptions,
|
|
29
29
|
MemorySelection,
|
|
@@ -80,6 +80,12 @@ export interface MemoryRecallOptions {
|
|
|
80
80
|
readonly minCoverage?: number
|
|
81
81
|
/** Upper bound on the selector, in ms; the signal it is given aborts then. Default 2,500. */
|
|
82
82
|
readonly selectTimeoutMs?: number
|
|
83
|
+
/**
|
|
84
|
+
* Ids recall must not offer, read afresh on every request. A host keeps a
|
|
85
|
+
* set-aside list here (records a refused request carried) and lifts it when
|
|
86
|
+
* the person restores a record. A throw reads as an empty list.
|
|
87
|
+
*/
|
|
88
|
+
readonly excluded?: () => Iterable<string> | Promise<Iterable<string>>
|
|
83
89
|
}
|
|
84
90
|
|
|
85
91
|
/** What a selector may know about a record: never its body. */
|
|
@@ -126,6 +132,27 @@ const OTHERS_PLURAL = (count: number): string =>
|
|
|
126
132
|
export const RECALLED_MEMORY_ENTRY_KEY = 'memory'
|
|
127
133
|
|
|
128
134
|
/** The `id@updatedAt` of every record the entries still in the history carry. */
|
|
135
|
+
/**
|
|
136
|
+
* The ids of the records the `memory` entries carry, in the order they were
|
|
137
|
+
* recorded and without repeats. `entries` are bodies as `turnContextEntries`
|
|
138
|
+
* returns them.
|
|
139
|
+
*/
|
|
140
|
+
export function recalledMemoryIds(entries: readonly string[]): string[] {
|
|
141
|
+
const ids = new Set<string>()
|
|
142
|
+
for (const entry of entries) {
|
|
143
|
+
for (const line of entry.split('\n')) {
|
|
144
|
+
if (!line.startsWith('{')) continue
|
|
145
|
+
try {
|
|
146
|
+
const parsed = JSON.parse(line) as { id?: unknown }
|
|
147
|
+
if (typeof parsed.id === 'string') ids.add(parsed.id)
|
|
148
|
+
} catch {
|
|
149
|
+
// a line of the entry that is not a record
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return [...ids]
|
|
154
|
+
}
|
|
155
|
+
|
|
129
156
|
function recordedRecords(entries: readonly string[]): Set<string> {
|
|
130
157
|
const seen = new Set<string>()
|
|
131
158
|
for (const entry of entries) {
|
|
@@ -377,8 +404,12 @@ export function createMemoryRecallStep(options: MemoryRecallOptions): PrepareSte
|
|
|
377
404
|
latestUserMessage,
|
|
378
405
|
contextBudget,
|
|
379
406
|
signal,
|
|
407
|
+
withheldKeys,
|
|
380
408
|
}) => {
|
|
381
409
|
signal?.throwIfAborted()
|
|
410
|
+
// A refused request was re-run without the memories it carried; adding
|
|
411
|
+
// them again would be refused again.
|
|
412
|
+
if (withheldKeys?.includes(RECALLED_MEMORY_ENTRY_KEY)) return undefined
|
|
382
413
|
// Leave room for the current request and response. The kernel supplies
|
|
383
414
|
// an estimate; using one character per remaining token is deliberately
|
|
384
415
|
// conservative for this optional text, not a billing/tokenizer claim.
|
|
@@ -484,6 +515,14 @@ export function createMemoryRecallStep(options: MemoryRecallOptions): PrepareSte
|
|
|
484
515
|
}
|
|
485
516
|
const recall = async (): Promise<Recalled> => {
|
|
486
517
|
const shown: RecalledMemory[] = []
|
|
518
|
+
let excludedIds: ReadonlySet<string> = new Set()
|
|
519
|
+
if (options.excluded) {
|
|
520
|
+
try {
|
|
521
|
+
excludedIds = new Set(await options.excluded())
|
|
522
|
+
} catch {
|
|
523
|
+
// An unreadable list excludes nothing.
|
|
524
|
+
}
|
|
525
|
+
}
|
|
487
526
|
const page = await options.store.list({
|
|
488
527
|
query: terms.join(' '),
|
|
489
528
|
status: 'active',
|
|
@@ -501,6 +540,7 @@ export function createMemoryRecallStep(options: MemoryRecallOptions): PrepareSte
|
|
|
501
540
|
let block = lead
|
|
502
541
|
const fresh = page.entries
|
|
503
542
|
.filter((entry) => entry.status === 'active')
|
|
543
|
+
.filter((entry) => !excludedIds.has(entry.id))
|
|
504
544
|
.filter((entry) => !known.has(`${entry.id}@${entry.updatedAt}`))
|
|
505
545
|
const candidates = fresh.slice(0, shortlist)
|
|
506
546
|
const picks = await choose(candidates)
|
package/src/types/agent/base.ts
CHANGED
|
@@ -226,6 +226,8 @@ export interface BaseAgentConfig {
|
|
|
226
226
|
*/
|
|
227
227
|
thinking?: import('../provider/index.js').ThinkingConfig
|
|
228
228
|
effort?: import('../provider/index.js').ReasoningEffort
|
|
229
|
+
/** Inference speed; see {@link import('../session/config.js').TurnConfig.speed}. */
|
|
230
|
+
speed?: import('../provider/index.js').InferenceSpeed
|
|
229
231
|
/** How the turn bounds its reasoning; see {@link import('../session/config.js').TurnConfig.reasoning}. */
|
|
230
232
|
reasoning?: import('../session/config.js').TurnConfig['reasoning']
|
|
231
233
|
/** Ask once for a check of edits before a turn ends; see {@link import('../session/config.js').TurnConfig.completionAudit}. */
|
package/src/types/agent/query.ts
CHANGED
|
@@ -100,6 +100,10 @@ export interface QueryAgentConfig extends BaseAgentConfig {
|
|
|
100
100
|
maxOutputContinuations?: QueryParams['maxOutputContinuations']
|
|
101
101
|
/** See {@link QueryParams.refusalFallback}. */
|
|
102
102
|
refusalFallback?: QueryParams['refusalFallback']
|
|
103
|
+
/** See {@link QueryParams.withholdOnRefusal}. */
|
|
104
|
+
withholdOnRefusal?: QueryParams['withholdOnRefusal']
|
|
105
|
+
/** See {@link QueryParams.withheldKeys}. */
|
|
106
|
+
withheldKeys?: QueryParams['withheldKeys']
|
|
103
107
|
maxToolOutputChars?: number
|
|
104
108
|
maxToolOutputCharsPerMessage?: number
|
|
105
109
|
retainedToolPreviewChars?: QueryParams['retainedToolPreviewChars']
|
|
@@ -42,6 +42,14 @@ export interface TokenUsage {
|
|
|
42
42
|
* {@link TokenUsage.cacheTtlMs}.
|
|
43
43
|
*/
|
|
44
44
|
cacheWriteTtlTokens?: { fiveMin?: number; oneHour?: number }
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The speed the provider says served this call, when it says. `'fast'` is a
|
|
48
|
+
* premium-priced mode, so pricing reads it per call: a per-call fact like
|
|
49
|
+
* {@link TokenUsage.cacheTtlMs}, never summed. Absent means standard or
|
|
50
|
+
* unreported.
|
|
51
|
+
*/
|
|
52
|
+
speed?: import('../provider/chat.js').InferenceSpeed
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
export function accumulateTokenUsage(current: TokenUsage, addition: TokenUsage): TokenUsage {
|
|
@@ -101,6 +109,9 @@ export function mergeTokenUsage(current: TokenUsage, next: TokenUsage): TokenUsa
|
|
|
101
109
|
...(next.cacheWriteTtlTokens !== undefined || current.cacheWriteTtlTokens !== undefined
|
|
102
110
|
? { cacheWriteTtlTokens: next.cacheWriteTtlTokens ?? current.cacheWriteTtlTokens }
|
|
103
111
|
: {}),
|
|
112
|
+
...(next.speed !== undefined || current.speed !== undefined
|
|
113
|
+
? { speed: next.speed ?? current.speed }
|
|
114
|
+
: {}),
|
|
104
115
|
}
|
|
105
116
|
}
|
|
106
117
|
|
package/src/types/hitl/index.ts
CHANGED
|
@@ -389,7 +389,9 @@ export interface ToolCallEscalation {
|
|
|
389
389
|
* asked; no rule, mode or remembered approval covers it. Set for the file
|
|
390
390
|
* tools' declared path and for the visible write targets of a shell line:
|
|
391
391
|
* output redirections, and the operands of `cp`, `mv`, `tee`, `touch`,
|
|
392
|
-
* `mkdir`, `rm`, `rmdir` and `sed -i`.
|
|
392
|
+
* `mkdir`, `rm`, `rmdir` and `sed -i`. A top-level entry of the home folder or
|
|
393
|
+
* the filesystem root that the call would create or delete is listed here
|
|
394
|
+
* too (when the turn reviews outside paths and runs without a sandbox).
|
|
393
395
|
*/
|
|
394
396
|
protectedPaths?: readonly string[]
|
|
395
397
|
/**
|
|
@@ -106,6 +106,15 @@ export interface ChatCompletionParams {
|
|
|
106
106
|
* that narrower set according to their documented provider policy.
|
|
107
107
|
*/
|
|
108
108
|
effort?: ReasoningEffort
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Inference speed. `'fast'` asks a provider for its premium low-latency
|
|
112
|
+
* mode, billed at a multiple of the standard rate; absent and `'standard'`
|
|
113
|
+
* are the same request. A driver with no such mode, or a model without it,
|
|
114
|
+
* must refuse `'fast'` rather than serve it at standard speed and let the
|
|
115
|
+
* caller believe it was honoured.
|
|
116
|
+
*/
|
|
117
|
+
speed?: InferenceSpeed
|
|
109
118
|
}
|
|
110
119
|
|
|
111
120
|
export interface ThinkingConfig {
|
|
@@ -174,6 +183,9 @@ export interface ThinkingConfig {
|
|
|
174
183
|
* transport or leave the vendor to refuse an unknown compatible-endpoint
|
|
175
184
|
* extension explicitly.
|
|
176
185
|
*/
|
|
186
|
+
/** `'fast'` is a premium low-latency mode; `'standard'` is the ordinary request. See {@link ChatCompletionParams.speed}. */
|
|
187
|
+
export type InferenceSpeed = 'standard' | 'fast'
|
|
188
|
+
|
|
177
189
|
export type ReasoningEffort =
|
|
178
190
|
| 'none'
|
|
179
191
|
| 'minimal'
|
|
@@ -170,6 +170,14 @@ export interface ProviderCapabilities {
|
|
|
170
170
|
* or the lifetime is the provider's own and cannot be chosen or read).
|
|
171
171
|
*/
|
|
172
172
|
cacheTtl?: readonly ('5m' | '1h')[]
|
|
173
|
+
/**
|
|
174
|
+
* The most base64 characters of inline images and documents this provider
|
|
175
|
+
* will take in one request, when its wire limit differs from the kernel's
|
|
176
|
+
* default (24 MiB). Counts the encoded value, like
|
|
177
|
+
* `turnConfig.maxRequestRichContentBytes`, which still overrides it.
|
|
178
|
+
* Absent means the kernel default.
|
|
179
|
+
*/
|
|
180
|
+
maxRequestRichContentBytes?: number
|
|
173
181
|
}
|
|
174
182
|
|
|
175
183
|
export interface ProviderFactoryResult {
|
|
@@ -69,6 +69,17 @@ export interface TurnConfig {
|
|
|
69
69
|
*/
|
|
70
70
|
effort?: import('../provider/index.js').ReasoningEffort
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Inference speed for every model call in the turn: `'fast'` asks for the
|
|
74
|
+
* provider's premium low-latency mode (billed at a multiple of the standard
|
|
75
|
+
* rate), absent and `'standard'` are the ordinary request. Turn-level for
|
|
76
|
+
* the same reason as {@link TurnConfig.effort}: speeds do not share a
|
|
77
|
+
* prompt-cache prefix, so a value that moves between steps pays for a cache
|
|
78
|
+
* miss each time. A driver or model without the mode REFUSES `'fast'`
|
|
79
|
+
* rather than serving it slowly.
|
|
80
|
+
*/
|
|
81
|
+
speed?: import('../provider/index.js').InferenceSpeed
|
|
82
|
+
|
|
72
83
|
/**
|
|
73
84
|
* How the turn bounds its reasoning. On by default.
|
|
74
85
|
*
|
|
@@ -519,7 +519,14 @@ type CoreSessionEvent =
|
|
|
519
519
|
/** The model that declined. */
|
|
520
520
|
model: string
|
|
521
521
|
providerId: string
|
|
522
|
-
outcome: 'fallback' | 'retry' | 'declined'
|
|
522
|
+
outcome: 'fallback' | 'retry' | 'withheld' | 'declined'
|
|
523
|
+
/**
|
|
524
|
+
* Set only with `outcome: 'withheld'`: the recorded-context keys the
|
|
525
|
+
* re-run leaves out of the request (see `QueryParams.withholdOnRefusal`).
|
|
526
|
+
*/
|
|
527
|
+
withheldKeys?: string[]
|
|
528
|
+
/** With `'withheld'`: the ids of the recalled memories those entries carried. */
|
|
529
|
+
withheldMemoryIds?: string[]
|
|
523
530
|
/** The model the request moves to. Set only with `outcome: 'fallback'`. */
|
|
524
531
|
fallbackModel?: string
|
|
525
532
|
/** The provider's own classification, when it gave one. */
|
|
@@ -98,6 +98,13 @@ export interface PrepareStepContext {
|
|
|
98
98
|
}
|
|
99
99
|
/** Every completed step, in order. */
|
|
100
100
|
readonly steps: readonly StepResult[]
|
|
101
|
+
/**
|
|
102
|
+
* Recorded-context keys the request leaves out: set aside by a refused
|
|
103
|
+
* request (`QueryParams.withholdOnRefusal`) or by the host
|
|
104
|
+
* (`QueryParams.withheldKeys`). A stage that records text under one of
|
|
105
|
+
* these keys should add nothing now; whatever it records is also left out.
|
|
106
|
+
*/
|
|
107
|
+
readonly withheldKeys?: readonly string[]
|
|
101
108
|
|
|
102
109
|
/**
|
|
103
110
|
* What the stages before this one decided, when several were supplied.
|
package/src/utils/cost.ts
CHANGED
|
@@ -41,6 +41,13 @@ export interface ModelPricing {
|
|
|
41
41
|
* part. The catalogue always supplies this.
|
|
42
42
|
*/
|
|
43
43
|
cache?: CacheRates
|
|
44
|
+
/**
|
|
45
|
+
* The vendor's published multiple of every rate on this card for a request
|
|
46
|
+
* served in fast mode (`TokenUsage.speed === 'fast'`). Absent means there is
|
|
47
|
+
* no published fast price: fast usage is then counted as unpriced, never
|
|
48
|
+
* charged at the standard rate, which would under-report it.
|
|
49
|
+
*/
|
|
50
|
+
fastMultiplier?: number
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
export { ZERO_COST }
|
|
@@ -54,6 +61,22 @@ interface Priced {
|
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
function priceUsage(usage: TokenUsage, pricing: ModelPricing): Priced {
|
|
64
|
+
if (usage.speed === 'fast') {
|
|
65
|
+
const multiplier = pricing.fastMultiplier
|
|
66
|
+
if (multiplier === undefined) {
|
|
67
|
+
return { cost: 0, cacheDiscount: 0, unpriced: usage.totalTokens }
|
|
68
|
+
}
|
|
69
|
+
const standard = priceStandard({ ...usage, speed: undefined }, pricing)
|
|
70
|
+
return {
|
|
71
|
+
cost: standard.cost * multiplier,
|
|
72
|
+
cacheDiscount: standard.cacheDiscount * multiplier,
|
|
73
|
+
unpriced: standard.unpriced,
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return priceStandard(usage, pricing)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function priceStandard(usage: TokenUsage, pricing: ModelPricing): Priced {
|
|
57
80
|
const perMillion = (tokens: number, rate: number) => (tokens / 1_000_000) * rate
|
|
58
81
|
|
|
59
82
|
const cache = pricing.cache
|