salmon-loop 0.3.2 → 0.4.1
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/authorization/non-interactive.js +9 -13
- package/dist/cli/chat.js +12 -6
- package/dist/cli/commands/allowlist.js +1 -1
- package/dist/cli/commands/chat.js +13 -13
- package/dist/cli/commands/parallel.js +1 -1
- package/dist/cli/commands/run/handler.js +6 -3
- package/dist/cli/commands/run/loop-params.js +1 -0
- package/dist/cli/commands/run/parse-options.js +14 -26
- package/dist/cli/commands/run/runtime-llm.js +15 -12
- package/dist/cli/headless/openai-responses-canonical-applier.js +1 -7
- package/dist/cli/reporters/standard.js +2 -3
- package/dist/cli/reporters/stream-json.js +2 -1
- package/dist/cli/slash/runtime.js +2 -2
- package/dist/cli/ui/hooks/useLoopEvents.js +1 -1
- package/dist/cli/ui/hooks/useLoopState.js +1 -1
- package/dist/core/ast/parser.js +18 -9
- package/dist/core/config/schema.js +738 -0
- package/dist/core/config/validate.js +11 -922
- package/dist/core/context/gatherers/ast-gatherer.js +4 -12
- package/dist/core/context/gatherers/ghost-dependency-gatherer.js +0 -1
- package/dist/core/context/gatherers/knowledge-gatherer.js +3 -0
- package/dist/core/context/service.js +8 -0
- package/dist/core/context/token/encoding-registry.js +7 -6
- package/dist/core/extensions/index.js +48 -3
- package/dist/core/extensions/load.js +3 -2
- package/dist/core/extensions/merge.js +5 -1
- package/dist/core/extensions/paths.js +6 -0
- package/dist/core/extensions/schemas.js +21 -0
- package/dist/core/facades/cli-command-chat.js +2 -0
- package/dist/core/facades/cli-run-handler.js +1 -0
- package/dist/core/facades/cli-utils-serialize.js +2 -0
- package/dist/core/grizzco/dsl/llm-strategy.js +3 -2
- package/dist/core/grizzco/engine/outcome/loop-result-mapper.js +15 -10
- package/dist/core/grizzco/engine/pipeline/pipeline.js +149 -240
- package/dist/core/grizzco/engine/transaction/attempt-failure.js +5 -4
- package/dist/core/grizzco/engine/transaction/authorization-summary.js +2 -1
- package/dist/core/grizzco/runtime/apply-back-runtime.js +2 -1
- package/dist/core/grizzco/services/registry.js +18 -0
- package/dist/core/grizzco/steps/audit.js +20 -10
- package/dist/core/grizzco/steps/display-report.js +4 -11
- package/dist/core/grizzco/steps/explore.js +9 -2
- package/dist/core/grizzco/steps/patch/prompt-input.js +4 -1
- package/dist/core/grizzco/steps/patch.js +1 -0
- package/dist/core/grizzco/steps/plan.js +58 -49
- package/dist/core/grizzco/steps/tool-runtime.js +3 -0
- package/dist/core/grizzco/workers/strata-sync-worker.js +2 -1
- package/dist/core/llm/ai-sdk/message-mapper.js +24 -18
- package/dist/core/llm/ai-sdk/request-params.js +1 -3
- package/dist/core/llm/ai-sdk/result-mapper.js +14 -8
- package/dist/core/llm/ai-sdk/retry-classifier.js +6 -4
- package/dist/core/llm/contracts/repair.js +16 -8
- package/dist/core/llm/errors.js +13 -10
- package/dist/core/llm/output-policy.js +8 -0
- package/dist/core/llm/redact.js +1 -3
- package/dist/core/llm/sub-agent-factory.js +48 -0
- package/dist/core/llm/tool-calling-stub.js +48 -0
- package/dist/core/llm/utils.js +17 -6
- package/dist/core/mcp/bridge/prompt-command-provider.js +4 -3
- package/dist/core/mcp/bridge/tool-bridge.js +5 -14
- package/dist/core/mcp/client/connection-manager.js +3 -2
- package/dist/core/mcp/host/sampling-provider.js +1 -1
- package/dist/core/mcp/schema/json-schema-to-zod.js +2 -1
- package/dist/core/memory/relevant-retrieval.js +6 -4
- package/dist/core/observability/authorization-decisions.js +13 -12
- package/dist/core/observability/error-mapping.js +2 -1
- package/dist/core/observability/token-usage.js +5 -4
- package/dist/core/plugin/loader.js +5 -4
- package/dist/core/prompts/registry.js +11 -29
- package/dist/core/protocols/a2a/sdk/server.js +2 -3
- package/dist/core/protocols/acp/formal-agent.js +10 -4
- package/dist/core/protocols/acp/stdio-server.js +6 -6
- package/dist/core/runtime/agent-server-runtime.js +3 -2
- package/dist/core/runtime/initialize.js +70 -6
- package/dist/core/session/compaction/index.js +4 -3
- package/dist/core/session/manager.js +24 -37
- package/dist/core/session/token-tracker.js +18 -7
- package/dist/core/skills/parser.js +3 -2
- package/dist/core/skills/runtime/MicroTaskRunner.js +1 -1
- package/dist/core/skills/runtime/SkillRunner.js +5 -2
- package/dist/core/slash/steps/slash-execute.js +7 -5
- package/dist/core/slash/strategy.js +1 -1
- package/dist/core/strata/layers/worktree.js +7 -9
- package/dist/core/strata/runtime/synchronizer.js +10 -9
- package/dist/core/streaming/canonical/parts-from-llm-stream-chunk.js +1 -11
- package/dist/core/structured-output/json-schema-validator.js +1 -13
- package/dist/core/sub-agent/context-snapshot.js +12 -6
- package/dist/core/sub-agent/controller.js +70 -1
- package/dist/core/sub-agent/core/loop.js +25 -3
- package/dist/core/sub-agent/core/manager.js +319 -116
- package/dist/core/sub-agent/registry-defaults.js +12 -0
- package/dist/core/sub-agent/registry.js +8 -0
- package/dist/core/sub-agent/team.js +98 -0
- package/dist/core/sub-agent/tools/task-await.js +109 -0
- package/dist/core/sub-agent/tools/task-spawn.js +49 -7
- package/dist/core/sub-agent/tools/team.js +92 -0
- package/dist/core/sub-agent/types.js +11 -2
- package/dist/core/tools/budget.js +4 -11
- package/dist/core/tools/builtin/code-search/executor.js +46 -43
- package/dist/core/tools/builtin/fs.js +14 -6
- package/dist/core/tools/builtin/index.js +41 -107
- package/dist/core/tools/builtin/interaction.js +13 -15
- package/dist/core/tools/builtin/proposal.js +11 -2
- package/dist/core/tools/capability/executor.js +5 -5
- package/dist/core/tools/headless-payload.js +1 -3
- package/dist/core/tools/mapper.js +8 -42
- package/dist/core/tools/parallel/persistence.js +17 -5
- package/dist/core/tools/parallel/scheduler.js +23 -21
- package/dist/core/tools/permissions/permission-rules.js +66 -114
- package/dist/core/tools/plugins/loader.js +4 -3
- package/dist/core/tools/router.js +24 -53
- package/dist/core/tools/session.js +54 -97
- package/dist/core/tools/streaming/ToolCallAccumulator.js +1 -3
- package/dist/core/tools/tool-visibility.js +2 -1
- package/dist/core/tools/types.js +10 -0
- package/dist/core/utils/error.js +79 -0
- package/dist/core/utils/serialize.js +63 -0
- package/dist/core/utils/zod.js +29 -0
- package/dist/core/workspace/capabilities.js +3 -2
- package/dist/integrations/langfuse/litellm-langfuse-outcome-reporter.js +9 -8
- package/dist/locales/en.js +2 -1
- package/package.json +1 -1
|
@@ -181,25 +181,17 @@ export class AstGatherer {
|
|
|
181
181
|
async gatherCallNames(parsedTree, lang, callsQuery) {
|
|
182
182
|
if (!parsedTree || !lang || !callsQuery)
|
|
183
183
|
return [];
|
|
184
|
-
const
|
|
185
|
-
if (typeof queryFn !== 'function')
|
|
186
|
-
return [];
|
|
187
|
-
const captures = (await queryFn(parsedTree, lang, callsQuery));
|
|
184
|
+
const captures = await AstParser.queryCapturesFromQuery(parsedTree, lang, callsQuery);
|
|
188
185
|
return Array.from(new Set(captures
|
|
189
186
|
.filter((c) => c.name === 'callee' && c.text.trim().length > 0)
|
|
190
187
|
.map((c) => c.text.trim())));
|
|
191
188
|
}
|
|
192
189
|
async gatherDeepAnalysis(primaryText, parsedTree, lang, flowPack) {
|
|
193
|
-
|
|
194
|
-
if (!parsedTree ||
|
|
195
|
-
!lang ||
|
|
196
|
-
!flowPack?.control ||
|
|
197
|
-
!flowPack?.exceptions ||
|
|
198
|
-
typeof queryFn !== 'function') {
|
|
190
|
+
if (!parsedTree || !lang || !flowPack?.control || !flowPack?.exceptions) {
|
|
199
191
|
return summarizeControlFlow(primaryText);
|
|
200
192
|
}
|
|
201
|
-
const controlCaptures =
|
|
202
|
-
const exceptionCaptures =
|
|
193
|
+
const controlCaptures = await AstParser.queryCapturesFromQuery(parsedTree, lang, flowPack.control);
|
|
194
|
+
const exceptionCaptures = await AstParser.queryCapturesFromQuery(parsedTree, lang, flowPack.exceptions);
|
|
203
195
|
const branchCount = controlCaptures.filter((c) => c.name === 'branch').length;
|
|
204
196
|
const loopCount = controlCaptures.filter((c) => c.name === 'loop').length;
|
|
205
197
|
const asyncBoundaryCount = controlCaptures.filter((c) => c.name === 'async').length;
|
|
@@ -50,6 +50,9 @@ export class KnowledgeGatherer {
|
|
|
50
50
|
data.deprecated_rules.forEach((r) => allDeprecated.add(r));
|
|
51
51
|
}
|
|
52
52
|
if (data.architectural_decisions) {
|
|
53
|
+
if (!Array.isArray(aggregated.architectural_decisions)) {
|
|
54
|
+
aggregated.architectural_decisions = [];
|
|
55
|
+
}
|
|
53
56
|
aggregated.architectural_decisions.push(...data.architectural_decisions);
|
|
54
57
|
}
|
|
55
58
|
if (data.user_preferences) {
|
|
@@ -119,6 +119,7 @@ export class ContextService {
|
|
|
119
119
|
expectedTargetSetSignature;
|
|
120
120
|
if (recordedTargetSetSignature !== expectedTargetSetSignature) {
|
|
121
121
|
await this.cacheStore.delete(cacheKey);
|
|
122
|
+
this.deleteUpdater(cacheKey);
|
|
122
123
|
this.cacheMetrics.misses += 1;
|
|
123
124
|
return {
|
|
124
125
|
missReason: 'target_signature_mismatch',
|
|
@@ -128,6 +129,7 @@ export class ContextService {
|
|
|
128
129
|
const nextSignature = await this.computeTrackedFilesSignature(repoPath, entry.trackedFiles);
|
|
129
130
|
if (nextSignature !== entry.signature) {
|
|
130
131
|
await this.cacheStore.delete(cacheKey);
|
|
132
|
+
this.deleteUpdater(cacheKey);
|
|
131
133
|
this.cacheMetrics.misses += 1;
|
|
132
134
|
return { missReason: 'signature_mismatch', targetSetSignature: expectedTargetSetSignature };
|
|
133
135
|
}
|
|
@@ -210,6 +212,7 @@ export class ContextService {
|
|
|
210
212
|
if (!last || Date.now() - last <= this.cacheTtlMs)
|
|
211
213
|
return false;
|
|
212
214
|
await this.cacheStore.delete(cacheKey);
|
|
215
|
+
this.deleteUpdater(cacheKey);
|
|
213
216
|
this.cacheMetrics.evictions += 1;
|
|
214
217
|
return true;
|
|
215
218
|
}
|
|
@@ -243,6 +246,7 @@ export class ContextService {
|
|
|
243
246
|
}
|
|
244
247
|
if (victimKey) {
|
|
245
248
|
await this.cacheStore.delete(victimKey);
|
|
249
|
+
this.deleteUpdater(victimKey);
|
|
246
250
|
this.cacheMetrics.evictions += 1;
|
|
247
251
|
}
|
|
248
252
|
}
|
|
@@ -253,6 +257,7 @@ export class ContextService {
|
|
|
253
257
|
const chunk = victims.slice(i, i + 10);
|
|
254
258
|
await Promise.all(chunk.map(async ([key]) => {
|
|
255
259
|
await this.cacheStore.delete(key);
|
|
260
|
+
this.deleteUpdater(key);
|
|
256
261
|
this.cacheMetrics.evictions += 1;
|
|
257
262
|
}));
|
|
258
263
|
}
|
|
@@ -285,6 +290,9 @@ export class ContextService {
|
|
|
285
290
|
}
|
|
286
291
|
return updater;
|
|
287
292
|
}
|
|
293
|
+
deleteUpdater(key) {
|
|
294
|
+
this.updaters.delete(key);
|
|
295
|
+
}
|
|
288
296
|
logDiff(key, diff) {
|
|
289
297
|
if (!diff.addedFiles.length && !diff.modifiedFiles.length && !diff.removedFiles.length) {
|
|
290
298
|
return;
|
|
@@ -24,13 +24,13 @@ class TiktokenEncoding {
|
|
|
24
24
|
this.initialized = true;
|
|
25
25
|
}
|
|
26
26
|
encode(text) {
|
|
27
|
-
this.
|
|
28
|
-
return Array.from(
|
|
27
|
+
const encoder = this.getEncoder();
|
|
28
|
+
return Array.from(encoder.encode(text));
|
|
29
29
|
}
|
|
30
30
|
decode(tokens) {
|
|
31
|
-
this.
|
|
31
|
+
const encoder = this.getEncoder();
|
|
32
32
|
const uint32Tokens = new Uint32Array(tokens);
|
|
33
|
-
const decoded =
|
|
33
|
+
const decoded = encoder.decode(uint32Tokens);
|
|
34
34
|
return new TextDecoder().decode(decoded);
|
|
35
35
|
}
|
|
36
36
|
count(text) {
|
|
@@ -43,10 +43,11 @@ class TiktokenEncoding {
|
|
|
43
43
|
}
|
|
44
44
|
this.initialized = false;
|
|
45
45
|
}
|
|
46
|
-
|
|
47
|
-
if (!this.
|
|
46
|
+
getEncoder() {
|
|
47
|
+
if (!this.encoder) {
|
|
48
48
|
throw new Error(`Encoding ${this.name} not initialized. Call initialize() first.`);
|
|
49
49
|
}
|
|
50
|
+
return this.encoder;
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
/**
|
|
@@ -3,9 +3,9 @@ import { buildResolvedMcpServersV2 } from '../mcp/config/index.js';
|
|
|
3
3
|
import { getLogger } from '../observability/logger.js';
|
|
4
4
|
import { loadConfig } from './load.js';
|
|
5
5
|
import { mergeScopedEntries } from './merge.js';
|
|
6
|
-
import { expandHome, getRepoMcpConfigPath, getRepoSkillConfigPath, getRepoToolConfigPath, getUserMcpConfigPath, getUserSkillConfigPath, getUserToolConfigPath, isWithinRoot, resolveRepoRelative, resolveUserRelative, } from './paths.js';
|
|
6
|
+
import { expandHome, getRepoAgentsConfigPath, getRepoMcpConfigPath, getRepoSkillConfigPath, getRepoToolConfigPath, getUserAgentsConfigPath, getUserMcpConfigPath, getUserSkillConfigPath, getUserToolConfigPath, isWithinRoot, resolveRepoRelative, resolveUserRelative, } from './paths.js';
|
|
7
7
|
import { redactExtensions } from './redact.js';
|
|
8
|
-
import { McpConfigSchema, SkillsConfigSchema, ToolsConfigSchema } from './schemas.js';
|
|
8
|
+
import { AgentsConfigSchema, McpConfigSchema, SkillsConfigSchema, ToolsConfigSchema, } from './schemas.js';
|
|
9
9
|
function defaultEnabled(scope) {
|
|
10
10
|
return scope === 'repo';
|
|
11
11
|
}
|
|
@@ -29,6 +29,47 @@ function buildResolvedPlugins(entries, repoRoot) {
|
|
|
29
29
|
};
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
+
function buildResolvedAgentProfiles(user, repo) {
|
|
33
|
+
const seen = new Map();
|
|
34
|
+
// User profiles first (lower priority)
|
|
35
|
+
if (user) {
|
|
36
|
+
for (const agent of user.agents) {
|
|
37
|
+
if (agent.enabled === false)
|
|
38
|
+
continue;
|
|
39
|
+
seen.set(agent.id, toResolvedProfile(agent, 'user'));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Repo profiles override user profiles (higher priority)
|
|
43
|
+
if (repo) {
|
|
44
|
+
for (const agent of repo.agents) {
|
|
45
|
+
if (agent.enabled === false) {
|
|
46
|
+
seen.delete(agent.id);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
seen.set(agent.id, toResolvedProfile(agent, 'repo'));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return Array.from(seen.values());
|
|
53
|
+
}
|
|
54
|
+
function toResolvedProfile(raw, scope) {
|
|
55
|
+
return {
|
|
56
|
+
id: raw.id,
|
|
57
|
+
name: raw.name,
|
|
58
|
+
role: raw.role,
|
|
59
|
+
description: raw.description,
|
|
60
|
+
allowedTools: raw.allowedTools ?? ['code.search', 'fs.read'],
|
|
61
|
+
readOnly: raw.readOnly ?? false,
|
|
62
|
+
stratagem: raw.stratagem ?? 'investigator',
|
|
63
|
+
toolInheritance: raw.toolInheritance,
|
|
64
|
+
permissionMode: raw.permissionMode,
|
|
65
|
+
systemPrompt: raw.systemPrompt,
|
|
66
|
+
maxTokens: raw.maxTokens,
|
|
67
|
+
maxAttempts: raw.maxAttempts,
|
|
68
|
+
timeoutMs: raw.timeoutMs,
|
|
69
|
+
model: raw.model,
|
|
70
|
+
scope,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
32
73
|
function buildResolvedSkills(user, repo, repoRoot) {
|
|
33
74
|
const repoDiscovery = repo?.discovery;
|
|
34
75
|
const userDiscovery = user?.discovery;
|
|
@@ -73,13 +114,15 @@ function buildResolvedSkills(user, repo, repoRoot) {
|
|
|
73
114
|
}
|
|
74
115
|
export async function resolveExtensions(options) {
|
|
75
116
|
const { repoRoot } = options;
|
|
76
|
-
const [userMcp, repoMcp, userTools, repoTools, userSkills, repoSkills] = await Promise.all([
|
|
117
|
+
const [userMcp, repoMcp, userTools, repoTools, userSkills, repoSkills, userAgents, repoAgents] = await Promise.all([
|
|
77
118
|
loadConfig(getUserMcpConfigPath(), McpConfigSchema),
|
|
78
119
|
loadConfig(getRepoMcpConfigPath(repoRoot), McpConfigSchema),
|
|
79
120
|
loadConfig(getUserToolConfigPath(), ToolsConfigSchema),
|
|
80
121
|
loadConfig(getRepoToolConfigPath(repoRoot), ToolsConfigSchema),
|
|
81
122
|
loadConfig(getUserSkillConfigPath(), SkillsConfigSchema),
|
|
82
123
|
loadConfig(getRepoSkillConfigPath(repoRoot), SkillsConfigSchema),
|
|
124
|
+
loadConfig(getUserAgentsConfigPath(), AgentsConfigSchema),
|
|
125
|
+
loadConfig(getRepoAgentsConfigPath(repoRoot), AgentsConfigSchema),
|
|
83
126
|
]);
|
|
84
127
|
const mergedServers = mergeScopedEntries(userMcp?.config.servers, repoMcp?.config.servers);
|
|
85
128
|
const mergedPlugins = mergeScopedEntries(userTools?.config.plugins, repoTools?.config.plugins);
|
|
@@ -87,11 +130,13 @@ export async function resolveExtensions(options) {
|
|
|
87
130
|
mcpServers: buildResolvedMcpServersV2(mergedServers, repoRoot),
|
|
88
131
|
toolPlugins: buildResolvedPlugins(mergedPlugins, repoRoot),
|
|
89
132
|
skillDiscovery: buildResolvedSkills(userSkills?.config, repoSkills?.config, repoRoot),
|
|
133
|
+
agentProfiles: buildResolvedAgentProfiles(userAgents?.config, repoAgents?.config),
|
|
90
134
|
};
|
|
91
135
|
const rawEffective = {
|
|
92
136
|
mcp: repoMcp?.config ?? userMcp?.config ?? null,
|
|
93
137
|
tools: repoTools?.config ?? userTools?.config ?? null,
|
|
94
138
|
skills: repoSkills?.config ?? userSkills?.config ?? null,
|
|
139
|
+
agents: repoAgents?.config ?? userAgents?.config ?? null,
|
|
95
140
|
};
|
|
96
141
|
return {
|
|
97
142
|
resolved,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { syncFs as fs } from '../adapters/fs/node-fs.js';
|
|
2
|
+
import { errorMessage } from '../utils/error.js';
|
|
2
3
|
export class ExtensionConfigError extends Error {
|
|
3
4
|
path;
|
|
4
5
|
constructor(path, message) {
|
|
@@ -18,7 +19,7 @@ export async function tryLoadJsonFile(path) {
|
|
|
18
19
|
: undefined) === 'ENOENT') {
|
|
19
20
|
return { exists: false };
|
|
20
21
|
}
|
|
21
|
-
throw new ExtensionConfigError(path, (error
|
|
22
|
+
throw new ExtensionConfigError(path, errorMessage(error) || 'Unable to read file');
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
export async function loadConfig(path, schema) {
|
|
@@ -30,7 +31,7 @@ export async function loadConfig(path, schema) {
|
|
|
30
31
|
return { path, config };
|
|
31
32
|
}
|
|
32
33
|
catch (error) {
|
|
33
|
-
throw new ExtensionConfigError(path, (error
|
|
34
|
+
throw new ExtensionConfigError(path, errorMessage(error) || 'Schema validation failed');
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
//# sourceMappingURL=load.js.map
|
|
@@ -11,7 +11,10 @@ export function mergeScopedEntries(user, repo) {
|
|
|
11
11
|
if (previous) {
|
|
12
12
|
merged.set(key, {
|
|
13
13
|
key,
|
|
14
|
-
entry: {
|
|
14
|
+
entry: {
|
|
15
|
+
...previous.entry,
|
|
16
|
+
...entry,
|
|
17
|
+
},
|
|
15
18
|
scope: 'repo',
|
|
16
19
|
});
|
|
17
20
|
}
|
|
@@ -38,6 +41,7 @@ export function mergeResolvedExtensions(base, overlay) {
|
|
|
38
41
|
: base.skillDiscovery.scope,
|
|
39
42
|
paths: [...base.skillDiscovery.paths, ...overlay.skillDiscovery.paths],
|
|
40
43
|
},
|
|
44
|
+
agentProfiles: [...base.agentProfiles, ...overlay.agentProfiles],
|
|
41
45
|
};
|
|
42
46
|
}
|
|
43
47
|
//# sourceMappingURL=merge.js.map
|
|
@@ -39,6 +39,12 @@ export function getUserToolConfigPath() {
|
|
|
39
39
|
export function getUserSkillConfigPath() {
|
|
40
40
|
return path.join(USER_CONFIG_DIR, 'skills-user.json');
|
|
41
41
|
}
|
|
42
|
+
export function getRepoAgentsConfigPath(repoRoot) {
|
|
43
|
+
return path.join(repoRoot, REPO_CONFIG_DIR, 'agents.json');
|
|
44
|
+
}
|
|
45
|
+
export function getUserAgentsConfigPath() {
|
|
46
|
+
return path.join(USER_CONFIG_DIR, 'agents-user.json');
|
|
47
|
+
}
|
|
42
48
|
/**
|
|
43
49
|
* Check whether a candidate path resides within (or equals) a given root directory.
|
|
44
50
|
*
|
|
@@ -21,4 +21,25 @@ export const SkillsConfigSchema = z
|
|
|
21
21
|
discovery: skillDiscoverySchema.optional().default({}),
|
|
22
22
|
})
|
|
23
23
|
.strict();
|
|
24
|
+
export const AgentProfileConfigSchema = z.object({
|
|
25
|
+
id: z.string().min(1),
|
|
26
|
+
name: z.string().min(1),
|
|
27
|
+
role: z.string().min(1),
|
|
28
|
+
description: z.string(),
|
|
29
|
+
allowedTools: z.array(z.string()).optional(),
|
|
30
|
+
toolInheritance: z.enum(['none', 'safe', 'all']).optional(),
|
|
31
|
+
permissionMode: z.enum(['default', 'plan', 'bypassPermissions']).optional(),
|
|
32
|
+
systemPrompt: z.string().optional(),
|
|
33
|
+
readOnly: z.boolean().optional(),
|
|
34
|
+
stratagem: z.enum(['investigator', 'surgeon', 'janitor']).optional(),
|
|
35
|
+
maxTokens: z.number().positive().optional(),
|
|
36
|
+
maxAttempts: z.number().positive().optional(),
|
|
37
|
+
timeoutMs: z.number().positive().optional(),
|
|
38
|
+
model: z.string().optional(),
|
|
39
|
+
enabled: z.boolean().optional(),
|
|
40
|
+
});
|
|
41
|
+
export const AgentsConfigSchema = z.object({
|
|
42
|
+
version: z.literal(1),
|
|
43
|
+
agents: z.array(AgentProfileConfigSchema),
|
|
44
|
+
});
|
|
24
45
|
//# sourceMappingURL=schemas.js.map
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export { ConfigError, normalizePermissionMode, resolveConfig } from '../config/index.js';
|
|
2
2
|
export { ExtensionConfigError, resolveExtensions } from '../extensions/index.js';
|
|
3
3
|
export { createRuntimeLlm } from '../llm/factory.js';
|
|
4
|
+
export { createSubAgentLlmFactory } from '../llm/sub-agent-factory.js';
|
|
4
5
|
export { getLogger } from '../observability/logger.js';
|
|
5
6
|
export { PluginLoader } from '../plugin/loader.js';
|
|
6
7
|
export { resolveExecutionProfile } from '../runtime/execution-profile.js';
|
|
7
8
|
export { clearPluginRegistry, createPluginRegistry, setPluginRegistry, } from '../plugin/registry.js';
|
|
8
9
|
export { clearPromptRegistry, createPromptRegistry, setPromptRegistry, } from '../prompts/registry.js';
|
|
10
|
+
export { getString } from '../utils/serialize.js';
|
|
9
11
|
//# sourceMappingURL=cli-command-chat.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { normalizePermissionMode } from '../config/index.js';
|
|
2
|
+
export { createSubAgentLlmFactory } from '../llm/sub-agent-factory.js';
|
|
2
3
|
export { getLogger, PlainReporter, SilentReporter } from '../observability/logger.js';
|
|
3
4
|
export { createPluginRegistry, setPluginRegistry, } from '../plugin/registry.js';
|
|
4
5
|
export { createPromptRegistry, setPromptRegistry, } from '../prompts/registry.js';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { resolveLlmCapabilities } from '../../llm/capabilities.js';
|
|
2
2
|
import { Phase } from '../../types/runtime.js';
|
|
3
|
+
import { FileStatus, OpType } from '../domain/grizzco-types.js';
|
|
3
4
|
import { DecisionEngine, PlanBuilder } from './DecisionEngine.js';
|
|
4
5
|
function defaultMaxRoundsForPhase(phase) {
|
|
5
6
|
// Explore needs more rounds to navigate the codebase
|
|
@@ -24,7 +25,7 @@ export function resolveLlmToolCallingPolicy(phase, llm) {
|
|
|
24
25
|
repoRoot: '',
|
|
25
26
|
file: {
|
|
26
27
|
path: '',
|
|
27
|
-
status:
|
|
28
|
+
status: FileStatus.CLEAN,
|
|
28
29
|
isBinary: false,
|
|
29
30
|
isSymlink: false,
|
|
30
31
|
isIgnored: false,
|
|
@@ -32,7 +33,7 @@ export function resolveLlmToolCallingPolicy(phase, llm) {
|
|
|
32
33
|
size: 0,
|
|
33
34
|
},
|
|
34
35
|
operation: {
|
|
35
|
-
type:
|
|
36
|
+
type: OpType.PATCH,
|
|
36
37
|
path: '',
|
|
37
38
|
},
|
|
38
39
|
options: {
|
|
@@ -5,6 +5,7 @@ import { buildFailureEnvelope } from '../../../observability/error-envelope.js';
|
|
|
5
5
|
import { getTokenUsageFromAuditTrail } from '../../../observability/token-usage.js';
|
|
6
6
|
import { resolveExecutionProfile } from '../../../runtime/execution-profile.js';
|
|
7
7
|
import { ErrorType, Phase } from '../../../types/runtime.js';
|
|
8
|
+
import { isRecord } from '../../../utils/serialize.js';
|
|
8
9
|
const ROOT_CAUSE_CODES = [
|
|
9
10
|
'LLM_RATE_LIMITED',
|
|
10
11
|
'LLM_UPSTREAM_5XX',
|
|
@@ -34,17 +35,19 @@ export function buildLoopResultFromTransaction({ executionReport, flowMode, opti
|
|
|
34
35
|
: 'NON_RETRYABLE_FAILURE';
|
|
35
36
|
const ctx = executionReport.lastContext ??
|
|
36
37
|
executionReport.flowReport.data;
|
|
38
|
+
const ctxObj = isRecord(ctx) ? ctx : null;
|
|
37
39
|
const contextHash = (() => {
|
|
38
|
-
const
|
|
40
|
+
const contextResult = isRecord(ctxObj?.contextResult) ? ctxObj.contextResult : null;
|
|
41
|
+
const meta = isRecord(contextResult?.meta) ? contextResult.meta : null;
|
|
42
|
+
const hashFromBudget = meta?.contextHash;
|
|
39
43
|
if (typeof hashFromBudget === 'string')
|
|
40
44
|
return hashFromBudget;
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
: undefined;
|
|
45
|
+
const context = isRecord(ctxObj?.context) ? ctxObj.context : null;
|
|
46
|
+
const hashFromContext = context?.contextHash;
|
|
44
47
|
return typeof hashFromContext === 'string' ? hashFromContext : undefined;
|
|
45
48
|
})();
|
|
46
|
-
const verifyArtifact =
|
|
47
|
-
?
|
|
49
|
+
const verifyArtifact = ctxObj && typeof ctxObj.verifyArtifact !== 'undefined'
|
|
50
|
+
? ctxObj.verifyArtifact
|
|
48
51
|
: executionReport.lastVerifyArtifact;
|
|
49
52
|
const artifactHints = (() => {
|
|
50
53
|
const hints = {
|
|
@@ -71,12 +74,14 @@ export function buildLoopResultFromTransaction({ executionReport, flowMode, opti
|
|
|
71
74
|
}
|
|
72
75
|
return hints;
|
|
73
76
|
})();
|
|
77
|
+
const report = isRecord(ctxObj?.report) ? ctxObj.report : null;
|
|
74
78
|
const assistantMessage = ((flowMode === 'answer' || profile.driver === 'agent') &&
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
typeof report?.summary === 'string' &&
|
|
80
|
+
report.summary.trim()
|
|
81
|
+
? report.summary.trim()
|
|
77
82
|
: undefined) ?? undefined;
|
|
78
|
-
const finalPatch =
|
|
79
|
-
const changedFiles =
|
|
83
|
+
const finalPatch = ctxObj && typeof ctxObj.diff === 'string' ? ctxObj.diff : undefined;
|
|
84
|
+
const changedFiles = Array.isArray(ctxObj?.changedFiles) ? ctxObj.changedFiles : undefined;
|
|
80
85
|
const authorizationDecisions = (() => {
|
|
81
86
|
if (!options.eventPayload?.includeAuthorizationDecisions)
|
|
82
87
|
return undefined;
|