@namzu/sdk 52.7.0 → 53.0.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 +39 -26
- package/dist/authorization/protected-paths.d.ts +2 -4
- package/dist/authorization/protected-paths.d.ts.map +1 -1
- package/dist/authorization/protected-paths.js +2 -4
- package/dist/authorization/protected-paths.js.map +1 -1
- package/dist/authorization/readonly-commands.d.ts +4 -4
- package/dist/authorization/readonly-commands.js +7 -7
- package/dist/authorization/readonly-commands.js.map +1 -1
- package/dist/authorization/readonly-flags.d.ts +1 -2
- package/dist/authorization/readonly-flags.d.ts.map +1 -1
- package/dist/authorization/readonly-flags.js +1 -2
- package/dist/authorization/readonly-flags.js.map +1 -1
- package/dist/authorization/removal.d.ts +2 -3
- package/dist/authorization/removal.d.ts.map +1 -1
- package/dist/authorization/removal.js +3 -4
- package/dist/authorization/removal.js.map +1 -1
- package/dist/authorization/shell-paths.d.ts +5 -5
- package/dist/authorization/shell-paths.js +6 -6
- package/dist/authorization/shell-paths.js.map +1 -1
- package/dist/compaction/context-window.d.ts +1 -1
- package/dist/compaction/context-window.js +1 -1
- package/dist/compaction/verifier.js +2 -2
- package/dist/compaction/verifier.js.map +1 -1
- package/dist/connector/web/page.d.ts +2 -3
- package/dist/connector/web/page.d.ts.map +1 -1
- package/dist/connector/web/page.js +2 -3
- package/dist/connector/web/page.js.map +1 -1
- package/dist/execution/workflow/prelude.d.ts.map +1 -1
- package/dist/execution/workflow/prelude.js +29 -5
- package/dist/execution/workflow/prelude.js.map +1 -1
- package/dist/execution/workflow/runtime.d.ts +2 -0
- package/dist/execution/workflow/runtime.d.ts.map +1 -1
- package/dist/execution/workflow/runtime.js +8 -3
- package/dist/execution/workflow/runtime.js.map +1 -1
- package/dist/execution/workflow/types.d.ts +3 -3
- package/dist/execution/workflow/types.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.d.ts +1 -1
- package/dist/manager/agent/lifecycle.js +1 -1
- package/dist/plugin/shell-hook.d.ts +1 -1
- package/dist/plugin/shell-hook.js +4 -4
- package/dist/plugin/shell-hook.js.map +1 -1
- package/dist/provider/errors.js +2 -2
- package/dist/provider/errors.js.map +1 -1
- package/dist/public-runtime.d.ts +1 -0
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js.map +1 -1
- package/dist/runtime/jobs/monitor-stream.d.ts +1 -2
- package/dist/runtime/jobs/monitor-stream.d.ts.map +1 -1
- package/dist/runtime/jobs/monitor-stream.js +1 -2
- package/dist/runtime/jobs/monitor-stream.js.map +1 -1
- package/dist/runtime/jobs/websocket-source.d.ts +1 -1
- package/dist/runtime/jobs/websocket-source.d.ts.map +1 -1
- package/dist/runtime/jobs/websocket-source.js +1 -1
- package/dist/runtime/jobs/websocket-source.js.map +1 -1
- package/dist/runtime/query/iteration/index.js +3 -3
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/outstanding-work.d.ts.map +1 -1
- package/dist/runtime/query/iteration/outstanding-work.js +10 -2
- package/dist/runtime/query/iteration/outstanding-work.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts +2 -2
- package/dist/runtime/query/iteration/phases/compaction-breaker.js +2 -2
- package/dist/runtime/query/iteration/phases/compaction.d.ts +3 -5
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +6 -8
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/request-repair.d.ts +1 -1
- package/dist/runtime/query/iteration/request-repair.js +2 -2
- package/dist/runtime/query/iteration/request-repair.js.map +1 -1
- package/dist/runtime/query/path-escalation.d.ts.map +1 -1
- package/dist/runtime/query/path-escalation.js +2 -3
- package/dist/runtime/query/path-escalation.js.map +1 -1
- package/dist/scheduler/completion-inbox.d.ts +21 -1
- package/dist/scheduler/completion-inbox.d.ts.map +1 -1
- package/dist/scheduler/completion-inbox.js +20 -1
- package/dist/scheduler/completion-inbox.js.map +1 -1
- package/dist/session/workspace/driver.d.ts +1 -1
- package/dist/store/checkpoint/memory.d.ts +1 -1
- package/dist/store/checkpoint/memory.js +1 -1
- package/dist/store/memory/markdown-format.d.ts +1 -1
- package/dist/store/memory/markdown-format.js +1 -1
- package/dist/store/memory/markdown.js +1 -1
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +1 -2
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/edit-match.d.ts +5 -6
- package/dist/tools/builtins/edit-match.d.ts.map +1 -1
- package/dist/tools/builtins/edit-match.js +5 -6
- package/dist/tools/builtins/edit-match.js.map +1 -1
- package/dist/types/provider/errors.js +1 -1
- package/dist/types/provider/errors.js.map +1 -1
- package/package.json +1 -1
- package/src/authorization/protected-paths.ts +2 -4
- package/src/authorization/readonly-commands.ts +7 -7
- package/src/authorization/readonly-flags.ts +1 -2
- package/src/authorization/removal.ts +3 -4
- package/src/authorization/shell-paths.ts +6 -6
- package/src/compaction/context-window.ts +1 -1
- package/src/compaction/verifier.ts +2 -2
- package/src/connector/web/page.ts +2 -3
- package/src/execution/workflow/prelude.ts +29 -5
- package/src/execution/workflow/runtime.ts +9 -3
- package/src/execution/workflow/types.ts +3 -3
- package/src/manager/agent/lifecycle.ts +1 -1
- package/src/plugin/shell-hook.ts +4 -4
- package/src/provider/errors.ts +2 -2
- package/src/public-runtime.ts +1 -0
- package/src/runtime/jobs/monitor-stream.ts +1 -2
- package/src/runtime/jobs/websocket-source.ts +1 -1
- package/src/runtime/query/iteration/index.ts +3 -3
- package/src/runtime/query/iteration/outstanding-work.ts +9 -2
- package/src/runtime/query/iteration/phases/compaction-breaker.ts +2 -2
- package/src/runtime/query/iteration/phases/compaction.ts +6 -8
- package/src/runtime/query/iteration/request-repair.ts +3 -3
- package/src/runtime/query/path-escalation.ts +2 -3
- package/src/scheduler/completion-inbox.ts +31 -1
- package/src/session/workspace/driver.ts +1 -1
- package/src/store/checkpoint/memory.ts +1 -1
- package/src/store/memory/markdown-format.ts +1 -1
- package/src/store/memory/markdown.ts +1 -1
- package/src/tools/builtins/bash.ts +1 -2
- package/src/tools/builtins/edit-match.ts +5 -6
- package/src/types/provider/errors.ts +1 -1
package/src/plugin/shell-hook.ts
CHANGED
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
* - `systemMessage` — a warning for the operator, reported through the logger.
|
|
58
58
|
* - `suppressOutput` — keep this hook's stdout out of the debug log.
|
|
59
59
|
* - `hookSpecificOutput` with `hookEventName` naming this event (Namzu's
|
|
60
|
-
* name or the
|
|
60
|
+
* name or the PascalCase spelling `PreToolUse`, `Stop`, ...):
|
|
61
61
|
* `permissionDecision` (`allow`, `deny` or `ask`) with
|
|
62
62
|
* `permissionDecisionReason`, `updatedInput` and `additionalContext` for
|
|
63
63
|
* `pre_tool_use`; `additionalContext` for `user_prompt_submit`,
|
|
@@ -458,8 +458,8 @@ function pathOf(toolInput: unknown): string | undefined {
|
|
|
458
458
|
return undefined
|
|
459
459
|
}
|
|
460
460
|
|
|
461
|
-
/** The
|
|
462
|
-
const
|
|
461
|
+
/** The PascalCase spelling of each event name, which a hook's JSON may use. */
|
|
462
|
+
const PASCAL_EVENT_NAMES: Readonly<Partial<Record<ShellHookEvent, string>>> = {
|
|
463
463
|
user_prompt_submit: 'UserPromptSubmit',
|
|
464
464
|
session_start: 'SessionStart',
|
|
465
465
|
session_end: 'SessionEnd',
|
|
@@ -565,7 +565,7 @@ function readShellHookJson(event: ShellHookEvent, stdout: string): ShellHookRead
|
|
|
565
565
|
if (typeof named !== 'string') {
|
|
566
566
|
return { invalid: '`hookSpecificOutput` is missing its `hookEventName`' }
|
|
567
567
|
}
|
|
568
|
-
if (named !== event && named !==
|
|
568
|
+
if (named !== event && named !== PASCAL_EVENT_NAMES[event]) {
|
|
569
569
|
return {
|
|
570
570
|
invalid: `\`hookSpecificOutput.hookEventName\` is "${named}" but this hook ran for ${event}`,
|
|
571
571
|
}
|
package/src/provider/errors.ts
CHANGED
|
@@ -260,8 +260,8 @@ const OVERFLOW_BODY_PATTERNS: readonly RegExp[] = [
|
|
|
260
260
|
// length" — so a pattern anchored on "exceeded" misses it entirely.
|
|
261
261
|
/exceeds?\s+(?:the\s+)?(?:model'?s?\s+)?context\s+(?:length|window|size)/i,
|
|
262
262
|
/context\s+(?:length|window|size)\s+exceed/i,
|
|
263
|
-
// The
|
|
264
|
-
// window". Here it must sit next to a verb that says the request did not
|
|
263
|
+
// The bare phrase "context
|
|
264
|
+
// window" is too broad on its own. Here it must sit next to a verb that says the request did not
|
|
265
265
|
// fit ("larger than the model context window of N tokens"), so a 400 that
|
|
266
266
|
// only names the window ("does not support this parameter with the 1M
|
|
267
267
|
// context window beta") stays an invalid request. The same pattern lives in
|
package/src/public-runtime.ts
CHANGED
|
@@ -722,6 +722,7 @@ export {
|
|
|
722
722
|
CompletionInbox,
|
|
723
723
|
formatCompletionNotification,
|
|
724
724
|
} from './scheduler/completion-inbox.js'
|
|
725
|
+
export type { CompletionInboxOptions } from './scheduler/completion-inbox.js'
|
|
725
726
|
|
|
726
727
|
// Scheduled jobs: WHEN something is due, and nothing about how a host stores
|
|
727
728
|
// or runs a job. The time engine and the evaluator are pure (`Intl` for time
|
|
@@ -15,8 +15,7 @@
|
|
|
15
15
|
* work without any injection), which is what lets the tests advance a window
|
|
16
16
|
* by calling a function rather than by waiting for one.
|
|
17
17
|
*
|
|
18
|
-
* The constants and the wording
|
|
19
|
-
* tool; deviations are named where they are made.
|
|
18
|
+
* The constants and the wording are fixed here.
|
|
20
19
|
*/
|
|
21
20
|
|
|
22
21
|
/** A longer line keeps its first this-many characters. */
|
|
@@ -29,7 +29,7 @@ import type { JobHost, JobSource } from './registry.js'
|
|
|
29
29
|
* asks a person first (see `tools/builtins/monitor.ts`).
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
-
/** The largest frame accepted; a bigger one ends the watch.
|
|
32
|
+
/** The largest frame accepted; a bigger one ends the watch. */
|
|
33
33
|
export const WEBSOCKET_MAX_PAYLOAD_BYTES = 1_048_576
|
|
34
34
|
export const WEBSOCKET_HANDSHAKE_TIMEOUT_MS = 15_000
|
|
35
35
|
/** After a polite close, how long a peer gets to answer before the socket is destroyed. */
|
|
@@ -526,7 +526,7 @@ export class IterationOrchestrator {
|
|
|
526
526
|
await this.ctx.checkpointMgr.markLoopStart?.(recorder)
|
|
527
527
|
|
|
528
528
|
// Context-overflow relief is a two-rung ladder per *stuck point*, not per
|
|
529
|
-
// turn
|
|
529
|
+
// turn (at most two reactive compactions per
|
|
530
530
|
// overflow): the first relief, then one deeper pass if the retry still
|
|
531
531
|
// overflows.
|
|
532
532
|
//
|
|
@@ -2121,7 +2121,7 @@ export class IterationOrchestrator {
|
|
|
2121
2121
|
classifyProviderError(err, this.ctx.provider.id).code === 'context_length_exceeded'
|
|
2122
2122
|
) {
|
|
2123
2123
|
// The rapid-refill check comes first, before the first reactive relief
|
|
2124
|
-
// of an overflow
|
|
2124
|
+
// of an overflow. A relief that follows
|
|
2125
2125
|
// the previous compaction within the refill window counts toward the
|
|
2126
2126
|
// limit, so a tool that re-fills the window every time it is called
|
|
2127
2127
|
// stops the turn instead of being cleared and called again without end.
|
|
@@ -2155,7 +2155,7 @@ export class IterationOrchestrator {
|
|
|
2155
2155
|
continue
|
|
2156
2156
|
}
|
|
2157
2157
|
// Out of rungs. The conversation is kept; say why compaction could not
|
|
2158
|
-
// make room when it errored
|
|
2158
|
+
// make room when it errored.
|
|
2159
2159
|
const cause = compactionErrorNote(this.ctx)
|
|
2160
2160
|
if (cause !== undefined && err instanceof Error) {
|
|
2161
2161
|
try {
|
|
@@ -163,7 +163,7 @@ export async function* holdForOutstandingWork(
|
|
|
163
163
|
hasToolCalls: boolean,
|
|
164
164
|
deliverInbound: () => number | Promise<number>,
|
|
165
165
|
): AsyncGenerator<SessionEvent, boolean> {
|
|
166
|
-
const inbox = ctx.completionInbox?.
|
|
166
|
+
const inbox = ctx.completionInbox?.holdsTurn ? ctx.completionInbox : undefined
|
|
167
167
|
const jobs = ctx.awaitedJobs?.hasPendingWork ? ctx.awaitedJobs : undefined
|
|
168
168
|
if (!inbox && !jobs) return false
|
|
169
169
|
|
|
@@ -370,7 +370,14 @@ export function settleOutstandingWork(ctx: IterationContext): void {
|
|
|
370
370
|
/** Work this turn walked away from. See {@link settleOutstandingWork}. */
|
|
371
371
|
export function recordAbandonedWork(ctx: IterationContext): void {
|
|
372
372
|
const abandoned = ctx.completionInbox?.outstandingTaskIds ?? []
|
|
373
|
-
if (abandoned.length > 0) {
|
|
373
|
+
if (abandoned.length > 0 && ctx.completionInbox?.holdsTurnOpen === false) {
|
|
374
|
+
// Handed over on purpose: the host keeps these running and tells the
|
|
375
|
+
// model when they end, so the turn did not walk away from them.
|
|
376
|
+
ctx.log.info('Turn ended with delegated work left running in the background', {
|
|
377
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
378
|
+
'namzu.runtime.tasks': abandoned,
|
|
379
|
+
})
|
|
380
|
+
} else if (abandoned.length > 0) {
|
|
374
381
|
ctx.log.warn('Turn ended with delegated work still running', {
|
|
375
382
|
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
376
383
|
'namzu.runtime.tasks': abandoned,
|
|
@@ -30,8 +30,8 @@ export const COMPACTION_REFILL_LIMIT = 3
|
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* One short line, shown once, when the turn stops on refills. It names the
|
|
33
|
-
* cause and a step that keeps the conversation:
|
|
34
|
-
*
|
|
33
|
+
* cause and a step that keeps the conversation: starting over is never
|
|
34
|
+
* offered here.
|
|
35
35
|
*/
|
|
36
36
|
export const COMPACTION_REFILL_MESSAGE =
|
|
37
37
|
'The context filled up again right after being compacted, three times in a row. A file being read or a tool output is probably too large for the context window. Try reading it in smaller parts.'
|
|
@@ -221,8 +221,7 @@ export function measureContext(ctx: IterationContext): {
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
/**
|
|
224
|
-
* Reactive compactions allowed for one overflow,
|
|
225
|
-
* terminal: the first relief, then at most one deeper pass.
|
|
224
|
+
* Reactive compactions allowed for one overflow: the first relief, then at most one deeper pass.
|
|
226
225
|
*/
|
|
227
226
|
export const OVERFLOW_RELIEF_LIMIT = 2
|
|
228
227
|
|
|
@@ -350,8 +349,8 @@ export async function relieveOverflow(
|
|
|
350
349
|
|
|
351
350
|
/**
|
|
352
351
|
* Why the last compaction attempt errored, kept for the turn so that when
|
|
353
|
-
* relief runs out the failure it ends on can say so,
|
|
354
|
-
*
|
|
352
|
+
* relief runs out the failure it ends on can say so, and it reads
|
|
353
|
+
* " · automatic compaction failed: <cause>".
|
|
355
354
|
*/
|
|
356
355
|
const compactionErrors = new WeakMap<object, string>()
|
|
357
356
|
const MAX_COMPACTION_CAUSE_CHARS = 300
|
|
@@ -430,9 +429,8 @@ async function declined(
|
|
|
430
429
|
/**
|
|
431
430
|
* The third refill in a row: stop the turn instead of compacting again.
|
|
432
431
|
* Returns true when this pass must not run. Only with `circuitBreaker`.
|
|
433
|
-
* The loop also asks it before the first reactive relief of an overflow,
|
|
434
|
-
*
|
|
435
|
-
* handling), so a re-read loop made only of overflows is counted too.
|
|
432
|
+
* The loop also asks it before the first reactive relief of an overflow, so a re-read loop made
|
|
433
|
+
* only of overflows is counted too.
|
|
436
434
|
*/
|
|
437
435
|
export async function stopOnRefill(ctx: IterationContext): Promise<boolean> {
|
|
438
436
|
const breaker = compactionBreaker(ctx)
|
|
@@ -721,7 +719,7 @@ async function runCompactionCheckInner(
|
|
|
721
719
|
const breaker = compactionBreaker(ctx)
|
|
722
720
|
if (breaker?.failuresOpen && !options?.force) {
|
|
723
721
|
if (breaker.takeFailureNotice()) {
|
|
724
|
-
// Silent for the person
|
|
722
|
+
// Silent for the person: a log line and the
|
|
725
723
|
// event for a host that wants it, but no sentence to show. Only the
|
|
726
724
|
// proactive pass stops; a real overflow still runs the reactive ladder.
|
|
727
725
|
ctx.log.warn('Compaction failed three times in a row — switched off for this turn', {
|
|
@@ -21,7 +21,7 @@ import { isProviderRejectedImageError } from './provider-rejected-image.js'
|
|
|
21
21
|
* Repair-and-retry for a request a provider rejects as invalid (a 400 that is
|
|
22
22
|
* not a context overflow), so a conversation does not dead-end on it.
|
|
23
23
|
*
|
|
24
|
-
*
|
|
24
|
+
* The silent 400 recoveries, in order: pair tool
|
|
25
25
|
* calls with results before a send, strip rejected reasoning, drop a
|
|
26
26
|
* parameter the model refuses, and take rejected media out of the OUTGOING
|
|
27
27
|
* request. Stored history is never edited.
|
|
@@ -77,7 +77,7 @@ type Rejection =
|
|
|
77
77
|
/** Most repair resends for one original request, across every send it makes. */
|
|
78
78
|
export const MAX_REPAIRS_PER_REQUEST = 5
|
|
79
79
|
const MAX_STRIPS_PER_INDEX = 3
|
|
80
|
-
/**
|
|
80
|
+
/** Media is dropped in these steps for an unprocessable request. */
|
|
81
81
|
const GENERIC_MEDIA_LIMITS: readonly number[] = [510, 255, 127]
|
|
82
82
|
|
|
83
83
|
const PARAMETER_CODES: ReadonlySet<string> = new Set([
|
|
@@ -608,7 +608,7 @@ export class RequestRepair {
|
|
|
608
608
|
victims = slots.filter((slot) => slot.messageIndex === newest.messageIndex)
|
|
609
609
|
}
|
|
610
610
|
} else {
|
|
611
|
-
// The
|
|
611
|
+
// The media steps, then halving for smaller requests, down to
|
|
612
612
|
// none: each step keeps fewer than the request held, newest first.
|
|
613
613
|
const limit =
|
|
614
614
|
GENERIC_MEDIA_LIMITS.find((candidate) => candidate < slots.length) ??
|
|
@@ -46,8 +46,7 @@ export interface PathEscalationContext {
|
|
|
46
46
|
* a root that itself sits under a protected name is not a reason to ask about
|
|
47
47
|
* every file in it. The case that matters is the managed worktree a sub-agent
|
|
48
48
|
* runs in, `~/.namzu/projects/<slug>/worktrees/<name>`, which lies under
|
|
49
|
-
* `.namzu` by construction
|
|
50
|
-
* for its own worktrees directory. A path in no root is looked at whole.
|
|
49
|
+
* `.namzu` by construction. A path in no root is looked at whole.
|
|
51
50
|
*/
|
|
52
51
|
function protectedScope(absolute: string, roots: readonly string[]): string {
|
|
53
52
|
let best: string | undefined
|
|
@@ -194,7 +193,7 @@ export async function shellEscalations(
|
|
|
194
193
|
if (!context.reviewOutside) continue
|
|
195
194
|
if (unresolved) {
|
|
196
195
|
// A write whose target is decided at runtime cannot be checked; a
|
|
197
|
-
// read of one is left
|
|
196
|
+
// read of one is left alone.
|
|
198
197
|
if (use.access === 'write') outside.add(spelled)
|
|
199
198
|
continue
|
|
200
199
|
}
|
|
@@ -43,6 +43,11 @@ const UNOWNED_BUFFER_LIMIT = 32
|
|
|
43
43
|
*/
|
|
44
44
|
const OWNED_WORK_DISPLAY_LIMIT = 16
|
|
45
45
|
|
|
46
|
+
export interface CompletionInboxOptions {
|
|
47
|
+
/** See {@link CompletionInbox.holdsTurnOpen}. Default `true`. */
|
|
48
|
+
readonly holdsTurnOpen?: boolean
|
|
49
|
+
}
|
|
50
|
+
|
|
46
51
|
/**
|
|
47
52
|
* Completions that finished with nobody left to hear them.
|
|
48
53
|
*
|
|
@@ -151,7 +156,23 @@ export class CompletionInbox {
|
|
|
151
156
|
* `log` is optional and unresolved until it is actually needed (the
|
|
152
157
|
* eviction-warning path in `hold()`), same reason as `LocalTaskScheduler`.
|
|
153
158
|
*/
|
|
154
|
-
constructor(
|
|
159
|
+
constructor(
|
|
160
|
+
private readonly log?: Logger,
|
|
161
|
+
options: CompletionInboxOptions = {},
|
|
162
|
+
) {
|
|
163
|
+
this.holdsTurnOpen = options.holdsTurnOpen !== false
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Whether a turn about to end waits here for the tasks still running.
|
|
168
|
+
*
|
|
169
|
+
* `true` (the default) is the original contract: the turn parks at its settle
|
|
170
|
+
* point until the tasks it launched report back, so their results enter the
|
|
171
|
+
* same turn. `false` lets the turn end with them still running; the host owns
|
|
172
|
+
* their completion from then on (it keeps them alive and wakes the model when
|
|
173
|
+
* they end). Completions that have already arrived are delivered either way.
|
|
174
|
+
*/
|
|
175
|
+
readonly holdsTurnOpen: boolean
|
|
155
176
|
|
|
156
177
|
/**
|
|
157
178
|
* Start listening.
|
|
@@ -349,6 +370,15 @@ export class CompletionInbox {
|
|
|
349
370
|
return this.unheard.size > 0 || this.outstanding.size > 0
|
|
350
371
|
}
|
|
351
372
|
|
|
373
|
+
/**
|
|
374
|
+
* Whether the turn has a reason to wait at its settle point: anything
|
|
375
|
+
* pending when it {@link holdsTurnOpen}, else only a completion already in
|
|
376
|
+
* hand (waiting for its persistence gate).
|
|
377
|
+
*/
|
|
378
|
+
get holdsTurn(): boolean {
|
|
379
|
+
return this.holdsTurnOpen ? this.hasPendingWork : this.unheard.size > 0
|
|
380
|
+
}
|
|
381
|
+
|
|
352
382
|
/**
|
|
353
383
|
* Wait for the next completion, deadline or abort, whichever comes first.
|
|
354
384
|
* Aborting releases only this waiter; work and undelivered results remain owned.
|
|
@@ -22,7 +22,7 @@ export interface CreateWorkspaceParams {
|
|
|
22
22
|
/**
|
|
23
23
|
* Traceable name below the configured workspace root. Nested names are
|
|
24
24
|
* accepted; absolute paths, traversal, and paths rewritten by a filesystem
|
|
25
|
-
* link are refused by the
|
|
25
|
+
* link are refused by the Git driver.
|
|
26
26
|
*/
|
|
27
27
|
label?: string
|
|
28
28
|
}
|
|
@@ -26,7 +26,7 @@ export interface InMemorySessionCheckpointStoreOptions {
|
|
|
26
26
|
*
|
|
27
27
|
* It keeps the serialised bytes rather than the object, so `restore` hashes
|
|
28
28
|
* exactly what `write` hashed and refuses exactly what the disk store
|
|
29
|
-
* refuses. It is the
|
|
29
|
+
* refuses. It is the counterpart of the disk store and the store an
|
|
30
30
|
* in-memory session keeps its checkpoints in.
|
|
31
31
|
*/
|
|
32
32
|
export class InMemorySessionCheckpointStore implements SessionCheckpointStore {
|
|
@@ -249,7 +249,7 @@ export interface MemoryFileFields {
|
|
|
249
249
|
/**
|
|
250
250
|
* The file for one memory. Fields that repeat another are left out — a title
|
|
251
251
|
* equal to the name, a summary equal to the description, the default format —
|
|
252
|
-
* so an ordinary file carries the
|
|
252
|
+
* so an ordinary file carries the canonical shape and nothing else.
|
|
253
253
|
*/
|
|
254
254
|
export function formatMemoryFile(fields: MemoryFileFields, body: string): string {
|
|
255
255
|
const lines: string[] = ['---']
|
|
@@ -53,7 +53,7 @@ import { MemoryRevisionConflictError, assertMemoryRevision, memoryRevision } fro
|
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
55
|
* Versioned like every other record this SDK persists. A memory file carries
|
|
56
|
-
* no `schemaVersion` while it is at version 1 — the
|
|
56
|
+
* no `schemaVersion` while it is at version 1 — the canonical shape has no
|
|
57
57
|
* such field and a hand-written file should not need one — so the stamp only
|
|
58
58
|
* appears once a later build writes a later version, and THIS build refuses
|
|
59
59
|
* that file rather than reading it partially and writing the difference away.
|
|
@@ -52,8 +52,7 @@ const DEFAULT_BASH_MAX_BUFFER_BYTES = readPositiveIntEnv(
|
|
|
52
52
|
*
|
|
53
53
|
* So the tool declares a ceiling and the executor is given a deadline above
|
|
54
54
|
* it (see `timeoutMs` on the definition), which makes this the only clock
|
|
55
|
-
* that can fire in practice. A request past the ceiling is CLAMPED to it,
|
|
56
|
-
* the reference terminal does: the command still runs, and a timeout reports
|
|
55
|
+
* that can fire in practice. A request past the ceiling is CLAMPED to it: the command still runs, and a timeout reports
|
|
57
56
|
* the deadline that was actually applied, so the number the model sees on a
|
|
58
57
|
* timeout is the one that fired.
|
|
59
58
|
*/
|
|
@@ -9,18 +9,17 @@
|
|
|
9
9
|
* carries the same transformation across to `new_string` so the replacement
|
|
10
10
|
* stays consistent with what it replaced.
|
|
11
11
|
*
|
|
12
|
-
* The strategies and their order are
|
|
13
|
-
*
|
|
14
|
-
* functions in its shipped bundle), so an edit that lands there lands here:
|
|
12
|
+
* The strategies and their order are fixed as follows, so an edit that matches
|
|
13
|
+
* under one of them matches here:
|
|
15
14
|
*
|
|
16
15
|
* 1. exact
|
|
17
16
|
* 2. curly vs straight quotes, both directions
|
|
18
17
|
* 3. `\uXXXX` escape in `old_string`, character in the file
|
|
19
18
|
* 4. character in `old_string`, `\uXXXX` escape in the file
|
|
20
19
|
*
|
|
21
|
-
*
|
|
22
|
-
* `<function_results>`, `\n\nH:` → `\n\nHuman:`, …)
|
|
23
|
-
*
|
|
20
|
+
* Prompt delimiters from a transcript format (`<fnr>` →
|
|
21
|
+
* `<function_results>`, `\n\nH:` → `\n\nHuman:`, …) are deliberately NOT
|
|
22
|
+
* expanded: those tokens are artifacts of a transcript format,
|
|
24
23
|
* not a mismatch a Namzu model produces against a real source file.
|
|
25
24
|
*
|
|
26
25
|
* Pure by construction, like `edit-apply`: every function here is from strings
|
|
@@ -337,7 +337,7 @@ function codeFromMessage(message: string, status?: number): ProviderErrorCode |
|
|
|
337
337
|
// overflow rescue tests for by exact equality. The turn died holding
|
|
338
338
|
// the remedy.
|
|
339
339
|
m.includes('too long for') ||
|
|
340
|
-
//
|
|
340
|
+
// Known wordings: `context window` and
|
|
341
341
|
// `input length and max_tokens exceed context limit` matchers).
|
|
342
342
|
// Only where the status cannot say otherwise: a 429, 5xx or 401 that
|
|
343
343
|
// mentions the window is still a rate limit, a server fault or an auth
|