@namzu/sdk 62.14.0 → 63.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 +32 -0
- package/dist/connector/mcp/stdio.d.ts.map +1 -1
- package/dist/connector/mcp/stdio.js +3 -0
- package/dist/connector/mcp/stdio.js.map +1 -1
- package/dist/eval/compare.d.ts +54 -0
- package/dist/eval/compare.d.ts.map +1 -1
- package/dist/eval/compare.js +146 -1
- package/dist/eval/compare.js.map +1 -1
- package/dist/eval/experiment.d.ts.map +1 -1
- package/dist/eval/experiment.js +46 -6
- package/dist/eval/experiment.js.map +1 -1
- package/dist/eval/index.d.ts +6 -2
- package/dist/eval/index.d.ts.map +1 -1
- package/dist/eval/index.js +3 -1
- package/dist/eval/index.js.map +1 -1
- package/dist/eval/report-stats.d.ts +6 -0
- package/dist/eval/report-stats.d.ts.map +1 -1
- package/dist/eval/report-stats.js +10 -0
- package/dist/eval/report-stats.js.map +1 -1
- package/dist/eval/run-options.d.ts +25 -0
- package/dist/eval/run-options.d.ts.map +1 -1
- package/dist/eval/run-options.js +36 -0
- package/dist/eval/run-options.js.map +1 -1
- package/dist/eval/run-summary.d.ts +8 -0
- package/dist/eval/run-summary.d.ts.map +1 -1
- package/dist/eval/run-summary.js +13 -3
- package/dist/eval/run-summary.js.map +1 -1
- package/dist/eval/settings.d.ts +74 -0
- package/dist/eval/settings.d.ts.map +1 -0
- package/dist/eval/settings.js +161 -0
- package/dist/eval/settings.js.map +1 -0
- package/dist/eval/split.d.ts +48 -0
- package/dist/eval/split.d.ts.map +1 -0
- package/dist/eval/split.js +41 -0
- package/dist/eval/split.js.map +1 -0
- package/dist/eval/types.d.ts +12 -0
- package/dist/eval/types.d.ts.map +1 -1
- package/dist/execution/local.d.ts.map +1 -1
- package/dist/execution/local.js +2 -1
- package/dist/execution/local.js.map +1 -1
- package/dist/peers/envelope.d.ts +11 -0
- package/dist/peers/envelope.d.ts.map +1 -1
- package/dist/peers/envelope.js +29 -0
- package/dist/peers/envelope.js.map +1 -1
- package/dist/peers/index.d.ts +3 -3
- package/dist/peers/index.d.ts.map +1 -1
- package/dist/peers/index.js +2 -2
- package/dist/peers/index.js.map +1 -1
- package/dist/peers/protocol.d.ts +26 -0
- package/dist/peers/protocol.d.ts.map +1 -1
- package/dist/peers/protocol.js +22 -2
- 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/plugin/hook-context.d.ts +30 -0
- package/dist/plugin/hook-context.d.ts.map +1 -0
- package/dist/plugin/hook-context.js +51 -0
- package/dist/plugin/hook-context.js.map +1 -0
- package/dist/plugin/index.d.ts +2 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1 -0
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/lifecycle.d.ts +9 -0
- package/dist/plugin/lifecycle.d.ts.map +1 -1
- package/dist/plugin/lifecycle.js +13 -0
- package/dist/plugin/lifecycle.js.map +1 -1
- package/dist/plugin/shell-hook.d.ts +87 -12
- package/dist/plugin/shell-hook.d.ts.map +1 -1
- package/dist/plugin/shell-hook.js +224 -32
- package/dist/plugin/shell-hook.js.map +1 -1
- package/dist/process/session-child.d.ts +21 -0
- package/dist/process/session-child.d.ts.map +1 -0
- package/dist/process/session-child.js +32 -0
- package/dist/process/session-child.js.map +1 -0
- package/dist/public-runtime.d.ts +4 -3
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +4 -3
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-types.d.ts +2 -2
- package/dist/public-types.d.ts.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.js +2 -3
- package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +2 -0
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +13 -1
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +3 -2
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/system-events.d.ts +3 -3
- package/dist/runtime/system-events.d.ts.map +1 -1
- package/dist/runtime/system-events.js +2 -1
- package/dist/runtime/system-events.js.map +1 -1
- package/dist/sandbox/provider/local.d.ts +1 -0
- package/dist/sandbox/provider/local.d.ts.map +1 -1
- package/dist/sandbox/provider/local.js +5 -2
- package/dist/sandbox/provider/local.js.map +1 -1
- package/dist/sandbox/terminal.d.ts.map +1 -1
- package/dist/sandbox/terminal.js +2 -1
- package/dist/sandbox/terminal.js.map +1 -1
- package/dist/tools/command-shell.d.ts.map +1 -1
- package/dist/tools/command-shell.js +7 -1
- package/dist/tools/command-shell.js.map +1 -1
- package/dist/types/message/index.d.ts +1 -1
- package/dist/types/message/index.d.ts.map +1 -1
- package/dist/types/message/index.js +1 -0
- package/dist/types/message/index.js.map +1 -1
- package/dist/types/plugin/index.d.ts +37 -10
- package/dist/types/plugin/index.d.ts.map +1 -1
- package/dist/types/plugin/index.js.map +1 -1
- package/package.json +1 -1
- package/src/connector/mcp/stdio.ts +3 -0
- package/src/eval/compare.ts +245 -2
- package/src/eval/experiment.ts +58 -4
- package/src/eval/index.ts +32 -1
- package/src/eval/report-stats.ts +11 -0
- package/src/eval/run-options.ts +51 -0
- package/src/eval/run-summary.ts +19 -1
- package/src/eval/settings.ts +225 -0
- package/src/eval/split.ts +83 -0
- package/src/eval/types.ts +12 -0
- package/src/execution/local.ts +2 -1
- package/src/peers/envelope.ts +36 -0
- package/src/peers/index.ts +3 -1
- package/src/peers/protocol.ts +24 -2
- package/src/plugin/hook-context.ts +58 -0
- package/src/plugin/index.ts +9 -0
- package/src/plugin/lifecycle.ts +13 -0
- package/src/plugin/shell-hook.ts +290 -43
- package/src/process/session-child.ts +38 -0
- package/src/public-runtime.ts +27 -0
- package/src/public-types.ts +2 -0
- package/src/runtime/query/executor/tool-call-admission.ts +2 -4
- package/src/runtime/query/executor.ts +15 -3
- package/src/runtime/query/index.ts +3 -3
- package/src/runtime/system-events.ts +2 -1
- package/src/sandbox/provider/local.ts +5 -1
- package/src/sandbox/terminal.ts +3 -1
- package/src/tools/command-shell.ts +7 -1
- package/src/types/message/index.ts +1 -0
- package/src/types/plugin/index.ts +48 -16
package/src/public-runtime.ts
CHANGED
|
@@ -697,9 +697,15 @@ export {
|
|
|
697
697
|
|
|
698
698
|
export {
|
|
699
699
|
attachShellHooks,
|
|
700
|
+
boundHookContext,
|
|
701
|
+
boundHookReplacement,
|
|
700
702
|
createShellHook,
|
|
701
703
|
DEFAULT_SHELL_HOOK_TIMEOUT_MS,
|
|
702
704
|
definePlugin,
|
|
705
|
+
frameOperatorHookContext,
|
|
706
|
+
MAX_HOOK_CONTEXT_CHARS,
|
|
707
|
+
MAX_HOOK_REPLACEMENT_CHARS,
|
|
708
|
+
sessionStartHookContext,
|
|
703
709
|
discoverAllPluginDirs,
|
|
704
710
|
discoverPlugins,
|
|
705
711
|
assertEnableable,
|
|
@@ -1428,6 +1434,20 @@ export {
|
|
|
1428
1434
|
loadEvalReportFile,
|
|
1429
1435
|
summarizeRun,
|
|
1430
1436
|
withEvalRunOptions,
|
|
1437
|
+
currentEvalSettings,
|
|
1438
|
+
evalSetting,
|
|
1439
|
+
DEFAULT_SETTINGS_NAME,
|
|
1440
|
+
buildSettingsSnapshot,
|
|
1441
|
+
defaultSettingsSnapshot,
|
|
1442
|
+
diffSettings,
|
|
1443
|
+
validateSettingsName,
|
|
1444
|
+
HELD_OUT_FRACTION,
|
|
1445
|
+
SPLIT_FILTERS,
|
|
1446
|
+
TASK_SPLIT_SEED,
|
|
1447
|
+
assignSplit,
|
|
1448
|
+
hashedSplit,
|
|
1449
|
+
taskId,
|
|
1450
|
+
validateSplitFilter,
|
|
1431
1451
|
compareHarnessTrials,
|
|
1432
1452
|
reviewHarnessCandidate,
|
|
1433
1453
|
claimMismatchScorer,
|
|
@@ -1931,6 +1951,7 @@ export {
|
|
|
1931
1951
|
MAX_PEER_CONNECTIONS,
|
|
1932
1952
|
MAX_PEER_MESSAGE_TEXT_BYTES,
|
|
1933
1953
|
MAX_PEER_REQUEST_BYTES,
|
|
1954
|
+
NoticeOutcomeSchema,
|
|
1934
1955
|
NoticeRequestSchema,
|
|
1935
1956
|
NoticeResponseSchema,
|
|
1936
1957
|
OUTSTANDING_EXPIRY_MS,
|
|
@@ -1958,6 +1979,7 @@ export {
|
|
|
1958
1979
|
createPeerEndpoint,
|
|
1959
1980
|
derivePeerRef,
|
|
1960
1981
|
formatPeerMessage,
|
|
1982
|
+
formatPersonMessage,
|
|
1961
1983
|
formatPeerNotice,
|
|
1962
1984
|
hardenPeerRuntimeDir,
|
|
1963
1985
|
isPeerRecordLive,
|
|
@@ -1973,6 +1995,11 @@ export {
|
|
|
1973
1995
|
udsPeerAddress,
|
|
1974
1996
|
writePeerRecord,
|
|
1975
1997
|
} from './peers/index.js'
|
|
1998
|
+
export {
|
|
1999
|
+
SESSION_CHILD_ENV,
|
|
2000
|
+
startedBySession,
|
|
2001
|
+
withSessionChildMarker,
|
|
2002
|
+
} from './process/session-child.js'
|
|
1976
2003
|
export {
|
|
1977
2004
|
ACCOUNTS_FILE_NAME,
|
|
1978
2005
|
ACCOUNTS_FILE_VERSION,
|
package/src/public-types.ts
CHANGED
|
@@ -244,6 +244,7 @@ export type {
|
|
|
244
244
|
ShellHookOnFailure,
|
|
245
245
|
ShellHookInput,
|
|
246
246
|
ShellHookOptions,
|
|
247
|
+
ShellHookPathFilter,
|
|
247
248
|
ShellHookOutcome,
|
|
248
249
|
ShellHooksConfig,
|
|
249
250
|
} from './plugin/shell-hook.js'
|
|
@@ -737,6 +738,7 @@ export type {
|
|
|
737
738
|
DeliverRequest,
|
|
738
739
|
DeliverResponse,
|
|
739
740
|
DeliverStatus,
|
|
741
|
+
NoticeOutcome,
|
|
740
742
|
NoticeRequest,
|
|
741
743
|
NoticeResponse,
|
|
742
744
|
PeerFrom,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { GENAI, NAMZU } from '../../../constants/telemetry/index.js'
|
|
2
|
+
import { boundHookContext } from '../../../plugin/hook-context.js'
|
|
2
3
|
import { callableToolNames, formatToolNames } from '../../../registry/tool/callable.js'
|
|
3
4
|
import { renderToolSchema } from '../../../registry/tool/schema.js'
|
|
4
5
|
import type { ToolCall, ToolInputError } from '../../../types/message/index.js'
|
|
@@ -433,12 +434,9 @@ function interpretPreToolResults(
|
|
|
433
434
|
*/
|
|
434
435
|
export function hookNote(texts: readonly string[]): string {
|
|
435
436
|
const joined = texts.join('\n')
|
|
436
|
-
return `[Hook note]\n${joined
|
|
437
|
+
return `[Hook note]\n${boundHookContext(joined)}`
|
|
437
438
|
}
|
|
438
439
|
|
|
439
|
-
/** A hook's text is one more thing for the model to read; it gets a bound. */
|
|
440
|
-
const MAX_HOOK_NOTE_CHARS = 8_000
|
|
441
|
-
|
|
442
440
|
/**
|
|
443
441
|
* Turn the call the model issued into a name and a parsed input, giving
|
|
444
442
|
* a configured repairer one chance to fix it first.
|
|
@@ -564,8 +564,14 @@ interface PostToolOverride {
|
|
|
564
564
|
readonly output: string
|
|
565
565
|
readonly isError: boolean
|
|
566
566
|
readonly content?: ToolResultContent
|
|
567
|
+
/** A hook replaced a result that stood; the record says so beside it. */
|
|
568
|
+
readonly replacedByHook?: true
|
|
567
569
|
}
|
|
568
570
|
|
|
571
|
+
/** What the record and the model are told beside a result a hook replaced. */
|
|
572
|
+
export const HOOK_REPLACED_RESULT_NOTE =
|
|
573
|
+
"A hook replaced this tool result: the text above is the hook's, not the tool's own output."
|
|
574
|
+
|
|
569
575
|
/** What `pre_tool_use` hooks said about a call beyond running it or not. */
|
|
570
576
|
export interface PreToolHookNotes {
|
|
571
577
|
/** The strictest permission answer among the hooks: `ask` outranks `allow`. */
|
|
@@ -2944,9 +2950,12 @@ export class ToolExecutor {
|
|
|
2944
2950
|
// receipt and the host's alike, framed as a hook's words. Added after
|
|
2945
2951
|
// the output budget so a bounded result is never trimmed to make room
|
|
2946
2952
|
// for it; the note has its own bound (`hookNote`).
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2953
|
+
// The mark comes first so the bound on hook text never cuts it off.
|
|
2954
|
+
const hookTexts = [
|
|
2955
|
+
postOverride?.replacedByHook === true ? HOOK_REPLACED_RESULT_NOTE : undefined,
|
|
2956
|
+
preparedHookContext,
|
|
2957
|
+
post.context,
|
|
2958
|
+
].filter((text): text is string => text !== undefined && text.length > 0)
|
|
2950
2959
|
if (hookTexts.length > 0) {
|
|
2951
2960
|
const note = hookNote(hookTexts)
|
|
2952
2961
|
output = `${output}\n\n${note}`
|
|
@@ -3562,8 +3571,11 @@ export class ToolExecutor {
|
|
|
3562
3571
|
override = {
|
|
3563
3572
|
output: result.output,
|
|
3564
3573
|
isError: false,
|
|
3574
|
+
...(result.disclose === true ? { replacedByHook: true as const } : {}),
|
|
3565
3575
|
...(result.content !== undefined ? { content: result.content } : {}),
|
|
3566
3576
|
}
|
|
3577
|
+
if (result.context) contexts.push(result.context)
|
|
3578
|
+
if (result.halt) this.requestHalt(result.halt.reason)
|
|
3567
3579
|
continue
|
|
3568
3580
|
// `retry` was a declared variant with no implementation: every
|
|
3569
3581
|
// site that consumed it threw. Here it finally means something
|
|
@@ -18,6 +18,7 @@ import { restoreWorkingState, snapshotWorkingState } from '../../compaction/wire
|
|
|
18
18
|
import { type CompactionConfig, CompactionConfigSchema } from '../../config/runtime.js'
|
|
19
19
|
import { childSessionLog } from '../../manager/agent/child-session.js'
|
|
20
20
|
import { type TurnRecorder, recordedTurnStart } from '../../manager/session/turn-recorder.js'
|
|
21
|
+
import { frameOperatorHookContext } from '../../plugin/hook-context.js'
|
|
21
22
|
import { PromptContributionRegistry } from '../../prompt/contributions.js'
|
|
22
23
|
import { resolveProviderCapabilities } from '../../provider/capabilities.js'
|
|
23
24
|
import type { ProviderChainMember } from '../../provider/fallback.js'
|
|
@@ -2199,8 +2200,7 @@ export async function* query(params: QueryParams): AsyncGenerator<SessionEvent,
|
|
|
2199
2200
|
promptContributions.replace({
|
|
2200
2201
|
id: 'hooks:subagent_start',
|
|
2201
2202
|
placement: 'context',
|
|
2202
|
-
render: () =>
|
|
2203
|
-
`Context from the operator's hooks:\n\n${startAnnotations.join('\n\n')}`,
|
|
2203
|
+
render: () => frameOperatorHookContext(startAnnotations),
|
|
2204
2204
|
})
|
|
2205
2205
|
}
|
|
2206
2206
|
yield* eventTranslator.drainPending()
|
|
@@ -2226,7 +2226,7 @@ export async function* query(params: QueryParams): AsyncGenerator<SessionEvent,
|
|
|
2226
2226
|
promptContributions.replace({
|
|
2227
2227
|
id: 'hooks:user_prompt_submit',
|
|
2228
2228
|
placement: 'context',
|
|
2229
|
-
render: () =>
|
|
2229
|
+
render: () => frameOperatorHookContext(annotations),
|
|
2230
2230
|
})
|
|
2231
2231
|
}
|
|
2232
2232
|
yield* eventTranslator.drainPending()
|
|
@@ -54,13 +54,14 @@ const SYSTEM_EVENT_STATUSES_LIST = [
|
|
|
54
54
|
'refused',
|
|
55
55
|
'idle',
|
|
56
56
|
'exited',
|
|
57
|
+
'delivered',
|
|
57
58
|
] as const
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
61
|
* The closed set of outcomes this envelope may report.
|
|
61
62
|
*
|
|
62
63
|
* Not every status applies to every kind: `completed`/`failed`/`cancelled`/
|
|
63
|
-
* `killed`/`interim` describe an `agent` or `job`; `queued`/`held`/`refused`
|
|
64
|
+
* `killed`/`interim` describe an `agent` or `job`; `queued`/`held`/`refused`/`delivered`
|
|
64
65
|
* describe a peer message or its delivery notice; `idle`/`exited` describe a
|
|
65
66
|
* peer's status notice. `formatSystemEvent` does not cross-check kind against
|
|
66
67
|
* status — the caller owns that pairing — because the two closed sets belong
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
// registry needs the same one, and a near-copy would reproduce in the copy
|
|
28
28
|
// every bug the original's comment was written to record.
|
|
29
29
|
import { killTree } from '../../process/kill-tree.js'
|
|
30
|
+
import { SESSION_CHILD_ENV } from '../../process/session-child.js'
|
|
30
31
|
import { resolveWithinAny, resolveWithinAnyReal } from '../../tools/paths.js'
|
|
31
32
|
import type { SandboxId } from '../../types/ids/index.js'
|
|
32
33
|
import type {
|
|
@@ -52,6 +53,7 @@ import {
|
|
|
52
53
|
WINDOWS_CORE_ENV_KEYS,
|
|
53
54
|
applyEnvironmentOverrides,
|
|
54
55
|
pickEnvironmentEntries,
|
|
56
|
+
setEnvironmentEntry,
|
|
55
57
|
} from '../../utils/process-environment.js'
|
|
56
58
|
import { createTempDir, resolveTempBase } from '../../utils/temp.js'
|
|
57
59
|
import { walkFilesLocally } from '../file-walk.js'
|
|
@@ -586,7 +588,7 @@ function buildSeatbeltArgs(
|
|
|
586
588
|
// Environment building
|
|
587
589
|
// ---------------------------------------------------------------------------
|
|
588
590
|
|
|
589
|
-
function buildSafeEnv(
|
|
591
|
+
export function buildSafeEnv(
|
|
590
592
|
configEnv?: Record<string, string>,
|
|
591
593
|
optsEnv?: Record<string, string>,
|
|
592
594
|
): Record<string, string> {
|
|
@@ -598,6 +600,8 @@ function buildSafeEnv(
|
|
|
598
600
|
|
|
599
601
|
applyEnvironmentOverrides(env, configEnv)
|
|
600
602
|
applyEnvironmentOverrides(env, optsEnv)
|
|
603
|
+
// Last: a command in a sandbox is still a command a session started.
|
|
604
|
+
setEnvironmentEntry(env, SESSION_CHILD_ENV, '1')
|
|
601
605
|
|
|
602
606
|
return env
|
|
603
607
|
}
|
package/src/sandbox/terminal.ts
CHANGED
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
* make teardown await every process it owns before using this primitive.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
+
import { withSessionChildMarker } from '../process/session-child.js'
|
|
30
|
+
|
|
29
31
|
export interface TerminalSize {
|
|
30
32
|
readonly cols: number
|
|
31
33
|
readonly rows: number
|
|
@@ -172,7 +174,7 @@ export function openTerminalWith(
|
|
|
172
174
|
cols: options.size.cols,
|
|
173
175
|
rows: options.size.rows,
|
|
174
176
|
cwd: options.cwd ?? defaults.cwd,
|
|
175
|
-
|
|
177
|
+
env: withSessionChildMarker({ ...(options.env ?? process.env) }) as Record<string, string>,
|
|
176
178
|
})
|
|
177
179
|
|
|
178
180
|
const dataSub = child.onData((chunk) => {
|
|
@@ -56,6 +56,7 @@ import { constants, accessSync, existsSync } from 'node:fs'
|
|
|
56
56
|
import { delimiter, isAbsolute, join, win32 } from 'node:path'
|
|
57
57
|
|
|
58
58
|
import { MSYS_TAG_VARIABLE, registerMsysShell, registerProcessTag } from '../process/kill-tree.js'
|
|
59
|
+
import { withSessionChildMarker } from '../process/session-child.js'
|
|
59
60
|
import type { ShellDialect } from '../types/tool/index.js'
|
|
60
61
|
|
|
61
62
|
/** The shell a host-side command runs in. */
|
|
@@ -460,8 +461,13 @@ export function spawnHostShell(
|
|
|
460
461
|
const windowsBash = shell.windows === true && shell.path !== undefined
|
|
461
462
|
const tag =
|
|
462
463
|
windowsBash || (shell.windows !== true && platform === 'linux') ? randomUUID() : undefined
|
|
464
|
+
// Every command the kernel runs on a session's behalf says so in its environment, and a program
|
|
465
|
+
// that must not be run by a model (`namzu send`) reads it. See `process/session-child.ts`.
|
|
466
|
+
const marked = withSessionChildMarker(spawned.env, platform)
|
|
463
467
|
const resolved =
|
|
464
|
-
tag === undefined
|
|
468
|
+
tag === undefined
|
|
469
|
+
? { ...spawned, env: marked }
|
|
470
|
+
: { ...spawned, env: { ...marked, [MSYS_TAG_VARIABLE]: tag } }
|
|
465
471
|
const common: SpawnOptions = {
|
|
466
472
|
cwd: options.cwd,
|
|
467
473
|
env: resolved.env,
|
|
@@ -96,7 +96,13 @@ export type PluginHookEvent =
|
|
|
96
96
|
* to what the model is told (`annotate`).
|
|
97
97
|
*/
|
|
98
98
|
| 'user_prompt_submit'
|
|
99
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* A host's session opened or closed. Carries `sessionId` and no `turnId`:
|
|
101
|
+
* these hooks run outside any turn. `session_start` carries `source`;
|
|
102
|
+
* `session_end` carries `endReason`. A `session_start` hook may answer with
|
|
103
|
+
* `context` (on `continue`) or `annotate`: text the model reads, from the
|
|
104
|
+
* first turn of the session on.
|
|
105
|
+
*/
|
|
100
106
|
| 'session_start'
|
|
101
107
|
| 'session_end'
|
|
102
108
|
/** A compaction pass is about to run / has run. Carries `compaction`. */
|
|
@@ -110,11 +116,6 @@ export type PluginHookEvent =
|
|
|
110
116
|
| 'subagent_start'
|
|
111
117
|
/** A child session's turn ended. Fired after its own `turn_end`; carries `parentSessionId`, `parentTurnId` and `agentType`. */
|
|
112
118
|
| 'subagent_stop'
|
|
113
|
-
/**
|
|
114
|
-
* A child session's turn is starting. Fired right after its own
|
|
115
|
-
* `turn_start`; carries `parentSessionId` and `parentTurnId`. Observational.
|
|
116
|
-
*/
|
|
117
|
-
| 'subagent_start'
|
|
118
119
|
| 'turn_start'
|
|
119
120
|
| 'turn_end'
|
|
120
121
|
/**
|
|
@@ -273,6 +274,21 @@ export interface PluginNotificationInfo {
|
|
|
273
274
|
readonly message: string
|
|
274
275
|
}
|
|
275
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Why a session started, on `session_start`: `startup` for a conversation
|
|
279
|
+
* with no earlier turn, `resume` for one that already had turns (a resumed
|
|
280
|
+
* conversation, a `--continue`, or a session rebuilt under a running one).
|
|
281
|
+
*/
|
|
282
|
+
export type PluginSessionSource = 'startup' | 'resume'
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Why a session closed, on `session_end`: `exit` when the host is finishing
|
|
286
|
+
* with it (the process ends, the person quits), `replaced` when the host
|
|
287
|
+
* builds another session in its place (a model or account switch, another
|
|
288
|
+
* conversation opened).
|
|
289
|
+
*/
|
|
290
|
+
export type PluginSessionEndReason = 'exit' | 'replaced'
|
|
291
|
+
|
|
276
292
|
export interface PluginHookContext {
|
|
277
293
|
/** The turn the hook fired in. Absent on `session_start` and `session_end`. */
|
|
278
294
|
readonly turnId?: TurnId
|
|
@@ -286,6 +302,10 @@ export interface PluginHookContext {
|
|
|
286
302
|
readonly parentTurnId?: TurnId
|
|
287
303
|
/** The name of the agent the child runs, on `subagent_start` and `subagent_stop`. */
|
|
288
304
|
readonly agentType?: string
|
|
305
|
+
/** Why the session started, on `session_start`. */
|
|
306
|
+
readonly source?: PluginSessionSource
|
|
307
|
+
/** Why the session closed, on `session_end`. */
|
|
308
|
+
readonly endReason?: PluginSessionEndReason
|
|
289
309
|
/** The operator's prompt, on `user_prompt_submit`. */
|
|
290
310
|
readonly prompt?: string
|
|
291
311
|
/** The pass, on `pre_compact` and `post_compact`. */
|
|
@@ -437,7 +457,18 @@ export type PluginHookResult =
|
|
|
437
457
|
* hook redacting a secret that also appears in an image must — this variant
|
|
438
458
|
* cannot inspect what it is preserving.
|
|
439
459
|
*/
|
|
440
|
-
| {
|
|
460
|
+
| ({
|
|
461
|
+
action: 'replace'
|
|
462
|
+
output: string
|
|
463
|
+
content?: ToolResultContent
|
|
464
|
+
/**
|
|
465
|
+
* Say, beside the result the model and the record carry, that a hook
|
|
466
|
+
* replaced it, so rewritten text is not passed off as the tool's own
|
|
467
|
+
* words. Off by default: a plugin that redacts quietly keeps doing so.
|
|
468
|
+
* A shell hook's replacement always sets it.
|
|
469
|
+
*/
|
|
470
|
+
disclose?: boolean
|
|
471
|
+
} & PluginHookNotes)
|
|
441
472
|
|
|
442
473
|
export function assertPluginHookResult(result: PluginHookResult): asserts result {
|
|
443
474
|
const action = result.action
|
|
@@ -472,15 +503,16 @@ export type PluginHookResultFor<E extends PluginHookEvent> = E extends 'user_pro
|
|
|
472
503
|
? Extract<PluginHookResult, { action: 'continue' | 'skip' }>
|
|
473
504
|
: E extends 'turn_end' | 'subagent_stop' | 'pre_compact'
|
|
474
505
|
? Extract<PluginHookResult, { action: 'continue' | 'skip' | 'error' }>
|
|
475
|
-
: E extends
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
506
|
+
: E extends 'session_start'
|
|
507
|
+
? Extract<PluginHookResult, { action: 'continue' | 'annotate' }>
|
|
508
|
+
: E extends
|
|
509
|
+
| 'turn_interrupt'
|
|
510
|
+
| 'session_end'
|
|
511
|
+
| 'notification'
|
|
512
|
+
| 'turn_failure'
|
|
513
|
+
| 'permission_denied'
|
|
514
|
+
? Extract<PluginHookResult, { action: 'continue' }>
|
|
515
|
+
: Extract<PluginHookResult, { action: 'continue' | 'error' }>
|
|
484
516
|
|
|
485
517
|
/** The event and its handler verdict stay correlated, including in hook arrays. */
|
|
486
518
|
export type PluginHookDefinition<E extends PluginHookEvent = PluginHookEvent> =
|