salmon-loop 0.2.13 → 0.3.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/dist/cli/argv/headless-detection.js +27 -0
- package/dist/cli/chat-flow.js +11 -0
- package/dist/cli/chat.js +160 -24
- package/dist/cli/commands/chat.js +14 -7
- package/dist/cli/commands/flow-mode.js +63 -0
- package/dist/cli/commands/registry.js +2 -0
- package/dist/cli/commands/run/benchmark-artifacts.js +41 -0
- package/dist/cli/commands/run/early-errors.js +23 -0
- package/dist/cli/commands/run/handler.js +115 -27
- package/dist/cli/commands/run/headless-error-writer.js +8 -0
- package/dist/cli/commands/run/loop-params.js +2 -0
- package/dist/cli/commands/run/mode.js +2 -5
- package/dist/cli/commands/run/parse-options.js +16 -0
- package/dist/cli/commands/run/persist-session.js +10 -1
- package/dist/cli/commands/run/preflight.js +10 -0
- package/dist/cli/commands/run/reporter-factory.js +4 -0
- package/dist/cli/commands/run/runtime-llm.js +38 -11
- package/dist/cli/commands/run/runtime-options.js +2 -2
- package/dist/cli/commands/serve.js +97 -77
- package/dist/cli/commands/tool-names.js +78 -78
- package/dist/cli/headless/anthropic-stream-normalized-encoder.js +6 -1
- package/dist/cli/headless/json-protocol.js +37 -0
- package/dist/cli/headless/native-stream-normalized-encoder.js +6 -1
- package/dist/cli/headless/protocol-metadata.js +22 -0
- package/dist/cli/headless/stream-json-protocol.js +34 -1
- package/dist/cli/index.js +6 -4
- package/dist/cli/locales/en.js +30 -6
- package/dist/cli/program-bootstrap.js +10 -5
- package/dist/cli/program-commands.js +5 -1
- package/dist/cli/reporters/anthropic-stream.js +7 -1
- package/dist/cli/reporters/json.js +4 -0
- package/dist/cli/reporters/stream-json.js +17 -2
- package/dist/cli/run-cli.js +5 -3
- package/dist/cli/slash/runtime.js +27 -12
- package/dist/cli/ui/components/CommandInput.js +7 -3
- package/dist/cli/ui/components/CommandSuggestionList.js +1 -1
- package/dist/cli/utils/command-option-source.js +13 -0
- package/dist/cli/utils/verify-resolver.js +8 -4
- package/dist/cli/utils/worktree-prepare-resolver.js +7 -3
- package/dist/core/adapters/fs/file-adapter.js +6 -0
- package/dist/core/adapters/fs/filesystem.js +2 -1
- package/dist/core/adapters/git/git-adapter.js +78 -1
- package/dist/core/backends/salmon-loop/task-executor.js +1 -0
- package/dist/core/benchmark/patch-artifact.js +124 -0
- package/dist/core/benchmark/swe-bench.js +25 -0
- package/dist/core/config/load.js +18 -11
- package/dist/core/config/resolve-llm.js +12 -0
- package/dist/core/config/resolvers/server.js +0 -6
- package/dist/core/config/validate.js +73 -21
- package/dist/core/context/gatherers/metadata-gatherer.js +1 -0
- package/dist/core/context/gatherers/ripgrep-gatherer.js +84 -2
- package/dist/core/context/keywords.js +18 -4
- package/dist/core/context/service-deps.js +2 -2
- package/dist/core/context/service.js +8 -0
- package/dist/core/context/steps/context-gather.js +38 -0
- package/dist/core/context/summarization/summarizer.js +55 -12
- package/dist/core/context/targeting/target-resolver.js +4 -4
- package/dist/core/extensions/index.js +23 -5
- package/dist/core/extensions/merge.js +14 -0
- package/dist/core/extensions/paths.js +31 -0
- package/dist/core/extensions/schemas.js +8 -5
- package/dist/core/facades/cli-chat.js +6 -2
- package/dist/core/facades/cli-command-chat.js +1 -0
- package/dist/core/facades/cli-command-tool-names.js +2 -0
- package/dist/core/facades/cli-observability.js +1 -1
- package/dist/core/facades/cli-program-bootstrap.js +1 -0
- package/dist/core/facades/cli-run-handler.js +4 -2
- package/dist/core/facades/cli-run-persist-session.js +1 -0
- package/dist/core/facades/cli-serve.js +4 -4
- package/dist/core/facades/cli-utils-worktree.js +1 -1
- package/dist/core/failure/diagnostics.js +53 -1
- package/dist/core/grizzco/dsl/llm-strategy.js +4 -1
- package/dist/core/grizzco/engine/outcome/loop-result-mapper.js +67 -9
- package/dist/core/grizzco/engine/pipeline/pipeline.js +6 -2
- package/dist/core/grizzco/engine/transaction/attempt-failure.js +90 -15
- package/dist/core/grizzco/engine/transaction/report-mapper.js +17 -3
- package/dist/core/grizzco/engine/transaction/transaction-runner.js +165 -7
- package/dist/core/grizzco/flows/AutopilotFlow.js +18 -0
- package/dist/core/grizzco/flows/flow-dispatch.js +11 -0
- package/dist/core/grizzco/steps/answer.js +13 -14
- package/dist/core/grizzco/steps/autopilot.js +396 -0
- package/dist/core/grizzco/steps/cache-sharing.js +29 -0
- package/dist/core/grizzco/steps/explore.js +37 -21
- package/dist/core/grizzco/steps/generateReview.js +2 -5
- package/dist/core/grizzco/steps/patch/apply-check.js +10 -0
- package/dist/core/grizzco/steps/patch/diff-normalization.js +70 -0
- package/dist/core/grizzco/steps/patch/diff-salvage.js +46 -0
- package/dist/core/grizzco/steps/patch/prompt-input.js +42 -0
- package/dist/core/grizzco/steps/patch.js +105 -146
- package/dist/core/grizzco/steps/plan.js +101 -25
- package/dist/core/grizzco/steps/preflight.js +5 -6
- package/dist/core/grizzco/steps/request-assembly.js +78 -0
- package/dist/core/grizzco/steps/research.js +39 -36
- package/dist/core/grizzco/steps/tool-runtime.js +47 -0
- package/dist/core/grizzco/steps/verify-shared.js +23 -0
- package/dist/core/grizzco/steps/verify.js +13 -21
- package/dist/core/interaction/orchestration/facade.js +1 -1
- package/dist/core/llm/ai-sdk/chat-executor.js +2 -0
- package/dist/core/llm/ai-sdk/high-level-phase-specs.js +63 -0
- package/dist/core/llm/ai-sdk/message-mapper.js +40 -10
- package/dist/core/llm/ai-sdk/provider-factory.js +14 -0
- package/dist/core/llm/ai-sdk/request-params.js +113 -1
- package/dist/core/llm/ai-sdk/result-mapper.js +16 -0
- package/dist/core/llm/ai-sdk.js +112 -27
- package/dist/core/llm/capabilities.js +12 -0
- package/dist/core/llm/contracts/repair.js +36 -30
- package/dist/core/llm/errors.js +83 -2
- package/dist/core/llm/message-composition.js +7 -22
- package/dist/core/llm/phase-router.js +29 -10
- package/dist/core/llm/redact.js +28 -3
- package/dist/core/llm/registry.js +2 -0
- package/dist/core/llm/request-augmentation.js +55 -0
- package/dist/core/llm/request-envelope.js +334 -0
- package/dist/core/llm/shared-request-assembly.js +35 -0
- package/dist/core/llm/stream-utils.js +13 -4
- package/dist/core/llm/utils.js +18 -29
- package/dist/core/memory/relevant-retrieval.js +144 -0
- package/dist/core/observability/logger.js +11 -2
- package/dist/core/patch/diff.js +1 -0
- package/dist/core/prompts/registry.js +39 -2
- package/dist/core/prompts/runtime.js +50 -12
- package/dist/core/prompts/templates/phases/patch_user.hbs +2 -5
- package/dist/core/prompts/templates/phases/research_user.hbs +11 -0
- package/dist/core/prompts/templates/phases/review_user.hbs +3 -0
- package/dist/core/prompts/templates/system/answer_system.hbs +5 -0
- package/dist/core/prompts/templates/system/autopilot_system.hbs +11 -0
- package/dist/core/prompts/templates/system/explore_system.hbs +14 -23
- package/dist/core/prompts/templates/system/main_system.hbs +4 -16
- package/dist/core/prompts/templates/system/patch_system.hbs +39 -8
- package/dist/core/prompts/templates/system/plan_system.hbs +86 -1
- package/dist/core/prompts/templates/system/research_system.hbs +2 -0
- package/dist/core/protocols/a2a/agent-card.js +5 -3
- package/dist/core/protocols/a2a/sdk/executor.js +2 -1
- package/dist/core/protocols/a2a/sdk/server.js +0 -1
- package/dist/core/protocols/acp/formal-agent.js +300 -58
- package/dist/core/protocols/acp/handlers.js +5 -1
- package/dist/core/protocols/acp/permission-provider.js +1 -1
- package/dist/core/protocols/shared/flow-mode-mapping.js +23 -0
- package/dist/core/public-capabilities/flow-mode-metadata.js +39 -0
- package/dist/core/public-capabilities/projections.js +29 -0
- package/dist/core/public-capabilities/registry.js +26 -0
- package/dist/core/public-capabilities/types.js +2 -0
- package/dist/core/runtime/agent-server-runtime.js +47 -43
- package/dist/core/runtime/execution-profile.js +67 -0
- package/dist/core/session/artifact-state.js +160 -0
- package/dist/core/session/compaction/index.js +183 -0
- package/dist/core/session/compaction/microcompact.js +78 -0
- package/dist/core/session/compaction/tracking.js +48 -0
- package/dist/core/session/compaction/types.js +11 -0
- package/dist/core/session/compression.js +8 -0
- package/dist/core/session/manager.js +244 -8
- package/dist/core/session/pruning-strategy.js +55 -9
- package/dist/core/session/replacement-preview-provider.js +24 -0
- package/dist/core/session/replacement-state.js +131 -0
- package/dist/core/session/resume-repair/pipeline.js +79 -0
- package/dist/core/session/resume-repair/stages/load-raw-archive-state.js +40 -0
- package/dist/core/session/resume-repair/stages/reattach-runtime-state.js +8 -0
- package/dist/core/session/resume-repair/stages/recover-orphaned-branches.js +10 -0
- package/dist/core/session/resume-repair/stages/relink-boundary-and-tail.js +36 -0
- package/dist/core/session/resume-repair/stages/replay-startup-hooks.js +23 -0
- package/dist/core/session/resume-repair/stages/rescue-stale-metadata.js +17 -0
- package/dist/core/session/resume-repair/types.js +2 -0
- package/dist/core/session/summary-sync.js +164 -13
- package/dist/core/session/token-tracker.js +6 -0
- package/dist/core/skills/audit.js +34 -0
- package/dist/core/skills/bridge.js +84 -7
- package/dist/core/skills/discovery.js +94 -0
- package/dist/core/skills/feature-flags.js +52 -0
- package/dist/core/skills/index.js +1 -1
- package/dist/core/skills/loader.js +195 -20
- package/dist/core/skills/parser.js +296 -24
- package/dist/core/skills/permissions.js +117 -0
- package/dist/core/skills/runtime/MicroTaskRunner.js +10 -4
- package/dist/core/skills/runtime/SkillRunner.js +240 -61
- package/dist/core/strata/layers/shadow-driver/shadow-driver.js +37 -7
- package/dist/core/strata/layers/worktree.js +67 -10
- package/dist/core/strata/runtime/synchronizer.js +29 -2
- package/dist/core/streaming/stream-assembler.js +75 -31
- package/dist/core/sub-agent/context-snapshot.js +156 -0
- package/dist/core/sub-agent/core/loop.js +1 -1
- package/dist/core/sub-agent/core/manager.js +119 -20
- package/dist/core/sub-agent/dispatch-policy.js +29 -0
- package/dist/core/sub-agent/prefix-consistency.js +48 -0
- package/dist/core/sub-agent/registry-defaults.js +4 -0
- package/dist/core/sub-agent/tools/task-spawn.js +79 -2
- package/dist/core/sub-agent/types.js +134 -5
- package/dist/core/tools/audit.js +13 -4
- package/dist/core/tools/builtin/ast-grep.js +1 -1
- package/dist/core/tools/builtin/ast.js +1 -1
- package/dist/core/tools/builtin/benchmark.js +360 -0
- package/dist/core/tools/builtin/code-search/backends/rg.js +2 -1
- package/dist/core/tools/builtin/code-search/executor.js +6 -1
- package/dist/core/tools/builtin/code-search/spec.js +26 -2
- package/dist/core/tools/builtin/fs.js +256 -23
- package/dist/core/tools/builtin/git.js +2 -2
- package/dist/core/tools/builtin/index.js +51 -2
- package/dist/core/tools/builtin/interaction.js +8 -1
- package/dist/core/tools/builtin/plan.js +37 -15
- package/dist/core/tools/builtin/shell.js +1 -1
- package/dist/core/tools/loader.js +39 -16
- package/dist/core/tools/mapper.js +17 -3
- package/dist/core/tools/mcp/client.js +2 -1
- package/dist/core/tools/parallel/scheduler.js +35 -4
- package/dist/core/tools/permissions/permission-rules.js +5 -10
- package/dist/core/tools/policy.js +6 -1
- package/dist/core/tools/recoverable-tool-errors.js +10 -0
- package/dist/core/tools/router.js +24 -6
- package/dist/core/tools/session.js +458 -48
- package/dist/core/tools/tool-visibility.js +62 -0
- package/dist/core/tools/types.js +9 -1
- package/dist/core/types/execution.js +4 -0
- package/dist/core/types/flow-mode.js +8 -0
- package/dist/core/utils/path.js +52 -0
- package/dist/core/verification/runner.js +4 -1
- package/dist/core/version.js +17 -0
- package/dist/languages/typescript/index.js +4 -1
- package/dist/locales/en.js +35 -2
- package/dist/utils/eol.js +1 -1
- package/package.json +14 -7
- package/scripts/fix-es-abstract-compat.js +77 -0
- package/dist/core/runtime/fastify-server-bundle.js +0 -26
- package/dist/core/runtime/sidecar-fastify-plugin.js +0 -35
- package/dist/core/runtime/sidecar-paths.js +0 -47
- package/dist/core/runtime/sidecar-route-catalog.js +0 -103
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { normalizePermissionMode } from '../../core/config/index.js';
|
|
2
|
+
import { buildA2AAgentCard, createAcpFormalAgent, createAgentServerRuntime, createInteractionFacade, createSalmonTaskExecutor, createTaskEventBus, createPluginRegistry, createPromptRegistry, getUserAcpSessionStorePath, GitSnapshotCheckpointService, getLogger, mergeResolvedExtensions, PACKAGE_VERSION, PlainReporter, PluginLoader, resolveExtensions, resolveExecutionProfile, runSalmonLoop, setPluginRegistry, setPromptRegistry, startAcpStdioServer, StderrReporter, } from '../../core/facades/cli-serve.js';
|
|
3
|
+
import { selectPublicCapabilitiesForSurface, toA2APublicSkills, } from '../../core/public-capabilities/projections.js';
|
|
4
|
+
import { buildPublicCapabilityRegistry } from '../../core/public-capabilities/registry.js';
|
|
2
5
|
import { createTerminalAuthorizationProvider } from '../authorization/provider.js';
|
|
3
6
|
import { text } from '../locales/index.js';
|
|
7
|
+
import { getOptionValueSourceWithGlobalFallback } from '../utils/command-option-source.js';
|
|
4
8
|
import { createOutcomeReporter } from '../utils/outcome-reporter.js';
|
|
5
9
|
import { resolveCliConfig } from '../utils/resolve-cli-config.js';
|
|
6
10
|
import { createRuntimeLlmAndWarn } from './run/runtime-llm.js';
|
|
@@ -10,21 +14,44 @@ function parsePort(value, fallback) {
|
|
|
10
14
|
const parsed = Number(value);
|
|
11
15
|
return Number.isFinite(parsed) ? parsed : Number.NaN;
|
|
12
16
|
}
|
|
13
|
-
function
|
|
17
|
+
function resolveDefaultAcpPermissionPolicy(permissionMode) {
|
|
18
|
+
return permissionMode === 'yolo' ? 'allow_all' : 'ask';
|
|
19
|
+
}
|
|
20
|
+
function resolveServePermissionMode({ command, allOptions, rawConfiguredPermissionMode, flowMode, }) {
|
|
21
|
+
const permissionModeOptionSource = getOptionValueSourceWithGlobalFallback(command, 'mode');
|
|
22
|
+
const configuredPermissionMode = normalizePermissionMode(rawConfiguredPermissionMode);
|
|
23
|
+
const rawPermissionMode = (permissionModeOptionSource === 'cli' ? allOptions.mode : undefined) ??
|
|
24
|
+
configuredPermissionMode ??
|
|
25
|
+
resolveExecutionProfile(flowMode).defaultPermissionMode ??
|
|
26
|
+
'interactive';
|
|
27
|
+
const permissionMode = normalizePermissionMode(rawPermissionMode);
|
|
28
|
+
if (!permissionMode) {
|
|
29
|
+
getLogger().error(`Invalid --mode "${String(rawPermissionMode)}". Expected "interactive" or "yolo".`, true);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
return permissionMode;
|
|
33
|
+
}
|
|
34
|
+
function buildServeLoopExecutionDefaults(mode) {
|
|
35
|
+
const profile = resolveExecutionProfile(mode);
|
|
36
|
+
const strategy = profile.defaultCheckpointStrategy ?? 'worktree';
|
|
14
37
|
return {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
name: deps.name,
|
|
19
|
-
version: deps.version,
|
|
20
|
-
capabilities: deps.capabilities,
|
|
21
|
-
}),
|
|
22
|
-
abort: async () => new Response('Abort not implemented for this runtime', { status: 501 }),
|
|
23
|
-
workspace_files: async () => new Response('Workspace file access not enabled', { status: 501 }),
|
|
24
|
-
logs_stream: async () => new Response('Log streaming not enabled', { status: 501 }),
|
|
25
|
-
config_patch: async () => new Response('Config patch not enabled', { status: 501 }),
|
|
38
|
+
strategy,
|
|
39
|
+
applyBackOnDirty: strategy === 'worktree' ? '3way' : undefined,
|
|
40
|
+
environmentMode: 'strict',
|
|
26
41
|
};
|
|
27
42
|
}
|
|
43
|
+
function registerServeShutdown({ message, closeRuntime, closeAcpStdio, }) {
|
|
44
|
+
process.once('SIGINT', async () => {
|
|
45
|
+
getLogger().info(message);
|
|
46
|
+
try {
|
|
47
|
+
await closeRuntime?.();
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
closeAcpStdio?.();
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
28
55
|
export function registerServeCommands(program) {
|
|
29
56
|
const serve = program
|
|
30
57
|
.command('serve')
|
|
@@ -33,8 +60,6 @@ export function registerServeCommands(program) {
|
|
|
33
60
|
.option('--a2a-port <port>', text.cli.a2aPortOption)
|
|
34
61
|
.option('--a2a-token <token>', text.cli.a2aTokenOption, (value, previous) => previous.concat([value]), [])
|
|
35
62
|
.option('--no-acp-stdio', text.cli.acpStdioDisableOption)
|
|
36
|
-
.option('--sidecar-socket <path>', text.cli.sidecarSocketOption)
|
|
37
|
-
.option('--sidecar-allow-conditional', text.cli.sidecarAllowConditionalOption)
|
|
38
63
|
.option('--no-color', text.cli.noColorOption)
|
|
39
64
|
.action(handleServeCommand);
|
|
40
65
|
serve
|
|
@@ -58,6 +83,13 @@ export async function handleServeCommand(_options, command) {
|
|
|
58
83
|
process.exit(1);
|
|
59
84
|
}
|
|
60
85
|
const { resolvedConfig, auditScope, repoPath: defaultRepoPath } = configResult;
|
|
86
|
+
const defaultFlowMode = 'autopilot';
|
|
87
|
+
const defaultPermissionMode = resolveServePermissionMode({
|
|
88
|
+
command,
|
|
89
|
+
allOptions,
|
|
90
|
+
rawConfiguredPermissionMode: resolvedConfig.raw?.mode,
|
|
91
|
+
flowMode: defaultFlowMode,
|
|
92
|
+
});
|
|
61
93
|
const serverConfig = resolvedConfig.server;
|
|
62
94
|
const rawA2aHost = allOptions.a2aHost ?? serverConfig?.a2a?.host;
|
|
63
95
|
const a2aHost = String(rawA2aHost ?? '127.0.0.1');
|
|
@@ -71,13 +103,6 @@ export async function handleServeCommand(_options, command) {
|
|
|
71
103
|
if (acpStdioEnabled) {
|
|
72
104
|
getLogger().setReporter(allOptions.color === false ? new StderrReporter() : new PlainReporter());
|
|
73
105
|
}
|
|
74
|
-
const sidecarListen = typeof allOptions.sidecarSocket === 'string' && allOptions.sidecarSocket.length > 0
|
|
75
|
-
? { type: 'pipe', path: allOptions.sidecarSocket }
|
|
76
|
-
: getSidecarListenOptions();
|
|
77
|
-
const allowConditional = allOptions.sidecarAllowConditional ?? serverConfig?.sidecar?.allowConditional ?? false;
|
|
78
|
-
if (sidecarListen.type === 'pipe' && !sidecarListen.path.startsWith('\\\\.\\pipe\\')) {
|
|
79
|
-
await mkdir(defaultPathAdapter.dirname(sidecarListen.path), { recursive: true });
|
|
80
|
-
}
|
|
81
106
|
const languagePlugins = createPluginRegistry();
|
|
82
107
|
setPluginRegistry(languagePlugins);
|
|
83
108
|
setPromptRegistry(createPromptRegistry());
|
|
@@ -99,28 +124,34 @@ export async function handleServeCommand(_options, command) {
|
|
|
99
124
|
forceNonInteractive: true,
|
|
100
125
|
});
|
|
101
126
|
const executor = createSalmonTaskExecutor({
|
|
102
|
-
runLoop: async ({ instruction, mode, repoPath, onEvent, signal, authorizationProvider, authorizationMode, fileSystemOverride, }) => {
|
|
127
|
+
runLoop: async ({ instruction, mode, repoPath, onEvent, signal, authorizationProvider, authorizationMode, fileSystemOverride, extensions: taskExtensions, }) => {
|
|
103
128
|
const effectiveRepoPath = repoPath ?? defaultRepoPath;
|
|
129
|
+
const flowMode = mode;
|
|
130
|
+
const executionDefaults = buildServeLoopExecutionDefaults(flowMode);
|
|
131
|
+
const permissionMode = resolveServePermissionMode({
|
|
132
|
+
command,
|
|
133
|
+
allOptions,
|
|
134
|
+
rawConfiguredPermissionMode: resolvedConfig.raw?.mode,
|
|
135
|
+
flowMode,
|
|
136
|
+
});
|
|
104
137
|
return await runSalmonLoop({
|
|
105
138
|
instruction,
|
|
106
139
|
repoPath: effectiveRepoPath,
|
|
107
140
|
llm,
|
|
108
|
-
mode:
|
|
141
|
+
mode: flowMode,
|
|
109
142
|
verify: resolvedConfig.verify.command,
|
|
110
|
-
|
|
111
|
-
applyBackOnDirty: '3way',
|
|
112
|
-
environmentMode: 'strict',
|
|
143
|
+
...executionDefaults,
|
|
113
144
|
llmOutput: resolvedConfig.llmOutput,
|
|
114
145
|
outcomeReporter,
|
|
115
146
|
langfuseSessionId: resolvedConfig.observability.langfuse.sessionId,
|
|
116
147
|
langfuseUserId: resolvedConfig.observability.langfuse.userId,
|
|
117
148
|
auditScope,
|
|
118
|
-
permissionMode
|
|
149
|
+
permissionMode,
|
|
119
150
|
languagePlugins,
|
|
120
151
|
fileSystemOverride,
|
|
121
152
|
authorizationProvider: authorizationProvider ?? defaultAuthorizationProvider,
|
|
122
153
|
authorizationMode,
|
|
123
|
-
extensions: extensions.resolved,
|
|
154
|
+
extensions: mergeResolvedExtensions(extensions.resolved, taskExtensions),
|
|
124
155
|
onEvent,
|
|
125
156
|
signal,
|
|
126
157
|
});
|
|
@@ -157,27 +188,20 @@ export async function handleServeCommand(_options, command) {
|
|
|
157
188
|
next();
|
|
158
189
|
}
|
|
159
190
|
: undefined;
|
|
160
|
-
const
|
|
191
|
+
const a2aPublicCapabilities = selectPublicCapabilitiesForSurface('a2a', buildPublicCapabilityRegistry());
|
|
192
|
+
const a2aSkills = toA2APublicSkills(a2aPublicCapabilities);
|
|
161
193
|
const agentCard = buildA2AAgentCard({
|
|
162
194
|
name: 'salmon-loop',
|
|
163
195
|
url: `http://${a2aHost}:${a2aPort}`,
|
|
164
|
-
capabilities,
|
|
196
|
+
capabilities: a2aSkills,
|
|
165
197
|
security: authTokens.length > 0 ? [{ type: 'http', scheme: 'bearer' }] : [],
|
|
166
198
|
});
|
|
167
|
-
const sidecarRoutes = buildSidecarRouteDescriptors({
|
|
168
|
-
strict: true,
|
|
169
|
-
catalog: defaultSidecarRouteCatalog,
|
|
170
|
-
handlers: buildSidecarHandlers({
|
|
171
|
-
name: 'salmon-loop',
|
|
172
|
-
version: '0.2.0',
|
|
173
|
-
capabilities,
|
|
174
|
-
}),
|
|
175
|
-
});
|
|
176
199
|
if (acpStdioEnabled) {
|
|
177
200
|
startAcpStdioServer((conn) => createAcpFormalAgent({
|
|
178
201
|
conn,
|
|
179
|
-
agentInfo: { name: 'salmon-loop', version:
|
|
180
|
-
defaultModeId:
|
|
202
|
+
agentInfo: { name: 'salmon-loop', version: PACKAGE_VERSION },
|
|
203
|
+
defaultModeId: 'autopilot',
|
|
204
|
+
defaultPermissionPolicy: resolveDefaultAcpPermissionPolicy(defaultPermissionMode),
|
|
181
205
|
checkpointReader: {
|
|
182
206
|
listBySession: async ({ repoPath, sessionId, limit }) => await checkpointService.list({ repoPath, sessionId, limit }),
|
|
183
207
|
getById: async ({ repoPath, checkpointId }) => (await checkpointService.loadWithStatus({ repoPath, checkpointId })).handle,
|
|
@@ -192,42 +216,25 @@ export async function handleServeCommand(_options, command) {
|
|
|
192
216
|
eventBus: sharedEventBus,
|
|
193
217
|
}));
|
|
194
218
|
getLogger().info(text.cli.acpStdioStarted('n/a (stdio)'));
|
|
195
|
-
// Handle SIGINT for graceful shutdown
|
|
196
|
-
process.on('SIGINT', () => {
|
|
197
|
-
getLogger().info('Received SIGINT, shutting down ACP server...');
|
|
198
|
-
process.stdin.destroy();
|
|
199
|
-
process.exit(0);
|
|
200
|
-
});
|
|
201
219
|
}
|
|
202
|
-
const fastify = (await import('fastify')).default;
|
|
203
220
|
const runtime = createAgentServerRuntime({
|
|
204
|
-
createFastify: () => fastify(),
|
|
205
221
|
a2a: {
|
|
206
222
|
buildAgentCard: () => agentCard,
|
|
207
223
|
executeTask: executor.execute,
|
|
208
224
|
eventBus: sharedEventBus,
|
|
209
225
|
authMiddleware,
|
|
210
226
|
},
|
|
211
|
-
sidecar: {
|
|
212
|
-
routes: sidecarRoutes,
|
|
213
|
-
allowConditional,
|
|
214
|
-
},
|
|
215
227
|
listen: {
|
|
216
228
|
a2a: { host: a2aHost, port: a2aPort },
|
|
217
|
-
sidecar: sidecarListen,
|
|
218
229
|
},
|
|
219
|
-
a2aBaseUrl: `http://${a2aHost}:${a2aPort}`,
|
|
220
230
|
});
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
231
|
+
registerServeShutdown({
|
|
232
|
+
message: 'Received SIGINT, shutting down server...',
|
|
233
|
+
closeRuntime: () => runtime.close(),
|
|
234
|
+
closeAcpStdio: acpStdioEnabled ? () => void process.stdin.destroy() : undefined,
|
|
225
235
|
});
|
|
226
236
|
await runtime.start();
|
|
227
|
-
|
|
228
|
-
? `http://${sidecarListen.host}:${sidecarListen.port}`
|
|
229
|
-
: sidecarListen.path;
|
|
230
|
-
getLogger().success(text.cli.serveStarted(a2aHost, a2aPort, sidecarAddress));
|
|
237
|
+
getLogger().success(text.cli.serveStarted(a2aHost, a2aPort));
|
|
231
238
|
}
|
|
232
239
|
export async function handleServeAcpCommand(_options, command) {
|
|
233
240
|
const allOptions = command.optsWithGlobals();
|
|
@@ -244,6 +251,13 @@ export async function handleServeAcpCommand(_options, command) {
|
|
|
244
251
|
process.exit(1);
|
|
245
252
|
}
|
|
246
253
|
const { resolvedConfig, auditScope, repoPath: defaultRepoPath } = configResult;
|
|
254
|
+
const defaultFlowMode = 'autopilot';
|
|
255
|
+
const defaultPermissionMode = resolveServePermissionMode({
|
|
256
|
+
command,
|
|
257
|
+
allOptions,
|
|
258
|
+
rawConfiguredPermissionMode: resolvedConfig.raw?.mode,
|
|
259
|
+
flowMode: defaultFlowMode,
|
|
260
|
+
});
|
|
247
261
|
getLogger().setReporter(allOptions.color === false ? new StderrReporter() : new PlainReporter());
|
|
248
262
|
const languagePlugins = createPluginRegistry();
|
|
249
263
|
setPluginRegistry(languagePlugins);
|
|
@@ -266,27 +280,33 @@ export async function handleServeAcpCommand(_options, command) {
|
|
|
266
280
|
forceNonInteractive: true,
|
|
267
281
|
});
|
|
268
282
|
const executor = createSalmonTaskExecutor({
|
|
269
|
-
runLoop: async ({ instruction, mode, repoPath, onEvent, signal, authorizationProvider, authorizationMode, }) => {
|
|
283
|
+
runLoop: async ({ instruction, mode, repoPath, onEvent, signal, authorizationProvider, authorizationMode, extensions: taskExtensions, }) => {
|
|
270
284
|
const effectiveRepoPath = repoPath ?? defaultRepoPath;
|
|
285
|
+
const flowMode = mode;
|
|
286
|
+
const executionDefaults = buildServeLoopExecutionDefaults(flowMode);
|
|
287
|
+
const permissionMode = resolveServePermissionMode({
|
|
288
|
+
command,
|
|
289
|
+
allOptions,
|
|
290
|
+
rawConfiguredPermissionMode: resolvedConfig.raw?.mode,
|
|
291
|
+
flowMode,
|
|
292
|
+
});
|
|
271
293
|
return await runSalmonLoop({
|
|
272
294
|
instruction,
|
|
273
295
|
repoPath: effectiveRepoPath,
|
|
274
296
|
llm,
|
|
275
|
-
mode:
|
|
297
|
+
mode: flowMode,
|
|
276
298
|
verify: resolvedConfig.verify.command,
|
|
277
|
-
|
|
278
|
-
applyBackOnDirty: '3way',
|
|
279
|
-
environmentMode: 'strict',
|
|
299
|
+
...executionDefaults,
|
|
280
300
|
llmOutput: resolvedConfig.llmOutput,
|
|
281
301
|
outcomeReporter,
|
|
282
302
|
langfuseSessionId: resolvedConfig.observability.langfuse.sessionId,
|
|
283
303
|
langfuseUserId: resolvedConfig.observability.langfuse.userId,
|
|
284
304
|
auditScope,
|
|
285
|
-
permissionMode
|
|
305
|
+
permissionMode,
|
|
286
306
|
languagePlugins,
|
|
287
307
|
authorizationProvider: authorizationProvider ?? defaultAuthorizationProvider,
|
|
288
308
|
authorizationMode,
|
|
289
|
-
extensions: extensions.resolved,
|
|
309
|
+
extensions: mergeResolvedExtensions(extensions.resolved, taskExtensions),
|
|
290
310
|
onEvent,
|
|
291
311
|
signal,
|
|
292
312
|
});
|
|
@@ -305,8 +325,9 @@ export async function handleServeAcpCommand(_options, command) {
|
|
|
305
325
|
});
|
|
306
326
|
startAcpStdioServer((conn) => createAcpFormalAgent({
|
|
307
327
|
conn,
|
|
308
|
-
agentInfo: { name: 'salmon-loop', version:
|
|
309
|
-
defaultModeId:
|
|
328
|
+
agentInfo: { name: 'salmon-loop', version: PACKAGE_VERSION },
|
|
329
|
+
defaultModeId: 'autopilot',
|
|
330
|
+
defaultPermissionPolicy: resolveDefaultAcpPermissionPolicy(defaultPermissionMode),
|
|
310
331
|
checkpointReader: {
|
|
311
332
|
listBySession: async ({ repoPath, sessionId, limit }) => await checkpointService.list({ repoPath, sessionId, limit }),
|
|
312
333
|
getById: async ({ repoPath, checkpointId }) => (await checkpointService.loadWithStatus({ repoPath, checkpointId })).handle,
|
|
@@ -321,10 +342,9 @@ export async function handleServeAcpCommand(_options, command) {
|
|
|
321
342
|
eventBus: sharedEventBus,
|
|
322
343
|
}));
|
|
323
344
|
getLogger().info(text.cli.acpStdioStarted('n/a (stdio)'));
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
process.stdin.destroy()
|
|
327
|
-
process.exit(0);
|
|
345
|
+
registerServeShutdown({
|
|
346
|
+
message: 'Received SIGINT, shutting down ACP server...',
|
|
347
|
+
closeAcpStdio: () => void process.stdin.destroy(),
|
|
328
348
|
});
|
|
329
349
|
}
|
|
330
350
|
//# sourceMappingURL=serve.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as os from 'os';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
import { getLogger, registerAllBuiltins, skillToToolSpec,
|
|
4
|
-
import {
|
|
3
|
+
import { getLogger, registerAllBuiltins, resolveExtensions, skillToToolSpec, SkillLoader, ToolRegistry, } from '../../core/facades/cli-command-tool-names.js';
|
|
4
|
+
import { stat, statSync } from '../utils/safe-fs.js';
|
|
5
5
|
const VALID_SIDE_EFFECTS = new Set([
|
|
6
6
|
'none',
|
|
7
7
|
'fs_read',
|
|
@@ -11,40 +11,23 @@ const VALID_SIDE_EFFECTS = new Set([
|
|
|
11
11
|
'git_read',
|
|
12
12
|
'git_write',
|
|
13
13
|
]);
|
|
14
|
+
// Cache key includes repoRoot. Extensions config is not part of the key because
|
|
15
|
+
// tool-names is used for tab completion where extensions may not be available.
|
|
14
16
|
const toolNameCache = new Map();
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (!skillFile || !existsSync(skillFile, root))
|
|
27
|
-
continue;
|
|
28
|
-
try {
|
|
29
|
-
const content = await readFileUtf8(skillFile, root);
|
|
30
|
-
skills.push(SkillParser.parse(content, skillFile));
|
|
31
|
-
}
|
|
32
|
-
catch (error) {
|
|
33
|
-
getLogger().warn(`Failed to load skill at ${skillFile}: ${error instanceof Error ? error.message : String(error)}`);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return skills;
|
|
37
|
-
}
|
|
38
|
-
function getSkillSearchPaths(repoRoot) {
|
|
39
|
-
return [
|
|
40
|
-
path.join(os.homedir(), '.claude/skills'),
|
|
41
|
-
path.join(repoRoot, '.salmonloop/skills'),
|
|
42
|
-
path.join(repoRoot, '.claude/skills'),
|
|
17
|
+
/**
|
|
18
|
+
* Compute a cache-invalidation signature based on mtime of all skill search
|
|
19
|
+
* paths that SkillLoader would scan. Mirrors the strict search order.
|
|
20
|
+
*/
|
|
21
|
+
async function computeSkillSignature(repoRoot, extraPaths = []) {
|
|
22
|
+
const searchPaths = [
|
|
23
|
+
...extraPaths,
|
|
24
|
+
path.join(repoRoot, '.salmonloop', 'skills'),
|
|
25
|
+
path.join(repoRoot, '.agents', 'skills'),
|
|
26
|
+
path.join(os.homedir(), '.salmonloop', 'skills'),
|
|
27
|
+
path.join(os.homedir(), '.agents', 'skills'),
|
|
43
28
|
];
|
|
44
|
-
}
|
|
45
|
-
async function computeSkillSignature(repoRoot) {
|
|
46
29
|
const parts = [];
|
|
47
|
-
for (const searchPath of
|
|
30
|
+
for (const searchPath of searchPaths) {
|
|
48
31
|
try {
|
|
49
32
|
const stats = await stat(searchPath);
|
|
50
33
|
parts.push(`${searchPath}:${stats.mtimeMs}`);
|
|
@@ -56,8 +39,14 @@ async function computeSkillSignature(repoRoot) {
|
|
|
56
39
|
return parts.join('|');
|
|
57
40
|
}
|
|
58
41
|
function computeSkillSignatureSync(repoRoot) {
|
|
42
|
+
const searchPaths = [
|
|
43
|
+
path.join(repoRoot, '.salmonloop', 'skills'),
|
|
44
|
+
path.join(repoRoot, '.agents', 'skills'),
|
|
45
|
+
path.join(os.homedir(), '.salmonloop', 'skills'),
|
|
46
|
+
path.join(os.homedir(), '.agents', 'skills'),
|
|
47
|
+
];
|
|
59
48
|
const parts = [];
|
|
60
|
-
for (const searchPath of
|
|
49
|
+
for (const searchPath of searchPaths) {
|
|
61
50
|
try {
|
|
62
51
|
const stats = statSync(searchPath);
|
|
63
52
|
parts.push(`${searchPath}:${stats.mtimeMs}`);
|
|
@@ -68,52 +57,63 @@ function computeSkillSignatureSync(repoRoot) {
|
|
|
68
57
|
}
|
|
69
58
|
return parts.join('|');
|
|
70
59
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
? safePathJoin(root, entry.name, 'SKILL.md')
|
|
79
|
-
: entry.name.endsWith('.md')
|
|
80
|
-
? safePathJoin(root, entry.name)
|
|
81
|
-
: null;
|
|
82
|
-
if (!skillFile || !existsSync(skillFile, root))
|
|
83
|
-
continue;
|
|
84
|
-
try {
|
|
85
|
-
const content = readFileUtf8Sync(skillFile, root);
|
|
86
|
-
skills.push(SkillParser.parse(content, skillFile));
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
getLogger().warn(`Failed to load skill at ${skillFile}: ${error instanceof Error ? error.message : String(error)}`);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return skills;
|
|
93
|
-
}
|
|
60
|
+
/**
|
|
61
|
+
* Get all known tool names including skills.
|
|
62
|
+
*
|
|
63
|
+
* Uses `resolveExtensions` to obtain the same SkillLoader configuration
|
|
64
|
+
* (extraPaths) as the main runtime, so that
|
|
65
|
+
* tool-name discovery and actual runtime skill availability stay consistent.
|
|
66
|
+
*/
|
|
94
67
|
export async function getKnownToolNames(repoRoot) {
|
|
95
|
-
|
|
68
|
+
// Resolve extensions to get the same loader config as the runtime
|
|
69
|
+
let skillDiscovery = {};
|
|
70
|
+
try {
|
|
71
|
+
const { resolved } = await resolveExtensions({ repoRoot });
|
|
72
|
+
skillDiscovery = resolved.skillDiscovery;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Extensions config unavailable — fall back to loader defaults
|
|
76
|
+
}
|
|
77
|
+
const extraPaths = skillDiscovery.paths ?? [];
|
|
78
|
+
const signature = await computeSkillSignature(repoRoot, extraPaths);
|
|
96
79
|
const cached = toolNameCache.get(repoRoot);
|
|
97
80
|
if (cached && cached.signature === signature)
|
|
98
81
|
return cached.names;
|
|
99
82
|
const registry = new ToolRegistry();
|
|
100
83
|
registerAllBuiltins(registry);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
84
|
+
const routerBox = { router: null };
|
|
85
|
+
const skillLoader = new SkillLoader({
|
|
86
|
+
repoRoot,
|
|
87
|
+
extraPaths,
|
|
88
|
+
});
|
|
89
|
+
const catalog = await skillLoader.loadCatalog();
|
|
90
|
+
for (const entry of catalog) {
|
|
91
|
+
try {
|
|
92
|
+
// Name-only registration: executor is never called, so null router is safe.
|
|
93
|
+
// Use catalog entry for lightweight registration (progressive disclosure).
|
|
94
|
+
registry.register(skillToToolSpec({ entry, loader: skillLoader }, routerBox));
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
const label = entry.name || entry.id;
|
|
98
|
+
getLogger().warn(`Failed to register skill ${label}: ${error instanceof Error ? error.message : String(error)}`);
|
|
111
99
|
}
|
|
112
100
|
}
|
|
113
101
|
const names = new Set(registry.listAll().map((spec) => spec.name));
|
|
114
102
|
toolNameCache.set(repoRoot, { names, signature });
|
|
115
103
|
return names;
|
|
116
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Synchronous variant for tab completion only.
|
|
107
|
+
*
|
|
108
|
+
* @nonAuthoritative This returns a best-effort approximation of known tool
|
|
109
|
+
* names using loader defaults (no extensions resolution, since
|
|
110
|
+
* resolveExtensions is async). The result may differ from the actual runtime
|
|
111
|
+
* tool set when custom `skills.json` discovery paths are configured.
|
|
112
|
+
*
|
|
113
|
+
* DO NOT use this for security decisions (allowlist enforcement, permission
|
|
114
|
+
* checks). Use the async {@link getKnownToolNames} instead, which resolves
|
|
115
|
+
* extensions for full consistency with the runtime.
|
|
116
|
+
*/
|
|
117
117
|
export function getKnownToolNamesSync(repoRoot) {
|
|
118
118
|
const signature = computeSkillSignatureSync(repoRoot);
|
|
119
119
|
const cached = toolNameCache.get(repoRoot);
|
|
@@ -121,16 +121,16 @@ export function getKnownToolNamesSync(repoRoot) {
|
|
|
121
121
|
return cached.names;
|
|
122
122
|
const registry = new ToolRegistry();
|
|
123
123
|
registerAllBuiltins(registry);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
124
|
+
const routerBox = { router: null };
|
|
125
|
+
const skillLoader = new SkillLoader({ repoRoot });
|
|
126
|
+
const skills = skillLoader.initializeSync();
|
|
127
|
+
for (const skill of skills) {
|
|
128
|
+
try {
|
|
129
|
+
registry.register(skillToToolSpec(skill, routerBox));
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
const label = skill.metadata?.name || skill.id;
|
|
133
|
+
getLogger().warn(`Failed to register skill ${label}: ${error instanceof Error ? error.message : String(error)}`);
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
const names = new Set(registry.listAll().map((spec) => spec.name));
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { encodeAnthropicStreamEvent, } from './anthropic-stream-protocol.js';
|
|
2
|
+
function asToolInput(value) {
|
|
3
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
4
|
+
? value
|
|
5
|
+
: {};
|
|
6
|
+
}
|
|
2
7
|
export function encodeNormalizedToAnthropicStreamLines(params) {
|
|
3
8
|
if (params.event.type === 'normalized.message_start') {
|
|
4
9
|
return [
|
|
@@ -64,7 +69,7 @@ export function encodeNormalizedToAnthropicStreamLines(params) {
|
|
|
64
69
|
}
|
|
65
70
|
if (params.event.type === 'normalized.tool_request_start') {
|
|
66
71
|
const parentToolUseId = params.event.callId;
|
|
67
|
-
const input = {};
|
|
72
|
+
const input = params.includeToolInput ? asToolInput(params.event.input) : {};
|
|
68
73
|
return [
|
|
69
74
|
encodeAnthropicStreamEvent({
|
|
70
75
|
sessionId: params.sessionId,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HEADLESS_SCHEMA_VERSION, normalizeHeadlessWarnings, } from './protocol-metadata.js';
|
|
1
2
|
function toExitCode(result) {
|
|
2
3
|
if (result.reason === 'Operation cancelled by user')
|
|
3
4
|
return 130;
|
|
@@ -31,6 +32,30 @@ function toAuthorizationDecisions(result) {
|
|
|
31
32
|
timestamp: d.timestamp,
|
|
32
33
|
}));
|
|
33
34
|
}
|
|
35
|
+
function toPatchArtifact(result) {
|
|
36
|
+
const artifact = result.benchmarkPatchArtifact;
|
|
37
|
+
if (!artifact)
|
|
38
|
+
return undefined;
|
|
39
|
+
return {
|
|
40
|
+
kind: artifact.kind,
|
|
41
|
+
path: artifact.path,
|
|
42
|
+
sha256: artifact.sha256,
|
|
43
|
+
bytes: artifact.bytes,
|
|
44
|
+
changed_files: artifact.changedFiles,
|
|
45
|
+
is_empty: artifact.isEmpty,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function toBenchmarkArtifact(result) {
|
|
49
|
+
const artifact = result.benchmarkArtifact;
|
|
50
|
+
if (!artifact)
|
|
51
|
+
return undefined;
|
|
52
|
+
return {
|
|
53
|
+
provider: artifact.provider,
|
|
54
|
+
instance_id: artifact.instanceId,
|
|
55
|
+
model_name_or_path: artifact.modelNameOrPath,
|
|
56
|
+
predictions_path: artifact.predictionsPath,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
34
59
|
export function encodeJsonResult(params) {
|
|
35
60
|
const overrides = params.overrides;
|
|
36
61
|
const exitCode = overrides?.exitCode ?? toExitCode(params.loopResult);
|
|
@@ -41,11 +66,13 @@ export function encodeJsonResult(params) {
|
|
|
41
66
|
const reason = overrides?.reason ?? safeHint;
|
|
42
67
|
const reasonCode = overrides?.reasonCode ?? params.loopResult.reasonCode;
|
|
43
68
|
const errorCode = overrides?.errorCode ?? params.loopResult.errorCode;
|
|
69
|
+
const warnings = normalizeHeadlessWarnings(params.warnings);
|
|
44
70
|
return {
|
|
45
71
|
result: params.resultText,
|
|
46
72
|
structured_output: params.structuredOutput,
|
|
47
73
|
session_id: params.sessionId,
|
|
48
74
|
metadata: {
|
|
75
|
+
schema_version: HEADLESS_SCHEMA_VERSION,
|
|
49
76
|
command: params.mode,
|
|
50
77
|
repo_path: params.repoPath,
|
|
51
78
|
instruction: params.instruction,
|
|
@@ -58,12 +85,15 @@ export function encodeJsonResult(params) {
|
|
|
58
85
|
remediation_steps: remediationSteps,
|
|
59
86
|
attempts: params.loopResult.attempts,
|
|
60
87
|
changed_files: params.loopResult.changedFiles ?? [],
|
|
88
|
+
patch_artifact: toPatchArtifact(params.loopResult),
|
|
89
|
+
benchmark_artifact: toBenchmarkArtifact(params.loopResult),
|
|
61
90
|
audit_path: params.loopResult.auditPath,
|
|
62
91
|
error_code: errorCode,
|
|
63
92
|
authorization_summary: params.loopResult.authorizationSummary,
|
|
64
93
|
usage: toUsage(params.loopResult),
|
|
65
94
|
authorization_decisions: toAuthorizationDecisions(params.loopResult),
|
|
66
95
|
structured_output_error: overrides?.structuredOutputError,
|
|
96
|
+
warnings,
|
|
67
97
|
timestamps: {
|
|
68
98
|
started_at: params.startedAt.toISOString(),
|
|
69
99
|
ended_at: params.endedAt.toISOString(),
|
|
@@ -79,11 +109,13 @@ export function encodeJsonResult(params) {
|
|
|
79
109
|
export function encodeJsonFailure(params) {
|
|
80
110
|
const at = params.at ?? new Date();
|
|
81
111
|
const exitCode = params.exitCode ?? 1;
|
|
112
|
+
const warnings = normalizeHeadlessWarnings(params.warnings);
|
|
82
113
|
return {
|
|
83
114
|
result: '',
|
|
84
115
|
structured_output: null,
|
|
85
116
|
session_id: params.sessionId,
|
|
86
117
|
metadata: {
|
|
118
|
+
schema_version: HEADLESS_SCHEMA_VERSION,
|
|
87
119
|
command: params.mode,
|
|
88
120
|
repo_path: params.repoPath,
|
|
89
121
|
instruction: params.instruction,
|
|
@@ -91,6 +123,8 @@ export function encodeJsonFailure(params) {
|
|
|
91
123
|
exit_code: exitCode,
|
|
92
124
|
reason: params.message,
|
|
93
125
|
error_code: params.errorCode,
|
|
126
|
+
audit_path: params.auditPath,
|
|
127
|
+
warnings,
|
|
94
128
|
timestamps: {
|
|
95
129
|
started_at: at.toISOString(),
|
|
96
130
|
ended_at: at.toISOString(),
|
|
@@ -99,11 +133,13 @@ export function encodeJsonFailure(params) {
|
|
|
99
133
|
};
|
|
100
134
|
}
|
|
101
135
|
export function encodeJsonCrash(params) {
|
|
136
|
+
const warnings = normalizeHeadlessWarnings(params.warnings);
|
|
102
137
|
return {
|
|
103
138
|
result: '',
|
|
104
139
|
structured_output: null,
|
|
105
140
|
session_id: params.sessionId,
|
|
106
141
|
metadata: {
|
|
142
|
+
schema_version: HEADLESS_SCHEMA_VERSION,
|
|
107
143
|
command: params.mode,
|
|
108
144
|
repo_path: params.repoPath,
|
|
109
145
|
instruction: params.instruction,
|
|
@@ -114,6 +150,7 @@ export function encodeJsonCrash(params) {
|
|
|
114
150
|
message: params.error.message,
|
|
115
151
|
stack: params.error.stack,
|
|
116
152
|
},
|
|
153
|
+
warnings,
|
|
117
154
|
timestamps: {
|
|
118
155
|
started_at: params.startedAt.toISOString(),
|
|
119
156
|
ended_at: params.endedAt.toISOString(),
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { encodeStreamEvent, encodeStreamFailure, } from './stream-json-protocol.js';
|
|
2
|
+
function asToolInput(value) {
|
|
3
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
4
|
+
? value
|
|
5
|
+
: {};
|
|
6
|
+
}
|
|
2
7
|
export function encodeNormalizedToNativeStreamLines(params) {
|
|
3
8
|
const at = params.event.timestamp;
|
|
4
9
|
if (params.event.type === 'normalized.message_start') {
|
|
@@ -75,7 +80,7 @@ export function encodeNormalizedToNativeStreamLines(params) {
|
|
|
75
80
|
const parentToolUseId = params.event.callId;
|
|
76
81
|
const phase = params.event.phase;
|
|
77
82
|
const round = params.event.round;
|
|
78
|
-
const input = {};
|
|
83
|
+
const input = params.includeToolInput ? asToolInput(params.event.input) : {};
|
|
79
84
|
return [
|
|
80
85
|
encodeStreamEvent({
|
|
81
86
|
uuid: params.uuid(),
|